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