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