use alloc::vec::Vec;
use miden_protocol::account::{AccountComponent, AccountProcedureRoot};
use thiserror::Error;
mod allow_all;
mod owner_only;
pub use allow_all::MintAllowAll;
pub use owner_only::MintOwnerOnly;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Error)]
pub enum MintPolicyError {
#[error(
"custom mint policy root must match a procedure root in one of the provided components"
)]
RootNotInComponents,
}
#[derive(Debug, Clone)]
pub struct MintPolicy {
root: AccountProcedureRoot,
components: Vec<AccountComponent>,
}
impl MintPolicy {
pub fn allow_all() -> Self {
Self {
root: MintAllowAll::root(),
components: vec![MintAllowAll.into()],
}
}
pub fn owner_only() -> Self {
Self {
root: MintOwnerOnly::root(),
components: vec![MintOwnerOnly.into()],
}
}
pub fn custom<I>(root: AccountProcedureRoot, components: I) -> Result<Self, MintPolicyError>
where
I: IntoIterator,
I::Item: Into<AccountComponent>,
{
let components: Vec<AccountComponent> = components.into_iter().map(Into::into).collect();
if !components.iter().any(|component| component.has_procedure(root)) {
return Err(MintPolicyError::RootNotInComponents);
}
Ok(Self { root, components })
}
pub fn root(&self) -> AccountProcedureRoot {
self.root
}
}
impl Default for MintPolicy {
fn default() -> Self {
Self::owner_only()
}
}
impl IntoIterator for MintPolicy {
type Item = AccountComponent;
type IntoIter = alloc::vec::IntoIter<AccountComponent>;
fn into_iter(self) -> Self::IntoIter {
self.components.into_iter()
}
}