Content Hub
Canton NetworkMay 2026 · 9 min read

The Onboarding Lifecycle for a Registry Token on Canton

From “I want to receive USDCx” to a working transfer feed, in four stages. What happens at each step, where it goes wrong, and what becomes queryable when you reach the end.

Martín Alejandro Mednik
Martín Alejandro MednikEngineering, Noves

Overview

Canton Coin (CC) “just works” on every Canton participant — the Daml packages it depends on are pre-installed, and the read APIs surface its data without extra configuration. Registry tokens like USDCx and CBTC don’t have that luxury. To receive them, your participant has to be onboarded into the issuer’s stack: install the Utility DARs, sign a pre-approval, get recognized by the issuer, and then start querying.

Here’s how the four stages compare to CC at a glance:

Canton CoinRegistry Token (USDCx, CBTC)
Daml packages on participantPre-installed (Splice Amulet)Utility DAR bundle upload (Stage 1)
Direct (single-step) transfersOptional TransferPreapprovalOptional TransferPreapproval (Stage 2)
2-step transfer fallbackYes, via TransferInstructionYes, via TransferInstruction
Holder credentialsNot requiredEnforced via holderRequirements (Stage 3)
Issuer recognition stepNoneKYC + on-chain Credential (Stage 3)
Read-side observabilityPublic API + Data AppSame shape, automatic

The rest of this post walks through each stage in order, with a note at the end on what changes when you onboard a second token after the first.


Stage 1 — Install the Utility DARs

The Canton Token Standard (CIP-0056) ships as a set of Daml package archives (DARs). For native CC, the participant already has everything it needs (the Splice Amulet packages are part of every Canton participant). For registry tokens (USDCx, CBTC, future stablecoins), the participant has to upload the Utility DAR bundle before any related contract can be created.

The bundle is a small set of packages — utility-registry-app-v0, utility-registry-v0, utility-registry-holding-v0, utility-credential-v0, and a few others — published by Digital Asset and available from their docs. For wallet-style use cases (“I want to hold and receive a registry token”), utility-registry-app-v0 is the package the rest of this post is about.

