Skip to content

The Identity Pallet

Introduction

The Substrate Identity Pallet is an out-of-the-box solution for adding personal information to your on-chain account. Personal information can include default fields such as your legal name, display name, website, Twitter handle, and Riot (now known as Element) name. You can also take advantage of custom fields to include any other relevant information.

The pallet also includes functionality to request judgments and verify on-chain identities from registrars, which are accounts appointed via governance to verify the identity information submitted and provide judgment on their findings for a fee.

This guide will provide an overview of the extrinsics, storage methods, and getters for the pallet constants available in the Identity Pallet on Moonbeam. This guide assumes you are familiar with identity-related terminology; if not, please check out the Managing your Account Identity page for more information.

Identity Pallet Interface

Extrinsics

The Identity Pallet provides the following extrinsics (functions):

addRegistrar(account) - adds an account as a registrar. Must be executed by the General Admin Origin
  • account - the account to add as a registrar
import { ApiPromise, WsProvider } from '@polkadot/api';

const account = INSERT_ACCOUNT;

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.addRegistrar(account);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
addSub(sub, data) - adds an account as a sub-account of the caller. You can optionally provide a name for the sub-account. This function is not callable via a NonTransfer proxy. You can sign the transaction directly or use a different proxy type (Any, IdentityJudgement, etc.)
  • sub - the account to add as a sub-account
  • data - an object that specifies the name of the sub-account, where the key is the data type and the value is the data. You can use any of the following data types to define the name of the sub-account:
    • None - no name should be used
    • Raw - a raw value using hex or ascii
    • BlakeTwo256 - a BLAKE2-256 hash value
    • Sha256 - a SHA-256 value
    • Keccak256 - a Keccak-256 value
    • ShaThree256 - a SHA3-256 value
import { ApiPromise, WsProvider } from '@polkadot/api';

const sub = 'INSERT_SUB_ACCOUNT';
const data = { INSERT_DATA_TYPE: 'INSERT_DATA' };
/* 
        For None, use the following format:
        const data = { 'None': null };

        For all other data types, use the name of the data type
        and the value formatted in that specific type. For example:
        const data = { 'Raw': 'Alice' };
        */

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.addSub(sub, data);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
cancelRequest(regIndex) - cancels the caller's request for judgment from a given registrar
  • regIndex - the index of the registrar
import { ApiPromise, WsProvider } from '@polkadot/api';

const regIndex = 'INSERT_INDEX_OF_REGISTRAR';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.cancelRequest(regIndex);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
clearIdentity() - clears the identity for the caller

None.

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.clearIdentity();
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
killIdentity(target) - removes an account's identity and sub-accounts. Must be executed by the General Admin Origin
  • target - the account to remove the identity and sub-accounts for
import { ApiPromise, WsProvider } from '@polkadot/api';

const target = 'INSERT_TARGET_ACCOUNT';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.killIdentity(target);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
provideJudgement(regIndex, target, judgement, identity) - provides judgment on an account's identity. The caller must be the registrar account that corresponds to the index. Must be executed by a registrar
  • regIndex - the index of the registrar submitting the judgement
  • target - the account to provide the judgment for
  • judgement - the judgement or level of confidence in the identity information provided. There are seven levels of confidence, you can either provide the name or the index of the confidence level:
    • Unknown or 0 - no judgement made yet. This is the default value
    • FeePaid or 1 - indicates a user has requested judgement and it is in progress
    • Reasonable or 2 - the information appears reasonable, but no in-depth checks were performed using legal identity documents
    • KnownGood or 3 - the information is correct and is based upon review of legal identity documents
    • OutOfDate or 4 - the information used to be good, but is now out of date
    • LowQuality or 5 - the information is low quality or imprecise, but can be updated as needed
    • Erroneous or 6 - the information is erroneous and may indicate malicious intent. This state cannot be modified and can only be removed if the entire identity has been removed
  • identity - the 32-byte hash of the identity
import { ApiPromise, WsProvider } from '@polkadot/api';

