Skip to main content

miden_standards/account/access/pausable/
manager.rs

1use miden_protocol::account::component::{AccountComponentCode, AccountComponentMetadata};
2use miden_protocol::account::{AccountComponent, AccountProcedureRoot};
3
4use crate::account::account_component_code;
5use crate::procedure_root;
6
7// PAUSABLE MANAGER COMPONENT
8// ================================================================================================
9
10account_component_code!(PAUSABLE_MANAGER_CODE, "access/pausable/manager.masl");
11
12procedure_root!(
13    PAUSABLE_MANAGER_PAUSE,
14    PausableManager::NAME,
15    PausableManager::PAUSE_PROC_NAME,
16    PausableManager::code()
17);
18
19procedure_root!(
20    PAUSABLE_MANAGER_UNPAUSE,
21    PausableManager::NAME,
22    PausableManager::UNPAUSE_PROC_NAME,
23    PausableManager::code()
24);
25
26/// Account component exposing `pause` and `unpause` admin procedures, gated by the account-wide
27/// [`crate::account::access::Authority`] component via `exec.authority::assert_authorized`.
28///
29/// `PausableManager` works uniformly with every standard access scheme:
30/// - [`crate::account::access::AccessControl::AuthControlled`] →
31///   [`crate::account::access::Authority::AuthControlled`] gates pause / unpause via the account's
32///   own auth component.
33/// - [`crate::account::access::AccessControl::Ownable2Step`] →
34///   [`crate::account::access::Authority::OwnerControlled`] requires the Ownable2Step owner.
35/// - [`crate::account::access::AccessControl::Rbac`] →
36///   [`crate::account::access::Authority::RbacControlled { role }`] requires the single configured
37///   role for both pause and unpause (no PAUSER / UNPAUSER separation — emergency pause is a
38///   coarse-grained capability).
39///
40/// Companion components required:
41/// - [`crate::account::access::Authority`] — installed automatically by the
42///   [`crate::account::access::AccessControl`] enum.
43/// - [`super::Pausable`] — provides the `is_paused` storage slot that pause / unpause write to.
44#[derive(Debug, Clone, Copy, Default)]
45pub struct PausableManager;
46
47impl PausableManager {
48    /// The name of the component.
49    pub const NAME: &'static str = "miden::standards::components::access::pausable::manager";
50
51    pub const PAUSE_PROC_NAME: &'static str = "pause";
52    pub const UNPAUSE_PROC_NAME: &'static str = "unpause";
53
54    /// Returns the [`AccountComponentCode`] of this component.
55    pub fn code() -> &'static AccountComponentCode {
56        &PAUSABLE_MANAGER_CODE
57    }
58
59    /// Returns the procedure root of the `pause` procedure exposed by this component.
60    pub fn pause_root() -> AccountProcedureRoot {
61        *PAUSABLE_MANAGER_PAUSE
62    }
63
64    /// Returns the procedure root of the `unpause` procedure exposed by this component.
65    pub fn unpause_root() -> AccountProcedureRoot {
66        *PAUSABLE_MANAGER_UNPAUSE
67    }
68}
69
70impl From<PausableManager> for AccountComponent {
71    fn from(_: PausableManager) -> Self {
72        let metadata = AccountComponentMetadata::new(PausableManager::NAME).with_description(
73            "PausableManager: pause / unpause admin procedures gated by the account-wide \
74             Authority component. Requires the Pausable companion component for storage and the \
75             Authority component for auth dispatch.",
76        );
77
78        AccountComponent::new(PausableManager::code().clone(), vec![], metadata).expect(
79            "pausable manager component should satisfy the requirements of a valid account component",
80        )
81    }
82}