# Create and mint a fund token

Source: https://docs.settlemint.com/docs/developers/runbooks/create-mint-funds
Use the DALP TypeScript client to create a fund token, assign the roles
needed for supply operations, unpause the token, and mint units to a
registered holder.




Fund issuance through the Platform API covers token deployment, role assignment, and minting units to registered holders. The deployment request defines the token, its reference price, optional classification fields, and management-fee metadata. Supply operations and investor records stay separate from the deployment payload.

<Mermaid
  chart="`flowchart TD
Operator[&#x22;Fund operator&#x22;] --> Client[&#x22;TypeScript client&#x22;]
Client --> Create[&#x22;Create fund token&#x22;]
Create --> Roles[&#x22;Grant token roles&#x22;]
Roles --> Unpause[&#x22;Unpause token&#x22;]
Unpause --> Mint[&#x22;Mint units&#x22;]
Mint --> Verify[&#x22;Verify holders&#x22;]
`"
/>

The diagram traces the path from fund operator through the TypeScript client to token creation, then through role grants and unpausing to minting. Holder verification follows each mint operation.

## Prerequisites [#prerequisites]

Before you run the script, confirm that you have:

* A DALP platform URL, such as `https://your-platform.example.com`.
* A running DALP instance.
* A DALP user profile with a connected address and PINCODE set from **Account → Wallet**.
* An API key for that profile.
* The `admin` system role if you need to grant `tokenManager` or register identities yourself.

Save your wallet address after login. You need it when registering identities, assigning token roles, and minting fund units.

## Quick reference [#quick-reference]

| Step | Goal                               | Method                                        |
| ---- | ---------------------------------- | --------------------------------------------- |
| 1    | Create the client                  | `createDalpClient`                            |
| 2    | Read the current user wallet       | `user.me`                                     |
| 3    | Prepare system access and identity | `tokenManager` role and identity registration |
| 4    | Create the fund token              | `token.create` with `type: "fund"`            |
| 5    | Grant token roles                  | `token.grantRole`                             |
| 6    | Unpause the token                  | `token.unpause`                               |
| 7    | Mint fund units                    | `token.mint`                                  |
| 8    | Check balances                     | `token.holders`                               |

## Fund creation fields [#fund-creation-fields]

The fund creation schema extends the base token fields with fund-specific pricing and metadata.

| Field                | Required | Purpose                                                                       |
| -------------------- | -------- | ----------------------------------------------------------------------------- |
| `type`               | Yes      | Must be `"fund"`.                                                             |
| `priceCurrency`      | Yes      | Fiat currency code for the fund unit reference price.                         |
| `basePrice`          | Yes      | Reference price per unit in `priceCurrency`, such as `"100.00"`.              |
| `managementFeeBps`   | Yes      | Management fee in basis points. Valid range is 0 to 10,000.                   |
| `class`              | No       | Fund class value, such as `LONG_SHORT_EQUITY`, when classification is useful. |
| `category`           | No       | Fund category value, such as `MULTI_STRATEGY`, when classification is useful. |
| `uniqueIdentifier`   | No       | ISIN or other identifier used for reporting when the fund has one.            |
| `initialModulePairs` | Yes      | Compliance modules to attach during creation. Use `[]` for a basic setup.     |

The creation payload models the token and its metadata. Keep underlying holdings, fee accruals, redemption terms, investor suitability evidence, and off-platform fund administration in the systems that own those records.

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

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

Create the generated DALP client with your platform URL and API key. Pass the platform URL and API key to `createDalpClient`.

```ts file=<rootDir>/src/examples/create-mint-fund.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";
```

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

Call `user.me` and keep the returned wallet address. You need it for holder enrollment, token-role grants, and the mint call in Step 7.

```ts file=<rootDir>/src/examples/create-mint-fund.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);
```

### Step 3: prepare system access and identity [#step-3-prepare-system-access-and-identity]

A fund issuer needs the `tokenManager` system role to create tokens. Each recipient also needs an entry in the identity registry before minting can succeed. Grant `tokenManager` through the platform role administration flow, and enroll every holder that will receive minted units. If your account does not have `admin`, ask an administrator to complete both steps before you continue.

### Step 4: create the fund token [#step-4-create-the-fund-token]

Create the fund token with `type: "fund"`. The example sets class to `LONG_SHORT_EQUITY`, category to `MULTI_STRATEGY`, a USD 100.00 reference price, and a 150 bps management fee.

```ts file=<rootDir>/src/examples/create-mint-fund.ts#L22-L49
  // Step 4: Create fund token
  const fund = await dalp.token.create({
    body: {
      type: "fund",
      name: "Global Growth Fund Class A",
      symbol: "GGFA",
      decimals: 18,
      countryCode: "056",
      priceCurrency: "USD",
      basePrice: "100.00",
      class: "LONG_SHORT_EQUITY",
      category: "MULTI_STRATEGY",
      managementFeeBps: 150,
      uniqueIdentifier: "BE0003796134",
      initialModulePairs: [],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });

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

The response can be queued. If it returns token data directly, save `fund.data.id` as the token address for the remaining steps.

If the response returns `transactionId`, `status`, and `statusUrl`, poll `dalp.transaction.status` with that `transactionId` until the status is `COMPLETED`. The completed status response gives you the confirmed transaction hash. The example script exits at this point once it logs the pending transaction ID, so production automation must wait until the deployment finishes before continuing.

Once deployment completes, call `dalp.token.list`. Filter for the fund's unique `symbol`, `uniqueIdentifier`, or other fields from the create request.

Save the returned `id` as the contract address before you continue. Do not proceed with permissions, unpause, or supply operations until the new fund appears in the token read model.

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

Grant the wallet the token roles needed for the next steps:

* `supplyManagement` allows minting and redemption-related supply operations.
* `emergency` allows the wallet to unpause the token.

```ts file=<rootDir>/src/examples/create-mint-fund.ts#L51-L74
  // 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");
```

Wait for the role-grant transactions to confirm before unpausing or minting. Add `governance` only if the wallet also needs to update valuation or redemption parameters through the API.

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

New tokens start paused. Unpause the fund token before minting or transferring supply.

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

### Step 7: mint fund units [#step-7-mint-fund-units]

Mint only to wallets registered in the identity registry. The example mints 100 fund units to the current user's wallet.

```ts file=<rootDir>/src/examples/create-mint-fund.ts#L88-L100
  // Step 7: Mint fund units — 100 units
  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 fund units");
```

The mint request returns when the transaction has been submitted. If you receive `RecipientNotVerified`, register the recipient wallet with `systemIdentityCreate` and retry.

### Step 8: verify holders [#step-8-verify-holders]

Read the holder list and confirm the minted unit balance before you continue with valuation, reporting, or fund administration.

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

## Full script [#full-script]

```ts file=<rootDir>/src/examples/create-mint-fund.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
  // Grant yourself 'tokenManager' and register your identity

  // Step 4: Create fund token
  const fund = await dalp.token.create({
    body: {
      type: "fund",
      name: "Global Growth Fund Class A",
      symbol: "GGFA",
      decimals: 18,
      countryCode: "056",
      priceCurrency: "USD",
      basePrice: "100.00",
      class: "LONG_SHORT_EQUITY",
      category: "MULTI_STRATEGY",
      managementFeeBps: 150,
      uniqueIdentifier: "BE0003796134",
      initialModulePairs: [],
      walletVerification: {
        secretVerificationCode: pincode,
        verificationType: "PINCODE",
      },
    },
  });

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

  // Step 7: Mint fund units — 100 units
  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 fund units");

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

await main();
```

![Fund token with investment category and management fee metadata](/docs/screenshots/funds/fund-detail-1.webp)

## Troubleshooting [#troubleshooting]

| Error or symptom                             | Fix                                                                                                 |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `Authentication missing`                     | Check the API key passed to `createDalpClient`.                                                     |
| `PINCODE_INVALID`                            | Reset or re-enter PINCODE from **Account → Wallet**.                                                |
| `tokenManager required`                      | Grant the `tokenManager` system role. This requires admin access.                                   |
| `Basis points cannot exceed 10000`           | Keep `managementFeeBps` between 0 and 10,000.                                                       |
| Invalid enum value for `class` or `category` | Use values from the fund class and category enums, such as `LONG_SHORT_EQUITY` or `MULTI_STRATEGY`. |
| `Token is paused`                            | Run the unpause step after the `emergency` role grant has confirmed.                                |
| Permission denied during mint                | Confirm the wallet has the `supplyManagement` token role.                                           |
| `RecipientNotVerified`                       | Register the recipient wallet in the identity registry with `systemIdentityCreate`.                 |

## Related [#related]

* [Developer runbooks](/docs/developers)
* [Private equity use case](/docs/business/use-cases/private-equity)
