miden_client/store/
account.rs1use alloc::vec::Vec;
4use core::fmt::Display;
5
6use miden_protocol::account::{Account, AccountCode, AccountId, PartialAccount};
7use miden_protocol::address::Address;
8use miden_protocol::{Felt, Word};
9
10use crate::ClientError;
11
12#[derive(Debug)]
17pub enum AccountRecordData {
18 Full(Account),
19 Partial(PartialAccount),
20}
21
22impl AccountRecordData {
23 pub fn id(&self) -> AccountId {
24 match self {
25 AccountRecordData::Full(account) => account.id(),
26 AccountRecordData::Partial(partial_account) => partial_account.id(),
27 }
28 }
29
30 pub fn commitment(&self) -> Word {
31 match self {
32 AccountRecordData::Full(account) => account.commitment(),
33 AccountRecordData::Partial(partial_account) => partial_account.commitment(),
34 }
35 }
36
37 pub fn initial_commitment(&self) -> Word {
38 match self {
39 AccountRecordData::Full(account) => account.initial_commitment(),
40 AccountRecordData::Partial(partial_account) => partial_account.initial_commitment(),
41 }
42 }
43
44 pub fn nonce(&self) -> Felt {
45 match self {
46 AccountRecordData::Full(account) => account.nonce(),
47 AccountRecordData::Partial(partial_account) => partial_account.nonce(),
48 }
49 }
50
51 pub fn seed(&self) -> Option<Word> {
52 match self {
53 AccountRecordData::Full(account) => account.seed(),
54 AccountRecordData::Partial(partial_account) => partial_account.seed(),
55 }
56 }
57
58 pub fn is_new(&self) -> bool {
59 match self {
60 AccountRecordData::Full(account) => account.is_new(),
61 AccountRecordData::Partial(partial_account) => partial_account.is_new(),
62 }
63 }
64
65 pub fn has_public_state(&self) -> bool {
66 match self {
67 AccountRecordData::Full(account) => account.has_public_state(),
68 AccountRecordData::Partial(partial_account) => partial_account.has_public_state(),
69 }
70 }
71
72 pub fn code(&self) -> &AccountCode {
73 match self {
74 AccountRecordData::Full(account) => account.code(),
75 AccountRecordData::Partial(partial_account) => partial_account.code(),
76 }
77 }
78}
79
80#[derive(Debug)]
89pub struct AccountRecord {
90 account_data: AccountRecordData,
92 status: AccountStatus,
94 addresses: Vec<Address>,
96}
97
98impl AccountRecord {
99 pub fn new(
100 account_data: AccountRecordData,
101 status: AccountStatus,
102 addresses: Vec<Address>,
103 ) -> Self {
104 #[cfg(debug_assertions)]
106 {
107 let account_seed = match &account_data {
108 AccountRecordData::Full(acc) => acc.seed(),
109 AccountRecordData::Partial(acc) => acc.seed(),
110 };
111 debug_assert_eq!(account_seed, status.seed().copied(), "account seed mismatch");
112 }
113
114 Self { account_data, status, addresses }
115 }
116
117 pub fn id(&self) -> AccountId {
118 match &self.account_data {
119 AccountRecordData::Full(acc) => acc.id(),
120 AccountRecordData::Partial(acc) => acc.id(),
121 }
122 }
123
124 pub fn account_data(&self) -> &AccountRecordData {
125 &self.account_data
126 }
127
128 pub fn status(&self) -> &AccountStatus {
129 &self.status
130 }
131
132 pub fn is_locked(&self) -> bool {
133 self.status.is_locked()
134 }
135
136 pub fn seed(&self) -> Option<Word> {
137 match &self.account_data {
138 AccountRecordData::Full(acc) => acc.seed(),
139 AccountRecordData::Partial(acc) => acc.seed(),
140 }
141 }
142
143 pub fn nonce(&self) -> Felt {
144 match &self.account_data {
145 AccountRecordData::Full(acc) => acc.nonce(),
146 AccountRecordData::Partial(acc) => acc.nonce(),
147 }
148 }
149
150 pub fn commitment(&self) -> Word {
151 match &self.account_data {
152 AccountRecordData::Full(acc) => acc.commitment(),
153 AccountRecordData::Partial(acc) => acc.commitment(),
154 }
155 }
156
157 pub fn addresses(&self) -> &Vec<Address> {
158 &self.addresses
159 }
160
161 pub fn code(&self) -> AccountCode {
162 match &self.account_data {
163 AccountRecordData::Full(acc) => acc.code().clone(),
164 AccountRecordData::Partial(acc) => acc.code().clone(),
165 }
166 }
167}
168
169impl TryFrom<AccountRecord> for Account {
170 type Error = ClientError;
171
172 fn try_from(value: AccountRecord) -> Result<Self, Self::Error> {
173 match value.account_data {
174 AccountRecordData::Full(acc) => Ok(acc),
175 AccountRecordData::Partial(acc) => Err(ClientError::AccountRecordNotFull(acc.id())),
176 }
177 }
178}
179
180impl TryFrom<AccountRecord> for PartialAccount {
181 type Error = ClientError;
182
183 fn try_from(value: AccountRecord) -> Result<Self, Self::Error> {
184 match value.account_data {
185 AccountRecordData::Partial(acc) => Ok(acc),
186 AccountRecordData::Full(acc) => Err(ClientError::AccountRecordNotPartial(acc.id())),
187 }
188 }
189}
190
191#[derive(Debug)]
198pub enum AccountStatus {
199 New { seed: Word },
202 Tracked,
204 Locked { seed: Option<Word> },
209}
210
211impl AccountStatus {
212 pub fn is_locked(&self) -> bool {
213 matches!(self, AccountStatus::Locked { .. })
214 }
215
216 pub fn seed(&self) -> Option<&Word> {
217 match self {
218 AccountStatus::New { seed } => Some(seed),
219 AccountStatus::Locked { seed } => seed.as_ref(),
220 AccountStatus::Tracked => None,
221 }
222 }
223}
224
225impl Display for AccountStatus {
226 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
227 match self {
228 AccountStatus::New { .. } => write!(f, "New"),
229 AccountStatus::Tracked => write!(f, "Tracked"),
230 AccountStatus::Locked { .. } => write!(f, "Locked"),
231 }
232 }
233}
234
235pub struct AccountUpdates {
240 updated_public_accounts: Vec<Account>,
242 mismatched_private_accounts: Vec<(AccountId, Word)>,
245}
246
247impl AccountUpdates {
248 pub fn new(
250 updated_public_accounts: Vec<Account>,
251 mismatched_private_accounts: Vec<(AccountId, Word)>,
252 ) -> Self {
253 Self {
254 updated_public_accounts,
255 mismatched_private_accounts,
256 }
257 }
258
259 pub fn updated_public_accounts(&self) -> &[Account] {
261 &self.updated_public_accounts
262 }
263
264 pub fn mismatched_private_accounts(&self) -> &[(AccountId, Word)] {
266 &self.mismatched_private_accounts
267 }
268}