Odos Rust SDK
A production-ready Rust SDK for Odos - the decentralized exchange aggregator that finds optimal token swap routes across 16+ EVM chains. Built with type safety, reliability, and developer experience in mind.
What Makes This Special
Optimal pricing through advanced routing - Odos analyzes paths across hundreds of DEXes and liquidity sources, splitting trades intelligently to minimize slippage and maximize output. The SDK makes this power accessible in just a few lines of Rust.
Battle-tested for production:
- Smart retry logic with exponential backoff for network resilience
- Structured error codes with clear categorization and trace IDs
- Rate limit detection with
Retry-Aftersupport - Full type safety via Alloy primitives (no string addresses or numeric guessing)
- Connection pooling, configurable timeouts, and graceful degradation
- Comprehensive logging and observability with
tracing
APIs for every use case:
- High-level
SwapBuilder- integrate swaps in minutes - Mid-level
quote→assemble- full control over the flow - Low-level contract bindings - advanced scenarios and direct router access
Quick Start
Add the SDK to your project:
[]
= "1.0"
Your First Swap
use *;
use ;
async
Three concepts, one builder, zero complexity. The SDK handles quote fetching, optimal routing, transaction assembly, and error recovery automatically.
Next steps: Check out GETTING_STARTED.md for a complete walkthrough, or jump to EXAMPLES.md for common patterns.
Core Features
Multi-Chain Support
Supports 16+ EVM chains out of the box:
| Category | Chains |
|---|---|
| Layer 1 | Ethereum |
| Layer 2 | Arbitrum, Optimism, Base, Polygon, zkSync, Scroll, Linea, Mantle, Mode |
| Sidechains | BSC, Avalanche, Fraxtal, Sonic, Unichain |
Chain selection is type-safe and simple:
let chain = ethereum; // or arbitrum(), optimism(), etc.
let chain = from_chain_id?; // From numeric ID
Complete Type Safety
Built on the Alloy ecosystem for bulletproof type safety:
use ;
// Parse addresses at compile time or runtime
let token: Address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48".parse?;
// Handle amounts with U256 (no floating point errors)
let one_usdc = U256from; // 6 decimals
// Validated slippage
let slippage = percent?; // 0.5%
let slippage = bps?; // 50 basis points
Resilient Error Handling
Structured errors with clear categorization:
use ;
match client.quote.await
Error codes match the Odos API documentation with type-safe categorization:
- 1XXX: General API errors
- 2XXX: Quote/routing errors (
NoViablePath,AlgoTimeout, etc.) - 3XXX: Internal service errors
- 4XXX: Validation errors (
InvalidChainId,InvalidTokenAmount, etc.) - 5XXX: Internal errors
Smart Retry Logic
Configurable retry behavior with exponential backoff:
use Duration;
use ;
// Conservative preset - only retry network errors
let client = with_retry_config?;
// Custom retry configuration
let client = with_retry_config?;
Rate limits are detected but not automatically retried - you control the global rate limiting strategy.
Three Ways to Swap
The SDK provides three levels of abstraction. Choose based on your needs:
1. High-Level: SwapBuilder
Perfect for most use cases. One builder, automatic flow:
use *;
let tx = client.swap
.chain
.from_token
.to_token
.slippage
.signer
.recipient // Optional: send output to different address
.build_transaction
.await?;
// Or just get a quote first
let quote = client.swap
.chain
.from_token
.to_token
.slippage
.signer
.quote
.await?;
println!;
2. Mid-Level: Quote + Assemble
More control over the quote and assembly phases:
use *;
// Step 1: Request quote
let quote_request = builder
.chain_id
.input_tokens
.output_tokens
.slippage_limit_percent
.user_addr
.compact
.simple
.referral_code
.disable_rfqs
.build;
let quote = client.quote.await?;
// Show user the expected output
println!;
// Step 2: User confirms, assemble transaction
let assembly_request = builder
.chain
.router_address
.signer_address
.output_recipient
.token_address
.token_amount
.path_id
.build;
let tx = client.assemble.await?;
3. Low-Level: Contract Bindings
Direct router contract access for advanced scenarios:
use ;
use NamedChain;
let router_address = Mainnet.v2_router_address?;
let router = new;
// Call contract methods directly
let result = router.swap.send.await?;
Configuration
Basic Configuration
use ;
use Duration;
let config = ClientConfig ;
let client = with_config?;
API Endpoints
Choose between public and enterprise endpoints:
use ;
// Public API (default)
let config = ClientConfig ;
// Enterprise API with higher rate limits
let config = ClientConfig ;
let client = with_config?;
Feature Flags
Customize what gets compiled based on your needs:
# Default: V2 + V3 routers
[]
= "1.0"
# Minimal: Just API types and HTTP client (no contract bindings)
[]
= { = "1.0", = false, = ["minimal"] }
# All contracts: V2 + V3 + Limit Orders
[]
= { = "1.0", = false, = ["contracts"] }
# Custom combination
[]
= { = "1.0", = false, = ["v2", "v3"] }
Available features:
minimal- Core API types and HTTP client onlyv2- V2 router contract bindingsv3- V3 router contract bindings (includes v2)limit-orders- Limit order contract bindings (includes v2)contracts- All contract bindings (v2 + v3 + limit-orders)default- V2 + V3 routers
Documentation
| Resource | Description |
|---|---|
| GETTING_STARTED.md | Complete walkthrough from setup to your first swap |
| EXAMPLES.md | Real-world patterns: error handling, testing, integration |
| API Docs | Complete API reference with inline examples |
| ERROR_HANDLING_GUIDE.md | Deep dive into error types and recovery strategies |
| CHANGELOG.md | Version history and migration guides |
| SECURITY.md | Security best practices and vulnerability reporting |
Advanced Topics
Rate Limiting Strategy
The SDK detects rate limits but doesn't retry them automatically. Implement your own strategy:
use Duration;
use sleep;
async
For production applications with high request volumes:
- Share a single
OdosClientinstance across your application - Implement a token bucket or leaky bucket algorithm
- Consider using a rate limiting library like
governor - Monitor rate limit errors and adjust your request rate dynamically
Router Versioning
The SDK supports multiple router versions with different capabilities:
use ;
use NamedChain;
let chain = Mainnet;
let availability = chain.router_availability?;
if availability.v3 else if availability.v2
if availability.limit_order
V3 router features:
- Deployed at the same address on all supported chains (CREATE2)
- Enhanced gas efficiency
- Improved MEV protection
Chain Support Detection
Check if a chain is supported before attempting operations:
use OdosChain;
use NamedChain;
let chain = Mainnet;
// Check general Odos support
if chain.supports_odos
// Check specific router availability
let availability = chain.router_availability?;
println!;
Examples
See EXAMPLES.md for comprehensive examples including:
- Multi-token swaps
- Error recovery and retry strategies
- Integration with wallets (ethers-rs, foundry)
- Gas estimation and optimization
- Testing with mocks
- Cross-chain workflows
- Production deployment patterns
Quick example - handling errors gracefully:
use *;
async
Contributing
We welcome contributions! Please see CONTRIBUTING.md for:
- Development setup (Rust 1.92+)
- Code standards and formatting
- Testing requirements
- PR process
- Release workflow
Quick development commands:
# Build
# Run tests
# Lint (CI enforces zero warnings)
# Format
# Security audit
Support
- Issues: GitHub Issues
- Odos Documentation: docs.odos.xyz
- Odos Discord: discord.gg/odos
Security
Security is a top priority. Please report vulnerabilities to security@semiotic.ai. See SECURITY.md for:
- Vulnerability reporting process
- API key security best practices
- Input validation guidelines
- Production deployment checklist
License
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Acknowledgments
Built with the excellent Alloy ecosystem for Ethereum interactions.
Ready to integrate? Start with GETTING_STARTED.md or dive into EXAMPLES.md for practical patterns.