1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use js_export_macro::js_export;
use miden_client::account::AccountId as NativeAccountId;
use miden_client::asset::AssetVault as NativeAssetVault;
use super::account_id::AccountId;
use super::fungible_asset::FungibleAsset;
use super::word::Word;
/// A container for an unlimited number of assets.
///
/// An asset vault can contain an unlimited number of assets. The assets are stored in a Sparse
/// Merkle tree as follows:
/// - For fungible assets, the index of a node is defined by the issuing faucet ID, and the value of
/// the node is the asset itself. Thus, for any fungible asset there will be only one node in the
/// tree.
/// - For non-fungible assets, the index is defined by the asset itself, and the asset is also the
/// value of the node.
///
/// An asset vault can be reduced to a single hash which is the root of the Sparse Merkle Tree.
#[derive(Clone)]
#[js_export]
pub struct AssetVault(NativeAssetVault);
#[js_export]
impl AssetVault {
/// Returns the root commitment of the asset vault tree.
pub fn root(&self) -> Word {
self.0.root().into()
}
/// Returns the balance for the given fungible faucet, or zero if absent.
///
/// Matches by faucet id across the vault's fungible assets, so the balance is
/// found regardless of the asset's callback flag.
#[js_export(js_name = "getBalance")]
pub fn get_balance(&self, faucet_id: &AccountId) -> u64 {
let native_faucet_id: NativeAccountId = faucet_id.into();
self.0
.assets()
.filter_map(|asset| {
if asset.is_fungible() {
Some(asset.unwrap_fungible())
} else {
None
}
})
.find(|fungible| fungible.faucet_id() == native_faucet_id)
.map_or(0, |fungible| u64::from(fungible.amount()))
}
/// Returns the fungible assets contained in this vault.
#[js_export(js_name = "fungibleAssets")]
pub fn fungible_assets(&self) -> Vec<FungibleAsset> {
self.0
.assets()
.filter_map(|asset| {
if asset.is_fungible() {
Some(asset.unwrap_fungible().into())
} else {
None // TODO: Support non fungible assets
}
})
.collect()
}
}
// CONVERSIONS
// ================================================================================================
impl From<NativeAssetVault> for AssetVault {
fn from(native_asset_vault: NativeAssetVault) -> Self {
AssetVault(native_asset_vault)
}
}
impl From<&NativeAssetVault> for AssetVault {
fn from(native_asset_vault: &NativeAssetVault) -> Self {
AssetVault(native_asset_vault.clone())
}
}