Prerequisites for Canton as Source Tutorials

Before starting the Canton as Source (canton2any) tutorials, ensure you have the following:

Development Environment

  • Node.js v20 or higher: You can use the nvm package to install and switch between Node.js versions. Once installed, verify the node version with:

    Terminal
    node -v
    

    Example output:

    $ node -v
    v22.15.0
    
  • npm: For installing and managing dependencies.

  • Git: For cloning the repository.

Starter Kit Repository

  1. Clone the CCIP Canton Starter Kit:

    Terminal
    git clone https://github.com/smartcontractkit/ccip-starter-kit-canton.git
    
  2. Navigate to the directory:

    Terminal
    cd ccip-starter-kit-canton
    
  3. Install dependencies:

    Terminal
    npm install
    

The starter kit uses @chainlink/ccip-sdk v1.10+ for Canton and Ethereum Sepolia interactions.

Understanding Canton Configuration (canton-config.json)

Canton deployment fields live in config/canton-config.json. Copy the example file and replace the two placeholder fields:

Terminal
cp config/canton-config.example.json config/canton-config.json

Replace party with your Canton testnet party ID (it must match your Okta application). Replace transferInstructionUrl with your validator's transfer-instruction API (Amulet fee transfers and token metadata — not EDS). On CCIP testnet with Chainlink-hosted parties, contact Chainlink for your assigned validator URL and ledger access. If you run your own validator, use your validator's transfer-instruction API URL instead.

All other fields (edsUrl, indexerUrl, ccipParty, ccvs, senderInstanceId, etc.) are pre-configured for the Canton CCIP testnet lane in canton-config.example.json.

Example canton-config.json:

config/canton-config.json
{
  "party": "YOUR_LEDGER_PARTY::1220…",
  "ccipParty": "ccipOwner::1220e382f4e57b0815e6be737006e381e6b7de448e06bd033ece6df498017879f551",
  "edsUrl": "https://eds.testnet.ccip.chain.link",
  "transferInstructionUrl": "https://validator.example.com/api/validator",
  "indexerUrl": "https://indexer-1.testnet.ccip.chain.link",
  "chainId": "canton:TestNet",
  "senderInstanceId": "prod-ccipsender",
  "ccvs": ["0xec1e288bcf8bbf034ac2d31b67f9b15a3f1f828d086c5b9d8fc2866129cd02fe"]
}

Key fields:

  • party: Your ledger party — the sender for canton2any scripts and the default Canton receiver for any2canton scripts.
  • transferInstructionUrl: Your validator's transfer-instruction API. Depends on which validator hosts your party (not the Global CCIP EDS at edsUrl).
  • senderInstanceId: The CCIPSender instance used when sending from Canton.
  • ccvs: CommitteeVerifier contract IDs required for message validation.
  • edsUrl / indexerUrl: Global CCIP Explicit Disclosure Service and indexer endpoints for proofs and disclosures.

Network selectors, router addresses, token instruments, and the default --gasLimit (50000 for destination ccipReceive) are defined in helperConfig.ts.

Optional script flags

Send scripts (canton2any:* and any2canton:*) share these common flags:

FlagDefaultDescription
--gasLimit50000Gas limit for ccipReceive on the destination chain (Sepolia for canton2any, Canton for any2canton)
--feeTokennativeCCIP fee token on the source chain (native: Amulet on Canton, ETH on Sepolia; or link)
--evmReceiver / --cantonReceiverSee configOverride the default receiver on the destination chain
--no-execauto-exec oncanton2any only — skip automatic execution on Sepolia; run canton2any:manual-exec after CCV verification
--finalityfinalizedany2canton only — requested source finality (finalized or block depth, e.g. 32)

Canton Ledger Access

Canton sends and executes use JWT authentication + direct ledger submit (same as ccip-cli without --wallet). No local signing key is required for participant-hosted parties.

Scripts obtain a JWT automatically via Okta client credentials (CANTON_AUTH_URL, CANTON_CLIENT_ID, and CANTON_CLIENT_SECRET in .env). Resolution order:

  1. CANTON_JWT in .env (explicit override)
  2. Client credentials → fresh token from Okta
  3. jwt field in canton-config.json (fallback only)

Wallets and Accounts

  • Canton party: Your on-ledger party ID in canton-config.json. Scripts submit commands on behalf of this party via submit-and-wait-for-transaction.

  • Ethereum Sepolia account (optional for source sends): Required only if you run canton2any:manual-exec on Sepolia or want to verify token delivery on the destination chain. Set EVM_PRIVATE_KEY and ETHEREUM_SEPOLIA_RPC_URL in .env. For data-only sends with default auto-execution, you only need the receiver contract address on Sepolia (the starter kit provides a default).

Environment Configuration (.env file)

Create .env from the example and replace every placeholder:

Terminal
cp .env.example .env
VariableDescription
EVM_PRIVATE_KEYSepolia signer private key (hex, with or without 0x)
ETHEREUM_SEPOLIA_RPC_URLYour Sepolia JSON-RPC URL
CANTON_LEDGER_URLCanton participant JSON Ledger API URL (not EDS or the validator)
CANTON_CONFIG_PATHPath to canton-config.json (default: ./config/canton-config.json)
CANTON_AUTH_URLOkta authorization server URL for your Canton party
CANTON_CLIENT_IDOkta client ID for your Canton party
CANTON_CLIENT_SECRETOkta client secret — scripts fetch a fresh JWT on each run

Example .env file:

.env
EVM_PRIVATE_KEY=0xYourSepoliaPrivateKey
ETHEREUM_SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY
CANTON_LEDGER_URL=https://your-canton-ledger-api.example.com
CANTON_CONFIG_PATH=./config/canton-config.json
CANTON_AUTH_URL=https://auth.example.com
CANTON_CLIENT_ID=your_okta_client_id
CANTON_CLIENT_SECRET=your_okta_client_secret

Testnet Tokens

Amulet (default CCIP fee token on Canton)

canton2any scripts pay CCIP fees in Amulet by default. Fund your Canton party with Amulet holdings before sending.

Check balances:

Terminal
npm run check-balance

Or check Amulet only:

Terminal
npm run check-balance -- --chain canton --token amulet

Token transfer and programmable token transfer tutorials send LINK from Canton to Sepolia. Your party needs LINK (link-token) holdings on Canton.

Terminal
npm run check-balance -- --chain canton --token link

Pass --feeToken link on send scripts to pay CCIP fees in LINK instead of Amulet.

Sepolia ETH (optional)

If you run canton2any:manual-exec yourself, your Sepolia account needs test ETH for gas. Use the Chainlink Faucet to obtain test ETH.

Verify Setup

From the starter kit root, confirm Canton connectivity and balances:

Terminal
npm run check-balance

You should see LINK and Amulet balances for your Canton party. If you configured EVM_PRIVATE_KEY, Sepolia LINK and TEST balances are shown as well.

When setup is complete, continue to the Canton as Source tutorials.

Get the latest Chainlink content straight to your inbox.