miden_standards/account/mint_policies/
auth_controlled.rs1use miden_protocol::Word;
2use miden_protocol::account::component::{
3 AccountComponentMetadata,
4 FeltSchema,
5 SchemaType,
6 StorageSchema,
7 StorageSlotSchema,
8};
9use miden_protocol::account::{
10 AccountComponent,
11 AccountType,
12 StorageMap,
13 StorageMapKey,
14 StorageSlot,
15 StorageSlotName,
16};
17use miden_protocol::utils::sync::LazyLock;
18
19use super::MintPolicyAuthority;
20use crate::account::components::auth_controlled_library;
21use crate::procedure_digest;
22
23procedure_digest!(
27 ALLOW_ALL_POLICY_ROOT,
28 AuthControlled::NAME,
29 AuthControlled::ALLOW_ALL_PROC_NAME,
30 auth_controlled_library
31);
32
33static ACTIVE_MINT_POLICY_PROC_ROOT_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
34 StorageSlotName::new("miden::standards::mint_policy_manager::active_policy_proc_root")
35 .expect("storage slot name should be valid")
36});
37static ALLOWED_MINT_POLICY_PROC_ROOTS_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
38 StorageSlotName::new("miden::standards::mint_policy_manager::allowed_policy_proc_roots")
39 .expect("storage slot name should be valid")
40});
41#[derive(Debug, Clone, Copy)]
57pub struct AuthControlled {
58 initial_policy_root: Word,
59}
60
61#[derive(Debug, Clone, Copy, Default)]
63pub enum AuthControlledInitConfig {
64 #[default]
66 AllowAll,
67 CustomInitialRoot(Word),
69}
70
71impl AuthControlled {
72 pub const NAME: &'static str = "miden::standards::components::mint_policies::auth_controlled";
74
75 const ALLOW_ALL_PROC_NAME: &str = "allow_all";
76
77 pub fn new(policy: AuthControlledInitConfig) -> Self {
79 let initial_policy_root = match policy {
80 AuthControlledInitConfig::AllowAll => Self::allow_all_policy_root(),
81 AuthControlledInitConfig::CustomInitialRoot(root) => root,
82 };
83
84 Self { initial_policy_root }
85 }
86
87 pub fn allow_all() -> Self {
90 Self::new(AuthControlledInitConfig::AllowAll)
91 }
92
93 pub fn active_policy_proc_root_slot() -> &'static StorageSlotName {
95 &ACTIVE_MINT_POLICY_PROC_ROOT_SLOT_NAME
96 }
97
98 pub fn allowed_policy_proc_roots_slot() -> &'static StorageSlotName {
100 &ALLOWED_MINT_POLICY_PROC_ROOTS_SLOT_NAME
101 }
102
103 pub fn active_policy_proc_root_slot_schema() -> (StorageSlotName, StorageSlotSchema) {
105 (
106 Self::active_policy_proc_root_slot().clone(),
107 StorageSlotSchema::value(
108 "The procedure root of the active mint policy in the mint policy auth controlled component",
109 [
110 FeltSchema::felt("proc_root_0"),
111 FeltSchema::felt("proc_root_1"),
112 FeltSchema::felt("proc_root_2"),
113 FeltSchema::felt("proc_root_3"),
114 ],
115 ),
116 )
117 }
118
119 pub fn allowed_policy_proc_roots_slot_schema() -> (StorageSlotName, StorageSlotSchema) {
121 (
122 Self::allowed_policy_proc_roots_slot().clone(),
123 StorageSlotSchema::map(
124 "The set of allowed mint policy procedure roots in the mint policy auth controlled component",
125 SchemaType::native_word(),
126 SchemaType::native_word(),
127 ),
128 )
129 }
130
131 pub fn policy_authority_slot() -> &'static StorageSlotName {
133 MintPolicyAuthority::slot()
134 }
135
136 pub fn policy_authority_slot_schema() -> (StorageSlotName, StorageSlotSchema) {
138 (
139 Self::policy_authority_slot().clone(),
140 StorageSlotSchema::value(
141 "Policy authority mode (AuthControlled = tx auth, OwnerControlled = external owner)",
142 [
143 FeltSchema::u8("policy_authority"),
144 FeltSchema::new_void(),
145 FeltSchema::new_void(),
146 FeltSchema::new_void(),
147 ],
148 ),
149 )
150 }
151
152 pub fn allow_all_policy_root() -> Word {
154 *ALLOW_ALL_POLICY_ROOT
155 }
156
157 pub fn mint_policy_authority(&self) -> MintPolicyAuthority {
159 MintPolicyAuthority::AuthControlled
160 }
161}
162
163impl Default for AuthControlled {
164 fn default() -> Self {
165 Self::allow_all()
166 }
167}
168
169impl From<AuthControlled> for AccountComponent {
170 fn from(auth_controlled: AuthControlled) -> Self {
171 let active_policy_proc_root_slot = StorageSlot::with_value(
172 AuthControlled::active_policy_proc_root_slot().clone(),
173 auth_controlled.initial_policy_root,
174 );
175 let allowed_policy_flag = Word::from([1u32, 0, 0, 0]);
176 let allow_all_policy_root = AuthControlled::allow_all_policy_root();
177
178 let mut allowed_policy_entries =
179 vec![(StorageMapKey::from_raw(allow_all_policy_root), allowed_policy_flag)];
180
181 if auth_controlled.initial_policy_root != allow_all_policy_root {
182 allowed_policy_entries.push((
183 StorageMapKey::from_raw(auth_controlled.initial_policy_root),
184 allowed_policy_flag,
185 ));
186 }
187
188 let allowed_policy_proc_roots = StorageMap::with_entries(allowed_policy_entries)
189 .expect("allowed mint policy roots should have unique keys");
190
191 let allowed_policy_proc_roots_slot = StorageSlot::with_map(
192 AuthControlled::allowed_policy_proc_roots_slot().clone(),
193 allowed_policy_proc_roots,
194 );
195 let policy_authority_slot = StorageSlot::from(auth_controlled.mint_policy_authority());
196
197 let storage_schema = StorageSchema::new(vec![
198 AuthControlled::active_policy_proc_root_slot_schema(),
199 AuthControlled::allowed_policy_proc_roots_slot_schema(),
200 AuthControlled::policy_authority_slot_schema(),
201 ])
202 .expect("storage schema should be valid");
203
204 let metadata =
205 AccountComponentMetadata::new(AuthControlled::NAME, [AccountType::FungibleFaucet])
206 .with_description(
207 "Mint policy auth controlled component for network fungible faucets",
208 )
209 .with_storage_schema(storage_schema);
210
211 AccountComponent::new(
212 auth_controlled_library(),
213 vec![
214 active_policy_proc_root_slot,
215 allowed_policy_proc_roots_slot,
216 policy_authority_slot,
217 ],
218 metadata,
219 )
220 .expect(
221 "mint policy auth controlled component should satisfy the requirements of a valid account component",
222 )
223 }
224}