# Deploy and mint a deposit

Source: https://docs.settlemint.com/docs/developers/runbooks/create-mint-deposits
Create a deposit token, handle queued creation responses, grant token roles,
unpause it, and mint deposit certificates with the DALP TypeScript SDK.




Deposit issuance turns a deposit product into an ERC-3643-style asset workflow: create the token, handle a queued creation response when one is returned, assign the operating roles, unpause the contract, then mint deposit certificates to registered wallets.

<Mermaid
  chart="`
flowchart TD
Issuer[&#x22;Deposit issuer&#x22;] --> Client[&#x22;TypeScript client&#x22;]
Client --> API[&#x22;DALP asset API&#x22;]
API --> Template[&#x22;Deposit token template&#x22;]
API --> Compliance[&#x22;Identity and compliance checks&#x22;]
API --> Queue[&#x22;Transaction queue when creation is asynchronous&#x22;]
API --> Denomination[&#x22;Denomination asset&#x22;]
Queue --> Template
Template --> Contract[&#x22;Deposit token contract&#x22;]
Contract --> Investor[&#x22;Investor wallet supply&#x22;]
`"
/>

## Prerequisites [#prerequisites]

Before running these commands, you need:

1. Your DALP platform URL, such as `https://your-platform.example.com`
2. An API key for the user that will create and operate the deposit token
3. PINCODE set up during onboarding. Manage it from **Account → Wallet**.
4. Admin access if you need to grant yourself system roles
5. The `tokenManager` system role granted before creating the deposit token
6. The issuer wallet and each recipient wallet registered in the identity registry before minting
7. Deposit product terms: denomination asset, decimals, price currency, base price, term length, and any early withdrawal policy you need to operate outside this minting flow

Your wallet address is returned by `dalp.user.me`. Set `decimals` to match the denomination asset you plan to use for accounting, then provide `priceCurrency` and `basePrice` so treasury and liability views can value the certificates consistently.

***

## Quick reference [#quick-reference]

| Step | What                      | Method                                  |
| ---- | ------------------------- | --------------------------------------- |
| 1    | Create SDK client         | `createDalpClient`                      |
| 2    | Get wallet address        | `dalp.user.me`                          |
| 3    | Grant system roles        | Grant `tokenManager` role               |
| 4    | Create deposit token      | `dalp.token.create` (type: `"deposit"`) |
| 5    | Grant token roles         | `dalp.token.grantRole`                  |
| 6    | Unpause                   | `dalp.token.unpause`                    |
| 7    | Mint deposit certificates | `dalp.token.mint`                       |
| 8    | Verify holders            | `dalp.token.holders`                    |

***

## Deposit token lifecycle flow [#deposit-token-lifecycle-flow]

The minting flow is intentionally linear. Do not mint until the token exists, the required token roles are granted, and the recipient identity is registered.

<Mermaid
  chart="`flowchart TB
  Init[Create SDK client<br/>createDalpClient] --> Auth[Read current user<br/>dalp.user.me]
  Auth --> Roles[Set Up System Roles<br/>+ Register Identity]
  Roles --> Create[Create Deposit Token<br/>POST /token/create]
  Create --> Queued{Queued response?}
  Queued -->|No| Config[Use token id]
  Queued -->|Yes| Status[Poll transaction status<br/>then list tokens]
  Status --> Config[Use token id]
  Config --> Grant[Grant Token Roles<br/>POST /token/:address/grant-role]
  Grant --> Unpause[Unpause Token<br/>PUT /token/:address/unpause]
  Unpause --> Mint[Mint Certificates<br/>POST /token/:address/mint]
  Mint --> Verify[Verify Holders<br/>GET /token/:address/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
`"
/>

Deposit-specific requirements:

| Requirement           | Detail                                                                                                            |
| --------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Identity registration | Register the issuer wallet and recipient wallets in the identity registry. Unregistered recipients fail the mint. |
| Decimal match         | Set token decimals to match the denomination asset you use for accounting.                                        |
| Liability tracking    | Set `priceCurrency` and `basePrice` on creation for treasury and liability views.                                 |
| System role           | Hold `tokenManager` to create the token.                                                                          |
| Token roles           | Hold `supplyManagement` to mint and `emergency` to unpause.                                                       |
| Queued creation       | Resolve a returned `transactionId` before granting token roles.                                                   |

***

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

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

Create the DALP SDK client with your platform URL and API key. Keep the PINCODE available for wallet verification on the write calls.

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

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

<details>
  <summary>
    <strong>Client helper implementation</strong>
  </summary>

  The shared client helper configures the generated DALP SDK client with your API key. Implementation:

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

  // Create the SDK client — replace with your actual values
  const dalp = createDalpClient({
    url: "https://your-platform.example.com",
    apiKey: "sm_dalp_xxxxxxxxxxxxxxxx",
  });

  // All methods are fully typed with auto-complete
  const me = await dalp.user.me({});
  console.log("Wallet:", me.data.wallet);

  const tokens = await dalp.token.list({ query: {} });
  console.log("Tokens:", tokens.data.length);
  ```
</details>

***

### Step 2: get your wallet address [#step-2-get-your-wallet-address]

```ts file=<rootDir>/src/examples/create-mint-deposit.ts#L11-L17
  // 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 your wallet address. You use it for identity registration, token role grants, and the first mint in this example.

***

### Step 3: set up system roles [#step-3-set-up-system-roles]

Complete the role and identity setup before calling `dalp.token.create`.

Grant the `tokenManager` system role. Optionally grant `claimPolicyManager` or `complianceManager` if you plan to automate collateral attestation or custom compliance. Only users with the `admin` role can grant system roles. If you do not have admin access, ask your system administrator.

Register your wallet address in the identity registry using `dalp.system.identity.create`. Do the same for any other recipient wallet you plan to mint to. An unregistered recipient causes the mint call to fail.

***

### Step 4: create deposit token [#step-4-create-deposit-token]

```ts file=<rootDir>/src/examples/create-mint-deposit.ts#L25-L48
  // Step 4: Create deposit token
  const deposit = await dalp.token.create({
    body: {
      type: "deposit",
      name: "12M USD CD",
      symbol: "CD12",
      decimals: 18,
      countryCode: "840",
      priceCurrency: "USD",
      basePrice: "1.00",
      initialModulePairs: [],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });

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

Parameters:

* `type`: Must be `"deposit"`.
* `name`: Deposit name, such as `"12M USD CD"`.
* `symbol`: Deposit symbol, such as `"CD12"`.
* `decimals`: Match the denomination asset decimals (see "Denomination asset selection" in the deposit guide).
* `countryCode`: ISO country code (840 = USA, 056 = Belgium, 276 = Germany).
* `priceCurrency`: ISO currency code, such as `"USD"`.
* `basePrice`: Fiat value per deposit token in the selected `priceCurrency`, such as `"1.00"`.
* `termLengthDays`: Optional term length in days.
* `interestRateBps`: Optional annual interest rate in basis points.
* `earlyWithdrawalPenaltyBps`: Optional early withdrawal penalty in basis points.
* `initialModulePairs`: Compliance modules (empty array `[]` for basic setup).

In synchronous mode, the response includes deposit data with `id`, which is the token contract address. Save that address for the remaining steps.

If DALP returns `transactionId` instead, the deposit creation transaction has been queued. Poll `dalp.transaction.status` until the transaction completes. Then call `dalp.token.list` with supported filters such as `name`, `symbol`, and `tokenType: "deposit"`. Save the matching token `id` before continuing with role grants, unpause, or minting.

The example script returns after logging the queued transaction ID. Production automation should resume the runbook only after it has resolved the deposit token address.

> For vault linking, denomination asset approvals, early-withdrawal automation, and bank-owned reconciliation controls, use the [deposit certificates guide](/docs/business/use-cases/deposits). This API guide covers contract deployment and minting.

***

### Step 5: grant token roles [#step-5-grant-token-roles]

Grant yourself `supplyManagement` for minting and `emergency` for unpausing the deposit contract.

When you create a token, you receive the token `admin` role and can grant additional token roles. Grant these roles before you try to unpause or mint.

```ts file=<rootDir>/src/examples/create-mint-deposit.ts#L50-L72
  // 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",
      },
    },
  });
```

Both role grant transactions must complete. Wait for confirmation before Step 6.

***

### Step 6: unpause the deposit [#step-6-unpause-the-deposit]

New tokens start paused. Unpause to enable transfers:

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

This step requires the `emergency` role from Step 5. Make sure both role grants are confirmed before unpausing.

***

### Step 7: mint deposit certificates [#step-7-mint-deposit-certificates]

Register each recipient wallet in the identity registry before minting. For your own wallet, complete Step 3 first. For another recipient, call `dalp.system.identity.create` before adding the address to `recipients`.

```ts file=<rootDir>/src/examples/create-mint-deposit.ts#L87-L100
  // Step 7: Mint deposit certificates — 50,000 units
  // IMPORTANT: Recipient must be registered in identity registry
  await dalp.token.mint({
    params: { tokenAddress },
    body: {
      recipients: [myWallet],
      amounts: [50_000_000_000_000_000_000_000n],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Minted deposit certificates");
```

Parameters:

* `tokenAddress`: Your deposit contract address (in path)
* `recipients`: Array of recipient wallet addresses. Each must be registered in the identity registry.
* `amounts`: Array of token-unit amounts. The example mints 50,000 certificates with 18 decimals.

This step requires the `supplyManagement` role from Step 5. The certificates appear in the holder list after the transaction is indexed. If DALP returns `RecipientNotVerified`, register that wallet with `dalp.system.identity.create` and retry the mint.

***

### Step 8: verify the mint [#step-8-verify-the-mint]

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

The holder list shows the recipient and minted balance. Asset views use the same token supply and price fields to show depositor positions and liability values.

***

## Full script [#full-script]

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

async function main() {
  // Step 1: Create the SDK client
  const dalp = createDalpClient({
    url: "https://your-platform.example.com",
    apiKey: "YOUR_API_KEY",
  });
  const pincode = "YOUR_PINCODE";

  // 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
  // - Register your identity (CRITICAL: required before minting)
  // See: /docs/developer-guides/runbooks/setup-roles

  // Step 4: Create deposit token
  const deposit = await dalp.token.create({
    body: {
      type: "deposit",
      name: "12M USD CD",
      symbol: "CD12",
      decimals: 18,
      countryCode: "840",
      priceCurrency: "USD",
      basePrice: "1.00",
      initialModulePairs: [],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });

  if ("transactionId" in deposit) {
    console.log("Deposit creation queued:", deposit.transactionId);
    return;
  }
  const tokenAddress = deposit.data.id;
  console.log("Deposit 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 deposit
  await dalp.token.unpause({
    params: { tokenAddress },
    body: {
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Deposit unpaused");

  // Step 7: Mint deposit certificates — 50,000 units
  // IMPORTANT: Recipient must be registered in identity registry
  await dalp.token.mint({
    params: { tokenAddress },
    body: {
      recipients: [myWallet],
      amounts: [50_000_000_000_000_000_000_000n],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });
  console.log("Minted deposit certificates");

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

await main();
```

***

![Tokenized deposits listing](/docs/screenshots/deposits/deposits-listing.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.                                                                                |
| `RecipientNotVerified`                          | Register the recipient wallet with `dalp.system.identity.create`, then retry the mint.                                                                        |
| Queued token creation                           | Poll `dalp.transaction.status` with the returned `transactionId`. Continue only after the queued operation completes and you have resolved the token address. |
| `Invalid country code`                          | Provide a numeric ISO 3166-1 code (`840`, `056`, `276`, etc.).                                                                                                |
| Mismatched decimals vs. denomination asset      | Match `decimals` to the ERC-20 you plan to lock in vaults, as described in the deposit guide's "Denomination asset selection."                                |

## Related [#related]

* [Deposit use case](/docs/business/use-cases/deposits)
* [Token lifecycle API guide](/docs/api-reference/tokens/token-lifecycle)
* [Developer runbooks](/docs/developers)
