Skip to main content

alloy_chains/
named.rs

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