SettleMint
Runbooks

Deploy and mint a bond

Step-by-step guide for creating and minting bond tokens using the DALP TypeScript client.

Bond issuance connects maturity terms, denomination assets, compliance checks, and minting through the Platform API. You create the bond, grant the required roles, unpause the contract, and mint initial supply to investor wallets. Each step below shows the corresponding Platform API call in context.

Rendering diagram...

The diagram traces the path from issuer through the TypeScript client to the Platform API, where bond terms, maturity, compliance checks, and the denomination asset feed the token contract. The contract then supplies bonds to investor wallets.

Prerequisites

Before running these commands, you need:

  1. Your DALP platform URL, such as https://your-platform.example.com
  2. A running DALP instance, local or hosted
  3. A user account created through the Console with email and password
  4. PINCODE set up during onboarding. Manage it from Account → Security.
  5. The admin role on your account to grant system roles in Step 3
  6. A deployed stablecoin contract address for the denomination asset. Create one using the Stablecoin Guide or use an existing address.

Your wallet address is available during DALP signup. Step 2 retrieves it programmatically so you can use it in role grants and minting calls. The stablecoin contract address in item 6 must exist before you run Step 4.


Quick reference

StepWhatSDK call
1Create the clientcreateDalpClient
2Get user infodalp.user.me
3Grant system rolesGrant tokenManager role
4Create bonddalp.token.create, then recover if queued
5Grant token rolesdalp.token.grantRole
6Unpausedalp.token.unpause
7Mint bondsdalp.token.mint
8Verifydalp.token.holders

Bond token lifecycle flow

This diagram shows the complete bond deployment and minting workflow:

Rendering diagram...

The table below lists the bond-specific fields and role requirements.

FieldDescription
denominationAssetStablecoin contract address for redemptions. Required.
faceValueRedemption value per bond at maturity
maturityDateFuture ISO timestamp when bonds become redeemable
System rolesRequires tokenManager before creation
Token rolessupplyManagement for minting; emergency for unpausing

Bond creation in the Asset Designer

Step-by-step commands

Step 1: create the client

Create the DALP SDK client with your platform URL and API key. All subsequent calls use this client instance.

import { createDalpClient } from "@settlemint/dalp-sdk";
import {
  v2TokenCreate,
  v2TokenGrantRole,
  v2TokenHolders,
  v2TokenMint,
  v2TokenUnpause,
  v2UserMe,
} from "@settlemint/dalp-sdk/operations";

