Overview

Designed by Digital Asset, Canton enables a “network of networks” that supports secure, interoperable transactions between financial institutions while maintaining strict privacy controls. At its core, the Canton Protocol provides a decentralized infrastructure that connects previously siloed financial systems.

The protocol uses Daml, an open source smart contract language, to define and execute agreements between parties in a secure, permissioned, and auditable manner. Daml specifies exactly who has authorization to view or modify any given contract.

The Canton Network—a public, permissioned blockchain—is the broader ecosystem of parties running Daml applications that communicate through the Canton blockchain protocol.

Canton Coin is the native asset of the Canton blockchain. It uses:

  • A UTXO model
  • The EdDSA signature algorithm

Canton Coin employs a burn-and-mint equilibrium model with the following characteristics:

  • Minting is inflationary: token supply increases over time until it reaches an equilibrium.
  • The protocol permanently removes synchronizer fees (for example, those paid for using a Super Validator) from circulation by burning them.
  • All synchronizer fees use USD as the denomination.
  • Token price uses USD as the denomination and may fluctuate based on market value.

Explorer

https://ccview.io/

Wallets Types

BitGo enables holding Canton in the following wallet types:

Multisig Cold Multisig Hot MPC Cold MPC Hot
Custodial
Self Managed

Ticker Symbols

Mainnet Testnet
canton tcanton

Units

Canton is divisible to 10⁻¹⁰.

Balances may be represented as integers or strings. BitGo recommends using string format to avoid exceeding JavaScript numeric limits.

Tokens

Token support on Canton blockchain is coming soon

Fees

Canton has zero fees for Canton Coin transactions, as CIP-0078 defines.

Address Format

Canton addresses follow the format: <partyHint>::<fingerprint>. The fingerprint is exactly 68 characters in length and it has a human-readable part called partyHint. The partyHint can be set to anything and BitGo sets the first 5 characters of the fingerprint as the partyHint. The fingerprint adheres to the following regular expression:

/^[a-fA-F0-9]{68}$/

Wallet Initialization

Canton network requires the wallet address to be initialized, meaning the address created during wallet creation must register on-chain. This is a transaction and requires to be signed using User keys. Before initializing the address, no activities can be done on-chain. User must be an Admin with spending rights to be able to initialize the request.

Note: User must have BitGo Offline Vault OVC 4.11.4 or later for BitGo Offline Vault wallet initialization.

2-Step Transfer

This is the default behavior of the chain where the receiver has an option to either accept or reject the incoming transaction. The sender can set an expiry for this offer. Canton merges and burns the input UTXO and creates two new UTXOs:

  • UTXO with the intended transfer value — locked on-chain (awaiting receiver acceptance)
  • UTXO with the change amount back to the sender — returned to the sender

BitGo recommends all users enable 1-Step Transfer for Canton Coin.

1-Step Transfer

This is an enhancement on top of 2-step; when enabled, deposits are auto-accepted. Only Canton Coin supports 1-step transfers. Enabling this requires signing with User Keys (an on-chain update signed by the User).

Memo ID Support

  • Optionally, a ?memoId=<n> query parameter can be appended to the address for use cases such as identifying transaction metadata. Here, <n> can be any integer.
  • Using memoId-based addressing eliminates the need to generate multiple deposit addresses per user. A single static address can be reused safely across users and use cases, with the memoId serving as the unique identifier.
  • Since Canton uses memoId-based receive addresses, manual consolidation is not required.

Canton Transfers

Canton uses a UTXO-based transaction model, which affects how the protocol constructs, validates, and optimizes transfers on-chain.

