# Arbitrary Messaging: Canton as Destination
Source: https://docs.chain.link/ccip/tutorials/canton/destination/arbitrary-messaging
Last Updated: 2026-07-06

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

This tutorial demonstrates how to send arbitrary data from Ethereum Sepolia to Canton and **execute** the message on Canton using the [`ccip-starter-kit-canton`](https://github.com/smartcontractkit/ccip-starter-kit-canton).

> \*\*NOTE: Prerequisites\*\*
>
>
>
> Complete the [Canton as Destination prerequisites](/ccip/tutorials/canton/destination/prerequisites) before starting. You need Sepolia ETH for send fees and Canton JWT access for `any2canton:manual-exec`.
>
> These steps use **Canton testnet** and **Ethereum Sepolia** only.

## Introduction

When Canton is the **destination** chain, the source send happens on Ethereum Sepolia and execution happens on Canton. For data-only messages:

1. You call the CCIP Router on Sepolia via `any2canton:data`.
2. CommitteeVerifier operators validate and aggregate proofs.
3. You run `any2canton:manual-exec` to execute on Canton — the SDK finds or creates a compatible `CCIPReceiver`.

## What You Will Build

In this tutorial, you will:

- Send a data-only message from Sepolia to your Canton party with `any2canton:data`.
- Wait for source finality and CCV verification.
- Execute the message on Canton with `any2canton:manual-exec`.
- Track progress in the [CCIP Explorer](/ccip/tools-resources/ccip-explorer).

## Understanding Arbitrary Messaging (any2canton)

Key points when Canton is the destination:

- **Two-step flow**: Send on Sepolia, then manually execute on Canton (all `any2canton` tutorials use manual execution on Canton).
- **Receiver**: Defaults to the `party` in `canton-config.json`. Override with `--cantonReceiver` on send or `--receiver` on manual exec.
- **Finality**: Default `--finality finalized` waits for Sepolia finality before execution is allowed. Pass `--finality 32` (or another block depth) for faster-than-finality.
- **Fee payment**: CCIP fees on Sepolia default to native ETH. Pass `--feeToken link` to pay in LINK.

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

## How the Scripts Work

**`scripts/any2canton/ccipSendData.ts`**:

1. Resolves the Canton receiver party from `canton-config.json`.
2. Builds and sends a data-only CCIP message via the SDK's `sendMessage` on Sepolia.
3. Prints the CCIP Message ID and a copy-pasteable `any2canton:manual-exec` command.

**`scripts/any2canton/manualExecute.ts`**:

1. Resolves the message by Sepolia tx hash or CCIP message ID.
2. Fetches proofs from the indexer and disclosures from Global CCIP EDS.
3. Calls `CantonChain.execute` — the SDK resolves or creates the `CCIPReceiver` and submits to the ledger.

## Running the Tutorial

### Prerequisites Check

1. Complete [prerequisites](/ccip/tutorials/canton/destination/prerequisites).
2. Confirm Sepolia ETH balance:

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

## Step 1: Send from Sepolia

```bash filename="Terminal"
npm run any2canton:data -- --dataString "Hello Canton"
```

Pay fee in LINK:

```bash filename="Terminal"
npm run any2canton:data -- --dataString "Hello Canton" --feeToken link
```

Request faster execution with block-depth finality (32 confirmations):

```bash filename="Terminal"
npm run any2canton:data -- --dataString "Hello Canton" --finality 32
```

Override the Canton receiver party:

```bash filename="Terminal"
npm run any2canton:data -- --dataString "Hello Canton" --cantonReceiver 'yourParty::1220…'
```

### Expected send output

```text
📧 Sending data from Sepolia → Canton: "Hello Canton"
   Receiver party: yourParty::1220…
🆔 CCIP Message ID: 0x…
🔗 CCIP Explorer: https://ccip.chain.link/#/side-drawer/msg/0x…
📜 Source transaction: https://sepolia.etherscan.io/tx/0x…

⚙️  Execute on Canton once the message is finalized on Sepolia:
   npm run any2canton:manual-exec -- 0x<sepoliaTxHash>
```

Save the Sepolia transaction hash or CCIP Message ID for the execution step.

## Step 2: Execute on Canton

Wait until the message is ready — timing depends on `--finality`:

- **`finalized`** (default): Wait for Sepolia finality (often 15+ minutes).
- **Block depth** (e.g. `32`): Wait for the specified number of Sepolia confirmations.

Monitor status in the [CCIP Explorer](/ccip/tools-resources/ccip-explorer). When CCV verification is complete, run:

```bash filename="Terminal"
npm run any2canton:manual-exec -- <sepoliaTxHashOrMessageId>
```

Example:

```bash filename="Terminal"
npm run any2canton:manual-exec -- 0x5a814d64666f60d2777c5425e8d0ea5a4b1bc9a3215eaeabced8b248050a3b99
```

### Expected execution output

```text
⚙️  Executing on Canton (OffRamp 0x…)…
   Resolving CCIPReceiver, fetching EDS disclosures, and submitting to the ledger — often 1–3 minutes with no further output.
✅ Canton execution transaction: https://lighthouse.testnet.cantonloop.com/transactions/…
```

> **TIP: Debug logging**
>
> Set `CCIP_DEBUG=1` in `.env` for step-by-step SDK logs during execution.

## Verification

1. Confirm **SUCCESS** state in the CCIP Explorer for your message ID.
2. Inspect the Canton execution transaction on [Canton Lighthouse](https://lighthouse.testnet.cantonloop.com).

> **CAUTION: Educational Example Disclaimer**
>
> This page includes an educational example to use a Chainlink system, product, or service and is provided to
> demonstrate how to interact with Chainlink's systems, products, and services to integrate them into your own. This
> template is provided "AS IS" and "AS AVAILABLE" without warranties of any kind, it has not been audited, and it may be
> missing key checks or error handling to make the usage of the system, product or service more clear. Do not use the
> code in this example in a production environment without completing your own audits and application of best practices.
> Neither Chainlink Labs, the Chainlink Foundation, nor Chainlink node operators are responsible for unintended outputs
> that are generated due to errors in code.