> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ixo.world/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage tokens

> Create, mint, transfer, retire, and govern IXO Protocol tokens with the IXO MultiClient SDK.

The IXO Protocol token module wraps the `ixo1155` smart contract — a CosmWasm implementation of the EIP-1155 multi-token standard. Each token domain has a token class (entity DID), a fixed cap, and supports both fungible and non-fungible balances within a single contract.

This guide shows the chain-level message patterns. For the data model and contract details, read the [`x/token` proto definitions](https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo/token/v1beta1) and the [`@ixo/impactxclient-sdk` README](https://github.com/ixofoundation/ixo-multiclient-sdk#readme).

## Before you start

You need:

* An IXO account with sufficient `uixo` for fees on the network you target — see [Networks and endpoints](/reference/networks-and-endpoints).
* An offline signer — see the [SDK README on creating signers](https://github.com/ixofoundation/ixo-multiclient-sdk#creating-signers).
* The token protocol entity DID (the value used as `class`). Token class is validated against an existing entity.
* For minting, a deployed token contract address (set via `MsgCreateToken`).
* For credit transfers, a valid `WithdrawPaymentAuthorization` if you act on behalf of another account — see [Custom authorisations for IXO Claims](/guides/dev/authz-custom).

```bash theme={"system"}
npm install @ixo/impactxclient-sdk
```

```ts theme={"system"}
import { ixo, createSigningClient } from "@ixo/impactxclient-sdk";

const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner);
```

## Create a token

`MsgCreateToken` registers a new token name under a token-protocol entity. Cap `"0"` means unlimited supply.

```ts theme={"system"}
const createMsg = {
  typeUrl: "/ixo.token.v1beta1.MsgCreateToken",
  value: ixo.token.v1beta1.MsgCreateToken.fromPartial({
    minter: signerAddress,
    class: "did:ixo:entity:protocol123",
    name: "CARBON",
    description: "Verified carbon offset units",
    image: "ipfs://bafy.../image.png",
    tokenType: "ixo1155",
    cap: "1000000",
  }),
};

await signingClient.signAndBroadcast(signerAddress, [createMsg], "auto");
```

## Mint tokens

`MsgMintToken` issues new units in batches against an existing token contract. Each batch references a unique `index` and a `collection` DID.

```ts theme={"system"}
const mintMsg = {
  typeUrl: "/ixo.token.v1beta1.MsgMintToken",
  value: ixo.token.v1beta1.MsgMintToken.fromPartial({
    minter: signerAddress,
    contractAddress: tokenContractAddress,
    owner: ownerAddress,
    mintBatch: [
      ixo.token.v1beta1.MintBatch.fromPartial({
        name: "CARBON",
        index: "bafkreih...",
        amount: "1000",
        collection: "did:ixo:entity:collection456",
        tokenData: [],
      }),
    ],
  }),
};

await signingClient.signAndBroadcast(signerAddress, [mintMsg], "auto");
```

## Transfer tokens

`MsgTransferToken` moves balances between accounts. All tokens in a single message must belong to the same contract.

```ts theme={"system"}
const transferMsg = {
  typeUrl: "/ixo.token.v1beta1.MsgTransferToken",
  value: ixo.token.v1beta1.MsgTransferToken.fromPartial({
    owner: signerAddress,
    recipient: recipientAddress,
    tokens: [
      ixo.token.v1beta1.TokenBatch.fromPartial({
        id: "bafkreih...",
        amount: "100",
      }),
    ],
  }),
};

await signingClient.signAndBroadcast(signerAddress, [transferMsg], "auto");
```

## Retire tokens

`MsgRetireToken` permanently removes tokens from circulation while preserving their on-chain history. Use this for end-claims such as voluntary carbon retirement.

```ts theme={"system"}
const retireMsg = {
  typeUrl: "/ixo.token.v1beta1.MsgRetireToken",
  value: ixo.token.v1beta1.MsgRetireToken.fromPartial({
    owner: signerAddress,
    tokens: [
      ixo.token.v1beta1.TokenBatch.fromPartial({
        id: "bafkreih...",
        amount: "50",
      }),
    ],
    jurisdiction: "ZA-WC-7700",
    reason: "Voluntary retirement on behalf of buyer X",
  }),
};
```

The `jurisdiction` field follows the format `<country-code>[-<sub-national-code>[-<postal-code>]]`. Only the country code is required.

## Transfer credit (ITMO state change)

`MsgTransferCredit` flips tokens to a "transferred" state when units are moved off-protocol to a different registry — for example, Internationally Transferred Mitigation Outcomes (ITMOs) under Article 6.2 of the Paris Agreement. It accepts an optional `authorization_id` for delegated transfers.

```ts theme={"system"}
const creditTransferMsg = {
  typeUrl: "/ixo.token.v1beta1.MsgTransferCredit",
  value: ixo.token.v1beta1.MsgTransferCredit.fromPartial({
    owner: signerAddress,
    tokens: [
      ixo.token.v1beta1.TokenBatch.fromPartial({
        id: "bafkreih...",
        amount: "100",
      }),
    ],
    jurisdiction: "CH",
    reason: "ITMO transfer to Swiss national registry",
    authorizationId: "auth-2025-001",
  }),
};
```

## Cancel, pause, or stop a token

| Operation         | Message          | Effect                                                                                 |
| ----------------- | ---------------- | -------------------------------------------------------------------------------------- |
| Cancel batches    | `MsgCancelToken` | Owner cancels specific token batches with a reason.                                    |
| Pause minting     | `MsgPauseToken`  | Minter halts further minting on a contract. `paused: true` to halt, `false` to resume. |
| Stop the contract | `MsgStopToken`   | Minter permanently stops the token contract. Irreversible.                             |

```ts theme={"system"}
const pauseMsg = {
  typeUrl: "/ixo.token.v1beta1.MsgPauseToken",
  value: ixo.token.v1beta1.MsgPauseToken.fromPartial({
    minter: signerAddress,
    contractAddress: tokenContractAddress,
    paused: true,
  }),
};
```

## Verify the result

Query token state through the [Blocksync GraphQL API](/api-reference/blocksync-graphql-api):

```graphql theme={"system"}
query Token($id: String!) {
  token(id: $id) {
    id
    name
    description
    cap
    class
    minter
    minted
    transferred
    retired
    cancelled
  }
}
```

Or read directly from the token contract via the [gRPC gateway API](/api-reference/grpc-gateway-api).

## Troubleshooting

<AccordionGroup>
  <Accordion title="invalid class DID" icon="circle-xmark">
    `class` must be a valid entity DID for an existing token-protocol entity. Confirm the entity exists and that you control it.
  </Accordion>

  <Accordion title="cap exceeded" icon="arrow-up-wide-short">
    `MsgMintToken` will fail if the new total would exceed the token `cap`. Either raise the cap by recreating the token or split issuance across additional token names.
  </Accordion>

  <Accordion title="contract paused or stopped" icon="ban">
    Minting is rejected on paused contracts and on stopped contracts. Issue `MsgPauseToken` with `paused: false` to resume; `MsgStopToken` cannot be reversed.
  </Accordion>

  <Accordion title="unauthorized credit transfer" icon="lock">
    Delegated `MsgTransferCredit` requires a `WithdrawPaymentAuthorization` referencing the supplied `authorization_id`. See [Custom authorisations for IXO Claims](/guides/dev/authz-custom).
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="IXO MultiClient SDK" icon="server" href="/sdk-reference/multiclient-sdk">
    Full SDK reference including signing client setup.
  </Card>

  <Card title="Token proto definitions" icon="github" href="https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo/token/v1beta1">
    Source of truth for token messages.
  </Card>

  <Card title="Bonds module" icon="line-chart" href="/guides/dev/bonds">
    Add bonding-curve pricing and reserves to tokens.
  </Card>

  <Card title="Custom authorisations" icon="key" href="/guides/dev/authz-custom">
    Delegate token operations safely.
  </Card>
</CardGroup>