Key Transfer Concepts

  • UTXO Model Canton operates on a UTXO (Unspent Transaction Output) model rather than an account-balance model. Each transfer consumes one or more UTXOs as inputs and produces new UTXOs as outputs.

  • Input Limits A single transfer can include up to 100 input Holding UTXOs. This prevents transactions from becoming excessively large or expensive to validate.

  • Holding Fees Every Holding UTXO continuously incurs a holding fee, denominated in USD. This fee causes UTXOs to self-deplete over time and discourages the creation of very small (“dust”) UTXOs.

    Let:

    • annualHoldingFeeUSD = the annual USD-denominated holding fee applied per UTXO
    • dailyHoldingFeeUSD = annualHoldingFeeUSD / 365.25
    • price = the CC/USD price from the current mining round (from /v0/scan-proxy/open-and-issuing-mining-rounds)

    Minimum viable UTXO amount: minimumAmountCC = dailyHoldingFeeUSD / price

    UTXO shelf life: lifetimeDays = (amountCC * price * 365.25) / annualHoldingFeeUSD

  • Key behaviors

    • Smaller UTXOs have shorter lifetimes.
    • When accrued fees exceed UTXO value, the UTXO is fully depleted and archived (effectively burned).
    • It is best practice to merge small UTXOs regularly to minimize depletion.
  • Change Handling When multiple input UTXOs are present:

    • The protocol merges them internally.
    • The protocol returns any remaining balance as a single new Holding UTXO, helping reduce UTXO fragmentation.

Transfer Workflows

Canton supports multiple transfer workflows depending on asset type and configuration.

  • 1-Step Transfers Enables instant, direct transfers without receiver interaction. Requirements:

    • The receiver must configure TransferPreapproval contracts.
    • The sender should include the receiver's TransferPreapproval contract while building the transaction.
    • Supported only for Canton Coin.
  • 2-Step Transfers (Default) Used when TransferPreapproval is not configured or when transferring other token types. Workflow:

    1. Sender creates a deposit offer.
    2. Receiver must explicitly accept the offer.
    3. Funds move only after the acceptance.
  • Self-Transfers Recommended for internal UTXO management:

    • Merging small UTXOs
    • Reducing holding fees
    • Preparing for large withdrawals
    • Avoiding dust accumulation Self-transfers follow the same UTXO rules but with sender = receiver.

Transfer SubTypes

In the Canton 2-step transfer flow, multiple transfers can be created as the offer progresses through different states. The transfer type and subType depend on whether the wallet is acting as the Sender or Receiver, and on the outcome of the offer.

Why Transfer SubTypes Exist

Canton introduced transfer subTypes to clearly distinguish between:

  • Intent / offer creation, where no funds move on-chain
  • Confirmed transfers, where actual value movement occurs

This allows consumers to correctly interpret transfer intent, balance impact, and final settlement without relying on heuristics.

pending_* SubTypes

Transfers with pending_* subTypes represent offers only and do not move funds. This locks the sender input utxo till acceptance or rejection or expiry of the offer occurs.

Key characteristics:

  • The transfer value is zero
  • No funds transfer between sender and receiver
  • Sender input utxo locks & spendable balance decreases
  • The system records the intended transfer amount in coinSpecific.<coinName>.hold

The hold amount represents the proposed transfer:

  • Sender: negative hold value
  • Receiver: positive hold value

This allows clients to understand the intended amount while ensuring balances are not affected until confirmation.

confirmed_* SubTypes

Transfers with confirmed_* subTypes represent actual money movement. These transfers reflect finalized settlement after the receiver accepts the offer.

Transfer Count by Role and Outcome

Sender

In a 2-step withdrawal flow, the sender observes the following transfers:

  • Offer accepted

  • withdrawalpending_withdrawal_offer

  • withdrawalconfirmed_withdrawal

  • Offer rejected

  • withdrawalpending_withdrawal_offer

  • depositwithdrawal_offer_rejected

  • Offer expired

  • withdrawalpending_withdrawal_offer

  • depositwithdrawal_offer_expired

Receiver

The receiver observes the following transfers:

  • Offer accepted (3 transfers)

  • depositpending_deposit_offer

  • depositconfirmed_deposit

  • withdrawaloffer_ack

  • Offer rejected (2 transfers)

  • depositpending_deposit_offer

  • withdrawaloffer_reject

Sender-side Transfers

Scenario Transfer Type Transfer SubType Description
2-step offer accepted by receiver withdrawal confirmed_withdrawal Withdrawal confirmed after the receiver accepts the offer
2-step offer created withdrawal pending_withdrawal_offer Initial withdrawal created when the sender creates a 2-step offer
2-step offer expired deposit withdrawal_offer_expired The protocol returns funds to the sender when the offer expires
2-step offer rejected by receiver deposit withdrawal_offer_rejected The protocol returns funds to the sender when the receiver rejects the offer

