bankai_sdk/fetch/evm/
beacon.rs

1use alloy_primitives::hex::ToHexExt;
2use bankai_types::api::proofs::MmrProofRequestDto;
3use bankai_types::verify::evm::beacon::BeaconHeader;
4use bankai_types::{api::proofs::HashingFunctionDto, fetch::evm::beacon::BeaconHeaderProof};
5use tree_hash::TreeHash;
6
7use crate::errors::SdkResult;
8use crate::fetch::{
9    bankai,
10    clients::{bankai_api::ApiClient, beacon_client::BeaconFetcher},
11};
12
13/// Fetcher for EVM beacon chain data with MMR proofs
14///
15/// This fetcher retrieves beacon chain (consensus layer) headers along with MMR proofs
16/// needed to decommit headers from STWO proofs.
17///
18/// The typical flow is:
19/// 1. Fetch a beacon header with its MMR proof
20/// 2. Use the MMR proof to decommit and verify the header from the STWO block proof
21/// 3. The verified beacon header can be used to verify consensus layer data
22pub struct BeaconChainFetcher {
23    pub api_client: ApiClient,
24    pub beacon_client: BeaconFetcher,
25    pub network_id: u64,
26}
27
28impl BeaconChainFetcher {
29    /// Creates a new beacon chain fetcher
30    ///
31    /// # Arguments
32    ///
33    /// * `api_client` - The Bankai API client for fetching MMR proofs
34    /// * `beacon_rpc` - The beacon chain API endpoint URL
35    /// * `network_id` - The network ID for this chain
36    pub fn new(api_client: ApiClient, beacon_rpc: String, network_id: u64) -> Self {
37        Self {
38            api_client,
39            beacon_client: BeaconFetcher::new(beacon_rpc),
40            network_id,
41        }
42    }
43
44    /// Fetches a beacon chain header with its MMR proof
45    ///
46    /// This retrieves the beacon chain header from the API and generates an MMR proof
47    /// that can be used to decommit this header from the STWO block proof's beacon MMR.
48    ///
49    /// # Arguments
50    ///
51    /// * `slot` - The beacon chain slot number to fetch
52    /// * `hashing_function` - The hash function to use for the MMR proof
53    /// * `bankai_block_number` - The Bankai block number containing the MMR
54    ///
55    /// # Returns
56    ///
57    /// A `BeaconHeaderProof` containing the header and MMR proof for decommitment
58    pub async fn header(
59        &self,
60        slot: u64,
61        hashing_function: HashingFunctionDto,
62        bankai_block_number: u64,
63    ) -> SdkResult<BeaconHeaderProof> {
64        let header_response = self.beacon_client.fetch_header(slot).await?;
65        let header: BeaconHeader = header_response.into();
66        let header_root = header.tree_hash_root();
67        let header_root_string = format!("0x{}", header_root.encode_hex());
68        let mmr_proof = bankai::mmr::fetch_mmr_proof(
69            &self.api_client,
70            &MmrProofRequestDto {
71                network_id: self.network_id,
72                block_number: bankai_block_number,
73                hashing_function,
74                header_hash: header_root_string,
75            },
76        )
77        .await?;
78        Ok(BeaconHeaderProof {
79            header,
80            mmr_proof: mmr_proof.into(),
81        })
82    }
83
84    /// Fetches a beacon header without an MMR proof
85    ///
86    /// Used internally by the batch builder. For verification purposes, use `header()` instead
87    /// to get the header with its MMR proof.
88    pub async fn header_only(&self, slot: u64) -> SdkResult<BeaconHeader> {
89        let header_response = self.beacon_client.fetch_header(slot).await?;
90        let header: BeaconHeader = header_response.into();
91        Ok(header)
92    }
93
94    /// Returns the network ID for this fetcher
95    pub fn network_id(&self) -> u64 {
96        self.network_id
97    }
98}