cctp-rs
A production-ready Rust implementation of Circle's Cross-Chain Transfer Protocol (CCTP), enabling seamless USDC transfers across blockchain networks.
Features
- 🚀 Type-safe contract interactions using Alloy
- 🔄 Multi-chain support for 26+ mainnet and testnet networks
- 📦 Builder pattern for intuitive API usage
- ⚡ CCTP v2 support with fast transfers (<30s settlement)
- 🤝 Relayer-aware APIs for permissionless v2 relay handling
- 🎯 Programmable hooks for advanced use cases
- 🔍 Comprehensive observability with OpenTelemetry integration
- 🤖 Agent/tooling-friendly message inspection with serializable v2 parsers
Supported Chains
CCTP v2 (Current)
Mainnet
- Ethereum, Arbitrum, Base, Optimism, Avalanche, Polygon, Unichain
- Linea, Sonic, Sei (v2-only chains)
Testnet
- Sepolia, Arbitrum Sepolia, Base Sepolia, Optimism Sepolia
- Avalanche Fuji, Polygon Amoy
CCTP v1 (Legacy)
Also supported for backwards compatibility
Quick Start
Add to your Cargo.toml:
[]
= "2"
Basic Example
use ;
use NamedChain;
use ;
use ;
async
Bridging USDC (V1)
use ;
use NamedChain;
use ;
use Provider;
async
Bridging USDC (V2 - Recommended)
use ;
use NamedChain;
use ;
use Provider;
async
Agent Tooling: Inspect a Canonical V2 Message
Tooling layers usually need structured JSON instead of raw message bytes. ParsedV2Message
and ParsedV2MessageSummary decode the canonical message returned by Circle's v2 API
into serializable Rust types.
Parsing failures return ParseMessageError, so this inspection path does not expand the
existing CctpError surface used by bridge operations.
DomainId values in serialized summaries use snake_case strings. Future releases may
add new domain variants, so older tooling should treat unknown domain strings as a
forward-compatibility case.
use ;
async
Architecture
The library is organized into several key modules:
bridge- Core CCTP bridge implementationchain- Chain-specific configurations and supportattestation- Attestation response types from Circle's Iris APIprotocol- Serializable protocol types plus canonical v2 message parsingerror- Comprehensive error types for proper error handlingcontracts- Type-safe bindings for TokenMessenger and MessageTransmitter
Error Handling
cctp-rs provides detailed error types for different failure scenarios:
use ;
// V1 example
match bridge.get_attestation.await
// V2 example (returns both message and attestation)
match v2_bridge.get_attestation.await
Advanced Usage
Custom Polling Configuration
use PollingConfig;
// V1: Wait up to 10 minutes with 30-second intervals
let attestation = bridge.get_attestation.await?;
// V2: Use preset for fast transfers (5 second intervals)
let = v2_bridge.get_attestation.await?;
// V2: Or customize for your needs
let = v2_bridge.get_attestation.await?;
// Check total timeout
let config = default;
println!;
Chain Configuration
use ;
use NamedChain;
// Get v1 chain-specific information
let chain = Arbitrum;
let confirmation_time = chain.confirmation_average_time_seconds?; // Standard: 19 minutes
let domain_id = chain.cctp_domain_id?;
let token_messenger = chain.token_messenger_address?;
println!;
// Get v2 attestation times (choose based on transfer mode)
let fast_time = chain.fast_transfer_confirmation_time_seconds?; // ~8 seconds
let standard_time = chain.standard_transfer_confirmation_time_seconds?; // ~19 minutes
println!;
println!;
Relayer-Aware Patterns (V2)
CCTP v2 is permissionless - anyone can relay a message once Circle's attestation is available. Third-party relayers (Synapse, LI.FI, etc.) actively monitor for burns and may complete transfers before your application does. This is a feature, not a bug!
Option A: Wait for Completion (Recommended)
If you don't need to self-relay, just wait for the transfer to complete:
use ;
async
Option B: Self-Relay with Graceful Handling
If you want to try minting yourself but handle relayer races:
use ;
async
Option C: Check Status Manually
let is_complete = bridge.is_message_received.await?;
if is_complete
Examples
Check out the examples/ directory for complete working examples:
CCTP v2 Examples
v2_integration_validation.rs- Comprehensive v2 validation (no network required)v2_standard_transfer.rs- Standard transfer with finalityv2_fast_transfer.rs- Fast transfer (<30s settlement)
CCTP v1 Examples (Legacy)
basic_bridge.rs- Simple USDC bridge exampleattestation_monitoring.rs- Monitor attestation statusmulti_chain.rs- Bridge across multiple chains
Run examples with:
# Recommended: Run v2 integration validation
# Or run specific examples
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Testing
Unit Tests
Run the full test suite with:
All 155 unit tests validate:
- Contract method selection logic
- Domain ID resolution and mapping
- Configuration validation
- URL construction for Circle's Iris API
- Error handling and edge cases
- Cross-chain compatibility
- Fast transfer support
- Hooks integration
Integration Validation
We provide comprehensive runnable examples that validate the complete v2 API without requiring network access:
# Validate all v2 configurations (no network required)
# Educational examples showing complete flows
The v2_integration_validation example validates:
- Chain support matrix (26+ chains)
- Domain ID mappings against Circle's official values
- Contract address consistency (unified v2 addresses)
- Bridge configuration variations (standard, fast, hooks)
- API endpoint construction (mainnet vs testnet)
- Fast transfer support and fee structures
- Error handling for unsupported chains
- Cross-chain compatibility
Live Testnet Testing
For pre-release validation on testnet:
- Get testnet tokens from Circle's faucet
- Update examples with your addresses and RPC endpoints
- Set environment variables for private keys
- Execute and monitor the full flow
Note: Integration tests requiring Circle's Iris API and live blockchains are not run in CI due to:
- Cost (gas fees on every test run)
- Time (10-15 minutes per transfer for attestation)
- Flakiness (network dependencies and rate limits)
- Complexity (requires funded wallets with private keys)
Instead, we validate via extensive unit tests and runnable examples. This approach ensures reliability while maintaining fast CI/CD pipelines.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Acknowledgments
- Circle for creating CCTP
- Alloy for the excellent Ethereum libraries
- The Rust community for amazing tools and support