Mint L1 or L2 subnames using SDK

This guide will show you how to implement a subname minting functionality using Namespace-SDK

Namespace SDK is a typescript library, which can be used to interact with Namespace API and smart contracts. It currently allows devs to mint subnames under listed ENS names and abstracts the different chain logic.

1. Listing an ENS name

The prerequisite for minting is for the parent ENS name to be listed on the Namespace platform. This can be done using the Manager on our platform.

Listing ENS Name

For testing purposes, we can use an already listed name "mint-on-namespace.eth". This name is listed on the Sepolia testnet and the subnames will be minted on the BaseSepolia testnet.

Get in touch with us on our Discord channel or Namespace Devs Telegram group if you need some testnet ETH.

2. Installing namespace-sdk library

The second step would be to include namespace-SDK dependency in our typescript project. Since the SDK uses viem under the hood, we would also need to include it as a dependency.

yarn add namespace-sdk viem

3. Create a NamespaceClient instance

We will use createNamespaceClientfunction to set up a Namespace Client with a given ChainId.

The ChainId specifies an id of a blockchain where the subnames are being minted from (In our case, since we will be using "mint-on-namespace.eth", we will specify baseSepolia.id (84532), this is so that viem knows which chain to look at when it simulates the mint transaction or when it checks for subname availability.

namespace-client.ts
import { createNamespaceClient } from "namespace-sdk";
import { baseSepolia } from "viem/chains";

export const NamespaceClient = createNamespaceClient({
    chainId: baseSepolia.id,
    mintSource: "my-app",
    rpcUrl: "https://alchemy-url"
});

export const ENS_NAME = "mint-on-namespace.eth";

Parameters

ParameterRequiredDescription

chainId

true

Specifies chain id where subnames are minted from, supported chains include

mintSource

false

Used to track the source of minted subnames on a blockchain, defaults to "namespace-sdk".

rpcUrl

false

Http RPC URL which will be used by SDK when it performs blockchain operations, defaults to a public RPC for a given chain

4. Getting a listed name and checking for subname availability

Now that we have our NamespaceClient, we can use it to fetch the listed name and check for subname availability.

details.ts
import { NamespaceClient, ENS_NAME } from "./namespace-client";
import { Listing } from "namespace-sdk";
import { sepolia } from "viem/chains";

const getListedName = async(): Listing => {
    // Here, we're specifying sepolia id as a second parameter
    // since our name is listed on sepolia testnet
    // for names listed on mainnet, we do not need to provide a second parameter
    return NamespaceClient.getListedName(ENS_NAME, sepolia.id)
}

const isSubnameAvailable = async (listedName: Listing, subnameLabel: string): boolean => {
    return NamespaceClient.isSubnameAvailable(listedName, subnameLabel);
}

5. Getting mint transaction parameters

Mint transaction parameters return all the needed values for executing a mint transaction

mint-parameters.ts
import { NamespaceClient, ENS_NAME } from "./namespace-client";
import { Listing, MintTransactionParameters, AddressRecord } from "namespace-sdk";
import { getListedName, isSubnameAvailable } from "./details.ts";
import { Address } from "viem";

// Minting a subname with provided label
export const getTxParameters = (listedName: Listing, minterAddress: Address, subnameLabel: string): Promise<MintTransactionParameters> => {
    return NamespaceClient.getMintTransactionParameters({
        minterAddress,
        subnameOwner: minterAddress,
        subnameLabel
    });
}

// Minting a subname and providing addresses/text records in the same transaction
export const getTxParametersWithRecords = (listedName: Listing, minterAddress: Address, subnameLabel: string, addresses: AddressRecord[]): Promise<MintTransactionParameters> => {
   return NamespaceClient.getMintTransactionParameters({
        minterAddress,
        subnameOwner: minterAddress,
        subnameLabel,
        records: {
             addresses: addresses,
             texts: []
        }
    });
}

6. Execute mint transaction

Now that we have all the required parameters, we can use all this to execute a mint transaction and mint a subname, using our preferred client library.

mint.ts
import { getListedName, isSubnameAvailable } from "./details.ts";
import { getTxParametersWithRecords } from "./mint-parameters";
import { Listing, MintTransactionParameters } from "namespace-sdk";
import { privateKeyToAccount } from "viem/accounts";
import { createWalletClient, http } from "viem";
import { baseSepolia } from "viem/chains";

const privateKeyAccount = privateKeyToAccount("0xmywalletkey");

const mint = async () => {
    const minterAddress = privateKeyAccount.address;
    const subnameLabel = "my-label";
    
    const listedName: Listing = await getListedName();
    const isAvailable = await isSubnameAvailable(listedName, subnameLabel);
    
    if (!isAvailable) {
        throw new Error("Subname is already taken");
    }
    
    const addressRecords = [{ coinType: 60, address: minterAddress }]; 
    const params = await getTxParametersWithRecords(listedName, minterAddress,         subnameLabel, addressRecords);
    
    const transactionHash = await getViemWalletClient().writeContract({
        functionName: params.functionName,
        args: params.args,
        abi: params.abi,
        value: params.value,
        address: params.contractAddress
    });
    
    console.log("Subname has been minted, transaction: " + transactionHash)

}

const getViemWalletClient = () => {
    return createWalletClient({
        transport: http(),
        chain: baseSepolia,
        account: privateKeyAccount
    })
}

We have now minted a subname on the BaseSepolia chain! We can now verify that it gets resolved on the ENS app using the URL: https://app.ens.domains/your-full-name.eth ( remember to switch to the Sepolia network if you've been using mint-on-namespace.eth )

Last updated