Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ jobs:
- name: Verify anvil is available
run: anvil --version

- name: Install Surfpool v1.1.1 (for SVM fork tests)
- name: Install Surfpool v1.1.2 (for SVM fork tests)
run: |
curl -sSL https://github.com/solana-foundation/surfpool/releases/download/v1.1.1/surfpool-linux-x64.tar.gz \
curl -sSL https://github.com/solana-foundation/surfpool/releases/download/v1.1.2/surfpool-linux-x64.tar.gz \
| tar xz -C /usr/local/bin

- name: Verify surfpool is available
Expand All @@ -53,6 +53,9 @@ jobs:
npx @arethetypeswrong/cli --pack . --profile esm-only || true

- name: Run tests with coverage
env:
# Temporary: pipe surfpool stdout/stderr to diagnose Solana fork test failures in CI
VERBOSE: '1'
run: |
set -o pipefail
npm test 2>&1 | tee coverage-summary.txt
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.5.0] - 2025-04-22

- SDK/CLI: Add `sourceTokenAddress` search filter to `searchMessages` and `--source-token` CLI option for filtering messages by source token
- CLI: Clean JSON output — data on stdout, diagnostics on stderr, single JSON envelope per command
- SDK/CLI: Add `--no-interactive` mode to disable all prompts for AI agents and automation, with auto-detection of non-TTY stdin
- SDK: add Fast Confirmation Rule/FCR/SAFE support to v2.0 lanes:
- `LaneFeatures.MIN_BLOCK_CONFIRMATIONS` and `CUSTOM_BLOCK_CONFIRMATIONS_RATE_LIMITS` replaced with `FINALITY_FAST`, `FINALITY_SAFE`, `FAST_RATE_LIMITS`
- `GenericExtraArgsV3.blockConfirmations` replaced with `finality: 'finalized' | 'safe' | number`

## [1.4.0] - 2026-03-26

Expand Down
2 changes: 1 addition & 1 deletion ccip-api-ref/docs-cli/guides/data-transfer-workflow.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ ccip-cli send \
--wallet ledger
```

See the [send command reference](/cli/send) for all options: [gas limit behavior](/cli/send#gas-limit-behavior), [lane-specific parameters](/cli/send#lane-specific-parameters), and [extra args](/cli/send#extra-args). Extra args like `blockConfirmations` and `ccvs` (encoded as GenericExtraArgsV3) require CCIP v2+ lanes — check your lane version in the [CCIP Directory](https://docs.chain.link/ccip/directory).
See the [send command reference](/cli/send) for all options: [gas limit behavior](/cli/send#gas-limit-behavior), [lane-specific parameters](/cli/send#lane-specific-parameters), and [extra args](/cli/send#extra-args). Extra args like `finality` and `ccvs` (encoded as GenericExtraArgsV3) require CCIP v2+ lanes — check your lane version in the [CCIP Directory](https://docs.chain.link/ccip/directory).

## Step 3: Track Message

Expand Down
2 changes: 1 addition & 1 deletion ccip-api-ref/docs-cli/guides/token-transfer-workflow.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ ccip-cli send \
--wallet ledger
```

