This page lists the Canton-specific API fields, identifiers, and errors in Ripple Custody. For task procedures, see Set up Canton accounts with the API and Send and receive Canton assets with the API.
| Intent | Operation | Purpose |
|---|---|---|
v0_CreateLedger | Registers a Canton network as a ledger. | |
v0_ValidateTickers | Registers Canton Coin or a CIP-56 token as a ticker. | |
v0_CreateAccount | Creates an account and derives its party key and party ID. | |
v0_CreateTransactionOrder | CreateParty | Allocates the account's party on the validator. |
v0_CreateTransactionOrder | CreateNativeTransferPreapproval | Creates the account's Canton Coin pre-approval. |
v0_CreateTransactionOrder | CreateTokenTransferPreapproval | Creates the account's pre-approval for one CIP-56 token. |
v0_CreateTransactionOrder | NativeTransfer | Sends Canton Coin. |
v0_CreateTransactionOrder | TokenTransfer | Sends a CIP-56 token. |
v0_CreateTransactionOrder | Withdraw | Cancels an outgoing two-step transfer offer. |
v0_CreateTransactionOrder | Accept | Accepts an incoming two-step transfer offer. |
v0_CreateTransactionOrder | Reject | Rejects an incoming two-step transfer offer. |
v0_CreateLedger takes the following parameters for a Canton ledger. You must provide every field.
| Field | Type | Description |
|---|---|---|
type | string | Canton |
synchronizerId | string, 5–255 characters | The synchronizer ID of the network. The vault checks every prepared transaction against it. |
operatorId | string, 5–255 characters | Your validator's own primary party ID. |
dsoPartyId | string, 5–255 characters | The Decentralized Synchronizer Operator party ID. It's the instrument administrator for Canton Coin. |
daRegistryOperator | string, 5–255 characters | The DA Registry operator party ID. |
v0_CreateLedger also requires id, alias, and customProperties.
| Network | dsoPartyId |
|---|---|
| MainNet | DSO::1220b1431ef217342db44d516bb9befde802be7d8899637d290895fa58880f19accc |
| TestNet | DSO::1220f22a8b8f2d813c25b9a684dc4dd52b532a0174d8e73a13cdf2baabfff7518337 |
| DevNet | DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a |
The daRegistryOperator is the same on all three networks:
DigitalAsset-UtilityOperator::12202679f2bbe57d8cba9ef3cee847ac8239df0877105ab1f01a77d47477fdce1204Get the synchronizerId and operatorId from your validator operator. DevNet resets regularly, so check the DevNet values after each reset.
In v0_ValidateTickers, a Canton ticker's ledgerDetails has type set to Canton and a properties object of one of the following types.
properties.type | Asset | Other fields |
|---|---|---|
Native | Canton Coin | None. |
Instrument | A CIP-56 token | instrumentAdmin (string, 5–255 characters): the party ID of the token's administrator.instrumentId (string, 1–255 characters): the token's instrument ID. |
Set decimals to 10 for every Canton ticker.
For a Canton transaction order, parameters has the following fields.
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Canton |
operation | object | Yes | One of the operations in Operation fields. |
Canton orders don't take a feeStrategy, and they don't support maximumFee. Ripple Custody rejects a Canton order that sets maximumFee.
| Operation | Field | Type | Required | Description |
|---|---|---|---|---|
CreateParty | type | string | Yes | CreateParty |
CreateNativeTransferPreapproval | type | string | Yes | CreateNativeTransferPreapproval |
CreateTokenTransferPreapproval | type | string | Yes | CreateTokenTransferPreapproval |
tickerId | UUID | Yes | The ticker ID of the CIP-56 token. | |
NativeTransfer | type | string | Yes | NativeTransfer |
destination | object | Yes | The receiver: an Address destination with the receiver's party ID, an Endpoint destination, or an Account destination. | |
amount | string | Yes | The amount in the smallest unit, as an integer string. The amount must be greater than zero. | |
executeBefore | date-time | No | The acceptance deadline for a two-step transfer offer. Defaults to 30 days after submission. | |
memo | string, 1–255 characters | No | An on-ledger reference, visible to the sender and receiver. | |
TokenTransfer | type | string | Yes | TokenTransfer |
destination | object | Yes | Same as NativeTransfer. | |
amount | string | Yes | Same as NativeTransfer. | |
tickerId | UUID | Yes | The ticker ID of the CIP-56 token. | |
executeBefore | date-time | No | Same as NativeTransfer. | |
memo | string, 1–255 characters | No | Same as NativeTransfer. | |
Withdraw | type | string | Yes | Withdraw |
contractId | string, 1–255 characters | Yes | The contract ID of your outgoing transfer offer. | |
Accept | type | string | Yes | Accept |
contractId | string, 1–255 characters | Yes | The contract ID of the incoming transfer offer. | |
Reject | type | string | Yes | Reject |
contractId | string, 1–255 characters | Yes | The contract ID of the incoming transfer offer. |
A dry run of a Canton order returns an estimate with type set to Canton and a fee field. The fee is always 0, because your validator operator party pays network fees as traffic.
For a Canton transaction, ledgerTransactionData.ledgerData has type set to Canton and can contain the following fields. Ripple Custody fills them for two-step transfer offers.
| Field | Type | Description |
|---|---|---|
contractId | string | The contract ID of the transfer offer. Use it in Accept, Reject, or Withdraw. |
sender | string | The sender's party ID. |
receiver | string | The receiver's party ID. |
amount | string | The amount in the smallest unit. |
instrumentId | string | The instrument ID of the asset. |
executeBefore | date-time | The deadline for the receiver to accept the offer. |
The ledgerTransactionId of a Canton transaction is the Canton update ID. Ripple Custody sets it after the network sequences the transaction.
A Canton account's party key is an Ed25519 key that Ripple Custody derives in your vault. The vault derives it from the account's ED25519_CUSTODY_1 key on a reserved derivation path, which only the vault's Canton support can use. You can't request a key on this path.
In the keys array of the account's provider details, the party key has the key ID ED25519_CANTON_PARTY_1 and the type VaultReserved:
{
"id": "ED25519_CANTON_PARTY_1",
"publicKey": {
"type": "PublicKey",
"value": "..."
},
"type": "VaultReserved"
}A VaultReserved key has a public key only, never an extended public key. Accounts without a Canton ledger don't have VaultReserved keys. If your integration reads the keys array, make sure it accepts this type before you create Canton accounts.
The party key appears in the keys array when you first add your Canton ledger to the account, with a v0_CreateAccount intent that includes the Canton ledger ID in ledgerIds, or with a v0_AddAccountLedgers intent.
The party key doesn't need a separate backup. The vault re-derives it from the account's ED25519_CUSTODY_1 key whenever it needs it, so backing up the vault covers it. After a restore, the key reappears in the keys array when the notary replays the request that first added the Canton ledger to the account.
c::<fingerprint>The fingerprint identifies the account's Ed25519 public key, so you can reproduce the party ID from the public key alone. For more information, see Parties and party IDs.
| Limit | Value |
|---|---|
| Decimal places for Canton assets | 10 |
| Maximum Holdings spent by one transfer | 100, as an upper bound. The network enforces it for Canton Coin, and Ripple Custody applies it to other CIP-56 tokens. The effective limit can be lower. |
| Time from preparing a transaction to executing it | 24 hours |
| Default deadline for a two-step transfer offer | 30 days |
| Minimum amount settled through a pre-approval | None |
Maximum memo length | 255 characters |
| Symptom | Cause | Resolution |
|---|---|---|
| A transfer fails with an invalid destination error. | The receiver party doesn't exist on the network. This happens when the receiving Ripple Custody account hasn't completed CreateParty. | Check the party ID. If the receiver is your own account, complete Step 2: Create the party. |
| An incoming transfer appears as a pending offer instead of a settled Holding. | The receiving account has no pre-approval for the asset. | Accept or reject the offer. To avoid offers in the future, create the missing pre-approval. |
| A transfer fails even though the balance covers the amount. | The transfer needs more Holdings than one transfer can spend, or another transfer in progress has reserved the account's Holdings. | Merge or split Holdings with a self-transfer. For more information, see Manage Holdings. |
| A transaction fails after a long signing delay. | More than 24 hours passed between preparing the transaction and executing it. The network rejects the prepared transaction. | Submit the order again, so that it's prepared and signed again. For cold vaults, see Set up cold vault accounts. |
A transaction stays in the Broadcasting status without a ledger transaction ID. | Ripple Custody hasn't observed the committed update yet. | Wait for the indexer to observe the update. If the status doesn't change, check the validator's health and connectivity. |
| The vault refuses to sign. | The prepared transaction doesn't match the approved intent, or its synchronizer ID doesn't match the ledger's synchronizerId. | Check the ledger parameters and the intent. Contact your Ripple liaison if the problem continues. |
| Ripple Custody can't connect to the validator. | An endpoint uses plaintext http, a firewall blocks the indexer, the Ledger API is behind a forward proxy, or the credentials are missing or out of date. | Check the validator prerequisites. |
| A balance looks out of date. | The indexed balance drifted from the validator's Holdings. | Force an account balance update. |
To confirm on-ledger state independently of Ripple Custody, look up the party in a Canton block explorer, such as Cantonscan for MainNet or CCView for DevNet.