Skip to content
Draft
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
31 changes: 31 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@ AVALANCHE_FUJI_RPC_URL=https://your-avalanche-fuji-rpc-url
POLYGON_AMOY_RPC_URL=https://your-polygon-amoy-rpc-url
BASE_SEPOLIA_RPC_URL=https://your-base-sepolia-rpc-url

# Your account address. Fill in with: cast wallet address --account myAccount
MY_EOA=

# Network constants used by the book (book/src). Fill these in from https://docs.chain.link/ccip/directory
# (router, chain selector, LINK, CCIP-BnM, RMN/ARM proxy, registry module owner, token admin registry).
# Only fill the chains you plan to run.
# Ethereum Sepolia
SEPOLIA_CHAIN_SELECTOR=
SEPOLIA_ROUTER=
SEPOLIA_LINK=
SEPOLIA_CCIP_BNM=
SEPOLIA_ARM_PROXY=
SEPOLIA_REGISTRY_MODULE_OWNER_CUSTOM=
SEPOLIA_TOKEN_ADMIN_REGISTRY=
# Polygon Amoy
AMOY_CHAIN_SELECTOR=
AMOY_ROUTER=
AMOY_LINK=
AMOY_CCIP_BNM=
AMOY_ARM_PROXY=
AMOY_REGISTRY_MODULE_OWNER_CUSTOM=
AMOY_TOKEN_ADMIN_REGISTRY=
# Avalanche Fuji (Legacy examples)
FUJI_CHAIN_SELECTOR=
FUJI_ROUTER=
FUJI_LINK=
FUJI_CCIP_BNM=

# Optional. The SDK examples (sdk-examples) read USER_KEY (or PRIVATE_KEY) for non-dry-run sends.
# USER_KEY=

# Optional. Fork tests (test/fork, FOUNDRY_PROFILE=fork) are pinned to the blocks in test/fork/utils/CCTForkTest.sol.
# Set these to run against a different block, for example a recent one to check whether the live lane has drifted.
# ETHEREUM_SEPOLIA_FORK_BLOCK=<block number>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ Script path: `script/examples/Example01.s.sol`
> This chapter assumes `--account myAccount`.


## Chapter Parameters

Set the parameters for this chapter. The defaults work as they are; change a value only if you want something different.

```bash
export RECEIVER=$MY_EOA # destination EOA
export AMOUNT=1000000000000000000 # 1 token (18 decimals)
export GAS_LIMIT=0 # token-only transfer to an EOA
export BLOCK_CONFIRMATIONS=1 # Fast Transfers depth, must be > 0
export FEE_TOKEN=0x0000000000000000000000000000000000000000 # native fee; use $SEPOLIA_LINK to pay in LINK
```

## Step 1: Get 1 CCIP-BnM Token

Use the faucet script on the source chain:
Expand All @@ -36,17 +48,18 @@ forge script script/Faucet.s.sol:Faucet \
--account myAccount \
--broadcast \
--sig "run(address)" \
<CCIP_BNM_SOURCE_TOKEN_ADDRESS>
$SEPOLIA_CCIP_BNM
```

## Step 2: (Optional) Check Executor Allowed Finality

Before choosing a Fast Transfers depth in `ExtraArgsV3`, you can read what finality modes the **Executor** allows. The on-chain API is **`getAllowedFinalityConfig() → bytes4`**, encoded with **`FinalityCodec`** (same family of values as `requestedFinalityConfig` in your message’s ExtraArgs).

From a shell (replace RPC and address):
From a shell. The executor address is printed as `[GATE] Executor:` by the finality-gates check further down this step; run that first, then export it:

```bash
cast call <EXECUTOR_ADDRESS> "getAllowedFinalityConfig()(bytes4)" --rpc-url ethereumSepolia
export EXECUTOR_ADDRESS=0x...
cast call $EXECUTOR_ADDRESS "getAllowedFinalityConfig()(bytes4)" --rpc-url ethereumSepolia
```

Why this matters:
Expand All @@ -59,7 +72,7 @@ Check the source pool, executor, and CCV finality settings before sending:
forge script script/examples/Example06.s.sol:Example06CheckFinalityGates \
--rpc-url ethereumSepolia \
--sig "run(address,uint64,address,uint16)" \
<SOURCE_ROUTER> <DESTINATION_CHAIN_SELECTOR> <CCIP_BNM_SOURCE_TOKEN_ADDRESS> <BLOCK_CONFIRMATIONS_GT_ZERO>
$SEPOLIA_ROUTER $AMOY_CHAIN_SELECTOR $SEPOLIA_CCIP_BNM $BLOCK_CONFIRMATIONS
```