const regIndex = 'INSERT_REGISTRAR_INDEX';
const target = 'INSERT_TARGET_ACCOUNT';
const judgement = 'INSERT_JUDGEMENT';
const identity = 'INSERT_IDENTITY';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.provideJudgement(
    regIndex,
    target,
    judgement,
    identity
  );
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
quitSub() - removes the caller as a sub-identity account

None.

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.quitSub();
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
removeSub(sub) - removes a sub-identity account for the caller
  • sub - the sub-identity account to remove
import { ApiPromise, WsProvider } from '@polkadot/api';

const sub = 'INSERT_ACCOUNT';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.removeSub(sub);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};
renameSub(sub) - renames a sub-identity account for the caller
  • sub - the sub-identity account to rename
import { ApiPromise, WsProvider } from '@polkadot/api';

const sub = 'INSERT_ACCOUNT';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.rename(sub);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};
requestJudgement(regIndex, maxFee) - requests judgment from a given registrar along with the maximum fee the caller is willing to pay
  • regIndex - the index of the registar to request judgement from
  • maxFee - the maximum fee in Wei that can be paid to the registrar for providing judgement
import { ApiPromise, WsProvider } from '@polkadot/api';

const regIndex = INSERT_REGISTRAR_INDEX;
const maxFee = INSERT_MAX_FEE;

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.requestJudgement(regIndex, maxFee);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
setAccountId(index, new) - sets a new account for an existing registrar. Must be executed by the registrar account that corresponds to the index.
  • index - the index of the registrar
  • new - the account to set as the registrar's new account
import { ApiPromise, WsProvider } from '@polkadot/api';

const index = INSERT_REGISTRAR_INDEX;
const newAccount = 'INSERT_NEW_ACCOUNT';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.setAccountId(index, newAccount);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
setFee(index, fee) - sets the fee for a registar. Must be executed by the registrar account that corresponds to the index
  • index - the index of the registrar
  • fee - the fee in Wei required to be paid to the registrar for a judgement
import { ApiPromise, WsProvider } from '@polkadot/api';

const index = INSERT_REGISTRAR_INDEX;
const fee = INSERT_FEE;

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.setFee(index, fee);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
setFields(index, fields) - sets the fields that a registrar cares about when providing judgements. Must be executed by the registrar account that corresponds to the index
  • index - the index of the registrar
  • fields - an array of the fields that the registrar cares about. The fields can be any of the following:
    • Display - a display name
    • Legal - a legal name
    • Web - a website
    • Riot - a Riot username
    • Email - an email address
    • PpgFingerprint - a PPG fingerprint
    • Image - an image
    • Twitter - a Twitter username
import { ApiPromise, WsProvider } from '@polkadot/api';

const index = INSERT_REGISTRAR_INDEX;
const fields = [INSERT_FIELDS];

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.setFields(index, fields);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
setIdentity(info) - sets the identity for the caller
  • info - the identity information. The identity information can include any of the following optional fields:
    • display - a display name
    • legal - a legal name
    • web - a website
    • riot - a Riot username
    • email - an email address
    • ppgFingerprint - a PPG fingerprint
    • image - an image
    • twitter - a Twitter username
    • additional - an array that contains custom fields for additional information. Each additional item is represented as an array that contains two objects: one for the field name and one for the field value. You can define the additional field names and values in the following formats:
      • None - no additional information should be used
      • Raw - a raw value using hex or ascii
      • BlakeTwo256 - a BLAKE2-256 hash value
      • Sha256 - a SHA-256 value
      • Keccak256 - a Keccak-256 value
      • ShaThree256 - a SHA3-256 value

When setting an identity, a deposit is required. If setting additional fields, an additional deposit will be required per each additional field. For more information, please refer to the Manage an Identity documentation.

import { ApiPromise, WsProvider } from '@polkadot/api';

/*
        Add as many or as few fields as you would like
        */
