Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ckb-devrel/ccc/llms.txt

Use this file to discover all available pages before exploring further.

@ckb-ccc/udt provides a TypeScript SDK for interacting with User Defined Tokens (UDT) and the xUDT standard on CKB. It is built on top of the SSRI protocol, supporting both SSRI-compliant contracts and legacy sUDT/xUDT tokens.

Installation

npm install @ckb-ccc/udt
If you are using @ckb-ccc/shell, the udt namespace is already available as ccc.udt.

Exports

ExportDescription
UdtMain class for interacting with a UDT
UdtPausableExtended class for pausable UDT tokens

The Udt class

Udt extends ssri.Trait and provides high-level methods for all token operations.

Constructor

const udt = new Udt(
  code,    // ccc.OutPointLike — the script code cell OutPoint
  script,  // ccc.ScriptLike  — the type script identifying this token
  config?, // { executor?: ssri.Executor | null }
);

Read methods

// Token metadata
const { res: name }     = await udt.name();     // string | undefined
const { res: symbol }   = await udt.symbol();   // string | undefined
const { res: decimals } = await udt.decimals(); // ccc.Num | undefined
const { res: icon }     = await udt.icon();     // string (data URI) | undefined

transfer

Transfer tokens to one or more recipients:
async transfer(
  signer: ccc.Signer,
  transfers: { to: ccc.ScriptLike; amount: ccc.NumLike }[],
  tx?: ccc.TransactionLike | null,
): Promise<ssri.ExecutorResponse<ccc.Transaction>>

mint

Mint new tokens (issuer only):
async mint(
  signer: ccc.Signer,
  mints: { to: ccc.ScriptLike; amount: ccc.NumLike }[],
  tx?: ccc.TransactionLike | null,
): Promise<ssri.ExecutorResponse<ccc.Transaction>>

completeBy

Balance UDT inputs/outputs automatically using the signer’s address as change:
async completeBy(
  tx: ccc.TransactionLike,
  from: ccc.Signer,
): Promise<ccc.Transaction>

completeChangeToLock

Balance UDT inputs/outputs with a custom change lock script:
async completeChangeToLock(
  txLike: ccc.TransactionLike,
  signer: ccc.Signer,
  change: ccc.ScriptLike,
): Promise<ccc.Transaction>

Usage examples

Transfer tokens

import { udt } from "@ckb-ccc/udt";
import { ccc } from "@ckb-ccc/shell";

const myToken = new udt.Udt(
  {
    txHash: "0x4e2e832e0b1e7b5994681b621b00c1e65f577ee4b440ef95fa07db9bb3d50269",
    index: 0,
  },
  {
    codeHash: "0xcc9dc33ef234e14bc788c43a4848556a5fb16401a04662fc55db9bb201987037",
    hashType: "type",
    args: "0x71fd1985b2971a9903e4d8ed0d59e6710166985217ca0681437883837b86162f",
  },
);

const { script: toScript } = await ccc.Address.fromString(
  "ckb1qzda0cr08m85hc8jlnfp3gog...",
  signer.client,
);

// Build the transfer transaction
const { res: tx } = await myToken.transfer(signer, [
  { to: toScript, amount: 100n },
]);

// Balance UDT change and capacity
const completedTx = await myToken.completeBy(tx, signer);
await completedTx.completeInputsByCapacity(signer);
await completedTx.completeFeeBy(signer);

const txHash = await signer.sendTransaction(completedTx);

Read token metadata

const { res: name }     = await myToken.name();
const { res: symbol }   = await myToken.symbol();
const { res: decimals } = await myToken.decimals();

console.log(`${name} (${symbol}), ${decimals} decimal places`);

Mint tokens

const { res: tx } = await myToken.mint(signer, [
  { to: recipientScript, amount: 1_000_000n },
]);

const completedTx = await myToken.completeBy(tx, signer);
await completedTx.completeInputsByCapacity(signer);
await completedTx.completeFeeBy(signer);

await signer.sendTransaction(completedTx);
@ckb-ccc/udt depends on @ckb-ccc/ssri. An ssri.Executor is optional — without one, the Udt class falls back to constructing transactions directly without querying SSRI metadata from the chain.

Build docs developers (and LLMs) love