radix_native_sdk/component/
object.rs1use crate::modules::metadata::Metadata;
2use crate::modules::role_assignment::RoleAssignment;
3use radix_common::data::scrypto::scrypto_encode;
4use radix_common::prelude::ScryptoEncode;
5use radix_common::types::GlobalAddress;
6use radix_engine_interface::api::*;
7use radix_engine_interface::object_modules::metadata::{
8 MetadataSetInput, MetadataVal, METADATA_SET_IDENT,
9};
10use radix_engine_interface::object_modules::ModuleConfig;
11use radix_engine_interface::prelude::*;
12use radix_engine_interface::types::NodeId;
13use radix_rust::indexmap;
14use sbor::rust::prelude::*;
15use sbor::rust::prelude::{Debug, ToOwned};
16
17#[derive(Debug)]
18pub struct BorrowedObject(pub NodeId);
19
20impl BorrowedObject {
21 pub fn new<T>(node_id: T) -> Self
22 where
23 T: Into<[u8; NodeId::LENGTH]>,
24 {
25 Self(NodeId(node_id.into()))
26 }
27
28 pub fn set_metadata<Y: SystemApi<E>, E: SystemApiError, S: AsRef<str>, V: MetadataVal>(
29 &mut self,
30 key: S,
31 value: V,
32 api: &mut Y,
33 ) -> Result<(), E> {
34 api.call_module_method(
35 &self.0,
36 AttachedModuleId::Metadata,
37 METADATA_SET_IDENT,
38 scrypto_encode(&MetadataSetInput {
39 key: key.as_ref().to_owned(),
40 value: value.to_metadata_value(),
41 })
42 .unwrap(),
43 )?;
44
45 Ok(())
46 }
47}
48
49pub fn globalize_object<Y: SystemApi<E>, E: SystemApiError>(
50 object_id: NodeId,
51 owner_role: OwnerRole,
52 address_reservation: GlobalAddressReservation,
53 main_roles: RoleAssignmentInit,
54 metadata: ModuleConfig<MetadataInit>,
55 api: &mut Y,
56) -> Result<GlobalAddress, E> {
57 let role_assignment = {
58 let roles = indexmap!(
59 ModuleId::Main => main_roles,
60 ModuleId::Metadata => metadata.roles,
61 );
62 RoleAssignment::create(owner_role, roles, api)?.0 .0
63 };
64
65 let metadata = Metadata::create_with_data(metadata.init, api)?.0;
66
67 let address = api.globalize(
68 object_id,
69 indexmap!(
70 AttachedModuleId::RoleAssignment => role_assignment,
71 AttachedModuleId::Metadata => metadata,
72 ),
73 Some(address_reservation),
74 )?;
75
76 Ok(address)
77}
78
79#[allow(clippy::too_many_arguments)]
80pub fn globalize_object_with_inner_object_and_event<
81 Y: SystemApi<E>,
82 E: SystemApiError,
83 V: ScryptoEncode,
84>(
85 object_id: NodeId,
86 owner_role: OwnerRole,
87 address_reservation: GlobalAddressReservation,
88 main_roles: RoleAssignmentInit,
89 metadata: ModuleConfig<MetadataInit>,
90 inner_object_bp: &str,
91 inner_object_fields: IndexMap<FieldIndex, FieldValue>,
92 event_name: &str,
93 event: V,
94 api: &mut Y,
95) -> Result<(GlobalAddress, NodeId), E> {
96 let role_assignment = {
97 let roles = indexmap!(
98 ModuleId::Main => main_roles,
99 ModuleId::Metadata => metadata.roles,
100 );
101 RoleAssignment::create(owner_role, roles, api)?.0 .0
102 };
103 let metadata = Metadata::create_with_data(metadata.init, api)?.0;
104
105 let (address, inner_object) = api
106 .globalize_with_address_and_create_inner_object_and_emit_event(
107 object_id,
108 indexmap!(
109 AttachedModuleId::RoleAssignment => role_assignment,
110 AttachedModuleId::Metadata => metadata,
111 ),
112 address_reservation,
113 inner_object_bp,
114 inner_object_fields,
115 event_name,
116 scrypto_encode(&event).unwrap(),
117 )?;
118
119 Ok((address, inner_object))
120}