A quote alone does not prove `ccipSend` will succeed with a non-`IPoolV2` pool.
Expand All @@ -74,22 +87,22 @@ forge script script/examples/Example01.s.sol:Example01 \
--account myAccount \
--broadcast \
--sig "run(address,uint64,address,address,uint256,uint32,uint16,address)" \
<SOURCE_ROUTER> \
<DESTINATION_CHAIN_SELECTOR> \
<RECEIVER_ON_DESTINATION_CHAIN> \
<CCIP_BNM_SOURCE_TOKEN_ADDRESS> \
<AMOUNT> \
<GAS_LIMIT> \
<BLOCK_CONFIRMATIONS_GT_ZERO> \
<FEE_TOKEN_ADDRESS>
$SEPOLIA_ROUTER \
$AMOY_CHAIN_SELECTOR \
$RECEIVER \
$SEPOLIA_CCIP_BNM \
$AMOUNT \
$GAS_LIMIT \
$BLOCK_CONFIRMATIONS \
$FEE_TOKEN
```

Parameter notes:

- `<AMOUNT>`: token amount in token decimals (for 18 decimals, `1e18` is 1 token).
- `<GAS_LIMIT>`: set to `0` for token-only transfer to an EOA receiver.
- `<BLOCK_CONFIRMATIONS_GT_ZERO>`: must be `> 0` and meet the source pool and executor minimums from Step 2.
- `<FEE_TOKEN_ADDRESS>`: Pass the LINK token address on the source chain here. If you want to pay for CCIP fees in native coin instead, pass `0x0000000000000000000000000000000000000000`
- `$AMOUNT`: token amount in token decimals (for 18 decimals, `1e18` is 1 token).
- `$GAS_LIMIT`: set to `0` for token-only transfer to an EOA receiver.
- `$BLOCK_CONFIRMATIONS`: must be `> 0` and meet the source pool and executor minimums from Step 2.
- `$FEE_TOKEN`: native coin by default (`0x0000000000000000000000000000000000000000`). To pay CCIP fees in LINK instead, run `export FEE_TOKEN=$SEPOLIA_LINK`.

## Verify Result

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ Scripts used:
>
> This chapter assumes `--account myAccount`.

## Chapter Parameters

Set the parameters for this chapter. The defaults work as they are; change a value only if you want something different.

```bash
export GAS_LIMIT=200000 # the receiver callback needs gas
export BLOCK_CONFIRMATIONS=1 # Fast Transfers depth, must be > 0
export MIN_BLOCK_DEPTH=1 # receiver minimum, must be <= BLOCK_CONFIRMATIONS
export FEE_TOKEN=0x0000000000000000000000000000000000000000 # native fee; use $SEPOLIA_LINK to pay in LINK
```

## Receiver Contract Context

### Pre-v2.0
Expand Down Expand Up @@ -99,10 +110,14 @@ forge script script/examples/Example02.s.sol:DeployBasicMessageReceiverWithCCVs
--account myAccount \
--broadcast \
--sig "run(address)" \
<DESTINATION_ROUTER>
$AMOY_ROUTER
```

Save the deployed address as `<BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS>`.
Copy the deployed address from the `[RESULT]` log and export it:

```bash
export BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS=0x...
```

By default, this receiver starts with `minBlockDepth = 0` (default finality only) for all source chains.

Expand All @@ -116,12 +131,12 @@ forge script script/examples/Example02.s.sol:SetBasicMessageReceiverWithCCVsMinB
--account myAccount \
--broadcast \
--sig "run(address,uint64,uint16)" \
<BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS> \
<SOURCE_CHAIN_SELECTOR> \
<MIN_BLOCK_DEPTH>
$BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS \
$SEPOLIA_CHAIN_SELECTOR \
$MIN_BLOCK_DEPTH
```

For this chapter, use `<MIN_BLOCK_DEPTH> = 1`.
This chapter uses `MIN_BLOCK_DEPTH=1` (set in Chapter Parameters).

- `0` means deafault finality-only behavior.
- `> 0` enables Fast Transfers with that minimum depth.
Expand All @@ -136,23 +151,23 @@ forge script script/examples/Example02.s.sol:Example02 \
--account myAccount \
--broadcast \
--sig "run(address,uint64,address,string,uint32,uint16,address)" \
<SOURCE_ROUTER> \
<DESTINATION_CHAIN_SELECTOR> \
<BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS> \
$SEPOLIA_ROUTER \
$AMOY_CHAIN_SELECTOR \
$BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS \
"Hello, World" \
<GAS_LIMIT> \
<BLOCK_CONFIRMATIONS_GT_ZERO> \
<FEE_TOKEN_ADDRESS>
$GAS_LIMIT \
$BLOCK_CONFIRMATIONS \
$FEE_TOKEN
```