async function main() {

Step 2: check that your session has a wallet

  // Replace these placeholders with your actual values
  const client = createDalpClient({
    baseUrl: "https://your-platform.example.com",
    apiKey: "YOUR_API_KEY",
  });
  const pincode = "YOUR_PINCODE";
  const stablecoinAddress = "YOUR_STABLECOIN_CONTRACT_ADDRESS";

Save the wallet address. You use it when you grant token roles and mint the first bond supply.


Step 3: set up system roles

Grant yourself the tokenManager system role before creating the bond. Only users with the admin role can grant system roles. If you do not have admin access, ask your system administrator to grant tokenManager.


Step 4: create the bond token

  }
  console.log("Wallet:", myWallet);

  // Step 3: Set up system roles
  // Follow the Set Up Roles guide to:
  // - Grant yourself 'tokenManager' system role
  // See: /docs/developer-guides/runbooks/setup-roles

  // Step 4: Create bond token
  const bond = (
    await v2TokenCreate({
      client,
      body: {
        type: "bond",
        name: "Test Corporate Bond",
        symbol: "TCBD",
        decimals: 18,
        countryCode: "840",
        cap: "1000000000000000000000000",
        faceValue: "1000000000000000000000",
        maturityDate: "2026-12-31T23:59:59Z",
        denominationAsset: stablecoinAddress,
        initialModulePairs: [],
        walletVerification: {
          secretVerificationCode: pincode,
          verificationType: "PINCODE",

Parameters:

  • type: Must be "bond".
  • name: Bond name, such as "Test Corporate Bond".
  • symbol: Bond symbol, such as "TCBD".
  • decimals: Usually 18 for bonds.
  • countryCode: ISO country code (840 = USA, 056 = Belgium, 276 = Germany).
  • cap: Maximum supply using toBigDecimal("1000000", 18) = 1M bonds.
  • faceValue: Redemption value per bond using toBigDecimal("1000", 18) = 1000 tokens.
  • maturityDate: When the bond matures (ISO string).
  • denominationAsset: Your stablecoin contract address from the stablecoin guide.
  • initialModulePairs: Compliance modules (empty array [] for basic setup).

A synchronous response returns bond data with data.id, the bond contract address. Save this address for the role grant, unpause, mint, and holder checks.

If the response contains transactionId instead of data.id, the request was queued. Poll dalp.transaction.status until the transaction completes. Then call dalp.token.list filtered by name, symbol, and tokenType and save the matching token id as tokenAddress. Production automation must wait for this resolution before continuing.


Step 5: grant token roles

Grant yourself supplyManagement for minting and emergency for unpausing on the bond contract. When you create a token, you automatically receive the admin role and the governance role. You must separately grant supplyManagement and emergency before proceeding.

      },
      throwOnError: true,
    })
  ).data;

  if ("transactionId" in bond) {
    console.log("Bond creation queued:", bond.transactionId);
    return;
  }
  const tokenAddress = bond.data.id;
  console.log("Bond created:", tokenAddress);

  // Step 5: Grant token roles
  (
    await v2TokenGrantRole({
      client,
      path: { tokenAddress },
      body: {
        accounts: [myWallet],
        role: "supplyManagement",
        walletVerification: {
          secretVerificationCode: pincode,
          verificationType: "PINCODE",
        },

The role grant transaction must complete before you proceed to Step 6.


Step 6: unpause the bond

New tokens start paused. Unpause the bond to enable transfers. This step requires the emergency role from Step 5 and a confirmed role-grant transaction.

      throwOnError: true,
    })
  ).data;
  (
    await v2TokenGrantRole({
      client,
      path: { tokenAddress },
      body: {
        accounts: [myWallet],
        role: "emergency",
        walletVerification: {

Step 7: mint bonds

          verificationType: "PINCODE",
        },
      },
      throwOnError: true,
    })
  ).data;
  console.log("Roles granted");

  // Step 6: Unpause the bond
  (
    await v2TokenUnpause({
      client,
      path: { tokenAddress },

Parameters:

  • tokenAddress: Your bond contract address (in path)
  • recipients: Array of recipient wallet address(es)
  • amounts: Array of amounts using toBigDecimal("100", 18) = 100 bonds

The Platform API returns the transaction hash. This step requires the supplyManagement role from Step 5.


Step 8: verify the mint

        walletVerification: {
          secretVerificationCode: pincode,
          verificationType: "PINCODE",

The response shows bond holders with their balances.


Full script

import { createDalpClient } from "@settlemint/dalp-sdk";
import {
  v2TokenCreate,
  v2TokenGrantRole,
  v2TokenHolders,
  v2TokenMint,
  v2TokenUnpause,
  v2UserMe,
} from "@settlemint/dalp-sdk/operations";

async function main() {
  // Step 1: Create the SDK client
  // Replace these placeholders with your actual values
  const client = createDalpClient({
    baseUrl: "https://your-platform.example.com",
    apiKey: "YOUR_API_KEY",
  });
  const pincode = "YOUR_PINCODE";
  const stablecoinAddress = "YOUR_STABLECOIN_CONTRACT_ADDRESS";

  // Step 2: Get your wallet address
  const me = (await v2UserMe({ client, throwOnError: true })).data;
  const myWallet = me.data.wallet;
  if (myWallet === null) {
    throw new Error("No wallet found. Create a wallet first via the DALP dashboard.");
  }
  console.log("Wallet:", myWallet);

  // Step 3: Set up system roles
  // Follow the Set Up Roles guide to:
  // - Grant yourself 'tokenManager' system role
  // See: /docs/developer-guides/runbooks/setup-roles

  // Step 4: Create bond token
  const bond = (
    await v2TokenCreate({
      client,
      body: {
        type: "bond",
        name: "Test Corporate Bond",
        symbol: "TCBD",
        decimals: 18,
        countryCode: "840",
        cap: "1000000000000000000000000",
        faceValue: "1000000000000000000000",
        maturityDate: "2026-12-31T23:59:59Z",
        denominationAsset: stablecoinAddress,
        initialModulePairs: [],
        walletVerification: {
          secretVerificationCode: pincode,
          verificationType: "PINCODE",
        },
      },
      throwOnError: true,
    })
  ).data;

  if ("transactionId" in bond) {
    console.log("Bond creation queued:", bond.transactionId);
    return;
  }
  const tokenAddress = bond.data.id;
  console.log("Bond created:", tokenAddress);

  // Step 5: Grant token roles
  (
    await v2TokenGrantRole({
      client,
      path: { tokenAddress },
      body: {
        accounts: [myWallet],
        role: "supplyManagement",
        walletVerification: {
          secretVerificationCode: pincode,
          verificationType: "PINCODE",
        },
      },
      throwOnError: true,
    })
  ).data;
  (
    await v2TokenGrantRole({
      client,
      path: { tokenAddress },
      body: {
        accounts: [myWallet],
        role: "emergency",
        walletVerification: {
          secretVerificationCode: pincode,
          verificationType: "PINCODE",
        },
      },
      throwOnError: true,
    })
  ).data;
  console.log("Roles granted");

  // Step 6: Unpause the bond
  (
    await v2TokenUnpause({
      client,
      path: { tokenAddress },
      body: {
        walletVerification: {
          secretVerificationCode: pincode,
          verificationType: "PINCODE",
        },
      },
      throwOnError: true,
    })
  ).data;
  console.log("Bond unpaused");

  // Step 7: Mint bonds — 100 bonds
  (
    await v2TokenMint({
      client,
      path: { tokenAddress },
      body: {
        recipients: [myWallet],
        amounts: ["100000000000000000000"],
        walletVerification: {
          secretVerificationCode: pincode,
          verificationType: "PINCODE",
        },
      },
      throwOnError: true,
    })
  ).data;
  console.log("Minted bonds");

  // Step 8: Verify holders
  const holders = (
    await v2TokenHolders({ client, path: { tokenAddress }, query: { page: { limit: "200" } }, throwOnError: true })
  ).data;
  console.log("Holders:", holders.data);
}

await main();

Deployed bond token details

Troubleshooting

ErrorFix
Authentication missingCheck the API key passed to createDalpClient.
PINCODE_INVALIDReconfirm your PINCODE.
USER_NOT_AUTHORIZED / tokenManager requiredGrant the tokenManager role (requires admin access).
Permission deniedGrant the required token roles (supplyManagement, emergency).
Token is pausedConfirm Step 6 (unpause) succeeded and the account holds the emergency role.
Invalid denomination assetVerify your stablecoin contract address from the stablecoin guide.
Maturity date must be in the futureUse a future date.

On this page