miden_objects/asset/vault/
vault_key.rs1use core::fmt;
2
3use miden_crypto::merkle::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 fn is_fungible(&self) -> bool {
87 self.0[0].as_int() == 0 && self.0[1].as_int() == 0
88 }
89}
90
91impl fmt::Display for AssetVaultKey {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 write!(f, "{}", self.0)
94 }
95}
96
97impl From<AssetVaultKey> for Word {
101 fn from(vault_key: AssetVaultKey) -> Self {
102 vault_key.0
103 }
104}
105
106impl From<Asset> for AssetVaultKey {
107 fn from(asset: Asset) -> Self {
108 asset.vault_key()
109 }
110}
111
112impl From<FungibleAsset> for AssetVaultKey {
113 fn from(fungible_asset: FungibleAsset) -> Self {
114 fungible_asset.vault_key()
115 }
116}
117
118impl From<NonFungibleAsset> for AssetVaultKey {
119 fn from(non_fungible_asset: NonFungibleAsset) -> Self {
120 non_fungible_asset.vault_key()
121 }
122}
123
124#[cfg(test)]
128mod tests {
129 use miden_core::Felt;
130
131 use super::*;
132 use crate::account::{AccountIdVersion, AccountStorageMode, AccountType};
133
134 fn make_non_fungible_key(prefix: u64) -> AssetVaultKey {
135 let word = [Felt::new(prefix), Felt::new(11), Felt::new(22), Felt::new(33)].into();
136 AssetVaultKey::new_unchecked(word)
137 }
138
139 #[test]
140 fn test_faucet_id_for_fungible_asset() {
141 let id = AccountId::dummy(
142 [0xff; 15],
143 AccountIdVersion::Version0,
144 AccountType::FungibleFaucet,
145 AccountStorageMode::Public,
146 );
147
148 let key =
149 AssetVaultKey::from_account_id(id).expect("Expected AssetVaultKey for FungibleFaucet");
150
151 assert_eq!(key.faucet_id_prefix(), id.prefix());
153
154 assert_eq!(key.faucet_id().unwrap(), id);
156 }
157
158 #[test]
159 fn test_faucet_id_for_non_fungible_asset() {
160 let id = AccountId::dummy(
161 [0xff; 15],
162 AccountIdVersion::Version0,
163 AccountType::NonFungibleFaucet,
164 AccountStorageMode::Public,
165 );
166
167 let prefix_value = id.prefix().as_u64();
168 let key = make_non_fungible_key(prefix_value);
169
170 assert_eq!(key.faucet_id_prefix(), id.prefix());
172
173 assert_eq!(key.faucet_id(), None);
175 }
176}