use crate::fuel_core_graphql_api::ports::{ OffChainDatabase, OnChainDatabase, }; use fuel_core_storage::{ iter::{ BoxedIter, IterDirection, }, not_found, tables::{ ContractsAssets, ContractsRawCode, }, Result as StorageResult, StorageAsRef, }; use fuel_core_types::{ fuel_types::{ AssetId, ContractId, }, fuel_vm::Salt, services::graphql_api::ContractBalance, }; pub trait ContractQueryData: Send + Sync { fn contract_id(&self, id: ContractId) -> StorageResult; fn contract_bytecode(&self, id: ContractId) -> StorageResult>; fn contract_salt(&self, id: ContractId) -> StorageResult; fn contract_balance( &self, contract_id: ContractId, asset_id: AssetId, ) -> StorageResult; fn contract_balances( &self, contract_id: ContractId, start_asset: Option, direction: IterDirection, ) -> BoxedIter>; } impl ContractQueryData for D { fn contract_id(&self, id: ContractId) -> StorageResult { let contract_exists = self.storage::().contains_key(&id)?; if contract_exists { Ok(id) } else { Err(not_found!(ContractsRawCode)) } } fn contract_bytecode(&self, id: ContractId) -> StorageResult> { let contract = self .storage::() .get(&id)? .ok_or(not_found!(ContractsRawCode))? .into_owned(); Ok(contract.into()) } fn contract_salt(&self, id: ContractId) -> StorageResult { self.contract_salt(&id) } fn contract_balance( &self, contract_id: ContractId, asset_id: AssetId, ) -> StorageResult { let amount = self .storage::() .get(&(&contract_id, &asset_id).into())? .ok_or(not_found!(ContractsAssets))? .into_owned(); Ok(ContractBalance { owner: contract_id, amount, asset_id, }) } fn contract_balances( &self, contract_id: ContractId, start_asset: Option, direction: IterDirection, ) -> BoxedIter> { self.contract_balances(contract_id, start_asset, direction) } }