Cross-Chain Tokens with Production Multisig Governance
This tutorial implements production-grade cross-chain tokens using Chainlink CCIP with dual-layer multisig governance between Solana Devnet and Ethereum Sepolia. You'll build a production-ready governance architecture following Path A from the CCIP Cross-Chain Token Integration Guide.
What You Will Build
Upon completion, you will have:
Component | Implementation | Security Model |
---|---|---|
Ethereum Sepolia | ERC20 token with CCIP BurnMint pool | EOA-controlled (tutorial) |
Solana Devnet | SPL token with dual-layer governance | Squads + SPL multisig |
Cross-Chain Bridge | Bidirectional token transfers | Autonomous operations |
Architecture (Solana) | Production-ready setup | Enterprise-grade governance |
Key Innovation: Dual-Layer Governance
Separation of Concerns Architecture:
- Layer 1 (Squads): Controls CCIP administration, pool ownership, protocol configuration
- Layer 2 (SPL Multisig): Controls mint authority with Pool Signer PDA for autonomous operations
Implementation Steps
You will:
- Deploy EVM token and pool on Ethereum Sepolia
- Create governed SPL tokens with Squads as mint authority
- Establish dual-layer multisig (Squads โ SPL multisig transfer)
- Configure cross-chain pools with autonomous operations
- Test bidirectional transfers and validate governance
Path A Production Governance Options:
- Direct Transfer: Transfer mint authority directly to Pool Signer PDA - suitable for development and testing (see tutorial)
- Educational Multisig: Learn SPL token multisig concepts - foundation for understanding (see tutorial)
- Production Governance (this tutorial): Implement enterprise-grade dual-layer multisig with Squads governance
Technical Architecture
Before proceeding with implementation, it's crucial to understand the dual-layer multisig governance architecture that provides enterprise-grade security.
Production Dual-Layer Multisig Architecture
This tutorial implements dual-layer multisig governance that separates concerns between protocol administration and token operations:
graph TB
subgraph "Layer 1: Squads Multisig Governance"
SM["Squads Multisig<br/>๐๏ธ Protocol Administration"]
TAR["CCIP Token Admin<br/>Registry Roles"]
PO["CCIP Pool<br/>Ownership"]
CS["Cross-chain<br/>Settings"]
PA["Protocol-level<br/>Functions"]
SM --> TAR
SM --> PO
SM --> CS
SM --> PA
end
subgraph "Layer 2: SPL Token Multisig"
SPL["SPL Token Multisig<br/>๐ Mint Authority Control"]
PDA["Pool Signer PDA<br/>โก Autonomous Operations"]
SMG["Squads Multisig<br/>๐๏ธ Governance Control"]
SPL --> PDA
SPL --> SMG
end
subgraph "Cross-Chain Operations"
CCT["Cross-Chain<br/>Token Transfers"]
AUTO["Autonomous<br/>Pool Operations"]
end
SM -.-> SMG
PDA --> AUTO
AUTO --> CCT
PA --> CCT
classDef governance fill:#e1f5fe,stroke:#0277bd,stroke-width:2px
classDef autonomous fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef operations fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px
class SM,SMG,TAR,PO,CS,PA governance
class PDA,AUTO autonomous
class SPL,CCT operations
Why Dual-Layer Architecture
Separation of Concerns:
- Layer 1 (Squads): Controls all CCIP protocol operations, pool configuration, and administrative functions
- Layer 2 (SPL Multisig): Controls token mint authority with autonomous pool operations
Production Benefits:
- Comprehensive Security: Two independent governance layers with different security models
- Operational Autonomy: Pool Signer PDA enables autonomous cross-chain transfers
- Administrative Control: Squads provides enterprise-grade governance for all configuration changes
- Scalable Architecture: Suitable for mainnet deployment with proper governance procedures
This tutorial focuses on mainnet-ready governance architecture, demonstrating how to implement comprehensive security controls while maintaining autonomous cross-chain token transfers through BurnMint token pools.
Tutorial Approach
This tutorial implements production-grade cross-chain tokens using a three-terminal workflow across specialized repositories:
Terminal | Repository | Purpose | Commands |
---|---|---|---|
Terminal 1 | CCIP Solana base58 Generator | Generate governance transactions | pnpm bs58 |
Terminal 2 | Smart Contract Examples (Hardhat) | Deploy EVM components | npx hardhat |
Terminal 3 | Solana Starter Kit | Test cross-chain transfers | yarn |
Key Implementation Notes
- Terminal 1 generates base58-encoded transactions for Squads multisig governance
- Terminal 2 uses EOA for tutorial simplicity; production deployments should use multisig wallets (e.g., Safe)
- Terminal 3 validates end-to-end cross-chain functionality
base58 Transaction Execution Workflow
Transaction Generation & Validation:
- CLI Simulation: Each base58 transaction is automatically simulated during generation
- Error Handling: If simulation fails, error logs appear in terminal - do not upload failed transactions to Squads
- Success Indicator: Successful simulation shows transaction preview and base58 output
Squads Multisig Execution Process:
- Propose: A signer imports the base58 transaction into Squads UI โ "Add instruction" โ "Import base58 encoded tx" โ Initiate Transaction
- Approve: Required threshold (M) of signers review and approve the transaction
- Simulate (Recommended): Before execution, signers can simulate through Squads interface to preview onchain effects
- Execute: After threshold approval, any signer can execute the transaction
Environment Variables
Variables use prefixes to prevent confusion across repositories:
Prefix | Usage | Examples |
---|---|---|
ETH_* | Ethereum addresses | ETH_TOKEN_ADDRESS , ETH_POOL_ADDRESS |
SOL_* | Solana addresses | SOL_TOKEN_MINT , SOL_POOL_ADDRESS |
CCIP_* | Protocol constants | CCIP_POOL_PROGRAM , CCIP_ROUTER_PROGRAM |
Prerequisites
System Requirements
Install these tools before starting:
Package Managers:
- Node.js v20+: Required for all repositories
- pnpm: Required for base58 Generator (
npm install -g pnpm
) - yarn: Required for Solana Starter Kit (
npm install -g yarn
)
Solana Development:
- Solana CLI: Installation guide
Wallets:
- Solana wallet: Phantom or Backpack for Devnet operations
- Ethereum wallet: MetaMask for Sepolia testnet operations
Repository Setup
Clone and install dependencies for all three repositories:
Terminal 1: base58 Generator
git clone https://github.com/smartcontractkit/ccip-solana-bs58-generator.git
cd ccip-solana-bs58-generator
pnpm install
Terminal 2: EVM Hardhat
git clone https://github.com/smartcontractkit/smart-contract-examples.git
cd smart-contract-examples/ccip/cct/hardhat
npm install
npm run compile
Terminal 3: Solana Starter Kit
git clone https://github.com/smartcontractkit/solana-starter-kit.git
cd solana-starter-kit
yarn install
Create and configure the .env file:
# Create .env file in the project root
cat > .env << 'EOF'
EVM_PRIVATE_KEY=your_private_key_here
EVM_RPC_URL=your_rpc_url_here
EOF
Replace the placeholder values with:
EVM_PRIVATE_KEY
: Your Ethereum wallet private key (for Sepolia testnet operations)EVM_RPC_URL
: Your Ethereum RPC URL (from Alchemy, Infura, or another provider)
Environment Configuration
Solana Configuration:
# Set Solana CLI to devnet
solana config set --url https://api.devnet.solana.com
# Create keypair (ONLY IF NEEDED)
solana-keygen new --outfile ~/.config/solana/id.json
# Check Config
solana config get
# Fund wallet
solana airdrop 3
Ethereum Sepolia Configuration:
# In Terminal 2 (Hardhat directory)
npx env-enc set-pw
npx env-enc set
Required environment variables:
ETHEREUM_SEPOLIA_RPC_URL
: RPC endpoint (Alchemy or Infura)PRIVATE_KEY
: Testnet wallet private keyETHERSCAN_API_KEY
: API key from Etherscan
Testnet Tokens:
- Solana Devnet: Use
solana airdrop 3
for SOL - Ethereum Sepolia: Use Chainlink faucets for LINK and ETH
Squads Multisig Setup
Step 1: Prepare Signers
Create multiple wallet addresses for your multisig signers:
# Create additional signers using Solana CLI
solana-keygen new --outfile ~/.config/solana/signer2.json
solana-keygen new --outfile ~/.config/solana/signer3.json
# Get signer addresses
solana address --keypair ~/.config/solana/id.json
solana address --keypair ~/.config/solana/signer2.json
solana address --keypair ~/.config/solana/signer3.json
# Fund signers (minimum 0.1 SOL each for transaction fees)
solana transfer <SIGNER2_ADDRESS> 0.1 --allow-unfunded-recipient
solana transfer <SIGNER3_ADDRESS> 0.1 --allow-unfunded-recipient
Alternatively, create signers in Phantom wallet and fund them:
# Transfer SOL to Phantom-created addresses
solana transfer <PHANTOM_SIGNER_ADDRESS> 0.5 --allow-unfunded-recipient
Step 2: Create Your Squad
- Visit devnet.squads.so
- Connect your Solana wallet (e.g., Phantom/Backpack)
- Click "Create New Squad"
- Configure your multisig:
- Squad Name: Choose a descriptive name (e.g., "CCIP Token Governance")
- Members: Add wallet addresses of all signers
- Threshold: Set approval threshold (recommended: 2/3 or 3/5)
Step 3: Record Critical Addresses
After Squad creation, navigate to Settings tab and record these addresses.
In Terminal 1 (base58 Generator), export the vault address:
# CRITICAL: Use the VAULT address, NOT the multisig address
export SOL_SQUAD_VAULT_MULTISIG="YOUR_VAULT_ADDRESS_HERE"
Verify the export:
echo "Squads Vault Address: $SOL_SQUAD_VAULT_MULTISIG"
Step 4: Test Your Squad
Perform a small test transaction to verify setup:
- Send a small amount of SOL to your Squad vault
- Create a test transaction in Squads UI (e.g., SOL transfer to your wallet)
- Confirm all signers can approve transactions
- Execute the transaction
For detailed setup guidance, see the Squads Documentation.
Token Creation Option
Phase 1: EVM Chain Setup (Ethereum Sepolia)
In this phase, you will deploy ERC20 tokens and configure CCIP BurnMint pools on Ethereum Sepolia. This setup is identical across all Path A variants and provides the foundation for cross-chain operations.
Step 1: Prepare EVM Environment
First, set up your terminal and verify your environment:
# Terminal 2: Navigate to EVM repository
# Verify location and project structure
# Should output: smart-contract-examples/ccip/cct/hardhat
pwd
# Verify private key variables are set:
npx env-enc view
# Expected verification output
$ npx env-enc view
The following variables are encrypted and stored in /../smart-contract-examples/ccip/cct/hardhat/.env.enc
PRIVATE_KEY = c8376...
ETHEREUM_SEPOLIA_RPC_URL = https://sepolia.gateway.tenderly.co/...
ETHERSCAN_API_KEY = 9AVYS...
Step 2: Deploy ERC20 Token
Deploy your cross-chain token on Ethereum Sepolia:
# Deploy ERC20 token
npx hardhat deployToken \
--name "AEM Token" \
--symbol "BnmAEM" \
--decimals 18 \
--verifycontract true \
--network sepolia
# Copy the token address from the output above
2025-08-12T14:40:21.321Z info: Deploying BurnMintERC20 contract to sepolia
2025-08-12T14:40:21.321Z info: Waiting 3 blocks for transaction 0xd47c0c1113d42bed9a8cc6bb002aaebf1d859573df865fcd3ff3c0b0fb1f59f7 to be confirmed...
2025-08-12T14:40:48.620Z info: Token deployed to: 0x9cE471d0a7bE21ee32276ddE49104fE02C812906
2025-08-12T14:40:48.682Z info: Granting mint and burn roles to 0x9d087fC03ae39b088326b67fA3C788236645b717
2025-08-12T14:41:27.376Z info: Verifying contract...
The contract 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 has already been verified on the block explorer. If you're trying to verify a partially verified contract, please use the --force flag.
https://sepolia.etherscan.io/address/0x9cE471d0a7bE21ee32276ddE49104fE02C812906#code
2025-08-12T14:41:27.983Z info: Token contract deployed and verified
Set the token address variable:
# REPLACE with actual address from deployment output
export ETH_TOKEN_ADDRESS="<INSERT_YOUR_ACTUAL_TOKEN_ADDRESS>"
Verify the address is set correctly:
echo "โ
Ethereum Token Address: $ETH_TOKEN_ADDRESS"
$ echo "โ
Ethereum Token Address: $ETH_TOKEN_ADDRESS"
โ
Ethereum Token Address: 0x9cE471d0a7bE21ee32276ddE49104fE02C812906
Step 3: Deploy and Configure CCIP BurnMint Pool
Deploy the BurnMint token pool:
# Deploy BurnMint pool
npx hardhat deployTokenPool \
--tokenaddress $ETH_TOKEN_ADDRESS \
--localtokendecimals 18 \
--pooltype burnMint \
--verifycontract true \
--network sepolia
2025-08-12T14:44:45.695Z info: Waiting 3 blocks for transaction 0xb751ffe3f2689a30807aa3205e35d69bd9bff08f0f52f7122a306b4a73216fde to be confirmed...
2025-08-12T14:54:13.315Z info: Token pool deployed to: 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342
2025-08-12T14:54:13.318Z info: Granting mint and burn roles to 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342 on token 0x9cE471d0a7bE21ee32276ddE49104fE02C812906
2025-08-12T14:54:49.181Z info: Verifying contract...
The contract 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342 has already been verified on the block explorer. If you're trying to verify a partially verified contract, please use the --force flag.
https://sepolia.etherscan.io/address/0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342#code
2025-08-12T14:54:49.800Z info: Token pool contract deployed and verified
๐ Copy the pool address from the output above:
Pool Address: 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342
Set the pool address and configure:
# REPLACE with actual address from deployment output
export ETH_POOL_ADDRESS="<INSERT_YOUR_ACTUAL_POOL_ADDRESS>"
Verify configuration
echo "โ
Ethereum Pool Address: $ETH_POOL_ADDRESS"
$ echo "โ
Ethereum Pool Address: $ETH_POOL_ADDRESS"
โ
Ethereum Pool Address: 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342
Step 4: Mint Initial Token Supply
Mint tokens for testing:
# Mint 1000 tokens for testing
npx hardhat mintTokens \
--tokenaddress $ETH_TOKEN_ADDRESS \
--amount 1000000000000000000000 \
--network sepolia
# Note: Balance can be checked in your wallet or through block explorer
echo "โ
Tokens minted successfully"
$ # Mint 1000 tokens for testing
npx hardhat mintTokens \
--tokenaddress $ETH_TOKEN_ADDRESS \
--amount 1000000000000000000000 \
--network sepolia
# Note: Balance can be checked in your wallet or through block explorer
echo "โ
Tokens minted successfully"
2025-08-12T15:48:47.067Z info: Minting 1000000000000000000000 of BnmAEM tokens to 0x9d087fC03ae39b088326b67fA3C788236645b717
2025-08-12T15:49:26.227Z info: Minted 1000000000000000000000 of BnmAEM tokens to 0x9d087fC03ae39b088326b67fA3C788236645b717 - transaction hash: 0xff28bbced4415a26efa158a3e5cfbdc41b7d8503dd60a75ae38c0ede1f9257fd
2025-08-12T15:49:26.316Z info: Current balance of 0x9d087fC03ae39b088326b67fA3C788236645b717 is 1000000000000000000000 BnmAEM
โ
Tokens minted successfully
Step 5: Claim CCIP Admin Role
In this step, you will use the claimAdmin
task to register your EOA as the administrator for the deployed token on Ethereum Sepolia. This process involves calling the RegistryModuleOwnerCustom
contract, which will fetch the CCIP admin of the token and set it up as the admin in the registry.
# Claim admin role for CCIP token registry
npx hardhat claimAdmin \
--tokenaddress $ETH_TOKEN_ADDRESS \
--network sepolia
2025-08-12T21:22:38.303Z info: ๐ฏ Attempting to claim admin for token 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 using getCCIPAdmin mode
2025-08-12T21:22:39.072Z info: Current token CCIP admin: 0x9d087fC03ae39b088326b67fA3C788236645b717
2025-08-12T21:22:39.072Z info: Claiming admin of 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 via getCCIPAdmin() for CCIP admin 0x9d087fC03ae39b088326b67fA3C788236645b717
2025-08-12T21:23:13.903Z info: โ
Successfully claimed admin of 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 using getCCIPAdmin mode. Transaction: 0x3765b1e222b7bb55ea7d601a10a27e83d7cbfe76ad8a286b39f833c9f17283ee
Step 6: Accept CCIP Admin Role
In this step, you will use the acceptAdminRole
task to accept the admin role for the deployed token on Ethereum Sepolia. Once you have claimed the role, accepting the role finalizes your control over the token administration.
# Accept admin role to complete CCIP registration
npx hardhat acceptAdminRole \
--tokenaddress $ETH_TOKEN_ADDRESS \
--network sepolia
2025-08-12T21:26:15.066Z info: Accepted admin role for token 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 tx: 0x883db3a63416eb02c56ec39661f6a7c90e7db8cabb57779a653008404b714d37
Step 7: Register Pool with Token
In this step, you will use the setPool
task to register the BurnMint token pool with the token in Ethereum's TokenAdminRegistry contract. This function sets the pool contract address for the token, enabling it for CCIP cross-chain transfers. Only the token administrator can call this function.
# Register token pool with TokenAdminRegistry contract
npx hardhat setPool \
--tokenaddress $ETH_TOKEN_ADDRESS \
--pooladdress $ETH_POOL_ADDRESS \
--network sepolia
2025-08-12T21:27:24.993Z info: Setting pool for token 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 to 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342 by 0x9d087fC03ae39b088326b67fA3C788236645b717
2025-08-12T21:28:14.346Z info: Pool set for token 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 to 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342
Phase 1 Complete: Save your variables:
# Save Phase 1 variables for later use
echo "export ETH_TOKEN_ADDRESS=\"$ETH_TOKEN_ADDRESS\"" > ~/.phase1_vars
echo "export ETH_POOL_ADDRESS=\"$ETH_POOL_ADDRESS\"" >> ~/.phase1_vars
echo "=== Phase 1 Complete - EVM Setup ==="
echo "โ
ETH Token: $ETH_TOKEN_ADDRESS"
echo "โ
ETH Pool: $ETH_POOL_ADDRESS"
$ # Save Phase 1 variables for later use
echo "export ETH_TOKEN_ADDRESS=\"$ETH_TOKEN_ADDRESS\"" > ~/.phase1_vars
echo "export ETH_POOL_ADDRESS=\"$ETH_POOL_ADDRESS\"" >> ~/.phase1_vars
echo "=== Phase 1 Complete - EVM Setup ==="
echo "โ
ETH Token: $ETH_TOKEN_ADDRESS"
echo "โ
ETH Pool: $ETH_POOL_ADDRESS"
=== Phase 1 Complete - EVM Setup ===
โ
ETH Token: 0x9cE471d0a7bE21ee32276ddE49104fE02C812906
โ
ETH Pool: 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342
Phase 2: Solana Setup with Production Dual Multisig Governance
In this phase, you will implement the production-grade dual-layer multisig governance architecture on Solana Devnet.
Step 1: Prepare base58 Environment
# Terminal 1: Verify location
# Should output: ccip-solana-bs58-generator
pwd
Set up CCIP protocol constants on Solana Devnet (DO NOT CHANGE THESE)
export CCIP_POOL_PROGRAM="3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo"
export CCIP_ROUTER_PROGRAM="Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C"
export CCIP_FEE_QUOTER_PROGRAM="FeeQPGkKDeRV1MgoYfMH6L8o3KeuYjwUZrgn4LRKfjHi"
Get your Solana wallet address for token recipient:
export SOL_WALLET_ADDRESS=$(solana address)
Verify all required variables are set:
echo "โ
Pool Program: $CCIP_POOL_PROGRAM"
echo "โ
Router Program: $CCIP_ROUTER_PROGRAM"
echo "โ
Squad Vault (from Prerequisites): $SOL_SQUAD_VAULT_MULTISIG"
echo "โ
Recipient Wallet: $SOL_WALLET_ADDRESS"
$ # Terminal 1: Verify location
# Should output: ccip-solana-bs58-generator
pwd
/.../ccip-solana-bs58-generator
$ export CCIP_POOL_PROGRAM="3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo"
export CCIP_ROUTER_PROGRAM="Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C"
export CCIP_FEE_QUOTER_PROGRAM="FeeQPGkKDeRV1MgoYfMH6L8o3KeuYjwUZrgn4LRKfjHi"
$ export SOL_WALLET_ADDRESS=$(solana address)
$ echo "โ
Pool Program: $CCIP_POOL_PROGRAM"
echo "โ
Router Program: $CCIP_ROUTER_PROGRAM"
echo "โ
Squad Vault (from Prerequisites): $SOL_SQUAD_VAULT_MULTISIG"
echo "โ
Recipient Wallet: $SOL_WALLET_ADDRESS"
โ
Pool Program: 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo
โ
Router Program: Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C
โ
Squad Vault (from Prerequisites): 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
โ
Recipient Wallet: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
Step 2: Create SPL Token (Layer 2 Foundation)
This command generates a transaction that creates a new SPL token mint with the following features:
- Mint Authority: Set to your Squad vault multisig for governance control
- Metaplex Metadata: Includes token name, symbol, and URI for cross-platform compatibility
- Initial Supply: Automatically mints 5,000 tokens (5,000,000,000,000 smallest units) to your wallet
- Deterministic Address: Uses a seed-based approach for predictable mint addresses
Generate the SPL token creation transaction (customize parameters or reuse the example):
# Generate SPL token creation transaction with initial supply
pnpm bs58 spl-token \
--env devnet \
--instruction create-mint \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--decimals 9 \
--with-metaplex true \
--name "AEM" \
--symbol "CCIP-AEM" \
--uri "https://cyan-pleasant-anteater-613.mypinata.cloud/ipfs/bafkreieirlwjqbtzniqsgcjebzexlcspcmvd4woh3ajvf2p4fuivkenw6i" \
--initial-supply 5000000000000 \
--recipient $SOL_WALLET_ADDRESS
$ pnpm bs58 spl-token \
--env devnet \
--instruction create-mint \
--authority "59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY" \
--decimals "9" \
--with-metaplex "true" \
--name "AEM" \
--symbol "CCIP-AEM" \
--uri "https://cyan-pleasant-anteater-613.mypinata.cloud/ipfs/bafkreieirlwjqbtzniqsgcjebzexlcspcmvd4woh3ajvf2p4fuivkenw6i" \
--initial-supply "5000000000000" \
--recipient "EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB"
> ccip-solana-bs58-generator@1.0.0 bs58
> tsx src/index.ts spl-token --env devnet --instruction create-mint...
INFO [2025-08-12 18:00:46.051]: ๐ Validating create mint parameters...
INFO [2025-08-12 18:00:46.052]: ๐ Token Program: spl-token (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)
INFO [2025-08-12 18:00:46.052]: ๐ Decimals: 9
INFO [2025-08-12 18:00:46.052]: ๐ Metaplex metadata enabled
INFO [2025-08-12 18:00:46.052]: ๐ Initial supply: 5000000000000 smallest units
INFO [2025-08-12 18:00:46.052]: ๐ Recipient: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
INFO [2025-08-12 18:00:46.060]: ๐ Generated mint address: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
๐ฏ COPY TRANSACTION DATA BELOW:
EmZGftWY3kgypWmDBu8jg2G4E5RzYwFCF3oQiXDcrr1fMeQqxTtmWqrWN8qRQ63otsHxXAH1mJXMRxm2hjwbpqF1WdD8AwZto8S2RVyYq6wS4XQ4pxXs38WgqgfFPWfMUXQu12fAqmthYZtfsY7pcYa8LsL48EBR9gSeR5rXHwKoXFv3Xp8Wm4XR86Aw3Gfqhv23vXgZQCKKEpPDHAccPeny5WmLpH3pcmP6yNBMBcyS6KV46DxcCX5mRSLg1Z2fbxvyeYsjb1woeykihAwE2FxSGnNxHN6SZ3yUpkE4a9Yt6nrK4ASqNgFZAGDCNEqdjmg2peW85DsvyijZeq9Meb3b57u6oBEBKB6Pbra56DcqgMk1zX1Y1neRfDuEfpETKCZbaC559vV2bHy94ybevY4fqxXLuJZjuppqpMPJKpfCNfMrSCp8M2UjGQERTfo5zLyccyP3p23GYZnYX1jWhe6f9QRBU24JcacETu1WKpACRQ2JWtShmu2PdXhPtD3X6u36rdRcEYrwipfBVJrqEWZJzPCYXu4tbHzH5MqRfgmtHKQJyS7MAM9wqYeFw7MBz2XrR2mscPZMjdmzTxg7bfaTFicxwXanpY1tBPJmb1uLDv5cQuMVp5MS59H81Kwfn3mssm7LN6KZYNwVzEo5Hd6TSm12oTqxDbqiXW21J5hmr9jVNvEEyHeaBPxuJn52QjU1EwE28u7uxNoXTqjP2mo26wsUBAhgGNYFuyXMrFqGzVsfyVeR28aefuQTmPkynVJeotCtwWE9KaGHGUT4wLBratbY2EGXmLNQVbWYD9gcEwFdtBwPxPLqyCHgwtt2qqZFgNr7j9Rw2FM75gb7H9SXvjRidgK74238LiADNVXZjRGSMa7WmfjXv8ShApAzcrG4JPoyE5KB9bPoBYAEwh3VakMVw2w5x913hZ2rG91wybdUTrVG4PBchirZkwuLMupAfb8wGMuno2PdAxWQwz94KiikBSb3fMS8q5MqXrepch1izPUDUoZPyi3g3ptBHeaHog3sqdSn9TVXFS6AwpWcRuQG93qAkRFuAM9p9LantroeqisgQAWDA1ALhEYFvC19p8y2tHQkZtxEV3vD77uH
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
INFO [2025-08-12 18:00:46.989]: โ
Transaction simulation completed
INFO [2025-08-12 18:00:46.990]: ๐ Transaction generated successfully!
INFO [2025-08-12 18:00:46.990]: ๐ Generated mint address: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
INFO [2025-08-12 18:00:46.990]: Size: 815 bytes, Compute units: 82,237
After execution, set the token mint:
# Copy the mint address from the base58 generator output above
export SOL_TOKEN_MINT="<YOUR_ACTUAL_MINT_ADDRESS>"
Verify the token mint:
echo "โ
Token Mint: $SOL_TOKEN_MINT"
export SOL_TOKEN_MINT="EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
โ
Token Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
Step 3: Initialize BurnMint Token Pool (Before Multisig Setup)
This command creates only one new account and establishes references to existing infrastructure:
What Gets Created:
- Pool State PDA: Creates the onchain Pool State account that stores your token's CCIP configuration
What Gets Referenced (Not Created):
- Authority Assignment: Sets your Squad vault as the pool owner with full configuration control
- Router Integration: References the existing global CCIP router and RMN (Risk Management Network)
- Pool Signer PDA: The Pool Signer PDA is mathematically derived but not created - it will be used on-demand during cross-chain operations
The initialize-pool
instruction creates only the Pool State account for your SPL token mint, establishing you as the pool owner while referencing existing global infrastructure.
Generate the pool initialization transaction:
# Generate pool initialization transaction
pnpm bs58 burnmint-token-pool --env devnet --instruction initialize-pool \
--program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG
$ pnpm bs58 burnmint-token-pool --env devnet --instruction initialize-pool \
--program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts burnmint-token-pool --env devnet --instruction initialize-pool --program-id 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
โ
RPC connection verified
๐ Generating initialize (pool) transaction...
๐ Building and simulating transaction...
โ
Transaction simulation completed
๐ฏ COPY TRANSACTION DATA BELOW:
FBAuxuhVLrvnXFVrZZ818eWSCdJFif8x7mkKK5X6RBW7AUvzhNKB2mMHfHAKP4UuBMDNQppHs931Vb1UuMYXoXqFE7FCNzYrmEgzok88gdhg37Ep4CegtPWh63eKEC9nx1eDD5nzw5hRn2oSHj3FWELNydyyPfDj4RUZkd5zBQhMczzV9U2Y7AUtLxAD4d9QRrc8akCnF4dR3maHQsyuKz9KEV1mKkKuQ1EhyN5rqRKJHydv4Jq1gnYiJQg9ERdJRTsN285veSmYgVoxYMphtczU5qcbHk5A9K2boa3YpTKNtLkgKve7GWs81QZ47V8Fpzdb9BU3aWBoZPiAs7zuDCJ4KtJdtq8uER5Yv73rgyPzj8ABEtxCGaDapi3E
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Transaction generated successfully!
๐ Transaction Details:
Instruction: burnmint.initialize
Size: 279 bytes
Base58 length: 380 characters
Compute units: 36,373
Generated: 2025-08-12T16:33:28.920Z
๐ Transaction Data (Base58):
๐ก Triple-click the line above to select the entire transaction data
๐ Account Information:
Total accounts: 7 1. gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM (writable) 2. EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND (read-only) 3. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable) 4. 11111111111111111111111111111111 (read-only) 5. 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo (read-only) 6. HtzqB9hPSCvcbB5ZbeeBEYmmnCrtK4Zeg2R1hapcCT4n (read-only) 7. 3sM46YunqEj7xWQaV3fzogeuAnqDZkW1suiVfGqpTRHz (read-only)
Account Breakdown from the Transaction (Example):
Account | Address | Purpose |
---|---|---|
#1 | gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM | Pool State PDA - Your main pool configuration |
#2 | EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND | Token Mint (your token) |
#3 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Authority (your Squad vault) |
#4 | 11111111111111111111111111111111 | System Program |
#5 | 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo | CCIP Pool Program |
#6 | HtzqB9hPSCvcbB5ZbeeBEYmmnCrtK4Zeg2R1hapcCT4n | Program Data PDA |
#7 | 3sM46YunqEj7xWQaV3fzogeuAnqDZkW1suiVfGqpTRHz | Global Config PDA - Program-wide configuration settings |
Key Addresses You Need:
- Account #1 โ
SOL_POOL_ADDRESS
(writable account = pool state) - Pool Signer PDA โ Must be derived separately (NOT in transaction accounts)
After execution, set the pool state address from the transaction:
# Set the pool state address from Account #1 in the transaction above
export SOL_POOL_ADDRESS="gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM"
Step 4: Derive Pool Signer PDA
The Pool Signer PDA is the critical address that will serve as the autonomous signing authority for cross-chain mint and burn operations.
# Derive all pool-related accounts including the Pool Signer PDA
pnpm bs58 utils \
--env devnet \
--instruction derive-accounts \
--program-type burnmint-token-pool \
--program-id "$CCIP_POOL_PROGRAM" \
--mint "$SOL_TOKEN_MINT"
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts utils --env devnet --instruction derive-accounts --program-type burnmint-token-pool --program-id 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
INFO [2025-08-13 00:55:54.229 +0200]: Starting deriveAccounts command
command: "derive-accounts"
programType: "burnmint-token-pool"
programId: "3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo"
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
globalOptions: {
"environment": "devnet",
"resolvedRpcUrl": "https://api.devnet.solana.com"
}
โ
RPC connection verified
๐ Deriving burnmint-token-pool accounts...
๐ Derived Accounts:
1. Pool State PDA
Address: gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM
Seeds: ["ccip_tokenpool_config", mint]
Bump: 253
Description: Main pool configuration account (created by initialize-pool)
2. Pool Signer PDA
Address: ERs5qJvN1hu4rGrtuj6WMhZznVWbCyf2g4ynMgFHCWKN
Seeds: ["ccip_tokenpool_signer", mint]
Bump: 254
Description: Autonomous mint/burn authority for cross-chain operations
3. Global Config PDA
Address: 3sM46YunqEj7xWQaV3fzogeuAnqDZkW1suiVfGqpTRHz
Seeds: ["config"]
Bump: 254
Description: Program-wide configuration settings
4. Pool Token ATA
Address: 9pVYxjcnV2gTTFrwnrh2Lb1zUwTefEjxSbpia1B6NUtn
Seeds: [mint, pool_signer_pda, token_program]
Description: Pool's token account (owned by Pool Signer PDA)
CRITICAL ADDRESS FOR CROSS-CHAIN OPERATIONS:
Pool Signer PDA: ERs5qJvN1hu4rGrtuj6WMhZznVWbCyf2g4ynMgFHCWKN
โณ This address signs all mint/burn transactions autonomously
INFO [2025-08-13 00:55:56.236 +0200]: Detected SPL Token v1
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
INFO [2025-08-13 00:55:56.238 +0200]: โ
Account derivation completed successfully
command: "derive-accounts"
Set the Pool Signer PDA address for use in subsequent steps:
# Set the Pool Signer PDA from the derivation output above
export SOL_POOL_SIGNER_PDA="<YOUR_ACTUAL_POOL_SIGNER_PDA>"
Verify both addresses are set correctly:
echo "Pool Address: $SOL_POOL_ADDRESS"
echo "Pool Signer PDA: $SOL_POOL_SIGNER_PDA"
Pool Address: gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM
Pool Signer PDA: ERs5qJvN1hu4rGrtuj6WMhZznVWbCyf2g4ynMgFHCWKN
Step 5: Register CCIP Administrator
This two-step process establishes your Squad vault as the CCIP token administrator, enabling you to enable your token in CCIP. Since your Squad vault currently holds the mint authority, you can complete this registration using the self-service registration flow without external assistance.
Why This Works: The Router's owner_propose_administrator instruction verifies onchain that the caller matches the token's mint_authority
field. Your Squad vault has this authority, enabling PATH A self-service registration.
Sub-step 5a: Propose Administrator
The owner_propose_administrator instruction creates a TokenAdminRegistry PDA for your token and sets your Squad vault as the pending administrator:
# Generate administrator registration transaction
pnpm bs58 router --env devnet --instruction owner-propose-administrator \
--program-id $CCIP_ROUTER_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--token-admin-registry-admin $SOL_SQUAD_VAULT_MULTISIG
$ pnpm bs58 router --env devnet --instruction owner-propose-administrator \
--program-id $CCIP_ROUTER_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--token-admin-registry-admin $SOL_SQUAD_VAULT_MULTISIG
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts router --env devnet --instruction owner-propose-administrator --program-id Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --token-admin-registry-admin 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
โ
RPC connection verified
๐ Generating owner_propose_administrator transaction...
๐ Building and simulating transaction...
โ
Transaction simulation completed
๐ฏ COPY TRANSACTION DATA BELOW:
jCi2q3RM6PzJZRhgUPyQh5bBo2juVuAMP2tXHnkmWowRbPHQUuvY3qhvv97A976wLhPkR829gHc7B7TdsMvryLs7KR5demyaYqRFRcb7rtoZ6buybtiQRihoxGacBKHMnxZoMXbsN31BHrjFP3TK1efdwgoWzY9h7c8XF6cUR4JahMrzdrRZJqEzS49f793tyPvNqjKpzwoX8MVutBaY5nDxu8tWCmf2NsZyWKuQRwRDB9P9UvjDoM5gtzFxMn2NGMp2QGW8zkqkjPPUPKvRK4uArcMoFyeMrhkwYAX2ofA7BM4MeVJ5RxE681PWpmKFxb139rpsKM3j8oUoPxZgiugdHg9mHSd4tsRFZEK2pzoixLvzbXQgobXzc
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Transaction generated successfully!
๐ Transaction Details:
Instruction: router.owner_propose_administrator
Size: 277 bytes
Base58 length: 377 characters
Compute units: 19,785
Generated: 2025-08-12T17:06:30.169Z
๐ Transaction Data (Base58):
๐ก Triple-click the line above to select the entire transaction data
๐ Account Information:
Total accounts: 5 1. 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 (read-only) 2. E7STtSanxZmYmyH6nBeb27QCpEvue4uq7QZ62uinSRwR (writable) 3. EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND (read-only) 4. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable) 5. 11111111111111111111111111111111 (read-only)
Account Breakdown from the Transaction (Example):
Account | Address | Description |
---|---|---|
#1 | 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 | Router Config PDA (read-only) |
#2 | E7STtSanxZmYmyH6nBeb27QCpEvue4uq7QZ62uinSRwR | ๐ฏ Token Admin Registry PDA - Gets created/updated for your token |
#3 | EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND | Token Mint (your token) |
#4 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Authority/Payer (your Squad vault) |
#5 | 11111111111111111111111111111111 | System Program |
What This Transaction Does: This transaction proposes your Squad vault as the administrator for your token in the Router's Token Admin Registry. Account #2 is the Token Admin Registry PDA that stores who has administrative control over your token's cross-chain operations.
Sub-step 5b: Accept Administrator Role
The accept_admin_role instruction completes the registration process by having the pending administrator (your Squad vault) explicitly accept the CCIP token administrator role:
# Generate administrator role acceptance transaction
pnpm bs58 router --env devnet --instruction accept-admin-role \
--program-id $CCIP_ROUTER_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG
$ pnpm bs58 router --env devnet --instruction accept-admin-role \
--program-id $CCIP_ROUTER_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts router --env devnet --instruction accept-admin-role --program-id Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
โ
RPC connection verified
๐ Generating accept_admin_role_token_admin_registry transaction...
๐ Building and simulating transaction...
โ
Transaction simulation completed
๐ฏ COPY TRANSACTION DATA BELOW:
2sM9hLJFuca8kadhK5vj9XrhMwgVdMHbbADrgprG7i6MGad9hyK9vQ7ZhV1JAvdBZJ6xwHmjaUJmjw6Kf8VyJXf51ppFmmBeAqEwKqPgbzgRDXfxn1oYB3q8LZXTfjATPZiX59ahdd9V4yW36Gj2mZnA6FQyBAtdmPpiYfva3vVqbERBhCcyVrUqbHRurVH6RpL8ENExot4UexBmtCikaM2tkyvNrnsTWUPcGVx4QMRxFjqzHxKhBWpPGA4g7yRgvUxgp2XbVb3Rf6AY6DynkMk22sDJ8HM3b
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Transaction generated successfully!
๐ Transaction Details:
Instruction: router.accept_admin_role_token_admin_registry
Size: 212 bytes
Base58 length: 289 characters
Compute units: 15,454
Generated: 2025-08-12T17:11:25.448Z
๐ Transaction Data (Base58):
๐ก Triple-click the line above to select the entire transaction data
๐ Account Information:
Total accounts: 4 1. 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 (read-only) 2. E7STtSanxZmYmyH6nBeb27QCpEvue4uq7QZ62uinSRwR (writable) 3. EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND (read-only) 4. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable)
Account Breakdown from the Transaction (Example):
Account | Address | Description |
---|---|---|
#1 | 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 | Router Config PDA (read-only) |
#2 | E7STtSanxZmYmyH6nBeb27QCpEvue4uq7QZ62uinSRwR | ๐ฏ Token Admin Registry PDA - Updates status to "active" |
#3 | EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND | Token Mint (your token) |
#4 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Authority (your Squad vault - must be pending admin) |
What This Transaction Does: This is the acceptance step of the two-phase administrator registration. It updates the Token Admin Registry PDA (Account #2) from "pending administrator" to "active administrator" status. Your Squad vault explicitly accepts the administrator role, completing the secure registration process.
Key Difference: Only 4 accounts (vs. 5 in the propose step) because we're updating an existing registry entry, not creating a new one.
After both transactions are executed, your Squad vault will be the CCIP token administrator. See Registration & Administration for more details.
Step 6: Create SPL Token Multisig (Layer 2 Mint Authority)
This command creates the second layer of your dual-multisig architecture by establishing an SPL token multisig that will control mint authority. The create-multisig
instruction creates a deterministic multisig account that includes both your Pool Signer PDA and Squad vault as authorized signers.
What This Accomplishes:
- SPL Token Multisig Creation: Establishes a new multisig account
- Dual Authority Setup: Includes both Pool Signer PDA (for autonomous CCIP operations) and Squad vault (for governance control)
- Threshold Configuration: Sets threshold to 1, allowing either signer to authorize mint operations
- Layer 2 Foundation: Creates the mint authority that will be transferred from your Squad vault in the next step
Token Program Detection: The CLI automatically detects whether your mint uses SPL Token v1 or Token-2022 and creates the appropriate multisig type.
# Generate SPL token multisig creation transaction
pnpm bs58 spl-token --env devnet --instruction create-multisig \
--authority "$SOL_SQUAD_VAULT_MULTISIG" \
--seed "production-multisig" \
--mint "$SOL_TOKEN_MINT" \
--signers "[\"$SOL_POOL_SIGNER_PDA\", \"$SOL_SQUAD_VAULT_MULTISIG\"]" \
--threshold 1
$ pnpm bs58 spl-token --env devnet --instruction create-multisig \
--authority "$SOL_SQUAD_VAULT_MULTISIG" \
--seed "production-multisig" \
--mint "$SOL_TOKEN_MINT" \
--signers "[\"$SOL_POOL_SIGNER_PDA\", \"$SOL_SQUAD_VAULT_MULTISIG\"]" \
--threshold 1
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts spl-token --env devnet --instruction create-multisig --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --seed production-multisig --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --signers '["ERs5qJvN1hu4rGrtuj6WMhZznVWbCyf2g4ynMgFHCWKN", "59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY"]' --threshold 1
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
INFO: Detected SPL Token v1
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
๐ Building and simulating transaction...
๐ฎ Derived SPL Token Multisig Address: pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk
๐ฏ COPY TRANSACTION DATA BELOW:
2NQikQ6fRxByKoYKAMVg9MMS5WZaaXnF6jKyNJyukHq7CXhwtigcb2ED1LYLto4oBEwwWRyivh9tPa95mBoZx6zpLJY7qYDJbw793SxUhDXYUbfQsUz61G4aQp9gAqBVNrzu5zbSDyn1DtGVeDNQr2doPhcq2LYmrA7JcSTUkwRy4TwrK6rH2HS41k1eSjEN1iqja3Pt39VU3n1Z8H2QKyKJyAW5wrRcx65Agk4UJxA8JH28MUJSbYcRkay9amPkyW5279pVEeXX8KdNgg1Y21heS6zeduJ7jUyvVvBwTUw73Cjdmw7xToKBfnrAwB6Dfzqj6TWLFtYY7r8bG3YdHC3qbe3to3TKFuE4ihMr191vjR5RawwKToKkfzexyaXeWjKRfT1ZtJZenUzWY9LForPC69hmtN26vwb5tZej5gjUzVmt6bxNVpYgC1w15bBB52Gk4dQ3TkN11s5LuPBF1vVEgtuWX8Kpvb2
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Transaction generated successfully!
๐ Transaction Details:
Instruction: spl.create_multisig
Size: 354 bytes
Base58 length: 483 characters
Compute units: 2,931
Generated: 2025-08-12T17:22:37.514Z
๐ Transaction Data (Base58):
๐ก Triple-click the line above to select the entire transaction data
๐ Account Information:
Total accounts: 2 1. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable) 2. pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk (writable)
Account Breakdown from the Transaction (Example):
Account | Address | Description |
---|---|---|
#1 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Payer/Authority (your Squad vault) |
#2 | pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk | ๐ฏ SPL Token Multisig (newly created) |
What This Transaction Does: This creates an SPL Token Multisig account that will control your token's mint authority. The CLI automatically detected SPL Token v1 and created the appropriate multisig type.
Key Details:
- Generated Multisig Address:
pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk
- Multisig Signers: Pool Signer PDA + Squad vault
- Threshold: 1 (either signer can authorize mint operations)
- Hybrid Control: Enables both automated CCIP operations and human governance
Execute this transaction through Squads and set the variable for the next step:
export SOL_SPL_MULTISIG="<INSERT_ACTUAL_SPL_MULTISIG_ADDRESS>"
Verify the variable:
echo "โ
SPL Multisig: $SOL_SPL_MULTISIG"
โ
SPL Multisig: pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk
Step 7: Transfer Mint Authority (Layer 2 Mint Authority)
Transfer mint authority from your Squad vault to the SPL Token Multisig, completing the dual-layer governance architecture. This enables both automated CCIP operations and human governance control.
What This Command Does:
- Authority Transfer: Moves mint control from Squad vault to SPL Token Multisig
- SPL Token Operation: Uses the native
SetAuthority
instruction for mint authority - Governance Architecture: Establishes the final production-ready control structure
- Dual Control Setup: Enables both Pool Signer PDA (autonomous) and Squad vault (governance) control
- Irreversible Change: Once executed, only the SPL Token Multisig can mint tokens
# Generate mint authority transfer transaction
pnpm bs58 spl-token --env devnet --instruction transfer-mint-authority \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--new-mint-authority $SOL_SPL_MULTISIG
$ pnpm bs58 spl-token --env devnet --instruction transfer-mint-authority \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--new-mint-authority $SOL_SPL_MULTISIG
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts spl-token --env devnet --instruction transfer-mint-authority --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --new-mint-authority pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
INFO: Detected SPL Token v1
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
๐ Building and simulating transaction...
๐ฏ COPY TRANSACTION DATA BELOW:
ebWdNECFDo2Uj45BAmovEt5J6YEvDjvLxqcRfWy6uDBmd3XVmBPspZjf3g6uWzwEcia4niHx6pLdH5PHMW4X8icbufe6DvzWrYxpvgcDz6yQrnZSE4W7usCnvcW2Q7dPcoyctmBpVK7qvSWb5AExokEKgrqzmPyNskA8qkTZScsEKyaRJoJc6HeNvuWJc3NxXCd9M3HrCTYi4L74pkGQpAeShMWsFiedc6sQ2Vmiyg8
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Transaction generated successfully!
๐ Transaction Details:
Instruction: spl.transfer_mint_authority
Size: 173 bytes
Base58 length: 235 characters
Compute units: 3,006
Generated: 2025-08-12T17:32:28.063Z
๐ Transaction Data (Base58):
๐ก Triple-click the line above to select the entire transaction data
๐ Account Information:
Total accounts: 2
1. EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND (writable)
2. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer)
Account Breakdown from the Transaction (Example):
Account | Address | Description |
---|---|---|
#1 | EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND | Token Mint (writable - authority updated) |
#2 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Current Authority (signer - Squad vault) |
Key Details:
- Current Authority:
59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
(Squad vault) - New Authority:
pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk
(SPL Token Multisig) - Token Mint:
EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
(authority field updated)
Step 8: Test Token Minting (Verify Dual-Layer Control)
Verify that your Squad vault can still mint tokens after the authority transfer. This proves the dual-layer governance is working correctly: Squad vault โ SPL Token Multisig โ Token minting.
Purpose of This Test:
- Verify Authority Transfer: Confirm the SPL Token Multisig now controls mint authority
- Prove Squad Control: Demonstrate that Squad vault can still mint through the multisig
- Validate Architecture: Test the dual-layer governance model works as designed
# Generate token minting transaction using SPL multisig
pnpm bs58 spl-token --env devnet --instruction mint \
--authority "$SOL_SQUAD_VAULT_MULTISIG" \
--mint "$SOL_TOKEN_MINT" \
--amount 1000000000 \
--recipient "$SOL_WALLET_ADDRESS" \
--multisig "$SOL_SPL_MULTISIG" \
--multisig-signers "[\"$SOL_SQUAD_VAULT_MULTISIG\"]"
$ pnpm bs58 spl-token --env devnet --instruction mint \
--authority "$SOL_SQUAD_VAULT_MULTISIG" \
--mint "$SOL_TOKEN_MINT" \
--amount 1000000000 \
--recipient "$SOL_WALLET_ADDRESS" \
--multisig "$SOL_SPL_MULTISIG" \
--multisig-signers "[\"$SOL_SQUAD_VAULT_MULTISIG\"]"
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts spl-token --env devnet --instruction mint --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --amount 1000000000 --recipient EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB --multisig pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk --multisig-signers '["59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY"]'
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
INFO: Detected SPL Token v1
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
๐ Building and simulating transaction...
๐ฏ COPY TRANSACTION DATA BELOW:
9FDWqLKmG2btBeVbENTJckgTiiKUamXHwp2Dpy79xXu7jHWshJCsSM8EkyYNgsZgPdvAqtjdjJjPDcfPqKdoHneCEaKvg35kHHgsqfdSnN7y4WqdHtt1KTFBcS9nWJiw9CPtVLuMyQJg9U4W2M4Af82mYt42SSZroRn4cRcqqLNcYsqHnZkrb8VN6miAVehvm7nJeo7YwWBrN53Pv6xN2xaLwLFLneMkLGQPDNfMaAAXXxZs3Fh3CQMXrkDmPfxzpwohNySBTmHdKSU8umSxchTWndTvViCN5V
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Transaction generated successfully!
๐ Transaction Details:
Instruction: spl.mint
Size: 213 bytes
Base58 length: 290 characters
Compute units: 5,365
Generated: 2025-08-12T18:16:11.500Z
๐ Transaction Data (Base58):
๐ก Triple-click the line above to select the entire transaction data
๐ Account Information:
Total accounts: 4
1. EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND (writable)
2. 5xwF4TX8qzvNyWzQNWYAG8f2RDJrGbuWeEA9R1asYgmg (writable)
3. pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk (read-only)
4. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer)
Account Breakdown from the Transaction (Example):
Account | Address | Description |
---|---|---|
#1 | EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND | Token Mint (writable - supply updated) |
#2 | 5xwF4TX8qzvNyWzQNWYAG8f2RDJrGbuWeEA9R1asYgmg | Recipient's ATA (writable - receives tokens) |
#3 | pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk | SPL Token Multisig (read-only - mint authority) |
#4 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Squad Vault (signer - multisig member) |
What This Transaction Does: This is an SPL Token Multisig Mint operation that proves your dual-layer governance is working correctly. The Squad vault acts as a signer for the SPL Token Multisig that now controls mint authority.
Key Details:
- Amount: 1,000,000,000 smallest units = 1 token (with 9 decimals)
- Recipient: Your wallet address (
EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
) - Mint Authority: SPL Token Multisig (
pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk
) - Multisig Signer: Squad vault (
59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
) - Token Program: SPL Token v1 (
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
)
Transaction Flow:
- Authority Verification: SPL Token program verifies the multisig has mint authority
- Signature Validation: Program confirms Squad vault is an authorized multisig signer
- Token Creation: 1 token is minted and added to total supply
- Token Transfer: New tokens are deposited into your wallet's ATA
Phase 2 Complete: Save your variables:
# Save all Solana variables
cat > ~/.phase2_vars << EOF
export CCIP_POOL_PROGRAM="$CCIP_POOL_PROGRAM"
export CCIP_ROUTER_PROGRAM="$CCIP_ROUTER_PROGRAM"
export CCIP_FEE_QUOTER_PROGRAM="$CCIP_FEE_QUOTER_PROGRAM"
export SOL_SQUAD_VAULT_MULTISIG="$SOL_SQUAD_VAULT_MULTISIG"
export SOL_TOKEN_MINT="$SOL_TOKEN_MINT"
export SOL_POOL_ADDRESS="$SOL_POOL_ADDRESS"
export SOL_POOL_SIGNER_PDA="$SOL_POOL_SIGNER_PDA"
export SOL_SPL_MULTISIG="$SOL_SPL_MULTISIG"
export SOL_WALLET_ADDRESS="$SOL_WALLET_ADDRESS"
EOF
echo "=== Phase 2 Complete - Dual Multisig Setup ==="
echo "โ
Token Mint: $SOL_TOKEN_MINT"
echo "โ
Pool Address: $SOL_POOL_ADDRESS"
echo "โ
Pool Signer PDA: $SOL_POOL_SIGNER_PDA"
echo "โ
Squads Multisig: $SOL_SQUAD_VAULT_MULTISIG"
echo "โ
SPL Multisig: $SOL_SPL_MULTISIG"
echo "โ
Wallet Address: $SOL_WALLET_ADDRESS"
=== Phase 2 Complete - Dual Multisig Setup ===
โ
Token Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
โ
Pool Address: BmLXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgDyX
โ
Pool Signer PDA: 9KXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgBfV
โ
Squads Multisig: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU
โ
SPL Multisig: AjKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgCxW
โ
Wallet Address: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
Phase 3: Cross-Chain Configuration
In this phase, you will configure the cross-chain connection and complete the CCIP setup.
Step 1: Load Phase 1 Variables
Load Phase 1 variables and set the Ethereum Sepolia chain selector for cross-chain configuration.
What This Step Does:
- Terminal Verification: Confirms you're in the correct base58 generator repository
- Variable Loading: Imports EVM token and pool addresses from Phase 1
- Chain Selector Setup: Establishes Ethereum Sepolia chain selector for cross-chain configuration
# Verify you are in the correct terminal (terminal 1)
# Should output: /Users/.../ccip-solana-bs58-generator
pwd
# Load Phase 1 EVM variables
source ~/.phase1_vars
# Set chain selector for Ethereum Sepolia
export ETHEREUM_SEPOLIA_CHAIN_SELECTOR="16015286601757825753"
# Verify variables are loaded
echo "โ
ETH Token: $ETH_TOKEN_ADDRESS"
echo "โ
ETH Pool: $ETH_POOL_ADDRESS"
echo "โ
Chain Selector: $ETHEREUM_SEPOLIA_CHAIN_SELECTOR"
$ pwd
/Users/.../ccip-solana-bs58-generator
$ source ~/.phase1_vars
$ export ETHEREUM_SEPOLIA_CHAIN_SELECTOR="16015286601757825753"
$ echo "โ
ETH Token: $ETH_TOKEN_ADDRESS"
โ
ETH Token: 0x9cE471d0a7bE21ee32276ddE49104fE02C812906
$ echo "โ
ETH Pool: $ETH_POOL_ADDRESS"
โ
ETH Pool: 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342
$ echo "โ
Chain Selector: $ETHEREUM_SEPOLIA_CHAIN_SELECTOR"
โ
Chain Selector: 16015286601757825753
Step 2: Configure Cross-Chain Pool Settings
Configure your token pool for cross-chain transfers to Ethereum Sepolia. This process involves two sequential operations:
- Initialize Chain Remote Config: Create the basic cross-chain configuration using init_chain_remote_config
- Edit Chain Remote Config: Add the remote pool address using edit_chain_remote_config
Step 2A: Initialize Chain Remote Config
Initialize the basic remote chain configuration for Ethereum Sepolia. Pool addresses must be empty at initialization and rate limits are not configured at this stage.
# Initialize basic cross-chain configuration (no rate limits, no pool addresses)
pnpm bs58 burnmint-token-pool --env devnet --instruction init-chain-remote-config \
--program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR \
--token-address $ETH_TOKEN_ADDRESS \
--decimals "18"
$ pnpm bs58 burnmint-token-pool --env devnet --instruction init-chain-remote-config \
--program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR \
--token-address $ETH_TOKEN_ADDRESS \
--decimals "18"
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts burnmint-token-pool --env devnet --instruction init-chain-remote-config --program-id 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --remote-chain-selector 16015286601757825753 --token-address 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 --decimals 18
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
INFO: Starting initChainRemoteConfig command
command: "init-chain-remote-config"
programId: "3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo"
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
authority: "59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY"
remoteChainSelector: "16015286601757825753"
tokenAddress: "0x9cE471d0a7bE21ee32276ddE49104fE02C812906"
decimals: "18"
globalOptions: {
"environment": "devnet",
"resolvedRpcUrl": "https://api.devnet.solana.com"
}
โ
RPC connection verified
๐ Generating initChainRemoteConfig transaction...
RPC URL: https://api.devnet.solana.com
Program ID: 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo
Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
Authority: 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
Remote Chain Selector: 16015286601757825753
Pool Addresses: 0 addresses
Token Address: 9cE471d0a7bE21ee32276ddE49104fE02C812906
Decimals: 18
โ๏ธ Building transaction instruction...
โ
Instruction built successfully
๐ Building and simulating transaction...
๐ฏ COPY TRANSACTION DATA BELOW:
K7mR9Xt2Vg8qpWnDFH3jMzE1yCdS5NbA4oZfLhUi6JmtPv9wXk2Bg7FqRtHsZcAa8Ln3VmYp4KgDr1EoTxWu5JbH2Nt9Lp6Xm7Zd3Cs4Vf8Yh1Rk5Qj9Et2Wm6Kp7Nh3Df4Bg8Ys1Xr5Cv2Mn9Lt6Zp3Fg7Jh4Vt8Ws1Nk6Qm2Rg9Yh5Vp7Dn4Kt1Xm8Fg2Cs6Zl3Wh7Nt5Vp9Km2Rg4Ys8Xl1Dn6Jp3Vt7Wh9Ns5Km2Bg4Yl8Xr1Dn3Jp6Vt9Wh2Ns8Km5Rg7Yl1Xr4Dn6Jp9Vt2Wh5Ns8Km1Bg4Yl7Xr3Dn9Jp2Vt5Wh8Ns1Km6Rg7Yl4Xr9Dn2Jp5Vt8Wh1Ns4Km7Bg3Yl9Xr2Dn5Jp8Vt1Wh4Ns7Km9Rg2Yl5Xr8Dn1Jp4Vt7Wh9Ns2Km5Bg6Yl1Xr4Dn7Jp9Vt2Wh5Ns8Km1Rg4Yl7Xr9Dn2Jp5Vt8Wh1Ns4Km6Bg7Yl9Xr2Dn5Jp8Vt1Wh4Ns7Km9Rg
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Transaction generated successfully!
๐ Transaction Details:
Instruction: initChainRemoteConfig
Size: 229 bytes
Base58 length: 312 characters
Compute units: 15,247
Generated: 2025-08-12T18:42:17.141Z
๐ Transaction Data (Base58):
๐ก Triple-click the line above to select the entire transaction data
๐ Account Information:
Total accounts: 4
1. gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM (read-only)
2. 9sc57SrLmm3hUCSShj6t1BsYDmmnM4USCshKYRt5DSFd (writable)
3. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable)
4. 11111111111111111111111111111111 (read-only)
Account Breakdown from the Transaction (Example):
Account | Address | Description |
---|---|---|
#1 | gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM | Pool State PDA (read-only - validation) |
#2 | 9sc57SrLmm3hUCSShj6t1BsYDmmnM4USCshKYRt5DSFd | Chain Remote Config PDA (writable - created) |
#3 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Squad Vault (signer, writable - pool authority) |
#4 | 11111111111111111111111111111111 | System Program (read-only - account creation) |
What This Command Does: This initializes the cross-chain configuration for your Solana token to enable CCIP bridging to Ethereum Sepolia. This creates the foundational connection without rate limits or pool addresses.
Key Details:
- Remote Chain: Ethereum Sepolia (chain selector:
16015286601757825753
) - Token Mapping: Links to ERC20 token
0x9cE471d0a7bE21ee32276ddE49104fE02C812906
- Decimal Precision: 18 decimals (standard EVM token format)
- Basic Setup: No rate limits or pool addresses configured at this stage
- Account Creation: Creates a new Chain Remote Config PDA for this cross-chain relationship
Transaction Flow:
- Authority Verification: Confirms Squad vault owns the pool state
- PDA Derivation: Calculates Chain Remote Config PDA using pool state + chain selector
- Account Creation: Creates new account with rent-exempt balance
- Basic Configuration: Stores minimal cross-chain parameters (no rate limits, no pool addresses)
Step 2B: Edit Chain Remote Config (Add Remote Pool Address)
After initializing the chain remote config, add the remote pool address to enable bidirectional cross-chain transfers. This uses edit_chain_remote_config
to specify the Ethereum pool address.
# Configure chain connection and remote pool address
pnpm bs58 burnmint-token-pool --env devnet --instruction edit-chain-remote-config \
--program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR \
--pool-addresses "[\"$ETH_POOL_ADDRESS\"]" \
--token-address $ETH_TOKEN_ADDRESS \
--decimals "18"
$ pnpm bs58 burnmint-token-pool --env devnet --instruction edit-chain-remote-config \
--program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR \
--pool-addresses "[\"0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342\"]" \
--token-address $ETH_TOKEN_ADDRESS \
--decimals "18"
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts burnmint-token-pool --env devnet --instruction edit-chain-remote-config --program-id 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --remote-chain-selector 16015286601757825753 --pool-addresses "[\"0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342\"]" --token-address 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 --decimals 18
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
INFO: Starting editChainRemoteConfig command
command: "edit-chain-remote-config"
programId: "3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo"
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
authority: "59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY"
remoteChainSelector: "16015286601757825753"
poolAddresses: ["0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342"]
tokenAddress: "0x9cE471d0a7bE21ee32276ddE49104fE02C812906"
decimals: "18"
โ
RPC connection verified
๐ Generating editChainRemoteConfig transaction...
RPC URL: https://api.devnet.solana.com
Program ID: 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo
Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
Authority: 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
Remote Chain Selector: 16015286601757825753
Pool Addresses: 1 address
Token Address: 9cE471d0a7bE21ee32276ddE49104fE02C812906
Decimals: 18
โ๏ธ Building transaction instruction...
โ
Instruction built successfully
๐ Building and simulating transaction...
๐ฏ COPY TRANSACTION DATA BELOW:
Ym3kR9wF2nH5vT8qL1cX6pB4mZ7sA3dE9jN5uY2wK8xP7hM1gF4tR6sB9vC3qL5eN8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Transaction generated successfully!
๐ Transaction Details:
Instruction: editChainRemoteConfig
Size: 356 bytes
Base58 length: 485 characters
Compute units: 19,742
Generated: 2025-08-12T19:15:23.487Z
๐ Transaction Data (Base58):
๐ก Triple-click the line above to select the entire transaction data
๐ Account Information:
Total accounts: 4
1. gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM (read-only)
2. 9sc57SrLmm3hUCSShj6t1BsYDmmnM4USCshKYRt5DSFd (writable)
3. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable)
4. 11111111111111111111111111111111 (read-only)
$ pnpm bs58 burnmint-token-pool --env devnet --instruction edit-chain-remote-config \
--program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR \
--pool-addresses "[\"0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342\"]" \
--token-address $ETH_TOKEN_ADDRESS \
--decimals "18"
> ccip-solana-bs58-generator@1.0.0 bs58 /Users/.../ccip-solana-bs58-generator
> tsx src/index.ts burnmint-token-pool --env devnet --instruction edit-chain-remote-config --program-id 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --remote-chain-selector 16015286601757825753 --pool-addresses "[\"0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342\"]" --token-address 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 --decimals 18
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
INFO: Starting editChainRemoteConfig command
command: "edit-chain-remote-config"
programId: "3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo"
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
authority: "59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY"
remoteChainSelector: "16015286601757825753"
poolAddresses: ["0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342"]
tokenAddress: "0x9cE471d0a7bE21ee32276ddE49104fE02C812906"
decimals: "18"
โ
RPC connection verified
๐ Generating editChainRemoteConfig transaction...
RPC URL: https://api.devnet.solana.com
Program ID: 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo
Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
Authority: 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
Remote Chain Selector: 16015286601757825753
Pool Addresses: 1 address
Token Address: 9cE471d0a7bE21ee32276ddE49104fE02C812906
Decimals: 18
โ๏ธ Building transaction instruction...
โ
Instruction built successfully
๐ Building and simulating transaction...
๐ฏ COPY TRANSACTION DATA BELOW:
Ym3kR9wF2nH5vT8qL1cX6pB4mZ7sA3dE9jN5uY2wK8xP7hM1gF4tR6sB9vC3qL5eN8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL8jY2wM7kR4xP1hF6gT9sB3cE5nL
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Transaction generated successfully!
๐ Transaction Details:
Instruction: editChainRemoteConfig
Size: 292 bytes
Base58 length: 398 characters
Compute units: 17,834
Generated: 2025-08-12T19:15:23.487Z
๐ Transaction Data (Base58):
๐ก Triple-click the line above to select the entire transaction data
๐ Account Information:
Total accounts: 4
1. gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM (read-only)
2. 9sc57SrLmm3hUCSShj6t1BsYDmmnM4USCshKYRt5DSFd (writable)
3. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable)
4. 11111111111111111111111111111111 (read-only)
Account Breakdown from the Transaction:
Account | Address | Description |
---|---|---|
#1 | gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM | Pool State PDA (read-only - authority validation) |
#2 | 9sc57SrLmm3hUCSShj6t1BsYDmmnM4USCshKYRt5DSFd | Chain Remote Config PDA (writable - configuration updated) |
#3 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Squad Vault Authority (signer, writable - fee payer) |
#4 | 11111111111111111111111111111111 | System Program (read-only - account operations) |
Transaction Flow:
- Authority Verification: Confirms Squad vault owns the pool state
- PDA Access: Updates the existing Chain Remote Config PDA
- Pool Address Addition: Adds the remote pool to the the remote pool list for Ethereum Sepolia
Step 3: Configure Rate Limits (Optional)
This command configures inbound and outbound rate limiting for token transfers between your Solana token and Ethereum Sepolia. Rate limits act as "token buckets" that control the flow of tokens across chains.
# Configure rate limits for cross-chain token transfers
pnpm bs58 burnmint-token-pool \
--env devnet \
--instruction set-chain-rate-limit \
--program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR \
--inbound-enabled "true" \
--inbound-capacity "20000000000" \
--inbound-rate "100000000" \
--outbound-enabled "true" \
--outbound-capacity "18000000000" \
--outbound-rate "100000000"
$ pnpm bs58 burnmint-token-pool \
--env devnet \
--instruction set-chain-rate-limit \
--program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR \
--inbound-enabled "true" \
--inbound-capacity "20000000000" \
--inbound-rate "100000000" \
--outbound-enabled "true" \
--outbound-capacity "18000000000" \
--outbound-rate "100000000"
> ccip-solana-bs58-generator@1.0.0 bs58 /.../ccip-solana-bs58-generator
> tsx src/index.ts burnmint-token-pool --env devnet --instruction set-chain-rate-limit --program-id 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --remote-chain-selector 16015286601757825753 --inbound-enabled true --inbound-capacity 20000000000 --inbound-rate 100000000 --outbound-enabled true --outbound-capacity 18000000000 --outbound-rate 100000000
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
INFO [2025-08-13 01:30:02.426 +0200]: Starting setChainRateLimit command
command: "set-chain-rate-limit"
programId: "3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo"
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
authority: "59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY"
remoteChainSelector: "16015286601757825753"
inboundEnabled: "true"
inboundCapacity: "20000000000"
inboundRate: "100000000"
outboundEnabled: "true"
outboundCapacity: "18000000000"
outboundRate: "100000000"
globalOptions: {
"environment": "devnet",
"resolvedRpcUrl": "https://api.devnet.solana.com"
}
โ
RPC connection verified
๐ Generating setChainRateLimit transaction...
RPC URL: https://api.devnet.solana.com
Program ID: 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo
Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
Authority: 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY
Remote Chain Selector: 16015286601757825753
Inbound Rate Limit: enabled (capacity: 20000000000, rate: 100000000)
Outbound Rate Limit: enabled (capacity: 18000000000, rate: 100000000)
โ๏ธ Building transaction instruction...
โ
Instruction built successfully
๐ Building and simulating transaction...
โ
Transaction simulation completed
๐ฏ COPY TRANSACTION DATA BELOW:
2osuKVgAa7jk8Ahvr7KPjeNDY7RAx29vFbgbkrKwtnGKbSjEBRi8e7gVMdRtj6rsWc57eVr3guqdjDifN4joBVRRnVNcH8i6FeQuRtshDvLahoYrUYnwU6wgp3FiANUN5czyX7rhNHdM4wMXSTG8L3Dvf8k6RJRq1kXrrU9oX7eDewiKv8q9VBJi86UZtYS4u3X3x99mCWkpca3x27RN54LU7UvFgLv2vBWTfTj1YP5RbFnipvPkCuxzWYXTpj2shy9wwVY87g8Fx9uJc4f2FTz4bvw5cRKstMYQpb1BzsEQMYyVss8ybW2rnJPeh4LovFPDhEVwcc8xjCYGap9sfnYsh
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
INFO [2025-08-13 01:30:04.536 +0200]: Transaction built successfully
instructionName: "setChainRateLimit"
transactionSize: "253 bytes"
base58Length: "345 characters"
hexLength: "506 characters"
accountCount: 3
signerCount: 1
computeUnits: 15592
INFO [2025-08-13 01:30:04.537 +0200]: Completed buildTransaction (setChainRateLimit)
durationMs: 987
INFO [2025-08-13 01:30:04.537 +0200]:
INFO [2025-08-13 01:30:04.537 +0200]: ๐ Transaction generated successfully!
INFO [2025-08-13 01:30:04.537 +0200]:
INFO [2025-08-13 01:30:04.537 +0200]: ๐ Transaction Details:
INFO [2025-08-13 01:30:04.537 +0200]: Instruction: setChainRateLimit
INFO [2025-08-13 01:30:04.537 +0200]: Size: 253 bytes
INFO [2025-08-13 01:30:04.537 +0200]: Base58 length: 345 characters
INFO [2025-08-13 01:30:04.562 +0200]: Compute units: 15 592
INFO [2025-08-13 01:30:04.562 +0200]: Generated: 2025-08-12T23:30:04.535Z
INFO [2025-08-13 01:30:04.562 +0200]:
INFO [2025-08-13 01:30:04.562 +0200]: ๐ Transaction Data (Base58):
INFO [2025-08-13 01:30:04.562 +0200]:
INFO [2025-08-13 01:30:04.562 +0200]: ๐ก Triple-click the line above to select the entire transaction data
INFO [2025-08-13 01:30:04.562 +0200]:
INFO [2025-08-13 01:30:04.562 +0200]: ๐ Account Information:
INFO [2025-08-13 01:30:04.562 +0200]: Total accounts: 3
INFO [2025-08-13 01:30:04.562 +0200]: 1. gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM (read-only)
INFO [2025-08-13 01:30:04.562 +0200]: 2. 9sc57SrLmm3hUCSShj6t1BsYDmmnM4USCshKYRt5DSFd (writable)
INFO [2025-08-13 01:30:04.562 +0200]: 3. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable)
INFO [2025-08-13 01:30:04.562 +0200]:
Transaction Accounts (3 total):
Account | Address | Type | Purpose |
---|---|---|---|
#1 | gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM | Read-only | Pool State PDA - Main pool configuration account |
#2 | 9sc57SrLmm3hUCSShj6t1BsYDmmnM4USCshKYRt5DSFd | Writable | Chain Config PDA - Chain-specific config (stores rate limits) |
#3 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Signer, Writable | Authority - Your Squad vault that can modify rate limits |
Step 4: Create Address Lookup Table
Create an Address Lookup Table (ALT) containing all accounts needed for CCIP router operations.
What This Command Does:
This command creates an Address Lookup Table (ALT) that stores frequently used accounts for CCIP operations. ALTs are a Solana optimization that reduces transaction size and costs by replacing full 32-byte addresses with small 1-byte indices.
# Generate address lookup table creation transaction
pnpm bs58 router --env devnet --instruction create-lookup-table \
--program-id $CCIP_ROUTER_PROGRAM \
--fee-quoter-program-id $CCIP_FEE_QUOTER_PROGRAM \
--pool-program-id $CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--additional-addresses "[\"$SOL_SPL_MULTISIG\"]"
> ccip-solana-bs58-generator@1.0.0 bs58 /.../ccip-solana-bs58-generat
> tsx src/index.ts router --env devnet --instruction create-lookup-table --program-id Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C --fee-quoter-program-id FeeQPGkKDeRV1MgoYfMH6L8o3KeuYjwUZrgn4LRKfjHi --pool-program-id 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --additional-addresses '["pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk"]'
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
โ
RPC connection verified
๐ Generating create_lookup_table transaction...
๐ Building and simulating transaction...
INFO [2025-08-12 21:38:31.405 +0200]: Detected SPL Token v1
mint: "EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
๐ฎ Derived Lookup Table Address: Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6
โ
Transaction simulation completed
๐ฏ COPY TRANSACTION DATA BELOW:
4Tv96e4E7ESPWQLmUo496tqU5fHzEJ11Baqk6FSZ4caP6KGA3ain6J7F2og8uHSdhfr49jvyoCdgHfuhfrnKGhwejpgQ6owNLFPJ6M8Q18HZAxexrekn7CdrNM1bKXZyxJhntkWBe8MSjLdKbyKvS5nDQKibTGnnSdBxP73qbA2hAqWvzJJrwctp45Wfd5bucH2mPCWF6D5KyMfFaKx3Y7S4F5uQVLbp4UKbXbKyf2ePyuPPBtL5WhGUNHdN5hMbYPzSKaPt9piFTPzLZqYfjgVuxTNcQBGanqcTG9hLyWu88DrNsBuEZZ8BG8EYayWbjxQDtQPfxFnLn85oF9nsCeF2WicDiiz6LTNHXraNWm6X5uFXNosaJZYNjtRWDfsLuqEZwpQpFB1T4Xq2x2dDgjqY5zt6cg7qAdZsqrqRxQHo8JX7Htm2tehZCvXb7yo2p9bEs4Yz8jmCjWCZiTDVXpEZb4j2cja7Cvbya9gqhViTn9huMVzqhRjsSo4md4kFN3S3pNTrbaih4nWSkQhtsHC5WHNybWykgom8cnM4CPUywdktxEXPjxACTMQ67Mb22YtfmKqjZUsS2cvptPrE39rEc9egrTtJDb7r
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
INFO [2025-08-12 21:38:32.212 +0200]: Transaction built successfully
instructionName: "router.create_lookup_table"
transactionSize: "557 bytes"
base58Length: "760 characters"
accountCount: 4
signerCount: 2
computeUnits: 19635
๐ Account Information:
Total accounts: 4
1. Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6 (writable)
2. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer)
3. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable)
4. 11111111111111111111111111111111 (read-only)
Address Lookup Table: Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6
Account Breakdown from the Transaction:
Account | Address | Description |
---|---|---|
#1 | Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6 | ALT Account (writable - being created) |
#2 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | ALT Authority (signer - will own the table) |
#3 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Fee Payer (signer, writable - pays creation costs) |
#4 | 11111111111111111111111111111111 | System Program (read-only - handles account creation) |
What This Command Does:
This command creates the ALT infrastructure needed for efficient CCIP operations by storing frequently used account addresses in a lookup table.
Transaction Flow:
- ALT Creation: Creates lookup table account
49FaPvs...
with Squad Vault as authority - Core Address Addition: Adds essential CCIP accounts (programs, PDAs) to the table
- SPL Multisig Addition: Adds your SPL multisig
$SOL_SPL_MULTISIG
via--additional-addresses
- Index Assignment: Each address gets a unique 1-byte index for future reference
ALT Contents (What Gets Stored): The created lookup table will contain indices for these accounts in this exact order:
Index | Account Address | Purpose |
---|---|---|
0 | Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6 | ALT Address (Self-Reference) |
1 | E7STtSanxZmYmyH6nBeb27QCpEvue4uq7QZ62uinSRwR | Token Admin Registry PDA |
2 | 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo | Pool Program ID |
3 | gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM | Pool State PDA |
4 | Pool Token ATA | Pool Signer's Associated Token Account |
5 | ERs5qJvN1hu4rGrtuj6WMhZznVWbCyf2g4ynMgFHCWKN | Pool Signer PDA |
6 | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | Token Program ID (SPL Token v1) |
7 | EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND | Token Mint |
8 | Fee Token Config PDA | Fee Quoter Token Config PDA |
9 | Router Pool Signer PDA | Router External Token Pools Signer PDA |
10 | pxbFPNVYvh37D976KMron9ed61scbSgExAjjTEkbmMk | SPL Token Multisig โ Your Additional Address! |
Transaction Efficiency Impact:
- Before ALT: Each account = 32 bytes (10 accounts = 320 bytes)
- After ALT: Each account = 1 byte index (10 accounts = 10 bytes)
- Savings: ~310 bytes per future CCIP transaction!
Set Variables:
Copy the ALT address from the transaction output and set the environment variable:
export SOL_ADDRESS_LOOKUP_TABLE="<YOUR_ALT_ADDRESS>"
Verify the variable is set:
echo "โ
Address Lookup Table: $SOL_ADDRESS_LOOKUP_TABLE"
โ
Address Lookup Table: Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6
Step 5: Register Pool with Router
Register your token pool with the CCIP Router using set_pool. This enables the router to route cross-chain transfers through your token pool.
What This Command Does:
- Pool Registration: Connects your token pool to the CCIP Router for cross-chain operations
- Lookup Table Integration: Uses the ALT created in the previous step for efficient account management
- Router Configuration: Enables the router to call your pool's token operations
# Generate pool registration transaction
pnpm bs58 router --env devnet --instruction set-pool \
--program-id $CCIP_ROUTER_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--pool-lookup-table $SOL_ADDRESS_LOOKUP_TABLE \
--writable-indexes "[3,4,7]"
> ccip-solana-bs58-generator@1.0.0 bs58 /.../ccip-solana-bs58-generator
> tsx src/index.ts router --env devnet --instruction set-pool --program-id Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C --mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --authority 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY --pool-lookup-table Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6 --writable-indexes '[3,4,7]'
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
๐ Validating RPC connectivity...
โ
RPC connection verified
๐ Generating set_pool transaction...
๐ Building and simulating transaction...
โ
Transaction simulation completed
๐ฏ COPY TRANSACTION DATA BELOW:
QmCar77mNEqzAzGvMRsXQY9UpezF7qcPt7iURnmpvC88c6KxAjXQ5ABLqcCp6ugnhwNF5WFHCnq5sb2Jd87dB2jg61riGSfhirXKuKFAEhQC4astS2cqm6vsNGSLKY5C7fmbAbYesCMKrhTXL2wjprH1aVUUfLvw1cvkJwHBm9HPvZBSYxxg95KpBEuaMP4hV9bEb3fRUNJdiNcrL5ak3MQPSEDMUTsNB7748nquGQqTMAEi3FiYQQEy2Amo3juQE2K1gS9zGvpsoLZQMTkRpy8HkNxmiAUwcmSorMSPnBFwTiSemchd9EYdqXryCY4BgZLRVbj4FTKTKZYJ3jajrKp
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
INFO [2025-08-12 22:04:20.445 +0200]: Transaction built successfully
instructionName: "router.set_pool"
transactionSize: "252 bytes"
base58Length: "343 characters"
hexLength: "504 characters"
accountCount: 5
signerCount: 1
computeUnits: 37367
INFO [2025-08-12 22:04:20.446 +0200]:
INFO [2025-08-12 22:04:20.446 +0200]: ๐ Transaction generated successfully!
INFO [2025-08-12 22:04:20.446 +0200]:
INFO [2025-08-12 22:04:20.446 +0200]: ๐ Transaction Details:
INFO [2025-08-12 22:04:20.446 +0200]: Instruction: router.set_pool
INFO [2025-08-12 22:04:20.446 +0200]: Size: 252 bytes
INFO [2025-08-12 22:04:20.541 +0200]: Compute units: 37 367
INFO [2025-08-12 22:04:20.541 +0200]: Generated: 2025-08-12T20:04:20.427Z
INFO [2025-08-12 22:04:20.542 +0200]:
INFO [2025-08-12 22:04:20.542 +0200]: ๐ Account Information:
INFO [2025-08-12 22:04:20.542 +0200]: Total accounts: 5
INFO [2025-08-12 22:04:20.543 +0200]: 1. 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 (read-only)
INFO [2025-08-12 22:04:20.543 +0200]: 2. E7STtSanxZmYmyH6nBeb27QCpEvue4uq7QZ62uinSRwR (writable)
INFO [2025-08-12 22:04:20.543 +0200]: 3. EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND (read-only)
INFO [2025-08-12 22:04:20.543 +0200]: 4. Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6 (read-only)
INFO [2025-08-12 22:04:20.543 +0200]: 5. 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY (signer, writable)
Account Breakdown from the Transaction:
Account | Address | Description |
---|---|---|
#1 | 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 | Router Config PDA (read-only - configuration reference) |
#2 | E7STtSanxZmYmyH6nBeb27QCpEvue4uq7QZ62uinSRwR | Token Admin Registry PDA (writable - pool registration) |
#3 | EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND | Token Mint (read-only - token identification) |
#4 | Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6 | Address Lookup Table (read-only - ALT registration) |
#5 | 59eNrRrxrZMdqJxS7J3WGaV4MLLog2er14kePiWVjXtY | Squad Vault Authority (signer, writable - admin & fees) |
What This Command Does:
This command registers your token pool with the CCIP Router. It configures the router to use your Address Lookup Table and specifies which accounts need write access during CCIP operations.
Key Configuration:
- ALT Integration: Uses the lookup table
49FaPvs...
you just created - Writable Indexes:
[3,4,7]
- Specific accounts from the ALTthat need write access during CCIP operations
Transaction Flow:
- Authority Verification: Confirms Squad Vault has CCIP token admin permissions
- Pool Registration: Updates Token Admin Registry with pool configuration
- ALT Association: Links your token with the specific lookup table
- Permission Setup: Defines which accounts can be modified during cross-chain operations
Writable Indexes Analysis: [3,4,7]
Based on the ALT order established earlier:
Index | ALT Account | Why Writable |
---|---|---|
3 | Pool State PDA | Gets updated during cross-chain operations |
4 | Pool Token ATA | Tokens get minted/burned during transfers |
7 | Token Mint | Supply gets modified during mint/burn operations |
Phase 3 Complete: Save all variables:
# Save all variables for testing phase
cat > ~/.all_vars << EOF
# Phase 1 - EVM
export ETH_TOKEN_ADDRESS="$ETH_TOKEN_ADDRESS"
export ETH_POOL_ADDRESS="$ETH_POOL_ADDRESS"
# Phase 2 - Solana
export CCIP_POOL_PROGRAM="$CCIP_POOL_PROGRAM"
export CCIP_ROUTER_PROGRAM="$CCIP_ROUTER_PROGRAM"
export SOL_SQUAD_VAULT_MULTISIG="$SOL_SQUAD_VAULT_MULTISIG"
export SOL_WALLET_ADDRESS="$SOL_WALLET_ADDRESS"
export SOL_TOKEN_MINT="$SOL_TOKEN_MINT"
export SOL_POOL_ADDRESS="$SOL_POOL_ADDRESS"
export SOL_POOL_SIGNER_PDA="$SOL_POOL_SIGNER_PDA"
export SOL_SPL_MULTISIG="$SOL_SPL_MULTISIG"
export SOL_ADDRESS_LOOKUP_TABLE="$SOL_ADDRESS_LOOKUP_TABLE"
# Chain Selectors
export ETHEREUM_SEPOLIA_CHAIN_SELECTOR="$ETHEREUM_SEPOLIA_CHAIN_SELECTOR"
export SOLANA_CHAIN_SELECTOR="$SOLANA_CHAIN_SELECTOR"
EOF
echo "=== Phase 3 Complete - Cross-Chain Configuration ==="
echo "โ
Address Lookup Table: $SOL_ADDRESS_LOOKUP_TABLE"
echo "โ
Cross-chain connection configured"
echo "โ
All variables saved to ~/.all_vars"
=== Phase 3 Complete - Cross-Chain Configuration ===
โ
Address Lookup Table: Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6
โ
Cross-chain connection configured
โ
All variables saved to ~/.all_vars
Phase 4: EVM Cross-Chain Setup
Configure the Ethereum pool to recognize the Solana chain and set production rate limits.
Step 1: Load Phase 3 Variables
Ensure you're in Terminal 2 (Hardhat) and load all the variables from Phase 3.
# Verify you are in the Hardhat directory (Terminal 2)
# Should be: /.../smart-contract-examples/ccip/cct/hardhat
pwd
# Load all environment variables from Phase 3
source ~/.all_vars
# Verify key variables are loaded
echo "โ
ETH Token: $ETH_TOKEN_ADDRESS"
echo "โ
ETH Pool: $ETH_POOL_ADDRESS"
echo "โ
SOL Token: $SOL_TOKEN_MINT"
echo "โ
SOL Pool: $SOL_POOL_ADDRESS"
echo "โ
SOL ALT: $SOL_ADDRESS_LOOKUP_TABLE"
/.../smart-contract-examples/ccip/cct/hardhat
โ
ETH Token: 0x9cE471d0a7bE21ee32276ddE49104fE02C812906
โ
ETH Pool: 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342
โ
SOL Token: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
โ
SOL Pool: gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM
โ
SOL ALT: Gs628Qdfakm6EHxYdvuf27HMnZNh2TqjJNjnyrQhu6t6
Step 2: Configure Cross-Chain Settings
Configure the Ethereum pool to recognize the Solana chain and set production rate limits using applyChainUpdates
.
# Configure cross-chain settings WITH rate limits
npx hardhat applyChainUpdates \
--pooladdress $ETH_POOL_ADDRESS \
--remotechain solanaDevnet \
--remotepooladdresses $SOL_POOL_ADDRESS \
--remotetokenaddress $SOL_TOKEN_MINT \
--outboundratelimitenabled true \
--outboundratelimitcapacity 18000000000000000000 \
--outboundratelimitrate 100000000000000000 \
--inboundratelimitenabled true \
--inboundratelimitcapacity 20000000000000000000 \
--inboundratelimitrate 100000000000000000 \
--network sepolia
# Configure cross-chain settings WITHOUT rate limits
npx hardhat applyChainUpdates \
--pooladdress $ETH_POOL_ADDRESS \
--remotechain solanaDevnet \
--remotepooladdresses $SOL_POOL_ADDRESS \
--remotetokenaddress $SOL_TOKEN_MINT \
--network sepolia
2025-08-12T20:25:00.424Z info: === Starting Chain Update Configuration ===
2025-08-12T20:25:00.425Z info: ๐น Local network: sepolia
2025-08-12T20:25:00.425Z info: ๐น Pool address: 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342
2025-08-12T20:25:00.425Z info: ๐น Remote chain: solanaDevnet
2025-08-12T20:25:00.426Z info: ๐น Remote chain type detected: svm
2025-08-12T20:25:00.426Z info: ๐น Remote chain selector: 16423721717087811551
2025-08-12T20:25:00.426Z info: ๐น Parsed 1 remote pool addresses
2025-08-12T20:25:00.484Z info: โ
All addresses validated successfully
2025-08-12T20:25:00.939Z info: ๐น Using signer: 0x9d087fC03ae39b088326b67fA3C788236645b717
2025-08-12T20:25:01.352Z info: โ
Connected to pool contract
2025-08-12T20:25:01.353Z info: ๐น Remote pool address 1: gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM โ 0x0a2515d8f6ec3b58297031a08a2736defe792239608d920214c91a0474705854
2025-08-12T20:25:01.353Z info: ๐น Remote token address: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND โ 0xca1558e396f86b9fbd3a5219af4207e2624d5acd0bcf272fb8713bf1f7c32a2e
2025-08-12T20:25:01.353Z info: === Rate Limiter Configuration ===
2025-08-12T20:25:01.353Z info: ๐น Outbound enabled: true
2025-08-12T20:25:01.353Z info: ๐น Outbound capacity: 18000000000000000000
2025-08-12T20:25:01.353Z info: ๐น Outbound rate: 100000000000000000
2025-08-12T20:25:01.353Z info: ๐น Inbound enabled: true
2025-08-12T20:25:01.353Z info: ๐น Inbound capacity: 20000000000000000000
2025-08-12T20:25:01.353Z info: ๐น Inbound rate: 100000000000000000
2025-08-12T20:25:01.353Z info: === Executing Transaction ===
2025-08-12T20:25:01.353Z info: ๐น Sending applyChainUpdates transaction...
2025-08-12T20:25:01.865Z info: ๐น Transaction sent: 0xe488cf4b7f0b59f465e25bf5f44ffa351e4a6fb3f2ba10c11930d45a791a5e56
2025-08-12T20:25:01.865Z info: ๐น Waiting for 3 confirmations...
2025-08-12T20:27:03.271Z info: โ
Chain update applied successfully!
2025-08-12T20:28:15.322Z info: === Starting Chain Update Configuration ===
2025-08-12T20:28:15.323Z info: ๐น Local network: sepolia
2025-08-12T20:28:15.323Z info: ๐น Pool address: 0xB8aE4F4eDDFEFb3476039606Bfb8caE74a554342
2025-08-12T20:28:15.323Z info: ๐น Remote chain: solanaDevnet
2025-08-12T20:28:15.324Z info: ๐น Remote chain type detected: svm
2025-08-12T20:28:15.324Z info: ๐น Remote chain selector: 16423721717087811551
2025-08-12T20:28:15.324Z info: ๐น Parsed 1 remote pool addresses
2025-08-12T20:28:15.381Z info: โ
All addresses validated successfully
2025-08-12T20:28:15.836Z info: ๐น Using signer: 0x9d087fC03ae39b088326b67fA3C788236645b717
2025-08-12T20:28:16.249Z info: โ
Connected to pool contract
2025-08-12T20:28:16.250Z info: ๐น Remote pool address 1: gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM โ 0x0a2515d8f6ec3b58297031a08a2736defe792239608d920214c91a0474705854
2025-08-12T20:28:16.250Z info: ๐น Remote token address: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND โ 0xca1558e396f86b9fbd3a5219af4207e2624d5acd0bcf272fb8713bf1f7c32a2e
2025-08-12T20:28:16.250Z info: === Rate Limiter Configuration ===
2025-08-12T20:28:16.250Z info: ๐น No rate limits configured (unlimited transfers)
2025-08-12T20:28:16.250Z info: === Executing Transaction ===
2025-08-12T20:28:16.250Z info: ๐น Sending applyChainUpdates transaction...
2025-08-12T20:28:16.762Z info: ๐น Transaction sent: 0x7f89ab2c3d4e5f6789abc123def4567890abcdef1234567890abcdef12345678
2025-08-12T20:28:16.762Z info: ๐น Waiting for 3 confirmations...
2025-08-12T20:30:18.168Z info: โ
Chain update applied successfully!
Phase 5: Testing and Validation
Step 1: Load Phase 4 Variables
Before testing cross-chain transfers, ensure your terminal environment is properly configured:
# Check current directory
# This should be the solana-starter-kit directory (Terminal 3)
pwd
Load all environment variables
source ~/.all_vars
Set Ethereum receiver for testing
export ETH_RECEIVER_ADDRESS="<YOUR_ETH_RECEIVER_ADDRESS>"
Verify critical variables for Solana Starter Kit
echo "SOL_TOKEN_MINT: $SOL_TOKEN_MINT"
echo "ETH_TOKEN_ADDRESS: $ETH_TOKEN_ADDRESS"
echo "ETH_RECEIVER_ADDRESS: $ETH_RECEIVER_ADDRESS"
echo "SOL_WALLET_ADDRESS: $SOL_WALLET_ADDRESS"
/.../solana-starter-kit
SOL_TOKEN_MINT: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
ETH_TOKEN_ADDRESS: 0x9cE471d0a7bE21ee32276ddE49104fE02C812906
ETH_RECEIVER_ADDRESS: 0x9d087fC03ae39b088326b67fA3C788236645b717
SOL_WALLET_ADDRESS: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
Transfer Direction 1: Solana โ Ethereum
Test the production multisig setup with a cross-chain transfer from Solana Devnet to Ethereum Sepolia:
Prepare for Testing
Before testing cross-chain transfers, you need to create the pool's Associated Token Account (ATA) and prepare your tokens:
Check Token Balance
bash # Check your current token balance spl-token balance $SOL_TOKEN_MINT
5001
Create Pool Associated Token Account
# Create Associated Token Account for the Pool Signer PDA
yarn svm:pool:create-token-account \
--token-mint $SOL_TOKEN_MINT \
--burn-mint-pool-program $CCIP_POOL_PROGRAM
yarn run v1.22.22
$ ts-node ./ccip-scripts/svm/pool/create-pool-token-account.ts --token-mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --burn-mint-pool-program 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo
[2025-08-12T21:07:03.573Z] ๐ CCIP Pool Token Account Creation
[2025-08-12T21:07:03.579Z] ==========================================
[2025-08-12T21:07:03.626Z] Network: solana-devnet
[2025-08-12T21:07:03.626Z] Wallet: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
[2025-08-12T21:07:03.626Z] ๐ฐ WALLET BALANCE
[2025-08-12T21:07:03.626Z] ==========================================
[2025-08-12T21:07:04.647Z] SOL Balance: 40371554145 lamports (40.371554145 SOL)
[2025-08-12T21:07:04.648Z] ๐ ACCOUNT CREATION CONFIGURATION
[2025-08-12T21:07:04.648Z] ==========================================
[2025-08-12T21:07:04.648Z] Token Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[2025-08-12T21:07:04.649Z] Burn-Mint Pool Program: 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo
[2025-08-12T21:07:04.651Z] ๐ VERIFYING POOL EXISTENCE
[2025-08-12T21:07:04.651Z] ==========================================
[2025-08-12T21:07:04.653Z] ๐ Pool Config PDA: gbsmzERXogUy74hMq5zYwAkKWd2Y2BKobsvhs26Z3MM
[2025-08-12T21:07:04.913Z] โ
Pool exists
[2025-08-12T21:07:04.913Z] Current pool token account: 9pVYxjcnV2gTTFrwnrh2Lb1zUwTefEjxSbpia1B6NUtn
[2025-08-12T21:07:04.913Z] Getting mint account info for EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND to determine token program ID...
[2025-08-12T21:07:05.189Z] Detected Standard Token Program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
[2025-08-12T21:07:05.189Z] Pool signer PDA: ERs5qJvN1hu4rGrtuj6WMhZznVWbCyf2g4ynMgFHCWKN
[2025-08-12T21:07:05.192Z] Expected pool token account (ATA): 9pVYxjcnV2gTTFrwnrh2Lb1zUwTefEjxSbpia1B6NUtn
[2025-08-12T21:07:05.192Z] ๐ CHECKING EXISTING ACCOUNT
[2025-08-12T21:07:05.192Z] ==========================================
[2025-08-12T21:07:05.448Z]
[2025-08-12T21:07:05.448Z] ๐ง CREATING POOL TOKEN ACCOUNT
[2025-08-12T21:07:05.448Z] ==========================================
[2025-08-12T21:07:05.448Z] Creating pool token account (ATA)...
[2025-08-12T21:07:06.927Z]
[2025-08-12T21:07:06.927Z] โ
POOL TOKEN ACCOUNT CREATED SUCCESSFULLY
[2025-08-12T21:07:06.927Z] ==========================================
[2025-08-12T21:07:06.928Z] Transaction Signature: 4KT4tWjXVuRFkRkf2SSLHrKBc8WmZRCpgRA77jLqrU5HFph5Y5SK4vUzUEUGobyZNs3URgNAEzc7sfvtPukWBhUA
[2025-08-12T21:07:06.928Z] Pool Token Account Address: 9pVYxjcnV2gTTFrwnrh2Lb1zUwTefEjxSbpia1B6NUtn
[2025-08-12T21:07:06.928Z] ๐ EXPLORER URLS
[2025-08-12T21:07:06.928Z] ==========================================
[2025-08-12T21:07:06.928Z] Transaction: https://explorer.solana.com/tx/4KT4tWjXVuRFkRkf2SSLHrKBc8WmZRCpgRA77jLqrU5HFph5Y5SK4vUzUEUGobyZNs3URgNAEzc7sfvtPukWBhUA?cluster=devnet
[2025-08-12T21:07:06.929Z] ๐ VERIFYING ACCOUNT CREATION
[2025-08-12T21:07:06.929Z] ==========================================
[2025-08-12T21:07:07.183Z] โ
Account creation verified!
[2025-08-12T21:07:07.183Z] ๐ Pool Token Account Setup Complete!
[2025-08-12T21:07:07.183Z] โ
ATA Address: 9pVYxjcnV2gTTFrwnrh2Lb1zUwTefEjxSbpia1B6NUtn
[2025-08-12T21:07:07.183Z] โ
Owner: ERs5qJvN1hu4rGrtuj6WMhZznVWbCyf2g4ynMgFHCWKN (Pool Signer PDA)
[2025-08-12T21:07:07.183Z] โ
Ready for cross-chain token operations
โจ Done in 7.60s.
Delegate Token Authority
# Delegate tokens for CCIP transfers
yarn svm:token:delegate --token-mint $SOL_TOKEN_MINT
5001
yarn run v1.22.22
$ ts-node ./ccip-scripts/svm/token/delegate-token-authority.ts --token-mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[2025-08-12T20:53:04.516Z] CCIP Token Authority Delegator
[2025-08-12T20:53:04.520Z] =============================================
[2025-08-12T20:53:04.564Z] Network: solana-devnet
[2025-08-12T20:53:04.565Z] Router Program: Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C
[2025-08-12T20:53:04.565Z] Wallet: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
[2025-08-12T20:53:04.565Z] ๐ฐ WALLET BALANCE
[2025-08-12T20:53:04.565Z] =============================================
[2025-08-12T20:53:06.086Z] SOL Balance: 40.371559145 SOL (40371559145 lamports)
[2025-08-12T20:53:06.087Z] ๐ PROCESSING TOKEN DELEGATIONS
[2025-08-12T20:53:06.087Z] =============================================
[2025-08-12T20:53:06.087Z] Custom token mints provided: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[2025-08-12T20:53:06.087Z] Using 'fee-billing' delegation type for ccip_send compatibility
[2025-08-12T20:53:06.087Z] Added custom token delegation for: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[1/1] Processing delegation for mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[2025-08-12T20:53:06.087Z] Getting mint account info for EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND to determine token program ID...
[2025-08-12T20:53:06.192Z] Detected Standard Token Program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
[2025-08-12T20:53:06.193Z] Token Program ID: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
[2025-08-12T20:53:06.193Z] Delegation Type: fee-billing
[2025-08-12T20:53:06.193Z] Delegate Address: 2AjuzTy6z2webxEUu7eZ1DkAyLagZaqH2dgzhbBYjJiG
[2025-08-12T20:53:06.193Z] Amount to delegate: 18446744073709551615
[2025-08-12T20:53:06.195Z] User Token Account: 5xwF4TX8qzvNyWzQNWYAG8f2RDJrGbuWeEA9R1asYgmg
[2025-08-12T20:53:06.298Z] Token account 5xwF4TX8qzvNyWzQNWYAG8f2RDJrGbuWeEA9R1asYgmg exists.
[2025-08-12T20:53:06.403Z] Sending transaction to delegate token authority...
[2025-08-12T20:53:07.257Z] โ
Token delegation successful!
[2025-08-12T20:53:07.257Z] Transaction signature: hh2t9GsXDbhN7DC4UnoP4gV5dxLGxSnNZt9gFKAd3bpBjmhuPb7cWS1WzG8B3Yv87R1eX63zXDw5YJekk8HzUxw
[2025-08-12T20:53:07.257Z] Explorer URL: https://explorer.solana.com/tx/hh2t9GsXDbhN7DC4UnoP4gV5dxLGxSnNZt9gFKAd3bpBjmhuPb7cWS1WzG8B3Yv87R1eX63zXDw5YJekk8HzUxw?cluster=devnet
[2025-08-12T20:53:07.258Z] โ
All delegations processed successfully
โจ Done in 23.60s.
yarn run v1.22.22
$ ts-node ./ccip-scripts/svm/token/check-token-approval.ts --token-mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[2025-08-12T20:53:14.474Z] CCIP Token Approval Checker
[2025-08-12T20:53:14.479Z] =========================================
[2025-08-12T20:53:14.566Z] Network: solana-devnet
[2025-08-12T20:53:14.567Z] Router Program: Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C
[2025-08-12T20:53:14.567Z] Wallet: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
[2025-08-12T20:53:14.568Z] ๐ฐ WALLET BALANCE
[2025-08-12T20:53:14.568Z] =============================================
[2025-08-12T20:53:16.351Z] SOL Balance: 40.371554145 SOL (40371554145 lamports)
[2025-08-12T20:53:16.352Z] ๐ PROCESSING TOKEN APPROVALS
[2025-08-12T20:53:16.353Z] =========================================
[2025-08-12T20:53:16.353Z] Custom token mints provided: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[2025-08-12T20:53:16.353Z] Using 'fee-billing' delegation type for ccip_send compatibility
[2025-08-12T20:53:16.353Z] Added custom token check for: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[1/1] Processing token: Custom Token (EbrEbzXX...)
[2025-08-12T20:53:16.354Z] Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[2025-08-12T20:53:16.354Z] Getting mint account info for EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND to determine token program ID...
[2025-08-12T20:53:16.623Z] Detected Standard Token Program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
[2025-08-12T20:53:16.623Z] Token Program ID: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
[2025-08-12T20:53:16.637Z] Token Account: 5xwF4TX8qzvNyWzQNWYAG8f2RDJrGbuWeEA9R1asYgmg
[2025-08-12T20:53:16.642Z] Expected Delegate (fee-billing): 2AjuzTy6z2webxEUu7eZ1DkAyLagZaqH2dgzhbBYjJiG
[2025-08-12T20:53:16.930Z] Balance: 5001000000000
[2025-08-12T20:53:16.930Z] Actual Delegate: 2AjuzTy6z2webxEUu7eZ1DkAyLagZaqH2dgzhbBYjJiG
[2025-08-12T20:53:16.930Z] Delegated Amount: 18446744073709551615
[2025-08-12T20:53:16.931Z] Matches Expected Delegate: โ Yes
[2025-08-12T20:53:16.931Z] ๐ TOKEN APPROVAL SUMMARY
[2025-08-12T20:53:16.931Z] =========================================
[2025-08-12T20:53:16.931Z] Token | Description | Balance | Delegate | Delegated Amount | Status
[2025-08-12T20:53:16.931Z] ------|-------------|---------|----------|-----------------|-------
[2025-08-12T20:53:16.931Z] EbrEbzXX... | Custom Token (EbrEbzXX...) | 5001000000000 | 2AjuzTy6... | 18446744073709551615 | โ Correct
[2025-08-12T20:53:16.931Z] โ
Token approval check completed successfully
โจ Done in 8.77s.
Execute Transfer
# Execute cross-chain transfer from Solana to Ethereum
yarn svm:token-transfer --token-mint $SOL_TOKEN_MINT --token-amount 1000000 --receiver $ETH_RECEIVER_ADDRESS
yarn run v1.22.22
$ ts-node ./ccip-scripts/svm/router/1_token-transfer.ts --token-mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --token-amount 1000000 --receiver
[2025-08-12T23:17:54.579Z] ๐ CCIP Token Transfer
[2025-08-12T23:17:54.581Z] =======================================
[2025-08-12T23:17:54.611Z] Network: devnet
[2025-08-12T23:17:54.611Z] Wallet: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
[2025-08-12T23:17:54.611Z]
[2025-08-12T23:17:54.612Z] ๐ฐ WALLET BALANCE
[2025-08-12T23:17:54.612Z] =======================================
[2025-08-12T23:17:55.002Z] SOL Balance: 40365443847 lamports (40.365443847 SOL)
[2025-08-12T23:17:55.002Z]
[2025-08-12T23:17:55.003Z] ๐ CCIP ROUTER INFORMATION
[2025-08-12T23:17:55.003Z] =======================================
[2025-08-12T23:17:55.003Z] CCIP Router Program ID: Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C
[2025-08-12T23:17:55.003Z] Fee Quoter Program ID: FeeQPGkKDeRV1MgoYfMH6L8o3KeuYjwUZrgn4LRKfjHi
[2025-08-12T23:17:55.003Z] RMN Remote Program ID: RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7
[2025-08-12T23:17:55.003Z] Using native SOL as fee token
[2025-08-12T23:17:55.003Z]
[2025-08-12T23:17:55.003Z] ๐ TOKEN TRANSFER PARAMETERS
[2025-08-12T23:17:55.003Z] ===========================================
[2025-08-12T23:17:55.003Z] Destination Chain: ethereum-sepolia
[2025-08-12T23:17:55.003Z] Destination Chain Selector: 16015286601757825753
[2025-08-12T23:17:55.003Z] EVM Receiver Address: 0x9d087fC03ae39b088326b67fA3C788236645b717
[2025-08-12T23:17:55.003Z] Token Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[2025-08-12T23:17:55.003Z] Token Amount: 1000000
[2025-08-12T23:17:55.003Z] Fee Token: 11111111111111111111111111111111
[2025-08-12T23:17:55.003Z] Gas Limit: 0
[2025-08-12T23:17:55.003Z] Allow Out Of Order Execution: true
[2025-08-12T23:17:55.004Z]
[2025-08-12T23:17:55.004Z] ๐ SENDING TOKEN TRANSFER
[2025-08-12T23:17:55.004Z] =======================================
[2025-08-12T23:17:55.004Z] Preparing CCIP message...
[2025-08-12T23:17:55.005Z] Sending CCIP message to destination chain 16015286601757825753
[2025-08-12T23:17:55.005Z] Building accounts for CCIP send to chain 16015286601757825753
[2025-08-12T23:17:55.009Z] Getting mint account info for EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND to determine token program ID...
[2025-08-12T23:18:10.134Z] Detected Standard Token Program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
[2025-08-12T23:18:26.400Z] CCIP message sent successfully: 5pBfCdgVYxbxqYGVE5669ty34xFiEEWb5ZBPYoDy9vXpGMu6abZDtJtSyfTUHxYmFNf4YqYcNz71iKQRoyUgbtAx
[2025-08-12T23:18:26.401Z] Parsing CCIP message sent event for transaction: 5pBfCdgVYxbxqYGVE5669ty34xFiEEWb5ZBPYoDy9vXpGMu6abZDtJtSyfTUHxYmFNf4YqYcNz71iKQRoyUgbtAx
[2025-08-12T23:18:26.523Z] Successfully extracted messageId: 0x8499fb356101f9a64a295c60e88ec320b21e854a536bf137c27055d7dc5e699e
[2025-08-12T23:18:26.523Z]
[2025-08-12T23:18:26.523Z] โ
TOKEN TRANSFER SENT SUCCESSFULLY
[2025-08-12T23:18:26.523Z] =======================================
[2025-08-12T23:18:26.523Z] Transaction Signature: 5pBfCdgVYxbxqYGVE5669ty34xFiEEWb5ZBPYoDy9vXpGMu6abZDtJtSyfTUHxYmFNf4YqYcNz71iKQRoyUgbtAx
[2025-08-12T23:18:26.523Z] CCIP Message ID: 0x8499fb356101f9a64a295c60e88ec320b21e854a536bf137c27055d7dc5e699e
[2025-08-12T23:18:26.523Z]
[2025-08-12T23:18:26.523Z] ๐ EXPLORER URLS
[2025-08-12T23:18:26.523Z] =======================================
[2025-08-12T23:18:26.523Z] Solana Transaction: https://explorer.solana.com/tx/5pBfCdgVYxbxqYGVE5669ty34xFiEEWb5ZBPYoDy9vXpGMu6abZDtJtSyfTUHxYmFNf4YqYcNz71iKQRoyUgbtAx?cluster=devnet
[2025-08-12T23:18:26.523Z] CCIP Explorer: https://ccip.chain.link/msg/0x8499fb356101f9a64a295c60e88ec320b21e854a536bf137c27055d7dc5e699e
[2025-08-12T23:18:26.523Z]
[2025-08-12T23:18:26.523Z] ๐ Transfer Complete!
[2025-08-12T23:18:26.523Z] โ
Sent 1000000 tokens to 0x9d087fC03ae39b088326b67fA3C788236645b717
[2025-08-12T23:18:26.523Z] โ
Message ID: 0x8499fb356101f9a64a295c60e88ec320b21e854a536bf137c27055d7dc5e699e
[2025-08-12T23:18:26.523Z] โ
Monitor progress on CCIP Explorer: https://ccip.chain.link/msg/0x8499fb356101f9a64a295c60e88ec320b21e854a536bf137c27055d7dc5e699e
โจ Done in 36.44s.
Monitor and Verify Transaction
Upon successful execution, the system generates critical tracking identifiers for transaction monitoring and verification.
Transaction Identifiers:
- Transaction Signature:
5pBfCdgVYxbxqYGVE5669ty34xFiEEWb5ZBPYoDy9vXpGMu6abZDtJtSyfTUHxYmFNf4YqYcNz71iKQRoyUgbtAx
- CCIP Message ID:
0x8499fb356101f9a64a295c60e88ec320b21e854a536bf137c27055d7dc5e699e
CCIP Explorer (Primary monitoring interface):
https://ccip.chain.link/msg/0x8499fb356101f9a64a295c60e88ec320b21e854a536bf137c27055d7dc5e699e
The CCIP Explorer provides comprehensive transaction visibility:
- Source chain (Solana) transaction confirmation
- CCIP message processing and routing
- Destination chain (Ethereum) message delivery
- Token minting completion on Ethereum
Solana Explorer (Source chain verification):
https://explorer.solana.com/tx/5pBfCdgVYxbxqYGVE5669ty34xFiEEWb5ZBPYoDy9vXpGMu6abZDtJtSyfTUHxYmFNf4YqYcNz71iKQRoyUgbtAx?cluster=devnet
Transfer Direction 2: Ethereum โ Solana
Execute Transfer
# Execute cross-chain transfer from Ethereum to Solana
yarn evm:transfer --token $ETH_TOKEN_ADDRESS --amount 1000000000000000000 --token-receiver $SOL_WALLET_ADDRESS
yarn run v1.22.22
$ ts-node ./ccip-scripts/evm/router/1_token-transfer.ts --token 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 --amount 1000000000000000000 --token-receiver EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
Current working directory: /.../solana-starter-kit
Found .env file at: /.../solana-starter-kit/.env
Successfully loaded environment variables from /.../solana-starter-kit/.env
[token-transfer] [INFO] ๐ EVM to Solana CCIP Token Transfer
[token-transfer] [INFO] =========================================
chainId ethereum-sepolia
[token-transfer] [INFO] Source Chain: ethereum-sepolia
[token-transfer] [INFO] Fee Token: link
[token-transfer] [INFO] Token Receiver: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
[token-transfer] [INFO] Compute Units: 0
[token-transfer] [INFO]
==== Environment Information ====
chainId ethereum-sepolia
[token-transfer] [INFO] Router Address: 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59
[ccip-messenger] [INFO] Creating client for chain: Ethereum Sepolia (ethereum-sepolia)
[token-transfer] [INFO] Wallet Address: 0x9d087fC03ae39b088326b67fA3C788236645b717
[token-transfer] [INFO] Native Balance: 592.730404718701499976 ETH
[token-transfer] [INFO]
๐ Validating Token Transfer
[token-transfer] [INFO] =========================================
[token-transfer] [INFO] Token: BnmAEM (0x9cE471d0a7bE21ee32276ddE49104fE02C812906)
[token-transfer] [INFO] Token Balance: 999.001 BnmAEM
[token-transfer] [INFO] Token: BnmAEM (0x9cE471d0a7bE21ee32276ddE49104fE02C812906)
[token-transfer] [INFO] Token Balance: 999.001 BnmAEM
[token-transfer] [INFO] Transfer Amount: 1.0 BnmAEM
[token-transfer] [INFO] โ
Token validation successful
[token-transfer] [INFO] Using fee token: 0x779877A7B0D9E8603169DdbD7836e478b4624789
[token-transfer] [INFO] Creating CCIP message request
[token-transfer] [INFO]
๐ Transfer Summary
[token-transfer] [INFO] =========================================
[token-transfer] [INFO]
==== Transfer Summary ====
[token-transfer] [INFO] Source Chain: Ethereum Sepolia
[token-transfer] [INFO] Destination Chain: Solana Devnet (16423721717087811551)
[token-transfer] [INFO] Sender: 0x9d087fC03ae39b088326b67fA3C788236645b717
[token-transfer] [INFO] Receiver: 11111111111111111111111111111111
[token-transfer] [INFO] Token Receiver: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
[token-transfer] [INFO] Fee Token: 0x779877A7B0D9E8603169DdbD7836e478b4624789
[token-transfer] [INFO]
Token Transfers:
[token-transfer] [INFO] 1. 1000000000000000000 raw units (0x9cE471d0a7bE21ee32276ddE49104fE02C812906)
[token-transfer] [INFO]
Extra Args: Solana-specific, 228 bytes
[token-transfer] [INFO]
๐ Executing Token Transfer
[token-transfer] [INFO] =========================================
[token-transfer] [INFO] Sending CCIP message...
[ccip-messenger] [INFO] Estimated fee: 13619642012026845
[ccip-messenger] [INFO] Approving 0.016343570414432214 LINK for CCIP Router
[ccip-messenger] [INFO] This token is being used as the fee token with a 20% buffer included
[ccip-messenger] [INFO] Approving 0.016343570414432214 tokens for 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59
[ccip-messenger] [INFO] LINK approved for CCIP Router
[ccip-messenger] [INFO] โ
Verified onchain allowance for LINK: 0.016343570414432214 (required: 0.016343570414432214)
[ccip-messenger] [INFO] Approving 1.0 BnmAEM for CCIP Router
[ccip-messenger] [INFO] Approving 1.0 tokens for 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59
[ccip-messenger] [INFO] BnmAEM approved for CCIP Router
[ccip-messenger] [INFO] โ
Verified onchain allowance for BnmAEM: 1.0 (required: 1.0)
[ccip-messenger] [INFO] Sending CCIP message...
[ccip-messenger] [INFO] Sending CCIP message...
[ccip-messenger] [INFO] Transaction sent: 0x164f3577d51af7502667b3664a5473721cd509ae8bf38f012ac66a47549386c5
[ccip-messenger] [INFO] Transaction sent: 0x164f3577d51af7502667b3664a5473721cd509ae8bf38f012ac66a47549386c5
[ccip-messenger] [INFO] Message ID: 0x1960374bd102e22019eef68f1a5bc9d1c9355a49a21d246b2a92953a63f831cf
[token-transfer] [INFO]
๐ Transfer Results
[token-transfer] [INFO] =========================================
[token-transfer] [INFO]
==== Transfer Results ====
[token-transfer] [INFO] Transaction Hash: 0x164f3577d51af7502667b3664a5473721cd509ae8bf38f012ac66a47549386c5
[token-transfer] [INFO] Transaction URL: https://sepolia.etherscan.io/tx/0x164f3577d51af7502667b3664a5473721cd509ae8bf38f012ac66a47549386c5
[token-transfer] [INFO] Message ID: 0x1960374bd102e22019eef68f1a5bc9d1c9355a49a21d246b2a92953a63f831cf
[token-transfer] [INFO] ๐ CCIP Explorer: https://ccip.chain.link/msg/0x1960374bd102e22019eef68f1a5bc9d1c9355a49a21d246b2a92953a63f831cf
[token-transfer] [INFO] Destination Chain Selector: 16423721717087811551
[token-transfer] [INFO] Sequence Number: 543
[token-transfer] [INFO]
Message tracking for Solana destinations:
[token-transfer] [INFO] Please check the CCIP Explorer link to monitor your message status.
[token-transfer] [INFO]
โ
Transaction completed on the source chain
[token-transfer] [INFO]
โ
Token Transfer Complete!
[token-transfer] [INFO] ๐ Your tokens are being bridged to Solana
โจ Done in 116.66s.
Monitor and Verify Transaction
Upon successful execution, the system generates distinct tracking identifiers for comprehensive monitoring across both blockchain networks.
Transaction Identifiers:
- Ethereum Transaction Hash:
0x164f3577d51af7502667b3664a5473721cd509ae8bf38f012ac66a47549386c5
- CCIP Message ID:
0x1960374bd102e22019eef68f1a5bc9d1c9355a49a21d246b2a92953a63f831cf
CCIP Explorer (Primary monitoring interface):
https://ccip.chain.link/msg/0x1960374bd102e22019eef68f1a5bc9d1c9355a49a21d246b2a92953a63f831cf
The CCIP Explorer provides comprehensive transaction visibility:
- Source chain (Ethereum) transaction confirmation
- CCIP message processing and routing
- Destination chain (Solana) message delivery
- Token minting completion on Solana network
Ethereum Sepolia Explorer (Source chain verification):
https://sepolia.etherscan.io/tx/0x164f3577d51af7502667b3664a5473721cd509ae8bf38f012ac66a47549386c5
Test Solana Rate Limit Enforcement (Optional)
# Attempt to transfer 25 tokens (exceeds rate limit capacity of 20)
yarn svm:token-transfer \
--token-mint $SOL_TOKEN_MINT \
--token-amount 25000000000 \
--receiver $ETH_RECEIVER_ADDRESS
$ yarn svm:token-transfer \
--token-mint $SOL_TOKEN_MINT \
--token-amount 25000000000 \
--receiver $ETH_RECEIVER_ADDRESS
yarn run v1.22.22
$ ts-node ./ccip-scripts/svm/router/1_token-transfer.ts --token-mint EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND --token-amount 25000000000 --receiver
[2025-08-13T00:09:26.249Z] ๐ CCIP Token Transfer
[2025-08-13T00:09:26.251Z] =======================================
[2025-08-13T00:09:26.281Z] Network: devnet
[2025-08-13T00:09:26.281Z] Wallet: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
[2025-08-13T00:09:26.281Z]
[2025-08-13T00:09:26.281Z] ๐ฐ WALLET BALANCE
[2025-08-13T00:09:26.281Z] =======================================
[2025-08-13T00:09:26.847Z] SOL Balance: 40364108169 lamports (40.364108169 SOL)
[2025-08-13T00:09:26.847Z]
[2025-08-13T00:09:26.847Z] ๐ CCIP ROUTER INFORMATION
[2025-08-13T00:09:26.847Z] =======================================
[2025-08-13T00:09:26.848Z] CCIP Router Program ID: Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C
[2025-08-13T00:09:26.848Z] Fee Quoter Program ID: FeeQPGkKDeRV1MgoYfMH6L8o3KeuYjwUZrgn4LRKfjHi
[2025-08-13T00:09:26.848Z] RMN Remote Program ID: RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7
[2025-08-13T00:09:26.848Z] Using native SOL as fee token
[2025-08-13T00:09:26.848Z]
[2025-08-13T00:09:26.848Z] ๐ TOKEN TRANSFER PARAMETERS
[2025-08-13T00:09:26.848Z] ===========================================
[2025-08-13T00:09:26.848Z] Destination Chain: ethereum-sepolia
[2025-08-13T00:09:26.848Z] Destination Chain Selector: 16015286601757825753
[2025-08-13T00:09:26.848Z] EVM Receiver Address: 0x9d087fC03ae39b088326b67fA3C788236645b717
[2025-08-13T00:09:26.848Z] Token Mint: EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND
[2025-08-13T00:09:26.848Z] Token Amount: 25000000000
[2025-08-13T00:09:26.848Z] Fee Token: 11111111111111111111111111111111
[2025-08-13T00:09:26.848Z] Gas Limit: 0
[2025-08-13T00:09:26.848Z] Allow Out Of Order Execution: true
[2025-08-13T00:09:26.849Z]
[2025-08-13T00:09:26.849Z] ๐ SENDING TOKEN TRANSFER
[2025-08-13T00:09:26.849Z] =======================================
[2025-08-13T00:09:26.849Z] Preparing CCIP message...
[2025-08-13T00:09:26.850Z] Sending CCIP message to destination chain 16015286601757825753
[2025-08-13T00:09:26.850Z] Building accounts for CCIP send to chain 16015286601757825753
[2025-08-13T00:09:26.855Z] Getting mint account info for EbrEbzXXUGurxRq55xtie1r4e8rHH99jUAwUaEygrKND to determine token program ID...
[2025-08-13T00:09:26.955Z] Detected Standard Token Program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
[2025-08-13T00:09:27.397Z] โ Failed to send token transfer: Simulation failed.
Message: Transaction simulation failed: Error processing Instruction 1: custom program error: 0x177f.
Logs:
[
"Program log: Instruction: LockOrBurnTokens",
"Program RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7 invoke [3]",
"Program log: Instruction: VerifyNotCursed",
"Program RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7 consumed 6856 of 1167595 compute units",
"Program RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7 success",
"Program log: AnchorError thrown in programs/base-token-pool/src/rate_limiter.rs:48. Error Code: RLMaxCapacityExceeded. Error Number: 6015. Error Message: RateLimit: max capacity exceeded.",
"Program 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo consumed 46498 of 1204388 compute units",
"Program 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo failed: custom program error: 0x177f",
"Program Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C consumed 241960 of 1399850 compute units",
"Program Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C failed: custom program error: 0x177f"
].
Catch the `SendTransactionError` and call `getLogs()` on it for full details.
[2025-08-13T00:09:27.410Z]
โ Command failed:
[2025-08-13T00:09:27.410Z] Simulation failed.
Message: Transaction simulation failed: Error processing Instruction 1: custom program error: 0x177f.
Logs:
[
"Program log: Instruction: LockOrBurnTokens",
"Program RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7 invoke [3]",
"Program log: Instruction: VerifyNotCursed",
"Program RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7 consumed 6856 of 1167595 compute units",
"Program RmnXLft1mSEwDgMKu2okYuHkiazxntFFcZFrrcXxYg7 success",
"Program log: AnchorError thrown in programs/base-token-pool/src/rate_limiter.rs:48. Error Code: RLMaxCapacityExceeded. Error Number: 6015. Error Message: RateLimit: max capacity exceeded.",
"Program 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo consumed 46498 of 1204388 compute units",
"Program 3BrkN1XcyeafuMZxomLZBUVdasEtpdMmpWfsEQmzN7vo failed: custom program error: 0x177f",
"Program Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C consumed 241960 of 1399850 compute units",
"Program Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C failed: custom program error: 0x177f"
].
Catch the `SendTransactionError` and call `getLogs()` on it for full details.
error Command failed with exit code 1.
The transaction correctly failed with RLMaxCapacityExceeded
error because:
- Attempted: 25 tokens (
25000000000
in smallest units) - Limit: 20 tokens maximum capacity (
20000000000
) - Result: Rate limiter blocked the excessive transfer
Key Error Details:
- Error Code:
RLMaxCapacityExceeded
(Error Number: 6015) - Source:
programs/base-token-pool/src/rate_limiter.rs:48
- Meaning: The token bucket capacity was exceeded
This demonstrates that your rate limits are properly configured and actively protecting against transfers that exceed the configured limits.
Test EVM Rate Limit Enforcement (Optional)
Test rate limits from the EVM side (Ethereum to Solana) using the same 25-token limit.
# Attempt to transfer 25 tokens from Ethereum (exceeds rate limit capacity of 20)
yarn evm:transfer \
--token $ETH_TOKEN_ADDRESS \
--amount 25000000000000000000 \
--token-receiver $SOL_WALLET_ADDRESS
$ yarn evm:transfer \
--token $ETH_TOKEN_ADDRESS \
--amount 25000000000000000000 \
--token-receiver $SOL_WALLET_ADDRESS
yarn run v1.22.22
$ ts-node ./ccip-scripts/evm/router/1_token-transfer.ts --token 0x9cE471d0a7bE21ee32276ddE49104fE02C812906 --amount 25000000000000000000 --token-receiver EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
Current working directory: /.../solana-starter-kit
Found .env file at: /.../solana-starter-kit/.env
Successfully loaded environment variables from /.../solana-starter-kit/.env
[token-transfer] [INFO] ๐ EVM to Solana CCIP Token Transfer
[token-transfer] [INFO] =========================================
chainId ethereum-sepolia
[token-transfer] [INFO] Source Chain: ethereum-sepolia
[token-transfer] [INFO] Fee Token: link
[token-transfer] [INFO] Token Receiver: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
[token-transfer] [INFO] Compute Units: 0
[token-transfer] [INFO]
==== Environment Information ====
chainId ethereum-sepolia
[token-transfer] [INFO] Router Address: 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59
[ccip-messenger] [INFO] Creating client for chain: Ethereum Sepolia (ethereum-sepolia)
[token-transfer] [INFO] Wallet Address: 0x9d087fC03ae39b088326b67fA3C788236645b717
[token-transfer] [INFO] Native Balance: 592.730404718701499976 ETH
[token-transfer] [INFO]
๐ Validating Token Transfer
[token-transfer] [INFO] =========================================
[token-transfer] [INFO] Token: BnmAEM (0x9cE471d0a7bE21ee32276ddE49104fE02C812906)
[token-transfer] [INFO] Token Balance: 999.001 BnmAEM
[token-transfer] [INFO] Transfer Amount: 25.0 BnmAEM
[token-transfer] [INFO] โ
Token validation successful
[token-transfer] [INFO] Using fee token: 0x779877A7B0D9E8603169DdbD7836e478b4624789
[token-transfer] [INFO] Creating CCIP message request
[token-transfer] [INFO]
๐ Transfer Summary
[token-transfer] [INFO] =========================================
[token-transfer] [INFO] Source Chain: Ethereum Sepolia
[token-transfer] [INFO] Destination Chain: Solana Devnet (16423721717087811551)
[token-transfer] [INFO] Sender: 0x9d087fC03ae39b088326b67fA3C788236645b717
[token-transfer] [INFO] Receiver: 11111111111111111111111111111111
[token-transfer] [INFO] Token Receiver: EPUjBP3Xf76K1VKsDSc6GupBWE8uykNksCLJgXZn87CB
[token-transfer] [INFO] Fee Token: 0x779877A7B0D9E8603169DdbD7836e478b4624789
[token-transfer] [INFO] Token Transfers:
[token-transfer] [INFO] 1. 25000000000000000000 raw units (0x9cE471d0a7bE21ee32276ddE49104fE02C812906)
[token-transfer] [INFO]
๐ Executing Token Transfer
[token-transfer] [INFO] =========================================
[token-transfer] [INFO] Sending CCIP message...
[ccip-messenger] [INFO] Estimated fee: 13619642012026845
[ccip-messenger] [INFO] Approving 0.016343570414432214 LINK for CCIP Router
[ccip-messenger] [INFO] This token is being used as the fee token with a 20% buffer included
[ccip-messenger] [INFO] Approving 0.016343570414432214 tokens for 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59
[ccip-messenger] [INFO] LINK approved for CCIP Router
[ccip-messenger] [INFO] โ
Verified on-chain allowance for LINK: 0.016343570414432214 (required: 0.016343570414432214)
[ccip-messenger] [INFO] Approving 25.0 BnmAEM for CCIP Router
[ccip-messenger] [INFO] Approving 25.0 tokens for 0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59
[ccip-messenger] [INFO] BnmAEM approved for CCIP Router
[ccip-messenger] [INFO] โ
Verified on-chain allowance for BnmAEM: 25.0 (required: 25.0)
[ccip-messenger] [INFO] Sending CCIP message...
[ccip-messenger] [ERROR] Error sending CCIP message: Error: execution reverted (unknown custom error) (action="estimateGas", data="0x1a76572a000000000000000000000000000000000000000000000000f9ccd8a1c50800000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000009ce471d0a7be21ee32276dde49104fe02c812906", reason=null, transaction={...})
[token-transfer] [ERROR] โ token-transfer failed:
execution reverted (unknown custom error) (action="estimateGas", data="0x1a76572a000000000000000000000000000000000000000000000000f9ccd8a1c50800000000000000000000000000000000000000000000000000015af1d78b58c400000000000000000000000000009ce471d0a7be21ee32276dde49104fe02c812906")
error Command failed with exit code 1.
The transaction correctly failed because:
- Attempted: 25 tokens (
25000000000000000000
wei - 18 decimals) - Limit: 18 tokens maximum capacity
- Error Selector:
0x1a76572a
(TokenMaxCapacityExceeded) - Decoded Values: Capacity:
18000000000000000000
, Attempted:25000000000000000000
, Token:0x9cE471d0a7bE21ee32276dde49104fe02c812906
This demonstrates that rate limits are enforced on both chains, protecting the cross-chain bridge from excessive transfers. The EVM error selector corresponds to the TokenMaxCapacityExceeded
error in the CCIP EVM v1.6.0 errors reference.