# CCIP Relay Service Custom relay mechanism for delivering CCIP messages from Chain 138 to Ethereum Mainnet. ## Architecture The relay system consists of: 1. **CCIPRelayRouter** (on Ethereum Mainnet): Receives relayed messages and forwards them to bridge contracts 2. **CCIPRelayBridge** (on Ethereum Mainnet): Receives messages from relay router and transfers tokens to recipients 3. **Relay Service** (off-chain): Monitors MessageSent events on Chain 138 and relays messages to Ethereum Mainnet ## Current Deployment ### Deployed Contracts (Ethereum Mainnet) - **Relay Router**: `0xAd9A228CcEB4cbB612cD165FFB72fE090ff10Afb` - **Relay Bridge**: `0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939` - **WETH9**: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` ### Source Chain (Chain 138) - **CCIP Router**: `0xd49B579DfC5912fA7CAa76893302c6e58f231431` - **WETH9 Bridge**: `0xBBb4a9202716eAAB3644120001cC46096913a3C8` - **WETH9**: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` ## Deployment ### 1. Deploy Relay Contracts on Ethereum Mainnet ```bash cd /home/intlc/projects/proxmox/smom-dbis-138 # Set environment variables export PRIVATE_KEY=0x... export RPC_URL_MAINNET=https://eth.llamarpc.com export WETH9_MAINNET=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 export RELAYER_ADDRESS=0x... # Address that will run relay service # Deploy forge script script/DeployCCIPRelay.s.sol:DeployCCIPRelay \ --rpc-url $RPC_URL_MAINNET \ --broadcast \ --legacy \ --via-ir ``` ### 2. Configure Environment The service uses environment variables. Create `.env` file in `services/relay/`: ```bash # 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=0xAd9A228CcEB4cbB612cD165FFB72fE090ff10Afb CCIP_RELAY_BRIDGE_MAINNET=0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939 # Relayer Configuration PRIVATE_KEY=0x... # Private key for relayer (needs ETH on mainnet for gas) 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 ``` **Important**: If `PRIVATE_KEY` contains variable expansion (e.g., `${PRIVATE_KEY}`), create a `.env.local` file with the expanded value to avoid issues with `dotenv`. ### 3. Install Dependencies ```bash cd services/relay npm install ``` ### 4. Start Relay Service ```bash # Start service npm start # Or use the wrapper script (recommended) ./start-relay.sh ``` ## How It Works 1. **Event Monitoring**: The relay service monitors `MessageSent` events from the CCIP Router on Chain 138 2. **Message Queue**: Detected messages are added to a queue for processing 3. **Token Address Mapping**: Source chain token addresses are mapped to destination chain addresses 4. **Message Relay**: For each message: - Constructs the `Any2EVMMessage` format with mapped token addresses - Calls `relayMessage` on the Relay Router contract on Ethereum Mainnet - Relay Router forwards to Relay Bridge - Relay Bridge calls `ccipReceive` and transfers tokens to recipient ## Configuration Key configuration options in `.env`: - `RPC_URL_138`: RPC endpoint for Chain 138 (default: `http://192.168.11.250:8545`) - `RPC_URL_MAINNET`: RPC endpoint for Ethereum Mainnet (default: `https://eth.llamarpc.com`) - `PRIVATE_KEY` or `RELAYER_PRIVATE_KEY`: Private key for relayer (needs ETH on mainnet for gas) - `START_BLOCK`: Block number to start monitoring from (default: `latest` or specific block number) - `POLL_INTERVAL`: How often to poll for new events in milliseconds (default: `5000`) - `CONFIRMATION_BLOCKS`: Number of confirmations to wait before processing (default: `1`) - `MAX_RETRIES`: Maximum retry attempts for failed relays (default: `3`) - `RETRY_DELAY`: Delay between retries in milliseconds (default: `5000`) ## Critical Requirements ### Bridge Funding **The relay bridge must be funded with WETH9 tokens before it can complete transfers.** - Bridge Address: `0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939` - WETH9 Address: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` - Current Status: Bridge must have sufficient WETH9 to cover all transfers To check bridge balance: ```bash cast call 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \ "balanceOf(address)" \ 0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939 \ --rpc-url $RPC_URL_MAINNET ``` To fund the bridge (if you have WETH9): ```bash cast send 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \ "transfer(address,uint256)" \ 0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939 \ 20000000000000000000000 \ --rpc-url $RPC_URL_MAINNET \ --private-key $PRIVATE_KEY ``` ## Security Considerations - **Relayer Role**: Only addresses with relayer role can call `relayMessage` - **Bridge Authorization**: Only authorized bridges can receive messages - **Replay Protection**: Messages are tracked by messageId to prevent duplicate processing - **Access Control**: Admin can add/remove bridges and relayers - **Token Address Mapping**: Source chain token addresses are mapped to destination chain addresses ## Monitoring The service logs all activities. Check logs for: - `relay-service.log`: Combined log output - Console output: Real-time status Monitor key metrics: - Messages detected per hour - Messages relayed successfully - Failed relay attempts - Bridge WETH9 balance ## Troubleshooting ### Service won't start 1. Check all environment variables are set correctly 2. Verify RPC endpoints are accessible 3. Ensure private key is valid and properly expanded (use `.env.local` if needed) 4. Check Node.js and npm are installed ### Messages not being relayed 1. Check relayer has ETH for gas on mainnet 2. Verify relay router and bridge addresses are correct 3. Ensure relayer address has RELAYER_ROLE 4. Check bridge is authorized in router 5. Verify bridge has sufficient WETH9 balance ### Relay transactions failing 1. **Most common**: Bridge has insufficient WETH9 tokens - fund the bridge 2. Check gas limit is sufficient (default: 1,000,000) 3. Verify message format is correct 4. Review error logs for specific revert reasons 5. Check transaction receipt for revert reason ### High gas costs - Adjust gas limit in `RelayService.js` if needed - Monitor gas prices and adjust timing if possible - Consider message batching for future improvements ## Development ```bash # Run in development mode with auto-reload npm run dev # Run tests (if available) npm test ``` ## Related Documentation - [Architecture Documentation](../docs/relay/ARCHITECTURE.md) - [Deployment Guide](DEPLOYMENT_GUIDE.md) - [Investigation Report](../docs/relay/INVESTIGATION_REPORT.md)