1use super::Chain;
4use alloc::{string::String, vec::Vec};
5use alloy_primitives::{
6 map::{DefaultHashBuilder, HashMap},
7 Address,
8};
9use op_alloy_genesis::{ChainConfig, HardForkConfiguration, RollupConfig};
10
11#[derive(Debug, Clone, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
13pub struct Superchain {
14 pub name: String,
16 pub config: SuperchainConfig,
18 pub chains: Vec<ChainConfig>,
20}
21
22#[derive(Debug, Clone, Default, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
24#[serde(rename_all = "PascalCase")]
25pub struct SuperchainConfig {
26 pub name: String,
28 pub l1: SuperchainL1Info,
30 pub protocol_versions_addr: Option<Address>,
32 pub superchain_config_addr: Option<Address>,
34 #[serde(flatten)]
36 pub hardfork_defaults: HardForkConfiguration,
37}
38
39#[derive(Debug, Clone, Default, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
41#[serde(rename_all = "PascalCase")]
42pub struct SuperchainL1Info {
43 #[serde(rename = "ChainID")]
45 pub chain_id: u64,
46 #[serde(rename = "PublicRPC")]
48 pub public_rpc: String,
49 pub explorer: String,
51}
52
53#[derive(Debug, Clone, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
55#[serde(rename_all = "camelCase")]
56pub struct Superchains {
57 pub superchains: Vec<Superchain>,
59}
60
61#[derive(Debug, Clone, Default, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
63#[serde(rename_all = "camelCase")]
64pub struct Registry {
65 pub chains: Vec<Chain>,
67 pub op_chains: HashMap<u64, ChainConfig, DefaultHashBuilder>,
69 pub rollup_configs: HashMap<u64, RollupConfig, DefaultHashBuilder>,
71}
72
73impl Registry {
74 pub fn read_chain_list() -> Vec<Chain> {
76 let chain_list = include_str!("../etc/chainList.json");
77 serde_json::from_str(chain_list).expect("Failed to read chain list")
78 }
79
80 pub fn read_superchain_configs() -> Superchains {
82 let superchain_configs = include_str!("../etc/configs.json");
83 serde_json::from_str(superchain_configs).expect("Failed to read superchain configs")
84 }
85
86 pub fn from_chain_list() -> Self {
88 let chains = Self::read_chain_list();
89 let superchains = Self::read_superchain_configs();
90 let mut op_chains = HashMap::default();
91 let mut rollup_configs = HashMap::default();
92
93 for superchain in superchains.superchains {
94 for mut chain_config in superchain.chains {
95 chain_config.l1_chain_id = superchain.config.l1.chain_id;
96 if let Some(a) = &mut chain_config.addresses {
97 a.zero_proof_addresses();
98 }
99 let mut rollup = chain_config.load_op_stack_rollup_config();
100 rollup.protocol_versions_address = superchain
101 .config
102 .protocol_versions_addr
103 .expect("Missing protocol versions address");
104 rollup.superchain_config_address = superchain.config.superchain_config_addr;
105 rollup_configs.insert(chain_config.chain_id, rollup);
106 op_chains.insert(chain_config.chain_id, chain_config);
107 }
108 }
109
110 Self { chains, op_chains, rollup_configs }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 use alloy_primitives::address;
118 use op_alloy_genesis::{AddressList, SuperchainLevel, OP_MAINNET_BASE_FEE_PARAMS};
119
120 #[test]
121 fn test_read_chain_configs() {
122 let superchains = Registry::from_chain_list();
123 assert!(superchains.chains.len() > 1);
124 let base_config = ChainConfig {
125 name: String::from("Base"),
126 chain_id: 8453,
127 l1_chain_id: 1,
128 public_rpc: String::from("https://mainnet.base.org"),
129 sequencer_rpc: String::from("https://mainnet-sequencer.base.org"),
130 explorer: String::from("https://explorer.base.org"),
131 superchain_level: SuperchainLevel::Frontier,
132 standard_chain_candidate: true,
133 superchain_time: Some(0),
134 batch_inbox_addr: address!("ff00000000000000000000000000000000008453"),
135 superchain: String::from("mainnet"),
136 chain: String::new(),
137 hardfork_configuration: crate::test_utils::BASE_MAINNET_CONFIG.hardfork_config(),
138 block_time: 2,
139 seq_window_size: 3600,
140 max_sequencer_drift: 600,
141 data_availability_type: "eth-da".to_string(),
142 optimism: Some(OP_MAINNET_BASE_FEE_PARAMS),
143 alt_da: None,
144 genesis: crate::test_utils::BASE_MAINNET_CONFIG.genesis,
145 addresses: Some(AddressList {
146 address_manager: address!("8EfB6B5c4767B09Dc9AA6Af4eAA89F749522BaE2"),
147 l1_cross_domain_messenger_proxy: address!(
148 "866E82a600A1414e583f7F13623F1aC5d58b0Afa"
149 ),
150 l1_erc721_bridge_proxy: address!("608d94945A64503E642E6370Ec598e519a2C1E53"),
151 l1_standard_bridge_proxy: address!("3154Cf16ccdb4C6d922629664174b904d80F2C35"),
152 l2_output_oracle_proxy: Some(address!("56315b90c40730925ec5485cf004d835058518A0")),
153 optimism_mintable_erc20_factory_proxy: address!(
154 "05cc379EBD9B30BbA19C6fA282AB29218EC61D84"
155 ),
156 optimism_portal_proxy: address!("49048044D57e1C92A77f79988d21Fa8fAF74E97e"),
157 system_config_proxy: address!("73a79Fab69143498Ed3712e519A88a918e1f4072"),
158 system_config_owner: address!("14536667Cd30e52C0b458BaACcB9faDA7046E056"),
159 proxy_admin: address!("0475cBCAebd9CE8AfA5025828d5b98DFb67E059E"),
160 proxy_admin_owner: address!("7bB41C3008B3f03FE483B28b8DB90e19Cf07595c"),
161 challenger: Some(address!("6F8C5bA3F59ea3E76300E3BEcDC231D656017824")),
162 guardian: address!("09f7150d8c019bef34450d6920f6b3608cefdaf2"),
163 anchor_state_registry_proxy: Some(address!(
164 "db9091e48b1c42992a1213e6916184f9ebdbfedf"
165 )),
166 delayed_weth_proxy: Some(address!("a2f2ac6f5af72e494a227d79db20473cf7a1ffe8")),
167 dispute_game_factory_proxy: Some(address!(
168 "43edb88c4b80fdd2adff2412a7bebf9df42cb40e"
169 )),
170 fault_dispute_game: Some(address!("cd3c0194db74c23807d4b90a5181e1b28cf7007c")),
171 mips: Some(address!("16e83ce5ce29bf90ad9da06d2fe6a15d5f344ce4")),
172 permissioned_dispute_game: Some(address!(
173 "19009debf8954b610f207d5925eede827805986e"
174 )),
175 preimage_oracle: Some(address!("9c065e11870b891d214bc2da7ef1f9ddfa1be277")),
176 }),
177 gas_paying_token: None,
178 };
179 assert_eq!(*superchains.op_chains.get(&8453).unwrap(), base_config);
180 }
181
182 #[test]
183 fn test_read_rollup_configs() {
184 let superchains = Registry::from_chain_list();
185 assert_eq!(
186 *superchains.rollup_configs.get(&10).unwrap(),
187 crate::test_utils::OP_MAINNET_CONFIG
188 );
189 }
190}