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