send
Send a CCIP message from a source chain to a destination chain.
Synopsis
ccip-cli send -s <source> -d <dest> -r <router> [options]
Description
The send command constructs and submits a CCIP message to transfer data and/or tokens between blockchains. It handles fee calculation, token approvals, and transaction submission.
Options
Required
| Option | Alias | Type | Description |
|---|---|---|---|
--source | -s | string | Source network (chain ID, selector, or name) |
--dest | -d | string | Destination network (chain ID, selector, or name) |
--router | -r | string | CCIP Router contract address on source chain |
Message
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--receiver | --to | string | - | Receiver address on destination. Defaults to sender if same chain family. Required for cross-family transfers. |
--data | - | string | - | Message data payload. Non-hex strings are UTF-8 encoded automatically. Hex strings (0x...) are used as-is. |
--transfer-tokens | -t | string[] | - | Token transfers as token=amount. See Token Amount Format. |
--fee-token | - | string | Native | Fee token address or symbol (e.g., LINK). Omit to pay in native token. |
Gas & Execution
| Option | Alias | Type | Default | Description |
|---|---|---|---|---|
--gas-limit | -L, --compute-units | number | - | Gas limit for receiver callback. See Gas Limit Behavior. |
--estimate-gas-limit | - | number | - | Estimate gas limit with % margin (e.g., 10 for +10%). Conflicts with --gas-limit. |
--allow-out-of-order-exec | --ooo | boolean | true | Allow out-of-order execution. Supported on v1.5+ lanes. |
Extra Args
| Option | Alias | Type | Description |
|---|---|---|---|
--extra | -x | string[] | Extra args as key=value. Values parsed as JSON with BigInt support; fallback to string. Repeated keys become arrays. |
Extra args fields like blockConfirmations, ccvs, ccvArgs, executor, executorArgs, tokenReceiver, and tokenArgs require CCIP v2+ lanes (GenericExtraArgsV3). Using them on older lanes will fail. The SDK auto-detects V3 when any V3-only field is present. Check your lane version in the CCIP Directory.
For array fields (ccvs, ccvArgs, tokenArgs), repeating a key creates an array automatically: -x ccvs=0xA -x ccvs=0xB produces ["0xA", "0xB"]. However, a single value is treated as a string, not an array. If your array has exactly one element, you must use the JSON array syntax:
# WRONG — produces string "0xVerifier1", not an array
-x ccvs=0xVerifier1
# CORRECT — produces ["0xVerifier1"]
-x ccvs='["0xVerifier1"]'
--extra values override values set by other flags. For example, --gas-limit 100000 -x gasLimit=200000 uses 200000.
Chain-Specific
| Option | Alias | Type | Description |
|---|---|---|---|
--token-receiver | - | string | Solana token receiver address if different from program receiver. Required when sending tokens + data to Solana. |
--account | --receiver-object-id | string[] | Solana accounts (append =rw for writable) or Sui receiver object IDs. |
Wallet
| Option | Alias | Type | Description |
|---|---|---|---|
--wallet | -w | string | Wallet source. See Configuration. |
--approve-max | - | boolean | Approve maximum token allowance instead of exact amount needed. |
Dry-Run
| Option | Type | Description |
|---|---|---|
--only-get-fee | boolean | Print the fee and exit without sending. |
--only-estimate | boolean | Print gas estimate and exit. Requires --estimate-gas-limit. |
Other
| Option | Type | Default | Description |
|---|---|---|---|
--wait | boolean | false | Wait for finality, commit, and execution before returning. |
See Configuration for global options (--rpcs, --rpcs-file, --format, --no-api, etc.).
Command Builder
Build your send command interactively:
ccip-cli send Builder
Send a CCIP message from source to destination chain
ccip-cli send --rpcs-file ./.env --format prettyToken Amount Format
The --transfer-tokens / -t option accepts token=amount pairs. The CLI converts human-readable amounts to smallest units using the token's decimals.
# Single token (1.5 tokens)
-t 0xTokenAddress=1.5
# Multiple tokens
-t 0xToken1=1.0 -t 0xToken2=50
# By symbol (if resolvable on source chain)
-t USDC=100
Gas Limit Behavior
If you're sending tokens without --data, the gas limit defaults to 0 — no receiver callback is executed, and the tokens are delivered directly. Only set --gas-limit or --estimate-gas-limit when your receiver contract processes the message in ccipReceive.
When --data is present and --gas-limit is omitted, the SDK applies a default of 200,000 for EVM and Solana destinations, or 1,000,000 for Sui. If your receiver needs more gas, set it explicitly or use --estimate-gas-limit to auto-calculate with a margin.
Lane-Specific Parameters
| Option | EVM→EVM | EVM→Solana | Solana→EVM | EVM→Sui |
|---|---|---|---|---|
--gas-limit / -L | Gas limit for ccipReceive | Compute units | Gas limit | Gas limit |
--estimate-gas-limit | Auto-estimate + % margin | Auto-estimate | Auto-estimate | - |
--token-receiver | v2+ lanes only (--extra) | Required if tokens + data | - | Optional |
--account | - | Receiver accounts (append =rw) | - | Receiver object IDs |
--ooo | Default: true | Default: true | Default: true | Default: true |
--extra / -x | v2+ lanes only | - | - | - |
Examples
Send a data message
ccip-cli send \
-s ethereum-testnet-sepolia \
-d arbitrum-sepolia \
-r 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
--to 0xAB4f961939BFE6A93567cC57C59eEd7084CE2131 \
--data "hello world"
Transfer tokens
ccip-cli send \
-s ethereum-testnet-sepolia \
-d arbitrum-sepolia \
-r 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
--to 0xAB4f961939BFE6A93567cC57C59eEd7084CE2131 \
-t 0xFd57b4ddBf88a4e07fF4e34C487b99af2Fe82a05=0.1 \
--fee-token LINK
Programmable token transfer (tokens + data)
ccip-cli send \
-s ethereum-testnet-sepolia \
-d arbitrum-sepolia \
-r 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
--to 0xAB4f961939BFE6A93567cC57C59eEd7084CE2131 \
-t 0xFd57b4ddBf88a4e07fF4e34C487b99af2Fe82a05=1.0 \
--data "deposit:pool-123" \
--estimate-gas-limit 15
Check fee without sending
ccip-cli send \
-s ethereum-testnet-sepolia \
-d arbitrum-sepolia \
-r 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
--to 0xAB4f961939BFE6A93567cC57C59eEd7084CE2131 \
-t 0xToken=1.0 \
--only-get-fee
EVM to Solana
ccip-cli send \
-s ethereum-testnet-sepolia \
-r 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
-d solana-devnet \
--to <SOLANA_PROGRAM_ADDRESS> \
--token-receiver <SOLANA_TOKEN_ACCOUNT> \
--account <ACCOUNT_1> \
--account <ACCOUNT_2>=rw \
-t 0xToken=1.0 \
--data "instruction-data" \
--wallet ledger
Solana to EVM
ccip-cli send \
-s solana-devnet \
-r <SOLANA_ROUTER> \
-d ethereum-testnet-sepolia \
--to 0xReceiverContract \
-t <SPL_TOKEN_MINT>=1.0 \
--wallet ledger
EVM to Sui
ccip-cli send \
-s ethereum-testnet-sepolia \
-r 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
-d sui-testnet \
--to 0xSuiReceiverAddress \
--account 0xObjectId1 \
--account 0xObjectId2 \
-t 0xToken=1.0 \
--wallet ledger
Extra args (CCIP v2+ lanes)
ccip-cli send \
-s ethereum-testnet-sepolia \
-d arbitrum-sepolia \
-r 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
--to 0xAB4f961939BFE6A93567cC57C59eEd7084CE2131 \
--data "hello world" \
-x blockConfirmations=5 \
-x ccvs='["0xVerifier1"]' \
-x executor=0xExecutorAddress
Send and wait for execution
ccip-cli send \
-s ethereum-testnet-sepolia \
-d arbitrum-sepolia \
-r 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
--to 0xAB4f961939BFE6A93567cC57C59eEd7084CE2131 \
--data "hello world" \
--wait
See Also
- show — Track message status after sending
- get-supported-tokens — Find supported tokens for transfer
- Configuration — Wallet and RPC setup
Exit Codes
| Code | Meaning |
|---|---|
0 | Success — transaction submitted (or fee/estimate returned for dry-run) |
1 | Error (network failure, transaction reverted, invalid arguments) |