maili_superchain/
lib.rs

1#![doc = include_str!("../README.md")]
2#![doc(
3    html_logo_url = "https://raw.githubusercontent.com/op-rs/maili/main/assets/square.png",
4    html_favicon_url = "https://raw.githubusercontent.com/op-rs/maili/main/assets/favicon.ico"
5)]
6#![cfg_attr(not(test), warn(unused_crate_dependencies))]
7#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
8#![no_std]
9
10extern crate alloc;
11
12use alloc::{string::String, vec::Vec};
13use alloy_primitives::Address;
14use maili_genesis::{ChainConfig, HardForkConfiguration};
15
16/// A superchain configuration.
17#[derive(Debug, Clone, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
18pub struct Superchain {
19    /// Superchain identifier, without capitalization or display changes.
20    pub name: String,
21    /// Superchain configuration file contents.
22    pub config: SuperchainConfig,
23    /// Chain IDs of chains that are part of this superchain.
24    pub chains: Vec<ChainConfig>,
25}
26
27/// A superchain configuration file format
28#[derive(Debug, Clone, Default, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
29pub struct SuperchainConfig {
30    /// Superchain name (e.g. "Mainnet")
31    pub name: String,
32    /// Superchain L1 anchor information
33    pub l1: SuperchainL1Info,
34    /// Default hardforks timestamps.
35    pub hardforks: HardForkConfiguration,
36    /// Optional addresses for the superchain-wide default protocol versions contract.
37    #[serde(alias = "protocolVersionsAddr")]
38    pub protocol_versions_addr: Option<Address>,
39    /// Optional address for the superchain-wide default superchain config contract.
40    #[serde(alias = "superchainConfigAddr")]
41    pub superchain_config_addr: Option<Address>,
42    /// The op contracts manager proxy address.
43    #[serde(alias = "OPContractsManagerProxyAddr")]
44    pub op_contracts_manager_proxy_addr: Option<Address>,
45}
46
47/// Superchain L1 anchor information
48#[derive(Debug, Clone, Default, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
49pub struct SuperchainL1Info {
50    /// L1 chain ID
51    #[serde(alias = "chainId")]
52    pub chain_id: u64,
53    /// L1 chain public RPC endpoint
54    #[serde(alias = "publicRPC")]
55    pub public_rpc: String,
56    /// L1 chain explorer RPC endpoint
57    pub explorer: String,
58}
59
60/// A list of Hydrated Superchain Configs.
61#[derive(Debug, Clone, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
62#[serde(rename_all = "camelCase")]
63pub struct Superchains {
64    /// A list of superchain configs.
65    pub superchains: Vec<Superchain>,
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    use alloc::{string::ToString, vec};
72
73    #[test]
74    fn test_superchain_serde() {
75        let raw: &str = r#"
76        {
77            "name": "Mainnet",
78            "config": {
79                "name": "Mainnet",
80                "l1": {
81                    "chainId": 10,
82                    "publicRPC": "https://mainnet.rpc",
83                    "explorer": "https://mainnet.explorer"
84                },
85                "hardforks": {
86                    "canyon_time": 1699981200,
87                    "delta_time": 1703203200,
88                    "ecotone_time": 1708534800,
89                    "fjord_time": 1716998400,
90                    "granite_time": 1723478400,
91                    "holocene_time": 1732633200
92                }
93            },
94            "chains": []
95        }
96        "#;
97
98        let superchain = Superchain {
99            name: "Mainnet".to_string(),
100            config: SuperchainConfig {
101                name: "Mainnet".to_string(),
102                l1: SuperchainL1Info {
103                    chain_id: 10,
104                    public_rpc: "https://mainnet.rpc".to_string(),
105                    explorer: "https://mainnet.explorer".to_string(),
106                },
107                hardforks: HardForkConfiguration {
108                    canyon_time: Some(1699981200),
109                    delta_time: Some(1703203200),
110                    ecotone_time: Some(1708534800),
111                    fjord_time: Some(1716998400),
112                    granite_time: Some(1723478400),
113                    holocene_time: Some(1732633200),
114                    isthmus_time: None,
115                    interop_time: None,
116                },
117                protocol_versions_addr: None,
118                superchain_config_addr: None,
119                op_contracts_manager_proxy_addr: None,
120            },
121            chains: vec![],
122        };
123
124        let deserialized: Superchain = serde_json::from_str(raw).unwrap();
125        assert_eq!(superchain, deserialized);
126    }
127}