const info = {
  display: 'INSERT_DISPLAY_NAME',
  legal: 'INSERT_LEGAL_NAME',
  additional: [[{ Raw: 'Discord' }, { Raw: 'INSERT_DISCORD_USERNAME' }]],
};

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.setIdentity(info);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();
setSubs(subs) - sets the sub-accounts for the caller. This function is not callable via a NonTransfer proxy. You can sign the transaction directly or use a different proxy type (Any, IdentityJudgement, etc.)
  • subs - an array that defines the sub-accounts. Each sub-account is represented as an array itself, with the address of the sub-account as the zero index and the name as the first index. The name is an object that can be defined in the following formats:
    • None - no additional information should be used
    • Raw - a raw value using hex or ascii
    • BlakeTwo256 - a BLAKE2-256 hash value
    • Sha256 - a SHA-256 value
    • Keccak256 - a Keccak-256 value
    • ShaThree256 - a SHA3-256 value
import { ApiPromise, WsProvider } from '@polkadot/api';

const subs = [
  [INSERT_ACCOUNT, { Raw: 'INSERT_SUB_ACCOUNT_NAME' }],
  [INSERT_ACCOUNT, { None: null }],
];

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('INSERT_WSS_ENDPOINT'),
  });

  const tx = api.tx.identity.setSubs(subs);
  const txHash = await tx.signAndSend('INSERT_ACCOUNT_OR_KEYRING');

  api.disconnect();
};

main();

Storage Methods

The Identity Pallet includes the following read-only storage methods to obtain chain state data:

authorityOf(account) – returns authority properties for a given account
  • account – the 20-byte account ID (AccountId20) you want to inspect.

An Option<PalletIdentityAuthorityProperties>

If the supplied account is not a username-granting authority, the call returns null.

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  // Connect to Moonbase
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-rpc.dwellir.com'),
  });

  // --- OPTION 1: Check a single account ----------------------
  // const account = '0x1234...';  // AccountId20 as hex
  // const infoOpt = await api.query.identity.authorityOf(account);
  // console.log(infoOpt.isSome ? infoOpt.unwrap().toHuman() : 'Not an authority');

  // --- OPTION 2: List *all* registered authorities -----------
  const entries = await api.query.identity.authorityOf.entries();

  if (entries.length === 0) {
    console.log('No authority accounts are registered.');
  } else {
    console.log(`Found ${entries.length} authority account(s):\n`);
    for (const [storageKey, optProps] of entries) {
      if (optProps.isSome) {
        const account = storageKey.args[0].toString();
        const { allowAutoClaim, deposit, provider } = optProps.unwrap();

        console.log(`• ${account}`);
        console.log(`    allowAutoClaim : ${allowAutoClaim.toString()}`);
        console.log(`    deposit        : ${deposit.toString()}`);
        console.log(`    provider       : ${provider.toString()}\n`);
      }
    }
  }

  await api.disconnect();
};

main().catch(console.error);
identityOf(account) - returns identity information for a given account
  • account - the account to get identity information for

Identity information for the given account, including judgments (if the account has requested a judgment from a registrar), the deposit is held for the identity and the identity information. If the account does not have an identity set, null is returned.

// If using Polkadot.js API and calling toJSON() on the query results
{
  judgements: [],
  deposit: '0x00000000000000000e53d254821d0000',
  info: {
    additional: [ [Array] ],
    display: { raw: '0x416c697468' },
    legal: { none: null },
    web: { none: null },
    riot: { none: null },
    email: { raw: '0x616c69746840616c6974682e636f6d' },
    pgpFingerprint: null,
    image: { none: null },
    twitter: { none: null }
  }
}
import { ApiPromise, WsProvider } from '@polkadot/api';

