Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@chainlink/ccip-cli

Package Overview
Dependencies
Maintainers
8
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@chainlink/ccip-cli

CCIP Command Line Interface, based on @chainlink/ccip-sdk

latest
Source
npmnpm
Version
1.7.1
Version published
Maintainers
8
Created
Source

@chainlink/ccip-cli

TypeScript CLI to interact with CCIP

This tool can be used to query and interact with CCIP contracts deployed in supported blockchains, through its publicly accessible data and methods, requiring only compatible RPCs for each involved network.

[!IMPORTANT] This tool is provided under an MIT license and is for convenience and illustration purposes only.

📖 Full Documentation - Complete command reference, all options, and troubleshooting guide.

Installation

To install it from latest NpmJS release, do:

npm install -g @chainlink/ccip-cli
ccip-cli --help

To run it directly with NPX, do:

npx @chainlink/ccip-cli --help

Or run it directly from github or a local clone of the repo (useful for local development):

git clone https://github.com/smartcontractkit/ccip-tools-ts
cd ccip-tools-ts
npm install  # install dependencies
./ccip-cli/ccip-cli --help  # shell script to run `./ccip-cli/src/index.ts`
alias ccip-cli="$PWD/ccip-cli/ccip-cli"  # optional, to run from local repo directly from anywhere

[!NOTE] In dev context below, we'll assume you are on ccip-cli folder.

RPCs

All commands require a list of RPCs endpoints for the networks of interest (source and destination). Both http[s] and ws[s] (websocket) URLs are supported.

This list can be passed in the command line, through the --rpc/--rpcs option; it may be passed multiple times, e.g. --rpc <source_rpc> --rpc <dest_rpc>, and are merged with those fetched from the rpcs file (--rpcs-file, default=./.env), which may contain multiple endpoints, one per line, with any prefix or suffix (only URLs are parsed).

The default filename is just for compatibility with previous tools, and isn't required to be an actual env file. .txt, .csv or .json arrays should work out of the box.

[!IMPORTANT] We recommend .env files. Do not upload RPCs with your API secrets in the URL to source countrol like github.

Example .env file:

https://ethereum-sepolia-rpc.publicnode.com
ARB_SEPOLIA_RPC: https://arbitrum-sepolia.drpc.org
RPC_AVALANCHE_TESTNET=https://avalanche-fuji-c-chain-rpc.publicnode.com
https://api.devnet.solana.com  # solana devnet public rpc
https://api.testnet.aptoslabs.com/v1  // `testnet` only would also work

Environment variables starting with RPC_ are also ingested. Suffix is not relevant.

Once the list is gathered, CLI connects to all RPCs in parallel on startup and uses the fastest to reply for each network.

Wallet

Commands which need to send transactions try to get a private key from a PRIVATE_KEY environment variable. Alternative names USER_KEY and OWNER_KEY are also supported (checked in that order).

Wallet options can also be passed as --wallet, where each chain family may interpret it however it can:

  • EVM can receive a 0x-hex private key, or the path to an encrypted json file (e.g. from geth, decrypted using the USER_KEY_PASSWORD environment variable or prompted password).

  • EVM also supports named keystores (Foundry Cast or Hardhat) via --wallet foundry:<name> / --wallet hardhat:<name>. The password is taken from $FOUNDRY_KEYSTORE_PASSWORD / $HARDHAT_KEYSTORE_PASSWORD (tool-specific), then $USER_KEY_PASSWORD, or prompted interactively. Foundry directory can be overridden with $FOUNDRY_DIR (default: ~/.foundry). Hardhat support delegates to node_modules/.bin/hardhat keystore get — Hardhat must be installed in your project:

    # Foundry
    cast wallet import sender --interactive
    ccip-cli send ... --wallet foundry:sender
    
    # Hardhat (run from inside your Hardhat project)
    npx hardhat keystore set sender
    ccip-cli send ... --wallet hardhat:sender
    
  • Solana can receive base58 private key, or the path to an id.json file (default=~/.config/solana/id.json) containing a private key encoded as a json array of numbers.

  • Aptos can receive 0x-hex private key string, or the path of a text file containing it.

Additionally, --wallet ledger (or --wallet "ledger:<derivationPath>") can be used to connect to a Ledger USB device. The derivation path defaults to Ledger Live derivations on each supported network, and passing an index selects an account of this derivation: E.g. --wallet ledger:1 uses derivation m/44'/60'/1'/0/0 for EVM accounts

Chain names and selectors

Where required, networks can be referred by ChainID, name or selector from chain-selectors. ChainIDs depend on the chain family and must be passed using this pattern:

  • EVM: numeric chain id; e.g. 1 for ethereum-mainnet.
  • Solana: genesis hash; e.g. 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d for solana-mainnet
  • Aptos, Sui: numeric chain id, prefixed with chain family and colon: e.g aptos:1 for aptos-mainnet

