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}