See the [send command reference](/cli/send) for all options: [token amount format](/cli/send#token-amount-format), [gas limit behavior](/cli/send#gas-limit-behavior), [lane-specific parameters](/cli/send#lane-specific-parameters), and [extra args](/cli/send#extra-args). Extra args like `blockConfirmations` and `ccvs` (encoded as GenericExtraArgsV3) require CCIP v2+ lanes — check your lane version in the [CCIP Directory](https://docs.chain.link/ccip/directory).
See the [send command reference](/cli/send) for all options: [token amount format](/cli/send#token-amount-format), [gas limit behavior](/cli/send#gas-limit-behavior), [lane-specific parameters](/cli/send#lane-specific-parameters), and [extra args](/cli/send#extra-args). Extra args like `finality` and `ccvs` (encoded as GenericExtraArgsV3) require CCIP v2+ lanes — check your lane version in the [CCIP Directory](https://docs.chain.link/ccip/directory).

## Step 4: Track Transfer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ ccip-cli send \
--wallet ledger
```

For all other options, see the [send command reference](/cli/send): [lane-specific parameters](/cli/send#lane-specific-parameters), [extra args](/cli/send#extra-args), and [gas limit behavior](/cli/send#gas-limit-behavior). Extra args like `blockConfirmations` and `ccvs` (encoded as GenericExtraArgsV3) require CCIP v2+ lanes — check your lane version in the [CCIP Directory](https://docs.chain.link/ccip/directory).
For all other options, see the [send command reference](/cli/send): [lane-specific parameters](/cli/send#lane-specific-parameters), [extra args](/cli/send#extra-args), and [gas limit behavior](/cli/send#gas-limit-behavior). Extra args like `finality` and `ccvs` (encoded as GenericExtraArgsV3) require CCIP v2+ lanes — check your lane version in the [CCIP Directory](https://docs.chain.link/ccip/directory).

## Troubleshooting

Expand Down
4 changes: 2 additions & 2 deletions ccip-api-ref/docs-cli/send.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ The `send` command constructs and submits a CCIP message to transfer data and/or
| `--extra` | `-x` | string[] | Extra args as `key=value`. Values parsed as JSON with BigInt support; fallback to string. Repeated keys become arrays. |

:::note
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](https://docs.chain.link/ccip/directory).
Extra args fields like `finality`, `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](https://docs.chain.link/ccip/directory).
:::

:::caution Array fields with a single element
Expand Down Expand Up @@ -245,7 +245,7 @@ ccip-cli send \
-r 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59 \
--to 0xAB4f961939BFE6A93567cC57C59eEd7084CE2131 \
--data "hello world" \
-x blockConfirmations=5 \
-x finality=5 \
-x ccvs='["0xVerifier1"]' \
-x executor=0xExecutorAddress
```
Expand Down
27 changes: 14 additions & 13 deletions ccip-api-ref/docs-cli/supported-tokens.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,16 @@ ccip-cli get-supported-tokens -n ethereum-mainnet -a 0xRouter... --fee-tokens

When a token is selected or specified:

| Field | Description |
| ----------------------- | ---------------------------------------------------------------------------------------------- |
| Token address | Contract address on the source chain |
| Symbol / Name | Token symbol and full name |
| Decimals | Token decimal places |
| Pool address | Associated token pool contract |
| Pool type | Lock/Release, Burn/Mint, etc. |
| `minBlockConfirmations` | (v2.0+ pools) Minimum source-chain block confirmations for FTF (0 = supported but not enabled) |
| Remote chains | Supported destination chains with rate limits |
| Field | Description |
| --------------- | ---------------------------------------------------------------------------------------------- |
| Token address | Contract address on the source chain |
| Symbol / Name | Token symbol and full name |
| Decimals | Token decimal places |
| Pool address | Associated token pool contract |
| Pool type | Lock/Release, Burn/Mint, etc. |
| `finalityDepth` | (v2.0+ pools) Minimum source-chain block confirmations for FTF (0 = supported but not enabled) |
| `finalitySafe` | (v2.0+ pools) Whether Pool supports safe finality (Fast Confirmation Rule) |
| Remote chains | Supported destination chains with rate limits |

## Examples

Expand Down Expand Up @@ -129,10 +130,10 @@ For each remote chain, the command displays rate limiter state:

For TokenPool v2.0+ contracts, additional fields may appear:

| Field | Description |
| --------------- | ------------------------------------------------------------ |
| `[ftf]outbound` | FTF outbound rate limiter state (custom block confirmations) |
| `[ftf]inbound` | FTF inbound rate limiter state (custom block confirmations) |
| Field | Description |
| ---------------- | ------------------------------------------------------------ |
| `[fast]outbound` | FTF outbound rate limiter state (custom block confirmations) |
| `[fast]inbound` | FTF inbound rate limiter state (custom block confirmations) |

These FTF rate limiters apply separate limits when transfers use custom (lower) block confirmations instead of full finality.

Expand Down
4 changes: 2 additions & 2 deletions ccip-api-ref/docs-sdk/guides/fee-estimation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ if (estimate.tokenTransferFee) {

Token transfer fee rates differ based on finality mode:

- **Standard finality** (`blockConfirmations = 0` or omitted): uses `defaultBlockConfirmationsTransferFeeBps`
- **Faster-Than-Finality** (`blockConfirmations > 0`): uses `customBlockConfirmationsTransferFeeBps`
- **Standard finality** (`finality = 0` or omitted): uses `finalityTransferFeeBps`
- **Faster-Than-Finality** (block depth `finality > 0`): uses `fastFinalityTransferFeeBps`

For the full FTF workflow — checking availability, estimating FTF fees with code examples, and computing received amounts — see [Faster-Than-Finality](/sdk/guides/ftf).

Expand Down
44 changes: 22 additions & 22 deletions ccip-api-ref/docs-sdk/guides/ftf.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ const features = await source.getLaneFeatures({
token: '0xTokenAddress...',
})

const minConfirmations = features.MIN_BLOCK_CONFIRMATIONS
const minConfirmations = features.FINALITY_FAST
```

Interpret `MIN_BLOCK_CONFIRMATIONS`:
Interpret `FINALITY_FAST`:

| Value | Lane version | Meaning |
|-------|-------------|---------|
| `undefined` | Pre-v2.0 | FTF not supported. Use V2 extraArgs only. |
| `0` | v2.0+ | V3 extraArgs supported, but FTF not enabled for this token. `blockConfirmations` has no effect. |
| `> 0` | v2.0+ with FTF | FTF enabled. Use `blockConfirmations >= minValue` in V3 extraArgs. |
| `0` | v2.0+ | V3 extraArgs supported, but FTF not enabled for this token. `finality` has no effect. |
| `> 0` | v2.0+ with FTF | FTF enabled. Use `finality >= minValue` in V3 extraArgs. |

:::note
Without a `token`, the result reflects lane version only: `undefined` for pre-v2.0, or a hardcoded `1` for v2.0+ (confirming V3 support without pool-specific FTF data). Pass a `token` to get the actual pool-specific value.
Expand All @@ -48,7 +48,7 @@ Without a `token`, the result reflects lane version only: `undefined` for pre-v2

## Send with FTF

Set `blockConfirmations` in `extraArgs`. The SDK auto-detects V3 encoding when any V3-only field is present:
Set `finality` in `extraArgs`. The SDK auto-detects V3 encoding when any V3-only field is present:

```typescript
import { EVMChain, networkInfo } from '@chainlink/ccip-sdk'
Expand All @@ -63,14 +63,14 @@ const features = await source.getLaneFeatures({
token: '0xTokenAddress...',
})

const minConfirmations = features.MIN_BLOCK_CONFIRMATIONS
const minConfirmations = features.FINALITY_FAST

let extraArgs
if (minConfirmations != null && minConfirmations > 0) {
// FTF enabled — use V3 with blockConfirmations
// FTF enabled — use V3 with finality
extraArgs = {
gasLimit: 200_000n,
blockConfirmations: minConfirmations,
finality: minConfirmations,
}
} else if (minConfirmations != null) {
// v2.0+ but FTF not enabled — V2-style args work
Expand Down Expand Up @@ -98,7 +98,7 @@ await source.sendMessage({
})
```

The SDK does **not** validate `extraArgs` against the lane's on-chain version. Passing V3 fields (e.g., `blockConfirmations`) to a pre-v2.0 lane will **revert** on-chain.
The SDK does **not** validate `extraArgs` against the lane's on-chain version. Passing V3 fields (e.g., `finality`) to a pre-v2.0 lane will **revert** on-chain.

## Estimate FTF Latency

Expand All @@ -118,7 +118,7 @@ When `numberOfBlocks` is omitted or `0`, the API returns latency for the lane's

## Estimate FTF Fees

Token transfer fees differ between standard and FTF. Call `getTotalFeesEstimate` with `blockConfirmations` in `extraArgs`:
Token transfer fees differ between standard and FTF. Call `getTotalFeesEstimate` with `finality` in `extraArgs`:

```typescript
const estimate = await source.getTotalFeesEstimate({
Expand All @@ -127,7 +127,7 @@ const estimate = await source.getTotalFeesEstimate({
message: {
receiver: '0xReceiverAddress...',
tokenAmounts: [{ token: '0xTokenAddress...', amount: 1_000_000n }],
extraArgs: { blockConfirmations: minConfirmations },
extraArgs: { finality: minConfirmations },
},
})

Expand All @@ -144,10 +144,10 @@ if (estimate.tokenTransferFee) {

The pool-level BPS rate applied depends on finality mode:

| Finality mode | `blockConfirmations` | BPS field used |
| Finality mode | `finality` | BPS field used |
|---------------|---------------------|----------------|
| Standard | `0` or omitted | `defaultBlockConfirmationsTransferFeeBps` |
| FTF | `> 0` | `customBlockConfirmationsTransferFeeBps` |
| Standard | `0` or omitted | `finalityTransferFeeBps` |
| FTF | `> 0` (block depth) | `fastFinalityTransferFeeBps` |

See [Fee Estimation](/sdk/guides/fee-estimation) for the full `TotalFeesEstimate` type and USDC/CCTP fee handling.

Expand All @@ -168,8 +168,8 @@ if (features.RATE_LIMITS) {
}

// FTF rate limits (only when FTF is enabled)
if (features.CUSTOM_BLOCK_CONFIRMATIONS_RATE_LIMITS) {
const ftf = features.CUSTOM_BLOCK_CONFIRMATIONS_RATE_LIMITS
if (features.FAST_RATE_LIMITS) {
const ftf = features.FAST_RATE_LIMITS
console.log('FTF — available:', ftf.tokens, '/', ftf.capacity)
}
```
Expand All @@ -180,8 +180,8 @@ FTF rate limits are also available per remote chain via `getTokenPoolRemotes`:
const remotes = await source.getTokenPoolRemotes(poolAddress, destSelector)
const remote = Object.values(remotes)[0]

if (remote && 'customBlockConfirmationsOutboundRateLimiterState' in remote) {
const ftfOutbound = remote.customBlockConfirmationsOutboundRateLimiterState
if (remote && 'fastOutboundRateLimiterState' in remote) {
const ftfOutbound = remote.fastOutboundRateLimiterState
if (ftfOutbound) {
console.log('FTF outbound:', ftfOutbound.tokens, '/', ftfOutbound.capacity)
}
Expand Down Expand Up @@ -216,15 +216,15 @@ async function sendWithFTF(
token: tokenAddress,
})

const minConfirmations = features.MIN_BLOCK_CONFIRMATIONS
const minConfirmations = features.FINALITY_FAST
if (minConfirmations == null || minConfirmations === 0) {
console.log('FTF not available on this lane/token')
return
}

// 2. Check FTF rate limits
if (features.CUSTOM_BLOCK_CONFIRMATIONS_RATE_LIMITS) {
const available = features.CUSTOM_BLOCK_CONFIRMATIONS_RATE_LIMITS.tokens
if (features.FAST_RATE_LIMITS) {
const available = features.FAST_RATE_LIMITS.tokens
console.log('FTF rate limit available:', available)
}

Expand All @@ -236,7 +236,7 @@ async function sendWithFTF(
const message = {
receiver,
tokenAmounts: [{ token: tokenAddress, amount }],
extraArgs: { blockConfirmations: minConfirmations },
extraArgs: { finality: minConfirmations },
}

const estimate = await source.getTotalFeesEstimate({
Expand Down
9 changes: 5 additions & 4 deletions ccip-api-ref/docs-sdk/guides/querying-data.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,10 @@ Returns `Partial<LaneFeatures>` — not all fields are guaranteed:

| Field | Type | Meaning |
|-------|------|---------|
| `MIN_BLOCK_CONFIRMATIONS` | `number \| undefined` | `undefined` = pre-v2.0 lane, `0` = v2.0+ but FTF not enabled for this token, `>0` = FTF enabled |
| `FINALITY_FAST` | `number \| undefined` | `undefined` = pre-v2.0 lane, `0` = v2.0+ but FTF not enabled for this token, `>0` = FTF enabled |
| `FINALITY_SAFE` | `true \| undefined` | `true` = FCR/safe finality supported on this lane |
| `RATE_LIMITS` | `RateLimiterState \| null` | Standard rate limiter state (`null` if disabled) |
| `CUSTOM_BLOCK_CONFIRMATIONS_RATE_LIMITS` | `RateLimiterState \| null` | FTF-specific rate limiter (only when `MIN_BLOCK_CONFIRMATIONS > 0`) |
| `FAST_RATE_LIMITS` | `RateLimiterState \| null` | FTF/FCR-specific rate limiter (only when FINALITY_FAST > 0 or FINALITY_SAFE) |

:::note
`getLaneFeatures` is implemented for EVM chains only.
Expand Down Expand Up @@ -442,8 +443,8 @@ async function getTransferInfo(
amount: amountString,
fee: formatUnits(fee, 18),
ftfEnabled:
laneFeatures.MIN_BLOCK_CONFIRMATIONS != null &&
laneFeatures.MIN_BLOCK_CONFIRMATIONS > 0,
laneFeatures.FINALITY_FAST != null &&
laneFeatures.FINALITY_FAST > 0,
rateLimited: laneFeatures.RATE_LIMITS != null,
}
}
Expand Down
Loading
Loading