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