Set Profile Metadata
This request is protected by authentication
hint: this means it requires an x-access-token header put in the request with your authentication token.
Lens Profile Manager Compatible: Gasless & Signless
This action can be used through the Lens Profile Manager to enable a gasless and signless experience.
Configure the metadata associated to a profile.
All the metadata of the profile is stored on-chain in a URL/IPFS link that points to the metadata just how NFTs work. This means updating profile details is a transaction.
There are two different approaches you can use to set a profile's metadata. Depending on the whitelist status of your app and the settings of the profile you would like to set metadata for, you can use:
- a) Set Profile Metadata via Lens Profile Manager (Gasless & Signless)
- b) Set Profile Metadata Using TypedData and Broadcasting Onchain via the API (Gasless & Signed)
To decide which approach to use, you can use the following table. Please note that a profile may also have another Profile Manager enabled that is not powered by the Lens API, this is not covered below. To learn more about checking a profile's Profile Manager settings, see Profile Manager.
Is Your App Whitelisted? | Profile has Lens Profiles Manager Enabled? | Approach To Use | |
---|---|---|---|
1 | true | true | Lens Profile Manager |
2 | true | false | TypedData & Broadcast via API |
3 | false | true | TypedData & Self-Funded |
4 | false | false | TypedData & Self-Funded |
a) Set Profile Metadata via Lens Profile Manager
If possible, using the Lens Profile Manager is the best way to set a profile's metadata. This will be a gasles and signless operation.
Request
- metadataURI:
URI
(required)- The URL/IPFS link to the metadata file.
Invocation
const typedDataResult = await lensClient.profile.setProfileMetadata({
metadataURI: "metadata-uri",
})
mutation SetProfileMetadata {
result: setProfileMetadata(
request: { metadataURI: "https://example.com/metadata.json" }
) {
... on RelaySuccess {
...RelaySuccess
}
... on LensProfileManagerRelayError {
...LensProfileManagerRelayError
}
}
}
Response
{
"txHash": "0x000000",
"txId": "0x01"
}
{
"reason": "FAILED" // LensProfileManagerRelayErrorReasonType
}
b) Set Profile Metadata Using TypedData and Broadcasting Onchain via the API
Request
- metadataURI:
URI
(required)- The URL/IPFS link to the metadata file.
Invocation
const result =
await lensClient.profile.createOnChainSetProfileMetadataTypedData({
metadataURI: "metadata-uri",
})
mutation CreateOnchainSetProfileMetadataTypedData {
result: createOnchainSetProfileMetadataTypedData(
request: { metadataURI: "urlToMetadataFile" }
) {
...CreateOnchainSetProfileMetadataBroadcastItemResult
}
}
Response
{
"id": "0x01",
"expiresAt": "2023-10-01T00:00:00Z",
"typedData": {
"types": {
"SetProfileMetadataURI": [
{ "name": "...", "type": "..." },
{ "name": "...", "type": "..." }
]
},
"domain": {
"name": "...",
"chainId": "...",
"version": "...",
"verifyingContract": "0x0000000"
},
"value": {
"nonce": "...",
"deadline": "2023-10-01T01:00:00Z"
}
}
}
Broadcasting the TypedData
Once you have the typed data for the follow action, you need to get the user to sign with their wallet and then broadcast it onchain.
See Broadcasting Onchain for more information.
Calling the Contract Directly
If you opt to bypass the API and directly push transactions from the client to the blockchain, you'll be responsible for encoding and validation.
This approach isn't covered in the API documentation, you can find guidance in the contract documentation.
Aligned with best practices demonstrated by projects like seaport on OpenSea, this is aimed at enhancing the user's awareness of what they're signing.
Full LensClient Example
Using the Lens Profile Manager:
// your LensClient instance must be authenticated
const result = await lensClient.profile.setProfileMetadata({
metadataURI: "metadata-uri",
})
const data = result.unwrap()
if (!isSuccessfulLensProfileManagerResponse(data)) {
console.log(`Something went wrong`, data)
return
}
await lensClient.transaction.waitUntilComplete({ txId: data.txId })
Using TypedData:
// your LensClient instance must be authenticated
const typedDataResult =
await lensClient.profile.createOnChainSetProfileMetadataTypedData({
metadataURI: "your-metadata-uri",
})
// typedDataResult is a Result object
const data = typedDataResult.unwrap()
// sign with the wallet
const signedTypedData = await wallet._signTypedData(
data.typedData.domain,
data.typedData.types,
data.typedData.value
)
// broadcast
const broadcastResult = await lensClient.transaction.broadcastOnchain({
id: data.id,
signature: signedTypedData,
})
// broadcastResult is a Result object
const broadcastResultValue = broadcastResult.unwrap()
if (!isRelaySuccess(broadcastResultValue)) {
console.log(`Something went wrong`, broadcastResultValue)
return
}
// or wait till transaction is indexed
await lensClient.transaction.waitUntilComplete({
txId: broadcastResultValue.txId,
})
console.log(
`Transaction was successfully broadcasted with txId ${broadcastResultValue.txId}`
)
Profile Metadata Structure
export enum MetadataDisplayType {
number = "number",
string = "string",
date = "date",
}
export enum MetadataVersions {
one = "1.0.0",
}
export interface AttributeData {
displayType?: MetadataDisplayType
traitType?: string
value: string
key: string
}
export interface ProfileMetadata {
/**
* The metadata version.
*/
version: MetadataVersions
/**
* The metadata id can be anything but if your uploading to ipfs
* you will want it to be random.. using uuid could be an option!
*/
metadata_id: string
/**
* The display name for the profile
*/
name: string | null
/**
* The bio for the profile
*/
bio: string | null
/**
* Cover picture
*/
cover_picture: string | null
/**
* Any custom attributes can be added here to save state for a profile
*/
attributes: AttributeData[]
}
Anything you put in attributes
will be extracted out of the metadata and put into the profile schema under attributes
.
Full GraphQL API Example
Updated about 1 month ago