use alloc::vec::Vec;
use core::fmt::Display;
use miden_protocol::account::{Account, AccountId, PartialAccount};
use miden_protocol::{Felt, Word};
use crate::ClientError;
use crate::sync::PublicAccountUpdate;
#[derive(Debug)]
pub enum AccountRecordData {
Full(Account),
Partial(PartialAccount),
}
impl AccountRecordData {
pub fn nonce(&self) -> Felt {
match self {
AccountRecordData::Full(account) => account.nonce(),
AccountRecordData::Partial(partial_account) => partial_account.nonce(),
}
}
}
#[derive(Debug)]
pub struct AccountRecord {
account_data: AccountRecordData,
status: AccountStatus,
}
impl AccountRecord {
pub fn new(account_data: AccountRecordData, status: AccountStatus) -> Self {
#[cfg(debug_assertions)]
{
let account_seed = match &account_data {
AccountRecordData::Full(acc) => acc.seed(),
AccountRecordData::Partial(acc) => acc.seed(),
};
debug_assert_eq!(account_seed, status.seed().copied(), "account seed mismatch");
}
Self { account_data, status }
}
pub fn is_locked(&self) -> bool {
self.status.is_locked()
}
pub fn nonce(&self) -> Felt {
self.account_data.nonce()
}
}
impl TryFrom<AccountRecord> for Account {
type Error = ClientError;
fn try_from(value: AccountRecord) -> Result<Self, Self::Error> {
match value.account_data {
AccountRecordData::Full(acc) => Ok(acc),
AccountRecordData::Partial(acc) => Err(ClientError::AccountRecordNotFull(acc.id())),
}
}
}
impl TryFrom<AccountRecord> for PartialAccount {
type Error = ClientError;
fn try_from(value: AccountRecord) -> Result<Self, Self::Error> {
match value.account_data {
AccountRecordData::Partial(acc) => Ok(acc),
AccountRecordData::Full(acc) => Err(ClientError::AccountRecordNotPartial(acc.id())),
}
}
}
#[derive(Debug, Clone)]
pub enum AccountStatus {
New { seed: Word },
Tracked,
Locked { seed: Option<Word> },
}
impl AccountStatus {
pub fn is_new(&self) -> bool {
matches!(self, AccountStatus::New { .. })
}
pub fn is_locked(&self) -> bool {
matches!(self, AccountStatus::Locked { .. })
}
pub fn seed(&self) -> Option<&Word> {
match self {
AccountStatus::New { seed } => Some(seed),
AccountStatus::Locked { seed } => seed.as_ref(),
AccountStatus::Tracked => None,
}
}
}
impl Display for AccountStatus {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
match self {
AccountStatus::New { .. } => write!(f, "New"),
AccountStatus::Tracked => write!(f, "Tracked"),
AccountStatus::Locked { .. } => write!(f, "Locked"),
}
}
}
pub struct AccountUpdates {
updated_public_accounts: Vec<PublicAccountUpdate>,
mismatched_private_accounts: Vec<(AccountId, Word)>,
}
impl AccountUpdates {
pub fn new(
updated_public_accounts: Vec<PublicAccountUpdate>,
mismatched_private_accounts: Vec<(AccountId, Word)>,
) -> Self {
Self {
updated_public_accounts,
mismatched_private_accounts,
}
}
pub fn updated_public_accounts(&self) -> &[PublicAccountUpdate] {
&self.updated_public_accounts
}
pub fn mismatched_private_accounts(&self) -> &[(AccountId, Word)] {
&self.mismatched_private_accounts
}
}