Token Transfers: Canton as Source
This tutorial demonstrates how to transfer LINK tokens from Canton testnet to Ethereum Sepolia using the ccip-starter-kit-canton.
Introduction
This tutorial covers a token-only transfer from Canton to Ethereum Sepolia without an attached data payload. When you transfer tokens using CCIP:
- Tokens are burned or locked in the token pool on Canton.
- Equivalent tokens are minted or released on Sepolia after destination execution.
- CCIP fees are collected on Canton in Amulet (default) or LINK.
The prod testnet lane maps Canton LINK to Sepolia TEST.
What You Will Build
In this tutorial, you will:
- Run
canton2any:tokento send LINK from Canton to Sepolia. - Pay CCIP fees in Amulet or LINK.
- Monitor the transfer in the CCIP Explorer.
- Verify TEST token balance on Sepolia after execution.
Understanding Token Transfers (canton2any)
Key points for token-only transfers from Canton:
- Burn and mint: LINK is burned on Canton; TEST is minted on Sepolia for the configured lane.
- Fee payment: CCIP fees are paid on Canton. Default fee token is Amulet; pass
--feeToken linkto pay in LINK. - No data payload: Token-only transfers omit the
datafield. - Token pool: The SDK fetches disclosures from the token pool operator EDS and obtains a
TokenPoolTicketduring send.
See the Canton as Source flow in the overview.
How the Script Works
The scripts/canton2any/ccipSendToken.ts script:
- Loads Canton config, authenticates to the ledger, and connects.
- Parses
--amount(human-readable LINK, e.g.0.001),--feeToken,--evmReceiver, and--no-exec. - Builds a message with
tokenAmountsfor the Canton LINK instrument and submits viaCantonChain.sendMessage. - Prints the CCIP Message ID, explorer links, and optional manual-exec hint.
Running the Token Transfer
Prerequisites Check
-
Complete prerequisites.
-
Verify LINK and Amulet balances:
Terminalnpm run check-balance -- --chain canton --token link npm run check-balance -- --chain canton --token amulet -
Set
EVM_PRIVATE_KEYif you will verify Sepolia balances or run manual execution.
Execute the Script
Send 0.001 LINK from Canton to Sepolia (default receiver):
npm run canton2any:token -- --amount 0.001
Pay CCIP fee in LINK:
npm run canton2any:token -- --amount 0.001 --feeToken link
Skip auto-execution on Sepolia:
npm run canton2any:token -- --amount 0.001 --no-exec
Understanding the Output
๐ช Sending 0.001 LINK from Canton โ Sepolia
Executor: default (auto-execution on Sepolia when an executor is configured)
๐ CCIP Message ID: 0xโฆ
๐ CCIP Explorer: https://ccip.chain.link/#/side-drawer/msg/0xโฆ
๐ Canton transaction: https://lighthouse.testnet.cantonloop.com/transactions/โฆ
Verification and Monitoring
CCIP Explorer
Track the full message lifecycle using the CCIP Explorer URL from the output.
Manual execution on Sepolia
If you used --no-exec:
npm run canton2any:manual-exec -- <cantonUpdateId | messageId>
Pass either the Canton update ID (๐ Canton transaction / Lighthouse link) or the CCIP Message ID (๐ CCIP Message ID, 0xโฆ) from the send output โ canton2any:manual-exec accepts both.
Verify TEST balance on Sepolia
After successful execution, check the Sepolia wallet that received TEST:
npm run check-balance -- --chain sepolia --token test
Or inspect the receiver address on Sepolia Etherscan.