Help & Support

Custom Username Namespaces

This guide explains custom Username Namespace and how to create and manage them.

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 custom Namespace, follow these steps.

You MUST be authenticated as Builder to create a custom Namespace.

1

Create Namespace Metadata

First, construct a Namespace Metadata object with the necessary content.

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

Example
import { namespace } from "@lens-protocol/metadata";
const metadata = namespace({  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 Namespace Metadata

Next, upload the Namespace Metadata object to a public URI.

import { storageClient } from "./storage-client";
const { uri } = await storageClient.uploadAsJson(metadata);
console.log(uri); // e.g., lens://4f91ca…

This example uses Lens Storage to host the Metadata object. See the Lens Metadata Standards guide for more information on hosting Metadata objects.

3

Deploy Namespace Contract

Next, deploy a Lens Namespace smart contract.

Use the createUsernameNamespace action to deploy the contract.

import { evmAddress, uri } from "@lens-protocol/client";import { createFeed } from "@lens-protocol/client/action";
const result = await createUsernameNamespace(sessionClient, {  symbol: "FOO",  namespace: "foo", // foo/<localName>  metadataUri: uri("lens://4f91ca…"),  rules: {    required: [      {        usernameLengthRule: {          maxLength: 10,          minLength: 3,        },      },    ],  },});

To learn more about how to use Username Rules, see the Username Rules guide.

4

Handle Result

Finally, handle the result using the adapter for the library of your choice:

import { handleOperationWith } from "@lens-protocol/client/viem";
// …
const result = await createUsernameNamespace(sessionClient, {  symbol: "FOO",  namespace: "foo",  metadataUri: uri("lens://4f91ca…"),}).andThen(handleOperationWith(walletClient));

See the Transaction Lifecycle guide for more information on how to determine the status of the transaction.

That's it—you now know how to create and manage Custom Username Namespaces, allowing to build app- or community-specific namespaces.

Fetch a Namespace

Use the fetchNamespace action to fetch a single Namespace by address or by transaction hash.

import { evmAddress } from "@lens-protocol/client";import { fetchNamespace } from "@lens-protocol/client/actions";import { client } from "./client";
const result = await fetchNamespace(client, {  namespace: evmAddress("0x1234…"),});
if (result.isErr()) {  return console.error(result.error);}
const namespace = result.value;

Search Namespaces

Use the paginated fetchNamespaces action to search for namespaces.

import { fetchNamespaces } from "@lens-protocol/client/actions";
import { client } from "./client";
const result = await fetchNamespaces(client, {  filter: {    searchBy: "name",  },});
if (result.isErr()) {  return console.error(result.error);}
// items: Array<UsernameNamespace>const { items, pageInfo } = result.value;

Continue with the Pagination guide for more information on how to handle paginated results.

Access Control

The Namespace contract supports two roles: Owner and Administrator.

Administrators can:

  • Update the Namespace Metadata

  • Update the Namespace Rules

  • Update the Namespace Extra Data

The Owner can do everything the administrators can do, plus transfer ownership of the Namespace to another address.

See the Team Management guide for more information on how to manage these roles.