Custom Username Namespaces

This guide explains how to create and manage custom username namespaces on Lens.


This guide provides an introduction to the concept of Custom Namespaces. More information will be provided in due course.

As mentioned in the Username concept page, there are two Namespace groups:

  • The Global Namespace: The familiar lens/* namespace.

  • Custom Namespace: App or community-specific namespaces that can govern issuance, monetization, and more by means of Username Rules.

Create a Custom Namespace

To create a Username Namespace, you need to:

  1. Create a Username Metadata object

  2. Upload the Username Metadata object onto a public URI.

  3. Deploy the Lens Username smart contract.

See the Lens Metadata Standards guide for more information on creating and hosting Metadata objects.

1

Create Username Metadata

Use the @lens-protocol/metadata package to construct a valid UsernameMetadata object:

Example
import { username } from "@lens-protocol/metadata";
const metadata = username({  description: "A collection of usernames",  collection: {    name: "Lens Usernames",    description: "The official lens/ usernames",  },});

Since usernames are ERC-721 tokens, you can also specify EIP-7572 contract-level metadata which makes it easier to trade and display usernames in wallets and marketplaces.

2

Upload Username Metadata

Then, upload the Username Metadata object to a public URI.

import { uploadJson } from "./my-upload-lib";
const metadataURI = await uploadJson(metadata); // e.g., lens://4f91ca…

3

Deploy Username Contract

Use the createUsernameNamespace mutation to deploy the Lens Username smart contract.

You MUST be authenticated as Builder to make this request.

mutation {  createUsernameNamespace(    request: {      metadataURI: "lens://4f91ca…"      namespace: "foo" # foo/<localName>      symbol: "FOO"
      # optional list of admins      # admins: [EvmAddress!]
      # other fields such as feed rules configuration      # will be documented in due course    }  ) {    ... on CreateNamespaceResponse {      hash    }
    ... on SelfFundedTransactionRequest {      ...SelfFundedTransactionRequest    }
    ... on TransactionWillFail {      reason    }  }}

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