// Helper function to decode hex to string
const hexToString = (hex) => {
  // Remove '0x' prefix if present
  const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex;
  // Convert hex to string
  const str = Buffer.from(cleanHex, 'hex').toString('utf8');
  return str;
};

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    const account = 'INSERT_ACCOUNT';
    const identity = await api.query.identity.identityOf(account);

    console.log('Raw identity response:', identity.toString());

    if (identity) {
      // Parse the raw response
      const rawResponse = JSON.parse(identity.toString());

      if (rawResponse[0]) {
        const formattedIdentity = {
          judgements: rawResponse[0].judgements,
          deposit: rawResponse[0].deposit,
          info: {
            additional: rawResponse[0].info.additional,
            display: rawResponse[0].info.display.raw
              ? hexToString(rawResponse[0].info.display.raw)
              : null,
            legal: rawResponse[0].info.legal,
            web: rawResponse[0].info.web,
            riot: rawResponse[0].info.riot,
            email: rawResponse[0].info.email,
            pgpFingerprint: rawResponse[0].info.pgpFingerprint,
            image: rawResponse[0].info.image,
            twitter: rawResponse[0].info.twitter,
          },
        };

        console.log(
          'Formatted Identity:',
          JSON.stringify(formattedIdentity, null, 2)
        );
      } else {
        console.log('No identity data found in the response');
      }
    } else {
      console.log('No identity found for this account');
    }
  } catch (error) {
    console.error('Error querying identity:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
palletVersion() - returns the current pallet version

None

The version of the pallet, e.g. 1

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  // Create the API instance
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  // Query the identity pallet version
  const version = await api.query.identity.palletVersion();

  // Log the version to console
  console.log('Identity Pallet Version:', version.toString());

  // Disconnect from the API
  await api.disconnect();
};

main().catch(console.error);
pendingUsernames(username) - returns information for a pending username
  • username – the username to query.
    Pass it as a Bytes value (hex-encoded or plain ASCII).

An Option that is:

  • null – if the username is not pending, or
  • (AccountId20, u32, PalletIdentityProvider) – when pending, where
    • AccountId20 is the account that has been offered the username
    • u32 is the block number deadline by which the account must accept it
    • PalletIdentityProvider is the authority that issued the username
import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  // Connect to a Moonbase RPC endpoint
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-rpc.dwellir.com'),
  });

  // Fetch *all* [StorageKey, Option<(AccountId20, u32, PalletIdentityProvider)>] pairs
  const entries = await api.query.identity.pendingUsernames.entries();

  if (entries.length === 0) {
    console.log('There are no pending usernames right now.');
  } else {
    console.log(`Found ${entries.length} pending username(s):\n`);
    for (const [storageKey, optValue] of entries) {
      if (optValue.isSome) {
        const [account, deadline, provider] = optValue.unwrap();

        // The username itself is part of the storage key after the 32-byte hash prefix
        // api.registry.createType('Bytes', rawBytes) makes it human-readable
        const raw = storageKey.args[0];               // Bytes
        const username = api.registry.createType('Bytes', raw).toUtf8();

        console.log(`• ${username}`);
        console.log(`    owner   : ${account.toString()}`);
        console.log(`    expires : block ${deadline.toNumber()}`);
        console.log(`    provider: ${provider.toString()}\n`);
      }
    }
  }

  await api.disconnect();
};

main().catch(console.error);
registrars() - returns the set of registrars

None

The set of registrators as a vector

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  // Create the API instance
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  // Query the registrars
  const registrars = await api.query.identity.registrars();

  // Format and log the registrars data
  const formattedRegistrars = registrars
    .map((reg) => {
      if (!reg.isSome) return null;
      const { account, fee, fields } = reg.unwrap();
      return {
        account: account.toString(),
        fee: fee.toHuman(),
        fields: fields.toNumber(),
      };
    })
    .filter((reg) => reg !== null);

  console.log('Registrars:', JSON.stringify(formattedRegistrars, null, 2));

  // Disconnect from the API
  await api.disconnect();
};

main().catch(console.error);
subsOf(AccountId20) - returns the sub-identities for all accounts or a given account
  • AccountId20 the account to check the sub-identities for

The sub-identities, if any.

Raw subs response: [0,[]]
    Formatted Subs: {
      "deposit": "0",
      "subAccounts": []
    }
    Number of sub-accounts: 0
