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