# Lens Protocol

<figure><img src="/files/vMRneCp5MqBSlQYNsD9U" alt=""><figcaption></figcaption></figure>

The [Lens Protocol](https://www.lens.xyz/) is a Web3 social graph on the Polygon Proof-of-Stake blockchain. It is designed to empower creators to own the links between themselves and their community, forming a fully composable, user-owned social graph. The point of this guide is a focused guide showing how to create and store your post metadata on IPFS/Arweave via 4EVERLAND.For additional information about creating a post on Lens, please visit the lens [documents](https://docs.lens.xyz/docs/create-post-typed-data).What you can expect in this tutorial:

1. Use 4EVERLAND to upload post assets to IPFS/Arweave.
2. Generate [structured metadata](https://docs.lens.xyz/docs/metadata-standards) for your post and upload it to IPFS/Arweave using 4EVERLAND.
3. When generating a new Lens Protocol post, use the URL created in the previous step as the content URI.

### Upload media to IPFS/Arweave

If your social post involves images, video or audio files, you can upload your files to IPFS/Arweave via 4EVERLAND in a number of optional ways:

* [4EVERLAND Dashboard](https://dashboard.4everland.org/bucket/storage/)
* CLI: <https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html>
* SDK: <https://aws.amazon.com/developer/tools/>
* 4EVERLAND API : [S3-Compatile API](https://docs.4everland.org/storage/bucket/s3-compatible-api), [Pinning Services API](https://docs.4everland.org/storage/4ever-pin/pinning-services-api)
* Various tools: <https://docs.4everland.org/storage/bucket/bucket-tools>

Either way, after you have uploaded the files, you can get the cid/arhash of the files and place them in the metadata.

#### Find the cases used in Lenster and Lenstube:

<https://github.com/lensterxyz/lenster/pull/954>

<https://github.com/lenstube-xyz/lenstube/blob/main/packages/utils/functions/uploadToIPFS.ts>

### Uploading Metadata

You can find out how to create almost any type of post in the full Lens Protocol [metadata specification](https://docs.lens.xyz/docs/metadata-standards). In this case, we assume that we have an image post which is stored in IPFS. The metadata is as follows:

```JSON
{
    "version": "2.0.0",
    "metadata_id": "${uuid()}",
    "description": "gm (🌿, 🌿)",
    "image": "https://ipfs.4everland.io/ipfs/bafkreigflfr75iwyond7p4b3ggv3drivofhcakokpmftmsf35v5ukbhsva",
    "imageMimeType": "image/png",
    "name": "Post by ?.lens",
    "attributes": [{ "traitType": "type", "value": "POST" }],
    "media": [
        {
            "item": "https://ipfs.4everland.io/ipfs/bafkreigflfr75iwyond7p4b3ggv3drivofhcakokpmftmsf35v5ukbhsva",
            "type": "image/png",
            "altTag": ""
        }
    ],
    "appId": "ImageUploader",
    "locale": "en",
    "mainContentFocus": "IMAGE"
}
```

* The function `uuid()` generates a unique post id using the [UUID npm package](https://www.npmjs.com/package/uuid).
* If the image is stored in Arweave, please replace the url in the metadata involving the image with the Arweave hash, e.g: <https://arweave.net/CO9EpX0lekJEfXUOeXncUmMuG8eEp5WJHXl9U9yZUYA>.

Uploading structured JSON data to IPFS/Arweave using 4EVERLAND is a breeze. The following is an example of taking a metadata stringfy and uploading it to the 4EVERLAND Bucket via the AWS-S3 API.

```JavaScript
import { S3 } from "@aws-sdk/client-s3";

// Create S3 instance
// View API key in 4EVERLAND Dashboard
const accessKey = "YOUR_ACCESS_KEY";
const secretKey = "YOUR_SECRET_KEY";

const s3Instance = new S3({
      endpoint: "https://endpoint.4everland.co",
      credentials: {
        accessKeyId: accessKey,
        secretAccessKey: secretKey,
      },
      region: "eu-west-2",
    });
    
//You will need to create a bucket before get started.
//await s3Instance.createBucket({
//      Bucket: 'YOUR_BUCKET_NAME',
//    });

 
// Upload metadata to your Bucket
const data = JSON.stringify(metadata);
await s3Instance.putObject({
      Bucket: 'YOUR_BUCKET_NAME',
      Key: 'metadata.json',
      Body: data,
      ContentType: 'application/json',
    });
// Get File CID    
const result = await s3Instance.headObject({
      Bucket: 'YOUR_BUCKET_NAME',
      Key: 'metadata.json',
    });
const cid = result.Metadata["ipfs-hash"];
console.log(`Upload success content URI= ipfs://${cid}`);


// In order this is an arbucket
// const arhash = result.Metadata["arweave-hash"]
// console.log(`Upload success content URI= https://arweave.net/${arhash}`);   

   
```

If you want to store your metadata on Arweave, you will need to turn on "Sync to AR" in the Dashboard.

### Creating A Post

After successfully uploading your metadata, you can convert the cid or arhash of the metadata to `contentURI`.The `contentURI` can be an IPFS or Arweave hash, formatted as follows:

```JavaScript
// IPFS
contentURI: ipfs://your-ipfs-hash
// Arweave
contentURI: https://arweave.net/your-arweave-hash
// or
contentURI: ar://your-arweave-hash
// when uploading to Arweave, be sure to set the "Content-Type" to "application/json"
```

Lastly, generate a post request with the created content URI and send it to the Lens contract calling via the`.post()` or`.postWithSig()` functions.

```JSON
{
    "profileId": "0x03",
    "contentURI": "ipfs://bafkreib6xvmu2k6wgp2fm4nmku2vdw44fajh3y3ln5s2e76qsiuvpsf5qu",
    "collectModule": {
        "revertCollectModule": true
    },
    "referenceModule": {
        "followerOnlyReferenceModule": false
    }
}
```

## To conclude

That's it! You have just used a few lines of code to combine 4EVERLAND + Lens Protocol to create and store your post metadata on IPFS and Arweave.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.4everland.org/more/use-cases/lens-protocol.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