import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    const account = 'INSERT_ACCOUNT';
    const subs = await api.query.identity.subsOf(account);

    // Log raw response for debugging
    console.log('Raw subs response:', subs.toString());

    if (subs) {
      // The response includes a tuple of [deposit, accounts]
      const [deposit, subAccounts] = subs;

      const formattedSubs = {
        deposit: deposit.toHuman(),
        subAccounts: subAccounts.toHuman(),
      };

      console.log('Formatted Subs:', JSON.stringify(formattedSubs, null, 2));
      console.log('Number of sub accounts:', subAccounts.length);
    } else {
      console.log('No sub identities found for this account');
    }
  } catch (error) {
    console.error('Error querying sub identities:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
superOf(AccountId20) - returns the super identity of all sub-accounts or for a given sub-account
  • AccountId20 - the account to check the super identities of

The super identities, if any.

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    const account = 'INSERT_ACCOUNT';
    const superOf = await api.query.identity.superOf(account);

    // Log raw response for debugging
    console.log('Raw superOf response:', superOf.toString());

    if (superOf.isSome) {
      // The response includes a tuple of [parentAccount, dataName]
      const [parentAccount, dataName] = superOf.unwrap();

      const formattedSuper = {
        parentAccount: parentAccount.toString(),
        dataName: dataName.toHuman(),
      };

      console.log(
        'Formatted Super Identity:',
        JSON.stringify(formattedSuper, null, 2)
      );
    } else {
      console.log('This account is not a sub-identity of any other account');
    }
  } catch (error) {
    console.error('Error querying super identity:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
unbindingUsernames(username) – returns the block height at which a username being revoked will be released
  • username – the username to inspect, supplied as Bytes (plain ASCII or hex).

An Option<u32>: it is null when the username is not in the unbinding process; otherwise it contains the block number after which the username becomes free to claim again.

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  // Connect to Moonbase
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-rpc.dwellir.com'),
  });

  // Fetch every (StorageKey, Option<u32>) pair
  const entries = await api.query.identity.unbindingUsernames.entries();

  if (entries.length === 0) {
    console.log('There are no usernames in the unbinding process.');
  } else {
    console.log(`Found ${entries.length} unbinding username(s):\n`);
    for (const [storageKey, optBlock] of entries) {
      if (optBlock.isSome) {
        // The username itself is the single argument encoded in the storage key
        const rawUsername = storageKey.args[0];
        const username = api.registry.createType('Bytes', rawUsername).toUtf8();

        const releaseBlock = optBlock.unwrap().toNumber();
        console.log(`${username} → releases at block ${releaseBlock}`);
      }
    }
  }

  await api.disconnect();
};

main().catch(console.error);
usernameInfoOf(username) – returns information for a given username
  • username – the username to look up.
    Supply it as a Bytes value (plain ASCII or hex).

An AccountId20 of the Account currently bound to the username and a provider value, i.e., the authority that issued the username.

If the username is unregistered, the call returns null.

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  // Connect to Moonbase-Alpha
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-rpc.dwellir.com'),
  });

  // Username to query (ASCII automatically wrapped as Bytes)
  const username = api.registry.createType('Bytes', 'alice');

  // Fetch username information
  const infoOpt = await api.query.identity.usernameInfoOf(username);

  if (infoOpt.isSome) {
    const { owner, provider } = infoOpt.unwrap();

    console.log(`Username          : ${username.toUtf8()}`);
    console.log(`  Owner account   : ${owner.toString()}`);
    console.log(`  Issued by       : ${provider.toString()}`);
  } else {
    console.log('Username is not registered.');
  }

  await api.disconnect();
};

main().catch(console.error);
usernameOf(account) – returns the primary username bound to an account
  • account – the AccountId20 you want to query.

Returns an Option<Bytes>: it is null when the account has no primary username; otherwise, it contains a Bytes value with the UTF-8 (or hex-encoded) string of the account’s primary username.

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  // Connect to Moonbase
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-rpc.dwellir.com'),
  });

  // Replace with any AccountId20 you wish to inspect
  const account = 'INSERT_ACCOUNT';

  // Query the storage item
  const usernameOpt = await api.query.identity.usernameOf(account);

  if (usernameOpt.isSome) {
    // Convert Bytes → UTF-8 for readability
    const username = usernameOpt.unwrap().toUtf8();
    console.log(`Primary username for ${account}: ${username}`);
  } else {
    console.log(`Account ${account} has no primary username set.`);
  }

  await api.disconnect();
};

