use alloc::sync::Arc;
use alloc::vec::Vec;
use miden_protocol::account::{
AccountHeader,
AccountId,
StorageMapKey,
StorageMapWitness,
StorageSlotName,
};
use miden_protocol::address::Address;
use miden_protocol::asset::{Asset, AssetVaultKey};
use miden_protocol::{Felt, Word};
use crate::errors::ClientError;
use crate::store::{AccountStatus, Store};
pub struct AccountReader {
store: Arc<dyn Store>,
account_id: AccountId,
}
impl AccountReader {
pub fn new(store: Arc<dyn Store>, account_id: AccountId) -> Self {
Self { store, account_id }
}
pub fn account_id(&self) -> AccountId {
self.account_id
}
pub async fn nonce(&self) -> Result<Felt, ClientError> {
let (header, _) = self.header().await?;
Ok(header.nonce())
}
pub async fn commitment(&self) -> Result<Word, ClientError> {
let (header, _) = self.header().await?;
Ok(header.to_commitment())
}
pub async fn storage_commitment(&self) -> Result<Word, ClientError> {
let (header, _) = self.header().await?;
Ok(header.storage_commitment())
}
pub async fn vault_root(&self) -> Result<Word, ClientError> {
let (header, _) = self.header().await?;
Ok(header.vault_root())
}
pub async fn code_commitment(&self) -> Result<Word, ClientError> {
let (header, _) = self.header().await?;
Ok(header.code_commitment())
}
pub async fn status(&self) -> Result<AccountStatus, ClientError> {
let (_, status) = self.header().await?;
Ok(status)
}
pub async fn header(&self) -> Result<(AccountHeader, AccountStatus), ClientError> {
self.store
.get_account_header(self.account_id)
.await?
.ok_or(ClientError::AccountDataNotFound(self.account_id))
}
pub async fn addresses(&self) -> Result<Vec<Address>, ClientError> {
self.store
.get_addresses_by_account_id(self.account_id)
.await
.map_err(ClientError::StoreError)
}
pub async fn get_balance(&self, faucet_id: AccountId) -> Result<u64, ClientError> {
if let Some(vault_key) = AssetVaultKey::new_fungible(faucet_id)
&& let Some((Asset::Fungible(fungible_asset), _)) =
self.store.get_account_asset(self.account_id, vault_key).await?
{
return Ok(fungible_asset.amount());
}
Ok(0)
}
pub async fn get_storage_item(
&self,
slot_name: impl Into<StorageSlotName>,
) -> Result<Word, ClientError> {
self.store
.get_account_storage_item(self.account_id, slot_name.into())
.await
.map_err(ClientError::StoreError)
}
pub async fn get_storage_map_item(
&self,
slot_name: impl Into<StorageSlotName>,
key: StorageMapKey,
) -> Result<Word, ClientError> {
let (value, _witness) =
self.store.get_account_map_item(self.account_id, slot_name.into(), key).await?;
Ok(value)
}
pub async fn get_storage_map_witness(
&self,
slot_name: impl Into<StorageSlotName>,
key: StorageMapKey,
) -> Result<(Word, StorageMapWitness), ClientError> {
self.store
.get_account_map_item(self.account_id, slot_name.into(), key)
.await
.map_err(ClientError::StoreError)
}
}