Skip to content

Commit f243a98

Browse files
committed
updates
1 parent 36b206f commit f243a98

File tree

4 files changed

+254
-245
lines changed

4 files changed

+254
-245
lines changed

src/content/ccip/tutorials/evm/cross-chain-tokens/configure-additional-networks-foundry.mdx

Lines changed: 128 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ date: Last Modified
44
title: "Configure Additional Networks using Foundry"
55
metadata:
66
description: "Learn how to configure additional networks in the smart-contract-examples repository to add support for more CCIP-supported chains using Foundry."
7-
excerpt: "network configuration, Foundry, HelperConfig.sol, CCIP Directory, chain configuration, smart-contract-examples"
7+
excerpt: "network configuration, Foundry, HelperConfig.s.sol, CCIP Directory, chain configuration, smart-contract-examples"
88
image: "/images/ccip/basic-architecture.png"
9-
datePublished: "2024-10-29"
10-
lastModified: "2025-10-24"
11-
estimatedTime: "10 minutes"
9+
datePublished: "2025-10-30"
10+
lastModified: "2025-10-30"
11+
estimatedTime: "5 minutes"
1212
difficulty: "beginner"
1313
---
1414

@@ -29,13 +29,11 @@ import { Aside, CopyText, PageTabs } from "@components"
2929
]}
3030
/>
3131

