Canton Network docsSDKs › Wallet SDK › Using the SDK › v0 to v1 migration
Token Namespace
Updated 12-11-2026
The token namespace provides methods to manage token operations including transfers, holdings, UTXOs, and allocations on the Canton Network. In v1, the token namespace replaces the
Option 2: Add token namespace later using extend()
This enables thread-safe concurrent operations and clearer code organization.
Accepting, rejecting, or withdrawing transfers
Listing pending transfers
You can also specify offsets for pagination:
Transactions by updateId:
You can specify additional parameters for pagination and limits:
Merging UTXOs
Merging consolidates multiple small UTXOs into larger ones to improve performance.
The merge operation groups UTXOs by instrument and creates self-transfers to consolidate them. You can optionally provide specific UTXOs to merge:
The
Executing, withdrawing or cancelling allocations
tokenStandard controller from v0.
Availability and extensibility
The token namespace is an extended namespace that requires configuration. You can initialize it either during SDK creation or later using theextend() method.
Option 1: Initialize during SDK creation
import { SDK, localNetStaticConfig } from '@canton-network/wallet-sdk'
export default async function () {
const sdk = await SDK.create({
auth: global.TOKEN_PROVIDER_CONFIG_DEFAULT,
ledgerClientUrl: localNetStaticConfig.LOCALNET_APP_USER_LEDGER_URL,
synchronizerId: global.LOCALNET_GLOBAL_SYNCHRONIZER,
token: global.TOKEN_NAMESPACE_CONFIG,
})
const partyId = EXISTING_PARTY_1
// token namespace is now available
await sdk.token.utxos.list({ partyId })
}
import { SDK, localNetStaticConfig } from '@canton-network/wallet-sdk'
export default async function () {
// Create basic SDK first
const basicSDK = await SDK.create({
auth: global.TOKEN_PROVIDER_CONFIG_DEFAULT,
ledgerClientUrl: localNetStaticConfig.LOCALNET_APP_USER_LEDGER_URL,
synchronizerId: global.LOCALNET_GLOBAL_SYNCHRONIZER,
})
// Extend with token namespace when needed
const extendedSDK = await basicSDK.extend({
token: global.TOKEN_NAMESPACE_CONFIG,
})
const partyId = EXISTING_PARTY_1
// Now token namespace is available
await extendedSDK.token.utxos.list({ partyId })
}
Key changes from v0 to v1
v0 used thetokenStandard controller with implicit party context set via sdk.setPartyId().
v1 uses the token namespace where you:
- Pass
partyIdexplicitly to each operation - Initialize the namespace with configuration
- Access operations through logical groupings (
transfer,utxos,allocation)
sdk.setPartyId(myPartyId)
const holdings = await sdk.tokenStandard?.listHoldingTransactions()
const holdings = await sdk.token.holdings({ partyId: myPartyId })
Transfers
Creating transfersconst transfer = await sdk.tokenStandard.createTransfer(
senderPartyId,
recipientPartyId,
amount.toString(),
{
instrumentId: 'Amulet',
instrumentAdmin: instrumentAdminPartyId
},
registryUrl,
memo
)
const [command, disclosedContracts] = await sdk.token.transfer.create({
sender: senderPartyId,
recipient: recipientPartyId,
amount: amount.toString(),
instrumentId: 'Amulet',
registryUrl,
inputUtxos: ['utxo-1', 'utxo-2'],
memo: 'Payment for services',
})
await sdk.tokenStandard.exerciseTransferInstructionChoice(transferCid, choiceType /* 'Accept' | 'Withdraw' | 'Reject' */)
// Accept transfer
const [acceptCommand, disclosed1] = await sdk.token.transfer.accept({
transferInstructionCid,
registryUrl,
})
// Reject transfer
const [rejectCommand, disclosed2] = await sdk.token.transfer.reject({
transferInstructionCid,
registryUrl,
})
// Withdraw transfer
const [withdrawCommand, disclosed3] = await sdk.token.transfer.withdraw({
transferInstructionCid,
registryUrl,
})
await sdk.setPartyId(partyId)
const pending = await sdk.tokenStandard
.fetchPendingTransferInstructionView()
const pending = await sdk.token.transfer.pending(myPartyId)
Holdings
Holdings represent the transaction history of token ownership for a party.await sdk.setPartyId(partyId)
const holdings = await sdk.tokenStandard
.listHoldingTransactions()
const holdings = await sdk.token.holdings({ partyId })
const holdings = await sdk.token.holdings({
partyId,
afterOffset: 10,
beforeOffset: 100,
})
await sdk.setPartyId(partyId)
const tx = await sdk.tokenStandard.getTransactionById('my-update-id')
const tx = await sdk.token.transactionsById({ updateId, partyId })
UTXOs
UTXOs (Unspent Transaction Outputs) are the actual holding contracts that represent token balances. Listing UTXOsawait sdk.setPartyId(partyId)
// List all UTXOs including locked ones
const allUtxos = await sdk.tokenStandard?.listHoldingUtxos()
// List only unlocked UTXOs
const usableUtxos = await sdk.tokenStandard?.listHoldingUtxos(false)
// List only unlocked UTXOs (default)
const usableUtxos = await sdk.token.utxos.list({
partyId
})
// List all UTXOs including locked ones
const allUtxos = await sdk.token.utxos.list({
partyId,
includeLocked: true,
})
const utxos = await sdk.token.utxos.list({
partyId,
includeLocked: false,
limit: 100,
offset: 0,
continueUntilCompletion: false,
})
await sdk.setPartyId(partyId)
const [commands, disclosedContracts] =
await sdk.tokenStandard.mergeHoldingUtxos(nodeLimit)
const [commands, disclosedContracts] = await sdk.token.utxos.merge({
partyId,
nodeLimit: 200,
memo: 'merge-utxos',
})
const [commands, disclosedContracts] = await sdk.token.utxos.merge({
partyId,
inputUtxos,
memo: 'custom merge',
})
Allocation
Allocations handle the issuance and distribution of new tokens. Listing pending allocationsawait sdk.setPartyId(partyId)
// Allocation requests
const requests = await sdk.tokenStandard
.fetchPendingAllocationRequestView()
// Allocation instructions
const instructions = await sdk.tokenStandard
.fetchPendingAllocationInstructionView()
// Allocations
const allocations = await sdk.tokenStandard
.fetchPendingAllocationView()
// All pending allocations (default)
const allocations = await sdk.token.allocation.pending(myPartyId)
pending method accepts an optional interface ID to filter by allocation type:
import {
ALLOCATION_REQUEST_INTERFACE_ID,
ALLOCATION_INSTRUCTION_INTERFACE_ID,
ALLOCATION_INTERFACE_ID,
} from '@canton-network/core-token-standard'
// Filter by specific type
const requests = await sdk.token.allocation.pending(
myPartyId,
ALLOCATION_REQUEST_INTERFACE_ID
)
const [command, disclosedContracts] = await sdk.tokenStandard.exerciseAllocationChoice(allocationCid, choice /* 'ExecuteTransfer' | 'Withdraw' | 'Cancel' */)
// Execute allocation
const [executeCommand, disclosedContracts1] = await sdk.token.allocation.execute({
allocationCid,
asset
})
// Withdraw allocation
const [withdrawCommand, disclosedContracts2] = await sdk.token.allocation.withdraw({
allocationCid,
asset,
})
// Cancel allocation
const [cancelCommand, disclosedContracts3] = await sdk.token.allocation.cancel({
allocationCid,
asset,
})
Migration reference
| v0 method | v1 method |
|---|---|
sdk.tokenStandard.createTransfer | sdk.token.transfer.create |
sdk.tokenStandard.exerciseTransferInstructionChoice | sdk.token.transfer.accept / sdk.token.transfer.reject / sdk.token.transfer.withdraw |
sdk.tokenStandard.fetchPendingTransferInstructionView | sdk.token.transfer.pending |
sdk.tokenStandard.listHoldingTransactions({partyId}) | sdk.token.holdings({partyId}) |
sdk.tokenStandard.listHoldingUtxos() | sdk.token.utxos.list({partyId}) |
sdk.tokenStandard.mergeHoldingUtxos | sdk.token.utxos.merge |
sdk.tokenStandard.fetchPendingAllocationRequestView | sdk.token.allocation.pending(partyId, ALLOCATION_REQUEST_INTERFACE_ID) |
sdk.tokenStandard.fetchPendingAllocationInstructionView | sdk.token.allocation.pending(partyId, ALLOCATION_INSTRUCTION_INTERFACE_ID) |
sdk.tokenStandard.fetchPendingAllocationView | sdk.token.allocation.pending(partyId) |
See also
- v0 to v1 migration overview
- Migration cheat sheet
- Configuration — SDK configuration
- Preparing and signing a transaction — Transaction lifecycle