Parameter notes:

- `<GAS_LIMIT>` must be `> 0` because the destination receiver callback needs gas.
- `<BLOCK_CONFIRMATIONS_GT_ZERO>` must be `> 0` for Fast Transfers.
- `<BLOCK_CONFIRMATIONS_GT_ZERO>` should be greater than or equal to `<MIN_BLOCK_DEPTH>`.
- `$GAS_LIMIT` must be `> 0` because the destination receiver callback needs gas.
- `$BLOCK_CONFIRMATIONS` must be `> 0` for Fast Transfers.
- `$BLOCK_CONFIRMATIONS` should be greater than or equal to `$MIN_BLOCK_DEPTH`.
- Executor may enforce a minimum block confirmations value and revert if too low.
- If requested confirmations exceed chain finality, default finality is used.
- `<FEE_TOKEN_ADDRESS>`: Pass the LINK token address on the source chain here. If you want to pay for CCIP fees in native coin instead, pass `0x0000000000000000000000000000000000000000`
- `$FEE_TOKEN`: native coin by default (`0x0000000000000000000000000000000000000000`). To pay CCIP fees in LINK instead, run `export FEE_TOKEN=$SEPOLIA_LINK`.

## Verify Result

Expand All @@ -165,5 +180,5 @@ Use that ID in the CCIP Explorer:
You can inspect receiver state on destination chain:

```bash
cast call <BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS> "latestMessage()(bytes)" --rpc-url polygonAmoy
cast call $BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS "latestMessage()(bytes)" --rpc-url polygonAmoy
```
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ This chapter uses Fast Transfers (`blockConfirmations > 0`), so destination rece
- Deploy `BasicMessageReceiverWithCCVs` before running this chapter.
- For default-finality programmable token transfer (`blockConfirmations = 0`), use Example04.

## Chapter Parameters

Set the parameters for this chapter. The defaults work as they are; change a value only if you want something different.

```bash
export AMOUNT=1000000000000000000 # 1 token (18 decimals)
export GAS_LIMIT=200000 # the receiver callback handles data
export BLOCK_CONFIRMATIONS=1 # Fast Transfers depth, must be > 0
export MIN_BLOCK_DEPTH=1 # receiver minimum, must be <= BLOCK_CONFIRMATIONS
export FEE_TOKEN=0x0000000000000000000000000000000000000000 # native fee; use $SEPOLIA_LINK to pay in LINK
```

## Before You Start

> **Important: Keystore first**
Expand All @@ -46,7 +58,7 @@ This chapter uses Fast Transfers (`blockConfirmations > 0`), so destination rece
> --account myAccount \
> --broadcast \
> --sig "run(address)" \
> <DESTINATION_ROUTER>
> $AMOY_ROUTER
> ```
>
> Then configure min block depth for your source chain:
Expand All @@ -57,16 +69,20 @@ This chapter uses Fast Transfers (`blockConfirmations > 0`), so destination rece
> --account myAccount \
> --broadcast \
> --sig "run(address,uint64,uint16)" \
> <BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS> \
> <SOURCE_CHAIN_SELECTOR> \
> <MIN_BLOCK_DEPTH>
> $BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS \
> $SEPOLIA_CHAIN_SELECTOR \
> $MIN_BLOCK_DEPTH
> ```
>
> For this Fast Transfers example, use `<MIN_BLOCK_DEPTH> > 0` and check the source pool minimum too.
> For this Fast Transfers example, `MIN_BLOCK_DEPTH` must be `> 0` (the default is `1`). Check the source pool minimum too.
>
> The script argument accepts `$MIN_BLOCK_DEPTH` (a `uint16` passed to `BasicMessageReceiverWithCCVs.setMinBlockDepth`). On-chain, the receiver does not return that integer directly to CCIP: `getCCVsAndFinalityConfig` sets `allowedFinalityConfig` to `FinalityCodec._encodeBlockDepth(minBlockDepth)` — the same `bytes4` finality encoding CCIP 2.0 uses elsewhere for allowed finality (depth `0` means wait for full/default finality).
>
> The script argument accepts `<MIN_BLOCK_DEPTH>` (a `uint16` passed to `BasicMessageReceiverWithCCVs.setMinBlockDepth`). On-chain, the receiver does not return that integer directly to CCIP: `getCCVsAndFinalityConfig` sets `allowedFinalityConfig` to `FinalityCodec._encodeBlockDepth(minBlockDepth)` — the same `bytes4` finality encoding CCIP 2.0 uses elsewhere for allowed finality (depth `0` means wait for full/default finality).
> Copy the receiver address from the `[RESULT]` log and export it for Step 2 below:
>
> Save the receiver address from the `[RESULT]` log and use it in Step 2 below.
> ```bash
> export BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS=0x...
> ```

