1use radix_common::constants::RESOURCE_PACKAGE;
2use radix_common::data::scrypto::model::*;
3use radix_common::data::scrypto::{
4 scrypto_decode, scrypto_encode, ScryptoDecode, ScryptoEncode, ScryptoValue,
5};
6use radix_common::math::Decimal;
7use radix_common::traits::NonFungibleData;
8use radix_common::ScryptoSbor;
9use radix_engine_interface::api::*;
10use radix_engine_interface::blueprints::resource::*;
11use radix_engine_interface::object_modules::metadata::MetadataInit;
12use radix_engine_interface::object_modules::ModuleConfig;
13use radix_engine_interface::types::*;
14use sbor::rust::prelude::*;
15
16#[derive(Debug, PartialEq, Eq, ScryptoSbor, Clone)]
18pub struct ResourceManager(pub ResourceAddress);
19
20impl ResourceManager {
21 pub fn new_fungible<Y: SystemBlueprintApi<E>, E: SystemApiError, M: Into<MetadataInit>>(
22 owner_role: OwnerRole,
23 track_total_supply: bool,
24 divisibility: u8,
25 resource_roles: FungibleResourceRoles,
26 metadata: M,
27 address_reservation: Option<GlobalAddressReservation>,
28 api: &mut Y,
29 ) -> Result<Self, E> {
30 let metadata = ModuleConfig {
31 init: metadata.into(),
32 roles: RoleAssignmentInit::default(),
33 };
34
35 let result = api.call_function(
36 RESOURCE_PACKAGE,
37 FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
38 FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
39 scrypto_encode(&FungibleResourceManagerCreateInput {
40 owner_role,
41 track_total_supply,
42 metadata,
43 resource_roles,
44 divisibility,
45 address_reservation,
46 })
47 .unwrap(),
48 )?;
49
50 let resource_address = scrypto_decode(result.as_slice()).unwrap();
51 Ok(ResourceManager(resource_address))
52 }
53
54 pub fn new_fungible_with_initial_supply<
55 Y: SystemBlueprintApi<E>,
56 E: SystemApiError,
57 M: Into<MetadataInit>,
58 >(
59 owner_role: OwnerRole,
60 track_total_supply: bool,
61 divisibility: u8,
62 initial_supply: Decimal,
63 resource_roles: FungibleResourceRoles,
64 metadata: M,
65 address_reservation: Option<GlobalAddressReservation>,
66 api: &mut Y,
67 ) -> Result<(Self, FungibleBucket), E> {
68 let metadata = ModuleConfig {
69 init: metadata.into(),
70 roles: RoleAssignmentInit::default(),
71 };
72
73 let result = api.call_function(
74 RESOURCE_PACKAGE,
75 FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
76 FUNGIBLE_RESOURCE_MANAGER_CREATE_WITH_INITIAL_SUPPLY_IDENT,
77 scrypto_encode(&FungibleResourceManagerCreateWithInitialSupplyInput {
78 owner_role,
79 track_total_supply,
80 metadata,
81 resource_roles,
82 divisibility,
83 initial_supply,
84 address_reservation,
85 })
86 .unwrap(),
87 )?;
88 let (resource_address, bucket): (ResourceAddress, FungibleBucket) =
89 scrypto_decode(result.as_slice()).unwrap();
90 Ok((ResourceManager(resource_address), bucket))
91 }
92
93 pub fn new_non_fungible<
94 N: NonFungibleData,
97 Y: SystemBlueprintApi<E>,
98 E: SystemApiError,
99 M: Into<MetadataInit>,
100 >(
101 owner_role: OwnerRole,
102 id_type: NonFungibleIdType,
103 track_total_supply: bool,
104 resource_roles: NonFungibleResourceRoles,
105 metadata: M,
106 address_reservation: Option<GlobalAddressReservation>,
107 api: &mut Y,
108 ) -> Result<Self, E> {
109 let metadata = ModuleConfig {
110 init: metadata.into(),
111 roles: RoleAssignmentInit::default(),
112 };
113
114 let non_fungible_schema =
115 NonFungibleDataSchema::new_local_without_self_package_replacement::<N>();
116 let result = api.call_function(
117 RESOURCE_PACKAGE,
118 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
119 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
120 scrypto_encode(&NonFungibleResourceManagerCreateInput {
121 owner_role,
122 id_type,
123 track_total_supply,
124 non_fungible_schema,
125 resource_roles,
126 metadata,
127 address_reservation,
128 })
129 .unwrap(),
130 )?;
131 let resource_address = scrypto_decode(result.as_slice()).unwrap();
132 Ok(ResourceManager(resource_address))
133 }
134
135 pub fn mint_non_fungible_single_ruid<
137 Y: SystemObjectApi<E>,
138 E: SystemApiError,
139 T: ScryptoEncode,
140 >(
141 &self,
142 data: T,
143 api: &mut Y,
144 ) -> Result<(NonFungibleBucket, NonFungibleLocalId), E> {
145 let value: ScryptoValue = scrypto_decode(&scrypto_encode(&data).unwrap()).unwrap();
146
147 let rtn = api.call_method(
148 self.0.as_node_id(),
149 NON_FUNGIBLE_RESOURCE_MANAGER_MINT_SINGLE_RUID_IDENT,
150 scrypto_encode(&NonFungibleResourceManagerMintSingleRuidInput { entry: value })
151 .unwrap(),
152 )?;
153
154 Ok(scrypto_decode(&rtn).unwrap())
155 }
156
157 pub fn mint_non_fungible<Y: SystemObjectApi<E>, E: SystemApiError, T: ScryptoEncode>(
159 &self,
160 data: IndexMap<NonFungibleLocalId, T>,
161 api: &mut Y,
162 ) -> Result<NonFungibleBucket, E> {
163 let rtn = api.call_method(
164 self.0.as_node_id(),
165 NON_FUNGIBLE_RESOURCE_MANAGER_MINT_IDENT,
166 scrypto_encode(&NonFungibleResourceManagerMintInput {
167 entries: data
168 .into_iter()
169 .map(|(key, value)| {
170 (
171 key,
172 (scrypto_decode(&scrypto_encode(&value).unwrap()).unwrap(),),
173 )
174 })
175 .collect(),
176 })
177 .unwrap(),
178 )?;
179
180 Ok(scrypto_decode(&rtn).unwrap())
181 }
182
183 pub fn mint_fungible<Y: SystemObjectApi<E>, E: SystemApiError>(
185 &mut self,
186 amount: Decimal,
187 api: &mut Y,
188 ) -> Result<FungibleBucket, E> {
189 let rtn = api.call_method(
190 self.0.as_node_id(),
191 FUNGIBLE_RESOURCE_MANAGER_MINT_IDENT,
192 scrypto_encode(&FungibleResourceManagerMintInput { amount }).unwrap(),
193 )?;
194
195 Ok(scrypto_decode(&rtn).unwrap())
196 }
197
198 pub fn get_non_fungible_data<Y: SystemObjectApi<E>, E: SystemApiError, T: ScryptoDecode>(
199 &self,
200 id: NonFungibleLocalId,
201 api: &mut Y,
202 ) -> Result<T, E> {
203 let rtn = api.call_method(
204 self.0.as_node_id(),
205 NON_FUNGIBLE_RESOURCE_MANAGER_GET_NON_FUNGIBLE_IDENT,
206 scrypto_encode(&NonFungibleResourceManagerGetNonFungibleInput { id }).unwrap(),
207 )?;
208
209 let data = scrypto_decode(&rtn).unwrap();
210 Ok(data)
211 }
212
213 pub fn resource_type<Y: SystemObjectApi<E>, E: SystemApiError>(
214 &self,
215 api: &mut Y,
216 ) -> Result<ResourceType, E> {
217 let rtn = api.call_method(
218 self.0.as_node_id(),
219 RESOURCE_MANAGER_GET_RESOURCE_TYPE_IDENT,
220 scrypto_encode(&ResourceManagerGetResourceTypeInput {}).unwrap(),
221 )?;
222
223 Ok(scrypto_decode(&rtn).unwrap())
224 }
225
226 pub fn burn<Y: SystemObjectApi<E>, E: SystemApiError>(
227 &mut self,
228 bucket: impl Into<Bucket>,
229 api: &mut Y,
230 ) -> Result<(), E> {
231 let bucket = bucket.into();
232 let rtn = api.call_method(
233 self.0.as_node_id(),
234 RESOURCE_MANAGER_BURN_IDENT,
235 scrypto_encode(&ResourceManagerBurnInput { bucket }).unwrap(),
236 )?;
237 Ok(scrypto_decode(&rtn).unwrap())
238 }
239
240 pub fn package_burn<Y: SystemObjectApi<E>, E: SystemApiError>(
241 &mut self,
242 bucket: impl Into<Bucket>,
243 api: &mut Y,
244 ) -> Result<(), E> {
245 let bucket = bucket.into();
246 let rtn = api.call_method(
247 self.0.as_node_id(),
248 RESOURCE_MANAGER_PACKAGE_BURN_IDENT,
249 scrypto_encode(&ResourceManagerPackageBurnInput { bucket }).unwrap(),
250 )?;
251 Ok(scrypto_decode(&rtn).unwrap())
252 }
253
254 pub fn total_supply<Y: SystemObjectApi<E>, E: SystemApiError>(
255 &self,
256 api: &mut Y,
257 ) -> Result<Option<Decimal>, E> {
258 let rtn = api.call_method(
259 self.0.as_node_id(),
260 RESOURCE_MANAGER_GET_TOTAL_SUPPLY_IDENT,
261 scrypto_encode(&ResourceManagerGetTotalSupplyInput {}).unwrap(),
262 )?;
263 Ok(scrypto_decode(&rtn).unwrap())
264 }
265
266 pub fn new_empty_fungible_bucket<Y: SystemObjectApi<E>, E: SystemApiError>(
267 &self,
268 api: &mut Y,
269 ) -> Result<FungibleBucket, E> {
270 Ok(FungibleBucket(self.new_empty_bucket(api)?.into()))
271 }
272
273 pub fn new_empty_non_fungible_bucket<Y: SystemObjectApi<E>, E: SystemApiError>(
274 &self,
275 api: &mut Y,
276 ) -> Result<NonFungibleBucket, E> {
277 Ok(NonFungibleBucket(self.new_empty_bucket(api)?.into()))
278 }
279
280 pub fn new_empty_bucket<Y: SystemObjectApi<E>, E: SystemApiError>(
281 &self,
282 api: &mut Y,
283 ) -> Result<Bucket, E> {
284 let rtn = api.call_method(
285 self.0.as_node_id(),
286 RESOURCE_MANAGER_CREATE_EMPTY_BUCKET_IDENT,
287 scrypto_encode(&ResourceManagerCreateEmptyBucketInput {}).unwrap(),
288 )?;
289 Ok(scrypto_decode(&rtn).unwrap())
290 }
291
292 pub fn new_empty_vault<Y: SystemObjectApi<E>, E: SystemApiError>(
293 &self,
294 api: &mut Y,
295 ) -> Result<Own, E> {
296 let rtn = api.call_method(
297 self.0.as_node_id(),
298 RESOURCE_MANAGER_CREATE_EMPTY_VAULT_IDENT,
299 scrypto_encode(&ResourceManagerCreateEmptyVaultInput {}).unwrap(),
300 )?;
301 Ok(scrypto_decode(&rtn).unwrap())
302 }
303}