Aptos Names

K
Account

This documentation is using @aptos-labs/ts-sdk v6.0.0

Modifying Names

Learn how to register, renew, and manage Aptos names using the TS SDK. The SDK provides transaction generation methods in the ans namespace that return both transaction data and a transaction object, allowing you to use either the pure TS-SDK approach or integrate with wallet adapters.

Prerequisites

Before modifying names, you'll need:

  • A connected wallet or account (using @aptos-labs/wallet-adapter-react or Account from the SDK)
  • An Aptos client instance configured with your network
  • The account that will sign the transaction

Transaction Return Structure

All ANS methods return an object with two properties:

  • data: InputEntryFunctionData - Used for wallet adapter integration
  • transaction: Transaction object - Used for pure TS-SDK with Account
const { data, transaction } = await aptos.registerName({ ... });

Pure TS-SDK (Using transaction)

This approach uses the SDK's Account class to sign and submit transactions directly. Use the transaction property from the result.

Registering a Domain

export async function registerDomain(sender: Account, domain: string, years: number = 1) {
  // Generate the transaction - returns { data, transaction }
  const { transaction } = await aptos.registerName({
    sender: sender.accountAddress,
    name: domain, // e.g., "example" or "example.apt"
    expiration: {
      policy: "domain",
      years: years as 1, // Currently only 1 year is supported
    },
    transferable: true, // Whether the domain can be transferred
  });

  // Sign and submit the transaction
  const pendingTxn = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction,
  });

  // Wait for confirmation
  const result = await aptos.waitForTransaction({
    transactionHash: pendingTxn.hash,
  });

  return result;
}

Registering a Subdomain

Register a subdomain under an existing domain. Subdomains can follow the domain's expiration or have an independent expiration:

Option 1: Subdomain that follows domain expiration

export async function registerSubdomainFollowDomain(
  sender: Account,
  domain: string,
  subdomain: string,
) {
  const { transaction } = await aptos.registerName({
    sender: sender.accountAddress,
    name: `${subdomain}.${domain}.apt`, // e.g., "subdomain.example.apt"
    expiration: {
      policy: "subdomain:follow-domain",
    },
    transferable: true,
  });

  const pendingTxn = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction,
  });

  return await aptos.waitForTransaction({
    transactionHash: pendingTxn.hash,
  });
}

Option 2: Subdomain with independent expiration

export async function registerSubdomainIndependent(
  sender: Account,
  domain: string,
  subdomain: string,
  expirationDate: Date,
) {
  const { transaction } = await aptos.registerName({
    sender: sender.accountAddress,
    name: `${subdomain}.${domain}.apt`,
    expiration: {
      policy: "subdomain:independent",
      expirationDate: expirationDate.getTime(), // Epoch milliseconds
    },
    transferable: true,
  });

  const pendingTxn = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction,
  });

  return await aptos.waitForTransaction({
    transactionHash: pendingTxn.hash,
  });
}

Renewing a Domain

export async function renewDomain(sender: Account, domain: string) {
  // Generate the renewal transaction - returns { data, transaction }
  const { transaction } = await aptos.renewDomain({
    sender: sender.accountAddress,
    name: domain, // e.g., "example" (domain only, not subdomain)
    years: 1, // Currently only 1 year is supported
  });

  // Sign and submit
  const pendingTxn = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction,
  });

  // Wait for confirmation
  return await aptos.waitForTransaction({
    transactionHash: pendingTxn.hash,
  });
}

Setting Primary Name

export async function setPrimaryName(sender: Account, name: string) {
  // Generate the transaction - returns { data, transaction }
  const { transaction } = await aptos.setPrimaryName({
    sender: sender.accountAddress,
    name, // e.g., "example.apt" or "subdomain.example.apt"
  });

  // Sign and submit
  const pendingTxn = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction,
  });

  // Wait for confirmation
  return await aptos.waitForTransaction({
    transactionHash: pendingTxn.hash,
  });
}

Clearing Primary Name

export async function clearPrimaryName(sender: Account) {
  // Omit the name parameter to clear the primary name
  // Returns { data, transaction }
  const { transaction } = await aptos.setPrimaryName({
    sender: sender.accountAddress,
    // name is optional - omitting it clears the primary name
  });

  const pendingTxn = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction,
  });

  return await aptos.waitForTransaction({
    transactionHash: pendingTxn.hash,
  });
}

Setting Target Address

export async function setTargetAddress(
  sender: Account,
  name: string,
  targetAddress: AccountAddress,
) {
  // Generate the transaction - returns { data, transaction }
  const { transaction } = await aptos.setTargetAddress({
    sender: sender.accountAddress,
    name, // e.g., "example.apt" or "subdomain.example.apt"
    address: targetAddress,
  });

  // Sign and submit
  const pendingTxn = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction,
  });

  // Wait for confirmation
  return await aptos.waitForTransaction({
    transactionHash: pendingTxn.hash,
  });
}

Clearing Target Address

export async function clearTargetAddress(sender: Account, name: string) {
  // Generate the transaction - returns { data, transaction }
  const { transaction } = await aptos.clearTargetAddress({
    sender: sender.accountAddress,
    name, // e.g., "example.apt" or "subdomain.example.apt"
  });

  // Sign and submit
  const pendingTxn = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction,
  });

  // Wait for confirmation
  return await aptos.waitForTransaction({
    transactionHash: pendingTxn.hash,
  });
}

Using with Wallet Adapter (Using data)

When using @aptos-labs/wallet-adapter-react, use the data property from the result, which is of type InputEntryFunctionData. This can be passed directly to the wallet's signAndSubmitTransaction method.

