use std::{sync::Arc, ops::Deref, collections::HashSet}; use rand_core::{RngCore, OsRng}; use sp_core::Encode; use sp_blockchain::{Error as BlockchainError, HeaderMetadata, HeaderBackend}; use sp_consensus::BlockStatus; use sp_block_builder::BlockBuilder; use sp_api::ProvideRuntimeApi; use sc_client_api::BlockBackend; use serai_abi::{primitives::prelude::*, SubstrateBlock as Block}; use serai_runtime::SeraiApi; use jsonrpsee::RpcModule; use super::utils::block_hash; pub(crate) fn module< C: 'static + Send + Sync + HeaderMetadata + HeaderBackend + BlockBackend + ProvideRuntimeApi>, >( client: Arc, ) -> Result, Box> { let mut module = RpcModule::new(client); module.register_method("blockchain/latest_finalized_block_number", |_params, client, _ext| { client.info().finalized_number }); module.register_method("blockchain/is_finalized", |params, client, _ext| { let block_hash = block_hash(&**client, ¶ms)?; let finalized = client.info().finalized_number; let Ok(Some(number)) = client.number(block_hash) else { return Err(jsonrpsee::types::error::ErrorObjectOwned::owned( -2, "failed to fetch block's number", Option::<()>::None, )); }; let Ok(status) = client.block_status(block_hash) else { return Err(jsonrpsee::types::error::ErrorObjectOwned::owned( -3, "failed to fetch block's status", Option::<()>::None, )); }; Ok( matches!(status, BlockStatus::InChainWithState | BlockStatus::InChainPruned) && (number <= finalized), ) })?; module.register_method("blockchain/block", |params, client, _ext| { let block_hash = block_hash(&**client, ¶ms)?; let Ok(Some(block)) = client.block(block_hash) else { return Err(jsonrpsee::types::error::ErrorObjectOwned::owned( -2, "couldn't find requested block", Option::<()>::None, )); }; Ok(hex::encode(borsh::to_vec(&serai_abi::Block::from(block.block)).unwrap())) })?; module.register_method("blockchain/events", |params, client, _ext| { let block_hash = block_hash(&**client, ¶ms)?; let Ok(events) = client.runtime_api().events(block_hash) else { return Err(jsonrpsee::types::error::ErrorObjectOwned::owned( -2, "couldn't fetch the events for the requested block", Option::<()>::None, )); }; Ok(events.into_iter().map(hex::encode).collect::>()) })?; Ok(module) }