Skip to main content

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