1use ethers_core::types::{
6 BlockId,
7 H256,
8};
9use ethers_providers::{
10 Http,
11 Provider,
12};
13use eyre::Result;
14use serde::{
15 Deserialize,
16 Serialize,
17};
18
19use crate::errors::RollupNodeError;
20
21#[derive(Debug, Clone, Default)]
23pub struct RollupNode {
24 pub client: Option<Provider<Http>>,
26}
27
28impl TryFrom<String> for RollupNode {
29 type Error = RollupNodeError;
30
31 fn try_from(url: String) -> Result<Self, Self::Error> {
32 Self::new(url.as_ref()).map_err(|_| Self::Error::RollupNodeInvalidUrl(url))
33 }
34}
35
36impl RollupNode {
37 pub fn new(l2_url: &str) -> Result<Self> {
39 let client = Provider::<Http>::try_from(l2_url)?;
40 Ok(Self {
41 client: Some(client),
42 })
43 }
44
45 pub async fn output_at_block(&self, block_num: u64) -> Result<OutputResponse> {
47 let output = self
48 .client
49 .as_ref()
50 .unwrap()
51 .request("optimism_outputAtBlock", vec![block_num])
52 .await?;
53 Ok(output)
54 }
55
56 pub async fn sync_status(&self) -> Result<SyncStatus> {
61 let empty_params: Vec<String> = Vec::new();
62 let sync_status = self
63 .client
64 .as_ref()
65 .unwrap()
66 .request("optimism_syncStatus", empty_params)
67 .await?;
68 Ok(sync_status)
69 }
70
71 pub async fn rollup_config(&self) -> Result<serde_json::Value> {
73 let empty_params: Vec<String> = Vec::new();
74 let config = self
75 .client
76 .as_ref()
77 .unwrap()
78 .request("optimism_rollupConfig", empty_params)
79 .await?;
80 Ok(config)
81 }
82
83 pub async fn version(&self) -> Result<String> {
85 let empty_params: Vec<String> = Vec::new();
86 let version = self
87 .client
88 .as_ref()
89 .unwrap()
90 .request("optimism_version", empty_params)
91 .await?;
92 Ok(version)
93 }
94}
95
96#[derive(
98 Debug,
99 Clone,
100 Serialize,
101 Deserialize,
102 Default,
103 Copy,
104 PartialEq,
105 Eq,
106 PartialOrd,
107 Ord,
108 Hash,
109)]
110pub struct SyncStatus {
111 pub current_l1: u64,
113 pub current_l1_finalized: u64,
115 pub head_l1: u64,
117 pub safe_l1: u64,
119 pub finalized_l1: u64,
121 pub unsafe_l2: u64,
123 pub safe_l2: u64,
125 pub finalized_l2: u64,
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
131pub struct OutputResponse {
132 pub version: Vec<u8>,
134 pub output_root: Vec<u8>,
136 pub block_ref: L2BlockRef,
138 pub withdrawal_storage_root: H256,
140 pub state_root: H256,
142 pub sync_status: SyncStatus,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
148pub struct L2BlockRef {
149 pub hash: H256,
151 pub number: u64,
153 pub parent_hash: H256,
155 pub time: u64,
157 #[serde(rename = "l1origin")]
159 pub l1_origin: BlockId,
160 pub sequence_number: u64,
162}