Post an Image on Lens

This tutorial will show you how to post an image on Lens leveraging Lens Storage Nodes.


You MUST be authenticated as Account Owner or Account Manager to make this request.

1

Create a Form

First, start by defining a form that allows users to upload an image file and a text.

index.html
<form id="post-form">  <label for="image">Image file:</label>  <input type="file" name="image" accept="image/png" multiple />
  <label for="content">Post content:</label>  <textarea name="content" row="3"></textarea>
  <button type="submit">Post</button></form>

With an event listener to handle the form submission.

index.ts
document.getElementById("post-form").addEventListener("submit", onSubmit);
async function onSubmit(event: SubmitEvent) {  // prevent the full page reload of a typical form submission  event.preventDefault();
  const input = event.currentTarget.elements["image"];  const textarea = event.currentTarget.elements["content"];
  // …}

2

Create and Upload the Post Metadata

Next, create an instance of the Lens StorageClient.

storage.ts
import { StorageClient, testnet } from "@lens-protocol/storage-node-client";
export const storageClient = StorageClient.create(testnet);

And upload the image and post content altogether as a single folder with the Post Metadata object as index file.

index.ts
import type { Resource } from "@lens-protocol/storage-node-client";import { image, MediaImageMimeType } from "@lens-protocol/metadata";import { storageClient } from "./storage";
// …
async function onSubmit(event: SubmitEvent) {  // …
  const { folder, files } = await storage.uploadFolder(input.files, {    index: (resources: Resource[]) =>      image({        content: textarea.value,        image: {          item: resources[0].uri,          type: MediaImageMimeType.PNG,        },      }),  });
  // …}

As we didn't provide an acl option to the uploadFolder method, the folder will be immutable. See the Uploading Content guide for more information on ACL templates.

3

Submit On-Chain

Then, use the post mutation to create a Lens Post with the folder URI as contentUri.

mutation {  post(request: { contentUri: "<folder.uri>" }) {    ... on PostResponse {      hash    }
    ... on SponsoredTransactionRequest {      ...SponsoredTransactionRequest    }
    ... on SelfFundedTransactionRequest {      ...SelfFundedTransactionRequest    }
    ... on TransactionWillFail {      reason    }  }}

4

Wait for the Transaction to Complete

Then, handle the result as explained in the Transaction Lifecycle guide.

In this example, we will assume the previous step returned a PostResponse object so we will poll the transactionStatus query until it returns a FinishedTransactionStatus result.

Query
query {  transactionStatus(    request: { txHash: "0x5e9d8f8a4b8e4b8e4b8e4b8e4b8e4b8e4b8e4b" }  ) {    ... on NotIndexedYetStatus {      reason      txHasMined    }
    ... on PendingTransactionStatus {      blockTimestamp    }
    ... on FinishedTransactionStatus {      blockTimestamp    }
    ... on FailedTransactionStatus {      reason      blockTimestamp    }  }}

5

Fetch the Post

Finally, fetch the newly created post.

Use the post query with the transaction hash to fetch the post.

query {  post(request: { txHash: "0x5e9d8f8a4b8e4b8e4b8e4b8e4b8e4b8e4b8e4b" }) {    ... on Post {      ...Post    }
    ... on Repost {      ...Repost    }  }}

That's it! You have successfully posted an image on Lens.