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