1use std::{
19 fmt::{Display, Formatter},
20 str::FromStr,
21 sync::Arc,
22};
23
24use serde::{Deserialize, Serialize};
25use strum::{Display, EnumIter, EnumString};
26
27#[derive(
29 Debug,
30 Clone,
31 Copy,
32 Hash,
33 PartialOrd,
34 PartialEq,
35 Ord,
36 Eq,
37 Display,
38 EnumIter,
39 EnumString,
40 Serialize,
41 Deserialize,
42)]
43#[non_exhaustive]
44#[strum(ascii_case_insensitive)]
45#[cfg_attr(
46 feature = "python",
47 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.model")
48)]
49pub enum Blockchain {
50 Abstract,
51 Arbitrum,
52 ArbitrumNova,
53 ArbitrumSepolia,
54 Aurora,
55 Avalanche,
56 Base,
57 BaseSepolia,
58 Berachain,
59 BerachainBartio,
60 Blast,
61 BlastSepolia,
62 Boba,
63 Bsc,
64 BscTestnet,
65 Celo,
66 Chiliz,
67 CitreaTestnet,
68 Curtis,
69 Cyber,
70 Darwinia,
71 Ethereum,
72 Fantom,
73 Flare,
74 Fraxtal,
75 Fuji,
76 GaladrielDevnet,
77 Gnosis,
78 GnosisChiado,
79 GnosisTraces,
80 HarmonyShard0,
81 Holesky,
82 HoleskyTokenTest,
83 Hyperliquid,
84 HyperliquidTemp,
85 Ink,
86 InternalTestChain,
87 Kroma,
88 Linea,
89 Lisk,
90 Lukso,
91 LuksoTestnet,
92 Manta,
93 Mantle,
94 MegaethTestnet,
95 Merlin,
96 Metall2,
97 Metis,
98 MevCommit,
99 Mode,
100 MonadTestnet,
101 MonadTestnetBackup,
102 MoonbaseAlpha,
103 Moonbeam,
104 Morph,
105 MorphHolesky,
106 Opbnb,
107 Optimism,
108 OptimismSepolia,
109 PharosDevnet,
110 Polygon,
111 PolygonAmoy,
112 PolygonZkEvm,
113 Rootstock,
114 Saakuru,
115 Scroll,
116 Sepolia,
117 ShimmerEvm,
118 Soneium,
119 Sophon,
120 SophonTestnet,
121 Superseed,
122 Unichain,
123 UnichainSepolia,
124 Xdc,
125 XdcTestnet,
126 Zeta,
127 Zircuit,
128 ZKsync,
129 Zora,
130}
131
132#[cfg_attr(feature = "python", pyo3::pyclass(module = "nautilus_pyo3.model"))]
134#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
135pub struct Chain {
136 pub name: Blockchain,
138 pub chain_id: u32,
140 pub hypersync_url: String,
142 pub rpc_url: Option<String>,
144 pub native_currency_decimals: u8,
146}
147
148pub type SharedChain = Arc<Chain>;
150
151impl Chain {
152 pub fn new(name: Blockchain, chain_id: u32) -> Self {
154 Self {
155 chain_id,
156 name,
157 hypersync_url: format!("https://{chain_id}.hypersync.xyz"),
158 rpc_url: None,
159 native_currency_decimals: 18, }
161 }
162
163 pub fn set_rpc_url(&mut self, rpc: String) {
165 self.rpc_url = Some(rpc);
166 }
167
168 pub fn from_chain_id(chain_id: u32) -> Option<&'static Chain> {
170 match chain_id {
171 2741 => Some(&chains::ABSTRACT),
172 42161 => Some(&chains::ARBITRUM),
173 42170 => Some(&chains::ARBITRUM_NOVA),
174 421614 => Some(&chains::ARBITRUM_SEPOLIA),
175 1313161554 => Some(&chains::AURORA),
176 43114 => Some(&chains::AVALANCHE),
177 8453 => Some(&chains::BASE),
178 84532 => Some(&chains::BASE_SEPOLIA),
179 80094 => Some(&chains::BERACHAIN),
180 80085 => Some(&chains::BERACHAIN_BARTIO),
181 81457 => Some(&chains::BLAST),
182 168587773 => Some(&chains::BLAST_SEPOLIA),
183 288 => Some(&chains::BOBA),
184 56 => Some(&chains::BSC),
185 97 => Some(&chains::BSC_TESTNET),
186 42220 => Some(&chains::CELO),
187 8888 => Some(&chains::CHILIZ),
188 3333 => Some(&chains::CITREA_TESTNET),
189 33111 => Some(&chains::CURTIS),
190 7560 => Some(&chains::CYBER),
191 46 => Some(&chains::DARWINIA),
192 1 => Some(&chains::ETHEREUM),
193 250 => Some(&chains::FANTOM),
194 14 => Some(&chains::FLARE),
195 252 => Some(&chains::FRAXTAL),
196 43113 => Some(&chains::FUJI),
197 696969 => Some(&chains::GALADRIEL_DEVNET),
198 100 => Some(&chains::GNOSIS),
199 10200 => Some(&chains::GNOSIS_CHIADO),
200 10300 => Some(&chains::GNOSIS_TRACES),
201 1666600000 => Some(&chains::HARMONY_SHARD_0),
202 17000 => Some(&chains::HOLESKY),
203 17001 => Some(&chains::HOLESKY_TOKEN_TEST),
204 7979 => Some(&chains::HYPERLIQUID),
205 7978 => Some(&chains::HYPERLIQUID_TEMP),
206 222 => Some(&chains::INK),
207 13337 => Some(&chains::INTERNAL_TEST_CHAIN),
208 255 => Some(&chains::KROMA),
209 59144 => Some(&chains::LINEA),
210 501 => Some(&chains::LISK),
211 42 => Some(&chains::LUKSO),
212 4201 => Some(&chains::LUKSO_TESTNET),
213 169 => Some(&chains::MANTA),
214 5000 => Some(&chains::MANTLE),
215 777 => Some(&chains::MEGAETH_TESTNET),
216 4200 => Some(&chains::MERLIN),
217 90 => Some(&chains::METALL2),
218 1088 => Some(&chains::METIS),
219 11 => Some(&chains::MEV_COMMIT),
220 34443 => Some(&chains::MODE),
221 2323 => Some(&chains::MONAD_TESTNET),
222 2358 => Some(&chains::MONAD_TESTNET_BACKUP),
223 1287 => Some(&chains::MOONBASE_ALPHA),
224 1284 => Some(&chains::MOONBEAM),
225 2710 => Some(&chains::MORPH),
226 2710111 => Some(&chains::MORPH_HOLESKY),
227 204 => Some(&chains::OPBNB),
228 10 => Some(&chains::OPTIMISM),
229 11155420 => Some(&chains::OPTIMISM_SEPOLIA),
230 1337 => Some(&chains::PHAROS_DEVNET),
231 137 => Some(&chains::POLYGON),
232 80002 => Some(&chains::POLYGON_AMOY),
233 1101 => Some(&chains::POLYGON_ZKEVM),
234 30 => Some(&chains::ROOTSTOCK),
235 1204 => Some(&chains::SAAKURU),
236 534352 => Some(&chains::SCROLL),
237 11155111 => Some(&chains::SEPOLIA),
238 148 => Some(&chains::SHIMMER_EVM),
239 109 => Some(&chains::SONEIUM),
240 138 => Some(&chains::SOPHON),
241 139 => Some(&chains::SOPHON_TESTNET),
242 10001 => Some(&chains::SUPERSEED),
243 9999 => Some(&chains::UNICHAIN),
244 9997 => Some(&chains::UNICHAIN_SEPOLIA),
245 50 => Some(&chains::XDC),
246 51 => Some(&chains::XDC_TESTNET),
247 7000 => Some(&chains::ZETA),
248 78600 => Some(&chains::ZIRCUIT),
249 324 => Some(&chains::ZKSYNC),
250 7777777 => Some(&chains::ZORA),
251 _ => None,
252 }
253 }
254
255 pub fn from_chain_name(chain_name: &str) -> Option<&'static Chain> {
259 let blockchain = Blockchain::from_str(chain_name).ok()?;
260
261 match blockchain {
262 Blockchain::Abstract => Some(&chains::ABSTRACT),
263 Blockchain::Arbitrum => Some(&chains::ARBITRUM),
264 Blockchain::ArbitrumNova => Some(&chains::ARBITRUM_NOVA),
265 Blockchain::ArbitrumSepolia => Some(&chains::ARBITRUM_SEPOLIA),
266 Blockchain::Aurora => Some(&chains::AURORA),
267 Blockchain::Avalanche => Some(&chains::AVALANCHE),
268 Blockchain::Base => Some(&chains::BASE),
269 Blockchain::BaseSepolia => Some(&chains::BASE_SEPOLIA),
270 Blockchain::Berachain => Some(&chains::BERACHAIN),
271 Blockchain::BerachainBartio => Some(&chains::BERACHAIN_BARTIO),
272 Blockchain::Blast => Some(&chains::BLAST),
273 Blockchain::BlastSepolia => Some(&chains::BLAST_SEPOLIA),
274 Blockchain::Boba => Some(&chains::BOBA),
275 Blockchain::Bsc => Some(&chains::BSC),
276 Blockchain::BscTestnet => Some(&chains::BSC_TESTNET),
277 Blockchain::Celo => Some(&chains::CELO),
278 Blockchain::Chiliz => Some(&chains::CHILIZ),
279 Blockchain::CitreaTestnet => Some(&chains::CITREA_TESTNET),
280 Blockchain::Curtis => Some(&chains::CURTIS),
281 Blockchain::Cyber => Some(&chains::CYBER),
282 Blockchain::Darwinia => Some(&chains::DARWINIA),
283 Blockchain::Ethereum => Some(&chains::ETHEREUM),
284 Blockchain::Fantom => Some(&chains::FANTOM),
285 Blockchain::Flare => Some(&chains::FLARE),
286 Blockchain::Fraxtal => Some(&chains::FRAXTAL),
287 Blockchain::Fuji => Some(&chains::FUJI),
288 Blockchain::GaladrielDevnet => Some(&chains::GALADRIEL_DEVNET),
289 Blockchain::Gnosis => Some(&chains::GNOSIS),
290 Blockchain::GnosisChiado => Some(&chains::GNOSIS_CHIADO),
291 Blockchain::GnosisTraces => Some(&chains::GNOSIS_TRACES),
292 Blockchain::HarmonyShard0 => Some(&chains::HARMONY_SHARD_0),
293 Blockchain::Holesky => Some(&chains::HOLESKY),
294 Blockchain::HoleskyTokenTest => Some(&chains::HOLESKY_TOKEN_TEST),
295 Blockchain::Hyperliquid => Some(&chains::HYPERLIQUID),
296 Blockchain::HyperliquidTemp => Some(&chains::HYPERLIQUID_TEMP),
297 Blockchain::Ink => Some(&chains::INK),
298 Blockchain::InternalTestChain => Some(&chains::INTERNAL_TEST_CHAIN),
299 Blockchain::Kroma => Some(&chains::KROMA),
300 Blockchain::Linea => Some(&chains::LINEA),
301 Blockchain::Lisk => Some(&chains::LISK),
302 Blockchain::Lukso => Some(&chains::LUKSO),
303 Blockchain::LuksoTestnet => Some(&chains::LUKSO_TESTNET),
304 Blockchain::Manta => Some(&chains::MANTA),
305 Blockchain::Mantle => Some(&chains::MANTLE),
306 Blockchain::MegaethTestnet => Some(&chains::MEGAETH_TESTNET),
307 Blockchain::Merlin => Some(&chains::MERLIN),
308 Blockchain::Metall2 => Some(&chains::METALL2),
309 Blockchain::Metis => Some(&chains::METIS),
310 Blockchain::MevCommit => Some(&chains::MEV_COMMIT),
311 Blockchain::Mode => Some(&chains::MODE),
312 Blockchain::MonadTestnet => Some(&chains::MONAD_TESTNET),
313 Blockchain::MonadTestnetBackup => Some(&chains::MONAD_TESTNET_BACKUP),
314 Blockchain::MoonbaseAlpha => Some(&chains::MOONBASE_ALPHA),
315 Blockchain::Moonbeam => Some(&chains::MOONBEAM),
316 Blockchain::Morph => Some(&chains::MORPH),
317 Blockchain::MorphHolesky => Some(&chains::MORPH_HOLESKY),
318 Blockchain::Opbnb => Some(&chains::OPBNB),
319 Blockchain::Optimism => Some(&chains::OPTIMISM),
320 Blockchain::OptimismSepolia => Some(&chains::OPTIMISM_SEPOLIA),
321 Blockchain::PharosDevnet => Some(&chains::PHAROS_DEVNET),
322 Blockchain::Polygon => Some(&chains::POLYGON),
323 Blockchain::PolygonAmoy => Some(&chains::POLYGON_AMOY),
324 Blockchain::PolygonZkEvm => Some(&chains::POLYGON_ZKEVM),
325 Blockchain::Rootstock => Some(&chains::ROOTSTOCK),
326 Blockchain::Saakuru => Some(&chains::SAAKURU),
327 Blockchain::Scroll => Some(&chains::SCROLL),
328 Blockchain::Sepolia => Some(&chains::SEPOLIA),
329 Blockchain::ShimmerEvm => Some(&chains::SHIMMER_EVM),
330 Blockchain::Soneium => Some(&chains::SONEIUM),
331 Blockchain::Sophon => Some(&chains::SOPHON),
332 Blockchain::SophonTestnet => Some(&chains::SOPHON_TESTNET),
333 Blockchain::Superseed => Some(&chains::SUPERSEED),
334 Blockchain::Unichain => Some(&chains::UNICHAIN),
335 Blockchain::UnichainSepolia => Some(&chains::UNICHAIN_SEPOLIA),
336 Blockchain::Xdc => Some(&chains::XDC),
337 Blockchain::XdcTestnet => Some(&chains::XDC_TESTNET),
338 Blockchain::Zeta => Some(&chains::ZETA),
339 Blockchain::Zircuit => Some(&chains::ZIRCUIT),
340 Blockchain::ZKsync => Some(&chains::ZKSYNC),
341 Blockchain::Zora => Some(&chains::ZORA),
342 }
343 }
344}
345
346impl Display for Chain {
347 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
348 write!(f, "Chain(name={}, id={})", self.name, self.chain_id)
349 }
350}
351
352pub mod chains {
354 use std::sync::LazyLock;
355
356 use crate::defi::chain::{Blockchain, Chain};
357
358 pub static ABSTRACT: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Abstract, 2741));
359 pub static ARBITRUM: LazyLock<Chain> =
360 LazyLock::new(|| Chain::new(Blockchain::Arbitrum, 42161));
361 pub static ARBITRUM_NOVA: LazyLock<Chain> =
362 LazyLock::new(|| Chain::new(Blockchain::ArbitrumNova, 42170));
363 pub static ARBITRUM_SEPOLIA: LazyLock<Chain> =
364 LazyLock::new(|| Chain::new(Blockchain::ArbitrumSepolia, 421614));
365 pub static AURORA: LazyLock<Chain> =
366 LazyLock::new(|| Chain::new(Blockchain::Aurora, 1313161554));
367 pub static AVALANCHE: LazyLock<Chain> =
368 LazyLock::new(|| Chain::new(Blockchain::Avalanche, 43114));
369 pub static BASE: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Base, 8453));
370 pub static BASE_SEPOLIA: LazyLock<Chain> =
371 LazyLock::new(|| Chain::new(Blockchain::BaseSepolia, 84532));
372 pub static BERACHAIN: LazyLock<Chain> =
373 LazyLock::new(|| Chain::new(Blockchain::Berachain, 80094));
374 pub static BERACHAIN_BARTIO: LazyLock<Chain> =
375 LazyLock::new(|| Chain::new(Blockchain::BerachainBartio, 80085));
376 pub static BLAST: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Blast, 81457));
377 pub static BLAST_SEPOLIA: LazyLock<Chain> =
378 LazyLock::new(|| Chain::new(Blockchain::BlastSepolia, 168587773));
379 pub static BOBA: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Boba, 288));
380 pub static BSC: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Bsc, 56));
381 pub static BSC_TESTNET: LazyLock<Chain> =
382 LazyLock::new(|| Chain::new(Blockchain::BscTestnet, 97));
383 pub static CELO: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Celo, 42220));
384 pub static CHILIZ: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Chiliz, 8888));
385 pub static CITREA_TESTNET: LazyLock<Chain> =
386 LazyLock::new(|| Chain::new(Blockchain::CitreaTestnet, 3333));
387 pub static CURTIS: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Curtis, 33111));
388 pub static CYBER: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Cyber, 7560));
389 pub static DARWINIA: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Darwinia, 46));
390 pub static ETHEREUM: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Ethereum, 1));
391 pub static FANTOM: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Fantom, 250));
392 pub static FLARE: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Flare, 14));
393 pub static FRAXTAL: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Fraxtal, 252));
394 pub static FUJI: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Fuji, 43113));
395 pub static GALADRIEL_DEVNET: LazyLock<Chain> =
396 LazyLock::new(|| Chain::new(Blockchain::GaladrielDevnet, 696969));
397 pub static GNOSIS: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Gnosis, 100));
398 pub static GNOSIS_CHIADO: LazyLock<Chain> =
399 LazyLock::new(|| Chain::new(Blockchain::GnosisChiado, 10200));
400 pub static GNOSIS_TRACES: LazyLock<Chain> =
406 LazyLock::new(|| Chain::new(Blockchain::GnosisTraces, 10300));
407 pub static HARMONY_SHARD_0: LazyLock<Chain> =
408 LazyLock::new(|| Chain::new(Blockchain::HarmonyShard0, 1666600000));
409 pub static HOLESKY: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Holesky, 17000));
410 pub static HOLESKY_TOKEN_TEST: LazyLock<Chain> =
413 LazyLock::new(|| Chain::new(Blockchain::HoleskyTokenTest, 17001));
414 pub static HYPERLIQUID: LazyLock<Chain> =
418 LazyLock::new(|| Chain::new(Blockchain::Hyperliquid, 7979));
419 pub static HYPERLIQUID_TEMP: LazyLock<Chain> =
420 LazyLock::new(|| Chain::new(Blockchain::HyperliquidTemp, 7978));
421 pub static INK: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Ink, 222));
423 pub static INTERNAL_TEST_CHAIN: LazyLock<Chain> =
425 LazyLock::new(|| Chain::new(Blockchain::InternalTestChain, 13337));
426 pub static KROMA: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Kroma, 255));
427 pub static LINEA: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Linea, 59144));
428 pub static LISK: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Lisk, 501));
429 pub static LUKSO: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Lukso, 42));
430 pub static LUKSO_TESTNET: LazyLock<Chain> =
431 LazyLock::new(|| Chain::new(Blockchain::LuksoTestnet, 4201));
432 pub static MANTA: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Manta, 169));
433 pub static MANTLE: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Mantle, 5000));
434 pub static MEGAETH_TESTNET: LazyLock<Chain> =
435 LazyLock::new(|| Chain::new(Blockchain::MegaethTestnet, 777));
436 pub static MERLIN: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Merlin, 4200));
437 pub static METALL2: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Metall2, 90));
438 pub static METIS: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Metis, 1088));
439 pub static MEV_COMMIT: LazyLock<Chain> =
440 LazyLock::new(|| Chain::new(Blockchain::MevCommit, 11));
441 pub static MODE: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Mode, 34443));
442 pub static MONAD_TESTNET: LazyLock<Chain> =
443 LazyLock::new(|| Chain::new(Blockchain::MonadTestnet, 2323));
444 pub static MONAD_TESTNET_BACKUP: LazyLock<Chain> =
445 LazyLock::new(|| Chain::new(Blockchain::MonadTestnetBackup, 2358));
446 pub static MOONBASE_ALPHA: LazyLock<Chain> =
447 LazyLock::new(|| Chain::new(Blockchain::MoonbaseAlpha, 1287));
448 pub static MOONBEAM: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Moonbeam, 1284));
449 pub static MORPH: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Morph, 2710));
450 pub static MORPH_HOLESKY: LazyLock<Chain> =
451 LazyLock::new(|| Chain::new(Blockchain::MorphHolesky, 2710111));
452 pub static OPBNB: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Opbnb, 204));
453 pub static OPTIMISM: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Optimism, 10));
454 pub static OPTIMISM_SEPOLIA: LazyLock<Chain> =
455 LazyLock::new(|| Chain::new(Blockchain::OptimismSepolia, 11155420));
456 pub static PHAROS_DEVNET: LazyLock<Chain> =
457 LazyLock::new(|| Chain::new(Blockchain::PharosDevnet, 1337));
458 pub static POLYGON: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Polygon, 137));
459 pub static POLYGON_AMOY: LazyLock<Chain> =
460 LazyLock::new(|| Chain::new(Blockchain::PolygonAmoy, 80002));
461 pub static POLYGON_ZKEVM: LazyLock<Chain> =
462 LazyLock::new(|| Chain::new(Blockchain::PolygonZkEvm, 1101));
463 pub static ROOTSTOCK: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Rootstock, 30));
464 pub static SAAKURU: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Saakuru, 1204));
465 pub static SCROLL: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Scroll, 534352));
466 pub static SEPOLIA: LazyLock<Chain> =
467 LazyLock::new(|| Chain::new(Blockchain::Sepolia, 11155111));
468 pub static SHIMMER_EVM: LazyLock<Chain> =
469 LazyLock::new(|| Chain::new(Blockchain::ShimmerEvm, 148));
470 pub static SONEIUM: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Soneium, 109));
471 pub static SOPHON: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Sophon, 138));
472 pub static SOPHON_TESTNET: LazyLock<Chain> =
473 LazyLock::new(|| Chain::new(Blockchain::SophonTestnet, 139));
474 pub static SUPERSEED: LazyLock<Chain> =
475 LazyLock::new(|| Chain::new(Blockchain::Superseed, 10001));
476 pub static UNICHAIN: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Unichain, 9999));
477 pub static UNICHAIN_SEPOLIA: LazyLock<Chain> =
478 LazyLock::new(|| Chain::new(Blockchain::UnichainSepolia, 9997));
479 pub static XDC: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Xdc, 50));
480 pub static XDC_TESTNET: LazyLock<Chain> =
481 LazyLock::new(|| Chain::new(Blockchain::XdcTestnet, 51));
482 pub static ZETA: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Zeta, 7000));
483 pub static ZIRCUIT: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Zircuit, 78600));
484 pub static ZKSYNC: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::ZKsync, 324));
485 pub static ZORA: LazyLock<Chain> = LazyLock::new(|| Chain::new(Blockchain::Zora, 7777777));
486}
487
488#[cfg(test)]
489mod tests {
490 use rstest::rstest;
491
492 use super::*;
493
494 #[rstest]
495 fn test_ethereum_chain() {
496 let eth_chain = chains::ETHEREUM.clone();
497 assert_eq!(eth_chain.to_string(), "Chain(name=Ethereum, id=1)");
498 assert_eq!(eth_chain.name, Blockchain::Ethereum);
499 assert_eq!(eth_chain.chain_id, 1);
500 assert_eq!(eth_chain.hypersync_url.as_str(), "https://1.hypersync.xyz")
501 }
502
503 #[rstest]
504 fn test_arbitrum_chain() {
505 let arbitrum_chain = chains::ARBITRUM.clone();
506 assert_eq!(arbitrum_chain.to_string(), "Chain(name=Arbitrum, id=42161)");
507 assert_eq!(arbitrum_chain.name, Blockchain::Arbitrum);
508 assert_eq!(arbitrum_chain.chain_id, 42161);
509 assert_eq!(
510 arbitrum_chain.hypersync_url.as_str(),
511 "https://42161.hypersync.xyz"
512 );
513 }
514
515 #[rstest]
516 fn test_chain_constructor() {
517 let chain = Chain::new(Blockchain::Polygon, 137);
518
519 assert_eq!(chain.name, Blockchain::Polygon);
520 assert_eq!(chain.chain_id, 137);
521 assert_eq!(chain.hypersync_url, "https://137.hypersync.xyz");
522 assert!(chain.rpc_url.is_none());
523 assert_eq!(chain.native_currency_decimals, 18);
524 }
525
526 #[rstest]
527 fn test_chain_set_rpc_url() {
528 let mut chain = Chain::new(Blockchain::Ethereum, 1);
529 assert!(chain.rpc_url.is_none());
530
531 let rpc_url = "https://mainnet.infura.io/v3/YOUR-PROJECT-ID".to_string();
532 chain.set_rpc_url(rpc_url.clone());
533
534 assert_eq!(chain.rpc_url, Some(rpc_url));
535 }
536
537 #[rstest]
538 fn test_chain_from_chain_id_valid() {
539 assert!(Chain::from_chain_id(1).is_some()); assert!(Chain::from_chain_id(137).is_some()); assert!(Chain::from_chain_id(42161).is_some()); assert!(Chain::from_chain_id(8453).is_some()); let eth_chain = Chain::from_chain_id(1).unwrap();
547 assert_eq!(eth_chain.name, Blockchain::Ethereum);
548 assert_eq!(eth_chain.chain_id, 1);
549 }
550
551 #[rstest]
552 fn test_chain_from_chain_id_invalid() {
553 assert!(Chain::from_chain_id(999999).is_none());
555 assert!(Chain::from_chain_id(0).is_none());
556 }
557
558 #[rstest]
559 fn test_chain_from_chain_name_valid() {
560 assert!(Chain::from_chain_name("Ethereum").is_some());
562 assert!(Chain::from_chain_name("Polygon").is_some());
563 assert!(Chain::from_chain_name("Arbitrum").is_some());
564 assert!(Chain::from_chain_name("Base").is_some());
565
566 let eth_chain = Chain::from_chain_name("Ethereum").unwrap();
568 assert_eq!(eth_chain.name, Blockchain::Ethereum);
569 assert_eq!(eth_chain.chain_id, 1);
570
571 let arbitrum_nova_chain = Chain::from_chain_name("ArbitrumNova").unwrap();
573 assert_eq!(arbitrum_nova_chain.name, Blockchain::ArbitrumNova);
574 assert_eq!(arbitrum_nova_chain.chain_id, 42170);
575
576 let bsc_chain = Chain::from_chain_name("Bsc").unwrap();
578 assert_eq!(bsc_chain.name, Blockchain::Bsc);
579 assert_eq!(bsc_chain.chain_id, 56);
580 }
581
582 #[rstest]
583 fn test_chain_from_chain_name_invalid() {
584 assert!(Chain::from_chain_name("InvalidChain").is_none());
586 assert!(Chain::from_chain_name("").is_none());
587 assert!(Chain::from_chain_name("NonExistentNetwork").is_none());
588 }
589
590 #[rstest]
591 fn test_chain_from_chain_name_case_sensitive() {
592 assert!(Chain::from_chain_name("Ethereum").is_some());
594 assert!(Chain::from_chain_name("ethereum").is_some()); assert!(Chain::from_chain_name("ETHEREUM").is_some()); assert!(Chain::from_chain_name("EtHeReUm").is_some()); assert!(Chain::from_chain_name("Arbitrum").is_some());
599 assert!(Chain::from_chain_name("arbitrum").is_some()); }
601
602 #[rstest]
603 fn test_chain_from_chain_name_consistency_with_id() {
604 let chains_to_test = [
606 ("Ethereum", 1),
607 ("Polygon", 137),
608 ("Arbitrum", 42161),
609 ("Base", 8453),
610 ("Optimism", 10),
611 ("Avalanche", 43114),
612 ("Fantom", 250),
613 ("Bsc", 56),
614 ];
615
616 for (name, id) in chains_to_test {
617 let chain_by_name =
618 Chain::from_chain_name(name).unwrap_or_else(|| panic!("Chain {name} should exist"));
619 let chain_by_id =
620 Chain::from_chain_id(id).unwrap_or_else(|| panic!("Chain {name} should exist"));
621
622 assert_eq!(chain_by_name.name, chain_by_id.name);
624 assert_eq!(chain_by_name.chain_id, chain_by_id.chain_id);
625 assert_eq!(chain_by_name.hypersync_url, chain_by_id.hypersync_url);
626 }
627 }
628}