# CCIP Integration Guide for Developers **Date**: 2025-01-27 **Network**: ChainID 138 (DeFi Oracle Meta Mainnet) --- ## Overview This guide provides technical details for developers integrating with CCIP infrastructure on ChainID 138. --- ## Architecture ### Components 1. **CCIP Router**: Routes messages between chains 2. **CCIP Bridges**: Handle token transfers 3. **CCIP Sender/Receiver**: Handle oracle data transmission ### Message Flow ``` Source Chain → CCIP Router → Destination Chain → CCIP Router → Receiver ``` --- ## Integration Patterns ### Pattern 1: Token Bridge Integration ```solidity // Import bridge interface import "./IC CIPWETH9Bridge.sol"; contract MyContract { CCIPWETH9Bridge public bridge; function transferCrossChain( uint64 destinationSelector, address recipient, uint256 amount ) external { // Approve bridge weth9.approve(address(bridge), amount); // Send cross-chain bytes32 messageId = bridge.sendCrossChain( destinationSelector, recipient, amount ); emit TransferInitiated(messageId, destinationSelector, amount); } } ``` ### Pattern 2: Oracle Data Integration ```solidity import "./CCIPSender.sol"; import "./CCIPReceiver.sol"; contract MyOracleContract { CCIPSender public sender; CCIPReceiver public receiver; function sendOracleUpdate( uint64 destinationSelector, uint256 answer, uint256 roundId, uint256 timestamp ) external payable { bytes32 messageId = sender.sendOracleUpdate{value: msg.value}( destinationSelector, answer, roundId, timestamp ); } function ccipReceive( IRouterClient.Any2EVMMessage calldata message ) external { // Process received oracle data (uint256 answer, uint256 roundId, uint256 timestamp) = abi.decode(message.data, (uint256, uint256, uint256)); // Update oracle updateOracle(answer, roundId, timestamp); } } ``` ### Pattern 3: Custom Message Sending ```solidity import "./IRouterClient.sol"; contract MyCustomContract { IRouterClient public router; function sendCustomMessage( uint64 destinationSelector, address receiver, bytes memory data ) external payable { IRouterClient.EVM2AnyMessage memory message = IRouterClient.EVM2AnyMessage({ receiver: abi.encode(receiver), data: data, tokenAmounts: new IRouterClient.TokenAmount[](0), feeToken: address(0), // Native ETH extraArgs: "" }); uint256 fee = router.getFee(destinationSelector, message); (bytes32 messageId, ) = router.ccipSend{value: fee}( destinationSelector, message ); emit MessageSent(messageId, destinationSelector); } } ``` --- ## Interfaces ### IRouterClient ```solidity interface IRouterClient { function ccipSend( uint64 destinationChainSelector, EVM2AnyMessage memory message ) external payable returns (bytes32 messageId, uint256 fees); function getFee( uint64 destinationChainSelector, EVM2AnyMessage memory message ) external view returns (uint256 fee); } ``` ### CCIPWETH9Bridge / CCIPWETH10Bridge ```solidity interface ICCIPBridge { function sendCrossChain( uint64 destinationChainSelector, address recipient, uint256 amount ) external returns (bytes32 messageId); function calculateFee( uint64 destinationChainSelector, uint256 amount ) external view returns (uint256 fee); function ccipReceive( IRouterClient.Any2EVMMessage calldata message ) external; } ``` --- ## Event Monitoring ### Router Events ```solidity event MessageSent( bytes32 indexed messageId, uint64 indexed destinationChainSelector, address indexed sender, bytes receiver, bytes data, TokenAmount[] tokenAmounts, address feeToken, bytes extraArgs ); event MessageReceived( bytes32 indexed messageId, uint64 indexed sourceChainSelector, address indexed sender, bytes data, TokenAmount[] tokenAmounts ); ``` ### Bridge Events ```solidity event CrossChainTransferInitiated( bytes32 indexed messageId, address indexed sender, uint64 indexed destinationChainSelector, address recipient, uint256 amount, uint256 nonce ); event CrossChainTransferCompleted( bytes32 indexed messageId, uint64 indexed sourceChainSelector, address indexed recipient, uint256 amount ); ``` --- ## Error Handling ### Common Errors ```solidity // Router errors "CCIPRouter: chain not supported" "CCIPRouter: insufficient native token fee" "CCIPRouter: duplicate message" // Bridge errors "CCIPWETH9Bridge: destination not enabled" "CCIPWETH9Bridge: transfer failed" "CCIPWETH9Bridge: transfer already processed" ``` ### Error Handling Pattern ```solidity try bridge.sendCrossChain(selector, recipient, amount) returns (bytes32 messageId) { emit TransferSuccess(messageId); } catch Error(string memory reason) { emit TransferFailed(reason); } catch (bytes memory lowLevelData) { emit TransferFailed("Low-level error"); } ``` --- ## Testing ### Unit Tests ```solidity function testCrossChainTransfer() public { // Setup uint256 amount = 1 ether; uint64 destSelector = 5009297550715157269; // Ethereum Mainnet // Approve weth9.approve(address(bridge), amount); // Send bytes32 messageId = bridge.sendCrossChain(destSelector, recipient, amount); // Verify assertTrue(messageId != bytes32(0)); emit TransferInitiated(messageId); } ``` ### Integration Tests Test end-to-end flow: 1. Send message on source chain 2. Verify message received on destination 3. Verify state changes 4. Test error cases --- ## Gas Optimization ### Tips 1. **Batch Operations**: Group multiple operations when possible 2. **Optimize Data**: Minimize message data size 3. **Cache Values**: Cache frequently accessed values 4. **Use Events**: Emit events instead of storage for logging ### Gas Estimates - **Router Message**: ~50,000 - 100,000 gas - **Bridge Transfer**: ~100,000 - 200,000 gas - **Fee Calculation**: ~5,000 gas (view function) --- ## Best Practices 1. **Always Calculate Fees**: Don't hardcode fee amounts 2. **Handle Errors**: Implement comprehensive error handling 3. **Monitor Events**: Track all CCIP events 4. **Verify Addresses**: Always verify contract addresses 5. **Test Thoroughly**: Test on testnet before mainnet --- ## Related Documentation - [CCIP Deployment Guide](../ccip/DEPLOYMENT_GUIDE_CHAIN138.md) - [User Guide](../user-guides/CCIP_BRIDGE_USER_GUIDE.md) - [CCIP Review](../CCIP_CHAIN138_REVIEW.md) --- **Last Updated**: 2025-01-27