# Deploy and mint a bond

Source: https://docs.settlemint.com/docs/developers/runbooks/create-mint-bonds
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.

<Mermaid
  chart="`
flowchart TD
Issuer[&#x22;Bond issuer&#x22;] --> Client[&#x22;TypeScript client&#x22;]
Client --> API[&#x22;DALP asset API&#x22;]
API --> Terms[&#x22;Bond terms and maturity&#x22;]
API --> Compliance[&#x22;Identity and compliance checks&#x22;]
API --> Denomination[&#x22;Denomination asset&#x22;]
Terms --> Contract[&#x22;Bond token contract&#x22;]
Contract --> Investor[&#x22;Investor wallet supply&#x22;]
`"
/>

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 [#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 → Wallet**.
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](/docs/developers/runbooks/create-mint-stablecoins) 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 [#quick-reference]

| Step | What               | SDK call                                    |
| ---- | ------------------ | ------------------------------------------- |
| 1    | Create the client  | `createDalpClient`                          |
| 2    | Get user info      | `dalp.user.me`                              |
| 3    | Grant system roles | Grant `tokenManager` role                   |
| 4    | Create bond        | `dalp.token.create`, then recover if queued |
| 5    | Grant token roles  | `dalp.token.grantRole`                      |
| 6    | Unpause            | `dalp.token.unpause`                        |
| 7    | Mint bonds         | `dalp.token.mint`                           |
| 8    | Verify             | `dalp.token.holders`                        |

***

## Bond token lifecycle flow [#bond-token-lifecycle-flow]

This diagram shows the complete bond deployment and minting workflow:

<Mermaid
  chart="`flowchart TB
  Init[Create Client<br/>createDalpClient] --> Auth[Read Wallet<br/>dalp.user.me]
  Auth --> Roles[Set Up System Roles<br/>tokenManager]
  Roles --> Create[Create Bond Token<br/>dalp.token.create]
  Create --> Config[Bond Configuration:<br/>denominationAsset<br/>faceValue<br/>maturityDate]
  Config --> Queued{Queued response?}
  Queued -->|transactionId| Recover[Poll transaction status<br/>then locate token]
  Queued -->|data.id| Grant[Grant Token Roles<br/>dalp.token.grantRole]
  Recover --> Grant
  Grant --> Unpause[Unpause Token<br/>dalp.token.unpause]
  Unpause --> Mint[Mint Bonds<br/>dalp.token.mint]
  Mint --> Verify[Verify Holders<br/>dalp.token.holders]
  
  style Init fill:#5fc9bf,stroke:#3a9d96,stroke-width:2px,color:#fff
  style Auth fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style Roles fill:#6ba4d4,stroke:#4a7ba8,stroke-width:2px,color:#fff
  style Create fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style Config fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style Grant fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style Unpause fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style Mint fill:#8571d9,stroke:#654bad,stroke-width:2px,color:#fff
  style Verify fill:#b661d9,stroke:#8a3fb3,stroke-width:2px,color:#fff
`"
/>

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

| Field               | Description                                               |
| ------------------- | --------------------------------------------------------- |
| `denominationAsset` | Stablecoin contract address for redemptions. Required.    |
| `faceValue`         | Redemption value per bond at maturity                     |
| `maturityDate`      | Future ISO timestamp when bonds become redeemable         |
| System roles        | Requires `tokenManager` before creation                   |
| Token roles         | `supplyManagement` for minting; `emergency` for unpausing |

***

![Bond creation in the Asset Designer](/docs/screenshots/asset-designer/design-bond-1.webp)

## Step-by-step commands [#step-by-step-commands]

### Step 1: create the client [#step-1-create-the-client]

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

```ts file=<rootDir>/src/examples/create-mint-bond.ts#L1-L11
import { createDalpClient } from "@settlemint/dalp-sdk";

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

***

### Step 2: check that your session has a wallet [#step-2-check-that-your-session-has-a-wallet]

```ts file=<rootDir>/src/examples/create-mint-bond.ts#L13-L19
  // Step 2: Get your wallet address
  const me = await dalp.user.me({});
  const myWallet = me.data.wallet;
  if (!myWallet) {
    throw new Error("No wallet found. Create a wallet first via the DALP dashboard.");
  }
  console.log("Wallet:", myWallet);
```

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

***

### Step 3: set up system roles [#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 [#step-4-create-the-bond-token]

```ts file=<rootDir>/src/examples/create-mint-bond.ts#L26-L51
  // Step 4: Create bond token
  const bond = await dalp.token.create({
    body: {
      type: "bond",
      name: "Test Corporate Bond",
      symbol: "TCBD",
      decimals: 18,
      countryCode: "840",
      cap: 1_000_000_000_000_000_000_000_000n,
      faceValue: 1_000_000_000_000_000_000_000n,
      maturityDate: new Date("2026-12-31T23:59:59Z").toISOString(),
      denominationAsset: stablecoinAddress,
      initialModulePairs: [],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });

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

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](/docs/developers/runbooks/create-mint-stablecoins).
* `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 [#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.

```ts file=<rootDir>/src/examples/create-mint-bond.ts#L53-L76
  // Step 5: Grant token roles
  await dalp.token.grantRole({
    params: { tokenAddress },
    body: {
      accounts: [myWallet],
      role: "supplyManagement",
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  await dalp.token.grantRole({
    params: { tokenAddress },
    body: {
      accounts: [myWallet],
      role: "emergency",
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Roles granted");
```

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

***

### Step 6: unpause the bond [#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.

```ts file=<rootDir>/src/examples/create-mint-bond.ts#L78-L88
  // Step 6: Unpause the bond
  await dalp.token.unpause({
    params: { tokenAddress },
    body: {
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Bond unpaused");
```

***

### Step 7: mint bonds [#step-7-mint-bonds]

```ts file=<rootDir>/src/examples/create-mint-bond.ts#L90-L102
  // Step 7: Mint bonds — 100 bonds
  await dalp.token.mint({
    params: { tokenAddress },
    body: {
      recipients: [myWallet],
      amounts: [100_000_000_000_000_000_000n],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Minted bonds");
```

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 [#step-8-verify-the-mint]

```ts file=<rootDir>/src/examples/create-mint-bond.ts#L104-L106
  // Step 8: Verify holders
  const holders = await dalp.token.holders({ params: { tokenAddress }, query: { limit: 200 } });
  console.log("Holders:", holders.data);
```

The response shows bond holders with their balances.

***

## Full script [#full-script]

```ts file=<rootDir>/src/examples/create-mint-bond.ts
import { createDalpClient } from "@settlemint/dalp-sdk";

async function main() {
  // Step 1: Create the SDK client
  // Replace these placeholders with your actual values
  const dalp = createDalpClient({
    url: "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 dalp.user.me({});
  const myWallet = me.data.wallet;
  if (!myWallet) {
    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 dalp.token.create({
    body: {
      type: "bond",
      name: "Test Corporate Bond",
      symbol: "TCBD",
      decimals: 18,
      countryCode: "840",
      cap: 1_000_000_000_000_000_000_000_000n,
      faceValue: 1_000_000_000_000_000_000_000n,
      maturityDate: new Date("2026-12-31T23:59:59Z").toISOString(),
      denominationAsset: stablecoinAddress,
      initialModulePairs: [],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });

  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 dalp.token.grantRole({
    params: { tokenAddress },
    body: {
      accounts: [myWallet],
      role: "supplyManagement",
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  await dalp.token.grantRole({
    params: { tokenAddress },
    body: {
      accounts: [myWallet],
      role: "emergency",
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Roles granted");

  // Step 6: Unpause the bond
  await dalp.token.unpause({
    params: { tokenAddress },
    body: {
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Bond unpaused");

  // Step 7: Mint bonds — 100 bonds
  await dalp.token.mint({
    params: { tokenAddress },
    body: {
      recipients: [myWallet],
      amounts: [100_000_000_000_000_000_000n],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Minted bonds");

  // Step 8: Verify holders
  const holders = await dalp.token.holders({ params: { tokenAddress }, query: { limit: 200 } });
  console.log("Holders:", holders.data);
}

await main();
```

***

![Deployed bond token details](/docs/screenshots/bonds/bonds-detail-1.webp)

## Troubleshooting [#troubleshooting]

| Error                                           | Fix                                                                                                                     |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `Authentication missing`                        | Check the API key passed to `createDalpClient`.                                                                         |
| `PINCODE_INVALID`                               | Reconfirm your PINCODE.                                                                                                 |
| `USER_NOT_AUTHORIZED` / `tokenManager required` | Grant the `tokenManager` role (requires admin access).                                                                  |
| `Permission denied`                             | Grant the required token roles (`supplyManagement`, `emergency`).                                                       |
| `Token is paused`                               | Confirm Step 6 (unpause) succeeded and the account holds the `emergency` role.                                          |
| `Invalid denomination asset`                    | Verify your stablecoin contract address from the [stablecoin guide](/docs/developers/runbooks/create-mint-stablecoins). |
| `Maturity date must be in the future`           | Use a future date.                                                                                                      |
