# CCIP Relay Deployment Guide This guide walks through deploying and configuring the custom CCIP relay mechanism. ## Prerequisites 1. **Ethereum Mainnet Access** - RPC endpoint for Ethereum Mainnet - Private key with ETH for gas fees - Sufficient ETH for contract deployment and relay operations 2. **WETH9 on Ethereum Mainnet** - Address: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` - **Bridge contract needs WETH9 tokens to transfer to recipients** (CRITICAL) 3. **Chain 138 Access** - RPC endpoint for Chain 138 - Access to router contract that emits MessageSent events ## Current Deployment ### Deployed Contracts (Ethereum Mainnet) - **Relay Router**: `0x416564Ab73Ad5710855E98dC7bC7Bff7387285BA` - **Relay Bridge**: `0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939` - **Additional Mainnet cW bridge**: `0x2bF74583206A49Be07E0E8A94197C12987AbD7B5` - **WETH9**: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` ### Source Chain (Chain 138) - **CCIP Router**: `0xd49B579DfC5912fA7CAa76893302c6e58f231431` - **WETH9 Bridge**: `0xBBb4a9202716eAAB3644120001cC46096913a3C8` - **WETH9**: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` ## Deployment Steps ### Step 1: Deploy Relay Contracts on Ethereum Mainnet ```bash cd /home/intlc/projects/proxmox/smom-dbis-138 # Set environment variables export PRIVATE_KEY=0x... # Your private key export RPC_URL_MAINNET=https://eth.llamarpc.com # Your mainnet RPC export WETH9_MAINNET=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 # Generate relayer address from private key (or use existing) export RELAYER_ADDRESS=$(cast wallet address $PRIVATE_KEY) # Deploy contracts forge script script/DeployCCIPRelay.s.sol:DeployCCIPRelay \ --rpc-url $RPC_URL_MAINNET \ --broadcast \ --legacy \ --via-ir \ --gas-price $(cast gas-price --rpc-url $RPC_URL_MAINNET) ``` After deployment, note the addresses: - `CCIPRelayRouter` address - `CCIPRelayBridge` address **Configuration Steps After Deployment:** ```bash # Set variables export RELAY_ROUTER=0x... # From deployment export RELAY_BRIDGE=0x... # From deployment # Authorize bridge in router cast send $RELAY_ROUTER \ "authorizeBridge(address)" \ $RELAY_BRIDGE \ --rpc-url $RPC_URL_MAINNET \ --private-key $PRIVATE_KEY \ --legacy # Grant relayer role cast send $RELAY_ROUTER \ "grantRelayerRole(address)" \ $RELAYER_ADDRESS \ --rpc-url $RPC_URL_MAINNET \ --private-key $PRIVATE_KEY \ --legacy ``` ### Step 2: Fund Relay Bridge with WETH9 ⚠️ CRITICAL **The relay bridge MUST be funded with WETH9 tokens before it can complete any transfers.** ```bash # Check WETH9 balance cast call 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \ "balanceOf(address)" \ $RELAY_BRIDGE_ADDRESS \ --rpc-url $RPC_URL_MAINNET # Transfer WETH9 to bridge (if you have WETH9) cast send 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \ "transfer(address,uint256)" \ $RELAY_BRIDGE_ADDRESS \ 20000000000000000000000 \ --rpc-url $RPC_URL_MAINNET \ --private-key $PRIVATE_KEY \ --legacy ``` **Important**: - The bridge must have sufficient WETH9 to cover all pending transfers - For the current pending transfer, at least 20,000 WETH9 is required - Consider funding with more than the minimum to handle multiple transfers ### Step 3: Configure Relay Service Create `.env` file in `services/relay/`: ```bash cd services/relay cat > .env << 'ENVEOF' # Source Chain (Chain 138) RPC_URL_138=http://192.168.11.250:8545 CCIP_ROUTER_CHAIN138=0xd49B579DfC5912fA7CAa76893302c6e58f231431 CCIPWETH9_BRIDGE_CHAIN138=0xBBb4a9202716eAAB3644120001cC46096913a3C8 # Destination Chain (Ethereum Mainnet) RPC_URL_MAINNET=https://eth.llamarpc.com CCIP_RELAY_ROUTER_MAINNET=0x416564Ab73Ad5710855E98dC7bC7Bff7387285BA CCIP_RELAY_BRIDGE_MAINNET=0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939 DEST_RELAY_BRIDGE_ALLOWLIST=0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939,0x2bF74583206A49Be07E0E8A94197C12987AbD7B5 # Relayer Configuration PRIVATE_KEY=0x... # Your private key (or use RELAYER_PRIVATE_KEY) RELAYER_PRIVATE_KEY=${PRIVATE_KEY} # Alternative name # Monitoring Configuration START_BLOCK=latest # or specific block number (e.g., 242500) POLL_INTERVAL=5000 # milliseconds CONFIRMATION_BLOCKS=1 # Retry Configuration MAX_RETRIES=3 RETRY_DELAY=5000 # milliseconds # Chain Selectors SOURCE_CHAIN_ID=138 DESTINATION_CHAIN_SELECTOR=5009297550715157269 ENVEOF ``` **Note**: If `PRIVATE_KEY` contains variable expansion (e.g., `${PRIVATE_KEY}`), create a `.env.local` file with the expanded value: ```bash # In services/relay/.env.local PRIVATE_KEY=0x...actual_private_key_here... RELAYER_PRIVATE_KEY=0x...actual_private_key_here... ``` ### Step 4: Install Dependencies ```bash cd services/relay npm install ``` ### Step 5: Test Configuration ```bash # Check relayer has ETH on mainnet cast balance $RELAYER_ADDRESS --rpc-url $RPC_URL_MAINNET # Check relay router configuration cast call $RELAY_ROUTER_ADDRESS \ "authorizedBridges(address)" \ $RELAY_BRIDGE_ADDRESS \ --rpc-url $RPC_URL_MAINNET # Should return: 0x0000000000000000000000000000000000000000000000000000000000000001 (true) # Check relayer has role RELAYER_ROLE=$(cast keccak "RELAYER_ROLE" | cut -c1-66) cast call $RELAY_ROUTER_ADDRESS \ "hasRole(bytes32,address)" \ $RELAYER_ROLE \ $RELAYER_ADDRESS \ --rpc-url $RPC_URL_MAINNET # Should return: 0x0000000000000000000000000000000000000000000000000000000000000001 (true) # Check bridge WETH9 balance cast call 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \ "balanceOf(address)" \ $RELAY_BRIDGE_ADDRESS \ --rpc-url $RPC_URL_MAINNET ``` ### Step 6: Start Relay Service ```bash # Using the wrapper script (recommended) ./start-relay.sh # Or directly npm start ``` The service will: 1. Monitor MessageSent events from Chain 138 router 2. Queue messages for relay 3. Relay messages to Ethereum Mainnet 4. Log all activities to `relay-service.log` ## Verification ### Check Service Status Monitor the logs: ```bash # Real-time logs tail -f relay-service.log # Check for errors tail -f relay-service.log | grep -i error ``` ### Test Message Relay 1. Initiate a bridge transfer on Chain 138 2. Watch logs for message detection: ```bash tail -f relay-service.log | grep "MessageSent" ``` 3. Verify relay transaction on Ethereum Mainnet 4. Check recipient received WETH9 ### Monitor Relay Bridge ```bash # Check bridge WETH9 balance cast call 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \ "balanceOf(address)" \ $RELAY_BRIDGE_ADDRESS \ --rpc-url $RPC_URL_MAINNET # Check if message was processed MESSAGE_ID=0x... # From the MessageSent event cast call $RELAY_BRIDGE_ADDRESS \ "processedTransfers(bytes32)" \ $MESSAGE_ID \ --rpc-url $RPC_URL_MAINNET # Returns: 0x0000000000000000000000000000000000000000000000000000000000000001 if processed ``` ## Troubleshooting ### Service won't start - Check all environment variables are set correctly - Verify RPC endpoints are accessible - Ensure private key is valid and properly expanded - Check Node.js and npm are installed (`node --version && npm --version`) - Check for errors in log output ### Messages not being relayed - Check relayer has sufficient ETH for gas on mainnet - Verify relay router has bridge authorized (see Step 1) - Ensure relayer has RELAYER_ROLE (see Step 1) - Check source chain router is emitting events - Verify START_BLOCK is set correctly (before the message was sent) ### Relay transactions failing **Most Common Issue: Bridge has insufficient WETH9 tokens** ```bash # Check bridge balance cast call 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \ "balanceOf(address)" \ $RELAY_BRIDGE_ADDRESS \ --rpc-url $RPC_URL_MAINNET # Fund bridge if needed (see Step 2) ``` Other potential issues: - Check gas limit is sufficient (default: 1,000,000) - Verify message format is correct - Review error logs for specific revert reasons - Check transaction receipt for revert reason: ```bash cast receipt $TX_HASH --rpc-url $RPC_URL_MAINNET ``` ### High gas costs - Consider batching multiple messages (future improvement) - Optimize gas usage in contracts (already optimized) - Monitor gas prices and adjust timing if possible ## Production Considerations 1. **High Availability**: Run multiple relay instances (future improvement) 2. **Monitoring**: Set up alerts for: - Failed relays - Bridge WETH9 balance below threshold - Service downtime 3. **Security**: - Protect private keys (use hardware wallets or key management) - Run service in secure environment - Monitor for suspicious activity 4. **Rate Limiting**: Implement rate limiting to prevent spam (future improvement) 5. **Message Ordering**: Ensure messages are relayed in order (currently sequential) 6. **Bridge Funding**: - **CRITICAL**: Maintain sufficient WETH9 balance - Set up alerts for low balance - Plan for automatic funding (future improvement) 7. **Gas Management**: - Monitor gas prices - Adjust gas limits if needed - Consider gas price strategies ## Next Steps After deployment: 1. Monitor relay service for 24 hours 2. Verify all messages are being relayed successfully 3. Set up monitoring and alerts 4. Document operational procedures 5. Plan for scaling if needed 6. **Ensure bridge is funded with sufficient WETH9** ## Related Documentation - [Service README](README.md) - [Architecture Documentation](../docs/relay/ARCHITECTURE.md) - [Investigation Report](../docs/relay/INVESTIGATION_REPORT.md)