Registering a Domain

export async function registerDomain(domain: string, years: number = 1) {
  if (!account?.address) throw new Error("No account connected");

  // Generate the transaction - returns { data, transaction }
  const { data } = await aptos.registerName({
    sender: account.address,
    name: domain,
    expiration: {
      policy: "domain",
      years: years as 1, // Currently only 1 year is supported
    },
    transferable: true,
  });

  // Use wallet's sign and submit with the data property
  const result = await signAndSubmitTransaction({
    data,
  });

  return result;
}

Registering a Subdomain

export async function registerSubdomain(domain: string, subdomain: string) {
  if (!account?.address) throw new Error("No account connected");

  const { data } = await aptos.registerName({
    sender: account.address,
    name: `${subdomain}.${domain}.apt`,
    expiration: {
      policy: "subdomain:follow-domain",
    },
    transferable: true,
  });

  const result = await signAndSubmitTransaction({
    data,
  });

  return result;
}

Renewing a Domain

export async function renewDomain(domain: string) {
  if (!account?.address) throw new Error("No account connected");

  const { data } = await aptos.renewDomain({
    sender: account.address,
    name: domain,
    years: 1,
  });

  const result = await signAndSubmitTransaction({
    data,
  });

  return result;
}

Setting Primary Name

export async function setPrimaryName(name: string) {
  if (!account?.address) throw new Error("No account connected");

  const senderAddress = AccountAddress.fromStringStrict(account.address);
  const { data } = await aptos.setPrimaryName({
    sender: senderAddress,
    name, // e.g., "example.apt" or "subdomain.example.apt"
  });

  const result = await signAndSubmitTransaction({
    data,
  });

  return result;
}

Clearing Primary Name

export async function clearPrimaryName() {
  if (!account?.address) throw new Error("No account connected");

  const senderAddress = AccountAddress.fromStringStrict(account.address);
  const { data } = await aptos.setPrimaryName({
    sender: senderAddress,
    // name is optional - omitting it clears the primary name
  });

  const result = await signAndSubmitTransaction({
    data,
  });

  return result;
}

Setting Target Address

export async function setTargetAddress(name: string, targetAddress: string) {
  if (!account?.address) throw new Error("No account connected");

  const address = AccountAddress.fromStringStrict(targetAddress);
  const { data } = await aptos.setTargetAddress({
    sender: account.address,
    name, // e.g., "example.apt" or "subdomain.example.apt"
    address,
  });

  const result = await signAndSubmitTransaction({
    data,
  });

  return result;
}

Clearing Target Address

export async function clearTargetAddress(name: string) {
  if (!account?.address) throw new Error("No account connected");

  const { data } = await aptos.clearTargetAddress({
    sender: account.address,
    name, // e.g., "example.apt" or "subdomain.example.apt"
  });

  const result = await signAndSubmitTransaction({
    data,
  });

  return result;
}

Complete Example: Register and Set Primary (Pure TS-SDK)

Here's a complete example that registers a domain and sets it as primary using the pure TS-SDK approach:

export async function registerAndSetPrimary(sender: Account, domain: string, years: number = 1) {
  // Step 1: Register the domain
  const { transaction: registerTx } = await aptos.registerName({
    sender: sender.accountAddress,
    name: domain,
    expiration: {
      policy: "domain",
      years: years as 1, // Currently only 1 year is supported
    },
    transferable: true,
  });

  const registerPending = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction: registerTx,
  });

  // Wait for registration to complete
  const registerResult = await aptos.waitForTransaction({
    transactionHash: registerPending.hash,
  });

  if (!registerResult.success) {
    throw new Error("Domain registration failed");
  }

  // Step 2: Set as primary name
  const { transaction: primaryTx } = await aptos.setPrimaryName({
    sender: sender.accountAddress,
    name: `${domain}.apt`,
  });

  const primaryPending = await aptos.signAndSubmitTransaction({
    signer: sender,
    transaction: primaryTx,
  });

  // Wait for primary name setting to complete
  const primaryResult = await aptos.waitForTransaction({
    transactionHash: primaryPending.hash,
  });

  if (!primaryResult.success) {
    throw new Error("Setting primary name failed");
  }

  return {
    registrationHash: registerPending.hash,
    primaryHash: primaryPending.hash,
  };
}

Complete Example: Register and Set Primary (Wallet Adapter)

Here's the same example using the wallet adapter approach:

export async function registerAndSetPrimary(domain: string, years: number = 1) {
  if (!account?.address) throw new Error("No account connected");

  // Step 1: Register the domain
  const { data: registerData } = await aptos.registerName({
    sender: account.address,
    name: domain,
    expiration: {
      policy: "domain",
      years: years as 1, // Currently only 1 year is supported
    },
    transferable: true,
  });

  const registerResult = await signAndSubmitTransaction({
    data: registerData,
  });

  if (!registerResult || typeof registerResult !== "object" || !("hash" in registerResult)) {
    throw new Error("Domain registration failed");
  }

  // Step 2: Set as primary name
  const senderAddress = AccountAddress.fromStringStrict(account.address);
  const { data: primaryData } = await aptos.setPrimaryName({
    sender: senderAddress,
    name: `${domain}.apt`,
  });

  const primaryResult = await signAndSubmitTransaction({
    data: primaryData,
  });

  if (!primaryResult || typeof primaryResult !== "object" || !("hash" in primaryResult)) {
    throw new Error("Setting primary name failed");
  }

  return {
    registrationHash: (registerResult as { hash: string }).hash,
    primaryHash: (primaryResult as { hash: string }).hash,
  };
}