use alloc::collections::BTreeSet;
use alloc::vec::Vec;
use miden_protocol::account::{Account, AccountCode, AccountId, AccountProcedureRoot};
use crate::account::components::StandardAccountComponent;
use crate::account::interface::{AccountComponentInterface, AccountInterface};
pub trait AccountInterfaceExt {
fn from_code(account_id: AccountId, code: &AccountCode) -> Self;
fn from_account(account: &Account) -> Self;
}
impl AccountInterfaceExt for AccountInterface {
fn from_code(account_id: AccountId, code: &AccountCode) -> Self {
let components = AccountComponentInterface::from_procedures(code.procedures());
Self::new(account_id, components)
}
fn from_account(account: &Account) -> Self {
let components = AccountComponentInterface::from_procedures(account.code().procedures());
Self::new(account.id(), components)
}
}
pub trait AccountComponentInterfaceExt {
fn from_procedures(procedures: &[AccountProcedureRoot]) -> Vec<AccountComponentInterface>;
}
impl AccountComponentInterfaceExt for AccountComponentInterface {
fn from_procedures(procedures: &[AccountProcedureRoot]) -> Vec<Self> {
let mut component_interface_vec = Vec::new();
let auth_procedure = procedures.first().copied();
let mut procedures = BTreeSet::from_iter(procedures.iter().copied());
StandardAccountComponent::extract_standard_components(
&mut procedures,
&mut component_interface_vec,
);
if !component_interface_vec.iter().any(|component| component.is_auth_component())
&& let Some(auth_procedure) = auth_procedure
{
procedures.remove(&auth_procedure);
component_interface_vec.push(AccountComponentInterface::CustomAuth(auth_procedure));
}
if !procedures.is_empty() {
component_interface_vec
.push(AccountComponentInterface::Custom(procedures.into_iter().collect()));
}
component_interface_vec
}
}