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