radix_native_sdk/resource/
vault.rs

1use radix_common::data::scrypto::model::*;
2use radix_common::data::scrypto::{scrypto_decode, scrypto_encode};
3use radix_common::math::Decimal;
4use radix_engine_interface::api::*;
5use radix_engine_interface::blueprints::resource::*;
6use radix_engine_interface::types::*;
7use sbor::rust::collections::IndexSet;
8
9// TODO: split impl
10
11pub trait NativeVault {
12    fn create<Y: SystemApi<E>, E: SystemApiError>(
13        resource_address: ResourceAddress,
14        api: &mut Y,
15    ) -> Result<Vault, E>;
16
17    fn put<Y: SystemApi<E>, E: SystemApiError>(
18        &mut self,
19        bucket: Bucket,
20        api: &mut Y,
21    ) -> Result<(), E>;
22
23    fn take<Y: SystemApi<E>, E: SystemApiError>(
24        &mut self,
25        amount: Decimal,
26        api: &mut Y,
27    ) -> Result<Bucket, E>;
28
29    fn take_advanced<Y: SystemApi<E>, E: SystemApiError>(
30        &mut self,
31        amount: Decimal,
32        withdraw_strategy: WithdrawStrategy,
33        api: &mut Y,
34    ) -> Result<Bucket, E>;
35
36    fn take_all<Y: SystemApi<E>, E: SystemApiError>(&mut self, api: &mut Y) -> Result<Bucket, E>;
37
38    fn amount<Y: SystemApi<E>, E: SystemApiError>(&self, api: &mut Y) -> Result<Decimal, E>;
39
40    fn resource_address<Y: SystemApi<E>, E: SystemApiError>(
41        &self,
42        api: &mut Y,
43    ) -> Result<ResourceAddress, E>;
44
45    fn burn<Y: SystemApi<E>, E: SystemApiError>(
46        &mut self,
47        amount: Decimal,
48        api: &mut Y,
49    ) -> Result<(), E>;
50}
51
52pub trait NativeFungibleVault {
53    fn lock_fee<Y: SystemApi<E>, E: SystemApiError>(
54        &mut self,
55        api: &mut Y,
56        amount: Decimal,
57    ) -> Result<(), E>;
58
59    fn lock_contingent_fee<Y: SystemApi<E>, E: SystemApiError>(
60        &mut self,
61        api: &mut Y,
62        amount: Decimal,
63    ) -> Result<(), E>;
64
65    fn create_proof_of_amount<Y: SystemApi<E>, E: SystemApiError>(
66        &self,
67        amount: Decimal,
68        api: &mut Y,
69    ) -> Result<Proof, E>;
70}
71
72pub trait NativeNonFungibleVault {
73    fn non_fungible_local_ids<Y: SystemApi<E>, E: SystemApiError>(
74        &self,
75        limit: u32,
76        api: &mut Y,
77    ) -> Result<IndexSet<NonFungibleLocalId>, E>;
78
79    fn take_non_fungibles<Y: SystemApi<E>, E: SystemApiError>(
80        &mut self,
81        non_fungible_local_ids: IndexSet<NonFungibleLocalId>,
82        api: &mut Y,
83    ) -> Result<Bucket, E>;
84
85    fn create_proof_of_non_fungibles<Y: SystemApi<E>, E: SystemApiError>(
86        &self,
87        ids: IndexSet<NonFungibleLocalId>,
88        api: &mut Y,
89    ) -> Result<Proof, E>;
90
91    fn burn_non_fungibles<Y: SystemApi<E>, E: SystemApiError>(
92        &mut self,
93        non_fungible_local_ids: IndexSet<NonFungibleLocalId>,
94        api: &mut Y,
95    ) -> Result<(), E>;
96
97    fn contains_non_fungible<Y: SystemApi<E>, E: SystemApiError>(
98        &mut self,
99        local_id: NonFungibleLocalId,
100        api: &mut Y,
101    ) -> Result<bool, E>;
102}
103
104impl NativeVault for Vault {
105    fn create<Y: SystemApi<E>, E: SystemApiError>(
106        resource_address: ResourceAddress,
107        api: &mut Y,
108    ) -> Result<Vault, E> {
109        let rtn = api.call_method(
110            resource_address.as_node_id(),
111            RESOURCE_MANAGER_CREATE_EMPTY_VAULT_IDENT,
112            scrypto_encode(&ResourceManagerCreateEmptyVaultInput {}).unwrap(),
113        )?;
114
115        let own: Own = scrypto_decode(&rtn).unwrap();
116        Ok(Self(own))
117    }
118
119    fn put<Y: SystemApi<E>, E: SystemApiError>(
120        &mut self,
121        bucket: Bucket,
122        api: &mut Y,
123    ) -> Result<(), E> {
124        let rtn = api.call_method(
125            self.0.as_node_id(),
126            VAULT_PUT_IDENT,
127            scrypto_encode(&VaultPutInput { bucket }).unwrap(),
128        )?;
129
130        let _: () = scrypto_decode(&rtn).unwrap();
131        Ok(())
132    }
133
134    fn take<Y: SystemApi<E>, E: SystemApiError>(
135        &mut self,
136        amount: Decimal,
137        api: &mut Y,
138    ) -> Result<Bucket, E> {
139        let rtn = api.call_method(
140            self.0.as_node_id(),
141            VAULT_TAKE_IDENT,
142            scrypto_encode(&VaultTakeInput { amount }).unwrap(),
143        )?;
144
145        Ok(scrypto_decode(&rtn).unwrap())
146    }
147
148    fn take_advanced<Y: SystemApi<E>, E: SystemApiError>(
149        &mut self,
150        amount: Decimal,
151        withdraw_strategy: WithdrawStrategy,
152        api: &mut Y,
153    ) -> Result<Bucket, E> {
154        let rtn = api.call_method(
155            self.0.as_node_id(),
156            VAULT_TAKE_ADVANCED_IDENT,
157            scrypto_encode(&VaultTakeAdvancedInput {
158                amount,
159                withdraw_strategy,
160            })
161            .unwrap(),
162        )?;
163
164        Ok(scrypto_decode(&rtn).unwrap())
165    }
166
167    fn take_all<Y: SystemApi<E>, E: SystemApiError>(&mut self, api: &mut Y) -> Result<Bucket, E> {
168        // TODO: Replace with actual take all blueprint method
169        let amount = self.amount(api)?;
170        let rtn = api.call_method(
171            self.0.as_node_id(),
172            VAULT_TAKE_IDENT,
173            scrypto_encode(&VaultTakeInput { amount }).unwrap(),
174        )?;
175
176        Ok(scrypto_decode(&rtn).unwrap())
177    }
178
179    fn amount<Y: SystemApi<E>, E: SystemApiError>(&self, api: &mut Y) -> Result<Decimal, E> {
180        let rtn = api.call_method(
181            self.0.as_node_id(),
182            VAULT_GET_AMOUNT_IDENT,
183            scrypto_encode(&VaultGetAmountInput {}).unwrap(),
184        )?;
185
186        Ok(scrypto_decode(&rtn).unwrap())
187    }
188
189    fn resource_address<Y: SystemApi<E>, E: SystemApiError>(
190        &self,
191        api: &mut Y,
192    ) -> Result<ResourceAddress, E> {
193        let address = api.get_outer_object(self.0.as_node_id())?;
194        Ok(ResourceAddress::try_from(address.into_node_id().0).unwrap())
195    }
196
197    fn burn<Y: SystemApi<E>, E: SystemApiError>(
198        &mut self,
199        amount: Decimal,
200        api: &mut Y,
201    ) -> Result<(), E> {
202        let rtn = api.call_method(
203            self.0.as_node_id(),
204            VAULT_BURN_IDENT,
205            scrypto_encode(&VaultBurnInput { amount }).unwrap(),
206        )?;
207
208        let _: () = scrypto_decode(&rtn).unwrap();
209        Ok(())
210    }
211}
212
213impl NativeFungibleVault for Vault {
214    fn lock_fee<Y: SystemApi<E>, E: SystemApiError>(
215        &mut self,
216        api: &mut Y,
217        amount: Decimal,
218    ) -> Result<(), E> {
219        let rtn = api.call_method(
220            self.0.as_node_id(),
221            FUNGIBLE_VAULT_LOCK_FEE_IDENT,
222            scrypto_encode(&FungibleVaultLockFeeInput {
223                amount,
224                contingent: false,
225            })
226            .unwrap(),
227        )?;
228        let _: () = scrypto_decode(&rtn).unwrap();
229        Ok(())
230    }
231
232    fn lock_contingent_fee<Y: SystemApi<E>, E: SystemApiError>(
233        &mut self,
234        api: &mut Y,
235        amount: Decimal,
236    ) -> Result<(), E> {
237        let rtn = api.call_method(
238            self.0.as_node_id(),
239            FUNGIBLE_VAULT_LOCK_FEE_IDENT,
240            scrypto_encode(&FungibleVaultLockFeeInput {
241                amount,
242                contingent: true,
243            })
244            .unwrap(),
245        )?;
246        let _: () = scrypto_decode(&rtn).unwrap();
247        Ok(())
248    }
249
250    fn create_proof_of_amount<Y: SystemApi<E>, E: SystemApiError>(
251        &self,
252        amount: Decimal,
253        api: &mut Y,
254    ) -> Result<Proof, E> {
255        let rtn = api.call_method(
256            self.0.as_node_id(),
257            FUNGIBLE_VAULT_CREATE_PROOF_OF_AMOUNT_IDENT,
258            scrypto_encode(&FungibleVaultCreateProofOfAmountInput { amount }).unwrap(),
259        )?;
260
261        Ok(scrypto_decode(&rtn).unwrap())
262    }
263}
264
265impl NativeNonFungibleVault for Vault {
266    fn take_non_fungibles<Y: SystemApi<E>, E: SystemApiError>(
267        &mut self,
268        non_fungible_local_ids: IndexSet<NonFungibleLocalId>,
269        api: &mut Y,
270    ) -> Result<Bucket, E> {
271        let rtn = api.call_method(
272            self.0.as_node_id(),
273            NON_FUNGIBLE_VAULT_TAKE_NON_FUNGIBLES_IDENT,
274            scrypto_encode(&NonFungibleVaultTakeNonFungiblesInput {
275                non_fungible_local_ids,
276            })
277            .unwrap(),
278        )?;
279
280        Ok(scrypto_decode(&rtn).unwrap())
281    }
282
283    fn create_proof_of_non_fungibles<Y: SystemApi<E>, E: SystemApiError>(
284        &self,
285        ids: IndexSet<NonFungibleLocalId>,
286        api: &mut Y,
287    ) -> Result<Proof, E> {
288        let rtn = api.call_method(
289            self.0.as_node_id(),
290            NON_FUNGIBLE_VAULT_CREATE_PROOF_OF_NON_FUNGIBLES_IDENT,
291            scrypto_encode(&NonFungibleVaultCreateProofOfNonFungiblesInput { ids }).unwrap(),
292        )?;
293
294        Ok(scrypto_decode(&rtn).unwrap())
295    }
296
297    fn burn_non_fungibles<Y: SystemApi<E>, E: SystemApiError>(
298        &mut self,
299        non_fungible_local_ids: IndexSet<NonFungibleLocalId>,
300        api: &mut Y,
301    ) -> Result<(), E> {
302        let rtn = api.call_method(
303            self.0.as_node_id(),
304            NON_FUNGIBLE_VAULT_BURN_NON_FUNGIBLES_IDENT,
305            scrypto_encode(&NonFungibleVaultBurnNonFungiblesInput {
306                non_fungible_local_ids,
307            })
308            .unwrap(),
309        )?;
310
311        let _: () = scrypto_decode(&rtn).unwrap();
312        Ok(())
313    }
314
315    fn non_fungible_local_ids<Y: SystemApi<E>, E: SystemApiError>(
316        &self,
317        limit: u32,
318        api: &mut Y,
319    ) -> Result<IndexSet<NonFungibleLocalId>, E> {
320        let rtn = api.call_method(
321            self.0.as_node_id(),
322            NON_FUNGIBLE_VAULT_GET_NON_FUNGIBLE_LOCAL_IDS_IDENT,
323            scrypto_encode(&NonFungibleVaultGetNonFungibleLocalIdsInput { limit }).unwrap(),
324        )?;
325
326        Ok(scrypto_decode(&rtn).unwrap())
327    }
328
329    fn contains_non_fungible<Y: SystemApi<E>, E: SystemApiError>(
330        &mut self,
331        local_id: NonFungibleLocalId,
332        api: &mut Y,
333    ) -> Result<bool, E> {
334        let rtn = api.call_method(
335            self.0.as_node_id(),
336            NON_FUNGIBLE_VAULT_CONTAINS_NON_FUNGIBLE_IDENT,
337            scrypto_encode(&NonFungibleVaultContainsNonFungibleInput { id: local_id }).unwrap(),
338        )?;
339
340        Ok(scrypto_decode(&rtn).unwrap())
341    }
342}