Receiver-side Transfers

Scenario Transfer Type Transfer SubType Description
2-step offer accepted deposit confirmed_deposit Deposit confirmed after accepting the offer
2-step offer received deposit pending_deposit_offer Deposit created when the receiver receives a 2-step offer
Offer acknowledgment (on accept) withdrawal offer_ack Acknowledgment transfer created when the receiver accepts the offer
Offer rejection (on reject) withdrawal offer_reject Transfer created when the receiver rejects the offer

UTXO expiry is independent of the 2-step transfer flow and can occur for any wallet. When a UTXO expires, it results in an on-chain burn represented by the following transfer:

Scenario Transfer Type Transfer SubType Description
UTXO expired withdrawal utxo_expired On-chain burn caused by UTXO expiry

1-Step Transfer SubTypes

Currently, 1-step transfers do not have a subType. The system represents them only by the transfer type.

Role Transfer Type Transfer SubType
Receiver deposit not present
Sender withdrawal not present

Note: If a payment transfer does not have a subType, it can be treated as a 1-step transfer. Consumers should not rely on 2-step semantics when subType is absent.

BitGo-Specific Notes

  • Minimum withdrawal amount: 1 CANTON

Create Wallet

    export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
    export COIN="tcanton"
    export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
      export LABEL="<DESIRED_WALLET_NAME>"
        export PASSPHRASE="<YOUR_BITGO_LOGIN_PASSPHRASE>"
          export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"

            curl -X POST \
            http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/generate \
            -H 'Content-Type: application/json' \
            -H "Authorization: Bearer $ACCESS_TOKEN" \
            -d '{
              "label": "'"$LABEL"'",
              "passphrase": "'"$PASSPHRASE"'",
              "enterprise": "'"$ENTERPRISE_ID"'",
              "disableTransactionNotifications": true,
              "disableKRSEmail": true
            }'

Create Address

    export COIN="tcanton"
    export WALLET_ID="<YOUR_WALLET_ID>"
    export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"

      curl -X POST \
      https://app.bitgo-test.com/api/v2/$COIN/wallet/$WALLET_ID/address \
      -H 'Content-Type: application/json' \
      -H "Authorization: Bearer $ACCESS_TOKEN"

Transact

You can use the sendMany function to send canton coin to a recipient in a transaction. Currently, BitGo only supports sending to a single recipient in a transaction.

    export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
    export COIN="tcanton"
    export WALLET_ID="<YOUR_WALLET_ID>"
    export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
    export ADDRESS="<DESTINATION_ADDRESS>"
    export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
    export WALLET_PASSPHRASE="<YOUR_WALLET_PASSPHRASE>"

      curl -X POST \
      http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/$WALLET_ID/sendmany \
      -H 'Content-Type: application/json' \
      -H "Authorization: Bearer $ACCESS_TOKEN" \
      -d '{
      "recipients": [
        {
           "address": "'"$ADDRESS"'",
           "amount": "'"$AMOUNT"'"
        },
      ],
      "walletPassphrase": "'"$WALLET_PASSPHRASE"'",
      "type": "transfer",
      "isTss": "true"
      }'

2-Step Deposit Acceptance/Rejection

If you have not enabled 1-step deposits on your canton wallet, then for every deposit, Canton creates an acknowledgement transaction request and you need to explicitly accept or reject it.

Note: The below snippet creates the acceptance/rejection transaction request; you still need to sign it.

    export BITGO_EXPRESS_HOST="<YOUR_LOCALHOST>"
    export WALLET_ID="<YOUR_WALLET_ID>"
    export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
    export ACKNOWLEDGE_TXREQUEST_ID="<DEPOSIT_ACK_TXREQUEST_ID>"

    curl -X POST \
    http://$BITGO_EXPRESS_HOST/api/v2/wallet/$WALLET_ID/txrequests \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -d '{
      "intent": {
        "intentType": "transferAccept", // "transferReject"
        "txRequestId": "'"$ACKNOWLEDGE_TXREQUEST_ID"'"
      },
      "preview": false,
      "apiVersion": "full"
    }'