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