use async_trait::async_trait; use common::errors::RpcError; use eyre::Result; use super::Rpc; use crate::types::*; pub struct NimbusRpc { rpc: String, } #[async_trait] impl Rpc for NimbusRpc { fn new(rpc: &str) -> Self { NimbusRpc { rpc: rpc.to_string(), } } async fn get_bootstrap(&self, block_root: &Vec) -> Result { let root_hex = hex::encode(block_root); let req = format!( "{}/eth/v1/beacon/light_client/bootstrap/0x{}", self.rpc, root_hex ); let res = reqwest::get(req) .await .map_err(|e| RpcError::new("bootstrap", e))? .json::() .await .map_err(|e| RpcError::new("bootstrap", e))?; Ok(res.data) } async fn get_updates(&self, period: u64) -> Result> { let req = format!( "{}/eth/v1/beacon/light_client/updates?start_period={}&count=1000", self.rpc, period ); let res = reqwest::get(req) .await .map_err(|e| RpcError::new("updates", e))? .json::() .await .map_err(|e| RpcError::new("updates", e))?; Ok(res.iter().map(|d| d.data.clone()).collect()) } async fn get_finality_update(&self) -> Result { let req = format!("{}/eth/v1/beacon/light_client/finality_update", self.rpc); let res = reqwest::get(req) .await .map_err(|e| RpcError::new("finality_update", e))? .json::() .await .map_err(|e| RpcError::new("finality_update", e))?; Ok(res.data) } async fn get_optimistic_update(&self) -> Result { let req = format!("{}/eth/v1/beacon/light_client/optimistic_update", self.rpc); let res = reqwest::get(req) .await .map_err(|e| RpcError::new("optimistic_update", e))? .json::() .await .map_err(|e| RpcError::new("optimistic_update", e))?; Ok(res.data) } async fn get_block(&self, slot: u64) -> Result { let req = format!("{}/eth/v2/beacon/blocks/{}", self.rpc, slot); let res = reqwest::get(req) .await .map_err(|e| RpcError::new("blocks", e))? .json::() .await .map_err(|e| RpcError::new("blocks", e))?; Ok(res.data.message) } } #[derive(serde::Deserialize, Debug)] struct BeaconBlockResponse { data: BeaconBlockData, } #[derive(serde::Deserialize, Debug)] struct BeaconBlockData { message: BeaconBlock, } type UpdateResponse = Vec; #[derive(serde::Deserialize, Debug)] struct UpdateData { data: Update, } #[derive(serde::Deserialize, Debug)] struct FinalityUpdateResponse { data: FinalityUpdate, } #[derive(serde::Deserialize, Debug)] struct OptimisticUpdateResponse { data: OptimisticUpdate, } #[derive(serde::Deserialize, Debug)] struct BootstrapResponse { data: Bootstrap, }