# 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. **Platform URL** - the DALP platform URL, such as `https://your-platform.example.com`.
2. **API key** - an API key for the user that will create and operate the deposit token.
3. **PINCODE** - wallet verification enabled during onboarding. Manage it from **Account → Wallet**.
4. **Admin role** - admin access if you need to grant yourself system roles.
5. **Token manager role** - the `tokenManager` system role before creating the deposit token.
6. **Registered identities** - 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:**

* **Identity registration** - register the issuer wallet and recipient wallets before minting.
* **Decimals alignment** - match token decimals to the denomination asset you use for accounting.
* **Liability tracking** - set `priceCurrency` and `basePrice` on creation.
* **System role** - hold `tokenManager` before creation.
* **Token roles** - hold `supplyManagement` before minting and `emergency` before unpausing.
* **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`.

1. **Grant system roles**:
   * `tokenManager` - Required to create tokens
   * `claimPolicyManager` or `complianceManager` - Optional, if you plan to automate collateral attestation or custom compliance

2. **Register identity**:
   * Register your wallet address in the identity registry before minting.
   * Use `dalp.system.identity.create` for the issuer wallet and for any other recipient wallet you mint to.
   * If a recipient is not registered, the mint call fails before certificates are issued.

Only users with `admin` role can grant system roles. If you do not have admin access, ask your system administrator to grant `tokenManager` and register the identities before you continue.

***

### 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 (e.g., "12M USD CD")
* `symbol`: Deposit symbol (e.g., "CD12")
* `decimals`: Match the denomination asset decimals (guide section "Denomination asset selection")
* `countryCode`: ISO country code (840 = USA, 056 = Belgium, 276 = Germany)
* `priceCurrency`: ISO currency code (e.g., "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)

**Expected:** 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",
      },
    },
  });
```

**Expected:** Both role grant transactions 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 address(es) - **must be verified in identity registry**
* `amounts`: Array of token-unit amounts. The example mints 50,000 certificates with 18 decimals.

**Expected:** The mint write completes and the certificates appear in the holder list after the transaction is indexed.

This step requires the `supplyManagement` role from Step 5. If DALP returns `RecipientNotVerified`, register that wallet with `dalp.system.identity.create`. Then 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);
```

**Expected:** 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]

**"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"** → Make sure Step 6 (unpause) succeeded and you have `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** → Align `decimals` with 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)
