# Canton concepts

This page explains the Canton Network concepts that affect how you custody assets in Ripple Custody. For the Canton Network's own documentation, see [docs.canton.network](https://docs.canton.network).

## How Canton differs from other ledgers

| Topic | Most ledgers | Canton |
|  --- | --- | --- |
| Identity | An address derived from a public key | A *party*, hosted on a validator, with a *party ID* |
| Data visibility | Global public state | Each validator stores only the data visible to its own parties |
| Node access | Any public RPC node | The validator that hosts your parties |
| Balance model | A single balance per asset, or UTXOs | A set of discrete *Holdings* per asset |
| Receiving | Always possible | Needs a *transfer pre-approval*, or the receiver accepts each transfer |
| Fees | Paid by the sending account | Paid as *traffic* by the validator operator |
| Finality | Probabilistic, or after several confirmations | Final when the network commits the transaction, in a single consensus round |


## Parties and party IDs

A *party* is the Canton identity that owns assets and takes part in transactions. Every Ripple Custody account on a Canton ledger has one party.

A *party ID* has two parts, separated by `::`:

```text
<hint>::<namespace fingerprint>
```

- The *hint* is a readable prefix. Ripple Custody uses `c` for every party that it creates.
- The *namespace fingerprint* identifies the key that controls the party. Ripple Custody derives it from the account's own Ed25519 public key.


For example: `c::12209d3b6f1c4a8e2f7b5d0c9a6e3f1b8d4c7a2e5f9b3d6c0a8e4f2b7d1c5a9e3f6b`.

The party ID is the Canton equivalent of an address. You share it with counterparties so that they can send assets to the account, and you use it as the `destination` address when you send.

### Namespaces and external parties

Each Ripple Custody account is its own *namespace*. The account's Ed25519 key signs the party's topology transactions, which register the party on the network, and it signs every ledger transaction that the party submits.

Canton calls this kind of party an *external party*: the validator hosts the party, but it doesn't hold the party's signing key. Your vault holds the key, and your validator can't move the party's assets on its own.

Because Ripple Custody derives the key from your vault's master seed, you can recover the party's key from your vault backup, like any other account key. For more information, see [Key derivation](/products/custody/accounts-and-assets/accounts/account-key-derivation-and-ledger-compatibility).

## Validators

A *validator* is the Canton node that hosts parties, submits their transactions, and stores the contracts they can see. Ripple Custody doesn't run validators. You or your node provider operate the validator, and Ripple Custody connects to it through three APIs:

| API | Protocol | Purpose |
|  --- | --- | --- |
| Ledger API | gRPC | Creates parties, prepares and executes transactions, and streams ledger updates. |
| Validator API | REST | Provides the Canton Coin registry that transfers and pre-approvals use. |
| DA Registry API | REST | Provides the registry for CIP-56 tokens other than Canton Coin. |


Each party is bound to the validator of the ledger that you create it on. For the division of responsibilities between you and Ripple, see [Architecture and responsibilities](/products/custody/accounts-and-assets/blockchains/canton/architecture-and-responsibilities).

## Canton Coin and CIP-56 tokens

