alloy_chains/
named.rs

1use alloy_primitives::{Address, address};
2use core::{cmp::Ordering, fmt, time::Duration};
3use num_enum::TryFromPrimitiveError;
4
5#[allow(unused_imports)]
6use alloc::string::String;
7// When adding a new chain:
8//   1. add new variant to the NamedChain enum;
9//   2. add extra information in the last `impl` block (explorer URLs, block time) when applicable;
10//   3. (optional) add aliases:
11//     - Strum (in kebab-case): `#[strum(to_string = "<main>", serialize = "<aliasX>", ...)]`
12//      `to_string = "<main>"` must be present and will be used in `Display`, `Serialize`
13//      and `FromStr`, while `serialize = "<aliasX>"` will be appended to `FromStr`.
14//      More info: <https://docs.rs/strum/latest/strum/additional_attributes/index.html#attributes-on-variants>
15//     - Serde (in snake_case): `#[cfg_attr(feature = "serde", serde(alias = "<aliasX>", ...))]`
16//      Aliases are appended to the `Deserialize` implementation.
17//      More info: <https://serde.rs/variant-attrs.html>
18//     - Add a test at the bottom of the file
19//   4. run `cargo test --all-features` to update the JSON bindings and schema.
20//   5. run `cargo +nightly fmt --all` to properly format the code.
21
22// We don't derive Serialize because it is manually implemented using AsRef<str> and it would break
23// a lot of things since Serialize is `kebab-case` vs Deserialize `snake_case`. This means that the
24// NamedChain type is not "round-trippable", because the Serialize and Deserialize implementations
25// do not use the same case style.
26
27/// An Ethereum EIP-155 chain.
28#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
29#[derive(strum::IntoStaticStr)] // Into<&'static str>, AsRef<str>, fmt::Display and serde::Serialize
30#[derive(strum::VariantNames)] // NamedChain::VARIANTS
31#[derive(strum::VariantArray)] // NamedChain::VARIANTS
32#[derive(strum::EnumString)] // FromStr, TryFrom<&str>
33#[derive(strum::EnumIter)] // NamedChain::iter
34#[derive(strum::EnumCount)] // NamedChain::COUNT
35#[derive(num_enum::TryFromPrimitive)] // TryFrom<u64>
36#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
37#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
38#[strum(serialize_all = "kebab-case")]
39#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
40#[repr(u64)]
41#[allow(missing_docs)]
42#[non_exhaustive]
43pub enum NamedChain {
44    #[strum(to_string = "mainnet", serialize = "ethlive")]
45    #[cfg_attr(feature = "serde", serde(alias = "ethlive"))]
46    Mainnet = 1,
47    Morden = 2,
48    Ropsten = 3,
49    Rinkeby = 4,
50    Goerli = 5,
51    Kovan = 42,
52    Holesky = 17000,
53    Hoodi = 560048,
54    Sepolia = 11155111,
55
56    #[cfg_attr(feature = "serde", serde(alias = "odyssey"))]
57    Odyssey = 911867,
58
59    Optimism = 10,
60    #[cfg_attr(feature = "serde", serde(alias = "optimism-kovan"))]
61    OptimismKovan = 69,
62    #[cfg_attr(feature = "serde", serde(alias = "optimism-goerli"))]
63    OptimismGoerli = 420,
64    #[cfg_attr(feature = "serde", serde(alias = "optimism-sepolia"))]
65    OptimismSepolia = 11155420,
66
67    #[strum(to_string = "bob")]
68    #[cfg_attr(feature = "serde", serde(alias = "bob"))]
69    Bob = 60808,
70    #[strum(to_string = "bob-sepolia")]
71    #[cfg_attr(feature = "serde", serde(alias = "bob-sepolia"))]
72    BobSepolia = 808813,
73
74    #[cfg_attr(feature = "serde", serde(alias = "arbitrum_one", alias = "arbitrum-one"))]
75    Arbitrum = 42161,
76    ArbitrumTestnet = 421611,
77    #[cfg_attr(feature = "serde", serde(alias = "arbitrum-goerli"))]
78    ArbitrumGoerli = 421613,
79    #[cfg_attr(feature = "serde", serde(alias = "arbitrum-sepolia"))]
80    ArbitrumSepolia = 421614,
81    #[cfg_attr(feature = "serde", serde(alias = "arbitrum-nova"))]
82    ArbitrumNova = 42170,
83
84    Cronos = 25,
85    CronosTestnet = 338,
86
87    Rsk = 30,
88    RskTestnet = 31,
89
90    #[strum(to_string = "telos")]
91    #[cfg_attr(feature = "serde", serde(alias = "telos", alias = "telos_evm"))]
92    TelosEvm = 40,
93    #[strum(to_string = "telos-testnet")]
94    #[cfg_attr(
95        feature = "serde",
96        serde(alias = "telos_testnet", alias = "telos-evm-testnet", alias = "telos_evm_testnet")
97    )]
98    TelosEvmTestnet = 41,
99
100    #[strum(to_string = "crab")]
101    #[cfg_attr(feature = "serde", serde(alias = "crab"))]
102    Crab = 44,
103    #[strum(to_string = "darwinia")]
104    #[cfg_attr(feature = "serde", serde(alias = "darwinia"))]
105    Darwinia = 46,
106    #[strum(to_string = "koi")]
107    #[cfg_attr(feature = "serde", serde(alias = "koi"))]
108    Koi = 701,
109
110    /// Note the correct name for BSC should be `BNB Smart Chain` due to the rebranding: <https://www.bnbchain.org/en/blog/bsc-is-now-bnb-chain-the-infrastructure-for-the-metafi-universe>
111    /// We keep `Binance Smart Chain` for backward compatibility, and the enum could be renamed in
112    /// the future release.
113    #[strum(to_string = "bsc", serialize = "binance-smart-chain", serialize = "bnb-smart-chain")]
114    #[cfg_attr(
115        feature = "serde",
116        serde(alias = "bsc", alias = "bnb-smart-chain", alias = "binance-smart-chain")
117    )]
118    BinanceSmartChain = 56,
119    #[strum(
120        to_string = "bsc-testnet",
121        serialize = "binance-smart-chain-testnet",
122        serialize = "bnb-smart-chain-testnet"
123    )]
124    #[cfg_attr(
125        feature = "serde",
126        serde(
127            alias = "bsc_testnet",
128            alias = "bsc-testnet",
129            alias = "bnb-smart-chain-testnet",
130            alias = "binance-smart-chain-testnet"
131        )
132    )]
133    BinanceSmartChainTestnet = 97,
134
135    Poa = 99,
136    Sokol = 77,
137
138    Scroll = 534352,
139    #[cfg_attr(
140        feature = "serde",
141        serde(alias = "scroll_sepolia_testnet", alias = "scroll-sepolia")
142    )]
143    ScrollSepolia = 534351,
144
145    Metis = 1088,
146
147    #[cfg_attr(feature = "serde", serde(alias = "conflux-espace-testnet"))]
148    CfxTestnet = 71,
149    #[cfg_attr(feature = "serde", serde(alias = "conflux-espace"))]
150    Cfx = 1030,
151
152    #[strum(to_string = "xdai", serialize = "gnosis", serialize = "gnosis-chain")]
153    #[cfg_attr(feature = "serde", serde(alias = "xdai", alias = "gnosis", alias = "gnosis-chain"))]
154    Gnosis = 100,
155
156    Polygon = 137,
157    #[strum(to_string = "amoy", serialize = "polygon-amoy")]
158    #[cfg_attr(feature = "serde", serde(alias = "amoy", alias = "polygon-amoy"))]
159    PolygonAmoy = 80002,
160
161    Fantom = 250,
162    FantomTestnet = 4002,
163
164    Moonbeam = 1284,
165    MoonbeamDev = 1281,
166
167    Moonriver = 1285,
168
169    Moonbase = 1287,
170
171    Dev = 1337,
172    #[strum(to_string = "anvil-hardhat", serialize = "anvil", serialize = "hardhat")]
173    #[cfg_attr(
174        feature = "serde",
175        serde(alias = "anvil", alias = "hardhat", alias = "anvil-hardhat")
176    )]
177    AnvilHardhat = 31337,
178
179    #[strum(to_string = "gravity-alpha-mainnet")]
180    #[cfg_attr(feature = "serde", serde(alias = "gravity-alpha-mainnet"))]
181    GravityAlphaMainnet = 1625,
182    #[strum(to_string = "gravity-alpha-testnet-sepolia")]
183    #[cfg_attr(feature = "serde", serde(alias = "gravity-alpha-testnet-sepolia"))]
184    GravityAlphaTestnetSepolia = 13505,
185
186    Evmos = 9001,
187    EvmosTestnet = 9000,
188
189    Plasma = 9745,
190
191    Chiado = 10200,
192
193    Oasis = 26863,
194
195    Emerald = 42262,
196    EmeraldTestnet = 42261,
197
198    FilecoinMainnet = 314,
199    FilecoinCalibrationTestnet = 314159,
200
201    Avalanche = 43114,
202    #[strum(to_string = "fuji", serialize = "avalanche-fuji")]
203    #[cfg_attr(feature = "serde", serde(alias = "fuji"))]
204    AvalancheFuji = 43113,
205
206    Celo = 42220,
207    CeloSepolia = 11142220,
208
209    Aurora = 1313161554,
210    AuroraTestnet = 1313161555,
211
212    Canto = 7700,
213    CantoTestnet = 740,
214
215    Boba = 288,
216
217    Base = 8453,
218    #[cfg_attr(feature = "serde", serde(alias = "base-goerli"))]
219    BaseGoerli = 84531,
220    #[cfg_attr(feature = "serde", serde(alias = "base-sepolia"))]
221    BaseSepolia = 84532,
222    #[cfg_attr(feature = "serde", serde(alias = "syndr"))]
223    Syndr = 404,
224    #[cfg_attr(feature = "serde", serde(alias = "syndr-sepolia"))]
225    SyndrSepolia = 444444,
226
227    Shimmer = 148,
228
229    Ink = 57073,
230    #[cfg_attr(feature = "serde", serde(alias = "ink_sepolia_testnet", alias = "ink-sepolia"))]
231    InkSepolia = 763373,
232
233    #[strum(to_string = "fraxtal")]
234    #[cfg_attr(feature = "serde", serde(alias = "fraxtal"))]
235    Fraxtal = 252,
236    #[strum(to_string = "fraxtal-testnet")]
237    #[cfg_attr(feature = "serde", serde(alias = "fraxtal-testnet"))]
238    FraxtalTestnet = 2522,
239
240    Blast = 81457,
241    #[cfg_attr(feature = "serde", serde(alias = "blast-sepolia"))]
242    BlastSepolia = 168587773,
243
244    Linea = 59144,
245    #[cfg_attr(feature = "serde", serde(alias = "linea-goerli"))]
246    LineaGoerli = 59140,
247    #[cfg_attr(feature = "serde", serde(alias = "linea-sepolia"))]
248    LineaSepolia = 59141,
249
250    #[strum(to_string = "zksync")]
251    #[cfg_attr(feature = "serde", serde(alias = "zksync"))]
252    ZkSync = 324,
253    #[strum(to_string = "zksync-testnet")]
254    #[cfg_attr(feature = "serde", serde(alias = "zksync_testnet", alias = "zksync-testnet"))]
255    ZkSyncTestnet = 300,
256
257    #[strum(to_string = "mantle")]
258    #[cfg_attr(feature = "serde", serde(alias = "mantle"))]
259    Mantle = 5000,
260    #[strum(to_string = "mantle-sepolia")]
261    #[cfg_attr(feature = "serde", serde(alias = "mantle-sepolia"))]
262    MantleSepolia = 5003,
263
264    #[strum(to_string = "xai")]
265    #[cfg_attr(feature = "serde", serde(alias = "xai"))]
266    Xai = 660279,
267    #[strum(to_string = "xai-sepolia")]
268    #[cfg_attr(feature = "serde", serde(alias = "xai-sepolia"))]
269    XaiSepolia = 37714555429,
270
271    #[strum(to_string = "happychain-testnet")]
272    #[cfg_attr(feature = "serde", serde(alias = "happychain-testnet"))]
273    HappychainTestnet = 216,
274
275    Viction = 88,
276
277    Zora = 7777777,
278    #[cfg_attr(feature = "serde", serde(alias = "zora-sepolia"))]
279    ZoraSepolia = 999999999,
280
281    Pgn = 424,
282    #[cfg_attr(feature = "serde", serde(alias = "pgn-sepolia"))]
283    PgnSepolia = 58008,
284
285    Mode = 34443,
286    #[cfg_attr(feature = "serde", serde(alias = "mode-sepolia"))]
287    ModeSepolia = 919,
288
289    Elastos = 20,
290
291    #[cfg_attr(feature = "serde", serde(alias = "etherlink"))]
292    Etherlink = 42793,
293
294    #[cfg_attr(feature = "serde", serde(alias = "etherlink-testnet"))]
295    EtherlinkTestnet = 128123,
296
297    Degen = 666666666,
298
299    #[strum(to_string = "opbnb-mainnet")]
300    #[cfg_attr(
301        feature = "serde",
302        serde(rename = "opbnb_mainnet", alias = "opbnb-mainnet", alias = "op-bnb-mainnet")
303    )]
304    OpBNBMainnet = 204,
305    #[strum(to_string = "opbnb-testnet")]
306    #[cfg_attr(
307        feature = "serde",
308        serde(rename = "opbnb_testnet", alias = "opbnb-testnet", alias = "op-bnb-testnet")
309    )]
310    OpBNBTestnet = 5611,
311
312    Ronin = 2020,
313
314    #[cfg_attr(feature = "serde", serde(alias = "ronin-testnet"))]
315    RoninTestnet = 2021,
316
317    Taiko = 167000,
318    #[cfg_attr(feature = "serde", serde(alias = "taiko-hekla"))]
319    TaikoHekla = 167009,
320
321    #[strum(to_string = "autonomys-nova-testnet")]
322    #[cfg_attr(
323        feature = "serde",
324        serde(rename = "autonomys_nova_testnet", alias = "autonomys-nova-testnet")
325    )]
326    AutonomysNovaTestnet = 490000,
327
328    Flare = 14,
329    #[cfg_attr(feature = "serde", serde(alias = "flare-coston2"))]
330    FlareCoston2 = 114,
331
332    #[strum(to_string = "acala")]
333    #[cfg_attr(feature = "serde", serde(alias = "acala"))]
334    Acala = 787,
335    #[strum(to_string = "acala-mandala-testnet")]
336    #[cfg_attr(feature = "serde", serde(alias = "acala-mandala-testnet"))]
337    AcalaMandalaTestnet = 595,
338    #[strum(to_string = "acala-testnet")]
339    #[cfg_attr(feature = "serde", serde(alias = "acala-testnet"))]
340    AcalaTestnet = 597,
341
342    #[strum(to_string = "karura")]
343    #[cfg_attr(feature = "serde", serde(alias = "karura"))]
344    Karura = 686,
345    #[strum(to_string = "karura-testnet")]
346    #[cfg_attr(feature = "serde", serde(alias = "karura-testnet"))]
347    KaruraTestnet = 596,
348    #[strum(to_string = "pulsechain")]
349    #[cfg_attr(feature = "serde", serde(alias = "pulsechain"))]
350    Pulsechain = 369,
351    #[strum(to_string = "pulsechain-testnet")]
352    #[cfg_attr(feature = "serde", serde(alias = "pulsechain-testnet"))]
353    PulsechainTestnet = 943,
354
355    #[strum(to_string = "cannon")]
356    #[cfg_attr(feature = "serde", serde(alias = "cannon"))]
357    Cannon = 13370,
358
359    #[strum(to_string = "immutable")]
360    #[cfg_attr(feature = "serde", serde(alias = "immutable"))]
361    Immutable = 13371,
362    #[strum(to_string = "immutable-testnet")]
363    #[cfg_attr(feature = "serde", serde(alias = "immutable-testnet"))]
364    ImmutableTestnet = 13473,
365
366    #[strum(to_string = "soneium")]
367    #[cfg_attr(feature = "serde", serde(alias = "soneium"))]
368    Soneium = 1868,
369
370    #[strum(to_string = "soneium-minato-testnet")]
371    #[cfg_attr(feature = "serde", serde(alias = "soneium-minato-testnet"))]
372    SoneiumMinatoTestnet = 1946,
373
374    #[cfg_attr(feature = "serde", serde(alias = "worldchain"))]
375    World = 480,
376    #[strum(to_string = "world-sepolia")]
377    #[cfg_attr(feature = "serde", serde(alias = "worldchain-sepolia", alias = "world-sepolia"))]
378    WorldSepolia = 4801,
379    Iotex = 4689,
380    Core = 1116,
381    Merlin = 4200,
382    Bitlayer = 200901,
383    Vana = 1480,
384    Zeta = 7000,
385    Kaia = 8217,
386    Story = 1514,
387    Sei = 1329,
388    #[strum(to_string = "sei-testnet")]
389    #[cfg_attr(feature = "serde", serde(alias = "sei-testnet"))]
390    SeiTestnet = 1328,
391    #[strum(to_string = "stable-mainnet")]
392    #[cfg_attr(feature = "serde", serde(alias = "stable-mainnet"))]
393    StableMainnet = 988,
394    #[strum(to_string = "stable-testnet")]
395    #[cfg_attr(feature = "serde", serde(alias = "stable-testnet"))]
396    StableTestnet = 2201,
397    #[strum(to_string = "megaeth")]
398    #[cfg_attr(feature = "serde", serde(alias = "megaeth"))]
399    MegaEth = 4326,
400    #[strum(to_string = "megaeth-testnet")]
401    #[cfg_attr(feature = "serde", serde(alias = "megaeth-testnet", alias = "megaeth_testnet"))]
402    MegaEthTestnet = 6343,
403
404    #[strum(to_string = "xdc-mainnet")]
405    #[cfg_attr(feature = "serde", serde(alias = "xdc-mainnet"))]
406    XdcMainnet = 50,
407    #[strum(to_string = "xdc-testnet")]
408    #[cfg_attr(feature = "serde", serde(alias = "xdc-testnet"))]
409    XdcTestnet = 51,
410
411    Unichain = 130,
412    #[strum(to_string = "unichain-sepolia")]
413    #[cfg_attr(feature = "serde", serde(alias = "unichain-sepolia"))]
414    UnichainSepolia = 1301,
415
416    #[strum(to_string = "signet-pecorino")]
417    #[cfg_attr(feature = "serde", serde(alias = "signet-pecorino"))]
418    SignetPecorino = 14174,
419
420    #[strum(to_string = "apechain")]
421    #[cfg_attr(feature = "serde", serde(alias = "apechain"))]
422    ApeChain = 33139,
423    #[strum(to_string = "curtis", serialize = "apechain-testnet")]
424    #[cfg_attr(feature = "serde", serde(alias = "apechain-testnet", alias = "curtis"))]
425    Curtis = 33111,
426
427    #[strum(to_string = "sonic")]
428    #[cfg_attr(feature = "serde", serde(alias = "sonic"))]
429    Sonic = 146,
430    #[strum(to_string = "sonic-testnet")]
431    #[cfg_attr(feature = "serde", serde(alias = "sonic-testnet"))]
432    SonicTestnet = 14601,
433
434    #[strum(to_string = "treasure")]
435    #[cfg_attr(feature = "serde", serde(alias = "treasure"))]
436    Treasure = 61166,
437
438    #[strum(to_string = "treasure-topaz", serialize = "treasure-topaz-testnet")]
439    #[cfg_attr(
440        feature = "serde",
441        serde(alias = "treasure-topaz-testnet", alias = "treasure-topaz")
442    )]
443    TreasureTopaz = 978658,
444
445    #[strum(to_string = "berachain-bepolia", serialize = "berachain-bepolia-testnet")]
446    #[cfg_attr(
447        feature = "serde",
448        serde(alias = "berachain-bepolia-testnet", alias = "berachain-bepolia")
449    )]
450    BerachainBepolia = 80069,
451
452    Berachain = 80094,
453
454    #[strum(to_string = "superposition-testnet")]
455    #[cfg_attr(feature = "serde", serde(alias = "superposition-testnet"))]
456    SuperpositionTestnet = 98985,
457
458    #[strum(to_string = "superposition")]
459    #[cfg_attr(feature = "serde", serde(alias = "superposition"))]
460    Superposition = 55244,
461
462    #[strum(serialize = "monad")]
463    #[cfg_attr(feature = "serde", serde(alias = "monad"))]
464    Monad = 143,
465
466    #[strum(serialize = "monad-testnet")]
467    #[cfg_attr(feature = "serde", serde(alias = "monad-testnet"))]
468    MonadTestnet = 10143,
469
470    #[strum(to_string = "hyperliquid")]
471    #[cfg_attr(feature = "serde", serde(alias = "hyperliquid"))]
472    Hyperliquid = 999,
473
474    #[strum(to_string = "abstract")]
475    #[cfg_attr(feature = "serde", serde(alias = "abstract"))]
476    Abstract = 2741,
477
478    #[strum(to_string = "abstract-testnet")]
479    #[cfg_attr(feature = "serde", serde(alias = "abstract-testnet"))]
480    AbstractTestnet = 11124,
481
482    #[strum(to_string = "corn")]
483    #[cfg_attr(feature = "serde", serde(alias = "corn"))]
484    Corn = 21000000,
485
486    #[strum(to_string = "corn-testnet")]
487    #[cfg_attr(feature = "serde", serde(alias = "corn-testnet"))]
488    CornTestnet = 21000001,
489
490    #[strum(to_string = "sophon")]
491    #[cfg_attr(feature = "serde", serde(alias = "sophon"))]
492    Sophon = 50104,
493
494    #[strum(to_string = "sophon-testnet")]
495    #[cfg_attr(feature = "serde", serde(alias = "sophon-testnet"))]
496    SophonTestnet = 531050104,
497
498    #[strum(to_string = "polkadot-testnet")]
499    #[cfg_attr(feature = "serde", serde(alias = "polkadot-testnet"))]
500    PolkadotTestnet = 420420417,
501
502    #[strum(to_string = "paseo-passethub")]
503    #[cfg_attr(feature = "serde", serde(alias = "paseo-passethub"))]
504    PaseoPassethub = 420420422,
505
506    #[strum(to_string = "lens")]
507    #[cfg_attr(feature = "serde", serde(alias = "lens"))]
508    Lens = 232,
509
510    #[strum(to_string = "lens-testnet")]
511    #[cfg_attr(feature = "serde", serde(alias = "lens-testnet"))]
512    LensTestnet = 37111,
513
514    #[strum(to_string = "injective")]
515    #[cfg_attr(feature = "serde", serde(alias = "injective"))]
516    Injective = 1776,
517
518    #[strum(to_string = "injective-testnet")]
519    #[cfg_attr(feature = "serde", serde(alias = "injective-testnet"))]
520    InjectiveTestnet = 1439,
521
522    #[strum(to_string = "katana")]
523    #[cfg_attr(feature = "serde", serde(alias = "katana"))]
524    Katana = 747474,
525
526    #[strum(to_string = "lisk")]
527    #[cfg_attr(feature = "serde", serde(alias = "lisk"))]
528    Lisk = 1135,
529
530    #[strum(to_string = "fuse")]
531    #[cfg_attr(feature = "serde", serde(alias = "fuse"))]
532    Fuse = 122,
533    #[strum(to_string = "fluent-devnet")]
534    #[cfg_attr(feature = "serde", serde(alias = "fluent-devnet"))]
535    FluentDevnet = 20993,
536
537    #[strum(to_string = "fluent-testnet")]
538    #[cfg_attr(feature = "serde", serde(alias = "fluent-testnet"))]
539    FluentTestnet = 20994,
540
541    #[strum(to_string = "skale-base")]
542    #[cfg_attr(feature = "serde", serde(alias = "skale-base"))]
543    SkaleBase = 1187947933,
544
545    #[strum(to_string = "skale-base-sepolia-testnet")]
546    #[cfg_attr(feature = "serde", serde(alias = "skale-base-sepolia-testnet"))]
547    SkaleBaseSepoliaTestnet = 324705682,
548
549    // === MemeCore chain ===
550    // Variants that belong to the MemeCore chain.
551    #[strum(to_string = "memecore")]
552    #[cfg_attr(feature = "serde", serde(alias = "memecore"))]
553    MemeCore = 4352,
554    #[strum(to_string = "formicarium", serialize = "memecore-formicarium")]
555    #[cfg_attr(feature = "serde", serde(alias = "formicairum", alias = "memecore-formicarium"))]
556    Formicarium = 43521,
557    #[strum(to_string = "insectarium", serialize = "memecore-insectarium")]
558    #[cfg_attr(feature = "serde", serde(alias = "insectarium", alias = "memecore-insectarium"))]
559    Insectarium = 43522,
560
561    #[strum(to_string = "tempo", serialize = "tempo-mainnet")]
562    #[cfg_attr(feature = "serde", serde(alias = "tempo", alias = "tempo-mainnet"))]
563    Tempo = 4217,
564
565    TempoTestnet = 42429,
566
567    TempoModerato = 42431,
568}
569
570// This must be implemented manually so we avoid a conflict with `TryFromPrimitive` where it treats
571// the `#[default]` attribute as its own `#[num_enum(default)]`
572impl Default for NamedChain {
573    #[inline]
574    fn default() -> Self {
575        Self::Mainnet
576    }
577}
578
579macro_rules! impl_into_numeric {
580    ($($t:ty)+) => {$(
581        impl From<NamedChain> for $t {
582            #[inline]
583            fn from(chain: NamedChain) -> Self {
584                chain as $t
585            }
586        }
587    )+};
588}
589
590impl_into_numeric!(u64 i64 u128 i128);
591#[cfg(target_pointer_width = "64")]
592impl_into_numeric!(usize isize);
593
594macro_rules! impl_try_from_numeric {
595    ($($native:ty)+) => {
596        $(
597            impl TryFrom<$native> for NamedChain {
598                type Error = TryFromPrimitiveError<NamedChain>;
599
600                #[inline]
601                fn try_from(value: $native) -> Result<Self, Self::Error> {
602                    (value as u64).try_into()
603                }
604            }
605        )+
606    };
607}
608
609impl_try_from_numeric!(u8 i8 u16 i16 u32 i32 usize isize);
610
611impl fmt::Display for NamedChain {
612    #[inline]
613    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
614        self.as_str().fmt(f)
615    }
616}
617
618impl AsRef<str> for NamedChain {
619    #[inline]
620    fn as_ref(&self) -> &str {
621        self.as_str()
622    }
623}
624
625impl PartialEq<u64> for NamedChain {
626    #[inline]
627    fn eq(&self, other: &u64) -> bool {
628        (*self as u64) == *other
629    }
630}
631
632impl PartialOrd<u64> for NamedChain {
633    #[inline]
634    fn partial_cmp(&self, other: &u64) -> Option<Ordering> {
635        (*self as u64).partial_cmp(other)
636    }
637}
638
639#[cfg(feature = "serde")]
640impl serde::Serialize for NamedChain {
641    #[inline]
642    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
643        s.serialize_str(self.as_ref())
644    }
645}
646
647#[cfg(feature = "rlp")]
648impl alloy_rlp::Encodable for NamedChain {
649    #[inline]
650    fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
651        (*self as u64).encode(out)
652    }
653
654    #[inline]
655    fn length(&self) -> usize {
656        (*self as u64).length()
657    }
658}
659
660#[cfg(feature = "rlp")]
661impl alloy_rlp::Decodable for NamedChain {
662    #[inline]
663    fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
664        let n = u64::decode(buf)?;
665        Self::try_from(n).map_err(|_| alloy_rlp::Error::Overflow)
666    }
667}
668
669#[cfg(feature = "arbitrary")]
670impl<'a> arbitrary::Arbitrary<'a> for NamedChain {
671    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
672        use strum::{EnumCount, VariantArray};
673        let idx = u.choose_index(NamedChain::COUNT)?;
674        Ok(NamedChain::VARIANTS[idx])
675    }
676}
677
678// NB: all utility functions *should* be explicitly exhaustive (not use `_` matcher) so we don't
679//     forget to update them when adding a new `NamedChain` variant.
680#[allow(clippy::match_like_matches_macro)]
681#[deny(unreachable_patterns, unused_variables)]
682impl NamedChain {
683    /// Returns the string representation of the chain.
684    #[inline]
685    pub fn as_str(&self) -> &'static str {
686        self.into()
687    }
688
689    /// Returns `true` if this chain is Ethereum or an Ethereum testnet.
690    pub const fn is_ethereum(&self) -> bool {
691        use NamedChain::*;
692
693        matches!(self, Mainnet | Morden | Ropsten | Rinkeby | Goerli | Kovan | Holesky | Sepolia)
694    }
695
696    /// Returns true if the chain contains Optimism configuration.
697    pub const fn is_optimism(self) -> bool {
698        use NamedChain::*;
699
700        matches!(
701            self,
702            Optimism
703                | OptimismGoerli
704                | OptimismKovan
705                | OptimismSepolia
706                | Base
707                | BaseGoerli
708                | BaseSepolia
709                | Fraxtal
710                | FraxtalTestnet
711                | Ink
712                | InkSepolia
713                | Mode
714                | ModeSepolia
715                | Pgn
716                | PgnSepolia
717                | Zora
718                | ZoraSepolia
719                | BlastSepolia
720                | OpBNBMainnet
721                | OpBNBTestnet
722                | Soneium
723                | SoneiumMinatoTestnet
724                | Odyssey
725                | World
726                | WorldSepolia
727                | Unichain
728                | UnichainSepolia
729                | HappychainTestnet
730                | Lisk
731                | Celo
732                | Katana
733        )
734    }
735
736    /// Returns true if the chain contains Gnosis configuration.
737    pub const fn is_gnosis(self) -> bool {
738        use NamedChain::*;
739
740        matches!(self, Gnosis | Chiado)
741    }
742
743    /// Returns true if the chain contains Polygon configuration.
744    pub const fn is_polygon(self) -> bool {
745        use NamedChain::*;
746
747        matches!(self, Polygon | PolygonAmoy)
748    }
749
750    /// Returns true if the chain contains Arbitrum configuration.
751    pub const fn is_arbitrum(self) -> bool {
752        use NamedChain::*;
753
754        matches!(self, Arbitrum | ArbitrumTestnet | ArbitrumGoerli | ArbitrumSepolia | ArbitrumNova)
755    }
756
757    /// Returns true if the chain contains Elastic Network configuration.
758    pub const fn is_elastic(self) -> bool {
759        use NamedChain::*;
760
761        matches!(
762            self,
763            ZkSync
764                | ZkSyncTestnet
765                | Abstract
766                | AbstractTestnet
767                | Sophon
768                | SophonTestnet
769                | Lens
770                | LensTestnet
771        )
772    }
773
774    /// Returns true if the chain contains Tempo configuration.
775    pub const fn is_tempo(self) -> bool {
776        use NamedChain::*;
777
778        matches!(self, Tempo | TempoTestnet)
779    }
780
781    /// Returns the chain's average blocktime, if applicable.
782    ///
783    /// It can be beneficial to know the average blocktime to adjust the polling of an HTTP provider
784    /// for example.
785    ///
786    /// **Note:** this is not an accurate average, but is rather a sensible default derived from
787    /// blocktime charts such as [Etherscan's](https://etherscan.com/chart/blocktime)
788    /// or [Polygonscan's](https://polygonscan.com/chart/blocktime).
789    ///
790    /// # Examples
791    ///
792    /// ```
793    /// use alloy_chains::NamedChain;
794    /// use std::time::Duration;
795    ///
796    /// assert_eq!(NamedChain::Mainnet.average_blocktime_hint(), Some(Duration::from_millis(12_000)),);
797    /// assert_eq!(NamedChain::Optimism.average_blocktime_hint(), Some(Duration::from_millis(2_000)),);
798    /// ```
799    pub const fn average_blocktime_hint(self) -> Option<Duration> {
800        use NamedChain::*;
801
802        Some(Duration::from_millis(match self {
803            Mainnet | Taiko | TaikoHekla | SignetPecorino => 12_000,
804
805            Arbitrum
806            | ArbitrumTestnet
807            | ArbitrumGoerli
808            | ArbitrumSepolia
809            | GravityAlphaMainnet
810            | GravityAlphaTestnetSepolia
811            | Xai
812            | XaiSepolia
813            | Syndr
814            | SyndrSepolia
815            | ArbitrumNova
816            | ApeChain
817            | Curtis
818            | SuperpositionTestnet
819            | Superposition => 260,
820
821            Optimism | OptimismGoerli | OptimismSepolia | Base | BaseGoerli | BaseSepolia
822            | Blast | BlastSepolia | Fraxtal | FraxtalTestnet | Zora | ZoraSepolia | Mantle
823            | MantleSepolia | Mode | ModeSepolia | Pgn | PgnSepolia | HappychainTestnet
824            | Soneium | SoneiumMinatoTestnet | Bob | BobSepolia => 2_000,
825
826            Ink | InkSepolia | Odyssey | Plasma => 1_000,
827
828            Viction => 2_000,
829
830            Polygon | PolygonAmoy => 2_100,
831
832            Acala | AcalaMandalaTestnet | AcalaTestnet | Karura | KaruraTestnet => 12_500,
833
834            Moonbeam | Moonriver => 6_500,
835
836            BinanceSmartChain | BinanceSmartChainTestnet => 750,
837
838            Avalanche | AvalancheFuji => 2_000,
839
840            Fantom | FantomTestnet => 1_200,
841
842            Cronos | CronosTestnet | Canto | CantoTestnet => 5_700,
843
844            Evmos | EvmosTestnet => 1_900,
845
846            Aurora | AuroraTestnet => 1_100,
847
848            Oasis => 5_500,
849
850            Emerald | Darwinia | Crab | Koi => 6_000,
851
852            Dev | AnvilHardhat => 200,
853
854            Celo | CeloSepolia => 1_000,
855
856            FilecoinCalibrationTestnet | FilecoinMainnet => 30_000,
857
858            Scroll | ScrollSepolia => 3_000,
859
860            Shimmer => 5_000,
861
862            Gnosis | Chiado => 5_000,
863
864            Elastos => 5_000,
865
866            Etherlink => 5_000,
867
868            EtherlinkTestnet => 5_000,
869
870            Degen => 600,
871
872            Cfx | CfxTestnet => 500,
873
874            OpBNBMainnet | OpBNBTestnet | AutonomysNovaTestnet => 1_000,
875
876            Ronin | RoninTestnet => 3_000,
877
878            Flare => 1_800,
879
880            FlareCoston2 => 2_500,
881
882            Pulsechain => 10000,
883            PulsechainTestnet => 10101,
884
885            Immutable | ImmutableTestnet => 2_000,
886
887            World | WorldSepolia => 2_000,
888
889            Iotex => 5_000,
890            Core => 3_000,
891            Merlin => 3_000,
892            Bitlayer => 3_000,
893            Vana => 6_000,
894            Zeta => 6_000,
895            Kaia => 1_000,
896            Story => 2_500,
897            Sei | SeiTestnet => 500,
898            StableMainnet | StableTestnet => 700,
899            MegaEth | MegaEthTestnet => 1_000,
900
901            XdcMainnet => 2400,
902            XdcTestnet => 2400,
903
904            Sonic | SonicTestnet => 1_000,
905
906            TelosEvm | TelosEvmTestnet | Tempo | TempoTestnet | TempoModerato => 500,
907
908            UnichainSepolia | Unichain => 1_000,
909
910            BerachainBepolia | Berachain => 2_000,
911
912            Monad | MonadTestnet => 400,
913
914            Hyperliquid => 2_000,
915
916            Abstract | AbstractTestnet => 1_000,
917            ZkSync | ZkSyncTestnet => 1_000,
918            Sophon | SophonTestnet => 1_000,
919            Lens | LensTestnet => 1_000,
920            Rsk | RskTestnet => 25_000,
921            Injective | InjectiveTestnet => 700,
922            Katana => 1_000,
923            Lisk => 2_000,
924            Fuse => 5_000,
925            FluentDevnet => 3_000,
926            FluentTestnet => 1_000,
927            MemeCore | Formicarium | Insectarium => 7_000,
928
929            SkaleBase | SkaleBaseSepoliaTestnet => 1_000,
930
931            PolkadotTestnet | PaseoPassethub => 6_000,
932
933            Morden | Ropsten | Rinkeby | Goerli | Kovan | Sepolia | Holesky | Hoodi | Moonbase
934            | MoonbeamDev | OptimismKovan | Poa | Sokol | EmeraldTestnet | Boba | Metis | Linea
935            | LineaGoerli | LineaSepolia | Treasure | TreasureTopaz | Corn | CornTestnet
936            | Cannon => {
937                return None;
938            }
939        }))
940    }
941
942    /// Returns whether the chain implements EIP-1559 (with the type 2 EIP-2718 transaction type).
943    ///
944    /// # Examples
945    ///
946    /// ```
947    /// use alloy_chains::NamedChain;
948    ///
949    /// assert!(!NamedChain::Mainnet.is_legacy());
950    /// assert!(NamedChain::Fantom.is_legacy());
951    /// ```
952    pub const fn is_legacy(self) -> bool {
953        use NamedChain::*;
954
955        match self {
956            // Known legacy chains / non EIP-1559 compliant.
957            Elastos | Emerald | EmeraldTestnet | Fantom | FantomTestnet | OptimismKovan | Ronin
958            | RoninTestnet | Rsk | RskTestnet | Shimmer | Treasure | TreasureTopaz | Viction
959            | Sophon | SophonTestnet => true,
960
961            // Known EIP-1559 chains.
962            Mainnet
963            | Goerli
964            | Sepolia
965            | Holesky
966            | Hoodi
967            | Odyssey
968            | Acala
969            | AcalaMandalaTestnet
970            | AcalaTestnet
971            | ArbitrumTestnet
972            | Base
973            | BaseGoerli
974            | BaseSepolia
975            | Boba
976            | Metis
977            | Oasis
978            | Blast
979            | BlastSepolia
980            | Celo
981            | CeloSepolia
982            | Fraxtal
983            | FraxtalTestnet
984            | Optimism
985            | OptimismGoerli
986            | OptimismSepolia
987            | Bob
988            | BobSepolia
989            | Polygon
990            | PolygonAmoy
991            | Avalanche
992            | AvalancheFuji
993            | Arbitrum
994            | ArbitrumGoerli
995            | ArbitrumSepolia
996            | ArbitrumNova
997            | GravityAlphaMainnet
998            | GravityAlphaTestnetSepolia
999            | Xai
1000            | XaiSepolia
1001            | HappychainTestnet
1002            | Syndr
1003            | SyndrSepolia
1004            | FilecoinMainnet
1005            | Linea
1006            | LineaGoerli
1007            | LineaSepolia
1008            | FilecoinCalibrationTestnet
1009            | Gnosis
1010            | Chiado
1011            | Zora
1012            | ZoraSepolia
1013            | Ink
1014            | InkSepolia
1015            | Mantle
1016            | MantleSepolia
1017            | Mode
1018            | ModeSepolia
1019            | Pgn
1020            | PgnSepolia
1021            | Etherlink
1022            | EtherlinkTestnet
1023            | Degen
1024            | OpBNBMainnet
1025            | OpBNBTestnet
1026            | Taiko
1027            | TaikoHekla
1028            | AutonomysNovaTestnet
1029            | Flare
1030            | FlareCoston2
1031            | Scroll
1032            | ScrollSepolia
1033            | Darwinia
1034            | Cfx
1035            | CfxTestnet
1036            | Crab
1037            | Pulsechain
1038            | PulsechainTestnet
1039            | Koi
1040            | Immutable
1041            | ImmutableTestnet
1042            | Soneium
1043            | SoneiumMinatoTestnet
1044            | Sonic
1045            | SonicTestnet
1046            | World
1047            | WorldSepolia
1048            | Unichain
1049            | UnichainSepolia
1050            | SignetPecorino
1051            | ApeChain
1052            | BerachainBepolia
1053            | Berachain
1054            | Curtis
1055            | SuperpositionTestnet
1056            | Superposition
1057            | Monad
1058            | MonadTestnet
1059            | Hyperliquid
1060            | Corn
1061            | CornTestnet
1062            | ZkSync
1063            | ZkSyncTestnet
1064            | AbstractTestnet
1065            | Abstract
1066            | Lens
1067            | LensTestnet
1068            | BinanceSmartChain
1069            | BinanceSmartChainTestnet
1070            | Karura
1071            | KaruraTestnet
1072            | TelosEvm
1073            | TelosEvmTestnet
1074            | FluentDevnet
1075            | FluentTestnet
1076            | Plasma
1077            | MemeCore
1078            | Formicarium
1079            | Insectarium
1080            | MegaEth
1081            | MegaEthTestnet => false,
1082
1083            // Unknown / not applicable, default to false for backwards compatibility.
1084            Dev
1085            | AnvilHardhat
1086            | Morden
1087            | Ropsten
1088            | Rinkeby
1089            | Cronos
1090            | CronosTestnet
1091            | Kovan
1092            | Sokol
1093            | Poa
1094            | Moonbeam
1095            | MoonbeamDev
1096            | Moonriver
1097            | Moonbase
1098            | Evmos
1099            | EvmosTestnet
1100            | Aurora
1101            | AuroraTestnet
1102            | Canto
1103            | CantoTestnet
1104            | Iotex
1105            | Core
1106            | Merlin
1107            | Bitlayer
1108            | Vana
1109            | Zeta
1110            | Kaia
1111            | Story
1112            | Sei
1113            | SeiTestnet
1114            | StableMainnet
1115            | StableTestnet
1116            | Injective
1117            | InjectiveTestnet
1118            | Katana
1119            | Lisk
1120            | Fuse
1121            | Cannon
1122            | SkaleBase
1123            | SkaleBaseSepoliaTestnet
1124            | PolkadotTestnet
1125            | PaseoPassethub
1126            | XdcMainnet
1127            | XdcTestnet
1128            | Tempo
1129            | TempoTestnet
1130            | TempoModerato => false,
1131        }
1132    }
1133
1134    /// Returns whether the chain supports the [Shanghai hardfork][ref].
1135    ///
1136    /// [ref]: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md
1137    pub const fn supports_shanghai(self) -> bool {
1138        use NamedChain::*;
1139
1140        matches!(
1141            self,
1142            Mainnet
1143                | Goerli
1144                | Sepolia
1145                | Holesky
1146                | Hoodi
1147                | AnvilHardhat
1148                | Optimism
1149                | OptimismGoerli
1150                | OptimismSepolia
1151                | Bob
1152                | BobSepolia
1153                | Odyssey
1154                | Base
1155                | BaseGoerli
1156                | BaseSepolia
1157                | Blast
1158                | BlastSepolia
1159                | Celo
1160                | CeloSepolia
1161                | Fraxtal
1162                | FraxtalTestnet
1163                | Ink
1164                | InkSepolia
1165                | Gnosis
1166                | Chiado
1167                | ZoraSepolia
1168                | Mantle
1169                | MantleSepolia
1170                | Mode
1171                | ModeSepolia
1172                | Polygon
1173                | Arbitrum
1174                | ArbitrumNova
1175                | ArbitrumSepolia
1176                | GravityAlphaMainnet
1177                | GravityAlphaTestnetSepolia
1178                | Xai
1179                | XaiSepolia
1180                | Syndr
1181                | SyndrSepolia
1182                | Etherlink
1183                | EtherlinkTestnet
1184                | Scroll
1185                | ScrollSepolia
1186                | HappychainTestnet
1187                | Shimmer
1188                | BinanceSmartChain
1189                | BinanceSmartChainTestnet
1190                | OpBNBMainnet
1191                | OpBNBTestnet
1192                | Taiko
1193                | TaikoHekla
1194                | Avalanche
1195                | AvalancheFuji
1196                | AutonomysNovaTestnet
1197                | Acala
1198                | AcalaMandalaTestnet
1199                | AcalaTestnet
1200                | Karura
1201                | KaruraTestnet
1202                | Darwinia
1203                | Crab
1204                | Cfx
1205                | CfxTestnet
1206                | Pulsechain
1207                | PulsechainTestnet
1208                | Koi
1209                | Immutable
1210                | ImmutableTestnet
1211                | Soneium
1212                | SoneiumMinatoTestnet
1213                | World
1214                | WorldSepolia
1215                | Iotex
1216                | Unichain
1217                | UnichainSepolia
1218                | SignetPecorino
1219                | StableMainnet
1220                | StableTestnet
1221                | MegaEth
1222                | MegaEthTestnet
1223                | ApeChain
1224                | Curtis
1225                | SuperpositionTestnet
1226                | Superposition
1227                | Monad
1228                | MonadTestnet
1229                | Corn
1230                | CornTestnet
1231                | Rsk
1232                | RskTestnet
1233                | Berachain
1234                | BerachainBepolia
1235                | Injective
1236                | InjectiveTestnet
1237                | FluentDevnet
1238                | FluentTestnet
1239                | Cannon
1240                | MemeCore
1241                | Formicarium
1242                | Insectarium
1243                | Tempo
1244                | TempoTestnet
1245                | TempoModerato
1246                | PaseoPassethub
1247        )
1248    }
1249
1250    /// Returns whether the chain is a testnet.
1251    pub const fn is_testnet(self) -> bool {
1252        use NamedChain::*;
1253
1254        match self {
1255            // Ethereum testnets.
1256            Goerli | Holesky | Kovan | Sepolia | Morden | Ropsten | Rinkeby | Hoodi => true,
1257
1258            // Other testnets.
1259            ArbitrumGoerli
1260            | ArbitrumSepolia
1261            | ArbitrumTestnet
1262            | SyndrSepolia
1263            | AuroraTestnet
1264            | AvalancheFuji
1265            | Odyssey
1266            | BaseGoerli
1267            | BaseSepolia
1268            | BlastSepolia
1269            | BinanceSmartChainTestnet
1270            | CantoTestnet
1271            | CronosTestnet
1272            | CeloSepolia
1273            | EmeraldTestnet
1274            | EvmosTestnet
1275            | FantomTestnet
1276            | FilecoinCalibrationTestnet
1277            | FraxtalTestnet
1278            | HappychainTestnet
1279            | LineaGoerli
1280            | LineaSepolia
1281            | InkSepolia
1282            | MantleSepolia
1283            | MoonbeamDev
1284            | OptimismGoerli
1285            | OptimismKovan
1286            | OptimismSepolia
1287            | BobSepolia
1288            | PolygonAmoy
1289            | ScrollSepolia
1290            | Shimmer
1291            | ZkSyncTestnet
1292            | ZoraSepolia
1293            | ModeSepolia
1294            | PgnSepolia
1295            | EtherlinkTestnet
1296            | OpBNBTestnet
1297            | RoninTestnet
1298            | TaikoHekla
1299            | AutonomysNovaTestnet
1300            | FlareCoston2
1301            | AcalaMandalaTestnet
1302            | AcalaTestnet
1303            | KaruraTestnet
1304            | CfxTestnet
1305            | PulsechainTestnet
1306            | GravityAlphaTestnetSepolia
1307            | XaiSepolia
1308            | Koi
1309            | ImmutableTestnet
1310            | SoneiumMinatoTestnet
1311            | WorldSepolia
1312            | UnichainSepolia
1313            | SignetPecorino
1314            | Curtis
1315            | TreasureTopaz
1316            | SonicTestnet
1317            | BerachainBepolia
1318            | SuperpositionTestnet
1319            | MonadTestnet
1320            | RskTestnet
1321            | TelosEvmTestnet
1322            | AbstractTestnet
1323            | LensTestnet
1324            | SophonTestnet
1325            | PolkadotTestnet
1326            | PaseoPassethub
1327            | InjectiveTestnet
1328            | FluentDevnet
1329            | FluentTestnet
1330            | SeiTestnet
1331            | StableTestnet
1332            | MegaEthTestnet
1333            | CornTestnet
1334            | Formicarium
1335            | Insectarium
1336            | SkaleBaseSepoliaTestnet
1337            | XdcTestnet
1338            | TempoTestnet
1339            | TempoModerato => true,
1340
1341            // Dev chains.
1342            Dev | AnvilHardhat | Cannon => true,
1343
1344            // Mainnets.
1345            Mainnet | Optimism | Arbitrum | ArbitrumNova | Blast | Syndr | Cronos | Rsk
1346            | BinanceSmartChain | Poa | Sokol | Scroll | Metis | Gnosis | Polygon | Fantom
1347            | Moonbeam | Moonriver | Moonbase | Evmos | Chiado | Oasis | Emerald | Plasma
1348            | FilecoinMainnet | Avalanche | Celo | Aurora | Canto | Boba | Base | Fraxtal | Ink
1349            | Linea | ZkSync | Mantle | GravityAlphaMainnet | Xai | Zora | Pgn | Mode | Viction
1350            | Elastos | Degen | OpBNBMainnet | Ronin | Taiko | Flare | Acala | Karura
1351            | Darwinia | Cfx | Crab | Pulsechain | Etherlink | Immutable | World | Iotex | Core
1352            | Merlin | Bitlayer | ApeChain | Vana | Zeta | Kaia | Treasure | Bob | Soneium
1353            | Sonic | Superposition | Berachain | Monad | Unichain | TelosEvm | Story | Sei
1354            | StableMainnet | MegaEth | Hyperliquid | Abstract | Sophon | Lens | Corn | Katana
1355            | Lisk | Fuse | Injective | MemeCore | SkaleBase | XdcMainnet | Tempo => false,
1356        }
1357    }
1358
1359    /// Returns the symbol of the chain's native currency.
1360    pub const fn native_currency_symbol(self) -> Option<&'static str> {
1361        use NamedChain::*;
1362
1363        Some(match self {
1364            Mainnet | Goerli | Holesky | Kovan | Sepolia | Morden | Ropsten | Rinkeby | Scroll
1365            | ScrollSepolia | Taiko | TaikoHekla | Unichain | UnichainSepolia | MegaEth
1366            | MegaEthTestnet | SuperpositionTestnet | Superposition | Abstract | ZkSync
1367            | ZkSyncTestnet | Katana | Lisk | Base | BaseGoerli | BaseSepolia | Optimism
1368            | OptimismSepolia => "ETH",
1369
1370            Mantle | MantleSepolia => "MNT",
1371
1372            GravityAlphaMainnet | GravityAlphaTestnetSepolia => "G",
1373
1374            Celo | CeloSepolia => "CELO",
1375
1376            Xai | XaiSepolia => "XAI",
1377
1378            HappychainTestnet => "HAPPY",
1379
1380            BinanceSmartChain | BinanceSmartChainTestnet | OpBNBMainnet | OpBNBTestnet => "BNB",
1381
1382            Etherlink | EtherlinkTestnet => "XTZ",
1383
1384            Degen => "DEGEN",
1385
1386            Ronin | RoninTestnet => "RON",
1387
1388            Shimmer => "SMR",
1389
1390            Flare => "FLR",
1391
1392            FlareCoston2 => "C2FLR",
1393
1394            Darwinia => "RING",
1395
1396            Crab => "CRAB",
1397
1398            Koi => "KRING",
1399
1400            Cfx | CfxTestnet => "CFX",
1401            Pulsechain | PulsechainTestnet => "PLS",
1402
1403            Immutable => "IMX",
1404            ImmutableTestnet => "tIMX",
1405
1406            World | WorldSepolia => "WRLD",
1407
1408            Iotex => "IOTX",
1409            Core => "CORE",
1410            Merlin => "BTC",
1411            Bitlayer => "BTC",
1412            Vana => "VANA",
1413            Zeta => "ZETA",
1414            Kaia => "KAIA",
1415            Story => "IP",
1416            Sei | SeiTestnet => "SEI",
1417            StableMainnet | StableTestnet => "gUSDT",
1418            ApeChain | Curtis => "APE",
1419
1420            XdcMainnet => "XDC",
1421            XdcTestnet => "TXDC",
1422
1423            Treasure | TreasureTopaz => "MAGIC",
1424
1425            BerachainBepolia | Berachain => "BERA",
1426
1427            Monad | MonadTestnet => "MON",
1428
1429            Sonic | SonicTestnet => "S",
1430
1431            TelosEvm | TelosEvmTestnet => "TLOS",
1432
1433            Hyperliquid => "HYPE",
1434
1435            SignetPecorino => "USDS",
1436
1437            Polygon | PolygonAmoy => "POL",
1438
1439            Corn | CornTestnet => "BTCN",
1440
1441            Sophon | SophonTestnet => "SOPH",
1442
1443            LensTestnet => "GRASS",
1444            Lens => "GHO",
1445
1446            Rsk => "RBTC",
1447            RskTestnet => "tRBTC",
1448
1449            Injective | InjectiveTestnet => "INJ",
1450
1451            Plasma => "XPL",
1452
1453            MemeCore => "M",
1454            Formicarium => "tM",
1455            Insectarium => "tM",
1456            PaseoPassethub => "PAS",
1457
1458            _ => return None,
1459        })
1460    }
1461
1462    /// Returns the chain's blockchain explorer and its API (Etherscan and Etherscan-like) URLs.
1463    ///
1464    /// Returns `(API_URL, BASE_URL)`.
1465    ///
1466    /// All URLs have no trailing `/`
1467    ///
1468    /// # Examples
1469    ///
1470    /// ```
1471    /// use alloy_chains::NamedChain;
1472    ///
1473    /// assert_eq!(
1474    ///     NamedChain::Mainnet.etherscan_urls(),
1475    ///     Some(("https://api.etherscan.io/v2/api?chainid=1", "https://etherscan.io"))
1476    /// );
1477    /// assert_eq!(NamedChain::AnvilHardhat.etherscan_urls(), None);
1478    /// ```
1479    pub const fn etherscan_urls(self) -> Option<(&'static str, &'static str)> {
1480        use NamedChain::*;
1481
1482        Some(match self {
1483            Mainnet => ("https://api.etherscan.io/v2/api?chainid=1", "https://etherscan.io"),
1484            Sepolia => {
1485                ("https://api.etherscan.io/v2/api?chainid=11155111", "https://sepolia.etherscan.io")
1486            }
1487            Holesky => {
1488                ("https://api.etherscan.io/v2/api?chainid=17000", "https://holesky.etherscan.io")
1489            }
1490            Hoodi => {
1491                ("https://api.etherscan.io/v2/api?chainid=560048", "https://hoodi.etherscan.io")
1492            }
1493            Polygon => ("https://api.etherscan.io/v2/api?chainid=137", "https://polygonscan.com"),
1494            PolygonAmoy => {
1495                ("https://api.etherscan.io/v2/api?chainid=80002", "https://amoy.polygonscan.com")
1496            }
1497            Avalanche => ("https://api.etherscan.io/v2/api?chainid=43114", "https://snowscan.xyz"),
1498            AvalancheFuji => {
1499                ("https://api.etherscan.io/v2/api?chainid=43113", "https://testnet.snowscan.xyz")
1500            }
1501            Optimism => {
1502                ("https://api.etherscan.io/v2/api?chainid=10", "https://optimistic.etherscan.io")
1503            }
1504            OptimismSepolia => (
1505                "https://api.etherscan.io/v2/api?chainid=11155420",
1506                "https://sepolia-optimism.etherscan.io",
1507            ),
1508            Bob => ("https://explorer.gobob.xyz/api", "https://explorer.gobob.xyz"),
1509            BobSepolia => (
1510                "https://bob-sepolia.explorer.gobob.xyz/api",
1511                "https://bob-sepolia.explorer.gobob.xyz",
1512            ),
1513            BinanceSmartChain => {
1514                ("https://api.etherscan.io/v2/api?chainid=56", "https://bscscan.com")
1515            }
1516            BinanceSmartChainTestnet => {
1517                ("https://api.etherscan.io/v2/api?chainid=97", "https://testnet.bscscan.com")
1518            }
1519            OpBNBMainnet => {
1520                ("https://api.etherscan.io/v2/api?chainid=204", "https://opbnb.bscscan.com")
1521            }
1522            OpBNBTestnet => (
1523                "https://api.etherscan.io/v2/api?chainid=5611",
1524                "https://opbnb-testnet.bscscan.com",
1525            ),
1526            Arbitrum => ("https://api.etherscan.io/v2/api?chainid=42161", "https://arbiscan.io"),
1527            ArbitrumSepolia => {
1528                ("https://api.etherscan.io/v2/api?chainid=421614", "https://sepolia.arbiscan.io")
1529            }
1530            ArbitrumNova => {
1531                ("https://api.etherscan.io/v2/api?chainid=42170", "https://nova.arbiscan.io")
1532            }
1533            GravityAlphaMainnet => {
1534                ("https://explorer.gravity.xyz/api", "https://explorer.gravity.xyz")
1535            }
1536            GravityAlphaTestnetSepolia => {
1537                ("https://explorer-sepolia.gravity.xyz/api", "https://explorer-sepolia.gravity.xyz")
1538            }
1539            HappychainTestnet => {
1540                ("https://explorer.testnet.happy.tech/api", "https://explorer.testnet.happy.tech")
1541            }
1542            XaiSepolia => (
1543                "https://api.etherscan.io/v2/api?chainid=37714555429",
1544                "https://sepolia.xaiscan.io",
1545            ),
1546            Xai => ("https://api.etherscan.io/v2/api?chainid=660279", "https://xaiscan.io"),
1547            Syndr => ("https://explorer.syndr.com/api", "https://explorer.syndr.com"),
1548            SyndrSepolia => {
1549                ("https://sepolia-explorer.syndr.com/api", "https://sepolia-explorer.syndr.com")
1550            }
1551            Cronos => ("https://api.etherscan.io/v2/api?chainid=25", "https://cronoscan.com"),
1552            Moonbeam => {
1553                ("https://api.etherscan.io/v2/api?chainid=1284", "https://moonbeam.moonscan.io")
1554            }
1555            Moonbase => {
1556                ("https://api.etherscan.io/v2/api?chainid=1287", "https://moonbase.moonscan.io")
1557            }
1558            Moonriver => {
1559                ("https://api.etherscan.io/v2/api?chainid=1285", "https://moonriver.moonscan.io")
1560            }
1561            Gnosis => ("https://api.etherscan.io/v2/api?chainid=100", "https://gnosisscan.io"),
1562            Scroll => ("https://api.etherscan.io/v2/api?chainid=534352", "https://scrollscan.com"),
1563            ScrollSepolia => {
1564                ("https://api.etherscan.io/v2/api?chainid=534351", "https://sepolia.scrollscan.com")
1565            }
1566            Ink => ("https://explorer.inkonchain.com/api/v2", "https://explorer.inkonchain.com"),
1567            InkSepolia => (
1568                "https://explorer-sepolia.inkonchain.com/api/v2",
1569                "https://explorer-sepolia.inkonchain.com",
1570            ),
1571            Shimmer => {
1572                ("https://explorer.evm.shimmer.network/api", "https://explorer.evm.shimmer.network")
1573            }
1574            Metis => (
1575                "https://api.routescan.io/v2/network/mainnet/evm/1088/etherscan",
1576                "https://explorer.metis.io",
1577            ),
1578            Chiado => {
1579                ("https://gnosis-chiado.blockscout.com/api", "https://gnosis-chiado.blockscout.com")
1580            }
1581            Plasma => (
1582                "https://api.routescan.io/v2/network/mainnet/evm/9745/etherscan/api",
1583                "https://plasmascan.to",
1584            ),
1585            FilecoinCalibrationTestnet => (
1586                "https://api.calibration.node.glif.io/rpc/v1",
1587                "https://calibration.filfox.info/en",
1588            ),
1589            Rsk => ("https://blockscout.com/rsk/mainnet/api", "https://blockscout.com/rsk/mainnet"),
1590            RskTestnet => (
1591                "https://rootstock-testnet.blockscout.com/api",
1592                "https://rootstock-testnet.blockscout.com",
1593            ),
1594            Emerald => {
1595                ("https://explorer.emerald.oasis.dev/api", "https://explorer.emerald.oasis.dev")
1596            }
1597            EmeraldTestnet => (
1598                "https://testnet.explorer.emerald.oasis.dev/api",
1599                "https://testnet.explorer.emerald.oasis.dev",
1600            ),
1601            Aurora => ("https://api.aurorascan.dev/api", "https://aurorascan.dev"),
1602            AuroraTestnet => {
1603                ("https://testnet.aurorascan.dev/api", "https://testnet.aurorascan.dev")
1604            }
1605            Celo => ("https://api.etherscan.io/v2/api?chainid=42220", "https://celoscan.io"),
1606            CeloSepolia => {
1607                ("https://api.etherscan.io/v2/api?chainid=11142220", "https://sepolia.celoscan.io")
1608            }
1609            Boba => ("https://api.bobascan.com/api", "https://bobascan.com"),
1610            Base => ("https://api.etherscan.io/v2/api?chainid=8453", "https://basescan.org"),
1611            BaseSepolia => {
1612                ("https://api.etherscan.io/v2/api?chainid=84532", "https://sepolia.basescan.org")
1613            }
1614            Fraxtal => ("https://api.etherscan.io/v2/api?chainid=252", "https://fraxscan.com"),
1615            FraxtalTestnet => {
1616                ("https://api.etherscan.io/v2/api?chainid=2522", "https://holesky.fraxscan.com")
1617            }
1618            Blast => ("https://api.etherscan.io/v2/api?chainid=81457", "https://blastscan.io"),
1619            BlastSepolia => (
1620                "https://api.etherscan.io/v2/api?chainid=168587773",
1621                "https://sepolia.blastscan.io",
1622            ),
1623            ZkSync => ("https://api.etherscan.io/v2/api?chainid=324", "https://era.zksync.network"),
1624            ZkSyncTestnet => (
1625                "https://api.etherscan.io/v2/api?chainid=300",
1626                "https://sepolia-era.zksync.network",
1627            ),
1628            Linea => ("https://api.etherscan.io/v2/api?chainid=59144", "https://lineascan.build"),
1629            LineaSepolia => {
1630                ("https://api.etherscan.io/v2/api?chainid=59141", "https://sepolia.lineascan.build")
1631            }
1632            Mantle => ("https://api.etherscan.io/v2/api?chainid=5000", "https://mantlescan.xyz"),
1633            MantleSepolia => {
1634                ("https://api.etherscan.io/v2/api?chainid=5003", "https://sepolia.mantlescan.xyz")
1635            }
1636            Viction => ("https://www.vicscan.xyz/api", "https://www.vicscan.xyz"),
1637            Zora => ("https://explorer.zora.energy/api", "https://explorer.zora.energy"),
1638            ZoraSepolia => {
1639                ("https://sepolia.explorer.zora.energy/api", "https://sepolia.explorer.zora.energy")
1640            }
1641            Mode => ("https://explorer.mode.network/api", "https://explorer.mode.network"),
1642            ModeSepolia => (
1643                "https://sepolia.explorer.mode.network/api",
1644                "https://sepolia.explorer.mode.network",
1645            ),
1646            Elastos => ("https://esc.elastos.io/api", "https://esc.elastos.io"),
1647            Etherlink => ("https://explorer.etherlink.com/api", "https://explorer.etherlink.com"),
1648            EtherlinkTestnet => (
1649                "https://testnet.explorer.etherlink.com/api",
1650                "https://testnet.explorer.etherlink.com",
1651            ),
1652            Degen => ("https://explorer.degen.tips/api", "https://explorer.degen.tips"),
1653            Ronin => ("https://skynet-api.roninchain.com/ronin", "https://app.roninchain.com"),
1654            RoninTestnet => (
1655                "https://api-gateway.skymavis.com/rpc/testnet",
1656                "https://saigon-app.roninchain.com",
1657            ),
1658            Taiko => ("https://api.etherscan.io/v2/api?chainid=167000", "https://taikoscan.io"),
1659            TaikoHekla => {
1660                ("https://api.etherscan.io/v2/api?chainid=167009", "https://hekla.taikoscan.io")
1661            }
1662            Flare => {
1663                ("https://flare-explorer.flare.network/api", "https://flare-explorer.flare.network")
1664            }
1665            FlareCoston2 => (
1666                "https://coston2-explorer.flare.network/api",
1667                "https://coston2-explorer.flare.network",
1668            ),
1669            Acala => ("https://blockscout.acala.network/api", "https://blockscout.acala.network"),
1670            AcalaMandalaTestnet => (
1671                "https://blockscout.mandala.aca-staging.network/api",
1672                "https://blockscout.mandala.aca-staging.network",
1673            ),
1674            Karura => {
1675                ("https://blockscout.karura.network/api", "https://blockscout.karura.network")
1676            }
1677            Darwinia => {
1678                ("https://explorer.darwinia.network/api", "https://explorer.darwinia.network")
1679            }
1680            Crab => {
1681                ("https://crab-scan.darwinia.network/api", "https://crab-scan.darwinia.network")
1682            }
1683            Cfx => ("https://evmapi.confluxscan.net/api", "https://evm.confluxscan.io"),
1684            CfxTestnet => {
1685                ("https://evmapi-testnet.confluxscan.net/api", "https://evmtestnet.confluxscan.io")
1686            }
1687            Pulsechain => ("https://api.scan.pulsechain.com", "https://scan.pulsechain.com"),
1688            PulsechainTestnet => (
1689                "https://api.scan.v4.testnet.pulsechain.com",
1690                "https://scan.v4.testnet.pulsechain.com",
1691            ),
1692            Immutable => ("https://explorer.immutable.com/api", "https://explorer.immutable.com"),
1693            ImmutableTestnet => (
1694                "https://explorer.testnet.immutable.com/api",
1695                "https://explorer.testnet.immutable.com",
1696            ),
1697            Soneium => ("https://soneium.blockscout.com/api", "https://soneium.blockscout.com"),
1698            SoneiumMinatoTestnet => (
1699                "https://soneium-minato.blockscout.com/api",
1700                "https://soneium-minato.blockscout.com",
1701            ),
1702            Odyssey => {
1703                ("https://odyssey-explorer.ithaca.xyz/api", "https://odyssey-explorer.ithaca.xyz")
1704            }
1705            World => ("https://api.etherscan.io/v2/api?chainid=480", "https://worldscan.org"),
1706            WorldSepolia => {
1707                ("https://api.etherscan.io/v2/api?chainid=4801", "https://sepolia.worldscan.org")
1708            }
1709            Unichain => ("https://api.etherscan.io/v2/api?chainid=130", "https://uniscan.xyz"),
1710            UnichainSepolia => {
1711                ("https://api.etherscan.io/v2/api?chainid=1301", "https://sepolia.uniscan.xyz")
1712            }
1713            SignetPecorino => {
1714                ("https://explorer.pecorino.signet.sh/api", "https://explorer.pecorino.signet.sh")
1715            }
1716            Core => ("https://openapi.coredao.org/api", "https://scan.coredao.org"),
1717            Merlin => ("https://scan.merlinchain.io/api", "https://scan.merlinchain.io"),
1718            Bitlayer => ("https://api.btrscan.com/scan/api", "https://www.btrscan.com"),
1719            Vana => ("https://api.vanascan.io/api", "https://vanascan.io"),
1720            Zeta => ("https://zetachain.blockscout.com/api", "https://zetachain.blockscout.com"),
1721            Kaia => ("https://mainnet-oapi.kaiascan.io/api", "https://kaiascan.io"),
1722            Story => ("https://www.storyscan.xyz/api/v2", "https://www.storyscan.xyz"),
1723            Sei => ("https://api.etherscan.io/v2/api?chainid=1329", "https://seiscan.io"),
1724            SeiTestnet => {
1725                ("https://api.etherscan.io/v2/api?chainid=1328", "https://testnet.seiscan.io")
1726            }
1727            StableMainnet => {
1728                ("https://api.etherscan.io/v2/api?chainid=988", "https://stablescan.xyz")
1729            }
1730            StableTestnet => {
1731                ("https://api.etherscan.io/v2/api?chainid=2201", "https://testnet.stablescan.xyz")
1732            }
1733            MegaEth => ("https://api.etherscan.io/v2/api?chainid=4326", "https://megascan.com"),
1734            MegaEthTestnet => {
1735                ("https://api.etherscan.io/v2/api?chainid=6343", "https://testnet.megascan.com")
1736            }
1737            XdcMainnet => ("https://api.etherscan.io/v2/api?chainid=50", "https://xdcscan.com"),
1738            XdcTestnet => {
1739                ("https://api.etherscan.io/v2/api?chainid=51", "https://testnet.xdcscan.com")
1740            }
1741            ApeChain => ("https://api.etherscan.io/v2/api?chainid=33139", "https://apescan.io"),
1742            Curtis => {
1743                ("https://api.etherscan.io/v2/api?chainid=33111", "https://curtis.apescan.io")
1744            }
1745            Sonic => ("https://api.etherscan.io/v2/api?chainid=146", "https://sonicscan.org"),
1746            SonicTestnet => {
1747                ("https://api.etherscan.io/v2/api?chainid=14601", "https://testnet.sonicscan.org")
1748            }
1749            BerachainBepolia => {
1750                ("https://api.etherscan.io/v2/api?chainid=80069", "https://testnet.berascan.com")
1751            }
1752            Berachain => ("https://api.etherscan.io/v2/api?chainid=80094", "https://berascan.com"),
1753            SuperpositionTestnet => (
1754                "https://testnet-explorer.superposition.so/api",
1755                "https://testnet-explorer.superposition.so",
1756            ),
1757            Superposition => {
1758                ("https://explorer.superposition.so/api", "https://explorer.superposition.so")
1759            }
1760            Monad => ("https://api.etherscan.io/v2/api?chainid=143", "https://monadscan.com"),
1761            MonadTestnet => {
1762                ("https://api.etherscan.io/v2/api?chainid=10143", "https://testnet.monadscan.com")
1763            }
1764            TelosEvm => ("https://api.teloscan.io/api", "https://teloscan.io"),
1765            TelosEvmTestnet => {
1766                ("https://api.testnet.teloscan.io/api", "https://testnet.teloscan.io")
1767            }
1768            Hyperliquid => {
1769                ("https://api.etherscan.io/v2/api?chainid=999", "https://hyperevmscan.io")
1770            }
1771            Abstract => ("https://api.etherscan.io/v2/api?chainid=2741", "https://abscan.org"),
1772            AbstractTestnet => {
1773                ("https://api.etherscan.io/v2/api?chainid=11124", "https://sepolia.abscan.org")
1774            }
1775            Corn => (
1776                "https://api.routescan.io/v2/network/mainnet/evm/21000000/etherscan/api",
1777                "https://cornscan.io",
1778            ),
1779            CornTestnet => (
1780                "https://api.routescan.io/v2/network/testnet/evm/21000001/etherscan/api",
1781                "https://testnet.cornscan.io",
1782            ),
1783            Sophon => ("https://api.etherscan.io/v2/api?chainid=50104", "https://sophscan.xyz"),
1784            SophonTestnet => (
1785                "https://api.etherscan.io/v2/api?chainid=531050104",
1786                "https://testnet.sophscan.xyz",
1787            ),
1788            Lens => ("https://explorer-api.lens.xyz", "https://explorer.lens.xyz"),
1789            LensTestnet => (
1790                "https://block-explorer-api.staging.lens.zksync.dev",
1791                "https://explorer.testnet.lens.xyz",
1792            ),
1793            Katana => ("https://api.etherscan.io/v2/api?chainid=747474", "https://katanascan.com"),
1794            Lisk => ("https://blockscout.lisk.com/api", "https://blockscout.lisk.com"),
1795            Fuse => ("https://explorer.fuse.io/api", "https://explorer.fuse.io"),
1796            Injective => (
1797                "https://blockscout-api.injective.network/api",
1798                "https://blockscout.injective.network",
1799            ),
1800            InjectiveTestnet => (
1801                "https://testnet.blockscout-api.injective.network/api",
1802                "https://testnet.blockscout.injective.network",
1803            ),
1804            FluentDevnet => {
1805                ("https://blockscout.dev.gblend.xyz/api", "https://blockscout.dev.gblend.xyz")
1806            }
1807            FluentTestnet => {
1808                ("https://testnet.fluentscan.xyz/api", "https://testnet.fluentscan.xyz")
1809            }
1810            MemeCore => ("https://api.etherscan.io/v2/api?chainid=4352", "https://memecorescan.io"),
1811            Formicarium => (
1812                "https://api.etherscan.io/v2/api?chainid=43521",
1813                "https://formicarium.memecorescan.io",
1814            ),
1815            Insectarium => (
1816                "https://insectarium.blockscout.memecore.com/api",
1817                "https://insectarium.blockscout.memecore.com",
1818            ),
1819            SkaleBase => (
1820                "https://skale-base-explorer.skalenodes.com/api",
1821                "https://skale-base-explorer.skalenodes.com",
1822            ),
1823            SkaleBaseSepoliaTestnet => (
1824                "https://base-sepolia-testnet-explorer.skalenodes.com/api",
1825                "https://base-sepolia-testnet-explorer.skalenodes.com",
1826            ),
1827            Tempo => {
1828                ("https://contracts.tempo.xyz/v2/contract", "https://explore.mainnet.tempo.xyz")
1829            }
1830            TempoTestnet => ("https://scout.tempo.xyz/api", "https://scout.tempo.xyz"),
1831            TempoModerato => ("https://scout.tempo.xyz/api", "https://scout.tempo.xyz"),
1832            PaseoPassethub => (
1833                "https://blockscout-passet-hub.parity-testnet.parity.io/api",
1834                "https://blockscout-passet-hub.parity-testnet.parity.io",
1835            ),
1836
1837            AcalaTestnet | AnvilHardhat | ArbitrumGoerli | ArbitrumTestnet
1838            | AutonomysNovaTestnet | BaseGoerli | Canto | CantoTestnet | CronosTestnet | Dev
1839            | Evmos | EvmosTestnet | Fantom | FantomTestnet | FilecoinMainnet | Goerli | Iotex
1840            | KaruraTestnet | Koi | Kovan | LineaGoerli | MoonbeamDev | Morden | Oasis
1841            | OptimismGoerli | OptimismKovan | Pgn | PgnSepolia | Poa | Rinkeby | Ropsten
1842            | Sokol | Treasure | TreasureTopaz | Cannon | PolkadotTestnet => {
1843                return None;
1844            }
1845        })
1846    }
1847
1848    /// Returns the chain's blockchain explorer's API key environment variable's default name.
1849    ///
1850    /// # Examples
1851    ///
1852    /// ```
1853    /// use alloy_chains::NamedChain;
1854    ///
1855    /// assert_eq!(NamedChain::Mainnet.etherscan_api_key_name(), Some("ETHERSCAN_API_KEY"));
1856    /// assert_eq!(NamedChain::AnvilHardhat.etherscan_api_key_name(), None);
1857    /// ```
1858    pub const fn etherscan_api_key_name(self) -> Option<&'static str> {
1859        use NamedChain::*;
1860
1861        let api_key_name = match self {
1862            Abstract
1863            | AbstractTestnet
1864            | ApeChain
1865            | Arbitrum
1866            | ArbitrumGoerli
1867            | ArbitrumNova
1868            | ArbitrumSepolia
1869            | ArbitrumTestnet
1870            | Aurora
1871            | AuroraTestnet
1872            | Avalanche
1873            | AvalancheFuji
1874            | Base
1875            | BaseGoerli
1876            | BaseSepolia
1877            | BinanceSmartChain
1878            | BinanceSmartChainTestnet
1879            | Blast
1880            | BlastSepolia
1881            | Celo
1882            | Cronos
1883            | CronosTestnet
1884            | Fraxtal
1885            | FraxtalTestnet
1886            | Gnosis
1887            | Goerli
1888            | Holesky
1889            | Hoodi
1890            | Hyperliquid
1891            | Katana
1892            | Kovan
1893            | Linea
1894            | LineaSepolia
1895            | Mainnet
1896            | Mantle
1897            | MantleSepolia
1898            | Monad
1899            | MonadTestnet
1900            | Morden
1901            | OpBNBMainnet
1902            | OpBNBTestnet
1903            | Optimism
1904            | OptimismGoerli
1905            | OptimismKovan
1906            | OptimismSepolia
1907            | Polygon
1908            | PolygonAmoy
1909            | Rinkeby
1910            | Ropsten
1911            | Scroll
1912            | ScrollSepolia
1913            | Sei
1914            | SeiTestnet
1915            | StableMainnet
1916            | StableTestnet
1917            | MegaEth
1918            | MegaEthTestnet
1919            | XdcMainnet
1920            | XdcTestnet
1921            | Sonic
1922            | SonicTestnet
1923            | Sophon
1924            | SophonTestnet
1925            | Syndr
1926            | SyndrSepolia
1927            | Taiko
1928            | TaikoHekla
1929            | Unichain
1930            | UnichainSepolia
1931            | Xai
1932            | XaiSepolia
1933            | ZkSync
1934            | ZkSyncTestnet
1935            | MemeCore
1936            | Formicarium => "ETHERSCAN_API_KEY",
1937
1938            Fantom | FantomTestnet => "FTMSCAN_API_KEY",
1939
1940            Moonbeam | Moonbase | MoonbeamDev | Moonriver => "MOONSCAN_API_KEY",
1941
1942            Acala
1943            | AcalaMandalaTestnet
1944            | AcalaTestnet
1945            | Canto
1946            | CantoTestnet
1947            | CeloSepolia
1948            | Etherlink
1949            | EtherlinkTestnet
1950            | Flare
1951            | FlareCoston2
1952            | Karura
1953            | KaruraTestnet
1954            | Mode
1955            | ModeSepolia
1956            | Pgn
1957            | PgnSepolia
1958            | Shimmer
1959            | Zora
1960            | ZoraSepolia
1961            | Darwinia
1962            | Crab
1963            | Koi
1964            | Immutable
1965            | ImmutableTestnet
1966            | Soneium
1967            | SoneiumMinatoTestnet
1968            | World
1969            | WorldSepolia
1970            | Curtis
1971            | Ink
1972            | InkSepolia
1973            | SuperpositionTestnet
1974            | Superposition
1975            | Vana
1976            | Story
1977            | Lisk
1978            | Fuse
1979            | Injective
1980            | InjectiveTestnet
1981            | SignetPecorino
1982            | SkaleBase
1983            | SkaleBaseSepoliaTestnet
1984            | PaseoPassethub
1985            | Tempo
1986            | TempoTestnet
1987            | TempoModerato => "BLOCKSCOUT_API_KEY",
1988
1989            Boba => "BOBASCAN_API_KEY",
1990
1991            Core => "CORESCAN_API_KEY",
1992            Merlin => "MERLINSCAN_API_KEY",
1993            Bitlayer => "BITLAYERSCAN_API_KEY",
1994            Zeta => "ZETASCAN_API_KEY",
1995            Kaia => "KAIASCAN_API_KEY",
1996            Berachain | BerachainBepolia => "BERASCAN_API_KEY",
1997            Corn | CornTestnet | Plasma => "ROUTESCAN_API_KEY",
1998            // Explicitly exhaustive. See NB above.
1999            Metis
2000            | Chiado
2001            | Odyssey
2002            | Sepolia
2003            | Rsk
2004            | RskTestnet
2005            | Sokol
2006            | Poa
2007            | Oasis
2008            | Emerald
2009            | EmeraldTestnet
2010            | Evmos
2011            | EvmosTestnet
2012            | AnvilHardhat
2013            | Dev
2014            | GravityAlphaMainnet
2015            | GravityAlphaTestnetSepolia
2016            | Bob
2017            | BobSepolia
2018            | FilecoinMainnet
2019            | LineaGoerli
2020            | FilecoinCalibrationTestnet
2021            | Viction
2022            | Elastos
2023            | Degen
2024            | Ronin
2025            | RoninTestnet
2026            | Cfx
2027            | CfxTestnet
2028            | Pulsechain
2029            | PulsechainTestnet
2030            | AutonomysNovaTestnet
2031            | Iotex
2032            | HappychainTestnet
2033            | Treasure
2034            | TreasureTopaz
2035            | TelosEvm
2036            | TelosEvmTestnet
2037            | Lens
2038            | LensTestnet
2039            | FluentDevnet
2040            | FluentTestnet
2041            | Cannon
2042            | Insectarium
2043            | PolkadotTestnet => return None,
2044        };
2045
2046        Some(api_key_name)
2047    }
2048
2049    /// Returns the chain's blockchain explorer's API key, from the environment variable with the
2050    /// name specified in [`etherscan_api_key_name`](NamedChain::etherscan_api_key_name).
2051    ///
2052    /// # Examples
2053    ///
2054    /// ```
2055    /// use alloy_chains::NamedChain;
2056    ///
2057    /// let chain = NamedChain::Mainnet;
2058    /// unsafe {
2059    ///     std::env::set_var(chain.etherscan_api_key_name().unwrap(), "KEY");
2060    /// }
2061    /// assert_eq!(chain.etherscan_api_key().as_deref(), Some("KEY"));
2062    /// ```
2063    #[cfg(feature = "std")]
2064    pub fn etherscan_api_key(self) -> Option<String> {
2065        self.etherscan_api_key_name().and_then(|name| std::env::var(name).ok())
2066    }
2067
2068    /// Returns the address of the public DNS node list for the given chain.
2069    ///
2070    /// See also <https://github.com/ethereum/discv4-dns-lists>.
2071    pub fn public_dns_network_protocol(self) -> Option<String> {
2072        use NamedChain::*;
2073
2074        const DNS_PREFIX: &str = "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@";
2075        if let Mainnet | Goerli | Sepolia | Ropsten | Rinkeby | Holesky | Hoodi = self {
2076            // `{DNS_PREFIX}all.{self.lower()}.ethdisco.net`
2077            let mut s = String::with_capacity(DNS_PREFIX.len() + 32);
2078            s.push_str(DNS_PREFIX);
2079            s.push_str("all.");
2080            let chain_str = self.as_ref();
2081            s.push_str(chain_str);
2082            let l = s.len();
2083            s[l - chain_str.len()..].make_ascii_lowercase();
2084            s.push_str(".ethdisco.net");
2085
2086            Some(s)
2087        } else {
2088            None
2089        }
2090    }
2091
2092    /// Returns the address of the most popular wrapped native token address for this chain, if it
2093    /// exists.
2094    ///
2095    /// Example:
2096    ///
2097    /// ```
2098    /// use alloy_chains::NamedChain;
2099    /// use alloy_primitives::address;
2100    ///
2101    /// let chain = NamedChain::Mainnet;
2102    /// assert_eq!(
2103    ///     chain.wrapped_native_token(),
2104    ///     Some(address!("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"))
2105    /// );
2106    /// ```
2107    pub const fn wrapped_native_token(self) -> Option<Address> {
2108        use NamedChain::*;
2109
2110        let addr = match self {
2111            Mainnet => address!("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
2112            Optimism => address!("4200000000000000000000000000000000000006"),
2113            BinanceSmartChain => address!("bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c"),
2114            OpBNBMainnet => address!("4200000000000000000000000000000000000006"),
2115            Arbitrum => address!("82af49447d8a07e3bd95bd0d56f35241523fbab1"),
2116            Base => address!("4200000000000000000000000000000000000006"),
2117            Linea => address!("e5d7c2a44ffddf6b295a15c148167daaaf5cf34f"),
2118            Mantle => address!("deaddeaddeaddeaddeaddeaddeaddeaddead1111"),
2119            Blast => address!("4300000000000000000000000000000000000004"),
2120            Gnosis => address!("e91d153e0b41518a2ce8dd3d7944fa863463a97d"),
2121            Scroll => address!("5300000000000000000000000000000000000004"),
2122            Taiko => address!("a51894664a773981c6c112c43ce576f315d5b1b6"),
2123            Avalanche => address!("b31f66aa3c1e785363f0875a1b74e27b85fd66c7"),
2124            Polygon => address!("0d500b1d8e8ef31e21c99d1db9a6444d3adf1270"),
2125            Fantom => address!("21be370d5312f44cb42ce377bc9b8a0cef1a4c83"),
2126            Iotex => address!("a00744882684c3e4747faefd68d283ea44099d03"),
2127            Core => address!("40375C92d9FAf44d2f9db9Bd9ba41a3317a2404f"),
2128            Merlin => address!("F6D226f9Dc15d9bB51182815b320D3fBE324e1bA"),
2129            Bitlayer => address!("ff204e2681a6fa0e2c3fade68a1b28fb90e4fc5f"),
2130            ApeChain => address!("48b62137EdfA95a428D35C09E44256a739F6B557"),
2131            Vana => address!("00EDdD9621Fb08436d0331c149D1690909a5906d"),
2132            Zeta => address!("5F0b1a82749cb4E2278EC87F8BF6B618dC71a8bf"),
2133            Kaia => address!("19aac5f612f524b754ca7e7c41cbfa2e981a4432"),
2134            Story => address!("1514000000000000000000000000000000000000"),
2135            Treasure => address!("263d8f36bb8d0d9526255e205868c26690b04b88"),
2136            Superposition => address!("1fB719f10b56d7a85DCD32f27f897375fB21cfdd"),
2137            Sonic => address!("039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38"),
2138            Berachain => address!("6969696969696969696969696969696969696969"),
2139            Hyperliquid => address!("5555555555555555555555555555555555555555"),
2140            Abstract => address!("3439153EB7AF838Ad19d56E1571FBD09333C2809"),
2141            Sei => address!("E30feDd158A2e3b13e9badaeABaFc5516e95e8C7"),
2142            ZkSync => address!("5aea5775959fbc2557cc8789bc1bf90a239d9a91"),
2143            Sophon => address!("f1f9e08a0818594fde4713ae0db1e46672ca960e"),
2144            Rsk => address!("967f8799af07df1534d48a95a5c9febe92c53ae0"),
2145            MemeCore | Formicarium | Insectarium => {
2146                address!("0x653e645e3d81a72e71328Bc01A04002945E3ef7A")
2147            }
2148            _ => return None,
2149        };
2150
2151        Some(addr)
2152    }
2153}
2154
2155#[cfg(test)]
2156mod tests {
2157    use super::*;
2158    use strum::{EnumCount, IntoEnumIterator};
2159
2160    #[allow(unused_imports)]
2161    use alloc::string::ToString;
2162
2163    #[test]
2164    #[cfg(feature = "serde")]
2165    fn default() {
2166        assert_eq!(serde_json::to_string(&NamedChain::default()).unwrap(), "\"mainnet\"");
2167    }
2168
2169    #[test]
2170    fn enum_iter() {
2171        assert_eq!(NamedChain::COUNT, NamedChain::iter().size_hint().0);
2172    }
2173
2174    #[test]
2175    fn roundtrip_string() {
2176        for chain in NamedChain::iter() {
2177            let chain_string = chain.to_string();
2178            assert_eq!(chain_string, format!("{chain}"));
2179            assert_eq!(chain_string.as_str(), chain.as_ref());
2180            #[cfg(feature = "serde")]
2181            assert_eq!(serde_json::to_string(&chain).unwrap(), format!("\"{chain_string}\""));
2182
2183            assert_eq!(chain_string.parse::<NamedChain>().unwrap(), chain);
2184        }
2185    }
2186
2187    #[test]
2188    #[cfg(feature = "serde")]
2189    fn roundtrip_serde() {
2190        for chain in NamedChain::iter() {
2191            let chain_string = serde_json::to_string(&chain).unwrap();
2192            let chain_string = chain_string.replace('-', "_");
2193            assert_eq!(serde_json::from_str::<'_, NamedChain>(&chain_string).unwrap(), chain);
2194        }
2195    }
2196
2197    #[test]
2198    #[cfg(feature = "arbitrary")]
2199    fn test_arbitrary_named_chain() {
2200        use arbitrary::{Arbitrary, Unstructured};
2201        let data = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 255];
2202        let mut unstructured = Unstructured::new(&data);
2203
2204        for _ in 0..10 {
2205            let _chain = NamedChain::arbitrary(&mut unstructured).unwrap();
2206        }
2207    }
2208
2209    #[test]
2210    fn aliases() {
2211        use NamedChain::*;
2212
2213        // kebab-case
2214        const ALIASES: &[(NamedChain, &[&str])] = &[
2215            (Mainnet, &["ethlive"]),
2216            (BinanceSmartChain, &["bsc", "bnb-smart-chain", "binance-smart-chain"]),
2217            (
2218                BinanceSmartChainTestnet,
2219                &["bsc-testnet", "bnb-smart-chain-testnet", "binance-smart-chain-testnet"],
2220            ),
2221            (Gnosis, &["gnosis", "gnosis-chain"]),
2222            (AnvilHardhat, &["anvil", "hardhat"]),
2223            (AvalancheFuji, &["fuji"]),
2224            (ZkSync, &["zksync"]),
2225            (ZkSyncTestnet, &["zksync-testnet"]),
2226            (Mantle, &["mantle"]),
2227            (MantleSepolia, &["mantle-sepolia"]),
2228            (GravityAlphaMainnet, &["gravity-alpha-mainnet"]),
2229            (GravityAlphaTestnetSepolia, &["gravity-alpha-testnet-sepolia"]),
2230            (Bob, &["bob"]),
2231            (BobSepolia, &["bob-sepolia"]),
2232            (HappychainTestnet, &["happychain-testnet"]),
2233            (Xai, &["xai"]),
2234            (XaiSepolia, &["xai-sepolia"]),
2235            (Base, &["base"]),
2236            (BaseGoerli, &["base-goerli"]),
2237            (BaseSepolia, &["base-sepolia"]),
2238            (Fraxtal, &["fraxtal"]),
2239            (FraxtalTestnet, &["fraxtal-testnet"]),
2240            (Ink, &["ink"]),
2241            (InkSepolia, &["ink-sepolia"]),
2242            (BlastSepolia, &["blast-sepolia"]),
2243            (Syndr, &["syndr"]),
2244            (SyndrSepolia, &["syndr-sepolia"]),
2245            (LineaGoerli, &["linea-goerli"]),
2246            (LineaSepolia, &["linea-sepolia"]),
2247            (AutonomysNovaTestnet, &["autonomys-nova-testnet"]),
2248            (Immutable, &["immutable"]),
2249            (ImmutableTestnet, &["immutable-testnet"]),
2250            (Soneium, &["soneium"]),
2251            (SoneiumMinatoTestnet, &["soneium-minato-testnet"]),
2252            (ApeChain, &["apechain"]),
2253            (Curtis, &["apechain-testnet", "curtis"]),
2254            (Treasure, &["treasure"]),
2255            (TreasureTopaz, &["treasure-topaz-testnet", "treasure-topaz"]),
2256            (BerachainBepolia, &["berachain-bepolia-testnet", "berachain-bepolia"]),
2257            (SuperpositionTestnet, &["superposition-testnet"]),
2258            (Superposition, &["superposition"]),
2259            (Hyperliquid, &["hyperliquid"]),
2260            (Abstract, &["abstract"]),
2261            (AbstractTestnet, &["abstract-testnet"]),
2262            (Sophon, &["sophon"]),
2263            (SophonTestnet, &["sophon-testnet"]),
2264            (Lens, &["lens"]),
2265            (LensTestnet, &["lens-testnet"]),
2266            (Katana, &["katana"]),
2267            (Lisk, &["lisk"]),
2268            (Fuse, &["fuse"]),
2269            (FluentDevnet, &["fluent-devnet"]),
2270            (FluentTestnet, &["fluent-testnet"]),
2271            (Injective, &["injective"]),
2272            (InjectiveTestnet, &["injective-testnet"]),
2273            (StableMainnet, &["stable-mainnet"]),
2274            (XdcMainnet, &["xdc-mainnet"]),
2275            (XdcTestnet, &["xdc-testnet"]),
2276            (SeiTestnet, &["sei-testnet"]),
2277            (StableTestnet, &["stable-testnet"]),
2278            (MegaEth, &["megaeth"]),
2279            (MegaEthTestnet, &["megaeth-testnet"]),
2280            (Cannon, &["cannon"]),
2281            (MemeCore, &["memecore"]),
2282            (Formicarium, &["formicarium", "memecore-formicarium"]),
2283            (Insectarium, &["insectarium", "memecore-insectarium"]),
2284        ];
2285
2286        for &(chain, aliases) in ALIASES {
2287            for &alias in aliases {
2288                let named = alias.parse::<NamedChain>().expect(alias);
2289                assert_eq!(named, chain);
2290
2291                #[cfg(feature = "serde")]
2292                {
2293                    assert_eq!(
2294                        serde_json::from_str::<NamedChain>(&format!("\"{alias}\"")).unwrap(),
2295                        chain
2296                    );
2297
2298                    assert_eq!(
2299                        serde_json::from_str::<NamedChain>(&format!("\"{named}\"")).unwrap(),
2300                        chain
2301                    );
2302                }
2303            }
2304        }
2305    }
2306
2307    #[test]
2308    #[cfg(feature = "serde")]
2309    fn serde_to_string_match() {
2310        for chain in NamedChain::iter() {
2311            let chain_serde = serde_json::to_string(&chain).unwrap();
2312            let chain_string = format!("\"{chain}\"");
2313            assert_eq!(chain_serde, chain_string);
2314        }
2315    }
2316
2317    #[test]
2318    fn test_dns_network() {
2319        let s = "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@all.mainnet.ethdisco.net";
2320        assert_eq!(NamedChain::Mainnet.public_dns_network_protocol().unwrap(), s);
2321    }
2322
2323    #[test]
2324    fn ensure_no_trailing_etherscan_url_separator() {
2325        for chain in NamedChain::iter() {
2326            if let Some((api, base)) = chain.etherscan_urls() {
2327                assert!(!api.ends_with('/'), "{chain:?} api url has trailing /");
2328                assert!(!base.ends_with('/'), "{chain:?} base url has trailing /");
2329            }
2330        }
2331    }
2332}