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#[derive(Debug, Clone, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
18pub struct Superchain {
19 pub name: String,
21 pub config: SuperchainConfig,
23 pub chains: Vec<ChainConfig>,
25}
26
27#[derive(Debug, Clone, Default, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
29pub struct SuperchainConfig {
30 pub name: String,
32 pub l1: SuperchainL1Info,
34 pub hardforks: HardForkConfiguration,
36 #[serde(alias = "protocolVersionsAddr")]
38 pub protocol_versions_addr: Option<Address>,
39 #[serde(alias = "superchainConfigAddr")]
41 pub superchain_config_addr: Option<Address>,
42 #[serde(alias = "OPContractsManagerProxyAddr")]
44 pub op_contracts_manager_proxy_addr: Option<Address>,
45}
46
47#[derive(Debug, Clone, Default, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
49pub struct SuperchainL1Info {
50 #[serde(alias = "chainId")]
52 pub chain_id: u64,
53 #[serde(alias = "publicRPC")]
55 pub public_rpc: String,
56 pub explorer: String,
58}
59
60#[derive(Debug, Clone, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
62#[serde(rename_all = "camelCase")]
63pub struct Superchains {
64 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}