use crate::{ database::{ database_description::off_chain::OffChain, Database, }, fuel_core_graphql_api::storage::coins::{ owner_coin_id_key, OwnedCoins, }, }; use fuel_core_chain_config::TableEntry; use fuel_core_storage::{ iter::{ IterDirection, IteratorOverTable, }, not_found, tables::Coins, Result as StorageResult, StorageAsRef, }; use fuel_core_txpool::types::TxId; use fuel_core_types::{ entities::coins::coin::CompressedCoin, fuel_tx::{ Address, UtxoId, }, }; use itertools::Itertools; impl Database { pub fn owned_coins_ids( &self, owner: &Address, start_coin: Option, direction: Option, ) -> impl Iterator> + '_ { let start_coin = start_coin.map(|b| owner_coin_id_key(owner, &b)); self.iter_all_filtered::( Some(*owner), start_coin.as_ref(), direction, ) // Safety: key is always 64 bytes .map(|res| { res.map(|(key, _)| { UtxoId::new( TxId::try_from(&key[32..64]).expect("The slice has size 32"), u16::from_be_bytes( key[64..].try_into().expect("The slice has size 2"), ) ) }) }) } } impl Database { pub fn coin(&self, utxo_id: &UtxoId) -> StorageResult { let coin = self .storage_as_ref::() .get(utxo_id)? .ok_or(not_found!(Coins))? .into_owned(); Ok(coin) } pub fn iter_coins( &self, ) -> impl Iterator>> + '_ { self.iter_all::(None) .map_ok(|(key, value)| TableEntry { key, value }) } }