miden_client/rpc/domain/
account_vault.rs1use alloc::string::ToString;
2use alloc::vec::Vec;
3
4use miden_protocol::Word;
5use miden_protocol::asset::{Asset, AssetVaultKey};
6use miden_protocol::block::BlockNumber;
7
8use crate::rpc::domain::MissingFieldHelper;
9use crate::rpc::{RpcConversionError, RpcError, generated as proto};
10
11impl TryFrom<proto::primitives::Asset> for Asset {
15 type Error = RpcConversionError;
16
17 fn try_from(value: proto::primitives::Asset) -> Result<Self, Self::Error> {
18 let key_word: Word = value
19 .key
20 .ok_or(proto::primitives::Asset::missing_field(stringify!(key)))?
21 .try_into()?;
22 let value_word: Word = value
23 .value
24 .ok_or(proto::primitives::Asset::missing_field(stringify!(value)))?
25 .try_into()?;
26 Asset::from_key_value_words(key_word, value_word)
27 .map_err(|e| RpcConversionError::InvalidField(e.to_string()))
28 }
29}
30
31pub struct AccountVaultInfo {
38 pub chain_tip: BlockNumber,
40 pub block_number: BlockNumber,
42 pub updates: Vec<AccountVaultUpdate>,
44}
45
46impl TryFrom<proto::rpc::SyncAccountVaultResponse> for AccountVaultInfo {
50 type Error = RpcError;
51
52 fn try_from(value: proto::rpc::SyncAccountVaultResponse) -> Result<Self, Self::Error> {
53 let pagination_info =
54 value
55 .pagination_info
56 .ok_or(proto::rpc::SyncAccountVaultResponse::missing_field(stringify!(
57 pagination_info
58 )))?;
59 let chain_tip = pagination_info.chain_tip;
60 let block_number = pagination_info.block_num;
61
62 let updates = value
63 .updates
64 .iter()
65 .map(|update| (*update).try_into())
66 .collect::<Result<Vec<_>, _>>()?;
67
68 Ok(Self {
69 chain_tip: chain_tip.into(),
70 block_number: block_number.into(),
71 updates,
72 })
73 }
74}
75
76pub struct AccountVaultUpdate {
81 pub block_num: BlockNumber,
83 pub asset: Option<Asset>,
85 pub vault_key: AssetVaultKey,
87}
88
89impl TryFrom<proto::rpc::AccountVaultUpdate> for AccountVaultUpdate {
93 type Error = RpcError;
94
95 fn try_from(value: proto::rpc::AccountVaultUpdate) -> Result<Self, Self::Error> {
96 let block_num = value.block_num;
97
98 let vault_key_inner: Word = value
99 .vault_key
100 .ok_or(proto::rpc::SyncAccountVaultResponse::missing_field(stringify!(vault_key)))?
101 .try_into()?;
102 let vault_key = AssetVaultKey::try_from(vault_key_inner)
103 .map_err(|e| RpcError::InvalidResponse(e.to_string()))?;
104
105 let asset = value.asset.map(Asset::try_from).transpose()?;
106
107 if let Some(ref asset) = asset
108 && asset.vault_key() != vault_key
109 {
110 return Err(RpcError::InvalidResponse(
111 "account vault update returned mismatched asset key".to_string(),
112 ));
113 }
114
115 Ok(Self {
116 block_num: block_num.into(),
117 asset,
118 vault_key,
119 })
120 }
121}