use alloy_chains::NamedChain;
use cctp_rs::{CctpError, CctpV1};
fn main() -> Result<(), CctpError> {
println!("🌐 Multi-Chain CCTP Configuration Example");
println!("========================================\n");
display_supported_chains()?;
compare_chain_configs()?;
display_routing_matrix()?;
Ok(())
}
fn display_supported_chains() -> Result<(), CctpError> {
println!("📋 Supported Chains:\n");
let chains = vec![
("Ethereum", NamedChain::Mainnet),
("Arbitrum", NamedChain::Arbitrum),
("Base", NamedChain::Base),
("Optimism", NamedChain::Optimism),
("Avalanche", NamedChain::Avalanche),
("Polygon", NamedChain::Polygon),
("Unichain", NamedChain::Unichain),
("Sepolia", NamedChain::Sepolia),
("Arbitrum Sepolia", NamedChain::ArbitrumSepolia),
("Base Sepolia", NamedChain::BaseSepolia),
("Optimism Sepolia", NamedChain::OptimismSepolia),
("Avalanche Fuji", NamedChain::AvalancheFuji),
("Polygon Amoy", NamedChain::PolygonAmoy),
];
println!("Mainnets:");
for (name, chain) in chains.iter().take(7) {
if chain.is_supported() {
let domain_id = chain.cctp_domain_id()?;
println!(" ✅ {name} (Domain ID: {domain_id})");
}
}
println!("\nTestnets:");
for (name, chain) in chains.iter().skip(7) {
if chain.is_supported() {
let domain_id = chain.cctp_domain_id()?;
println!(" ✅ {name} (Domain ID: {domain_id})");
}
}
Ok(())
}
fn compare_chain_configs() -> Result<(), CctpError> {
println!("\n⏱️ Chain Confirmation Times:\n");
let mut configs: Vec<(String, u64)> = Vec::new();
let chains = vec![
("Ethereum", NamedChain::Mainnet),
("Arbitrum", NamedChain::Arbitrum),
("Avalanche", NamedChain::Avalanche),
("Polygon", NamedChain::Polygon),
];
for (name, chain) in chains {
let confirmation_time = chain.confirmation_average_time_seconds()?;
configs.push((name.to_string(), confirmation_time));
}
configs.sort_by_key(|k| k.1);
for (name, time) in configs {
let minutes = time / 60;
let seconds = time % 60;
let time_str = if minutes > 0 {
format!("{minutes} min {seconds} sec")
} else {
format!("{seconds} sec")
};
let emoji = get_speed_emoji(time);
println!(" {emoji} - {name}: {time_str}");
}
Ok(())
}
fn display_routing_matrix() -> Result<(), CctpError> {
println!("\n🔀 Routing Matrix (Sample Routes):\n");
let routes = vec![
("Ethereum", "Arbitrum", "Most popular L1 → L2 route"),
("Ethereum", "Base", "Coinbase's L2 solution"),
("Arbitrum", "Optimism", "L2 → L2 routing"),
("Polygon", "Avalanche", "Cross-chain DeFi"),
];
for (source, dest, description) in routes {
println!(" {source} → {dest}");
println!(" └─ {description}");
let source_chain = match source {
"Ethereum" => NamedChain::Mainnet,
"Arbitrum" => NamedChain::Arbitrum,
"Polygon" => NamedChain::Polygon,
_ => continue,
};
let dest_chain = match dest {
"Arbitrum" => NamedChain::Arbitrum,
"Base" => NamedChain::Base,
"Optimism" => NamedChain::Optimism,
"Avalanche" => NamedChain::Avalanche,
_ => continue,
};
let source_domain = source_chain.cctp_domain_id()?;
let dest_domain = dest_chain.cctp_domain_id()?;
println!(" └─ Domain IDs: {source_domain} → {dest_domain}\n");
}
Ok(())
}
fn get_speed_emoji(seconds: u64) -> &'static str {
match seconds {
0..=60 => "🚀", 61..=300 => "⚡", 301..=900 => "🔄", _ => "⏳", }
}