miden_lib/account/components/
mod.rs

1use alloc::collections::BTreeMap;
2use alloc::vec::Vec;
3
4use miden_objects::Word;
5use miden_objects::account::AccountProcedureInfo;
6use miden_objects::assembly::Library;
7use miden_objects::utils::Deserializable;
8use miden_objects::utils::sync::LazyLock;
9
10use crate::account::interface::AccountComponentInterface;
11
12// Initialize the Basic Wallet library only once.
13static BASIC_WALLET_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
14    let bytes =
15        include_bytes!(concat!(env!("OUT_DIR"), "/assets/account_components/basic_wallet.masl"));
16    Library::read_from_bytes(bytes).expect("Shipped Basic Wallet library is well-formed")
17});
18
19// Initialize the Rpo Falcon 512 library only once.
20static RPO_FALCON_512_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
21    let bytes =
22        include_bytes!(concat!(env!("OUT_DIR"), "/assets/account_components/rpo_falcon_512.masl"));
23    Library::read_from_bytes(bytes).expect("Shipped Rpo Falcon 512 library is well-formed")
24});
25
26// Initialize the Basic Fungible Faucet library only once.
27static BASIC_FUNGIBLE_FAUCET_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
28    let bytes = include_bytes!(concat!(
29        env!("OUT_DIR"),
30        "/assets/account_components/basic_fungible_faucet.masl"
31    ));
32    Library::read_from_bytes(bytes).expect("Shipped Basic Fungible Faucet library is well-formed")
33});
34
35// Initialize the Rpo Falcon 512 ACL library only once.
36static RPO_FALCON_512_ACL_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
37    let bytes = include_bytes!(concat!(
38        env!("OUT_DIR"),
39        "/assets/account_components/rpo_falcon_512_acl.masl"
40    ));
41    Library::read_from_bytes(bytes).expect("Shipped Rpo Falcon 512 ACL library is well-formed")
42});
43
44// Initialize the NoAuth library only once.
45static NO_AUTH_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
46    let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/account_components/no_auth.masl"));
47    Library::read_from_bytes(bytes).expect("Shipped NoAuth library is well-formed")
48});
49
50// Initialize the Multisig Rpo Falcon 512 library only once.
51static RPO_FALCON_512_MULTISIG_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
52    let bytes = include_bytes!(concat!(
53        env!("OUT_DIR"),
54        "/assets/account_components/multisig_rpo_falcon_512.masl"
55    ));
56    Library::read_from_bytes(bytes).expect("Shipped Multisig Rpo Falcon 512 library is well-formed")
57});
58
59/// Returns the Basic Wallet Library.
60pub fn basic_wallet_library() -> Library {
61    BASIC_WALLET_LIBRARY.clone()
62}
63
64/// Returns the Basic Fungible Faucet Library.
65pub fn basic_fungible_faucet_library() -> Library {
66    BASIC_FUNGIBLE_FAUCET_LIBRARY.clone()
67}
68
69/// Returns the Rpo Falcon 512 Library.
70pub fn rpo_falcon_512_library() -> Library {
71    RPO_FALCON_512_LIBRARY.clone()
72}
73
74/// Returns the Rpo Falcon 512 ACL Library.
75pub fn rpo_falcon_512_acl_library() -> Library {
76    RPO_FALCON_512_ACL_LIBRARY.clone()
77}
78
79/// Returns the NoAuth Library.
80pub fn no_auth_library() -> Library {
81    NO_AUTH_LIBRARY.clone()
82}
83
84/// Returns the Multisig Library.
85pub fn multisig_library() -> Library {
86    RPO_FALCON_512_MULTISIG_LIBRARY.clone()
87}
88
89// WELL KNOWN COMPONENTS
90// ================================================================================================
91
92/// The enum holding the types of basic well-known account components provided by the `miden-lib`.
93pub enum WellKnownComponent {
94    BasicWallet,
95    BasicFungibleFaucet,
96    AuthRpoFalcon512,
97    AuthRpoFalcon512Acl,
98    AuthRpoFalcon512Multisig,
99    AuthNoAuth,
100}
101
102impl WellKnownComponent {
103    /// Returns the iterator over digests of all procedures exported from the component.
104    pub fn procedure_digests(&self) -> impl Iterator<Item = Word> {
105        let library = match self {
106            Self::BasicWallet => BASIC_WALLET_LIBRARY.as_ref(),
107            Self::BasicFungibleFaucet => BASIC_FUNGIBLE_FAUCET_LIBRARY.as_ref(),
108            Self::AuthRpoFalcon512 => RPO_FALCON_512_LIBRARY.as_ref(),
109            Self::AuthRpoFalcon512Acl => RPO_FALCON_512_ACL_LIBRARY.as_ref(),
110            Self::AuthRpoFalcon512Multisig => RPO_FALCON_512_MULTISIG_LIBRARY.as_ref(),
111            Self::AuthNoAuth => NO_AUTH_LIBRARY.as_ref(),
112        };
113
114        library.exports().map(|export| {
115            library
116                .mast_forest()
117                .get_node_by_id(export.node)
118                .expect("export node not in the forest")
119                .digest()
120        })
121    }
122
123    /// Checks whether procedures from the current component are present in the procedures map
124    /// and if so it removes these procedures from this map and pushes the corresponding component
125    /// interface to the component interface vector.
126    fn extract_component(
127        &self,
128        procedures_map: &mut BTreeMap<Word, &AccountProcedureInfo>,
129        component_interface_vec: &mut Vec<AccountComponentInterface>,
130    ) {
131        // Determine if this component should be extracted based on procedure matching
132        if self
133            .procedure_digests()
134            .all(|proc_digest| procedures_map.contains_key(&proc_digest))
135        {
136            // Extract the storage offset from any matching procedure
137            let mut storage_offset = 0u8;
138            self.procedure_digests().for_each(|component_procedure| {
139                if let Some(proc_info) = procedures_map.remove(&component_procedure) {
140                    storage_offset = proc_info.storage_offset();
141                }
142            });
143
144            // Create the appropriate component interface
145            match self {
146                Self::BasicWallet => {
147                    component_interface_vec.push(AccountComponentInterface::BasicWallet)
148                },
149                Self::BasicFungibleFaucet => component_interface_vec
150                    .push(AccountComponentInterface::BasicFungibleFaucet(storage_offset)),
151                Self::AuthRpoFalcon512 => component_interface_vec
152                    .push(AccountComponentInterface::AuthRpoFalcon512(storage_offset)),
153                Self::AuthRpoFalcon512Acl => component_interface_vec
154                    .push(AccountComponentInterface::AuthRpoFalcon512Acl(storage_offset)),
155                Self::AuthRpoFalcon512Multisig => component_interface_vec
156                    .push(AccountComponentInterface::AuthRpoFalcon512Multisig(storage_offset)),
157                Self::AuthNoAuth => {
158                    component_interface_vec.push(AccountComponentInterface::AuthNoAuth)
159                },
160            }
161        }
162    }
163
164    /// Gets all well known components which could be constructed from the provided procedures map
165    /// and pushes them to the `component_interface_vec`.
166    pub fn extract_well_known_components(
167        procedures_map: &mut BTreeMap<Word, &AccountProcedureInfo>,
168        component_interface_vec: &mut Vec<AccountComponentInterface>,
169    ) {
170        Self::BasicWallet.extract_component(procedures_map, component_interface_vec);
171        Self::BasicFungibleFaucet.extract_component(procedures_map, component_interface_vec);
172        Self::AuthRpoFalcon512.extract_component(procedures_map, component_interface_vec);
173        Self::AuthRpoFalcon512Acl.extract_component(procedures_map, component_interface_vec);
174        Self::AuthRpoFalcon512Multisig.extract_component(procedures_map, component_interface_vec);
175        Self::AuthNoAuth.extract_component(procedures_map, component_interface_vec);
176    }
177}