Skip to main content

miden_standards/account/interface/
extension.rs

1use alloc::collections::BTreeSet;
2use alloc::vec::Vec;
3
4use miden_protocol::account::{Account, AccountCode, AccountId, AccountProcedureRoot};
5
6use crate::AuthMethod;
7use crate::account::components::StandardAccountComponent;
8use crate::account::interface::{AccountComponentInterface, AccountInterface};
9
10// ACCOUNT INTERFACE EXTENSION TRAIT
11// ================================================================================================
12
13/// An extension for [`AccountInterface`] that allows instantiation from higher-level types.
14pub trait AccountInterfaceExt {
15    /// Creates a new [`AccountInterface`] instance from the provided account ID, authentication
16    /// methods and account code.
17    fn from_code(account_id: AccountId, auth: Vec<AuthMethod>, code: &AccountCode) -> Self;
18
19    /// Creates a new [`AccountInterface`] instance from the provided [`Account`].
20    fn from_account(account: &Account) -> Self;
21}
22
23impl AccountInterfaceExt for AccountInterface {
24    fn from_code(account_id: AccountId, auth: Vec<AuthMethod>, code: &AccountCode) -> Self {
25        let components = AccountComponentInterface::from_procedures(code.procedures());
26
27        Self::new(account_id, auth, components)
28    }
29
30    fn from_account(account: &Account) -> Self {
31        let components = AccountComponentInterface::from_procedures(account.code().procedures());
32        let mut auth = Vec::new();
33
34        // Find the auth component and extract all auth methods from it
35        // An account should have only one auth component
36        for component in components.iter() {
37            if component.is_auth_component() {
38                auth = component.get_auth_methods(account.storage());
39                break;
40            }
41        }
42
43        Self::new(account.id(), auth, components)
44    }
45}
46
47/// An extension for [`AccountComponentInterface`] that allows instantiation from a set of procedure
48/// roots.
49pub trait AccountComponentInterfaceExt {
50    /// Creates a vector of [`AccountComponentInterface`] instances from the provided set of
51    /// procedures.
52    fn from_procedures(procedures: &[AccountProcedureRoot]) -> Vec<AccountComponentInterface>;
53}
54
55impl AccountComponentInterfaceExt for AccountComponentInterface {
56    fn from_procedures(procedures: &[AccountProcedureRoot]) -> Vec<Self> {
57        let mut component_interface_vec = Vec::new();
58
59        let mut procedures = BTreeSet::from_iter(procedures.iter().copied());
60
61        // Standard component interfaces
62        // ----------------------------------------------------------------------------------------
63
64        // Get all available standard components which could be constructed from the
65        // `procedures` map and push them to the `component_interface_vec`
66        StandardAccountComponent::extract_standard_components(
67            &mut procedures,
68            &mut component_interface_vec,
69        );
70
71        // Custom component interfaces
72        // ----------------------------------------------------------------------------------------
73
74        // All remaining procedures are put into the custom bucket.
75        component_interface_vec
76            .push(AccountComponentInterface::Custom(procedures.into_iter().collect()));
77
78        component_interface_vec
79    }
80}