use std::collections::HashMap; use std::fmt::{Debug, Formatter}; use std::num::NonZeroU64; use std::ops::RangeInclusive; use async_trait::async_trait; use fuels::prelude::{Bech32ContractId, WalletUnlocked}; use hyperlane_core::Indexed; use tracing::instrument; use hyperlane_core::{ utils::bytes_to_hex, ChainCommunicationError, ChainResult, ContractLocator, HyperlaneAbi, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Indexer, LogMeta, Mailbox, TxCostEstimate, TxOutcome, H256, U256, }; use crate::{ contracts::mailbox::Mailbox as FuelMailboxInner, conversions::*, make_provider, ConnectionConf, }; /// A reference to a Mailbox contract on some Fuel chain pub struct FuelMailbox { contract: FuelMailboxInner, domain: HyperlaneDomain, } impl FuelMailbox { /// Create a new fuel mailbox pub fn new( conf: &ConnectionConf, locator: ContractLocator, mut wallet: WalletUnlocked, ) -> ChainResult { let provider = make_provider(conf)?; wallet.set_provider(provider); let address = Bech32ContractId::from_h256(&locator.address); Ok(FuelMailbox { contract: FuelMailboxInner::new(address, wallet), domain: locator.domain.clone(), }) } } impl HyperlaneContract for FuelMailbox { fn address(&self) -> H256 { self.contract.contract_id().into_h256() } } impl HyperlaneChain for FuelMailbox { fn domain(&self) -> &HyperlaneDomain { &self.domain } fn provider(&self) -> Box { todo!() } } impl Debug for FuelMailbox { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", self as &dyn HyperlaneContract) } } #[async_trait] impl Mailbox for FuelMailbox { #[instrument(level = "debug", err, ret, skip(self))] async fn count(&self, lag: Option) -> ChainResult { assert!( lag.is_none(), "Fuel does not support querying point-in-time" ); self.contract .methods() .count() .simulate() .await .map(|r| r.value) .map_err(ChainCommunicationError::from_other) } #[instrument(level = "debug", err, ret, skip(self))] async fn delivered(&self, id: H256) -> ChainResult { todo!() } #[instrument(err, ret, skip(self))] async fn default_ism(&self) -> ChainResult { todo!() } #[instrument(err, ret, skip(self))] async fn recipient_ism(&self, recipient: H256) -> ChainResult { todo!() } #[instrument(err, ret, skip(self))] async fn process( &self, message: &HyperlaneMessage, metadata: &[u8], tx_gas_limit: Option, ) -> ChainResult { todo!() } #[instrument(err, ret, skip(self), fields(msg=%message, metadata=%bytes_to_hex(metadata)))] async fn process_estimate_costs( &self, message: &HyperlaneMessage, metadata: &[u8], ) -> ChainResult { todo!() } fn process_calldata(&self, message: &HyperlaneMessage, metadata: &[u8]) -> Vec { todo!() } } /// Struct that retrieves event data for a Fuel Mailbox contract #[derive(Debug)] pub struct FuelMailboxIndexer {} #[async_trait] impl Indexer for FuelMailboxIndexer { async fn fetch_logs_in_range( &self, range: RangeInclusive, ) -> ChainResult, LogMeta)>> { todo!() } async fn get_finalized_block_number(&self) -> ChainResult { todo!() } } #[async_trait] impl Indexer for FuelMailboxIndexer { async fn fetch_logs_in_range( &self, range: RangeInclusive, ) -> ChainResult, LogMeta)>> { todo!() } async fn get_finalized_block_number(&self) -> ChainResult { todo!() } } struct FuelMailboxAbi; impl HyperlaneAbi for FuelMailboxAbi { const SELECTOR_SIZE_BYTES: usize = 8; fn fn_map() -> HashMap, &'static str> { // Can't support this without Fuels exporting it in the generated code todo!() } }