## Step 1: Get 1 CCIP-BnM Token on Sepolia

Expand All @@ -78,7 +94,7 @@ forge script script/Faucet.s.sol:Faucet \
--account myAccount \
--broadcast \
--sig "run(address)" \
<CCIP_BNM_SOURCE_TOKEN_ADDRESS>
$SEPOLIA_CCIP_BNM
```

## Step 2: Send Hello World + CCIP-BnM
Expand All @@ -89,25 +105,25 @@ forge script script/examples/Example03.s.sol:Example03 \
--account myAccount \
--broadcast \
--sig "run(address,uint64,address,string,address,uint256,uint32,uint16,address)" \
<SOURCE_ROUTER> \
<DESTINATION_CHAIN_SELECTOR> \
<BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS> \
$SEPOLIA_ROUTER \
$AMOY_CHAIN_SELECTOR \
$BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS \
"Hello, World" \
<CCIP_BNM_SOURCE_TOKEN_ADDRESS> \
<AMOUNT> \
<GAS_LIMIT> \
<BLOCK_CONFIRMATIONS_GT_ZERO> \
<FEE_TOKEN_ADDRESS>
$SEPOLIA_CCIP_BNM \
$AMOUNT \
$GAS_LIMIT \
$BLOCK_CONFIRMATIONS \
$FEE_TOKEN
```

Parameter notes:

- `<AMOUNT>` uses token decimals (`1e18` is 1 token for 18-decimal tokens).
- `<GAS_LIMIT>` must be `> 0` because the receiver contract callback handles data.
- `<BLOCK_CONFIRMATIONS_GT_ZERO>` must meet the source pool and receiver minimums.
- `$AMOUNT` uses token decimals (`1e18` is 1 token for 18-decimal tokens).
- `$GAS_LIMIT` must be `> 0` because the receiver contract callback handles data.
- `$BLOCK_CONFIRMATIONS` must meet the source pool and receiver minimums.
- Executor may enforce a minimum block confirmation value and revert if too low.
- If requested confirmations exceed chain finality, default finality is used.
- `<FEE_TOKEN_ADDRESS>`: Pass the LINK token address on the source chain here. If you want to pay for CCIP fees in native coin instead, pass `0x0000000000000000000000000000000000000000`
- `$FEE_TOKEN`: native coin by default (`0x0000000000000000000000000000000000000000`). To pay CCIP fees in LINK instead, run `export FEE_TOKEN=$SEPOLIA_LINK`.

## Verify Result

Expand All @@ -118,7 +134,7 @@ Parameter notes:
Optional receiver checks on Amoy:

```bash
cast call <BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS> "latestMessage()(bytes)" --rpc-url polygonAmoy
cast call <BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS> "latestSender()(address)" --rpc-url polygonAmoy
cast call <BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS> "latestSourceChainSelector()(uint64)" --rpc-url polygonAmoy
cast call $BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS "latestMessage()(bytes)" --rpc-url polygonAmoy
cast call $BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS "latestSender()(address)" --rpc-url polygonAmoy
cast call $BASIC_MESSAGE_RECEIVER_WITH_CCVS_ADDRESS "latestSourceChainSelector()(uint64)" --rpc-url polygonAmoy
```
Loading
Loading