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;
9use miden_processor::MastNodeExt;
10
11use crate::account::interface::AccountComponentInterface;
12
13// Initialize the Basic Wallet library only once.
14static BASIC_WALLET_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
15    let bytes =
16        include_bytes!(concat!(env!("OUT_DIR"), "/assets/account_components/basic_wallet.masl"));
17    Library::read_from_bytes(bytes).expect("Shipped Basic Wallet library is well-formed")
18});
19
20/// Initialize the ECDSA K256 Keccak library only once.
21static ECDSA_K256_KECCAK_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
22    let bytes = include_bytes!(concat!(
23        env!("OUT_DIR"),
24        "/assets/account_components/ecdsa_k256_keccak.masl"
25    ));
26    Library::read_from_bytes(bytes).expect("Shipped Ecdsa K256 Keccak library is well-formed")
27});
28
29// Initialize the ECDSA K256 Keccak ACL library only once.
30static ECDSA_K256_KECCAK_ACL_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
31    let bytes = include_bytes!(concat!(
32        env!("OUT_DIR"),
33        "/assets/account_components/ecdsa_k256_keccak_acl.masl"
34    ));
35    Library::read_from_bytes(bytes).expect("Shipped Ecdsa K256 Keccak ACL library is well-formed")
36});
37
38/// Initialize the ECDSA K256 Keccak Multisig library only once.
39static ECDSA_K256_KECCAK_MULTISIG_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
40    let bytes = include_bytes!(concat!(
41        env!("OUT_DIR"),
42        "/assets/account_components/multisig_ecdsa_k256_keccak.masl"
43    ));
44    Library::read_from_bytes(bytes)
45        .expect("Shipped Multisig Ecdsa K256 Keccak library is well-formed")
46});
47
48// Initialize the Rpo Falcon 512 library only once.
49static RPO_FALCON_512_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
50    let bytes =
51        include_bytes!(concat!(env!("OUT_DIR"), "/assets/account_components/rpo_falcon_512.masl"));
52    Library::read_from_bytes(bytes).expect("Shipped Rpo Falcon 512 library is well-formed")
53});
54
55// Initialize the Basic Fungible Faucet library only once.
56static BASIC_FUNGIBLE_FAUCET_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
57    let bytes = include_bytes!(concat!(
58        env!("OUT_DIR"),
59        "/assets/account_components/basic_fungible_faucet.masl"
60    ));
61    Library::read_from_bytes(bytes).expect("Shipped Basic Fungible Faucet library is well-formed")
62});
63
64// Initialize the Network Fungible Faucet library only once.
65static NETWORK_FUNGIBLE_FAUCET_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
66    let bytes = include_bytes!(concat!(
67        env!("OUT_DIR"),
68        "/assets/account_components/network_fungible_faucet.masl"
69    ));
70    Library::read_from_bytes(bytes).expect("Shipped Network Fungible Faucet library is well-formed")
71});
72
73// Initialize the Rpo Falcon 512 ACL library only once.
74static RPO_FALCON_512_ACL_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
75    let bytes = include_bytes!(concat!(
76        env!("OUT_DIR"),
77        "/assets/account_components/rpo_falcon_512_acl.masl"
78    ));
79    Library::read_from_bytes(bytes).expect("Shipped Rpo Falcon 512 ACL library is well-formed")
80});
81
82// Initialize the NoAuth library only once.
83static NO_AUTH_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
84    let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/account_components/no_auth.masl"));
85    Library::read_from_bytes(bytes).expect("Shipped NoAuth library is well-formed")
86});
87
88// Initialize the Multisig Rpo Falcon 512 library only once.
89static RPO_FALCON_512_MULTISIG_LIBRARY: LazyLock<Library> = LazyLock::new(|| {
90    let bytes = include_bytes!(concat!(
91        env!("OUT_DIR"),
92        "/assets/account_components/multisig_rpo_falcon_512.masl"
93    ));
94    Library::read_from_bytes(bytes).expect("Shipped Multisig Rpo Falcon 512 library is well-formed")
95});
96
97/// Returns the Basic Wallet Library.
98pub fn basic_wallet_library() -> Library {
99    BASIC_WALLET_LIBRARY.clone()
100}
101
102/// Returns the Basic Fungible Faucet Library.
103pub fn basic_fungible_faucet_library() -> Library {
104    BASIC_FUNGIBLE_FAUCET_LIBRARY.clone()
105}
106
107/// Returns the Network Fungible Faucet Library.
108pub fn network_fungible_faucet_library() -> Library {
109    NETWORK_FUNGIBLE_FAUCET_LIBRARY.clone()
110}
111
112/// Returns the ECDSA K256 Keccak Library.
113pub fn ecdsa_k256_keccak_library() -> Library {
114    ECDSA_K256_KECCAK_LIBRARY.clone()
115}
116
117/// Returns the ECDSA K256 Keccak ACL Library.
118pub fn ecdsa_k256_keccak_acl_library() -> Library {
119    ECDSA_K256_KECCAK_ACL_LIBRARY.clone()
120}
121
122/// Returns the ECDSA K256 Keccak Multisig Library.
123pub fn ecdsa_k256_keccak_multisig_library() -> Library {
124    ECDSA_K256_KECCAK_MULTISIG_LIBRARY.clone()
125}
126
127/// Returns the Rpo Falcon 512 Library.
128pub fn rpo_falcon_512_library() -> Library {
129    RPO_FALCON_512_LIBRARY.clone()
130}
131
132/// Returns the Rpo Falcon 512 ACL Library.
133pub fn rpo_falcon_512_acl_library() -> Library {
134    RPO_FALCON_512_ACL_LIBRARY.clone()
135}
136
137/// Returns the NoAuth Library.
138pub fn no_auth_library() -> Library {
139    NO_AUTH_LIBRARY.clone()
140}
141
142/// Returns the RPO Falcon 512 Multisig Library.
143pub fn rpo_falcon_512_multisig_library() -> Library {
144    RPO_FALCON_512_MULTISIG_LIBRARY.clone()
145}
146
147// WELL KNOWN COMPONENTS
148// ================================================================================================
149
150/// The enum holding the types of basic well-known account components provided by the `miden-lib`.
151pub enum WellKnownComponent {
152    BasicWallet,
153    BasicFungibleFaucet,
154    NetworkFungibleFaucet,
155    AuthEcdsaK256Keccak,
156    AuthEcdsaK256KeccakAcl,
157    AuthEcdsaK256KeccakMultisig,
158    AuthRpoFalcon512,
159    AuthRpoFalcon512Acl,
160    AuthRpoFalcon512Multisig,
161    AuthNoAuth,
162}
163
164impl WellKnownComponent {
165    /// Returns the iterator over digests of all procedures exported from the component.
166    pub fn procedure_digests(&self) -> impl Iterator<Item = Word> {
167        let library = match self {
168            Self::BasicWallet => BASIC_WALLET_LIBRARY.as_ref(),
169            Self::BasicFungibleFaucet => BASIC_FUNGIBLE_FAUCET_LIBRARY.as_ref(),
170            Self::NetworkFungibleFaucet => NETWORK_FUNGIBLE_FAUCET_LIBRARY.as_ref(),
171            Self::AuthEcdsaK256Keccak => ECDSA_K256_KECCAK_LIBRARY.as_ref(),
172            Self::AuthEcdsaK256KeccakAcl => ECDSA_K256_KECCAK_ACL_LIBRARY.as_ref(),
173            Self::AuthEcdsaK256KeccakMultisig => ECDSA_K256_KECCAK_MULTISIG_LIBRARY.as_ref(),
174            Self::AuthRpoFalcon512 => RPO_FALCON_512_LIBRARY.as_ref(),
175            Self::AuthRpoFalcon512Acl => RPO_FALCON_512_ACL_LIBRARY.as_ref(),
176            Self::AuthRpoFalcon512Multisig => RPO_FALCON_512_MULTISIG_LIBRARY.as_ref(),
177            Self::AuthNoAuth => NO_AUTH_LIBRARY.as_ref(),
178        };
179
180        library.exports().map(|export| {
181            library
182                .mast_forest()
183                .get_node_by_id(export.node)
184                .expect("export node not in the forest")
185                .digest()
186        })
187    }
188
189    /// Checks whether procedures from the current component are present in the procedures map
190    /// and if so it removes these procedures from this map and pushes the corresponding component
191    /// interface to the component interface vector.
192    fn extract_component(
193        &self,
194        procedures_map: &mut BTreeMap<Word, &AccountProcedureInfo>,
195        component_interface_vec: &mut Vec<AccountComponentInterface>,
196    ) {
197        // Determine if this component should be extracted based on procedure matching
198        if self
199            .procedure_digests()
200            .all(|proc_digest| procedures_map.contains_key(&proc_digest))
201        {
202            // Extract the storage offset from any matching procedure
203            let mut storage_offset = 0u8;
204            self.procedure_digests().for_each(|component_procedure| {
205                if let Some(proc_info) = procedures_map.remove(&component_procedure) {
206                    storage_offset = proc_info.storage_offset();
207                }
208            });
209
210            // Create the appropriate component interface
211            match self {
212                Self::BasicWallet => {
213                    component_interface_vec.push(AccountComponentInterface::BasicWallet)
214                },
215                Self::BasicFungibleFaucet => component_interface_vec
216                    .push(AccountComponentInterface::BasicFungibleFaucet(storage_offset)),
217                Self::NetworkFungibleFaucet => component_interface_vec
218                    .push(AccountComponentInterface::NetworkFungibleFaucet(storage_offset)),
219                Self::AuthEcdsaK256Keccak => component_interface_vec
220                    .push(AccountComponentInterface::AuthEcdsaK256Keccak(storage_offset)),
221                Self::AuthEcdsaK256KeccakAcl => component_interface_vec
222                    .push(AccountComponentInterface::AuthEcdsaK256KeccakAcl(storage_offset)),
223                Self::AuthEcdsaK256KeccakMultisig => component_interface_vec
224                    .push(AccountComponentInterface::AuthEcdsaK256KeccakMultisig(storage_offset)),
225                Self::AuthRpoFalcon512 => component_interface_vec
226                    .push(AccountComponentInterface::AuthRpoFalcon512(storage_offset)),
227                Self::AuthRpoFalcon512Acl => component_interface_vec
228                    .push(AccountComponentInterface::AuthRpoFalcon512Acl(storage_offset)),
229                Self::AuthRpoFalcon512Multisig => component_interface_vec
230                    .push(AccountComponentInterface::AuthRpoFalcon512Multisig(storage_offset)),
231                Self::AuthNoAuth => {
232                    component_interface_vec.push(AccountComponentInterface::AuthNoAuth)
233                },
234            }
235        }
236    }
237
238    /// Gets all well known components which could be constructed from the provided procedures map
239    /// and pushes them to the `component_interface_vec`.
240    pub fn extract_well_known_components(
241        procedures_map: &mut BTreeMap<Word, &AccountProcedureInfo>,
242        component_interface_vec: &mut Vec<AccountComponentInterface>,
243    ) {
244        Self::BasicWallet.extract_component(procedures_map, component_interface_vec);
245        Self::BasicFungibleFaucet.extract_component(procedures_map, component_interface_vec);
246        Self::NetworkFungibleFaucet.extract_component(procedures_map, component_interface_vec);
247        Self::AuthEcdsaK256Keccak.extract_component(procedures_map, component_interface_vec);
248        Self::AuthEcdsaK256KeccakAcl.extract_component(procedures_map, component_interface_vec);
249        Self::AuthEcdsaK256KeccakMultisig
250            .extract_component(procedures_map, component_interface_vec);
251        Self::AuthRpoFalcon512.extract_component(procedures_map, component_interface_vec);
252        Self::AuthRpoFalcon512Acl.extract_component(procedures_map, component_interface_vec);
253        Self::AuthRpoFalcon512Multisig.extract_component(procedures_map, component_interface_vec);
254        Self::AuthNoAuth.extract_component(procedures_map, component_interface_vec);
255    }
256}