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