Cross-Chain Token Setup: BurnMint 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
This tutorial implements the production multisig governance variant of Path A from the CCIP Cross-Chain Token Integration Guide. This approach is designed for production environments with enterprise-grade dual-layer governance.
Cross-Chain Token Architecture
This tutorial implements the Burn and Mint token handling mechanism between Solana Devnet and Ethereum Sepolia with dual-layer multisig governance. You'll deploy two BurnMint pools (one on each chain) that work together to maintain consistent token supply across chains while providing enterprise-grade security controls.
How Burn and Mint Works:
- Source Chain: Burns tokens from sender's account
- CCIP Protocol: Transmits message cross-chain
- Destination Chain: Mints equivalent tokens to the receiver
For complete details on token handling mechanisms, see Token Handling Mechanisms.
Component Overview
| Component | Implementation | Authority 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 Transfer | Bidirectional token transfers | Autonomous operations |
Dual-Layer Governance Architecture
This tutorial implements dual-layer multisig governance that separates concerns:
- Layer 1 (Squads): Controls CCIP administration, pool ownership, protocol configuration
- Layer 2 (SPL Multisig): Controls mint authority with Pool Signer PDA for autonomous operations
Production Benefits:
- Comprehensive Security: Two independent governance layers
- Operational Autonomy: Pool Signer PDA enables autonomous cross-chain transfers
- Administrative Control: Squads provides enterprise-grade governance
Prerequisites
This tutorial uses a two-terminal workflow with Squads multisig governance on Solana. Install the system tools below, create your Squad on devnet, clone both repositories, then complete environment setup before starting Phase 1.
System Requirements
- Node.js v22 or higher: Required for all tools. Verify with
node -v - pnpm: Required for the BS58 generator (
npm install -g pnpm) - npm: Required for the Hardhat project (bundled with Node.js)
- Solana CLI: Installation guide (includes
spl-token) - Git: For cloning repositories
- CCIP CLI: For cross-chain transfer testing in the final phase
Wallets:
- Solana: Phantom or Backpack for Devnet and Squads operations
- Ethereum: MetaMask for Sepolia testnet operations
Install the CCIP CLI globally:
npm install -g @chainlink/ccip-cli
ccip-cli --help
See the CCIP CLI documentation for RPC and wallet configuration.
Repository Setup
Terminal 1: CCIP Solana BS58 Generator (skip git clone if you already have the repo)
git clone https://github.com/smartcontractkit/ccip-solana-bs58-generator.git
cd ccip-solana-bs58-generator
pnpm install
Terminal 2: Smart Contract Examples (Hardhat) (skip git clone if you already have the repo)
git clone https://github.com/smartcontractkit/smart-contract-examples.git
cd smart-contract-examples/ccip/cct/hardhat
npm install
npm run compile
Environment Configuration
Solana (Terminal 1)
First, check whether your environment is already set up:
solana config get
solana address
solana balance
If the RPC URL is already https://api.devnet.solana.com, your keypair path is correct, and you have sufficient SOL, skip to Ethereum Sepolia setup below.
Otherwise, run only the steps you need:
# Set devnet (skip if config get already shows devnet)
solana config set --url https://api.devnet.solana.com
# Point to your keypair (skip if config get already shows the path you want)
solana config set --keypair ~/.config/solana/id.json
# Create a keypair only if the file does not exist yet
solana-keygen new --outfile ~/.config/solana/id.json
# Fund your wallet if balance is low
solana airdrop 3
solana balance
Ethereum Sepolia (Terminal 2)
# Required at the start of each session
npx env-enc set-pw
# Verify existing variables (skip npx env-enc set if all required vars are already configured)
npx env-enc view
# Add or update variables only if missing
npx env-enc set
Required 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:
solana airdrop 3for SOL - Ethereum Sepolia: ETH for gas and CCIP fees (Chainlink faucet or Google Cloud Faucet). LINK is optional for
--fee-token LINKon EVM sends.
Squads Multisig Setup
Step 1: Prepare 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 and fund them:
solana transfer <PHANTOM_SIGNER_ADDRESS> 0.5 --allow-unfunded-recipient
Step 2: Create your Squad
- Visit devnet.squads.so
- Connect your Solana wallet (Phantom or Backpack)
- Click Create New Squad
- Configure members and threshold (recommended: 2/3 or 3/5)
Step 3: Record the vault address
After Squad creation, open the Settings tab and copy the vault address (not the multisig address).
In Terminal 1:
# CRITICAL: Use the VAULT address, NOT the multisig address
export SOL_SQUAD_VAULT_MULTISIG="YOUR_VAULT_ADDRESS_HERE"
echo "Squads Vault Address: $SOL_SQUAD_VAULT_MULTISIG"
Step 4: Test your Squad
- 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 signers can approve and execute
See Squads Documentation for detailed setup guidance.
Token Creation Option
Tutorial Approach
| Terminal | Repository | Purpose | Commands |
|---|---|---|---|
| Terminal 1 | CCIP Solana BS58 Generator | Governance txs and pre-transfer setup | pnpm bs58 |
| Terminal 2 | Smart Contract Examples (Hardhat) | Deploy and configure EVM components | npx hardhat |
| Either | Global @chainlink/ccip-cli | Cross-chain transfer testing (final phase) | ccip-cli send |
The CCIP Solana BS58 Generator README contains command syntax, simulation behavior, and troubleshooting.
Key Implementation Notes
- Terminal 1 generates base58 transactions for Squads governance (no
--execute). Pre-transfer delegation steps use--executewith your local wallet. - Terminal 2 uses an EOA for tutorial simplicity; production EVM deployments should use multisig wallets (e.g., Safe).
- Cross-chain transfers use
@chainlink/ccip-cli: Terminal 1 for Solana → EVM, Terminal 2 for EVM → Solana. For EVM sends, prefer--wallet hardhat:<name>(Hardhat keystore) from the Hardhat directory; alternatively exportPRIVATE_KEYmanually afternpx env-enc view(Hardhat tasks load env-enc automatically, butccip-clidoes not). Provide RPCs via--rpc/--rpcs,RPC_*environment variables, or a.envfile — see CCIP CLI configuration.
base58 Transaction Execution Workflow
Transaction generation:
- CLI simulation: Each base58 transaction is simulated during generation
- Error handling: If simulation fails, do not upload the transaction to Squads
- Success: Terminal shows a transaction preview and base58 output
Squads execution:
- Propose: Import base58 output in Squads UI → Developers (left sidebar) → TX Builder → Import base58 encoded tx → Initiate Transaction
- Approve: Required threshold of signers approves
- Simulate (recommended): Preview onchain effects in Squads before execution
- Execute: Any approved signer executes after threshold is met
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 |
SOL_CCIP_* | Solana CCIP program IDs | SOL_CCIP_POOL_PROGRAM, SOL_CCIP_ROUTER, SOL_CCIP_FEE_QUOTER_PROGRAM |
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 = <redacted>
ETHEREUM_SEPOLIA_RPC_URL = <your-rpc-url>
ETHERSCAN_API_KEY = <your-api-key>
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 \
--network ethereumSepolia
# Copy the token address from the output above
2026-06-15T02:13:08.069Z info: 🚀 Deploying BurnMintERC20 to ethereumSepolia...
2026-06-15T02:13:08.070Z info: name: AEM Token, symbol: BnmAEM
2026-06-15T02:13:11.271Z info: ⏳ Deployment tx: 0x14b95ce298b558c75b32a725b6ade65081fb0cfcb3f6d8fe418ae269f7c4d55a
2026-06-15T02:13:11.272Z info: Waiting for 3 confirmation(s)...
2026-06-15T02:13:37.103Z info: ✅ Token deployed at: 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184
2026-06-15T02:13:37.554Z info: Granting mint and burn roles to 0x8C244f0B2164E6A3BED74ab429B0ebd661Bb14CA...
2026-06-15T02:13:38.674Z info: Waiting for 3 confirmation(s)...
2026-06-15T02:14:17.239Z info: ✅ Mint/Burn roles granted.
2026-06-15T02:14:17.240Z info: Verifying contract...
The contract at 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184 has already been verified on Etherscan.
If you need to verify a partially verified contract, please use the --force flag.
Explorer: https://sepolia.etherscan.io/address/0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184#code
2026-06-15T02:14:20.167Z info: ✅ Token contract verified successfully
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: 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184
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 \
--network ethereumSepolia
2026-06-15T02:15:20.985Z info: 🚀 Deploying burnMint pool on ethereumSepolia
2026-06-15T02:15:20.986Z info: Token: 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184
2026-06-15T02:15:20.986Z info: Decimals: 18
2026-06-15T02:15:20.986Z info: Allowlist: None
2026-06-15T02:15:24.267Z info: ⏳ Deployment tx: 0xc9c69358b1bea84aa2e3a1272ddfaf4acc97984d3bc789f1767aa8ebe113b203
2026-06-15T02:15:24.268Z info: Waiting for 3 confirmation(s)...
2026-06-15T02:16:02.874Z info: ✅ Token pool deployed at: 0x7115d906b67f9bc1a70ab16a8e38c603d9669749
2026-06-15T02:16:02.875Z info: Granting mint and burn roles to 0x7115d906b67f9bc1a70ab16a8e38c603d9669749 on token 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184
2026-06-15T02:16:04.278Z info: Waiting for 3 confirmation(s)...
2026-06-15T02:16:38.732Z info: ✅ Mint/Burn roles granted
2026-06-15T02:16:38.733Z info: Verifying contract...
The contract at 0x7115d906b67f9bc1a70ab16a8e38c603d9669749 has already been verified on Etherscan.
If you need to verify a partially verified contract, please use the --force flag.
Explorer: https://sepolia.etherscan.io/address/0x7115d906b67f9bc1a70ab16a8e38c603d9669749#code
2026-06-15T02:16:41.809Z info: ✅ Token pool contract verified successfully
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: 0x7115d906b67f9bc1a70ab16a8e38c603d9669749
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 ethereumSepolia
# Note: Balance can be checked in your wallet or through block explorer
echo "✅ Tokens minted successfully"
2026-06-15T02:17:35.518Z info: 🪙 Minting 1000000000000000000000 BnmAEM to 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca...
2026-06-15T02:17:37.201Z info: ⏳ Mint tx: 0x1cdc4a47c7480d1fe4b1faae8a551bc321e737f09a376630e4fa072cda608536
2026-06-15T02:17:37.201Z info: Waiting for 3 confirmation(s)...
2026-06-15T02:18:16.137Z info: ✅ Minted 1000000000000000000000 BnmAEM to 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca
2026-06-15T02:18:16.137Z info: Current balance of 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca: 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 ethereumSepolia
2026-06-15T02:19:38.212Z info: 🎯 Claiming admin for 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184 using getCCIPAdmin mode
2026-06-15T02:19:41.279Z info: ✅ Current wallet 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca is CCIP admin
2026-06-15T02:19:42.928Z info: 📤 TX sent: 0x755387fa8a9c5fde16421916cd51662aa2422851b8c424d1a005e0a2f3d67b61. Waiting for 3 confirmations...
2026-06-15T02:20:13.013Z info: ✅ Admin claimed for 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184 on ethereumSepolia (3 confirmations)
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 ethereumSepolia
2026-06-15T02:20:44.300Z info: 🔄 Accepting admin role for 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184 on ethereumSepolia...
2026-06-15T02:20:46.491Z info: Checking pending admin for 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184...
2026-06-15T02:20:46.709Z info: ✅ Current wallet 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca is the pending admin
2026-06-15T02:20:46.710Z info: Accepting admin role...
2026-06-15T02:20:48.341Z info: 📤 TX sent: 0x3e5adbac941a1653bfd393127e7d37678453d0a4355009ae0dd7b42c53291a70. Waiting for 3 confirmations...
2026-06-15T02:21:26.960Z info: ✅ Admin role accepted for 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184 on ethereumSepolia (3 confirmations)
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 ethereumSepolia
2026-06-15T02:21:54.807Z info: 🔗 Setting pool for token 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184 on ethereumSepolia...
2026-06-15T02:21:57.200Z info: 🔹 Using signer: 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca
2026-06-15T02:21:57.201Z info: Using TokenAdminRegistry: 0x95F29FEE11c5C55d26cCcf1DB6772DE953B37B82
2026-06-15T02:21:57.436Z info: Checking token configuration for 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184...
2026-06-15T02:21:57.686Z info: Token 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184 current admin: 0x8C244f0B2164E6A3BED74ab429B0ebd661Bb14CA
2026-06-15T02:21:57.687Z info: ✅ Current wallet 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca is the token administrator
2026-06-15T02:21:57.687Z info: Setting pool 0x7115d906b67f9bc1a70ab16a8e38c603d9669749 for token 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184...
2026-06-15T02:21:59.266Z info: 📤 TX sent: 0x3f8d7a1143cf1c90635a067fd93822e59881a1479536c0fe57877c145722bafd. Waiting for 3 confirmations...
2026-06-15T02:22:29.413Z info: ✅ Pool successfully set for token 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184 → 0x7115d906b67f9bc1a70ab16a8e38c603d9669749 on ethereumSepolia (3 confirmations)
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"
=== Phase 1 Complete - EVM Setup ===
✅ ETH Token: 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184
✅ ETH Pool: 0x7115d906b67f9bc1a70ab16a8e38c603d9669749
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
/.../ccip-solana-bs58-generator
Set up CCIP constants on Solana Devnet (DO NOT CHANGE THESE)
export SOL_CCIP_POOL_PROGRAM="41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB"
export SOL_CCIP_ROUTER="Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C"
export SOL_CCIP_FEE_QUOTER_PROGRAM="FeeQPGkKDeRV1MgoYfMH6L8o3KeuYjwUZrgn4LRKfjHi"
Note: You can find the Router, Fee Quoter, and self-serve pool programs addresses in the CCIP Directory.
Get your Solana wallet address for token recipient:
export SOL_WALLET_ADDRESS=$(solana address)
Verify all required variables are set:
echo "✅ Pool Program: $SOL_CCIP_POOL_PROGRAM"
echo "✅ Router Program: $SOL_CCIP_ROUTER"
echo "✅ Squad Vault (from Prerequisites): $SOL_SQUAD_VAULT_MULTISIG"
echo "✅ Recipient Wallet: $SOL_WALLET_ADDRESS"
✅ Pool Program: 41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB
✅ Router Program: Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C
✅ Squad Vault (from Prerequisites): AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB
✅ Recipient Wallet: GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN
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
INFO [2026-06-15 08:03:01.523 +0530]: 🔍 Validating create mint parameters...
INFO [2026-06-15 08:03:01.523 +0530]: 📋 Token Program: spl-token (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)
INFO [2026-06-15 08:03:01.523 +0530]: 📋 Decimals: 9
INFO [2026-06-15 08:03:01.523 +0530]: 📋 Metaplex metadata enabled
INFO [2026-06-15 08:03:01.523 +0530]: Name: "AEM"
INFO [2026-06-15 08:03:01.523 +0530]: Symbol: "CCIP-AEM"
INFO [2026-06-15 08:03:01.523 +0530]: URI: https://cyan-pleasant-anteater-613.mypinata.cloud/ipfs/bafkreieirlwjqbtzniqsgcjebzexlcspcmvd4woh3ajvf2p4fuivkenw6i
INFO [2026-06-15 08:03:01.523 +0530]: 📋 Initial supply: 5000000000000 smallest units
INFO [2026-06-15 08:03:01.523 +0530]: 📋 Recipient: GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN
INFO [2026-06-15 08:03:01.524 +0530]: ✅ Parameter validation completed
INFO [2026-06-15 08:03:01.524 +0530]: 🎨 Creating mint with Metaplex metadata...
INFO [2026-06-15 08:03:01.526 +0530]: 📋 Generated mint address: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
INFO [2026-06-15 08:03:01.526 +0530]: 📋 Mint seed: mint_1781490781524_o1hlbt
INFO [2026-06-15 08:03:01.526 +0530]: 📋 Using token program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
INFO [2026-06-15 08:03:01.982 +0530]: 📋 Generated 3 instructions for mint + metadata creation
INFO [2026-06-15 08:03:01.982 +0530]: 💰 Adding initial supply mint instructions...
INFO [2026-06-15 08:03:01.982 +0530]: 📋 Creating ATA for recipient: gKhGBvVGw62EdjfdNQFvVvvbg8CqdepTrdmSdVsEDBS
INFO [2026-06-15 08:03:01.983 +0530]: 📋 Will mint 5000000000000 smallest units to gKhGBvVGw62EdjfdNQFvVvvbg8CqdepTrdmSdVsEDBS
INFO [2026-06-15 08:03:01.983 +0530]: 🔄 Building and simulating transaction...
INFO [2026-06-15 08:03:01.983 +0530]: 📋 Metadata PDA: 7ndwZpSAP4BRYY42Aph3knmRfUxdJbKAAm7CnDcurGp5
🎯 COPY TRANSACTION DATA BELOW:
Ued1t9JWnpB6ojDXJk4iKCycwPLpRz88njSywTd6n3QcSYuN1DwZAuQU48J9jxKvCKxJWgsHahfcjCggoVpRjp7n8YFAyWaeD78zNJHTWxXvmz8zYHDvKYpoFJ7boSxP6vBF9UDsX29rBQ4BNktjtdP8xR4pYKedrd9h6whuP2khWXno77JfRkd13Q21Ux3Wkq7qoXCoDfvZqgticxALcqfJQAjJNysMHh5qbpZzSvB62pXuGYT5bmyiX1tCDnCTAsCxE2YCAMnrPrJZWffDWxCUHarWuGNeWu9hsdgGbPe8vpeqQgmkJJcVygXD3BVwmqNroBKybitYX8ehVYc4pPpHFCFsRen99pb3PBAVwbrkqSmuCWhUmz5Wfwsi3oFc3kBRTtUfnMGNnKtaDUx6J92ztfoyLoAE3UTv6TbJDJZEQvJaUyfPNdXojYDM35c6Apbkiy5KtVv9VhoJzD3SuHZBKHy1onRw4JATTqCtGbnRi4L4ksjchPiUc9u7KvwVe8F9u3MVNNX2AeDoNUb4VU7g5prXnNbXN8AWxXdRsjV734NYroCELhVbgX5sDnMx3EZZEiutAvKDdxvLhfQ1swomFCm6YP9gbyQrPsbqKeovUzECj8Ka6AG1JCCXSQGF6KqwAJBQt2LbZdmzvbPBbbyRDSy8dbWEfyFrbhCwzNADs8A9HZdVcQpjgWXwj7DkXF5tnWTD5g1TZ1dhHdx5WcQtgT96kzed6zQo2BbW44VJWNHpPXaFHJsxEJEWRehkrAxsrGLSMYfn2jsiebewoduXFKHV9KeNe5haBYPji1VBNbkenZsGmbeXFbujKfXNZ5iLBR3PvSKo8hmTm8xhig2QjM6XyvYeZbQiygEYCicZFKbTNvfgCJaWJDdk7ePwtKkseajSuYeGGG8ATn1KkBX83caNPgbNejiA2J9sW18MphqnLu2ffymDJhH71R2eNgHfg6TH4K9BGytaNXCfHBRGqrubZEcABnLuUejMrUuKxPTwDXu4LTP8tveJFhQREn4RZUxkWRXXA89V2qE5Fm7MwmVNF5Df93s6gVw2f1CG61Gvk9uATKRxgRJWmNrW26pRgjNKUrtWKDB1y
────────────────────────────────────────────────────────────────────────────────
INFO [2026-06-15 08:03:02.145 +0530]: Transaction built successfully
instructionName: "spl-token.create_mint_with_metaplex"
transactionSize: "810 bytes"
base58Length: "1105 characters"
hexLength: "1620 characters"
accountCount: 2
signerCount: 1
computeUnits: 59159
INFO [2026-06-15 08:03:02.145 +0530]: Completed buildTransaction (spl-token.create_mint_with_metaplex)
durationMs: 162
INFO [2026-06-15 08:03:02.145 +0530]:
INFO [2026-06-15 08:03:02.145 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 08:03:02.145 +0530]:
INFO [2026-06-15 08:03:02.145 +0530]: 📋 Transaction Details:
INFO [2026-06-15 08:03:02.145 +0530]: Instruction: spl-token.create_mint_with_metaplex
INFO [2026-06-15 08:03:02.145 +0530]: Size: 810 bytes
INFO [2026-06-15 08:03:02.145 +0530]: Base58 length: 1105 characters
INFO [2026-06-15 08:03:02.152 +0530]: Compute units: 59,159
INFO [2026-06-15 08:03:02.152 +0530]: Generated: 2026-06-15T02:33:02.145Z
INFO [2026-06-15 08:03:02.152 +0530]:
INFO [2026-06-15 08:03:02.152 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 08:03:02.152 +0530]:
INFO [2026-06-15 08:03:02.153 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 08:03:02.153 +0530]:
INFO [2026-06-15 08:03:02.153 +0530]: 📊 Account Information:
INFO [2026-06-15 08:03:02.153 +0530]: Total accounts: 2
INFO [2026-06-15 08:03:02.153 +0530]: 1. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 08:03:02.153 +0530]: 2. hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub (writable)
INFO [2026-06-15 08:03:02.153 +0530]:
INFO [2026-06-15 08:03:02.153 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 08:03:02.153 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 08:03:02.153 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 08:03:02.153 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 08:03:02.153 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 08:03:02.153 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 08:03:02.153 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 08:03:02.153 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 08:03:02.153 +0530]:
INFO [2026-06-15 08:03:02.153 +0530]: 🔍 Important Notes:
INFO [2026-06-15 08:03:02.153 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 08:03:02.153 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 08:03:02.153 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 08:03:02.153 +0530]: • Estimated compute units: 59,159
INFO [2026-06-15 08:03:02.153 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 08:03:02.153 +0530]:
INFO [2026-06-15 08:03:02.153 +0530]: ✅ Transaction simulation completed
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"
✅ Token Mint: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
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 $SOL_CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG
🔄 Generating initialize (pool) transaction...
🔄 Building and simulating transaction...
🎯 COPY TRANSACTION DATA BELOW:
FBAv1ygQ7d4A9pXavcpnpX3bSYzxYrqx2KhfKhBPUzFJr5rqj2d7Uow4onYpUkEChmVKXh6MiCWJmnYhSUxYtz8sJPrgyYLpjECLeYahtHYo49SM8MvGfdzdaErj9PV2jCtasFegtw5NXCcYhdZzotFruk6apSpuDeaefpJQ69MsgEP2w4aYqQxbFY57FwYjhtVyBMBBALn2EkBqSPfJJG9fix3uTAL5Ho51TbGYCn8UHvDWZaqVbBzxRNxwbE5Kmdm3rPebhGSZB6TQ1Tgw67zocNPtPyryM8tLqog2jWD3UgTqxBEBx9EVB17xjXYKdXFDUteWyBRrvhRiX81hGq5FAZp5FUHYceZ5f2A56G7GKLjA8KvtPTMic9fi
────────────────────────────────────────────────────────────────────────────────
✅ Transaction simulation completed
INFO [2026-06-15 08:17:08.736 +0530]: Transaction built successfully
instructionName: "burnmint-token-pool.initialize"
transactionSize: "279 bytes"
base58Length: "380 characters"
hexLength: "558 characters"
accountCount: 7
signerCount: 1
computeUnits: 31818
INFO [2026-06-15 08:17:08.736 +0530]: Completed buildTransaction (burnmint-token-pool.initialize)
durationMs: 361
INFO [2026-06-15 08:17:08.736 +0530]:
INFO [2026-06-15 08:17:08.736 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 08:17:08.736 +0530]:
INFO [2026-06-15 08:17:08.737 +0530]: 📋 Transaction Details:
INFO [2026-06-15 08:17:08.737 +0530]: Instruction: burnmint-token-pool.initialize
INFO [2026-06-15 08:17:08.737 +0530]: Size: 279 bytes
INFO [2026-06-15 08:17:08.737 +0530]: Base58 length: 380 characters
INFO [2026-06-15 08:17:08.748 +0530]: Compute units: 31,818
INFO [2026-06-15 08:17:08.748 +0530]: Generated: 2026-06-15T02:47:08.735Z
INFO [2026-06-15 08:17:08.748 +0530]:
INFO [2026-06-15 08:17:08.748 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 08:17:08.748 +0530]:
INFO [2026-06-15 08:17:08.748 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 08:17:08.748 +0530]:
INFO [2026-06-15 08:17:08.748 +0530]: 📊 Account Information:
INFO [2026-06-15 08:17:08.748 +0530]: Total accounts: 7
INFO [2026-06-15 08:17:08.748 +0530]: 1. 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu (writable)
INFO [2026-06-15 08:17:08.748 +0530]: 2. hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub (read-only)
INFO [2026-06-15 08:17:08.748 +0530]: 3. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 08:17:08.748 +0530]: 4. 11111111111111111111111111111111 (read-only)
INFO [2026-06-15 08:17:08.748 +0530]: 5. 41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB (read-only)
INFO [2026-06-15 08:17:08.748 +0530]: 6. 4sVSCJqG9ZKEvnpN38qTzb7Kc8QdHakBgB87HN3FYRaz (read-only)
INFO [2026-06-15 08:17:08.748 +0530]: 7. E4Bsi43kX3iwXAFia2ebm1mS5Xkmmdv3minZDnfo7Zzf (read-only)
INFO [2026-06-15 08:17:08.748 +0530]:
INFO [2026-06-15 08:17:08.748 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 08:17:08.748 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 08:17:08.748 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 08:17:08.748 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 08:17:08.748 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 08:17:08.748 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 08:17:08.748 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 08:17:08.748 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 08:17:08.748 +0530]:
INFO [2026-06-15 08:17:08.748 +0530]: 🔍 Important Notes:
INFO [2026-06-15 08:17:08.748 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 08:17:08.748 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 08:17:08.748 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 08:17:08.748 +0530]: • Estimated compute units: 31,818
INFO [2026-06-15 08:17:08.748 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 08:17:08.748 +0530]:
Account Breakdown from the Transaction (Example):
| Account | Address | Purpose |
|---|---|---|
| #1 | 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu | Pool State PDA - Your main pool configuration |
| #2 | hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub | Token Mint (your token) |
| #3 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | Authority (your Squad vault) |
| #4 | 11111111111111111111111111111111 | System Program |
| #5 | 41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB | CCIP Pool Program |
| #6 | 4sVSCJqG9ZKEvnpN38qTzb7Kc8QdHakBgB87HN3FYRaz | Program Data PDA |
| #7 | E4Bsi43kX3iwXAFia2ebm1mS5Xkmmdv3minZDnfo7Zzf | 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="<YOUR_ACTUAL_POOL_STATE_ADDRESS>"
Verify the pool address:
echo "✅ Pool Address: $SOL_POOL_ADDRESS"
✅ Pool Address: 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu
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 "$SOL_CCIP_POOL_PROGRAM" \
--mint "$SOL_TOKEN_MINT"
🔍 Deriving burnmint-token-pool accounts...
INFO [2026-06-15 08:22:10.837 +0530]: Starting deriveAccounts command
command: "derive-accounts"
programType: "burnmint-token-pool"
programId: "41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB"
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
globalOptions: {
"environment": "devnet",
"resolvedRpcUrl": "https://api.devnet.solana.com"
}
📊 Derived Accounts:
1. Pool State PDA
Address: 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu
Seeds: ["ccip_tokenpool_config", mint]
Bump: 254
Description: Main pool configuration account (created by initialize-pool)
2. Pool Signer PDA
Address: 62So4PhmWWzMpVXKzsCXdNUfrrB4jGXTVda9BzS6HTeo
Seeds: ["ccip_tokenpool_signer", mint]
Bump: 253
Description: 🎯 CRITICAL: Autonomous mint/burn authority for cross-chain operations
3. Global Config PDA
Address: E4Bsi43kX3iwXAFia2ebm1mS5Xkmmdv3minZDnfo7Zzf
Seeds: ["config"]
Bump: 255
Description: Program-wide configuration settings
4. Pool Token ATA
Address: 2Lzp4uRF6N2x65aMpKqFrajFukAbTCtQcG8thVgqcsEh
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: 62So4PhmWWzMpVXKzsCXdNUfrrB4jGXTVda9BzS6HTeo
↳ This address signs all mint/burn transactions autonomously
INFO [2026-06-15 08:22:11.104 +0530]: Detected SPL Token v1
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
INFO [2026-06-15 08:22:11.106 +0530]: ✅ 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: 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu
Pool Signer PDA: 62So4PhmWWzMpVXKzsCXdNUfrrB4jGXTVda9BzS6HTeo
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 $SOL_CCIP_ROUTER \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--token-admin-registry-admin $SOL_SQUAD_VAULT_MULTISIG
🔄 Generating owner_propose_administrator transaction...
🔄 Building and simulating transaction...
🎯 COPY TRANSACTION DATA BELOW:
jCi2zBJS8zFbgd7FMisv8MxZKac472KQX9mA3dgncufisCZ1X415QuNpkCb25EkyBr2qj43VXPAZVZToFvsmDxdv3kUoVAXBVRAnVNtcWKWc2Y4qezTSjTD7xsLugoZ6mXe9PSegYhY9M8Wkk8Mag3DBUrkSzkha1NoWk26qBjNWYMmNvDoQSv3ev1W8rEK1cmK7aSEAYSgUy1LnB1f1YCUwEQ9A4SdJAvJoEHHugAcK2F8NKyYwe2TbPfLWbsdRJVeYNPJSEv24Ddm8DyFP2tU2hkXbqbUUVen5RFKHS8mghUWScAbfomYtVLqfm5tW3ytz43SA3vrd1CKfL1ad1NvjxY4wiQ81Jkc5chtb2jjBD5U6d9vL1ZgeP
────────────────────────────────────────────────────────────────────────────────
✅ Transaction simulation completed
INFO [2026-06-15 08:32:10.160 +0530]: Transaction built successfully
instructionName: "router.owner_propose_administrator"
transactionSize: "277 bytes"
base58Length: "377 characters"
hexLength: "554 characters"
accountCount: 5
signerCount: 1
computeUnits: 19731
INFO [2026-06-15 08:32:10.160 +0530]: Completed buildTransaction (router.owner_propose_administrator)
durationMs: 400
INFO [2026-06-15 08:32:10.160 +0530]:
INFO [2026-06-15 08:32:10.160 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 08:32:10.160 +0530]:
INFO [2026-06-15 08:32:10.160 +0530]: 📋 Transaction Details:
INFO [2026-06-15 08:32:10.160 +0530]: Instruction: router.owner_propose_administrator
INFO [2026-06-15 08:32:10.160 +0530]: Size: 277 bytes
INFO [2026-06-15 08:32:10.160 +0530]: Base58 length: 377 characters
INFO [2026-06-15 08:32:10.171 +0530]: Compute units: 19,731
INFO [2026-06-15 08:32:10.171 +0530]: Generated: 2026-06-15T03:02:10.159Z
INFO [2026-06-15 08:32:10.171 +0530]:
INFO [2026-06-15 08:32:10.171 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 08:32:10.171 +0530]:
INFO [2026-06-15 08:32:10.172 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 08:32:10.172 +0530]:
INFO [2026-06-15 08:32:10.172 +0530]: 📊 Account Information:
INFO [2026-06-15 08:32:10.172 +0530]: Total accounts: 5
INFO [2026-06-15 08:32:10.172 +0530]: 1. 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 (read-only)
INFO [2026-06-15 08:32:10.172 +0530]: 2. 6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3 (writable)
INFO [2026-06-15 08:32:10.172 +0530]: 3. hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub (read-only)
INFO [2026-06-15 08:32:10.172 +0530]: 4. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 08:32:10.172 +0530]: 5. 11111111111111111111111111111111 (read-only)
INFO [2026-06-15 08:32:10.172 +0530]:
INFO [2026-06-15 08:32:10.172 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 08:32:10.172 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 08:32:10.172 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 08:32:10.172 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 08:32:10.172 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 08:32:10.172 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 08:32:10.172 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 08:32:10.172 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 08:32:10.172 +0530]:
INFO [2026-06-15 08:32:10.172 +0530]: 🔍 Important Notes:
INFO [2026-06-15 08:32:10.172 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 08:32:10.172 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 08:32:10.172 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 08:32:10.172 +0530]: • Estimated compute units: 19,731
INFO [2026-06-15 08:32:10.172 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 08:32:10.172 +0530]:
Account Breakdown from the Transaction (Example):
| Account | Address | Description |
|---|---|---|
| #1 | 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 | Router Config PDA (read-only) |
| #2 | 6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3 | 🎯 Token Admin Registry PDA - Gets created/updated for your token |
| #3 | hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub | Token Mint (your token) |
| #4 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | 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 $SOL_CCIP_ROUTER \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG
🔄 Generating accept_admin_role_token_admin_registry transaction...
🔄 Building and simulating transaction...
🎯 COPY TRANSACTION DATA BELOW:
2sM9hjkg4Y6d1pD6Zqca74vGeRSLBrpBnGsxsjPpmpcutTVk3n4e8Wd7S4qBEfzAkxoCdyNBbdMuatpJq4yTCQM3HfY7bz2oR4bc4KQHHS9AJo6Ct8A615FR1vZJS3WUvk6miYRUFDkEJQYybC8p9HpCMVejMyCaXaREaEujJCcoJbRhSEoS7TVsjetAoGiJxdNaDTZNsXD9scmf8n8jWSf7ixwCYRmg6d7PaFBTmBYuNMz73bc3RFjspc7eKAn5FCh8zktHuzKTznsETzdCsMjaS6HFwe7js
────────────────────────────────────────────────────────────────────────────────
✅ Transaction simulation completed
INFO [2026-06-15 08:36:38.368 +0530]: Transaction built successfully
instructionName: "router.accept_admin_role_token_admin_registry"
transactionSize: "212 bytes"
base58Length: "289 characters"
hexLength: "424 characters"
accountCount: 4
signerCount: 1
computeUnits: 15454
INFO [2026-06-15 08:36:38.368 +0530]: Completed buildTransaction (router.accept_admin_role_token_admin_registry)
durationMs: 455
INFO [2026-06-15 08:36:38.368 +0530]:
INFO [2026-06-15 08:36:38.368 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 08:36:38.368 +0530]:
INFO [2026-06-15 08:36:38.368 +0530]: 📋 Transaction Details:
INFO [2026-06-15 08:36:38.368 +0530]: Instruction: router.accept_admin_role_token_admin_registry
INFO [2026-06-15 08:36:38.368 +0530]: Size: 212 bytes
INFO [2026-06-15 08:36:38.368 +0530]: Base58 length: 289 characters
INFO [2026-06-15 08:36:38.379 +0530]: Compute units: 15,454
INFO [2026-06-15 08:36:38.379 +0530]: Generated: 2026-06-15T03:06:38.367Z
INFO [2026-06-15 08:36:38.379 +0530]:
INFO [2026-06-15 08:36:38.379 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 08:36:38.379 +0530]:
INFO [2026-06-15 08:36:38.380 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 08:36:38.380 +0530]:
INFO [2026-06-15 08:36:38.380 +0530]: 📊 Account Information:
INFO [2026-06-15 08:36:38.380 +0530]: Total accounts: 4
INFO [2026-06-15 08:36:38.380 +0530]: 1. 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 (read-only)
INFO [2026-06-15 08:36:38.380 +0530]: 2. 6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3 (writable)
INFO [2026-06-15 08:36:38.380 +0530]: 3. hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub (read-only)
INFO [2026-06-15 08:36:38.380 +0530]: 4. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 08:36:38.380 +0530]:
INFO [2026-06-15 08:36:38.380 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 08:36:38.380 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 08:36:38.380 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 08:36:38.380 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 08:36:38.380 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 08:36:38.380 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 08:36:38.380 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 08:36:38.380 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 08:36:38.380 +0530]:
INFO [2026-06-15 08:36:38.380 +0530]: 🔍 Important Notes:
INFO [2026-06-15 08:36:38.380 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 08:36:38.380 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 08:36:38.380 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 08:36:38.380 +0530]: • Estimated compute units: 15,454
INFO [2026-06-15 08:36:38.380 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 08:36:38.380 +0530]:
Account Breakdown from the Transaction (Example):
| Account | Address | Description |
|---|---|---|
| #1 | 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 | Router Config PDA (read-only) |
| #2 | 6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3 | 🎯 Token Admin Registry PDA - Updates status to "active" |
| #3 | hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub | Token Mint (your token) |
| #4 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | 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
📮 Derived SPL Token Multisig Address: 3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX
💡 Address derived from: authority + sha256("production-multisig" + mint).hex().slice(0,32) + tokenProgram
INFO [2026-06-15 08:40:27.414 +0530]: Detected SPL Token v1
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
INFO [2026-06-15 08:40:27.506 +0530]: 🔄 Building and simulating transaction...
🎯 COPY TRANSACTION DATA BELOW:
WCDiQnLJH3zA77eqJ2auuEMCa1NJz9woANE14hbg1zEC7jXMQoLn1QGwjeQtanXX6xBrdytPjFgErnhViNWSutu5iFuZw8qj26ep9KVcd2CwhcmPqNvFX4wHRZUNe1m3JWey2gRDmNDHY4DwPvHcHauXMoyNHipUPctH3X3yi9R4sdVuhAwUNaGUp41teGHUDSXY3DQGnMH7VsLDm5eeNXDHzP2N8Wg6ZhG7uPbCzmY5y3h6yw5PrLgBNNyr4jkLGQv1B4vQwBzfZp5v27DYtYKT1eD3zbFn3nNAD6FxAc3aLok1FhPNnjLWJLVS75JgwkSuiyGMUwnuBuyqvTrF7PTSUooF8PatnSP3YQwDxgiV89QCTpvcT29dqDVvjmw78vLz8YBWkg14JKKznLc6roDmSqq6yvYG192krqRNadFTfht43uP2fMSg56MEY1eHsfGUtKCRyHeknQxAGY63DjRoFdd3BvsX839Azrcu1PcPr5oWmh2x
────────────────────────────────────────────────────────────────────────────────
INFO [2026-06-15 08:40:27.693 +0530]: Transaction built successfully
instructionName: "spl.create_multisig"
transactionSize: "367 bytes"
base58Length: "500 characters"
hexLength: "734 characters"
accountCount: 2
signerCount: 1
computeUnits: 317
INFO [2026-06-15 08:40:27.693 +0530]: Completed buildTransaction (spl.create_multisig)
durationMs: 186
INFO [2026-06-15 08:40:27.693 +0530]:
INFO [2026-06-15 08:40:27.693 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 08:40:27.693 +0530]:
INFO [2026-06-15 08:40:27.693 +0530]: 📋 Transaction Details:
INFO [2026-06-15 08:40:27.693 +0530]: Instruction: spl.create_multisig
INFO [2026-06-15 08:40:27.693 +0530]: Size: 367 bytes
INFO [2026-06-15 08:40:27.693 +0530]: Base58 length: 500 characters
INFO [2026-06-15 08:40:27.706 +0530]: Compute units: 317
INFO [2026-06-15 08:40:27.706 +0530]: Generated: 2026-06-15T03:10:27.693Z
INFO [2026-06-15 08:40:27.706 +0530]:
INFO [2026-06-15 08:40:27.706 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 08:40:27.706 +0530]:
INFO [2026-06-15 08:40:27.706 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 08:40:27.706 +0530]:
INFO [2026-06-15 08:40:27.706 +0530]: 📊 Account Information:
INFO [2026-06-15 08:40:27.706 +0530]: Total accounts: 2
INFO [2026-06-15 08:40:27.706 +0530]: 1. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 08:40:27.706 +0530]: 2. 3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX (writable)
INFO [2026-06-15 08:40:27.706 +0530]:
INFO [2026-06-15 08:40:27.706 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 08:40:27.706 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 08:40:27.706 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 08:40:27.706 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 08:40:27.706 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 08:40:27.706 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 08:40:27.706 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 08:40:27.706 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 08:40:27.706 +0530]:
INFO [2026-06-15 08:40:27.706 +0530]: 🔍 Important Notes:
INFO [2026-06-15 08:40:27.706 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 08:40:27.706 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 08:40:27.706 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 08:40:27.706 +0530]: • Estimated compute units: 317
INFO [2026-06-15 08:40:27.706 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 08:40:27.706 +0530]:
INFO [2026-06-15 08:40:27.706 +0530]: ✅ Transaction simulation completed
Account Breakdown from the Transaction (Example):
| Account | Address | Description |
|---|---|---|
| #1 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | Payer/Authority (your Squad vault) |
| #2 | 3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX | 🎯 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:
3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX - 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
After execution, 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: 3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX
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
SetAuthorityinstruction 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
🎯 COPY TRANSACTION DATA BELOW:
ebWdWNFhuGinVAQnt9sMpWPabw6CwHKXVERVZQCg48S2yWseshdn366QFPpZvpg8pF9Bq91HzHbMoZgBV9kqJ6s6w6TCRAZxFmjnj4DQxAUomo3xs1ejMZ1AFHgXnBQi5srP9DWFXgbWoakvx4DRD19HJqjUG72TGQBxxnhz1JP45ksgcSrWYKm5GNAyHQomPX45JCopta3Bd3X8sGdFT9dYn6AFmeEkRCZ2yPdFphs
────────────────────────────────────────────────────────────────────────────────
INFO [2026-06-15 08:46:23.823 +0530]: Detected SPL Token v1
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
INFO [2026-06-15 08:46:23.824 +0530]: 🔄 Building and simulating transaction...
INFO [2026-06-15 08:46:23.980 +0530]: Transaction built successfully
instructionName: "spl.transfer_mint_authority"
transactionSize: "173 bytes"
base58Length: "235 characters"
hexLength: "346 characters"
accountCount: 2
signerCount: 1
computeUnits: 125
INFO [2026-06-15 08:46:23.980 +0530]: Completed buildTransaction (spl.transfer_mint_authority)
durationMs: 156
INFO [2026-06-15 08:46:23.980 +0530]:
INFO [2026-06-15 08:46:23.980 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 08:46:23.980 +0530]:
INFO [2026-06-15 08:46:23.980 +0530]: 📋 Transaction Details:
INFO [2026-06-15 08:46:23.980 +0530]: Instruction: spl.transfer_mint_authority
INFO [2026-06-15 08:46:23.980 +0530]: Size: 173 bytes
INFO [2026-06-15 08:46:23.980 +0530]: Base58 length: 235 characters
INFO [2026-06-15 08:46:23.993 +0530]: Compute units: 125
INFO [2026-06-15 08:46:23.993 +0530]: Generated: 2026-06-15T03:16:23.979Z
INFO [2026-06-15 08:46:23.993 +0530]:
INFO [2026-06-15 08:46:23.993 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 08:46:23.993 +0530]:
INFO [2026-06-15 08:46:23.993 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 08:46:23.993 +0530]:
INFO [2026-06-15 08:46:23.993 +0530]: 📊 Account Information:
INFO [2026-06-15 08:46:23.993 +0530]: Total accounts: 2
INFO [2026-06-15 08:46:23.993 +0530]: 1. hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub (writable)
INFO [2026-06-15 08:46:23.993 +0530]: 2. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer)
INFO [2026-06-15 08:46:23.993 +0530]:
INFO [2026-06-15 08:46:23.993 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 08:46:23.993 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 08:46:23.993 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 08:46:23.993 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 08:46:23.993 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 08:46:23.993 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 08:46:23.993 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 08:46:23.993 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 08:46:23.993 +0530]:
INFO [2026-06-15 08:46:23.993 +0530]: 🔍 Important Notes:
INFO [2026-06-15 08:46:23.993 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 08:46:23.993 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 08:46:23.993 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 08:46:23.993 +0530]: • Estimated compute units: 125
INFO [2026-06-15 08:46:23.993 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 08:46:23.993 +0530]:
INFO [2026-06-15 08:46:23.993 +0530]: ✅ Transaction simulation completed
Account Breakdown from the Transaction (Example):
| Account | Address | Description |
|---|---|---|
| #1 | hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub | Token Mint (writable - authority updated) |
| #2 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | Current Authority (signer - Squad vault) |
Key Details:
- Current Authority:
AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB(Squad vault) - New Authority:
3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX(SPL Token Multisig) - Token Mint:
hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub(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\"]"
INFO [2026-06-15 08:52:03.242 +0530]: Detected SPL Token v1
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
INFO [2026-06-15 08:52:03.319 +0530]: 🔄 Building and simulating transaction...
🎯 COPY TRANSACTION DATA BELOW:
9FDWs7rMsQrSvtR1sVHAhsnEdSpxvFrJrsQR972U6ki1he4BAiYBEZLRct47owtf91sWBGUsNwqEGR6cfDgYAkUfx9MTAUffrLwcWPoNX9Emc63eFdjjaSxGhHjD1HJmeX2r55F4huroJhsYiYSC1xaQvkPRUaXwZUHQg2FL3RgqDWaVg9HBHKnhoDwmbMcp21a5zAEL3M9x1K6K6edUjE77katfvNPi5asX19Acd1SQoZrCmXWUrefYKdfyS6zsNR7dJNVp62wGrq218fsthrk24tYrZkQ38T
────────────────────────────────────────────────────────────────────────────────
INFO [2026-06-15 08:52:03.475 +0530]: Transaction built successfully
instructionName: "spl.mint"
transactionSize: "213 bytes"
base58Length: "290 characters"
hexLength: "426 characters"
accountCount: 4
signerCount: 1
computeUnits: 252
INFO [2026-06-15 08:52:03.475 +0530]: Completed buildTransaction (spl.mint)
durationMs: 156
INFO [2026-06-15 08:52:03.475 +0530]:
INFO [2026-06-15 08:52:03.475 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 08:52:03.475 +0530]:
INFO [2026-06-15 08:52:03.475 +0530]: 📋 Transaction Details:
INFO [2026-06-15 08:52:03.475 +0530]: Instruction: spl.mint
INFO [2026-06-15 08:52:03.475 +0530]: Size: 213 bytes
INFO [2026-06-15 08:52:03.475 +0530]: Base58 length: 290 characters
INFO [2026-06-15 08:52:03.488 +0530]: Compute units: 252
INFO [2026-06-15 08:52:03.488 +0530]: Generated: 2026-06-15T03:22:03.474Z
INFO [2026-06-15 08:52:03.488 +0530]:
INFO [2026-06-15 08:52:03.488 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 08:52:03.488 +0530]:
INFO [2026-06-15 08:52:03.488 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 08:52:03.488 +0530]:
INFO [2026-06-15 08:52:03.488 +0530]: 📊 Account Information:
INFO [2026-06-15 08:52:03.488 +0530]: Total accounts: 4
INFO [2026-06-15 08:52:03.488 +0530]: 1. hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub (writable)
INFO [2026-06-15 08:52:03.488 +0530]: 2. gKhGBvVGw62EdjfdNQFvVvvbg8CqdepTrdmSdVsEDBS (writable)
INFO [2026-06-15 08:52:03.488 +0530]: 3. 3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX (read-only)
INFO [2026-06-15 08:52:03.488 +0530]: 4. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer)
INFO [2026-06-15 08:52:03.488 +0530]:
INFO [2026-06-15 08:52:03.488 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 08:52:03.488 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 08:52:03.488 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 08:52:03.488 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 08:52:03.488 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 08:52:03.488 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 08:52:03.488 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 08:52:03.488 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 08:52:03.488 +0530]:
INFO [2026-06-15 08:52:03.488 +0530]: 🔍 Important Notes:
INFO [2026-06-15 08:52:03.488 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 08:52:03.488 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 08:52:03.488 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 08:52:03.488 +0530]: • Estimated compute units: 252
INFO [2026-06-15 08:52:03.488 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 08:52:03.488 +0530]:
INFO [2026-06-15 08:52:03.488 +0530]: ✅ Transaction simulation completed
Account Breakdown from the Transaction (Example):
| Account | Address | Description |
|---|---|---|
| #1 | hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub | Token Mint (writable - supply updated) |
| #2 | gKhGBvVGw62EdjfdNQFvVvvbg8CqdepTrdmSdVsEDBS | Recipient's ATA (writable - receives tokens) |
| #3 | 3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX | SPL Token Multisig (read-only - mint authority) |
| #4 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | 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 (
GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN) - Mint Authority: SPL Token Multisig (
3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX) - Multisig Signer: Squad vault (
AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB) - 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 SOL_CCIP_POOL_PROGRAM="$SOL_CCIP_POOL_PROGRAM"
export SOL_CCIP_ROUTER="$SOL_CCIP_ROUTER"
export SOL_CCIP_FEE_QUOTER_PROGRAM="$SOL_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: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
✅ Pool Address: 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu
✅ Pool Signer PDA: 62So4PhmWWzMpVXKzsCXdNUfrrB4jGXTVda9BzS6HTeo
✅ Squads Multisig: AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB
✅ SPL Multisig: 3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX
✅ Wallet Address: GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN
Phase 3: Solana Cross-Chain Setup
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: 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184
$ echo "✅ ETH Pool: $ETH_POOL_ADDRESS"
✅ ETH Pool: 0x7115d906b67f9bc1a70ab16a8e38c603d9669749
$ 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 $SOL_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"
🔄 Generating initChainRemoteConfig transaction...
RPC URL: https://api.devnet.solana.com
Program ID: 41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB
Mint: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
Authority: AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB
Remote Chain Selector: 16015286601757825753
Pool Addresses: 0 addresses (must be empty at init)
Token Address: 8b7ce78b89f05eaec2e803e638ff5b0f6f009184
Decimals: 18
⚙️ Building transaction instruction...
✅ Instruction built successfully
🔄 Building and simulating transaction...
INFO [2026-06-15 09:08:54.451 +0530]: Starting initChainRemoteConfig command
command: "burnmint-token-pool.init-chain-remote-config"
programId: "41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB"
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
authority: "AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB"
remoteChainSelector: "16015286601757825753"
poolAddresses: "[]"
tokenAddress: "0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184"
decimals: "18"
globalOptions: {
"environment": "devnet",
"resolvedRpcUrl": "https://api.devnet.solana.com"
}
🎯 COPY TRANSACTION DATA BELOW:
Q14g5jbgtmANfZSMSbAWmxrcrdnGPxD1uBo8aVDcQnQx6TTzqxMFyh9TVRBWDHZUR4VfubX8rAFgCp7c8Eo3MwiZjeA4V1ouP7VwhRmmh8N16BVLWQiQx1sGgTK6LmjdUrNfoivsGxgY9LemmbW6HDH6abBM4efhBsfoGZvzFVQ5L3jjcvU1uzC93MwM3WQDtoDQGpkjYQkoEFon99L3KARFyCHhAVdFRdvDXrR9foWo8Rsod4Ap8vimqNWRCcPyQmh3mgeNPHUS1pqLunparTxbfpQqmhfgqd43J7wsbyCU7cDfg78pZZDRrDmwGkrUVfrKLYvBZCKdFrmWQnuKLJ1EHKqhgd4B7DcoErYvr2L5c1vBGL7SADdVrSqdwrQ9WDfTUuKP5TDt6Zf
────────────────────────────────────────────────────────────────────────────────
✅ Transaction simulation completed
INFO [2026-06-15 09:08:54.905 +0530]: Transaction built successfully
instructionName: "initChainRemoteConfig"
transactionSize: "293 bytes"
base58Length: "399 characters"
hexLength: "586 characters"
accountCount: 4
signerCount: 1
computeUnits: 19402
INFO [2026-06-15 09:08:54.905 +0530]: Completed buildTransaction (initChainRemoteConfig)
durationMs: 450
INFO [2026-06-15 09:08:54.906 +0530]:
INFO [2026-06-15 09:08:54.906 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 09:08:54.906 +0530]:
INFO [2026-06-15 09:08:54.906 +0530]: 📋 Transaction Details:
INFO [2026-06-15 09:08:54.906 +0530]: Instruction: initChainRemoteConfig
INFO [2026-06-15 09:08:54.906 +0530]: Size: 293 bytes
INFO [2026-06-15 09:08:54.906 +0530]: Base58 length: 399 characters
INFO [2026-06-15 09:08:54.916 +0530]: Compute units: 19,402
INFO [2026-06-15 09:08:54.916 +0530]: Generated: 2026-06-15T03:38:54.905Z
INFO [2026-06-15 09:08:54.916 +0530]:
INFO [2026-06-15 09:08:54.917 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 09:08:54.917 +0530]:
INFO [2026-06-15 09:08:54.917 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 09:08:54.917 +0530]:
INFO [2026-06-15 09:08:54.917 +0530]: 📊 Account Information:
INFO [2026-06-15 09:08:54.917 +0530]: Total accounts: 4
INFO [2026-06-15 09:08:54.917 +0530]: 1. 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu (read-only)
INFO [2026-06-15 09:08:54.917 +0530]: 2. A3TEVLHYCbBzncbmVtiZAsK9R281n9oe4DZwMZyKy5p2 (writable)
INFO [2026-06-15 09:08:54.917 +0530]: 3. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 09:08:54.917 +0530]: 4. 11111111111111111111111111111111 (read-only)
INFO [2026-06-15 09:08:54.917 +0530]:
INFO [2026-06-15 09:08:54.917 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 09:08:54.917 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 09:08:54.917 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 09:08:54.917 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 09:08:54.917 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 09:08:54.917 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 09:08:54.917 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 09:08:54.917 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 09:08:54.917 +0530]:
INFO [2026-06-15 09:08:54.917 +0530]: 🔍 Important Notes:
INFO [2026-06-15 09:08:54.917 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 09:08:54.917 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 09:08:54.917 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 09:08:54.917 +0530]: • Estimated compute units: 19,402
INFO [2026-06-15 09:08:54.917 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 09:08:54.917 +0530]:
INFO [2026-06-15 09:08:54.917 +0530]: initChainRemoteConfig command completed successfully
command: "burnmint-token-pool.init-chain-remote-config"
transactionSize: "293 bytes"
computeUnits: 19402
Account Breakdown from the Transaction (Example):
| Account | Address | Description |
|---|---|---|
| #1 | 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu | Pool State PDA (read-only - validation) |
| #2 | A3TEVLHYCbBzncbmVtiZAsK9R281n9oe4DZwMZyKy5p2 | Chain Remote Config PDA (writable - created) |
| #3 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | 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
0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184 - 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 $SOL_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"
🔄 Generating editChainRemoteConfig transaction...
RPC URL: https://api.devnet.solana.com
Program ID: 41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB
Mint: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
Authority: AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB
Remote Chain Selector: 16015286601757825753
Pool Addresses: 1 addresses
Token Address: 8b7ce78b89f05eaec2e803e638ff5b0f6f009184
Decimals: 18
⚙️ Building transaction instruction...
✅ Instruction built successfully
🔄 Building and simulating transaction...
INFO [2026-06-15 09:13:31.147 +0530]: Starting editChainRemoteConfig command
command: "burnmint-token-pool.edit-chain-remote-config"
programId: "41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB"
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
authority: "AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB"
remoteChainSelector: "16015286601757825753"
poolAddresses: "[\"0x7115d906b67f9bc1a70ab16a8e38c603d9669749\"]"
tokenAddress: "0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184"
decimals: "18"
globalOptions: {
"environment": "devnet",
"resolvedRpcUrl": "https://api.devnet.solana.com"
}
🎯 COPY TRANSACTION DATA BELOW:
AFoMPPpvGwnZ4Y3NzMYH5szHnSfKR5DVEBiNkyefN9eQdbhCsQwncNrBH6yt2ngwTxZtBUgeTaKSMEaevUjWZ6WqoajmGj5vFcgATkEo7saA5zdcjsjiqC79GUNCsYRYEmShb8cTUBgtGKE2N59vAREx1DHdnRkjvL1jwVHcV1JnBxTMnf1hFCxZXWxQpZmtxjR7F4imo1sFJhehPvXqfn9Vo4WrBf11xmm1VPQYEpQN2k484hfW361BJ6yPMnK5xbv7fkP9nfaTWUnCno6zaM632cqfua9BVDSbxxvKwNuTk4BYC2EUhWhu6WFddn2YgJvNoaZ3jFcmRF8kQb48Bvs4Z62NoMYn66JuPEMAdqTetg91gzTLpxS1QKEsXbbieTpGp5DVRxksv21sT1NAhYcGfRnTdjSaAbApHjQ2V6rxmNqF
────────────────────────────────────────────────────────────────────────────────
✅ Transaction simulation completed
INFO [2026-06-15 09:13:31.628 +0530]: Transaction built successfully
instructionName: "editChainRemoteConfig"
transactionSize: "317 bytes"
base58Length: "432 characters"
hexLength: "634 characters"
accountCount: 4
signerCount: 1
computeUnits: 20533
INFO [2026-06-15 09:13:31.628 +0530]: Completed buildTransaction (editChainRemoteConfig)
durationMs: 477
INFO [2026-06-15 09:13:31.628 +0530]:
INFO [2026-06-15 09:13:31.628 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 09:13:31.628 +0530]:
INFO [2026-06-15 09:13:31.628 +0530]: 📋 Transaction Details:
INFO [2026-06-15 09:13:31.628 +0530]: Instruction: editChainRemoteConfig
INFO [2026-06-15 09:13:31.628 +0530]: Size: 317 bytes
INFO [2026-06-15 09:13:31.628 +0530]: Base58 length: 432 characters
INFO [2026-06-15 09:13:31.637 +0530]: Compute units: 20,533
INFO [2026-06-15 09:13:31.637 +0530]: Generated: 2026-06-15T03:43:31.628Z
INFO [2026-06-15 09:13:31.637 +0530]:
INFO [2026-06-15 09:13:31.637 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 09:13:31.637 +0530]:
INFO [2026-06-15 09:13:31.637 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 09:13:31.637 +0530]:
INFO [2026-06-15 09:13:31.637 +0530]: 📊 Account Information:
INFO [2026-06-15 09:13:31.637 +0530]: Total accounts: 4
INFO [2026-06-15 09:13:31.637 +0530]: 1. 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu (read-only)
INFO [2026-06-15 09:13:31.637 +0530]: 2. A3TEVLHYCbBzncbmVtiZAsK9R281n9oe4DZwMZyKy5p2 (writable)
INFO [2026-06-15 09:13:31.637 +0530]: 3. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 09:13:31.637 +0530]: 4. 11111111111111111111111111111111 (read-only)
INFO [2026-06-15 09:13:31.637 +0530]:
INFO [2026-06-15 09:13:31.637 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 09:13:31.637 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 09:13:31.637 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 09:13:31.637 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 09:13:31.637 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 09:13:31.637 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 09:13:31.637 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 09:13:31.637 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 09:13:31.637 +0530]:
INFO [2026-06-15 09:13:31.637 +0530]: 🔍 Important Notes:
INFO [2026-06-15 09:13:31.637 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 09:13:31.637 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 09:13:31.637 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 09:13:31.637 +0530]: • Estimated compute units: 20,533
INFO [2026-06-15 09:13:31.637 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 09:13:31.637 +0530]:
INFO [2026-06-15 09:13:31.637 +0530]: editChainRemoteConfig command completed successfully
command: "burnmint-token-pool.edit-chain-remote-config"
transactionSize: "317 bytes"
computeUnits: 20533
Account Breakdown from the Transaction:
| Account | Address | Description |
|---|---|---|
| #1 | 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu | Pool State PDA (read-only - authority validation) |
| #2 | A3TEVLHYCbBzncbmVtiZAsK9R281n9oe4DZwMZyKy5p2 | Chain Remote Config PDA (writable - configuration updated) |
| #3 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | 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 $SOL_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"
🔄 Generating setChainRateLimit transaction...
RPC URL: https://api.devnet.solana.com
Program ID: 41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB
Mint: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
Authority: AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB
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...
INFO [2026-06-15 09:17:10.371 +0530]: Starting setChainRateLimit command
command: "burnmint-token-pool.set-chain-rate-limit"
programId: "41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB"
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
authority: "AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB"
remoteChainSelector: "16015286601757825753"
inboundEnabled: "true"
inboundCapacity: "20000000000"
inboundRate: "100000000"
outboundEnabled: "true"
outboundCapacity: "18000000000"
outboundRate: "100000000"
globalOptions: {
"environment": "devnet",
"resolvedRpcUrl": "https://api.devnet.solana.com"
}
🎯 COPY TRANSACTION DATA BELOW:
2osuKtP31rW7xJebzwQn4Xqs8QpiBRYpQVTWtwq69tqevXsC1jJcB5D93DuUYshzs2Z8jjRANiKBxmSGhBuqkYinKvCK29HDtd2Uyi47ncTMMnFUh8F5vs2QcZ9H8162JPkvEwHVLjXhuvF4e9e8VHRMGmEFk3W3uXwveVT3Q9UdaTx9qnVgUd2ynU6e2H159KdgZ2N1vKHEJNUuX4JEVgbo3ruvUjv7vFYiZ3pYaFStGgzRcdqqDJZigGYiv4oQ35AbTxfhDuJcUeL3nL9BRRAx2Kvu4E3wDKHDLTLk9ch9bQFKYvVc1SHuXWkNnHR3aEMwiLp88XJMvcfsCgEWw9hDh
────────────────────────────────────────────────────────────────────────────────
✅ Transaction simulation completed
INFO [2026-06-15 09:17:10.712 +0530]: Transaction built successfully
instructionName: "setChainRateLimit"
transactionSize: "253 bytes"
base58Length: "345 characters"
hexLength: "506 characters"
accountCount: 3
signerCount: 1
computeUnits: 17096
INFO [2026-06-15 09:17:10.713 +0530]: Completed buildTransaction (setChainRateLimit)
durationMs: 338
INFO [2026-06-15 09:17:10.713 +0530]:
INFO [2026-06-15 09:17:10.713 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 09:17:10.713 +0530]:
INFO [2026-06-15 09:17:10.713 +0530]: 📋 Transaction Details:
INFO [2026-06-15 09:17:10.713 +0530]: Instruction: setChainRateLimit
INFO [2026-06-15 09:17:10.713 +0530]: Size: 253 bytes
INFO [2026-06-15 09:17:10.713 +0530]: Base58 length: 345 characters
INFO [2026-06-15 09:17:10.720 +0530]: Compute units: 17,096
INFO [2026-06-15 09:17:10.720 +0530]: Generated: 2026-06-15T03:47:10.712Z
INFO [2026-06-15 09:17:10.720 +0530]:
INFO [2026-06-15 09:17:10.720 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 09:17:10.720 +0530]:
INFO [2026-06-15 09:17:10.721 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 09:17:10.721 +0530]:
INFO [2026-06-15 09:17:10.721 +0530]: 📊 Account Information:
INFO [2026-06-15 09:17:10.721 +0530]: Total accounts: 3
INFO [2026-06-15 09:17:10.721 +0530]: 1. 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu (read-only)
INFO [2026-06-15 09:17:10.721 +0530]: 2. A3TEVLHYCbBzncbmVtiZAsK9R281n9oe4DZwMZyKy5p2 (writable)
INFO [2026-06-15 09:17:10.721 +0530]: 3. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 09:17:10.721 +0530]:
INFO [2026-06-15 09:17:10.721 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 09:17:10.721 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 09:17:10.721 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 09:17:10.721 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 09:17:10.721 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 09:17:10.721 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 09:17:10.721 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 09:17:10.721 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 09:17:10.721 +0530]:
INFO [2026-06-15 09:17:10.721 +0530]: 🔍 Important Notes:
INFO [2026-06-15 09:17:10.721 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 09:17:10.721 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 09:17:10.721 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 09:17:10.721 +0530]: • Estimated compute units: 17,096
INFO [2026-06-15 09:17:10.721 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 09:17:10.721 +0530]:
INFO [2026-06-15 09:17:10.721 +0530]: setChainRateLimit command completed successfully
command: "burnmint-token-pool.set-chain-rate-limit"
transactionSize: "253 bytes"
computeUnits: 17096
Transaction Accounts (3 total):
| Account | Address | Type | Purpose |
|---|---|---|---|
| #1 | 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu | Read-only | Pool State PDA - Main pool configuration account |
| #2 | A3TEVLHYCbBzncbmVtiZAsK9R281n9oe4DZwMZyKy5p2 | Writable | Chain Config PDA - Chain-specific config (stores rate limits) |
| #3 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | 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 $SOL_CCIP_ROUTER \
--fee-quoter-program-id $SOL_CCIP_FEE_QUOTER_PROGRAM \
--pool-program-id $SOL_CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--additional-addresses "[\"$SOL_SPL_MULTISIG\"]"
🔄 Generating create_lookup_table transaction...
🔄 Building and simulating transaction...
🎯 COPY TRANSACTION DATA BELOW:
4Tv97PYyrMme7P36n8oAz29YxbpdKWYcAHQmjxpUgAh8wwU1E7Q5bnUqBzQp2xnXL6Z3kFaQhxtR4jj5YHs8yhFzELPrjRhWUuGZbQhyJrGsqDqsL3YGeycrgFhFSieJCjKv9qVfmNwhBwmvjLTcGRKNgwNmUXYB67pzkDwwj8xgN7mdg13wBxFNSGvbBsoBhFqNqDfq4p4who4JKxKHnx4GRi8LdeNgf2ctSi3XZTq2SFAp4yeqMKNyegXXzxV5D7LosUqxCt3umcrq7HG3RZfm4ctkJFAduZftvUcJ18MKgPNmTw4TBGC7HLBoYi8fp7m4EMSPiPgHK6vzxmt5QaAYk6PDpjG7tcE5bxF3LTMqXXA94GEhox79b3uVFKVutUCgAdtq3qCrnfBf5h3j1Md7ybGuQDV5AmKQg8DDGUDPybi2aDr8zTpXY8rBDisYysxvx6JoRyS4ZTxnFUYFLh1dHUXrbD2F8yEfEQpokkxw3oW5bTqwqCr3cA17vvTSo1dvbQYyNoJyuDqnmAGs2UvMDAxJxtQgxCPQcc1ZJzNQgmFai1wnohmPsVVWMVgXcARDbJvzHDeZxtQH99KfrTFvbLsaGgWAv6iqYKT1fhzoQsDpTPvhmUzQNYUoFgysCcDS5jKNZgtQ9M7oiBDV464HZfAbfq9K4erB9g71f4NHEgwohNUeTvKaMiMD6ubHdCQuM5y92Fc6NtMdgYW38rU1Q53NnzWnkD68d7kvCXGT3UJ41v7GuGBX
────────────────────────────────────────────────────────────────────────────────
📮 Derived Lookup Table Address: DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv
✅ Transaction simulation completed
⚠️ ALT CREATION TIMING CONSTRAINT
This transaction must be imported AND executed within 60-90 seconds
due to slot-dependent address derivation.
💡 RECOMMENDED: Use the companion tool for immediate execution:
pnpm create-alt --keypair <EOA_KEYPAIR> --authority AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB \
--program-id Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C \
--fee-quoter-program-id FeeQPGkKDeRV1MgoYfMH6L8o3KeuYjwUZrgn4LRKfjHi \
--pool-program-id 41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB \
--mint hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub \
--env devnet
INFO [2026-06-15 09:37:03.045 +0530]: Detected SPL Token v1
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
INFO [2026-06-15 09:37:03.321 +0530]: Transaction built successfully
instructionName: "router.create_lookup_table"
transactionSize: "557 bytes"
base58Length: "760 characters"
hexLength: "1114 characters"
accountCount: 4
signerCount: 2
computeUnits: 19521
INFO [2026-06-15 09:37:03.321 +0530]: Completed buildTransaction (router.create_lookup_table)
durationMs: 183
INFO [2026-06-15 09:37:03.322 +0530]:
INFO [2026-06-15 09:37:03.322 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 09:37:03.322 +0530]:
INFO [2026-06-15 09:37:03.322 +0530]: 📋 Transaction Details:
INFO [2026-06-15 09:37:03.322 +0530]: Instruction: router.create_lookup_table
INFO [2026-06-15 09:37:03.322 +0530]: Size: 557 bytes
INFO [2026-06-15 09:37:03.322 +0530]: Base58 length: 760 characters
INFO [2026-06-15 09:37:03.329 +0530]: Compute units: 19,521
INFO [2026-06-15 09:37:03.329 +0530]: Generated: 2026-06-15T04:07:03.321Z
INFO [2026-06-15 09:37:03.329 +0530]:
INFO [2026-06-15 09:37:03.329 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 09:37:03.329 +0530]:
INFO [2026-06-15 09:37:03.329 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 09:37:03.329 +0530]:
INFO [2026-06-15 09:37:03.329 +0530]: 📊 Account Information:
INFO [2026-06-15 09:37:03.329 +0530]: Total accounts: 4
INFO [2026-06-15 09:37:03.329 +0530]: 1. DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv (writable)
INFO [2026-06-15 09:37:03.329 +0530]: 2. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer)
INFO [2026-06-15 09:37:03.329 +0530]: 3. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 09:37:03.329 +0530]: 4. 11111111111111111111111111111111 (read-only)
INFO [2026-06-15 09:37:03.329 +0530]:
INFO [2026-06-15 09:37:03.329 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 09:37:03.329 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 09:37:03.329 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 09:37:03.329 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 09:37:03.329 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 09:37:03.329 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 09:37:03.329 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 09:37:03.329 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 09:37:03.329 +0530]:
INFO [2026-06-15 09:37:03.330 +0530]: 🔍 Important Notes:
INFO [2026-06-15 09:37:03.330 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 09:37:03.330 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 09:37:03.330 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 09:37:03.330 +0530]: • Estimated compute units: 19,521
INFO [2026-06-15 09:37:03.330 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 09:37:03.330 +0530]:
Account Breakdown from the Transaction:
| Account | Address | Description |
|---|---|---|
| #1 | DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv | ALT Account (writable - being created) |
| #2 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | ALT Authority (signer - will own the table) |
| #3 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | 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
DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zvwith 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_MULTISIGvia--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 | DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv | ALT Address (Self-Reference) |
| 1 | 6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3 | Token Admin Registry PDA |
| 2 | 41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB | Pool Program ID |
| 3 | 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu | Pool State PDA |
| 4 | 2Lzp4uRF6N2x65aMpKqFrajFukAbTCtQcG8thVgqcsEh | Pool Signer's Associated Token Account |
| 5 | 62So4PhmWWzMpVXKzsCXdNUfrrB4jGXTVda9BzS6HTeo | Pool Signer PDA |
| 6 | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | Token Program ID (SPL Token v1) |
| 7 | hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub | Token Mint |
| 8 | GTz54AfhMRkKzFVse8jX8rjAx21fA86ZmVBF1v5VUC3u | Fee Quoter Token Config PDA |
| 9 | H6ZviaabTYZqUPgiSoMDbeVthcNW9ULcAuUu3zRLFqDR | Router External Token Pools Signer PDA |
| 10 | 3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX | 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: DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv
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 $SOL_CCIP_ROUTER \
--mint $SOL_TOKEN_MINT \
--authority $SOL_SQUAD_VAULT_MULTISIG \
--pool-lookup-table $SOL_ADDRESS_LOOKUP_TABLE \
--writable-indexes "[3,4,7]"
🔄 Generating set_pool transaction...
🔄 Building and simulating transaction...
🎯 COPY TRANSACTION DATA BELOW:
QmCawFUFrWLVf4xbxo2fJyttTDxiAsdLTbZfn4tgZUjn1TcfyExg71Uugx2fD6A4L38xjLemqiRRAaZy18w67UgpHw7KZvDp1YRGtWyYbZifpMcvXDqu6L8iMX9f8MqPLT1eFKwwBFxNmksaCC8KrSTMVaXeWATpMGEz9nDdXJdt4GvvoxJSjwdmLt2UQEEHtctnPPG6iL3iWidCcQDGoJeLnTfnwAT3KG89UAuFwxxiqF8Ub6Yqbesy1jm18yXvdeiVmuAYAeLCWmZzeUPKGkGccKv3dvY4xGX8LwJQLzfhDGKapDz533cKHXStjkhyEmwF5FHbEQk9URGQYNuL5Dg
────────────────────────────────────────────────────────────────────────────────
✅ Transaction simulation completed
INFO [2026-06-15 09:41:01.361 +0530]: Transaction built successfully
instructionName: "router.set_pool"
transactionSize: "252 bytes"
base58Length: "343 characters"
hexLength: "504 characters"
accountCount: 5
signerCount: 1
computeUnits: 37367
INFO [2026-06-15 09:41:01.361 +0530]: Completed buildTransaction (router.set_pool)
durationMs: 326
INFO [2026-06-15 09:41:01.361 +0530]:
INFO [2026-06-15 09:41:01.361 +0530]: 🎉 Transaction generated successfully!
INFO [2026-06-15 09:41:01.361 +0530]:
INFO [2026-06-15 09:41:01.361 +0530]: 📋 Transaction Details:
INFO [2026-06-15 09:41:01.361 +0530]: Instruction: router.set_pool
INFO [2026-06-15 09:41:01.361 +0530]: Size: 252 bytes
INFO [2026-06-15 09:41:01.361 +0530]: Base58 length: 343 characters
INFO [2026-06-15 09:41:01.372 +0530]: Compute units: 37,367
INFO [2026-06-15 09:41:01.372 +0530]: Generated: 2026-06-15T04:11:01.360Z
INFO [2026-06-15 09:41:01.372 +0530]:
INFO [2026-06-15 09:41:01.372 +0530]: 🔗 Transaction Data (Base58):
INFO [2026-06-15 09:41:01.372 +0530]:
INFO [2026-06-15 09:41:01.372 +0530]: 💡 Triple-click the line above to select the entire transaction data
INFO [2026-06-15 09:41:01.372 +0530]:
INFO [2026-06-15 09:41:01.372 +0530]: 📊 Account Information:
INFO [2026-06-15 09:41:01.372 +0530]: Total accounts: 5
INFO [2026-06-15 09:41:01.372 +0530]: 1. 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 (read-only)
INFO [2026-06-15 09:41:01.372 +0530]: 2. 6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3 (writable)
INFO [2026-06-15 09:41:01.372 +0530]: 3. hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub (read-only)
INFO [2026-06-15 09:41:01.372 +0530]: 4. DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv (read-only)
INFO [2026-06-15 09:41:01.372 +0530]: 5. AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB (signer, writable)
INFO [2026-06-15 09:41:01.372 +0530]:
INFO [2026-06-15 09:41:01.372 +0530]: 💡 Usage Instructions:
INFO [2026-06-15 09:41:01.372 +0530]: 1. 📋 Copy the Base58 transaction data from the box above
INFO [2026-06-15 09:41:01.372 +0530]: 2. 🔗 Open your Squads multisig interface
INFO [2026-06-15 09:41:01.372 +0530]: 3. ➕ Create a "Custom Transaction" or "Raw Transaction"
INFO [2026-06-15 09:41:01.372 +0530]: 4. 📝 Paste the Base58 data into the transaction field
INFO [2026-06-15 09:41:01.372 +0530]: 5. ✅ Review all accounts and parameters carefully
INFO [2026-06-15 09:41:01.372 +0530]: 6. 👥 Get required signatures from multisig members
INFO [2026-06-15 09:41:01.372 +0530]: 7. 🚀 Execute the transaction on Solana
INFO [2026-06-15 09:41:01.372 +0530]:
INFO [2026-06-15 09:41:01.372 +0530]: 🔍 Important Notes:
INFO [2026-06-15 09:41:01.372 +0530]: • Transaction was simulated and validated before generation
INFO [2026-06-15 09:41:01.372 +0530]: • All public keys and accounts have been verified
INFO [2026-06-15 09:41:01.372 +0530]: • Always double-check the transaction details in your multisig
INFO [2026-06-15 09:41:01.372 +0530]: • Estimated compute units: 37,367
INFO [2026-06-15 09:41:01.372 +0530]: • This transaction is valid until the blockhash expires (~2 minutes)
INFO [2026-06-15 09:41:01.372 +0530]:
Account Breakdown from the Transaction:
| Account | Address | Description |
|---|---|---|
| #1 | 3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3 | Router Config PDA (read-only - configuration reference) |
| #2 | 6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3 | Token Admin Registry PDA (writable - pool registration) |
| #3 | hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub | Token Mint (read-only - token identification) |
| #4 | DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv | Address Lookup Table (read-only - ALT registration) |
| #5 | AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB | 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
DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zvyou 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 SOL_CCIP_POOL_PROGRAM="$SOL_CCIP_POOL_PROGRAM"
export SOL_CCIP_ROUTER="$SOL_CCIP_ROUTER"
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"
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: DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv
✅ 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: 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184
✅ ETH Pool: 0x7115d906b67f9bc1a70ab16a8e38c603d9669749
✅ SOL Token: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
✅ SOL Pool: 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu
✅ SOL ALT: DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv
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 ethereumSepolia
# 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 ethereumSepolia
2026-06-15T04:20:46.391Z info: === Starting Chain Update Configuration ===
2026-06-15T04:20:46.392Z info: 🔹 Local network: ethereumSepolia
2026-06-15T04:20:46.392Z info: 🔹 Pool address: 0x7115d906b67f9bc1a70ab16a8e38c603d9669749
2026-06-15T04:20:46.393Z info: 🔹 Remote chain: solanaDevnet
2026-06-15T04:20:46.393Z info: 🔹 Remote chain family: svm
2026-06-15T04:20:46.393Z info: 🔹 Remote chain selector: 16423721717087811551
2026-06-15T04:20:47.891Z info: ✅ All addresses validated successfully
2026-06-15T04:20:48.336Z info: ✅ Using signer: 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca
2026-06-15T04:20:48.589Z info: ✅ Connected to TokenPool contract
2026-06-15T04:20:48.590Z info: Remote pool 1: 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu → 0x1cc091f29ab8f1bd3c6d04a7f33ffdfb1efd2f803f33558762502af90a58ce32
2026-06-15T04:20:48.591Z info: === Rate Limiter Configuration ===
2026-06-15T04:20:48.591Z info: Outbound enabled: true
2026-06-15T04:20:48.591Z info: capacity: 18000000000000000000
2026-06-15T04:20:48.591Z info: rate: 100000000000000000
2026-06-15T04:20:48.591Z info: Inbound enabled: true
2026-06-15T04:20:48.591Z info: capacity: 20000000000000000000
2026-06-15T04:20:48.591Z info: rate: 100000000000000000
2026-06-15T04:20:48.591Z info: === Executing applyChainUpdates() ===
2026-06-15T04:20:50.227Z info: 📤 TX sent: 0x0a485bde9eca53e5d9acaa5edaf25e28375129cd98d130230fd107faf5195600
2026-06-15T04:20:50.227Z info: Waiting for 3 confirmations...
2026-06-15T04:21:24.518Z info: ✅ Chain update applied successfully on ethereumSepolia (3 confirmations)!
2026-06-15T04:23:15.391Z info: === Starting Chain Update Configuration ===
2026-06-15T04:23:15.392Z info: 🔹 Local network: ethereumSepolia
2026-06-15T04:23:15.392Z info: 🔹 Pool address: 0x7115d906b67f9bc1a70ab16a8e38c603d9669749
2026-06-15T04:23:15.393Z info: 🔹 Remote chain: solanaDevnet
2026-06-15T04:23:15.393Z info: 🔹 Remote chain family: svm
2026-06-15T04:23:15.393Z info: 🔹 Remote chain selector: 16423721717087811551
2026-06-15T04:23:16.891Z info: ✅ All addresses validated successfully
2026-06-15T04:23:17.336Z info: ✅ Using signer: 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca
2026-06-15T04:23:17.589Z info: ✅ Connected to TokenPool contract
2026-06-15T04:23:17.590Z info: Remote pool 1: 2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu → 0x1cc091f29ab8f1bd3c6d04a7f33ffdfb1efd2f803f33558762502af90a58ce32
2026-06-15T04:23:17.591Z info: === Rate Limiter Configuration ===
2026-06-15T04:23:17.591Z info: Outbound enabled: false
2026-06-15T04:23:17.591Z info: Inbound enabled: false
2026-06-15T04:23:17.591Z info: === Executing applyChainUpdates() ===
2026-06-15T04:23:19.227Z info: 📤 TX sent: 0xc4e8a1f92b3d5678e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
2026-06-15T04:23:19.227Z info: Waiting for 3 confirmations...
2026-06-15T04:23:53.518Z info: ✅ Chain update applied successfully on ethereumSepolia (3 confirmations)!
Phase 5: Pre-Transfer Setup, Validation, and Testing
Step 1: Load Configuration
# Check current directory (Terminal 1)
pwd
# Should show: .../ccip-solana-bs58-generator
# Load all environment variables
source ~/.all_vars
# Verify critical variables
echo "SOL_TOKEN_MINT: $SOL_TOKEN_MINT"
echo "ETH_TOKEN_ADDRESS: $ETH_TOKEN_ADDRESS"
echo "SOL_POOL_SIGNER_PDA: $SOL_POOL_SIGNER_PDA"
echo "SOL_SPL_MULTISIG: $SOL_SPL_MULTISIG"
echo "SOL_ADDRESS_LOOKUP_TABLE: $SOL_ADDRESS_LOOKUP_TABLE"
echo "SOL_WALLET_ADDRESS: $SOL_WALLET_ADDRESS"
/.../ccip-solana-bs58-generator
SOL_TOKEN_MINT: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
ETH_TOKEN_ADDRESS: 0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184
SOL_POOL_SIGNER_PDA: 62So4PhmWWzMpVXKzsCXdNUfrrB4jGXTVda9BzS6HTeo
SOL_SPL_MULTISIG: 3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX
SOL_ADDRESS_LOOKUP_TABLE: DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv
SOL_WALLET_ADDRESS: GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN
Step 2: Pre-Transfer Setup
Before cross-chain transfers (when available), complete token delegation so CCIP can move tokens from your wallet.
Check Token Balance
spl-token balance $SOL_TOKEN_MINT
5001
Create Pool Associated Token Account
If not created during pool setup, create the pool's ATA:
# Create ATA owned by the Pool Signer PDA
spl-token create-account $SOL_TOKEN_MINT \
--owner $SOL_POOL_SIGNER_PDA \
--fee-payer $HOME/.config/solana/id.json
Creating account 2Lzp4uRF6N2x65aMpKqFrajFukAbTCtQcG8thVgqcsEh
Signature: 2iH5vhcB2iNtez9HgtgqNCZFF1zdBiE8FdnhD5n9gbEdwL1ucLLc8os9ipCTKhVjLMYkPT3KD5KovrS8K59CJzS4
Delegate Token Authority
# Derive the CCIP fee-billing signer PDA
export SOL_CCIP_FEE_BILLING_SIGNER=$(solana find-program-derived-address $SOL_CCIP_ROUTER string:fee_billing_signer | head -1)
echo "SOL_CCIP_FEE_BILLING_SIGNER=$SOL_CCIP_FEE_BILLING_SIGNER"
SOL_CCIP_FEE_BILLING_SIGNER=2AjuzTy6z2webxEUu7eZ1DkAyLagZaqH2dgzhbBYjJiG
Approve the fee-billing signer to transfer tokens from your ATA:
# --amount is u64 max (2^64 - 1): max delegation for CCIP fee billing
pnpm bs58 --env devnet --execute spl-token \
--instruction approve \
--authority $SOL_WALLET_ADDRESS \
--mint $SOL_TOKEN_MINT \
--delegate $SOL_CCIP_FEE_BILLING_SIGNER \
--amount 18446744073709551615
🔍 Detecting token program...
INFO [2026-06-15 09:58:35.097 +0530]: Starting approve command
command: "spl-token.approve"
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
delegate: "2AjuzTy6z2webxEUu7eZ1DkAyLagZaqH2dgzhbBYjJiG"
authority: "GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN"
amount: "18446744073709551615"
globalOptions: {
"environment": "devnet",
"execute": true,
"resolvedRpcUrl": "https://api.devnet.solana.com",
"keypair": "/Users/syed-cll/.config/solana/id.json",
"_signerKeypair": {
"_keypair": {
"publicKey": {
"0": 230,
"1": 211,
"2": 30,
...
"29": 179,
"30": 114,
"31": 73
},
"secretKey": {
"0": 191,
"1": 198,
"2": 244,
...
"61": 179,
"62": 114,
"63": 73
}
}
}
}
✅ Detected token program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
🔍 Auto-deriving Associated Token Account...
✅ Derived ATA: gKhGBvVGw62EdjfdNQFvVvvbg8CqdepTrdmSdVsEDBS
🔄 Generating approve transaction...
RPC URL: https://api.devnet.solana.com
Token Program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Mint: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
Token Account: gKhGBvVGw62EdjfdNQFvVvvbg8CqdepTrdmSdVsEDBS
Delegate: 2AjuzTy6z2webxEUu7eZ1DkAyLagZaqH2dgzhbBYjJiG
Authority (Token Account Owner): GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN
Amount: 18446744073709551615
⚙️ Building transaction instruction...
✅ Instruction built successfully
🔄 Building and simulating transaction...
INFO [2026-06-15 09:58:35.357 +0530]: Detected SPL Token v1
mint: "hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub"
programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
INFO [2026-06-15 09:58:35.514 +0530]: Transaction built successfully
instructionName: "approve"
transactionSize: "180 bytes"
base58Length: "245 characters"
hexLength: "360 characters"
accountCount: 3
signerCount: 1
computeUnits: 123
INFO [2026-06-15 09:58:35.514 +0530]: Completed buildTransaction (approve)
durationMs: 155
INFO [2026-06-15 09:58:35.668 +0530]:
INFO [2026-06-15 09:58:35.668 +0530]: 🖊️ EXECUTE MODE — signing & sending on devnet
INFO [2026-06-15 09:58:35.668 +0530]: Signer: GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN
INFO [2026-06-15 09:58:35.668 +0530]: Instruction: approve
INFO [2026-06-15 09:58:35.668 +0530]: RPC: https://api.devnet.solana.com
INFO [2026-06-15 09:58:35.668 +0530]:
✅ Transaction simulation completed
INFO [2026-06-15 09:58:36.528 +0530]: Transaction confirmed successfully
signature: "3D5wGk6nf3ZnWx7ymBZQ4QxFMSLNRTwwDCok1zhNjpv7byJKVW8SzsHanmdS5ua899JtD2yBsgEgu5f257JBN4Rg"
attempt: 1
INFO [2026-06-15 09:58:36.528 +0530]:
INFO [2026-06-15 09:58:36.528 +0530]: 🎉 Transaction executed successfully!
INFO [2026-06-15 09:58:36.528 +0530]:
INFO [2026-06-15 09:58:36.528 +0530]: 📋 Execution Details:
INFO [2026-06-15 09:58:36.528 +0530]: Instruction: approve
INFO [2026-06-15 09:58:36.528 +0530]: Signature: 3D5wGk6nf3ZnWx7ymBZQ4QxFMSLNRTwwDCok1zhNjpv7byJKVW8SzsHanmdS5ua899JtD2yBsgEgu5f257JBN4Rg
INFO [2026-06-15 09:58:36.528 +0530]: Explorer: https://explorer.solana.com/tx/3D5wGk6nf3ZnWx7ymBZQ4QxFMSLNRTwwDCok1zhNjpv7byJKVW8SzsHanmdS5ua899JtD2yBsgEgu5f257JBN4Rg?cluster=devnet
INFO [2026-06-15 09:58:36.528 +0530]:
INFO [2026-06-15 09:58:36.528 +0530]: approve command completed successfully
command: "spl-token.approve"
transactionSize: "180 bytes"
computeUnits: 123
Verify Delegation
Check that your token account is delegated to the fee-billing signer:
# Find your Associated Token Account (ATA) address
export SOL_TOKEN_ACCOUNT=$(spl-token accounts $SOL_TOKEN_MINT --owner $SOL_WALLET_ADDRESS --addresses-only)
echo "SOL_TOKEN_ACCOUNT=$SOL_TOKEN_ACCOUNT"
SOL_TOKEN_ACCOUNT=gKhGBvVGw62EdjfdNQFvVvvbg8CqdepTrdmSdVsEDBS
Display token account and delegation status:
spl-token display $SOL_TOKEN_ACCOUNT
SPL Token Account
Address: gKhGBvVGw62EdjfdNQFvVvvbg8CqdepTrdmSdVsEDBS
Program: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Balance: 5001
Decimals: 9
Mint: hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub
Owner: GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN
State: Initialized
Delegation:
Delegate: 2AjuzTy6z2webxEUu7eZ1DkAyLagZaqH2dgzhbBYjJiG
Allowance: 18446744073.709551615
Close authority: (not set)
Step 3: Verify Solana Pool and Chain Config
# Verify pool state
pnpm bs58 --env devnet burnmint-token-pool \
--instruction get-state \
--program-id $SOL_CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT
# Verify Ethereum Sepolia remote chain config
pnpm bs58 --env devnet burnmint-token-pool \
--instruction get-chain-config \
--program-id $SOL_CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR
# Verify mint authority is the SPL multisig
spl-token display $SOL_TOKEN_MINT
Confirm the following:
- Pool owner matches your Squads vault (
$SOL_SQUAD_VAULT_MULTISIG) - Mint authority is the SPL token multisig (
$SOL_SPL_MULTISIG) with Pool Signer PDA as a signer - Remote chain config includes
$ETH_POOL_ADDRESSand$ETH_TOKEN_ADDRESS - Rate limit settings match your Phase 3 configuration (if enabled)
- Token delegation is set to the fee-billing signer
Step 4: Verify Ethereum Pool (Terminal 2)
Switch to Terminal 2 (Smart Contract Examples - Hardhat):
npx hardhat getPoolConfig \
--pooladdress $ETH_POOL_ADDRESS \
--network ethereumSepolia
Confirm the Ethereum pool recognizes Solana Devnet with your $SOL_POOL_ADDRESS and $SOL_TOKEN_MINT.
Configure CCIP CLI
Export these RPC URLs once before your first transfer:
export SOLANA_DEVNET_RPC="https://api.devnet.solana.com"
export ETHEREUM_SEPOLIA_RPC_URL="<YOUR_ETHEREUM_SEPOLIA_RPC_URL>"
export ETH_CCIP_ROUTER="0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59"
Use the same ETHEREUM_SEPOLIA_RPC_URL from your env-enc setup in Terminal 2 (npx env-enc view). On ccip-cli send, the source chain RPC quotes fees and submits the transaction; for token-only transfers in this tutorial, that is the only RPC strictly required to send. Pass both RPCs on cross-chain commands anyway: the destination RPC is required for ccip-cli show --wait and for optional send features such as --estimate-gas-limit or send --wait.
Transfer Solana → Ethereum
Terminal 1 (CCIP Solana BS58 Generator):
source ~/.all_vars
export ETH_RECEIVER_ADDRESS="<YOUR_ETHEREUM_RECEIVER_ADDRESS>"
ccip-cli send \
-s solana-devnet \
-r $SOL_CCIP_ROUTER \
-d ethereum-testnet-sepolia \
--to $ETH_RECEIVER_ADDRESS \
-t $SOL_TOKEN_MINT=0.001 \
--wallet ~/.config/solana/id.json \
--rpc $SOLANA_DEVNET_RPC \
--rpc $ETHEREUM_SEPOLIA_RPC_URL
Using rate-limited fetch for public solana nodes, commands may be slow
Fee: 133805598n = 0.133805598 SOL
🚀 Sending message to 0x8c244f0b2164e6a3bed74ab429b0ebd661bb14ca @ ethereum-testnet-sepolia , tx => 2PaRwTZcUPwMz4Y3wmCbYA57w6jgQdM8WuNHyMy3N4o4eSdnxH2oQo1WEKpHDHQMka6gSSK8vdaz2UHp2MY8AFiA, messageId => 0xe36a4b5d82dd8071cf132918b55ad59e53d985872ad9d182305803f37a61ec98
Using rate-limited fetch for public solana nodes, commands may be slow
Lane:
┌────────────────┬────────────────────────────────────────────────┬────────────────────────────┐
│ (index) │ source │ dest │
├────────────────┼────────────────────────────────────────────────┼────────────────────────────┤
│ name │ 'solana-devnet' │ 'ethereum-testnet-sepolia' │
│ chainId │ 'EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG' │ 11155111 │
│ chainSelector │ 16423721717087811551n │ 16015286601757825753n │
│ onRamp/version │ 'Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C' │ '1.6.0' │
└────────────────┴────────────────────────────────────────────────┴────────────────────────────┘
Request (source):
┌──────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────┐
│ (index) │ Values │
├──────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤
│ messageId │ '0xe36a4b5d82dd8071cf132918b55ad59e53d985872ad9d182305803f37a61ec98' │
│ origin │ 'GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN' │
│ sender │ 'GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN' │
│ receiver │ '0x8C244f0B2164E6A3BED74ab429B0ebd661Bb14CA' │
│ sequenceNumber │ 3077 │
│ nonce │ '0 => allow out-of-order exec' │
│ gasLimit │ 0n │
│ transactionHash │ '2PaRwTZcUPwMz4Y3wmCbYA57w6jgQdM8WuNHyMy3N4o4eSdnxH2oQo1WEKpHDHQMka6gSSK8vdaz2UHp2MY8AFiA' │
│ logIndex │ 35 │
│ blockNumber │ 469529662 │
│ timestamp │ '2026-06-15 04:34:55 (2s ago)' │
│ finalized │ '12s left' │
│ fee │ '0.133805598 SOL' │
│ tokens │ '0.001 CCIP-AEM' │
│ data │ '0x' │
│ feeValueJuels │ 1159415351000000000n │
│ allowOutOfOrderExecution │ true │
└──────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────┘
CCIP Explorer: https://ccip.chain.link/msg/0xe36a4b5d82dd8071cf132918b55ad59e53d985872ad9d182305803f37a61ec98
The -t flag uses human-readable amounts (0.001 tokens with 9 decimals = 1,000,000 smallest units).
# Replace with the transaction hash or message ID from the send output
ccip-cli show <TX_HASH_OR_MESSAGE_ID> --wait \
--rpc $SOLANA_DEVNET_RPC \
--rpc $ETHEREUM_SEPOLIA_RPC_URL
Using rate-limited fetch for public solana nodes, commands may be slow
Lane:
┌────────────────┬────────────────────────────────────────────────┬────────────────────────────┐
│ (index) │ source │ dest │
├────────────────┼────────────────────────────────────────────────┼────────────────────────────┤
│ name │ 'solana-devnet' │ 'ethereum-testnet-sepolia' │
│ chainId │ 'EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG' │ 11155111 │
│ chainSelector │ 16423721717087811551n │ 16015286601757825753n │
│ onRamp/version │ 'Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C' │ '1.6.2' │
└────────────────┴────────────────────────────────────────────────┴────────────────────────────┘
Request (source):
┌────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────┐
│ (index) │ Values │
├────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤
│ messageId │ '0xe36a4b5d82dd8071cf132918b55ad59e53d985872ad9d182305803f37a61ec98' │
│ origin │ 'GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN' │
│ sender │ 'GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN' │
│ receiver │ '0x8C244f0B2164E6A3BED74ab429B0ebd661Bb14CA' │
│ sequenceNumber │ 3077 │
│ nonce │ '0 => allow out-of-order exec' │
│ gasLimit │ 0n │
│ transactionHash │ '2PaRwTZcUPwMz4Y3wmCbYA57w6jgQdM8WuNHyMy3N4o4eSdnxH2oQo1WEKpHDHQMka6gSSK8vdaz2UHp2MY8AFiA' │
│ logIndex │ 2 │
│ blockNumber │ 469529662 │
│ timestamp │ '2026-06-15 04:34:55 (58s ago)' │
│ finalized │ true │
│ fee │ '0.133805598 SOL' │
│ tokens │ '0.001 CCIP-AEM' │
│ fees.fixedFeesDetails.tokenAddress │ 'So11111111111111111111111111111111111111112' │
│ fees.fixedFeesDetails.totalAmount │ 133805598n │
│ finality │ 0n │
│ finalityType │ 'FINALIZED' │
│ routerAddress │ 'Ccip842gzYHhvdDkSyi2YVCoAWPbYJoApMFzSxQroE9C' │
│ allowOutOfOrderExecution │ true │
│ status │ 'COMMITTED' │
│ readyForManualExecution │ false │
│ receiptTransactionHash │ null │
│ receiptTimestamp │ undefined │
│ deliveryTime │ null │
│ offRamp │ '0x0820f975ce90EE5c508657F0C58b71D1fcc85cE0' │
└────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────┘
CCIP Explorer: https://ccip.chain.link/msg/0xe36a4b5d82dd8071cf132918b55ad59e53d985872ad9d182305803f37a61ec98
[SENT] Waiting for source chain finalization...
[SOURCE_FINALIZED] Source chain finalized
[SOURCE_FINALIZED] Waiting for commit on destination chain...
[COMMITTED] Commit report accepted on destination chain
┌─────────────────┬──────────────────────────────────────────────────────────────────────┐
│ (index) │ Values │
├─────────────────┼──────────────────────────────────────────────────────────────────────┤
│ merkleRoot │ '0xdce4e8a082a45983a5ad0ce37abe06fb4f72dcc7e1c624b2e8dbf0f47590c909' │
│ min │ 3077 │
│ max │ 3077 │
│ origin │ '0x3d4990B971284fEbfb476710baF873fc5b65ee3e' │
│ contract │ '0x0820f975ce90EE5c508657F0C58b71D1fcc85cE0' │
│ transactionHash │ '0xed981056b3ad340d799bf5019fd4f2ef064cd05ab58c5fa99c0cccf03c73d1af' │
│ blockNumber │ 11063152 │
│ timestamp │ '2026-06-15 04:35:36 (41s after request)' │
└─────────────────┴──────────────────────────────────────────────────────────────────────┘
[BLESSED] Waiting for execution on destination chain...
[SUCCESS] Message executed on destination chain
┌─────────────────┬──────────────────────────────────────────────────────────────────────┐
│ (index) │ Values │
├─────────────────┼──────────────────────────────────────────────────────────────────────┤
│ state │ '✅ success' │
│ gasUsed │ 87342 │
│ origin │ '0xc03BfDf1C576bc3720DcD45B6B4EF6A0aEf4dfe6' │
│ contract │ '0x0820f975ce90EE5c508657F0C58b71D1fcc85cE0' │
│ transactionHash │ '0x3d1e483eeca0bef62b7a760111e7c6d5f4186c68862101d958784a2b504aea73' │
│ logIndex │ 712 │
│ blockNumber │ 11063155 │
│ timestamp │ '2026-06-15 04:36:12 (1m17s after request)' │
└─────────────────┴──────────────────────────────────────────────────────────────────────┘
Transfer Ethereum → Solana
Switch to Terminal 2 (Smart Contract Examples - Hardhat):
ccip-cli does not load Hardhat env-enc automatically. Run these commands from the Hardhat project directory. Prefer Hardhat keystore over exporting a private key in plain text.
source ~/.all_vars
ccip-cli send \
-s ethereum-testnet-sepolia \
-r $ETH_CCIP_ROUTER \
-d solana-devnet \
--to $SOL_WALLET_ADDRESS \
-t $ETH_TOKEN_ADDRESS=1.0 \
--wallet hardhat:<YOUR_KEYSTORE_ACCOUNT_NAME> \
--rpc $ETHEREUM_SEPOLIA_RPC_URL \
--rpc $SOLANA_DEVNET_RPC
Use the keystore account name from your Hardhat project (see Hardhat keystore). This keeps the signing key encrypted instead of in shell history.
source ~/.all_vars
# ccip-cli does not read env-enc — view and export the same key used in Phase 1
npx env-enc view
export PRIVATE_KEY="<YOUR_PRIVATE_KEY_FROM_ENV_ENC>"
ccip-cli send \
-s ethereum-testnet-sepolia \
-r $ETH_CCIP_ROUTER \
-d solana-devnet \
--to $SOL_WALLET_ADDRESS \
-t $ETH_TOKEN_ADDRESS=1.0 \
--rpc $ETHEREUM_SEPOLIA_RPC_URL \
--rpc $SOLANA_DEVNET_RPC
Do not commit or share the exported key. Prefer the Hardhat keystore tab for production-like workflows.
For token-only transfers to Solana, --to is the destination wallet that receives minted tokens. CCIP fees are paid in native Sepolia ETH by default — ensure your wallet has sufficient ETH for gas and fees.
ccip-cli show <TX_HASH_OR_MESSAGE_ID> --wait \
--rpc $ETHEREUM_SEPOLIA_RPC_URL \
--rpc $SOLANA_DEVNET_RPC
Lane:
┌────────────────┬──────────────────────────────────────────────┬────────────────────────────────────────────────┐
│ (index) │ source │ dest │
├────────────────┼──────────────────────────────────────────────┼────────────────────────────────────────────────┤
│ name │ 'ethereum-testnet-sepolia' │ 'solana-devnet' │
│ chainId │ 11155111 │ 'EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG' │
│ chainSelector │ 16015286601757825753n │ 16423721717087811551n │
│ onRamp/version │ '0x23a5084Fa78104F3DF11C63Ae59fcac4f6AD9DeE' │ '1.6.0' │
└────────────────┴──────────────────────────────────────────────┴────────────────────────────────────────────────┘
Request (source):
┌────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────┐
│ (index) │ Values │
├────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤
│ messageId │ '0x62d00e2bd81645ea26d8ad804a97d4cdd9724d15a4881ae6f0ff5aeacb8d95ae' │
│ origin │ '0x8C244f0B2164E6A3BED74ab429B0ebd661Bb14CA' │
│ sender │ '0x8C244f0B2164E6A3BED74ab429B0ebd661Bb14CA' │
│ receiver │ '11111111111111111111111111111111' │
│ sequenceNumber │ 10201 │
│ nonce │ '0 => allow out-of-order exec' │
│ computeUnits │ 0n │
│ transactionHash │ '0xd010ae34f97985e8aadf7910482ad8b311a76491a5077f1ff929c072fcb0d620' │
│ logIndex │ 1053 │
│ blockNumber │ 11063166 │
│ timestamp │ '2026-06-15 04:38:24 (19m12s ago)' │
│ finalized │ true │
│ fee │ '0.000350949027443669 WETH' │
│ tokens │ '1.0 BnmAEM' │
│ accounts │ undefined │
│ fees.fixedFeesDetails.tokenAddress │ '0x097D90c9d3E0B50Ca60e1ae45F6A81010f9FB534' │
│ fees.fixedFeesDetails.totalAmount │ 350949027443669n │
│ finality │ 0n │
│ finalityType │ 'FINALIZED' │
│ routerAddress │ '0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59' │
│ accountIsWritableBitmap │ 0n │
│ allowOutOfOrderExecution │ true │
│ tokenReceiver │ 'GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN' │
│ status │ 'SUCCESS' │
│ readyForManualExecution │ false │
│ receiptTransactionHash │ '64SNgMXWoakBk7SZVcKUnBZFyWiGqTZUaRfSGk9ZeiAfBY4oysaVzZnq7KYR8KwyVjFtomao5hjXNGgaoqQjCDp2' │
│ receiptTimestamp │ '2026-06-15 04:57:10' │
│ deliveryTime │ 1126000n │
│ offRamp │ 'offqSMQWgQud6WJz694LRzkeN5kMYpCHTpXQr3Rkcjm' │
└────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────┘
CCIP Explorer: https://ccip.chain.link/msg/0x62d00e2bd81645ea26d8ad804a97d4cdd9724d15a4881ae6f0ff5aeacb8d95ae
[SENT] Waiting for source chain finalization...
Using rate-limited fetch for public solana nodes, commands may be slow
[SOURCE_FINALIZED] Source chain finalized
[SOURCE_FINALIZED] Waiting for commit on destination chain...
[SUCCESS] Message executed on destination chain
┌─────────────────┬────────────────────────────────────────────────────────────────────────────────────────────┐
│ (index) │ Values │
├─────────────────┼────────────────────────────────────────────────────────────────────────────────────────────┤
│ state │ '✅ success' │
│ origin │ 'GedMetJrF1cYn3FqS7e1huH8bb4cVxXkVdqhSNdgz5K6' │
│ contract │ 'offqSMQWgQud6WJz694LRzkeN5kMYpCHTpXQr3Rkcjm' │
│ transactionHash │ '64SNgMXWoakBk7SZVcKUnBZFyWiGqTZUaRfSGk9ZeiAfBY4oysaVzZnq7KYR8KwyVjFtomao5hjXNGgaoqQjCDp2' │
│ logIndex │ 24 │
│ blockNumber │ 469533190 │
│ timestamp │ '2026-06-15 04:57:10 (18m46s after request)' │
└─────────────────┴────────────────────────────────────────────────────────────────────────────────────────────┘
Optional: Test Rate Limit Enforcement
If you configured rate limits in Phase 3, attempt a transfer that exceeds capacity (25 tokens vs 20-token limit):
# Terminal 1
ccip-cli send \
-s solana-devnet \
-r $SOL_CCIP_ROUTER \
-d ethereum-testnet-sepolia \
--to $ETH_RECEIVER_ADDRESS \
-t $SOL_TOKEN_MINT=25 \
--wallet ~/.config/solana/id.json \
--rpc $SOLANA_DEVNET_RPC \
--rpc $ETHEREUM_SEPOLIA_RPC_URL
Expect RLMaxCapacityExceeded (Error 6015) when limits are enabled.
# Terminal 2 — use the same wallet option as the E→S transfer above
ccip-cli send \
-s ethereum-testnet-sepolia \
-r $ETH_CCIP_ROUTER \
-d solana-devnet \
--to $SOL_WALLET_ADDRESS \
-t $ETH_TOKEN_ADDRESS=25 \
--wallet hardhat:<YOUR_KEYSTORE_ACCOUNT_NAME> \
--rpc $ETHEREUM_SEPOLIA_RPC_URL \
--rpc $SOLANA_DEVNET_RPC
Expect TokenMaxCapacityExceeded (selector 0x1a76572a) when limits are enabled.
Optional: Verify Rate Limit Configuration
If you configured rate limits in Phase 3, confirm they appear in your chain configuration:
# Terminal 1 — inspect Solana outbound/inbound rate limits
pnpm bs58 --env devnet burnmint-token-pool \
--instruction get-chain-config \
--program-id $SOL_CCIP_POOL_PROGRAM \
--mint $SOL_TOKEN_MINT \
--remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR
# Terminal 2 — inspect EVM rate limit settings
npx hardhat getPoolConfig \
--pooladdress $ETH_POOL_ADDRESS \
--network ethereumSepolia
Congratulations! Your production cross-chain token infrastructure with Squads governance is fully configured on both chains.