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 #[allow(clippy::too_many_arguments)]
55 pub fn new_fungible_with_initial_supply<
56 Y: SystemBlueprintApi<E>,
57 E: SystemApiError,
58 M: Into<MetadataInit>,
59 >(
60 owner_role: OwnerRole,
61 track_total_supply: bool,
62 divisibility: u8,
63 initial_supply: Decimal,
64 resource_roles: FungibleResourceRoles,
65 metadata: M,
66 address_reservation: Option<GlobalAddressReservation>,
67 api: &mut Y,
68 ) -> Result<(Self, FungibleBucket), E> {
69 let metadata = ModuleConfig {
70 init: metadata.into(),
71 roles: RoleAssignmentInit::default(),
72 };
73
74 let result = api.call_function(
75 RESOURCE_PACKAGE,
76 FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
77 FUNGIBLE_RESOURCE_MANAGER_CREATE_WITH_INITIAL_SUPPLY_IDENT,
78 scrypto_encode(&FungibleResourceManagerCreateWithInitialSupplyInput {
79 owner_role,
80 track_total_supply,
81 metadata,
82 resource_roles,
83 divisibility,
84 initial_supply,
85 address_reservation,
86 })
87 .unwrap(),
88 )?;
89 let (resource_address, bucket): (ResourceAddress, FungibleBucket) =
90 scrypto_decode(result.as_slice()).unwrap();
91 Ok((ResourceManager(resource_address), bucket))
92 }
93
94 pub fn new_non_fungible<
95 N: NonFungibleData,
98 Y: SystemBlueprintApi<E>,
99 E: SystemApiError,
100 M: Into<MetadataInit>,
101 >(
102 owner_role: OwnerRole,
103 id_type: NonFungibleIdType,
104 track_total_supply: bool,
105 resource_roles: NonFungibleResourceRoles,
106 metadata: M,
107 address_reservation: Option<GlobalAddressReservation>,
108 api: &mut Y,
109 ) -> Result<Self, E> {
110 let metadata = ModuleConfig {
111 init: metadata.into(),
112 roles: RoleAssignmentInit::default(),
113 };
114
115 let non_fungible_schema =
116 NonFungibleDataSchema::new_local_without_self_package_replacement::<N>();
117 let result = api.call_function(
118 RESOURCE_PACKAGE,
119 NON_FUNGIBLE_RESOURCE_MANAGER_BLUEPRINT,
120 NON_FUNGIBLE_RESOURCE_MANAGER_CREATE_IDENT,
121 scrypto_encode(&NonFungibleResourceManagerCreateInput {
122 owner_role,
123 id_type,
124 track_total_supply,
125 non_fungible_schema,
126 resource_roles,
127 metadata,
128 address_reservation,
129 })
130 .unwrap(),
131 )?;
132 let resource_address = scrypto_decode(result.as_slice()).unwrap();
133 Ok(ResourceManager(resource_address))
134 }
135
136 pub fn mint_non_fungible_single_ruid<
138 Y: SystemObjectApi<E>,
139 E: SystemApiError,
140 T: ScryptoEncode,
141 >(
142 &self,
143 data: T,
144 api: &mut Y,
145 ) -> Result<(NonFungibleBucket, NonFungibleLocalId), E> {
146 let value: ScryptoValue = scrypto_decode(&scrypto_encode(&data).unwrap()).unwrap();
147
148 let rtn = api.call_method(
149 self.0.as_node_id(),
150 NON_FUNGIBLE_RESOURCE_MANAGER_MINT_SINGLE_RUID_IDENT,
151 scrypto_encode(&NonFungibleResourceManagerMintSingleRuidInput { entry: value })
152 .unwrap(),
153 )?;
154
155 Ok(scrypto_decode(&rtn).unwrap())
156 }
157
158 pub fn mint_non_fungible<Y: SystemObjectApi<E>, E: SystemApiError, T: ScryptoEncode>(
160 &self,
161 data: IndexMap<NonFungibleLocalId, T>,
162 api: &mut Y,
163 ) -> Result<NonFungibleBucket, E> {
164 let rtn = api.call_method(
165 self.0.as_node_id(),
166 NON_FUNGIBLE_RESOURCE_MANAGER_MINT_IDENT,
167 scrypto_encode(&NonFungibleResourceManagerMintInput {
168 entries: data
169 .into_iter()
170 .map(|(key, value)| {
171 (
172 key,
173 (scrypto_decode(&scrypto_encode(&value).unwrap()).unwrap(),),
174 )
175 })
176 .collect(),
177 })
178 .unwrap(),
179 )?;
180
181 Ok(scrypto_decode(&rtn).unwrap())
182 }
183
184 pub fn mint_fungible<Y: SystemObjectApi<E>, E: SystemApiError>(
186 &mut self,
187 amount: Decimal,
188 api: &mut Y,
189 ) -> Result<FungibleBucket, E> {
190 let rtn = api.call_method(
191 self.0.as_node_id(),
192 FUNGIBLE_RESOURCE_MANAGER_MINT_IDENT,
193 scrypto_encode(&FungibleResourceManagerMintInput { amount }).unwrap(),
194 )?;
195
196 Ok(scrypto_decode(&rtn).unwrap())
197 }
198
199 pub fn get_non_fungible_data<Y: SystemObjectApi<E>, E: SystemApiError, T: ScryptoDecode>(
200 &self,
201 id: NonFungibleLocalId,
202 api: &mut Y,
203 ) -> Result<T, E> {
204 let rtn = api.call_method(
205 self.0.as_node_id(),
206 NON_FUNGIBLE_RESOURCE_MANAGER_GET_NON_FUNGIBLE_IDENT,
207 scrypto_encode(&NonFungibleResourceManagerGetNonFungibleInput { id }).unwrap(),
208 )?;
209
210 let data = scrypto_decode(&rtn).unwrap();
211 Ok(data)
212 }
213
214 pub fn resource_type<Y: SystemObjectApi<E>, E: SystemApiError>(
215 &self,
216 api: &mut Y,
217 ) -> Result<ResourceType, E> {
218 let rtn = api.call_method(
219 self.0.as_node_id(),
220 RESOURCE_MANAGER_GET_RESOURCE_TYPE_IDENT,
221 scrypto_encode(&ResourceManagerGetResourceTypeInput {}).unwrap(),
222 )?;
223
224 Ok(scrypto_decode(&rtn).unwrap())
225 }
226
227 pub fn burn<Y: SystemObjectApi<E>, E: SystemApiError>(
228 &mut self,
229 bucket: impl Into<Bucket>,
230 api: &mut Y,
231 ) -> Result<(), E> {
232 let bucket = bucket.into();
233 let rtn = api.call_method(
234 self.0.as_node_id(),
235 RESOURCE_MANAGER_BURN_IDENT,
236 scrypto_encode(&ResourceManagerBurnInput { bucket }).unwrap(),
237 )?;
238 let _: () = scrypto_decode(&rtn).unwrap();
239 Ok(())
240 }
241
242 pub fn package_burn<Y: SystemObjectApi<E>, E: SystemApiError>(
243 &mut self,
244 bucket: impl Into<Bucket>,
245 api: &mut Y,
246 ) -> Result<(), E> {
247 let bucket = bucket.into();
248 let rtn = api.call_method(
249 self.0.as_node_id(),
250 RESOURCE_MANAGER_PACKAGE_BURN_IDENT,
251 scrypto_encode(&ResourceManagerPackageBurnInput { bucket }).unwrap(),
252 )?;
253 let _: () = scrypto_decode(&rtn).unwrap();
254 Ok(())
255 }
256
257 pub fn total_supply<Y: SystemObjectApi<E>, E: SystemApiError>(
258 &self,
259 api: &mut Y,
260 ) -> Result<Option<Decimal>, E> {
261 let rtn = api.call_method(
262 self.0.as_node_id(),
263 RESOURCE_MANAGER_GET_TOTAL_SUPPLY_IDENT,
264 scrypto_encode(&ResourceManagerGetTotalSupplyInput {}).unwrap(),
265 )?;
266 Ok(scrypto_decode(&rtn).unwrap())
267 }
268
269 pub fn new_empty_fungible_bucket<Y: SystemObjectApi<E>, E: SystemApiError>(
270 &self,
271 api: &mut Y,
272 ) -> Result<FungibleBucket, E> {
273 Ok(FungibleBucket(self.new_empty_bucket(api)?))
274 }
275
276 pub fn new_empty_non_fungible_bucket<Y: SystemObjectApi<E>, E: SystemApiError>(
277 &self,
278 api: &mut Y,
279 ) -> Result<NonFungibleBucket, E> {
280 Ok(NonFungibleBucket(self.new_empty_bucket(api)?))
281 }
282
283 pub fn new_empty_bucket<Y: SystemObjectApi<E>, E: SystemApiError>(
284 &self,
285 api: &mut Y,
286 ) -> Result<Bucket, E> {
287 let rtn = api.call_method(
288 self.0.as_node_id(),
289 RESOURCE_MANAGER_CREATE_EMPTY_BUCKET_IDENT,
290 scrypto_encode(&ResourceManagerCreateEmptyBucketInput {}).unwrap(),
291 )?;
292 Ok(scrypto_decode(&rtn).unwrap())
293 }
294
295 pub fn new_empty_vault<Y: SystemObjectApi<E>, E: SystemApiError>(
296 &self,
297 api: &mut Y,
298 ) -> Result<Own, E> {
299 let rtn = api.call_method(
300 self.0.as_node_id(),
301 RESOURCE_MANAGER_CREATE_EMPTY_VAULT_IDENT,
302 scrypto_encode(&ResourceManagerCreateEmptyVaultInput {}).unwrap(),
303 )?;
304 Ok(scrypto_decode(&rtn).unwrap())
305 }
306}