Skip to main content

miden_standards/account/components/
mod.rs

1use alloc::collections::BTreeSet;
2use alloc::vec::Vec;
3
4use miden_protocol::account::AccountProcedureRoot;
5
6use crate::account::access::{Authority, Ownable2Step, RoleBasedAccessControl};
7use crate::account::auth::{
8    AuthGuardedMultisig,
9    AuthMultisig,
10    AuthMultisigSmart,
11    AuthNetworkAccount,
12    AuthSingleSig,
13    AuthTxFeeCollector,
14    NoAuth,
15};
16use crate::account::faucets::FungibleFaucet;
17use crate::account::inspection::CodeInspection;
18use crate::account::interface::AccountComponentInterface;
19use crate::account::note_creator::NoteCreator;
20use crate::account::wallets::BasicWallet;
21
22// STANDARD ACCOUNT COMPONENTS
23// ================================================================================================
24
25/// The enum holding the types of standard account components defined in the `miden-standards`
26/// crate.
27pub enum StandardAccountComponent {
28    BasicWallet,
29    NoteCreator,
30    FungibleFaucet,
31    CodeInspection,
32    Authority,
33    Ownable2Step,
34    RoleBasedAccessControl,
35    AuthSingleSig,
36    AuthMultisig,
37    AuthMultisigSmart,
38    AuthGuardedMultisig,
39    AuthNoAuth,
40    AuthNetworkAccount,
41    AuthTxFeeCollector,
42}
43
44impl StandardAccountComponent {
45    /// Returns the iterator over the [`AccountProcedureRoot`]s of all procedures exported from
46    /// the component.
47    pub fn procedure_roots(&self) -> impl Iterator<Item = AccountProcedureRoot> {
48        let code = match self {
49            Self::BasicWallet => BasicWallet::code(),
50            Self::NoteCreator => NoteCreator::code(),
51            Self::FungibleFaucet => FungibleFaucet::code(),
52            Self::CodeInspection => CodeInspection::code(),
53            Self::Authority => Authority::code(),
54            Self::Ownable2Step => Ownable2Step::code(),
55            Self::RoleBasedAccessControl => RoleBasedAccessControl::code(),
56            Self::AuthSingleSig => AuthSingleSig::code(),
57            Self::AuthMultisig => AuthMultisig::code(),
58            Self::AuthMultisigSmart => AuthMultisigSmart::code(),
59            Self::AuthGuardedMultisig => AuthGuardedMultisig::code(),
60            Self::AuthNoAuth => NoAuth::code(),
61            Self::AuthNetworkAccount => AuthNetworkAccount::code(),
62            Self::AuthTxFeeCollector => AuthTxFeeCollector::code(),
63        };
64
65        code.procedure_roots()
66    }
67
68    /// Checks whether procedures from the current component are present in the procedures map
69    /// and if so it removes these procedures from this map and pushes the corresponding component
70    /// interface to the component interface vector.
71    fn extract_component(
72        &self,
73        procedures_set: &mut BTreeSet<AccountProcedureRoot>,
74        component_interface_vec: &mut Vec<AccountComponentInterface>,
75    ) {
76        // Determine if this component should be extracted based on procedure matching
77        if self.procedure_roots().all(|proc_root| procedures_set.contains(&proc_root)) {
78            // Remove the procedure root of any matching procedure.
79            self.procedure_roots().for_each(|component_procedure| {
80                procedures_set.remove(&component_procedure);
81            });
82
83            // Create the appropriate component interface
84            match self {
85                Self::BasicWallet => {
86                    component_interface_vec.push(AccountComponentInterface::BasicWallet)
87                },
88                Self::NoteCreator => {
89                    component_interface_vec.push(AccountComponentInterface::NoteCreator)
90                },
91                Self::FungibleFaucet => {
92                    component_interface_vec.push(AccountComponentInterface::FungibleFaucet)
93                },
94                Self::CodeInspection => {
95                    component_interface_vec.push(AccountComponentInterface::CodeInspection)
96                },
97                Self::Authority => {
98                    component_interface_vec.push(AccountComponentInterface::Authority)
99                },
100                Self::Ownable2Step => {
101                    component_interface_vec.push(AccountComponentInterface::Ownable2Step)
102                },
103                Self::RoleBasedAccessControl => {
104                    component_interface_vec.push(AccountComponentInterface::RoleBasedAccessControl)
105                },
106                Self::AuthSingleSig => {
107                    component_interface_vec.push(AccountComponentInterface::AuthSingleSig)
108                },
109                Self::AuthMultisig => {
110                    component_interface_vec.push(AccountComponentInterface::AuthMultisig)
111                },
112                Self::AuthMultisigSmart => {
113                    component_interface_vec.push(AccountComponentInterface::AuthMultisigSmart)
114                },
115                Self::AuthGuardedMultisig => {
116                    component_interface_vec.push(AccountComponentInterface::AuthGuardedMultisig)
117                },
118                Self::AuthNoAuth => {
119                    component_interface_vec.push(AccountComponentInterface::AuthNoAuth)
120                },
121                Self::AuthNetworkAccount => {
122                    component_interface_vec.push(AccountComponentInterface::AuthNetworkAccount)
123                },
124                Self::AuthTxFeeCollector => {
125                    component_interface_vec.push(AccountComponentInterface::AuthTxFeeCollector)
126                },
127            }
128        }
129    }
130
131    /// Gets all standard components which could be constructed from the provided procedures map
132    /// and pushes them to the `component_interface_vec`.
133    pub fn extract_standard_components(
134        procedures_set: &mut BTreeSet<AccountProcedureRoot>,
135        component_interface_vec: &mut Vec<AccountComponentInterface>,
136    ) {
137        Self::BasicWallet.extract_component(procedures_set, component_interface_vec);
138        // Must run after `BasicWallet`: `NoteCreator`'s only procedure (`create_note`) is a subset
139        // of the basic wallet's, so a full wallet must claim it first to avoid misdetection.
140        Self::NoteCreator.extract_component(procedures_set, component_interface_vec);
141        Self::FungibleFaucet.extract_component(procedures_set, component_interface_vec);
142        Self::CodeInspection.extract_component(procedures_set, component_interface_vec);
143        Self::Authority.extract_component(procedures_set, component_interface_vec);
144        Self::RoleBasedAccessControl.extract_component(procedures_set, component_interface_vec);
145        Self::Ownable2Step.extract_component(procedures_set, component_interface_vec);
146        Self::AuthSingleSig.extract_component(procedures_set, component_interface_vec);
147        Self::AuthGuardedMultisig.extract_component(procedures_set, component_interface_vec);
148        Self::AuthMultisig.extract_component(procedures_set, component_interface_vec);
149        Self::AuthMultisigSmart.extract_component(procedures_set, component_interface_vec);
150        Self::AuthNoAuth.extract_component(procedures_set, component_interface_vec);
151        Self::AuthNetworkAccount.extract_component(procedures_set, component_interface_vec);
152        Self::AuthTxFeeCollector.extract_component(procedures_set, component_interface_vec);
153    }
154}