If the DARs aren’t installed, any CreateCommandfor a registry-token template will reject with a “package not found”-style error. The exact error code and shape varies by Canton version and API surface — what you’ll consistently see is a reference to the package name (e.g. #utility-registry-app-v0) that the participant can’t resolve:

JSON
{
  "error": "PACKAGE_NOT_FOUND",
  "details": "package #utility-registry-app-v0 not found on participant"
}
{
  "error": "PACKAGE_NOT_FOUND",
  "details": "package #utility-registry-app-v0 not found on participant"
}

This is the most common gotcha when first integrating a registry token. The fix is a single upload against your participant’s admin API (or via Canton console). Once the Utility DARs are in place they cover every Token Standard-compliant token issued through the Registry Utility, not just one — so this stage runs exactly once per node.

If you’re on a node-as-a-service provider, you don’t run this step yourself; ask the provider to install the DARs on your participant. Most won’t have them pre-installed unless another tenant has already needed them.


Stage 2 — Sign the Pre-Approval

Both CC and registry tokens support two transfer flows under the Token Standard:

  1. Two-step: the sender creates a TransferInstruction, the receiver explicitly accepts. Works without any setup on the receiver’s side.
  2. Direct (single-step): settles in a single Daml transaction — but only if the receiver has a TransferPreapproval contract in place.

For CC the preapproval lives in the Splice Amulet package; for registry tokens it lives in the Utility DARs you just installed. The Registry Utility’s preapproval template is at:

DAML TEMPLATE
#utility-registry-app-v0:Utility.Registry.App.V0.Model.TransferPreapproval:TransferPreapproval
#utility-registry-app-v0:Utility.Registry.App.V0.Model.TransferPreapproval:TransferPreapproval

Creating one is a CreateCommand submitted by the prospective recipient. The template has four fields worth knowing about:

  • operator — the Utility operator party.
  • receiver — your party (the single signatory).
  • instrumentAdmin— the issuer/registrar party whose instruments you’re preapproving.
  • instrumentAllowances — a list of instrument IDs to scope the preapproval. An empty list = blanket preapproval for every instrument that admin issues.

Once the contract is active, any sender can move tokens to your party using the direct flow, subject to the issuer’s holder requirements (Stage 3).

If you have multiple parties on the participant (e.g., one per business entity), each party signs its own preapproval. The scoping rule is per-issuer, not per-token: a single preapproval can cover every instrument from the same instrumentAdmin. USDCx and CBTC happen to have differentadmins (Circle’s xReserve and BitSafe respectively), so they need separate preapproval contracts — but two instruments from the same admin can share one.


Stage 3 — Get Recognized by the Issuer

This stage is the easiest to overlook from your participant’s perspective. Even after the DARs are installed and the preapproval is signed, the issuer (Circle’s xReserve for USDCx, BitSafe for CBTC) has its own onboarding to run: KYC paperwork, sanctions screening, sign-off in their compliance system.

The off-chain part is what most people focus on, but it produces an on-chain output that matters for debugging. The Registry Utility uses the Credential Utility to enforce who can hold or transfer a given instrument:

  • Each instrument’s InstrumentConfiguration declares holderRequirements: a list of PartyCredentialRequirement entries that both sender and receiver must satisfy for transfers to succeed.
  • A Credential contract issued by the registrar (or another trusted issuer) is what proves a party meets those requirements. Two flavors exist: subject-held (the party can see their own credential) and issuer-held(the registrar maintains an “allowlist-style” credential about the party, which the party may not even observe).
  • Validation runs at execution time. Until your party has a valid credential, transfers to it will be rejected at the validation step, not silently queued — which is why “the preapproval is signed but transfers still fail” is the canonical Stage-3 symptom.

The reliable source of truth for the workflow is the issuer’s own onboarding documentation. Digital Asset publishes a Registry Utility user guide covering the canonical roles and credential requirements; the Canton Foundation owns CIP-0056 itself.


Stage 4 — Transfers Begin, Observability Becomes the Question

Once stages 1–3 are in place, your party can receive tokens. Holding contracts work the same way as for CC: each transfer creates a Holdingcontract (implementing the Token Standard’s Holding interface) on the recipient side, identified by an instrumentId (admin + id) and an amount.

What changes is the question. Instead of “how do I make this work,” it’s:

  • What’s my current USDCx balance?
  • What’s the transfer history this month, by counterparty?
  • Which counterparties have an active pre-approval contract with me?
  • Does the locked vs. unlocked split look right?

For external observability — balances, transfer history, daily aggregates — the Canton Public Data API exposes registry-token data the same way it exposes CC data, with tokenId and registrar fields surfaced on every row:

BASH
curl "https://api.canton.noves.fi/canton/balances/PARTY_ID?token=USDCx" \
  --header "apiKey: YOUR_API_KEY"
curl "https://api.canton.noves.fi/canton/balances/PARTY_ID?token=USDCx" \
  --header "apiKey: YOUR_API_KEY"

Returns the current balance with USD valuation and registrar metadata. Drop the ?token= parameter to get every token a party holds in one response. Transfer history follows the same shape:

BASH
curl "https://api.canton.noves.fi/canton/transactions/PARTY_ID?token=USDCx" \
  --header "apiKey: YOUR_API_KEY"
curl "https://api.canton.noves.fi/canton/transactions/PARTY_ID?token=USDCx" \
  --header "apiKey: YOUR_API_KEY"

For internal operational visibility— including pre-approval state, locked balances, and any private transfers visible only to your participant — you’ll need a participant-node-side indexer. The Noves Data App (open source at github.com/Noves-Inc/canton-data-app) runs in your environment, indexes everything you’re entitled to see, and surfaces the private slices through /api/v2/parties/{party}/preapprovals?token=USDCx and the rest of the local API.


Multi-Token Considerations

Adding a second registry token doesn’t restart the lifecycle from zero — but it doesn’t always pick up at four, either. What matters is whether the new token is issued by an admin you’ve already onboarded.

  • Stage 1 is genuinely one-time. The Utility DARs cover every Registry Utility-issued token.
  • Stage 2depends on the admin. If the new token comes from an admin you already have a preapproval with, you can extend the existing preapproval’s instrumentAllowances(or rely on a blanket preapproval if you set one up). If it’s a new admin, you sign a new preapproval.
  • Stage 3 repeats per issuer. Each issuer has their own KYC and credential workflow.
  • Stage 4 is automatic. Both the Public API and the Data App treat new tokens the same as old ones — no integration work on the read side.

The pattern that follows: install DARs once, onboard each new issuer, and let the read layer scale automatically.


Resources