main().catch(console.error);

Pallet Constants

The Identity Pallet includes the following read-only functions to obtain pallet constants:

basicDeposit() - returns the amount held on deposit for a registered identity

None

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    // Query the basicDeposit constant
    const basicDeposit = api.consts.identity.basicDeposit;

    // Log raw response for debugging
    console.log('Raw basicDeposit response:', basicDeposit.toString());

    // Format the deposit amount
    console.log('Basic Deposit (formatted):', basicDeposit.toHuman());
  } catch (error) {
    console.error('Error querying basic deposit:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
Raw basicDeposit response: 1025800000000000000
Basic Deposit (formatted): 1,025,800,000,000,000,000
byteDeposit() - returns the amount held on deposit per additional bytes of data for a registered identity

None

import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    // Query the byteDeposit constant
    const byteDeposit = api.consts.identity.byteDeposit;

    // Log raw response for debugging
    console.log('Raw byteDeposit response:', byteDeposit.toString());

    // Format the deposit amount
    console.log('Byte Deposit (formatted):', byteDeposit.toHuman());
  } catch (error) {
    console.error('Error querying byte deposit:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
Raw byteDeposit response: 100000000000000
Byte Deposit (formatted): 100,000,000,000,000
maxRegistrars() - returns the maximum number of registrars allowed in the system

None

  • u32 - Maximum number of registrars allowed
import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    // Query the maxRegistrars constant
    const maxRegistrars = api.consts.identity.maxRegistrars;

    // Get the number as a plain integer
    console.log('Max Registrars (number):', maxRegistrars.toNumber());
  } catch (error) {
    console.error('Error querying max registrars:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
maxSubAccounts() - returns the maximum number of sub-accounts allowed per account

None

  • u32 - Maximum number of sub-accounts allowed per identity
import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    const maxSubAccounts = api.consts.identity.maxSubAccounts;
    console.log('Max SubAccounts (number):', maxSubAccounts.toNumber());
  } catch (error) {
    console.error('Error querying max subaccounts:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
subAccountDeposit() - returns the amount held on deposit for a registered sub-account

None

  • Balance - Amount of currency held on deposit for a sub-account
import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    const subAccountDeposit = api.consts.identity.subAccountDeposit;
    console.log('SubAccount Deposit:', subAccountDeposit.toHuman());
  } catch (error) {
    console.error('Error querying subaccount deposit:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
pendingUsernameExpiration() - returns the time period for which a username remains pending

None

  • BlockNumber - Number of blocks before a pending username expires
import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    // Query the pendingUsernameExpiration constant from identity pallet
    const pendingExpiration = api.consts.identity.pendingUsernameExpiration;
    console.log('Pending Username Expiration:', pendingExpiration.toHuman());
  } catch (error) {
    console.error('Error querying pending username expiration:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
maxSuffixLength() - returns the maximum length allowed for a username suffix

None

  • u32 - Maximum number of characters allowed in a username suffix
import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    const maxSuffixLength = api.consts.identity.maxSuffixLength;
    console.log('Max Suffix Length:', maxSuffixLength.toHuman());
  } catch (error) {
    console.error('Error querying max suffix length:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
maxUsernameLength() - returns the maximum length allowed for a username

None

  • u32 - Maximum number of characters allowed in a username
import { ApiPromise, WsProvider } from '@polkadot/api';

const main = async () => {
  const api = await ApiPromise.create({
    provider: new WsProvider('wss://moonbase-alpha.public.blastapi.io'),
  });

  try {
    const maxUsernameLength = api.consts.identity.maxUsernameLength;
    console.log('Max Username Length:', maxUsernameLength.toHuman());
  } catch (error) {
    console.error('Error querying max username length:', error);
  } finally {
    await api.disconnect();
  }
};

main().catch((error) => {
  console.error('Script error:', error);
  process.exit(1);
});
Last update: June 17, 2025
| Created: September 15, 2023