op_contracts/
manager.rs

1use std::{
2    fs,
3    path::{Path, PathBuf},
4};
5
6use eyre::Result;
7use serde_json::{Map, Value};
8
9use ethers_core::types::Address;
10
11/// AddressManager
12///
13/// The address manger.
14#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
15pub struct AddressManager {
16    /// The path to the deployment directory.
17    pub deployment_dir: PathBuf,
18}
19
20impl AddressManager {
21    /// Creates a new address manager.
22    pub fn new(deployment_dir: PathBuf) -> Self {
23        Self { deployment_dir }
24    }
25
26    /// Returns the address of the given contract.
27    pub fn get_address(&self, contract: &str) -> Result<Address> {
28        let file_name = format!("{}.json", contract);
29        let path = self.deployment_dir.join(file_name);
30
31        if path.exists() {
32            let data = read_json(&path)?;
33            let address = data["address"].as_str().unwrap();
34
35            Ok(address.parse()?)
36        } else {
37            Err(eyre::eyre!("No address found for contract: {}", contract))
38        }
39    }
40
41    /// Returns a set of addresses and SDK addresses using the given deployment directory.
42    pub fn set_addresses(deployment_dir: &Path) -> Result<(Value, Value)> {
43        let mut addresses = Map::new();
44        let mut sdk_addresses = Map::new();
45
46        for entry in fs::read_dir(deployment_dir)? {
47            let entry = entry?;
48            let path = entry.path();
49
50            if path.is_file() && path.extension().unwrap_or_default() == "json" {
51                // We can safely unwrap because the file exists and it has a name
52                let file_name = path.file_stem().unwrap().to_string_lossy().to_string();
53                let data = read_json(&path)?;
54
55                if let Some(address) = data["address"].as_str() {
56                    addresses.insert(file_name, address.to_owned().into());
57                }
58            }
59        }
60
61        sdk_addresses.insert(
62            "AddressManager".to_owned(),
63            Address::zero().to_string().into(),
64        );
65        sdk_addresses.insert("BondManager".to_owned(), Address::zero().to_string().into());
66        sdk_addresses.insert(
67            "StateCommitmentChain".to_owned(),
68            Address::zero().to_string().into(),
69        );
70        sdk_addresses.insert(
71            "CanonicalTransactionChain".to_owned(),
72            Address::zero().to_string().into(),
73        );
74        sdk_addresses.insert(
75            "L1CrossDomainMessenger".to_owned(),
76            addresses
77                .get("Proxy__OVM_L1CrossDomainMessenger")
78                .expect("Failed to get L1CrossDomainMessenger address")
79                .clone(),
80        );
81        sdk_addresses.insert(
82            "L1StandardBridge".to_owned(),
83            addresses
84                .get("Proxy__OVM_L1StandardBridge")
85                .expect("Failed to get L1StandardBridge address")
86                .clone(),
87        );
88        sdk_addresses.insert(
89            "OptimismPortal".to_owned(),
90            addresses
91                .get("OptimismPortalProxy")
92                .expect("Failed to get OptimismPortal address")
93                .clone(),
94        );
95        sdk_addresses.insert(
96            "L2OutputOracle".to_owned(),
97            addresses
98                .get("L2OutputOracleProxy")
99                .expect("Failed to get L2OutputOracle address")
100                .clone(),
101        );
102
103        Ok((Value::Object(addresses), Value::Object(sdk_addresses)))
104    }
105}
106
107/// Read a JSON file and return a `serde_json::Value`.
108pub fn read_json(file_path: &Path) -> Result<Value> {
109    let file = std::fs::File::open(file_path)?;
110    let reader = std::io::BufReader::new(file);
111    let json_value: Value = serde_json::from_reader(reader)?;
112    Ok(json_value)
113}