Skip to main content

Create a Decentralized Identity

If you want to benefit from Self-Sovereign Identity, you need to create a Decentralized Identity. This identity consists of many parts that have different functions. This page will cover the basics about identity creation and publishing.

Identity Generation Process

  1. The generation of an identity requires a address with funds to cover the Storage Deposit. In test networks, a faucet can be used to request funds.
  2. Create the content of the DID Document, a minimal document contains one verification method.
  3. Construct a new Alias Output that includes the DID Document in the State Metadata.
  4. Publish the generated Alias Output.

The DID is only known once the Alias Output is successfully published, since the DID's Tag contains the Alias ID.

See the example below to create an identity in Rust or Node.js.

As this page is a simple overview about creating an identity, further wiki pages are available for more in-depth explanation. Note that the Iota Identity Framework follows IOTA DID Method Specification.

// Copyright 2020-2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { Client, MnemonicSecretManager, SecretManager } from "@iota/client-wasm/node";
import { Bip39 } from "@iota/crypto.js";
import {
} from "@iota/identity-wasm/node";
import { Bech32Helper, IAliasOutput } from "@iota/iota.js";
import { API_ENDPOINT, ensureAddressHasFunds } from "../util";

/** Demonstrate how to create a DID Document and publish it in a new Alias Output. */
export async function createIdentity(): Promise<{
didClient: IotaIdentityClient;
secretManager: SecretManager;
walletAddressBech32: string;
did: IotaDID;
}> {
const client = new Client({
primaryNode: API_ENDPOINT,
localPow: true,
const didClient = new IotaIdentityClient(client);

// Get the Bech32 human-readable part (HRP) of the network.
const networkHrp: string = await didClient.getNetworkHrp();

// Generate a random mnemonic for our wallet.
const secretManager: MnemonicSecretManager = {
mnemonic: Bip39.randomMnemonic(),
const walletAddressBech32 = (await client.generateAddresses(secretManager, {
accountIndex: 0,
range: {
start: 0,
end: 1,
console.log("Wallet address Bech32:", walletAddressBech32);

// Request funds for the wallet, if needed - only works on development networks.
await ensureAddressHasFunds(client, walletAddressBech32);

// Create a new DID document with a placeholder DID.
// The DID will be derived from the Alias Id of the Alias Output after publishing.
const document = new IotaDocument(networkHrp);

// Insert a new Ed25519 verification method in the DID document.
let keypair = new KeyPair(KeyType.Ed25519);
let method = new VerificationMethod(, keypair.type(), keypair.public(), "#key-1");
document.insertMethod(method, MethodScope.VerificationMethod());

// Construct an Alias Output containing the DID document, with the wallet address
// set as both the state controller and governor.
const address = Bech32Helper.addressFromBech32(walletAddressBech32, networkHrp);
const aliasOutput: IAliasOutput = await didClient.newDidOutput(address, document);
console.log("Alias Output:", JSON.stringify(aliasOutput, null, 2));

// Publish the Alias Output and get the published DID document.
const published = await didClient.publishDidOutput(secretManager, aliasOutput);
console.log("Published DID document:", JSON.stringify(published, null, 2));

return {