Programmable Token Transfers: Canton as Destination

This tutorial demonstrates how to send a programmable token transfer (PTT) from Ethereum Sepolia to Canton — TEST tokens plus arbitrary data — and execute it on Canton using the ccip-starter-kit-canton.

Introduction

A programmable token transfer delivers both tokens and a data payload to the destination. On Canton, execution:

  1. Resolves or creates a CCIPReceiver for the message finality.
  2. Processes TokenReceiveTicket and mints LINK via the token pool.
  3. Delivers the attached data to your receiver logic through ccipReceive on Canton.

What You Will Build

In this tutorial, you will:

  • Send 1 TEST plus a UTF-8 data string from Sepolia with any2canton:data-and-token.
  • Execute on Canton with any2canton:manual-exec.
  • Verify LINK balance and message execution.

Understanding Programmable Token Transfers (any2canton)

AspectToken-onlyProgrammable token transfer
Send scriptany2canton:tokenany2canton:data-and-token
DataEmpty--dataString payload
Canton executionLINK mint + accept TransferInstructionLINK mint + data delivered to receiver

The execution path fetches proofs, Global CCIP EDS disclosures, and token pool operator EDS inputs — see the Canton as Destination flow.

Running the Tutorial

Prerequisites Check

  1. Complete prerequisites.

  2. Mint TEST on Sepolia:

    Terminal
    npm run faucet:evm-test
    

Step 1: Send data + TEST from Sepolia

Terminal
npm run any2canton:data-and-token -- --dataString "Hello" --amount 1

Pay CCIP fee in LINK and use block-depth finality:

Terminal
npm run any2canton:data-and-token -- \
  --dataString "Hello" \
  --amount 1 \
  --feeToken link \
  --finality 32

Expected send output

📧🪙 Sending data + 1 TEST from Sepolia → Canton: "Hello"
   Receiver party: yourParty::1220…
   LINK is minted on Canton only after manual execution.
🆔 CCIP Message ID: 0x…

⚙️  Execute on Canton once Sepolia reaches 32 block confirmations for this message:
   npm run any2canton:manual-exec -- 0x<sepoliaTxHash>

Step 2: Execute on Canton

After finality and Committee Verifier proofs are on the indexer:

Terminal
npm run any2canton:manual-exec -- <sepoliaTxHash>

Optional custom receiver hint:

Terminal
npm run any2canton:manual-exec -- <sepoliaTxHash> --receiver 'yourParty::1220…'

Verification

  1. CCIP Explorer: Confirm SUCCESS for the transfer.
  2. LINK balance: npm run check-balance -- --chain canton --token link
  3. Canton Lighthouse: Inspect the execution transaction for token pool and receiver activity.

Get the latest Chainlink content straight to your inbox.