Skip to content

Canton reference

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.

Intents and operations

IntentOperationPurpose
v0_CreateLedgerRegisters a Canton network as a ledger.
v0_ValidateTickersRegisters Canton Coin or a CIP-56 token as a ticker.
v0_CreateAccountCreates an account and derives its party key and party ID.
v0_CreateTransactionOrderCreatePartyAllocates the account's party on the validator.
v0_CreateTransactionOrderCreateNativeTransferPreapprovalCreates the account's Canton Coin pre-approval.
v0_CreateTransactionOrderCreateTokenTransferPreapprovalCreates the account's pre-approval for one CIP-56 token.
v0_CreateTransactionOrderNativeTransferSends Canton Coin.
v0_CreateTransactionOrderTokenTransferSends a CIP-56 token.
v0_CreateTransactionOrderWithdrawCancels an outgoing two-step transfer offer.
v0_CreateTransactionOrderAcceptAccepts an incoming two-step transfer offer.
v0_CreateTransactionOrderRejectRejects an incoming two-step transfer offer.

Ledger parameters

v0_CreateLedger takes the following parameters for a Canton ledger. You must provide every field.

FieldTypeDescription
typestringCanton
synchronizerIdstring, 5–255 charactersThe synchronizer ID of the network. The vault checks every prepared transaction against it.
operatorIdstring, 5–255 charactersYour validator's own primary party ID.
dsoPartyIdstring, 5–255 charactersThe Decentralized Synchronizer Operator party ID. It's the instrument administrator for Canton Coin.
daRegistryOperatorstring, 5–255 charactersThe DA Registry operator party ID.

v0_CreateLedger also requires id, alias, and customProperties.

Network identifiers

NetworkdsoPartyId
MainNetDSO::1220b1431ef217342db44d516bb9befde802be7d8899637d290895fa58880f19accc
TestNetDSO::1220f22a8b8f2d813c25b9a684dc4dd52b532a0174d8e73a13cdf2baabfff7518337
DevNetDSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a

The daRegistryOperator is the same on all three networks:

DigitalAsset-UtilityOperator::12202679f2bbe57d8cba9ef3cee847ac8239df0877105ab1f01a77d47477fdce1204

Get the synchronizerId and operatorId from your validator operator. DevNet resets regularly, so check the DevNet values after each reset.

Ticker ledger details

In v0_ValidateTickers, a Canton ticker's ledgerDetails has type set to Canton and a properties object of one of the following types.

properties.typeAssetOther fields
NativeCanton CoinNone.
InstrumentA CIP-56 tokeninstrumentAdmin (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.

Transaction order parameters

For a Canton transaction order, parameters has the following fields.

FieldTypeRequiredDescription
typestringYesCanton
operationobjectYesOne 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 fields

OperationFieldTypeRequiredDescription
CreatePartytypestringYesCreateParty
CreateNativeTransferPreapprovaltypestringYesCreateNativeTransferPreapproval
CreateTokenTransferPreapprovaltypestringYesCreateTokenTransferPreapproval
tickerIdUUIDYesThe ticker ID of the CIP-56 token.
NativeTransfertypestringYesNativeTransfer
destinationobjectYesThe receiver: an Address destination with the receiver's party ID, an Endpoint destination, or an Account destination.
amountstringYesThe amount in the smallest unit, as an integer string. The amount must be greater than zero.
executeBeforedate-timeNoThe acceptance deadline for a two-step transfer offer. Defaults to 30 days after submission.
memostring, 1–255 charactersNoAn on-ledger reference, visible to the sender and receiver.
TokenTransfertypestringYesTokenTransfer
destinationobjectYesSame as NativeTransfer.
amountstringYesSame as NativeTransfer.
tickerIdUUIDYesThe ticker ID of the CIP-56 token.
executeBeforedate-timeNoSame as NativeTransfer.
memostring, 1–255 charactersNoSame as NativeTransfer.
WithdrawtypestringYesWithdraw
contractIdstring, 1–255 charactersYesThe contract ID of your outgoing transfer offer.
AccepttypestringYesAccept
contractIdstring, 1–255 charactersYesThe contract ID of the incoming transfer offer.
RejecttypestringYesReject
contractIdstring, 1–255 charactersYesThe contract ID of the incoming transfer offer.

Transaction estimate

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.

Transaction ledger data

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.

FieldTypeDescription
contractIdstringThe contract ID of the transfer offer. Use it in Accept, Reject, or Withdraw.
senderstringThe sender's party ID.
receiverstringThe receiver's party ID.
amountstringThe amount in the smallest unit.
instrumentIdstringThe instrument ID of the asset.
executeBeforedate-timeThe 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.

Account keys

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.

Party ID format

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.

Limits

LimitValue
Decimal places for Canton assets10
Maximum Holdings spent by one transfer100, 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 it24 hours
Default deadline for a two-step transfer offer30 days
Minimum amount settled through a pre-approvalNone
Maximum memo length255 characters

Errors and troubleshooting

SymptomCauseResolution
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.