[CIP-56](https://github.com/canton-foundation/cips/blob/main/cip-0056/cip-0056.md), the Canton Token Standard, is comparable to ERC-20 on Ethereum. It defines how token holdings and transfers work, so every conformant token behaves the same way. Ripple Custody supports the CIP-56 holding and transfer interfaces. It doesn't support CIP-56 allocations or delivery versus payment (DvP).

| Asset | Description | Registry | Ticker type in Ripple Custody |
|  --- | --- | --- | --- |
| Canton Coin (CC), also called Amulet | The native asset of the Canton Network. It pays for network traffic and funds validator rewards. | Validator API | `Native` |
| CIP-56 tokens | Tokens that an issuer publishes through the DA Registry. | DA Registry API | `Instrument` |


Two values identify a CIP-56 token:

- `instrumentAdmin`: the party ID of the token's administrator, usually the issuer or registry.
- `instrumentId`: the token's identifier within that administrator's namespace.


Canton Coin's administrator is always the Decentralized Synchronizer Operator (DSO) party. Ripple Custody reads it from the ledger configuration, so a Canton Coin ticker doesn't need these values. Ripple Custody compares the instrument administrator with the DSO party to tell Canton Coin apart from a CIP-56 token with the same name.

All Canton assets use 10 decimal places. For example, 1 CC is `10000000000` in the smallest unit.

The token issuer, not Ripple, deploys a new token's Daml archive (DAR) to the network. Your validator operator installs and updates the DARs for the tokens you hold. After the issuer publishes the token, you register it as a ticker. For more information, see [Register Canton Coin and CIP-56 tokens](/products/custody/accounts-and-assets/blockchains/canton/connect-your-validator#register-canton-coin-and-cip-56-tokens).

## Holdings

Canton represents a balance as a set of discrete contracts called *Holdings*, a model similar to UTXOs. Each Holding records an owner, an instrument, and an amount. The account's balance for an instrument is the sum of its Holdings.

When an account sends assets:

1. Ripple Custody selects Holdings to cover the amount, smallest first. If that selection needs too many Holdings, Ripple Custody selects the largest first instead. For a transfer that settles directly, Ripple Custody reserves the selected Holdings.
2. The transfer spends the selected Holdings.
3. The network creates a new Holding for the receiver and, if the selected Holdings exceed the amount, a new *change* Holding for the sender.


This model has two practical effects:

- **One transfer can spend at most 100 Holdings.** For Canton Coin, the Canton Network enforces this limit. For other CIP-56 tokens, Ripple Custody applies it. Treat 100 as an upper bound: in practice, the limit can be lower. For example, an account with 1,000 Holdings of 1 CC each can send at most 100 CC in one transfer.
- **A reserved Holding serves one transfer at a time.** Ripple Custody reserves Holdings only for transfers that settle directly, not for two-step transfer offers. If an account has one large Holding, a second transfer that starts while the first is in progress fails, even if the balance covers both.


To merge or split Holdings, send a self-transfer. For more information, see [Manage Holdings](/products/custody/accounts-and-assets/blockchains/canton/send-and-receive-api#manage-holdings).

### Holding fees on Canton Coin

Canton Coin Holdings incur a *holding fee* that accrues each network round. The fee doesn't reduce the recorded amount straight away. When the accrued fee on a Holding exceeds the Holding's amount, the network can expire the Holding and remove it. Ripple Custody records an expired Holding as a transfer with no receiver. CIP-56 tokens don't have holding fees.

## Transfer pre-approvals and two-step transfers

A Canton transfer settles in one of two ways, depending on the receiver:

| Receiver state | What happens |
|  --- | --- |
| Has an active *transfer pre-approval* for the asset | The transfer settles directly. The receiver gets a new Holding straight away and doesn't need to sign. |
| Has no pre-approval for the asset | The transfer creates a *transfer offer*, a `TransferInstruction` contract. The sender's Holdings stay locked until the receiver accepts or rejects the offer, the sender withdraws it, or the offer expires. |


A transfer pre-approval is a standing consent that the receiver gives once. Ripple Custody creates pre-approvals with two orders:

- `CreateNativeTransferPreapproval`, once per account, for Canton Coin. Your validator accepts the pre-approval and renews it automatically.
- `CreateTokenTransferPreapproval`, once per account per CIP-56 token.


Pre-approvals are what make Canton work with cold vaults and long approval flows. The account signs once when you set up each pre-approval, and afterward it receives assets without any further signatures.

Pre-approvals accept any amount
A pre-approval settles any incoming amount, with no minimum. Any sender can send repeated dust amounts to a pre-approved account. The account doesn't lose any assets, but the dust transfers appear in its transaction history and lead to Holding fragmentation. For more information, see [Holdings](#holdings).

## Traffic and network fees

Canton has no gas market. Instead, validators buy *traffic* with Canton Coin, and each transaction consumes traffic.

- Your validator operator party pays the network fees for every transaction that your Ripple Custody accounts submit. Keep a Canton Coin balance on the validator operator party to cover them.
- Ripple Custody accounts don't need a Canton Coin balance to pay fees.
- Canton transaction orders have no fee strategy and don't support `maximumFee`. The dry-run fee estimate is always `0`. For more information, see [Transaction estimate](/products/custody/accounts-and-assets/blockchains/canton/reference#transaction-estimate).


## Validator rewards

The Canton Network rewards validators for their activity. It pays rewards to the validator's own service party, never to a Ripple Custody party. The Splice Validator App collects them automatically.

The validator service party's signing key stays with the validator and can't move to external custody. For why, see [Security model](/products/custody/accounts-and-assets/blockchains/canton/architecture-and-responsibilities#security-model).

To hold your rewards in custody, transfer them from the validator service party to a Ripple Custody account's party ID. If the account has a Canton Coin pre-approval, the transfer settles directly. You or your validator operator run this transfer outside Ripple Custody.

## Networks

The Canton Network has three environments. You register each one that you use as a separate ledger in Ripple Custody, with its own validator.

| Network | Purpose |
|  --- | --- |
| MainNet | Production |
| TestNet | Pre-production testing |
| DevNet | Development, reset regularly |


For the network-specific values that you need to register each ledger, see [Canton reference](/products/custody/accounts-and-assets/blockchains/canton/reference#network-identifiers).