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