32-
When working with the [smart-contract-examples](https://github.com/smartcontractkit/smart-contract-examples/tree/main/ccip/cct) CCIP tutorials, you may need to add support for additional blockchain networks beyond the default testnet configurations (_Avalanche Fuji_, _Ethereum Sepolia_, _Arbitrum Sepolia_, _Base Sepolia_, and _Polygon Amoy_). This guide explains how to update the network configuration files in the Foundry version of the repository.
32+
When working with the [smart-contract-examples](https://github.com/smartcontractkit/smart-contract-examples/tree/main/ccip/cct) CCIP tutorials, you may need to add support for additional blockchain networks beyond the default testnet configurations (_Avalanche Fuji_, _Ethereum Sepolia_, _Arbitrum Sepolia_, and _Base Sepolia_, and _Polygon Amoy_).
3333

34-
## Overview
34+
This guide explains how to update the network configuration file in the [Foundry version of the repository](https://github.com/smartcontractkit/smart-contract-examples/tree/main/ccip/cct/foundry). The configuration file stores network-specific information such as:
3535

36-
The [smart-contract-examples](https://github.com/smartcontractkit/smart-contract-examples/tree/main/ccip/cct/foundry) repository includes pre-configured network settings for common CCIP testnets. These configuration files store network-specific information such as:
37-
38-
- Chain selectors
36+
- Chain selectors (unique CCIP identifiers)
3937
- Router addresses
4038
- RMN Proxy addresses
4139
- Token Admin Registry addresses
@@ -44,17 +42,9 @@ The [smart-contract-examples](https://github.com/smartcontractkit/smart-contract
4442
- Block confirmations
4543
- Native currency symbols
4644

47-
**Default networks included**:
48-
49-
- Avalanche Fuji
50-
- Ethereum Sepolia
51-
- Arbitrum Sepolia
52-
- Base Sepolia
53-
- Polygon Amoy
45+
These values vary by network and must be accurate for your CCIP transactions to work correctly. If you want to use additional networks (e.g., Optimism Sepolia, BNB Chain Testnet, or mainnet networks) supported by CCIP, you'll need to update the configuration file following this guide.
5446

55-
These values vary by network and must be accurate for your CCIP transactions to work correctly. If you want to use additional networks (e.g., Optimism Sepolia, BNB Chain Testnet, or mainnet networks), you'll need to update the configuration files following this guide.
56-
57-
## Finding Network Configuration Values
47+
## Find Network Configuration Values
5848

5949
All CCIP-supported networks and their configuration details are available in the **CCIP Directory**:
6050

@@ -63,7 +53,7 @@ All CCIP-supported networks and their configuration details are available in the
6353

6454
The CCIP Directory provides:
6555

66-
- Chain selectors
56+
- Chain selectors (unique CCIP identifiers)
6757
- Router contract addresses
6858
- RMN Proxy addresses
6959
- Token Admin Registry addresses
@@ -75,9 +65,27 @@ The CCIP Directory provides:
7565
incorrect addresses or chain selectors will cause your transactions to fail.
7666
</Aside>
7767

78-
## Updating Configuration Files
68+
## Add `RPC_URL` Environment Variable
69+
70+
To add support for additional networks, you need to configure the `RPC_URL_<NEW_NETWORK_NAME>` environment variable in your `.env` file. This variable should point to the RPC endpoint of the network you want to add.
71+
72+
1. Open the `.env` file in the root of [`smart-contract-examples/ccip/cct/foundry`](https://github.com/smartcontractkit/smart-contract-examples/tree/main/ccip/cct/foundry).
73+
74+
2. Add a new line for the `RPC_URL_<NEW_NETWORK_NAME>` variable:
75+
76+
```env
77+
RPC_URL_<NEW_NETWORK_NAME>=https://your-new-network-rpc-url
78+
```
7979

80-
In the smart-contract-examples repository, Foundry projects store network configuration in `script/HelperConfig.s.sol`.
80+
You can obtain an RPC URL by signing up for a personal endpoint from [Alchemy](https://www.alchemy.com/), [Infura](https://www.infura.io/), or another node provider service.
81+
82+
3. Save the file, then load the environment variables into the terminal session where you will run the commands:
83+
84+
```bash
85+
source .env
86+
```
87+
88+
## Update Configuration File
8189

8290
**File location**: [`smart-contract-examples/ccip/cct/foundry/script/HelperConfig.s.sol`](https://github.com/smartcontractkit/smart-contract-examples/blob/main/ccip/cct/foundry/script/HelperConfig.s.sol)
8391

@@ -90,28 +98,20 @@ pragma solidity 0.8.24;
9098
import {Script} from "forge-std/Script.sol";
9199
92100
contract HelperConfig is Script {
93-
NetworkConfig public activeNetworkConfig;
94-
95-
struct NetworkConfig {
96-
uint64 chainSelector;
97-
address router;
98-
address rmnProxy;
99-
address tokenAdminRegistry;
100-
address registryModuleOwnerCustom;
101-
address link;
102-
uint256 confirmations;
103-
string nativeCurrencySymbol;
104-
}
101+
// Rest of the code...
105102
106103
constructor() {
107-
if (block.chainid == 11155111) {
108-
activeNetworkConfig = getEthereumSepoliaConfig();
109-
} else if (block.chainid == 421614) {
110-
activeNetworkConfig = getArbitrumSepolia();
111-
} else if (block.chainid == 43113) {
104+
105+
// Rest of the existing networks...
106+
107+
else if (block.chainid == 43113) {
112108
activeNetworkConfig = getAvalancheFujiConfig();
113-
} else if (block.chainid == 84532) {
114-
activeNetworkConfig = getBaseSepoliaConfig();
109+
}
110+
111+
// Rest of the existing networks...
112+
113+
else {
114+
revert("Unsupported network");
115115
}
116116
}
117117
@@ -129,7 +129,23 @@ contract HelperConfig is Script {
129129
return avalancheFujiConfig;
130130
}
131131
132-
// Add more network configurations here...
132+
// Rest of the existing network configurations...
133+
134+
function getNetworkConfig(uint256 chainId) public pure returns (NetworkConfig memory) {
135+
136+
// Rest of the existing networks...
137+
138+
else if (chainId == 43113) {
139+
return getAvalancheFujiConfig();
140+
}
141+
142+
// Rest of the existing networks...
143+
144+
else {
145+
revert("Unsupported chain ID");
146+
}
147+
}
148+
133149
}
134150
```
135151

@@ -143,7 +159,7 @@ contract HelperConfig is Script {
143159

144160
1. Open `script/HelperConfig.s.sol` in your preferred editor
145161

146-
1. Visit the [CCIP Directory](/ccip/directory/testnet) (for testnet) or [Mainnet Directory](/ccip/directory/mainnet) (for mainnet)
162+
1. Visit the [CCIP Directory](/ccip/directory)
147163

148164
1. Locate your desired network in the directory and copy the following values:
149165
- Chain Selector
@@ -153,7 +169,7 @@ contract HelperConfig is Script {
153169
- Registry Module Owner Custom address
154170
- LINK token address
155171

156-
1. Find the network's chain ID from its official documentation
172+
1. Determine the chain ID from official network documentation, from [ChainList](https://chainlist.org/), or by running the [`cast chain-id`](https://getfoundry.sh/cast/reference/chain-id/) command.
157173

158174
1. Add a new condition in the `constructor()` to detect the chain ID
159175

@@ -163,25 +179,27 @@ contract HelperConfig is Script {
163179
- `confirmations`: Number of block confirmations to wait (typically 2-3 for testnets, 5-10 for mainnet)
164180
- `nativeCurrencySymbol`: The native currency symbol (e.g., "ETH", "AVAX", "POL")
165181

166-
1. Save the file and test your configuration with a simple script
167-
168182
**Example: Adding Optimism Sepolia Testnet**:
169183

170184
```solidity
185+
// Rest of the code...
186+
171187
constructor() {
172188
if (block.chainid == 11155111) {
173189
activeNetworkConfig = getEthereumSepoliaConfig();
174-
} else if (block.chainid == 421614) {
175-
activeNetworkConfig = getArbitrumSepolia();
176-
} else if (block.chainid == 43113) {
177-
activeNetworkConfig = getAvalancheFujiConfig();
178-
} else if (block.chainid == 84532) {
179-
activeNetworkConfig = getBaseSepoliaConfig();
180-
} else if (block.chainid == 11155420) {
190+
}
191+
192+
// Rest of the existing networks...
193+
194+
else if (block.chainid == 11155420) {
181195
activeNetworkConfig = getOptimismSepoliaConfig();
196+
} else {
197+
revert("Unsupported network");
182198
}
183199
}
184200
201+
// Rest of the existing network configurations...
202+
185203
function getOptimismSepoliaConfig() public pure returns (NetworkConfig memory) {
186204
NetworkConfig memory optimismSepoliaConfig = NetworkConfig({
187205
chainSelector: 5224473277236331295,
@@ -195,78 +213,93 @@ function getOptimismSepoliaConfig() public pure returns (NetworkConfig memory) {
195213
});
196214
return optimismSepoliaConfig;
197215
}
198-
```
199216
200-
## Verifying Your Configuration
217+
function getNetworkConfig(uint256 chainId) public pure returns (NetworkConfig memory) {
218+
if (chainId == 11155111) {
219+
return getEthereumSepoliaConfig();
220+
}
201221
202-
After updating your configuration files, verify that:
222+
// Rest of the existing networks...
203223
204-
1. **Chain Selector**: Matches the value in the CCIP Directory
205-
1. **Router Address**: Matches the CCIP Router address for your network
206-
1. **RMN Proxy**: Matches the RMN Proxy address
207-
1. **Token Admin Registry**: Matches the registry address
208-
1. **Registry Module Owner Custom**: Matches the registry module address
209-
1. **LINK Token**: Matches the LINK token address for your network
210-
1. **Chain ID**: Correct for your network
211-
1. **Block Confirmations**: Set to a reasonable value (2-3 for testnets, higher for mainnet)
224+
else if (chainId == 11155420) {
225+
return getOptimismSepoliaConfig();
226+
} else {
227+
revert("Unsupported chain ID");
228+
}
229+
}
230+
```
212231

213232
<Aside type="caution" title="Test Before Production">
214233
Always test your configuration on testnet before deploying to mainnet. Incorrect configuration values can result in
215234
failed transactions or loss of funds.
216235
</Aside>
217236

218-
## Common Configuration Errors
237+
## Next Steps
219238

220-
### Incorrect Chain Selector
239+
Once you've updated your network configuration in the smart-contract-examples repository:
221240

222-
**Symptom**: Transactions fail with "destination chain not supported" error
223-
**Solution**: Verify the chain selector matches the CCIP Directory exactly
241+
1. **Fund your wallet** with native tokens and LINK for the new network using the [Chainlink faucets](https://faucets.chain.link/) (for testnets)
224242

225-
### Wrong Router Address
243+
1. **Test the configuration** by running a simple deployment:
226244

227-
**Symptom**: Transactions revert when calling CCIP Router
228-
**Solution**: Ensure you're using the correct CCIP Router address from the directory
245+
```bash
246+
forge script script/DeployToken.s.sol --rpc-url $RPC_URL_<NEW_NETWORK_NAME> --private-key $PRIVATE_KEY --broadcast
247+
```
229248

230-
### Mismatched Token Addresses
249+
<br></br>
231250

232-
**Symptom**: LINK approval or transfer operations fail
233-
**Solution**: Verify the LINK token address for your specific network
251+
#### Contract Verification (Optional)
234252

235-
### Chain ID Mismatch
253+
**Automatic Verification (Natively Supported):**
254+
Most standard networks are natively supported by Foundry for contract verification. Check [Foundry's `StdChains.sol::StdChains::initializeStdChains()`](https://github.com/foundry-rs/forge-std/blob/master/src/StdChains.sol#L193) function for the complete list of supported networks.
236255

237-
**Symptom**: Wrong network configuration is loaded
238-
**Solution**: Check that the chain ID in the constructor matches your target network
256+
You just need to add the `--verify` flag when deploying:
239257

240-
## Related Resources
258+
```bash
259+
forge script script/DeployToken.s.sol --rpc-url $RPC_URL_<NEW_NETWORK_NAME> --private-key $PRIVATE_KEY --broadcast --verify
260+
```
241261

242-
- [CCIP Directory - Testnet](/ccip/directory/testnet): Complete list of testnet networks and configuration values
243-
- [CCIP Directory - Mainnet](/ccip/directory/mainnet): Complete list of mainnet networks and configuration values
244-
- [Register from an EOA (Burn & Mint)](/ccip/tutorials/evm/cross-chain-tokens/register-from-eoa-burn-mint-foundry): Tutorial using these configuration files
245-
- [Set Token Pool rate limits](/ccip/tutorials/evm/cross-chain-tokens/update-rate-limiters-foundry): Tutorial for configuring rate limiters
262+
Or if already deployed, you can verify using the [`forge verify-contract` command](https://getfoundry.sh/forge/reference/verify-contract#forge-verify-contract).
246263

247-
## Adapting for Your Own Projects
264+
<br></br>
248265

249-
While this guide focuses on the smart-contract-examples repository structure, you can adapt these principles for your own projects:
266+
#### Custom Network Deployment and Verification
250267

251-
1. **Different project structure**: Adjust the file paths to match your project's organization
252-
1. **Custom configuration format**: You may use environment variables, YAML, TOML, or other formats—apply the same CCIP Directory values
253-
1. **Additional parameters**: Your project may require extra configuration fields beyond what's shown here
254-
1. **Multiple networks**: Consider organizing configurations by environment (development, staging, production)
268+
**Custom Network Deployment:**
269+
For networks not natively supported by Foundry, replace the dynamic chain name lookup (`getChain(block.chainid).chainAlias`) in your deployment script with a hardcoded string, as the `getChain` call will revert on unsupported networks.
255270

256-
The key principle remains the same: **Always retrieve official CCIP configuration values from the [CCIP Directory](/ccip/directory)** to ensure compatibility and correctness.
271+
So, replace this line:
257272

258-
## Next Steps
273+
```solidity
274+
string memory chainName = getChain(block.chainid).chainAlias;
275+
```
259276

260-
Once you've updated your network configuration in the smart-contract-examples repository:
277+
with this:
261278

262-
1. **Update RPC URLs**: Add the RPC URL to your `.env` file and use the environment variable as the value for the `--rpc-url` flag
279+
```solidity
280+
string memory chainName = "custom"; // or any other string identifier you prefer
281+
```
263282

264-
1. **Fund your wallet** with native tokens and LINK for the new network using the [Chainlink faucets](https://faucets.chain.link/) (for testnets)
283+
<br></br>
265284

266-
1. **Test the configuration** by running a simple deployment:
285+
**Custom Network Verification:**
286+
For networks not natively supported by Foundry, include the `--verifier`, `--verifier-url`, and `--verifier-api-key` flags together with `--verify` when deploying, like:
267287

268288
```bash
269-
forge script script/DeployToken.s.sol --rpc-url $YOUR_NEW_NETWORK_RPC_URL --private-key $PRIVATE_KEY --broadcast
289+
forge script script/DeployToken.s.sol --rpc-url $RPC_URL_<NEW_NETWORK_NAME> --private-key $PRIVATE_KEY --broadcast --verify --verifier custom --verifier-url $CUSTOM_EXPLORER_API_URL --verifier-api-key $CUSTOM_EXPLORER_API_KEY
270290
```
271291

292+
Refer to the [Foundry docs](https://getfoundry.sh/forge/reference/verify-check/) for more details.
293+
294+
This is particularly useful for:
295+
- Newer networks not yet added to Hardhat
296+
- Private/enterprise chains
297+
- Custom testnets
298+
299+
**Note:** With [Etherscan API V2](https://docs.etherscan.io/introduction), a single `ETHERSCAN_API_KEY` works across all Etherscan-compatible networks.
300+
272301
1. **Follow the tutorials** using your newly configured network
302+
303+
## Adapt for Your Own Projects
304+
305+
While this guide focuses on the smart-contract-examples repository structure, you can adapt these principles for your own projects.

0 commit comments

Comments
 (0)