Skip to main content

miden_standards/account/components/
mod.rs

1use alloc::collections::BTreeSet;
2use alloc::vec::Vec;
3
4use miden_processor::MastNodeExt;
5use miden_protocol::Word;
6use miden_protocol::account::AccountProcedureRoot;
7use miden_protocol::assembly::{Library, LibraryExport};
8use miden_protocol::utils::Deserializable;
9use miden_protocol::utils::sync::LazyLock;
10
11use crate::account::interface::AccountComponentInterface;
12
13// WALLET LIBRARIES
14// ================================================================================================
15
16// Initialize the Basic Wallet library only once.
17static BASIC_WALLET_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
18    let bytes = include_bytes!(concat!(
19        env!("OUT_DIR"),
20        "/assets/account_components/wallets/basic_wallet.masl"
21    ));
22    Library::read_from_bytes(bytes).expect("Shipped Basic Wallet library is well-formed")
23});
24
25// AUTH LIBRARIES
26// ================================================================================================
27
28/// Initialize the ECDSA K256 Keccak library only once.
29static ECDSA_K256_KECCAK_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
30    let bytes = include_bytes!(concat!(
31        env!("OUT_DIR"),
32        "/assets/account_components/auth/ecdsa_k256_keccak.masl"
33    ));
34    Library::read_from_bytes(bytes).expect("Shipped Ecdsa K256 Keccak library is well-formed")
35});
36
37// Initialize the ECDSA K256 Keccak ACL library only once.
38static ECDSA_K256_KECCAK_ACL_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
39    let bytes = include_bytes!(concat!(
40        env!("OUT_DIR"),
41        "/assets/account_components/auth/ecdsa_k256_keccak_acl.masl"
42    ));
43    Library::read_from_bytes(bytes).expect("Shipped Ecdsa K256 Keccak ACL library is well-formed")
44});
45
46/// Initialize the ECDSA K256 Keccak Multisig library only once.
47static ECDSA_K256_KECCAK_MULTISIG_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
48    let bytes = include_bytes!(concat!(
49        env!("OUT_DIR"),
50        "/assets/account_components/auth/ecdsa_k256_keccak_multisig.masl"
51    ));
52    Library::read_from_bytes(bytes)
53        .expect("Shipped Multisig Ecdsa K256 Keccak library is well-formed")
54});
55
56// Initialize the Falcon 512 RPO library only once.
57static FALCON_512_RPO_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
58    let bytes = include_bytes!(concat!(
59        env!("OUT_DIR"),
60        "/assets/account_components/auth/falcon_512_rpo.masl"
61    ));
62    Library::read_from_bytes(bytes).expect("Shipped Falcon 512 RPO library is well-formed")
63});
64
65// Initialize the Falcon 512 RPO ACL library only once.
66static FALCON_512_RPO_ACL_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
67    let bytes = include_bytes!(concat!(
68        env!("OUT_DIR"),
69        "/assets/account_components/auth/falcon_512_rpo_acl.masl"
70    ));
71    Library::read_from_bytes(bytes).expect("Shipped Falcon 512 RPO ACL library is well-formed")
72});
73
74// Initialize the Multisig Falcon 512 RPO library only once.
75static FALCON_512_RPO_MULTISIG_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
76    let bytes = include_bytes!(concat!(
77        env!("OUT_DIR"),
78        "/assets/account_components/auth/falcon_512_rpo_multisig.masl"
79    ));
80    Library::read_from_bytes(bytes).expect("Shipped Multisig Falcon 512 RPO library is well-formed")
81});
82
83// Initialize the NoAuth library only once.
84static NO_AUTH_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
85    let bytes =
86        include_bytes!(concat!(env!("OUT_DIR"), "/assets/account_components/auth/no_auth.masl"));
87    Library::read_from_bytes(bytes).expect("Shipped NoAuth library is well-formed")
88});
89
90// FAUCET LIBRARIES
91// ================================================================================================
92
93// Initialize the Basic Fungible Faucet library only once.
94static BASIC_FUNGIBLE_FAUCET_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
95    let bytes = include_bytes!(concat!(
96        env!("OUT_DIR"),
97        "/assets/account_components/faucets/basic_fungible_faucet.masl"
98    ));
99    Library::read_from_bytes(bytes).expect("Shipped Basic Fungible Faucet library is well-formed")
100});
101
102// Initialize the Network Fungible Faucet library only once.
103static NETWORK_FUNGIBLE_FAUCET_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
104    let bytes = include_bytes!(concat!(
105        env!("OUT_DIR"),
106        "/assets/account_components/faucets/network_fungible_faucet.masl"
107    ));
108    Library::read_from_bytes(bytes).expect("Shipped Network Fungible Faucet library is well-formed")
109});
110
111// METADATA LIBRARIES
112// ================================================================================================
113
114// Initialize the Storage Schema library only once.
115static STORAGE_SCHEMA_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
116    let bytes = include_bytes!(concat!(
117        env!("OUT_DIR"),
118        "/assets/account_components/metadata/schema_commitment.masl"
119    ));
120    Library::read_from_bytes(bytes).expect("Shipped Storage Schema library is well-formed")
121});
122
123/// Returns the Basic Wallet Library.
124pub fn basic_wallet_library() -> Library {
125    BASIC_WALLET_LIBRARY.clone()
126}
127
128/// Returns the Basic Fungible Faucet Library.
129pub fn basic_fungible_faucet_library() -> Library {
130    BASIC_FUNGIBLE_FAUCET_LIBRARY.clone()
131}
132
133/// Returns the Network Fungible Faucet Library.
134pub fn network_fungible_faucet_library() -> Library {
135    NETWORK_FUNGIBLE_FAUCET_LIBRARY.clone()
136}
137
138/// Returns the Storage Schema Library.
139pub fn storage_schema_library() -> Library {
140    STORAGE_SCHEMA_LIBRARY.clone()
141}
142
143/// Returns the ECDSA K256 Keccak Library.
144pub fn ecdsa_k256_keccak_library() -> Library {
145    ECDSA_K256_KECCAK_LIBRARY.clone()
146}
147
148/// Returns the ECDSA K256 Keccak ACL Library.
149pub fn ecdsa_k256_keccak_acl_library() -> Library {
150    ECDSA_K256_KECCAK_ACL_LIBRARY.clone()
151}
152
153/// Returns the ECDSA K256 Keccak Multisig Library.
154pub fn ecdsa_k256_keccak_multisig_library() -> Library {
155    ECDSA_K256_KECCAK_MULTISIG_LIBRARY.clone()
156}
157
158/// Returns the Falcon 512 RPO Library.
159pub fn falcon_512_rpo_library() -> Library {
160    FALCON_512_RPO_LIBRARY.clone()
161}
162
163/// Returns the Falcon 512 RPO ACL Library.
164pub fn falcon_512_rpo_acl_library() -> Library {
165    FALCON_512_RPO_ACL_LIBRARY.clone()
166}
167
168/// Returns the NoAuth Library.
169pub fn no_auth_library() -> Library {
170    NO_AUTH_LIBRARY.clone()
171}
172
173/// Returns the Falcon 512 RPO Multisig Library.
174pub fn falcon_512_rpo_multisig_library() -> Library {
175    FALCON_512_RPO_MULTISIG_LIBRARY.clone()
176}
177
178// WELL KNOWN COMPONENTS
179// ================================================================================================
180
181/// The enum holding the types of basic well-known account components provided by the `miden-lib`.
182pub enum WellKnownComponent {
183    BasicWallet,
184    BasicFungibleFaucet,
185    NetworkFungibleFaucet,
186    AuthEcdsaK256Keccak,
187    AuthEcdsaK256KeccakAcl,
188    AuthEcdsaK256KeccakMultisig,
189    AuthFalcon512Rpo,
190    AuthFalcon512RpoAcl,
191    AuthFalcon512RpoMultisig,
192    AuthNoAuth,
193}
194
195impl WellKnownComponent {
196    /// Returns the iterator over digests of all procedures exported from the component.
197    pub fn procedure_digests(&self) -> impl Iterator<Item = Word> {
198        let library = match self {
199            Self::BasicWallet => BASIC_WALLET_LIBRARY.as_ref(),
200            Self::BasicFungibleFaucet => BASIC_FUNGIBLE_FAUCET_LIBRARY.as_ref(),
201            Self::NetworkFungibleFaucet => NETWORK_FUNGIBLE_FAUCET_LIBRARY.as_ref(),
202            Self::AuthEcdsaK256Keccak => ECDSA_K256_KECCAK_LIBRARY.as_ref(),
203            Self::AuthEcdsaK256KeccakAcl => ECDSA_K256_KECCAK_ACL_LIBRARY.as_ref(),
204            Self::AuthEcdsaK256KeccakMultisig => ECDSA_K256_KECCAK_MULTISIG_LIBRARY.as_ref(),
205            Self::AuthFalcon512Rpo => FALCON_512_RPO_LIBRARY.as_ref(),
206            Self::AuthFalcon512RpoAcl => FALCON_512_RPO_ACL_LIBRARY.as_ref(),
207            Self::AuthFalcon512RpoMultisig => FALCON_512_RPO_MULTISIG_LIBRARY.as_ref(),
208            Self::AuthNoAuth => NO_AUTH_LIBRARY.as_ref(),
209        };
210
211        library
212            .exports()
213            .filter(|export| matches!(export, LibraryExport::Procedure(_)))
214            .map(|proc_export| {
215                library
216                    .mast_forest()
217                    .get_node_by_id(proc_export.unwrap_procedure().node)
218                    .expect("export node not in the forest")
219                    .digest()
220            })
221    }
222
223    /// Checks whether procedures from the current component are present in the procedures map
224    /// and if so it removes these procedures from this map and pushes the corresponding component
225    /// interface to the component interface vector.
226    fn extract_component(
227        &self,
228        procedures_set: &mut BTreeSet<AccountProcedureRoot>,
229        component_interface_vec: &mut Vec<AccountComponentInterface>,
230    ) {
231        // Determine if this component should be extracted based on procedure matching
232        if self.procedure_digests().all(|proc_digest| {
233            procedures_set.contains(&AccountProcedureRoot::from_raw(proc_digest))
234        }) {
235            // Remove the procedure root of any matching procedure.
236            self.procedure_digests().for_each(|component_procedure| {
237                procedures_set.remove(&AccountProcedureRoot::from_raw(component_procedure));
238            });
239
240            // Create the appropriate component interface
241            match self {
242                Self::BasicWallet => {
243                    component_interface_vec.push(AccountComponentInterface::BasicWallet)
244                },
245                Self::BasicFungibleFaucet => {
246                    component_interface_vec.push(AccountComponentInterface::BasicFungibleFaucet)
247                },
248                Self::NetworkFungibleFaucet => {
249                    component_interface_vec.push(AccountComponentInterface::NetworkFungibleFaucet)
250                },
251                Self::AuthEcdsaK256Keccak => {
252                    component_interface_vec.push(AccountComponentInterface::AuthEcdsaK256Keccak)
253                },
254                Self::AuthEcdsaK256KeccakAcl => {
255                    component_interface_vec.push(AccountComponentInterface::AuthEcdsaK256KeccakAcl)
256                },
257                Self::AuthEcdsaK256KeccakMultisig => component_interface_vec
258                    .push(AccountComponentInterface::AuthEcdsaK256KeccakMultisig),
259                Self::AuthFalcon512Rpo => {
260                    component_interface_vec.push(AccountComponentInterface::AuthFalcon512Rpo)
261                },
262                Self::AuthFalcon512RpoAcl => {
263                    component_interface_vec.push(AccountComponentInterface::AuthFalcon512RpoAcl)
264                },
265                Self::AuthFalcon512RpoMultisig => component_interface_vec
266                    .push(AccountComponentInterface::AuthFalcon512RpoMultisig),
267                Self::AuthNoAuth => {
268                    component_interface_vec.push(AccountComponentInterface::AuthNoAuth)
269                },
270            }
271        }
272    }
273
274    /// Gets all well known components which could be constructed from the provided procedures map
275    /// and pushes them to the `component_interface_vec`.
276    pub fn extract_well_known_components(
277        procedures_set: &mut BTreeSet<AccountProcedureRoot>,
278        component_interface_vec: &mut Vec<AccountComponentInterface>,
279    ) {
280        Self::BasicWallet.extract_component(procedures_set, component_interface_vec);
281        Self::BasicFungibleFaucet.extract_component(procedures_set, component_interface_vec);
282        Self::NetworkFungibleFaucet.extract_component(procedures_set, component_interface_vec);
283        Self::AuthEcdsaK256Keccak.extract_component(procedures_set, component_interface_vec);
284        Self::AuthEcdsaK256KeccakAcl.extract_component(procedures_set, component_interface_vec);
285        Self::AuthEcdsaK256KeccakMultisig
286            .extract_component(procedures_set, component_interface_vec);
287        Self::AuthFalcon512Rpo.extract_component(procedures_set, component_interface_vec);
288        Self::AuthFalcon512RpoAcl.extract_component(procedures_set, component_interface_vec);
289        Self::AuthFalcon512RpoMultisig.extract_component(procedures_set, component_interface_vec);
290        Self::AuthNoAuth.extract_component(procedures_set, component_interface_vec);
291    }
292}