Shell Completion

The CLI supports shell tab-completion for commands and options. To enable it, add the completion script to your shell profile:

# bash
ccip-cli completion >> ~/.bashrc

# zsh
ccip-cli completion >> ~/.zshrc

Then restart your shell or source the profile. After setup, pressing <TAB> will autocomplete commands and flags:

ccip-cli s<TAB>        # completes to: send, show, get-supported-tokens
ccip-cli send --<TAB>  # lists all send options

Quick command reference:

Common options

  • -v: Verbose/debug output
  • --format=pretty (default): Human-readable tabular output
  • --format=log: Basic console logging, may show some more details (e.g. token addresses)
  • --format=json: Machine-readable JSON
  • --page=10000: limits eth_getLogs (and others) pagination/scanning ranges (e.g. for RPCs which don't support large ranges)
  • --no-api: Disable CCIP API integration (fully decentralized mode, RPC-only)
  • --api=<url>: Use a custom CCIP API URL instead of the default api.ccip.chain.link

Environment variable prefix: All CLI options can be set via environment variables using the CCIP_ prefix. For example:

  • CCIP_API=false → same as --no-api
  • CCIP_API=https://custom-api.example.com → same as --api=https://custom-api.example.com
  • CCIP_VERBOSE=true → same as --verbose
  • CCIP_FORMAT=json → same as --format=json

send

ccip-cli send \
    --source ethereum-testnet-sepolia \
    --dest ethereum-testnet-sepolia-arbitrum-1 \
    --router 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
    --receiver 0xAB4f961939BFE6A93567cC57C59eEd7084CE2131 \
    --data 'hello world' \
    --gas-limit 300000 \
    --fee-token 0x779877A7B0D9E8603169DdbD7836e478b4624789 \
    --transfer-tokens 0xFd57b4ddBf88a4e07fF4e34C487b99af2Fe82a05=0.1

Sends a CCIP message from source to destination chain.

Required options:

OptionAliasDescription
--source-sSource chain (chainId, selector, or name)
--dest-dDestination chain (chainId, selector, or name)
--router-rRouter contract address on source

Message options:

OptionAliasDescription
--receiver--toReceiver address; defaults to sender if same chain family
--dataData payload (non-hex = UTF-8 encoded)
--gas-limit-LGas limit for receiver callback (default: ramp config)
--estimate-gas-limitAuto-estimate with % margin; conflicts with --gas-limit
--allow-out-of-order-exec--oooSkip sender nonce enforcement (v1.5+ lanes)
--extra-xExtra args as key=value (parsed as JSON with bigint support; repeated keys become arrays)

Token options:

OptionAliasDescription
--fee-tokenPay fee in ERC20 (default: native token)
--transfer-tokens-tToken transfers as token=amount (e.g., 0xToken=0.1)
--approve-maxApprove max allowance instead of exact

Utility options:

OptionAliasDescription
--only-get-feePrint fee and exit
--only-estimatePrint gas estimate and exit (requires --estimate-gas-limit)
--waitWait for execution on destination
--wallet-wWallet (ledger[:index] or private key)

Solana/Sui options:

OptionDescription
--token-receiverSolana token receiver if different from program
--accountSolana accounts (append =rw for writable) or Sui object IDs

show (default command)

ccip-cli [show] <tx_hash_or_message_id> [--log-index num] [--wait]

Accepts a transaction hash or CCIP message ID (both are 32-byte hex strings). When given a tx hash, it looks for CCIPSendRequested (<=v1.5) or CCIPMessageSent (>=1.6) events in the transaction, trying every available RPC and using the first network to respond. When the CCIP API is enabled (default), it also tries to look up the input as a message ID via the API; whichever resolves first wins.

If more than one CCIP message request is present in a transaction, the user is prompted to select one from a list, with some basic info on the screen. The --log-index option allows to pre-select a request non-interactively.

--wait watches for execution on the destination chain instead of exiting after showing current state.

If an RPC for dest is also available, scans for the CommitReport for this request, and Execution Receipts until a success receipt or latest block is hit.

manual-exec

ccip-cli manual-exec <tx-hash-or-id> [--log-index num] [--gas-limit num] [--tokens-gas-limit num] [--wallet wallet]

Try to manually execute the message identified by a source transaction hash or CCIP message ID (32-byte hex). When a message ID is provided and the API is available (default), execution inputs are fetched from the CCIP API, removing the need for source chain RPC access. If more than one message is found, user is prompted same as with show command above. --log-index allows pre-selecting a message non-interactively.

--gas-limit (aliases -L, --compute-units) allows to override the exec limit for this message (in the OffRamp, not transaction, which is always estimated). --gas-limit=0 default re-uses limit specified in original request.

--tokens-gas-limit allows to override the gas limit for the token pool operations, if any.

--estimate-gas-limit option will try to estimate automatically the gas limit override for the message execution, based on the current state of the network. That's only for main ccipReceive exec callback. Tokens gas limit override estimation is not supported for estimation.

Solana Special Cases

--force-buffer to force using a buffer for messages too large to fit in a single transaction

--force-lookup-table creates a lookup table for all the accounts used in the message, to fit in the transaction.

If a solana message fails serialization, it's recommended to try with buffer first, then with lookup table. The former gets auto-cleared upon successful execution, while the latter needs a grace period to be cleared. --clear-leftover-accounts can be used to scan and wait for the accounts to be cleared, after exec.

Sui Special Cases

--receiver-object-ids specifies receiver object IDs required for Sui execution (e.g., --receiver-object-ids 0xabc... 0xdef...).

Canton Special Cases

Canton requires a config file with connection parameters via --canton-config <path>. The Canton Ledger API URL is provided through the normal --rpcs mechanism.

Config file format (JSON):

{
  "party": "sender::party",
  "ccipParty": "ccip::party",
  "jwt": "eyJ...",
  "edsUrl": "https://eds.example.com",
  "transferInstructionUrl": "https://transfer-instruction.example.com",
  "externalEdsUrlsByOwner": {
    "owner::party": "https://external-eds.example.com"
  },
  "indexerUrl": "https://indexer.example.com"
}

Required fields: party, ccipParty, jwt, edsUrl, transferInstructionUrl
Optional fields: externalEdsUrlsByOwner, indexerUrl

Example

ccip-cli manual-exec 0xafd36a0b99d5457e403c918194cb69cd070d991dcbadc99576acfce5020c0b6b \
  --wallet ledger \
  --compute-units 500000 \
  --force-buffer \
  --clear-leftover-accounts

parse

ccip-cli parse 0xbf16aab6000000000000000000000000779877a7b0d9e8603169ddbd7836e478b4624789

Error: EVM2EVMOnRamp_1.2.0.UnsupportedToken(address)
Args: { token: '0x779877A7B0D9E8603169DdbD7836e478b4624789' }

Attempts to parse function call data, error and revert reasons for CCIP contracts. Supports hex (EVM), base64 (Solana), and other chain-specific formats.

It'll recursively try to decode returnData and error arguments.

get-supported-tokens

ccip-cli get-supported-tokens --network <network> --address <address> [--token <token>]

List supported tokens in a given Router/OnRamp/TokenAdminRegistry, or show info about a specific token/pool.

Required options:

OptionAliasDescription
--network-nSource network: chainId or name
--address-aRouter/OnRamp/TokenAdminRegistry/TokenPool contract address

Optional:

OptionAliasDescription
--token-tToken address to query (pre-selects from list if address is a registry)
--fee-tokensList fee tokens instead of transferable tokens

Examples

# List all supported tokens from a router
ccip-cli get-supported-tokens -n ethereum-mainnet -a 0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D

# Get details for a specific token
ccip-cli get-supported-tokens -n ethereum-mainnet -a 0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D -t 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48

# Query a token pool directly
ccip-cli get-supported-tokens -n ethereum-mainnet -a 0xTokenPoolAddress

Output Format Options

  • --format pretty (default): Human-readable output
  • --format log: Basic console logging
  • --format json: Machine-readable JSON

token

ccip-cli token --network <network> --holder <address> [--token <token>]

Query native or token balance for an address.

Required options:

OptionAliasDescription
--network-nNetwork: chainId or name (e.g., ethereum-mainnet, solana-devnet)
--holder-HWallet address to query balance for

Optional:

OptionAliasDescription
--token-tToken address (omit for native token balance)

Examples

# Native ETH balance
ccip-cli token -n ethereum-mainnet -H 0x1234...abcd

# ERC-20 token balance
ccip-cli token -n ethereum-mainnet -H 0x1234...abcd -t 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48

# Solana native SOL balance
ccip-cli token -n solana-devnet -H EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB

lane-latency

ccip-cli lane-latency <source> <dest> [--api=<url>] [--block-confirmations=<n>]

Query real-time lane latency between source and destination chains using the CCIP API.

Arguments:

ArgumentDescription
<source>Source network (chainId, selector, or name)
<dest>Destination network (chainId, selector, or name)

Options:

OptionDescription
--apiCustom CCIP API URL (default: https://api.ccip.chain.link)
--block-confirmations, -cNumber of block confirmations to use for latency calculation

Note: This command requires CCIP API access and respects the --no-api flag.

Example

ccip-cli lane-latency ethereum-mainnet arbitrum-mainnet

Supported Chains

Chain FamilyStatusNotes
EVMSupportedFull functionality
SolanaSupportedFull functionality
AptosSupportedFull functionality
SuiPartialManual execution only
TONPartialNo token pool/registry queries
CantonPartialRequires config file; no fee/balance APIs

FAQs

Package last updated on 28 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts