# Deploy and mint a deposit

Source: https://docs.settlemint.com/docs/developer-guides/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. If the create request is queued, the script logs the `transactionId`; poll `dalp.transaction.status` until the transaction completes, then use `dalp.token.list` to retrieve the token address before continuing.

Save the contract address. You need it for every remaining step.

> Vault linking, denomination asset approvals, and early-withdrawal automation continue in the deposit user guide. 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/executive-overview/use-cases/deposits)
* [Token lifecycle API guide](/docs/developer-guides/api-integration/token-lifecycle)
* [Developer runbooks](/docs/developer-guides)
