# Token Transfers: Canton as Source
Source: https://docs.chain.link/ccip/canton/tutorials/source/token-transfers
Last Updated: 2026-07-06

> For the complete documentation index, see [llms.txt](/llms.txt).

> **CAUTION**
>
> Addresses shown may change due to upgrades since Canton contracts are immutable. Confirm party IDs and contract addresses with [Chainlink CCIP](https://chain.link/ccip-contact).

This tutorial demonstrates how to transfer **LINK** tokens from Canton testnet to Ethereum Sepolia using the [`ccip-starter-kit-canton`](https://github.com/smartcontractkit/ccip-starter-kit-canton).

> **NOTE: Prerequisites**
>
> Complete the [Canton as Source prerequisites](/ccip/canton/tutorials/source/prerequisites). For token transfers you also need:
>
> - **LINK** holdings on your Canton party (the token being sent).
> - **Amulet** (or LINK with `--feeToken link`) for CCIP fees.
> - A registered token pool on the Token Admin Registry — the prod testnet **LINK ↔ TEST** lane is pre-configured. For custom instruments, see [Cross-Chain Token guides](/ccip/canton/tutorials/cross-chain-tokens).
>
> These steps use **Canton testnet** and **Ethereum Sepolia** only.

## Introduction

This tutorial covers a token-only transfer from Canton to Ethereum Sepolia without an attached data payload. When you transfer tokens using CCIP:

1. Tokens are burned or locked in the token pool on Canton.
2. Equivalent tokens are minted or released on Sepolia after destination execution.
3. 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:token` to send LINK from Canton to Sepolia.
- Pay CCIP fees in Amulet or LINK.
- Monitor the transfer in the [CCIP Explorer](/ccip/tools-resources/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 link` to pay in LINK.
- **No data payload**: Token-only transfers omit the `data` field.
- **Token pool**: The SDK fetches disclosures from the token pool operator EDS and obtains a `TokenPoolTicket` during send.

See the [Canton as Source flow](/ccip/canton/concepts/overview#canton--public-chain) in the overview.

## How the Script Works

The `scripts/canton2any/ccipSendToken.ts` script:

1. Loads Canton config, authenticates to the ledger, and connects.
2. Parses `--amount` (human-readable LINK, e.g. `0.001`), `--feeToken`, `--evmReceiver`, and `--no-exec`.
3. Builds a message with `tokenAmounts` for the Canton LINK instrument and submits via `CantonChain.sendMessage`.
4. Prints the CCIP Message ID, explorer links, and optional manual-exec hint.

## Running the Token Transfer

### Prerequisites Check

1. Complete [prerequisites](/ccip/canton/tutorials/source/prerequisites).

2. Verify LINK and Amulet balances:

   ```bash filename="Terminal"
   npm run check-balance -- --chain canton --token link
   npm run check-balance -- --chain canton --token amulet
   ```

3. Set `EVM_PRIVATE_KEY` if you will verify Sepolia balances or run manual execution.

### Execute the Script

Send `0.001` LINK from Canton to Sepolia (default receiver):

```bash filename="Terminal"
npm run canton2any:token -- --amount 0.001
```

Pay CCIP fee in LINK:

```bash filename="Terminal"
npm run canton2any:token -- --amount 0.001 --feeToken link
```

Skip auto-execution on Sepolia:

```bash filename="Terminal"
npm run canton2any:token -- --amount 0.001 --no-exec
```

### Understanding the Output

```text
🪙 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`:

```bash filename="Terminal"
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:

```bash filename="Terminal"
npm run check-balance -- --chain sepolia --token test
```

Or inspect the receiver address on [Sepolia Etherscan](https://sepolia.etherscan.io/).

> **NOTE: Decimals**
>
> Canton LINK uses **10** decimal places in the starter kit configuration (`helperConfig.ts`), not the 18 decimals used on Sepolia ERC-20 tokens.

> **CAUTION: Educational Example Disclaimer**
>
> Please note, this page contains community examples only — these are not Chainlink products or services and are not
> supported or maintained by Chainlink. This code represents an example of using a Chainlink product or service, and is
> intended for demonstration and educational purposes only. It is provided "AS IS" and "AS AVAILABLE" without warranties
> of any kind, may not have been audited, and may omit checks or error handling. Each party intending to use this
> example code does so entirely at their own risk and must perform its own audits, security and code review, key
> management, and testing before any production deployment and ensure the operation and performance of such code matches
> expectations. Neither Chainlink Labs nor the Chainlink Foundation deploys, operates, monitors, maintains or endorses
> any deployment of this code. Note that this is not a Chainlink product, feature or service, and there are no
> commitments made with respect to the code, including compatibility with future Chainlink releases. You should not rely
> on this code without first conducting your own technical, engineering, and security review. This code is also outside
> the scope of any Chainlink bug bounty programs. Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node
> operators are responsible for outcomes due to errors in this example or how it is deployed or operated, or liable for
> any resulting claims or damages. Use of the Chainlink Network is subject to the Chainlink Foundation [Terms of
> Service](https://chain.link/terms), which provides important information and disclosures. By using this code, you
> acknowledge and agree to these terms.