radix_engine_interface/blueprints/package/
invocations.rs

1use crate::blueprints::resource::*;
2use crate::internal_prelude::*;
3use crate::types::*;
4use radix_blueprint_schema_init::TypeRef;
5use radix_blueprint_schema_init::{
6    BlueprintCollectionSchema, BlueprintKeyValueSchema, FunctionSchemaInit,
7};
8use radix_blueprint_schema_init::{BlueprintFunctionsSchemaInit, ReceiverInfo};
9use radix_blueprint_schema_init::{BlueprintSchemaInit, BlueprintStateSchemaInit, FieldSchema};
10use radix_common::data::manifest::model::ManifestAddressReservation;
11use radix_common::data::manifest::model::ManifestBlobRef;
12use radix_engine_interface::object_modules::metadata::MetadataInit;
13use sbor::basic_well_known_types::ANY_TYPE;
14use sbor::rust::prelude::*;
15use sbor::LocalTypeId;
16
17pub const PACKAGE_BLUEPRINT: &str = "Package";
18
19pub const PACKAGE_PUBLISH_WASM_IDENT: &str = "publish_wasm";
20
21#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor, ManifestSbor)]
22pub struct PackagePublishWasmInput {
23    pub definition: PackageDefinition,
24    pub code: Vec<u8>,
25    pub metadata: MetadataInit,
26}
27
28#[derive(Debug, Clone, Eq, PartialEq, ManifestSbor)]
29pub struct PackagePublishWasmManifestInput {
30    pub definition: PackageDefinition,
31    pub code: ManifestBlobRef,
32    pub metadata: MetadataInit,
33}
34
35pub type PackagePublishWasmOutput = (PackageAddress, Bucket);
36
37pub const PACKAGE_PUBLISH_WASM_ADVANCED_IDENT: &str = "publish_wasm_advanced";
38
39#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor)]
40pub struct PackagePublishWasmAdvancedInput {
41    pub owner_role: OwnerRole,
42    pub definition: PackageDefinition,
43    pub code: Vec<u8>,
44    pub metadata: MetadataInit,
45    pub package_address: Option<GlobalAddressReservation>,
46}
47
48#[derive(Debug, Clone, Eq, PartialEq, ManifestSbor)]
49pub struct PackagePublishWasmAdvancedManifestInput {
50    pub owner_role: OwnerRole,
51    pub definition: PackageDefinition,
52    pub code: ManifestBlobRef,
53    pub metadata: MetadataInit,
54    pub package_address: Option<ManifestAddressReservation>,
55}
56
57pub type PackagePublishWasmAdvancedOutput = PackageAddress;
58
59pub const PACKAGE_PUBLISH_NATIVE_IDENT: &str = "publish_native";
60
61#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor)]
62pub struct PackagePublishNativeInput {
63    pub definition: PackageDefinition,
64    pub native_package_code_id: u64,
65    pub metadata: MetadataInit,
66    pub package_address: Option<GlobalAddressReservation>,
67}
68
69#[derive(Debug, Clone, Eq, PartialEq, ManifestSbor)]
70pub struct PackagePublishNativeManifestInput {
71    pub definition: PackageDefinition,
72    pub native_package_code_id: u64,
73    pub metadata: MetadataInit,
74    pub package_address: Option<ManifestAddressReservation>,
75}
76
77pub type PackagePublishNativeOutput = PackageAddress;
78
79pub const PACKAGE_CLAIM_ROYALTIES_IDENT: &str = "PackageRoyalty_claim_royalties";
80
81#[cfg_attr(
82    feature = "fuzzing",
83    derive(arbitrary::Arbitrary, serde::Serialize, serde::Deserialize)
84)]
85#[derive(
86    Debug, Clone, Eq, PartialEq, ScryptoSbor, ManifestCategorize, ManifestEncode, ManifestDecode,
87)]
88pub struct PackageClaimRoyaltiesInput {}
89
90pub type PackageClaimRoyaltiesManifestInput = PackageClaimRoyaltiesInput;
91
92pub type PackageClaimRoyaltiesOutput = Bucket;
93
94/// The set of blueprints and their associated definitions for a package
95#[derive(Debug, Clone, Eq, PartialEq, Default, ScryptoSbor, ManifestSbor)]
96pub struct PackageDefinition {
97    pub blueprints: IndexMap<String, BlueprintDefinitionInit>,
98}
99
100/// A blueprint may be specified as either an Outer or Inner Blueprint. If an inner blueprint, an associated outer
101/// blueprint must be specified and only a component of the outer blueprint may instantiate the inner blueprint.
102/// Inner blueprint components may access the state of its outer blueprint component directly.
103#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor, ManifestSbor)]
104pub enum BlueprintType {
105    Outer,
106    Inner { outer_blueprint: String },
107}
108
109impl Default for BlueprintType {
110    fn default() -> Self {
111        BlueprintType::Outer
112    }
113}
114
115/// Structure which defines static interface qualities of a Blueprint
116#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor, ManifestSbor)]
117pub struct BlueprintDefinitionInit {
118    /// Whether the blueprint is an Outer or Inner Blueprint
119    pub blueprint_type: BlueprintType,
120
121    /// If true, all components of this blueprint type may not be persisted.
122    pub is_transient: bool,
123
124    /// The set of all possible features a component instantiator may specify.
125    pub feature_set: IndexSet<String>,
126
127    /// A set of addresses which will always be visible to call frames of this blueprint.
128    pub dependencies: IndexSet<GlobalAddress>,
129
130    /// The schema of the blueprint including interface, state, and events
131    pub schema: BlueprintSchemaInit,
132
133    /// Blueprint module: Royalty configuration
134    pub royalty_config: PackageRoyaltyConfig,
135
136    /// Blueprint module: Auth configuration such as role definitions
137    pub auth_config: AuthConfig,
138}
139
140impl Default for BlueprintDefinitionInit {
141    fn default() -> Self {
142        Self {
143            blueprint_type: BlueprintType::default(),
144            is_transient: false,
145            feature_set: IndexSet::default(),
146            dependencies: IndexSet::default(),
147            schema: BlueprintSchemaInit::default(),
148            royalty_config: PackageRoyaltyConfig::default(),
149            auth_config: AuthConfig::default(),
150        }
151    }
152}
153
154#[derive(Debug, Clone, Eq, PartialEq, Default, ScryptoSbor, ManifestSbor)]
155pub struct AuthConfig {
156    pub function_auth: FunctionAuth,
157    pub method_auth: MethodAuthTemplate,
158}
159
160#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor, ManifestSbor)]
161pub enum FunctionAuth {
162    /// All functions are accessible
163    AllowAll,
164    /// Functions are protected by an access rule
165    AccessRules(IndexMap<String, AccessRule>),
166    /// Only the root call frame may call all functions.
167    /// Used primarily for transaction processor functions, any other use would
168    /// essentially make the function inaccessible for any normal transaction
169    RootOnly,
170}
171
172impl Default for FunctionAuth {
173    fn default() -> Self {
174        FunctionAuth::AllowAll
175    }
176}
177
178#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor, ManifestSbor)]
179pub enum MethodAuthTemplate {
180    /// All methods are accessible
181    AllowAll,
182    /// Methods are protected by a static method to roles mapping
183    StaticRoleDefinition(StaticRoleDefinition),
184}
185
186impl Default for MethodAuthTemplate {
187    fn default() -> Self {
188        MethodAuthTemplate::AllowAll
189    }
190}
191
192#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor, ManifestSbor)]
193pub enum RoleSpecification {
194    /// Roles are specified in the current blueprint and defined in the instantiated object.
195    /// The map contains keys for all possible roles, mapping to a list of roles which may update
196    /// the access rule for each role.
197    Normal(IndexMap<RoleKey, RoleList>),
198    /// Roles are specified in the *outer* blueprint and defined in the instantiated *outer* object.
199    /// This may only be used by inner blueprints and is currently used by the Vault blueprints
200    UseOuter,
201}
202
203#[derive(Debug, Clone, Eq, PartialEq, ScryptoSbor, ManifestSbor)]
204pub struct StaticRoleDefinition {
205    pub roles: RoleSpecification,
206    pub methods: IndexMap<MethodKey, MethodAccessibility>,
207}
208
209impl Default for StaticRoleDefinition {
210    fn default() -> Self {
211        Self {
212            methods: index_map_new(),
213            roles: RoleSpecification::Normal(index_map_new()),
214        }
215    }
216}
217
218impl PackageDefinition {
219    // For testing only
220    pub fn new_single_function_test_definition(
221        blueprint_name: &str,
222        function_name: &str,
223    ) -> PackageDefinition {
224        Self::new_functions_only_test_definition(
225            blueprint_name,
226            vec![(
227                function_name,
228                format!("{}_{}", blueprint_name, function_name).as_str(),
229                false,
230            )],
231        )
232    }
233
234    // For testing only
235    pub fn new_roles_only_test_definition(
236        blueprint_name: &str,
237        roles: IndexMap<RoleKey, RoleList>,
238    ) -> PackageDefinition {
239        let mut blueprints = index_map_new();
240        blueprints.insert(
241            blueprint_name.to_string(),
242            BlueprintDefinitionInit {
243                auth_config: AuthConfig {
244                    function_auth: FunctionAuth::AllowAll,
245                    method_auth: MethodAuthTemplate::StaticRoleDefinition(StaticRoleDefinition {
246                        roles: RoleSpecification::Normal(roles),
247                        ..Default::default()
248                    }),
249                },
250                ..Default::default()
251            },
252        );
253        PackageDefinition { blueprints }
254    }
255
256    // For testing only
257    pub fn new_functions_only_test_definition(
258        blueprint_name: &str,
259        functions: Vec<(&str, &str, bool)>,
260    ) -> PackageDefinition {
261        let mut blueprints = index_map_new();
262        blueprints.insert(
263            blueprint_name.to_string(),
264            BlueprintDefinitionInit {
265                schema: BlueprintSchemaInit {
266                    functions: BlueprintFunctionsSchemaInit {
267                        functions: functions
268                            .into_iter()
269                            .map(|(function_name, export_name, has_receiver)| {
270                                let schema = FunctionSchemaInit {
271                                    receiver: if has_receiver {
272                                        Some(ReceiverInfo::normal_ref())
273                                    } else {
274                                        None
275                                    },
276                                    input: TypeRef::Static(LocalTypeId::WellKnown(ANY_TYPE)),
277                                    output: TypeRef::Static(LocalTypeId::WellKnown(ANY_TYPE)),
278                                    export: export_name.to_string(),
279                                };
280                                (function_name.to_string(), schema)
281                            })
282                            .collect(),
283                    },
284                    ..Default::default()
285                },
286                ..Default::default()
287            },
288        );
289        PackageDefinition { blueprints }
290    }
291
292    // For testing only
293    pub fn new_with_fields_test_definition(
294        blueprint_name: &str,
295        num_fields: usize,
296        functions: Vec<(&str, &str, bool)>,
297    ) -> PackageDefinition {
298        let mut blueprints = index_map_new();
299        blueprints.insert(
300            blueprint_name.to_string(),
301            BlueprintDefinitionInit {
302                schema: BlueprintSchemaInit {
303                    state: BlueprintStateSchemaInit {
304                        fields: (0..num_fields)
305                            .map(|_| FieldSchema::static_field(LocalTypeId::WellKnown(ANY_TYPE)))
306                            .collect(),
307                        ..Default::default()
308                    },
309                    functions: BlueprintFunctionsSchemaInit {
310                        functions: functions
311                            .into_iter()
312                            .map(|(function_name, export_name, has_receiver)| {
313                                let schema = FunctionSchemaInit {
314                                    receiver: if has_receiver {
315                                        Some(ReceiverInfo::normal_ref())
316                                    } else {
317                                        None
318                                    },
319                                    input: TypeRef::Static(LocalTypeId::WellKnown(ANY_TYPE)),
320                                    output: TypeRef::Static(LocalTypeId::WellKnown(ANY_TYPE)),
321                                    export: export_name.to_string(),
322                                };
323                                (function_name.to_string(), schema)
324                            })
325                            .collect(),
326                        ..Default::default()
327                    },
328                    ..Default::default()
329                },
330                ..Default::default()
331            },
332        );
333        PackageDefinition { blueprints }
334    }
335
336    pub fn new_with_field_test_definition(
337        blueprint_name: &str,
338        functions: Vec<(&str, &str, bool)>,
339    ) -> PackageDefinition {
340        Self::new_with_fields_test_definition(blueprint_name, 1, functions)
341    }
342
343    // For testing only
344    pub fn new_with_kv_collection_test_definition(
345        blueprint_name: &str,
346        functions: Vec<(&str, &str, bool)>,
347    ) -> PackageDefinition {
348        let mut blueprints = index_map_new();
349        blueprints.insert(
350            blueprint_name.to_string(),
351            BlueprintDefinitionInit {
352                schema: BlueprintSchemaInit {
353                    state: BlueprintStateSchemaInit {
354                        collections: vec![BlueprintCollectionSchema::KeyValueStore(
355                            BlueprintKeyValueSchema {
356                                key: TypeRef::Static(LocalTypeId::WellKnown(ANY_TYPE)),
357                                value: TypeRef::Static(LocalTypeId::WellKnown(ANY_TYPE)),
358                                allow_ownership: true,
359                            },
360                        )],
361                        ..Default::default()
362                    },
363                    functions: BlueprintFunctionsSchemaInit {
364                        functions: functions
365                            .into_iter()
366                            .map(|(function_name, export_name, has_receiver)| {
367                                let schema = FunctionSchemaInit {
368                                    receiver: if has_receiver {
369                                        Some(ReceiverInfo::normal_ref())
370                                    } else {
371                                        None
372                                    },
373                                    input: TypeRef::Static(LocalTypeId::WellKnown(ANY_TYPE)),
374                                    output: TypeRef::Static(LocalTypeId::WellKnown(ANY_TYPE)),
375                                    export: export_name.to_string(),
376                                };
377                                (function_name.to_string(), schema)
378                            })
379                            .collect(),
380                        ..Default::default()
381                    },
382                    ..Default::default()
383                },
384                ..Default::default()
385            },
386        );
387        PackageDefinition { blueprints }
388    }
389}