Skip to main content
Version: 0.96.0

CCIP SDK

TypeScript SDK for sending, tracking, and executing cross-chain messages on CCIP.

Package@chainlink/ccip-sdk
Version0.96.0
Node.jsv20+ (v23+ recommended)
LicenseMIT

Installation

Bash
npm install @chainlink/ccip-sdk

Quick Start

TypeScript
import { EVMChain } from '@chainlink/ccip-sdk'

// Connect to Ethereum Sepolia
const chain = await EVMChain.fromUrl('https://rpc.sepolia.org')
console.log('Connected to:', chain.network.name)

// Fetch CCIP requests from a transaction
const requests = await chain.getMessagesInTx('0x...')
for (const req of requests) {
console.log('Message ID:', req.message.messageId)
console.log('Destination:', req.lane.destChainSelector)
}

Prerequisites

You need RPC endpoints for the chains you want to interact with. Node.js v20+ is required (v23+ recommended for native fetch support).

  • QuickNode - Multi-chain support with free tier
  • Alchemy - Enterprise-grade with free tier
  • Chainlist.org - Free public RPCs for EVM networks
  • Infura - Reliable EVM endpoints with free tier
  • Nodereal - Aptos and EVM support with free tier
Tip: For quick testing, Chainlist.org provides free public RPCs. For production, use Alchemy or Infura for better rate limits.

Chain Support

Supported chain families:
EVM iconEVMSolana iconSolanaAptos iconAptos

Quick Reference

TaskMethodReference
Connect to chainEVMChain.fromUrl(rpcUrl)EVMChain
Track messagechain.getMessagesInTx(txHash)getMessagesInTx
Get feechain.getFee({ router, destChainSelector, message })getFee
Send messagechain.sendMessage({ router, destChainSelector, message })sendMessage
Manual executioncalculateManualExecProof(request)calculateManualExecProof
Decode messagedecodeMessage(log)decodeMessage

Concepts

Chain Classes

ClassBlockchainImport
EVMChainEthereum, Arbitrum, Optimism, etc.import { EVMChain } from '@chainlink/ccip-sdk'
SolanaChainSolanaimport { SolanaChain } from '@chainlink/ccip-sdk'
AptosChainAptosimport { AptosChain } from '@chainlink/ccip-sdk'
SuiChainSuiimport { SuiChain } from '@chainlink/ccip-sdk'
TONChainTONimport { TONChain } from '@chainlink/ccip-sdk'

Message Lifecycle

  1. Sent - Message emitted on source chain (CCIPRequest)
  2. Committed - Merkle root committed on destination (CommitReport)
  3. Executed - Message executed on destination (ExecutionReceipt)

Chain Selectors vs Chain IDs

CCIP uses chain selectors (not chain IDs) to identify networks. Chain selectors are unique identifiers assigned by CCIP that remain consistent across the protocol.

TypeScript
import { networkInfo } from '@chainlink/ccip-sdk'

// Wrong: Using chain ID for CCIP operations
const destChain = 84532 // Base Sepolia chain ID - DON'T USE

// Correct: Using CCIP chain selector
const destSelector = networkInfo('ethereum-testnet-sepolia-base-1').chainSelector
// Returns: 10344971235874465080n

Always use chain selectors for:

  • destChainSelector in messages
  • Lane configuration
  • Fee estimation

Use networkInfo() to convert between chain IDs, names, and selectors.

Extra Arguments

Configure gas limits and execution parameters:

TypeScript
import { encodeExtraArgs } from '@chainlink/ccip-sdk'

const extraArgs = encodeExtraArgs({
gasLimit: 200000n,
allowOutOfOrderExecution: true,
})

Error Handling

The SDK throws typed errors:

TypeScript
import {
EVMChain,
CCIPMessageNotFoundInTxError,
CCIPBlockNotFoundError,
} from '@chainlink/ccip-sdk'

try {
const requests = await chain.getMessagesInTx(txHash)
} catch (error) {
if (error instanceof CCIPMessageNotFoundInTxError) {
console.log('No CCIP messages in transaction:', error.context.txHash)
} else if (error instanceof CCIPBlockNotFoundError) {
console.log('Block not found:', error.context.block)
} else {
throw error
}
}

See Error Handling for recovery patterns.

Next Steps