miden_protocol/asset/vault/
vault_key.rs1use core::fmt;
2
3use miden_crypto::merkle::smt::LeafIndex;
4use miden_processor::SMT_DEPTH;
5
6use crate::Word;
7use crate::account::AccountType::FungibleFaucet;
8use crate::account::{AccountId, AccountIdPrefix};
9use crate::asset::{Asset, FungibleAsset, NonFungibleAsset};
10
11#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord)]
33pub struct AssetVaultKey(Word);
34
35impl AssetVaultKey {
36 pub fn new_unchecked(value: Word) -> Self {
43 Self(value)
44 }
45
46 pub fn faucet_id_prefix(&self) -> AccountIdPrefix {
48 if self.is_fungible() {
49 AccountIdPrefix::new_unchecked(self.0[3])
50 } else {
51 AccountIdPrefix::new_unchecked(self.0[0])
52 }
53 }
54
55 pub fn faucet_id(&self) -> Option<AccountId> {
57 if self.is_fungible() {
58 Some(AccountId::new_unchecked([self.0[3], self.0[2]]))
59 } else {
60 None
61 }
62 }
63
64 pub fn to_leaf_index(&self) -> LeafIndex<SMT_DEPTH> {
66 LeafIndex::<SMT_DEPTH>::from(self.0)
67 }
68
69 pub fn from_account_id(faucet_id: AccountId) -> Option<Self> {
74 match faucet_id.account_type() {
75 FungibleFaucet => {
76 let mut key = Word::empty();
77 key[2] = faucet_id.suffix();
78 key[3] = faucet_id.prefix().as_felt();
79 Some(AssetVaultKey::new_unchecked(key))
80 },
81 _ => None,
82 }
83 }
84
85 pub fn as_word(&self) -> &Word {
87 &self.0
88 }
89
90 fn is_fungible(&self) -> bool {
92 self.0[0].as_int() == 0 && self.0[1].as_int() == 0
93 }
94}
95
96impl fmt::Display for AssetVaultKey {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 write!(f, "{}", self.0)
99 }
100}
101
102impl From<AssetVaultKey> for Word {
106 fn from(vault_key: AssetVaultKey) -> Self {
107 vault_key.0
108 }
109}
110
111impl From<Asset> for AssetVaultKey {
112 fn from(asset: Asset) -> Self {
113 asset.vault_key()
114 }
115}
116
117impl From<FungibleAsset> for AssetVaultKey {
118 fn from(fungible_asset: FungibleAsset) -> Self {
119 fungible_asset.vault_key()
120 }
121}
122
123impl From<NonFungibleAsset> for AssetVaultKey {
124 fn from(non_fungible_asset: NonFungibleAsset) -> Self {
125 non_fungible_asset.vault_key()
126 }
127}
128
129#[cfg(test)]
133mod tests {
134 use miden_core::Felt;
135
136 use super::*;
137 use crate::account::{AccountIdVersion, AccountStorageMode, AccountType};
138
139 fn make_non_fungible_key(prefix: u64) -> AssetVaultKey {
140 let word = [Felt::new(prefix), Felt::new(11), Felt::new(22), Felt::new(33)].into();
141 AssetVaultKey::new_unchecked(word)
142 }
143
144 #[test]
145 fn test_faucet_id_for_fungible_asset() {
146 let id = AccountId::dummy(
147 [0xff; 15],
148 AccountIdVersion::Version0,
149 AccountType::FungibleFaucet,
150 AccountStorageMode::Public,
151 );
152
153 let key =
154 AssetVaultKey::from_account_id(id).expect("Expected AssetVaultKey for FungibleFaucet");
155
156 assert_eq!(key.faucet_id_prefix(), id.prefix());
158
159 assert_eq!(key.faucet_id().unwrap(), id);
161 }
162
163 #[test]
164 fn test_faucet_id_for_non_fungible_asset() {
165 let id = AccountId::dummy(
166 [0xff; 15],
167 AccountIdVersion::Version0,
168 AccountType::NonFungibleFaucet,
169 AccountStorageMode::Public,
170 );
171
172 let prefix_value = id.prefix().as_u64();
173 let key = make_non_fungible_key(prefix_value);
174
175 assert_eq!(key.faucet_id_prefix(), id.prefix());
177
178 assert_eq!(key.faucet_id(), None);
180 }
181}