use super::scalars::{ U32, U64, }; use crate::{ fuel_core_graphql_api::database::ReadView, graphql_api::api_service::GasPriceProvider, query::{ BlockQueryData, SimpleTransactionData, }, }; use async_graphql::{ Context, Object, }; use fuel_core_types::{ blockchain::block::Block, fuel_tx::{ field::MintGasPrice, Transaction, }, }; pub struct LatestGasPrice { pub gas_price: U64, pub block_height: U32, } #[Object] impl LatestGasPrice { async fn gas_price(&self) -> U64 { self.gas_price } async fn block_height(&self) -> U32 { self.block_height } } #[derive(Default)] pub struct LatestGasPriceQuery {} #[Object] impl LatestGasPriceQuery { async fn latest_gas_price( &self, ctx: &Context<'_>, ) -> async_graphql::Result { let query: &ReadView = ctx.data_unchecked(); let latest_block: Block<_> = query.latest_block()?; let block_height: u32 = (*latest_block.header().height()).into(); let mut gas_price: U64 = 0.into(); if let Some(tx_id) = latest_block.transactions().last() { if let Transaction::Mint(mint_tx) = query.transaction(tx_id)? { gas_price = (*mint_tx.gas_price()).into(); } } Ok(LatestGasPrice { gas_price, block_height: block_height.into(), }) } } pub struct EstimateGasPrice { pub gas_price: U64, } #[Object] impl EstimateGasPrice { async fn gas_price(&self) -> U64 { self.gas_price } } #[derive(Default)] pub struct EstimateGasPriceQuery {} #[Object] impl EstimateGasPriceQuery { async fn estimate_gas_price( &self, ctx: &Context<'_>, #[graphql( desc = "Number of blocks into the future to estimate the gas price for" )] block_horizon: Option, ) -> async_graphql::Result { let query: &ReadView = ctx.data_unchecked(); let latest_block_height: u32 = query.latest_block_height()?.into(); let target_block = block_horizon .and_then(|h| h.0.checked_add(latest_block_height)) .ok_or(async_graphql::Error::new(format!( "Invalid block horizon. Overflows latest block :{latest_block_height:?}" )))?; let gas_price_provider = ctx.data_unchecked::(); let gas_price = gas_price_provider .worst_case_gas_price(target_block.into()) .await; Ok(EstimateGasPrice { gas_price: gas_price.into(), }) } }