1use core::marker::PhantomData;
2
3use crate::{
4 api::{
5 const_handles, use_raw_handle, BigIntApiImpl, BlockchainApiImpl, CallTypeApi,
6 HandleConstraints, ManagedBufferApiImpl, RawHandle, SendApiImpl, StaticVarApiImpl,
7 },
8 types::{
9 BigUint, CodeMetadata, RewaOrDcdtTokenPayment, DcdtTokenPayment, ManagedAddress,
10 ManagedArgBuffer, ManagedBuffer, ManagedType, ManagedVec, TokenIdentifier,
11 },
12};
13
14#[derive(Default)]
15pub struct SendRawWrapper<A>
16where
17 A: CallTypeApi,
18{
19 _phantom: PhantomData<A>,
20}
21
22impl<A> SendRawWrapper<A>
23where
24 A: CallTypeApi,
25{
26 pub fn new() -> Self {
27 SendRawWrapper {
28 _phantom: PhantomData,
29 }
30 }
31
32 fn load_code_metadata_to_mb(
33 &self,
34 code_metadata: CodeMetadata,
35 code_metadata_handle: RawHandle,
36 ) {
37 let code_metadata_bytes = code_metadata.to_byte_array();
38 A::managed_type_impl().mb_overwrite(
39 use_raw_handle(code_metadata_handle),
40 &code_metadata_bytes[..],
41 );
42 }
43
44 pub fn direct_rewa<D>(&self, to: &ManagedAddress<A>, rewa_value: &BigUint<A>, data: D)
45 where
46 D: Into<ManagedBuffer<A>>,
47 {
48 let empty_mb_handle: A::ManagedBufferHandle =
49 use_raw_handle(const_handles::MBUF_TEMPORARY_1);
50 A::managed_type_impl().mb_overwrite(empty_mb_handle.clone(), &[]);
51
52 let _ = A::send_api_impl().transfer_value_execute(
53 to.get_handle().get_raw_handle(),
54 rewa_value.get_handle().get_raw_handle(),
55 0,
56 data.into().get_handle().get_raw_handle(),
57 empty_mb_handle.get_raw_handle(),
58 );
59 }
60
61 pub fn direct_rewa_execute(
62 &self,
63 to: &ManagedAddress<A>,
64 rewa_value: &BigUint<A>,
65 gas_limit: u64,
66 endpoint_name: &ManagedBuffer<A>,
67 arg_buffer: &ManagedArgBuffer<A>,
68 ) -> Result<(), &'static [u8]> {
69 A::send_api_impl().transfer_value_execute(
70 to.get_handle().get_raw_handle(),
71 rewa_value.get_handle().get_raw_handle(),
72 gas_limit,
73 endpoint_name.get_handle().get_raw_handle(),
74 arg_buffer.get_handle().get_raw_handle(),
75 )
76 }
77
78 pub fn transfer_dcdt_execute(
79 &self,
80 to: &ManagedAddress<A>,
81 token: &TokenIdentifier<A>,
82 value: &BigUint<A>,
83 gas_limit: u64,
84 endpoint_name: &ManagedBuffer<A>,
85 arg_buffer: &ManagedArgBuffer<A>,
86 ) -> Result<(), &'static [u8]> {
87 self.transfer_dcdt_nft_execute(to, token, 0, value, gas_limit, endpoint_name, arg_buffer)
88 }
89
90 #[allow(clippy::too_many_arguments)]
91 pub fn transfer_dcdt_nft_execute(
92 &self,
93 to: &ManagedAddress<A>,
94 token: &TokenIdentifier<A>,
95 nonce: u64,
96 rewa_value: &BigUint<A>,
97 gas_limit: u64,
98 endpoint_name: &ManagedBuffer<A>,
99 arg_buffer: &ManagedArgBuffer<A>,
100 ) -> Result<(), &'static [u8]> {
101 let mut payments: ManagedVec<A, DcdtTokenPayment<A>> = ManagedVec::new();
102 payments.push(DcdtTokenPayment::new(
103 token.clone(),
104 nonce,
105 rewa_value.clone(),
106 ));
107 self.multi_dcdt_transfer_execute(to, &payments, gas_limit, endpoint_name, arg_buffer)
108 }
109
110 pub fn multi_dcdt_transfer_execute(
111 &self,
112 to: &ManagedAddress<A>,
113 payments: &ManagedVec<A, DcdtTokenPayment<A>>,
114 gas_limit: u64,
115 endpoint_name: &ManagedBuffer<A>,
116 arg_buffer: &ManagedArgBuffer<A>,
117 ) -> Result<(), &'static [u8]> {
118 A::send_api_impl().multi_transfer_dcdt_nft_execute(
119 to.get_handle().get_raw_handle(),
120 payments.get_handle().get_raw_handle(),
121 gas_limit,
122 endpoint_name.get_handle().get_raw_handle(),
123 arg_buffer.get_handle().get_raw_handle(),
124 )
125 }
126
127 pub fn multi_rewa_or_dcdt_transfer_execute(
128 &self,
129 to: &ManagedAddress<A>,
130 payments: &ManagedVec<A, RewaOrDcdtTokenPayment<A>>,
131 gas_limit: u64,
132 endpoint_name: &ManagedBuffer<A>,
133 arg_buffer: &ManagedArgBuffer<A>,
134 ) -> Result<(), &'static [u8]> {
135 if let Some(single_item) = payments.is_single_item() {
136 if single_item.token_identifier.is_rewa() {
137 return self.direct_rewa_execute(
138 to,
139 &single_item.amount,
140 gas_limit,
141 endpoint_name,
142 arg_buffer,
143 );
144 }
145 }
146 A::send_api_impl().multi_transfer_dcdt_nft_execute(
147 to.get_handle().get_raw_handle(),
148 payments.get_handle().get_raw_handle(),
149 gas_limit,
150 endpoint_name.get_handle().get_raw_handle(),
151 arg_buffer.get_handle().get_raw_handle(),
152 )
153 }
154
155 pub fn async_call_raw(
156 &self,
157 to: &ManagedAddress<A>,
158 rewa_value: &BigUint<A>,
159 endpoint_name: &ManagedBuffer<A>,
160 arg_buffer: &ManagedArgBuffer<A>,
161 ) -> ! {
162 A::send_api_impl().async_call_raw(
163 to.get_handle().get_raw_handle(),
164 rewa_value.get_handle().get_raw_handle(),
165 endpoint_name.get_handle().get_raw_handle(),
166 arg_buffer.get_handle().get_raw_handle(),
167 )
168 }
169
170 #[allow(clippy::too_many_arguments)]
171 pub fn create_async_call_raw(
172 &self,
173 to: &ManagedAddress<A>,
174 rewa_value: &BigUint<A>,
175 endpoint_name: &ManagedBuffer<A>,
176 arg_buffer: &ManagedArgBuffer<A>,
177 success_callback: &'static str,
178 error_callback: &'static str,
179 gas: u64,
180 extra_gas_for_callback: u64,
181 serialized_callback_closure_args: &ManagedBuffer<A>,
182 ) {
183 A::send_api_impl().create_async_call_raw(
184 to.get_handle().get_raw_handle(),
185 rewa_value.get_handle().get_raw_handle(),
186 endpoint_name.get_handle().get_raw_handle(),
187 arg_buffer.get_handle().get_raw_handle(),
188 success_callback,
189 error_callback,
190 gas,
191 extra_gas_for_callback,
192 serialized_callback_closure_args
193 .get_handle()
194 .get_raw_handle(),
195 )
196 }
197
198 pub fn deploy_contract(
203 &self,
204 gas: u64,
205 rewa_value: &BigUint<A>,
206 code: &ManagedBuffer<A>,
207 code_metadata: CodeMetadata,
208 arg_buffer: &ManagedArgBuffer<A>,
209 ) -> (ManagedAddress<A>, ManagedVec<A, ManagedBuffer<A>>) {
210 let code_metadata_handle = const_handles::MBUF_TEMPORARY_1;
211 self.load_code_metadata_to_mb(code_metadata, code_metadata_handle);
212 let new_address_handle = A::static_var_api_impl().next_handle();
213 let result_handle = A::static_var_api_impl().next_handle();
214 A::send_api_impl().deploy_contract(
215 gas,
216 rewa_value.get_handle().get_raw_handle(),
217 code.get_handle().get_raw_handle(),
218 code_metadata_handle,
219 arg_buffer.get_handle().get_raw_handle(),
220 new_address_handle,
221 result_handle,
222 );
223 unsafe {
224 (
225 ManagedAddress::from_raw_handle(new_address_handle),
226 ManagedVec::from_raw_handle(result_handle),
227 )
228 }
229 }
230
231 pub fn deploy_from_source_contract(
235 &self,
236 gas: u64,
237 rewa_value: &BigUint<A>,
238 source_contract_address: &ManagedAddress<A>,
239 code_metadata: CodeMetadata,
240 arg_buffer: &ManagedArgBuffer<A>,
241 ) -> (ManagedAddress<A>, ManagedVec<A, ManagedBuffer<A>>) {
242 let code_metadata_handle = const_handles::MBUF_TEMPORARY_1;
243 self.load_code_metadata_to_mb(code_metadata, code_metadata_handle);
244 let new_address_handle = A::static_var_api_impl().next_handle();
245 let result_handle = A::static_var_api_impl().next_handle();
246 A::send_api_impl().deploy_from_source_contract(
247 gas,
248 rewa_value.get_handle().get_raw_handle(),
249 source_contract_address.get_handle().get_raw_handle(),
250 code_metadata_handle,
251 arg_buffer.get_handle().get_raw_handle(),
252 new_address_handle,
253 result_handle,
254 );
255 unsafe {
256 (
257 ManagedAddress::from_raw_handle(new_address_handle),
258 ManagedVec::from_raw_handle(result_handle),
259 )
260 }
261 }
262
263 pub fn upgrade_from_source_contract(
264 &self,
265 sc_address: &ManagedAddress<A>,
266 gas: u64,
267 rewa_value: &BigUint<A>,
268 source_contract_address: &ManagedAddress<A>,
269 code_metadata: CodeMetadata,
270 arg_buffer: &ManagedArgBuffer<A>,
271 ) {
272 let code_metadata_handle = const_handles::MBUF_TEMPORARY_1;
273 self.load_code_metadata_to_mb(code_metadata, code_metadata_handle);
274 A::send_api_impl().upgrade_from_source_contract(
275 sc_address.get_handle().get_raw_handle(),
276 gas,
277 rewa_value.get_handle().get_raw_handle(),
278 source_contract_address.get_handle().get_raw_handle(),
279 code_metadata_handle,
280 arg_buffer.get_handle().get_raw_handle(),
281 )
282 }
283
284 pub fn upgrade_contract(
288 &self,
289 sc_address: &ManagedAddress<A>,
290 gas: u64,
291 rewa_value: &BigUint<A>,
292 code: &ManagedBuffer<A>,
293 code_metadata: CodeMetadata,
294 arg_buffer: &ManagedArgBuffer<A>,
295 ) {
296 let code_metadata_handle = const_handles::MBUF_TEMPORARY_1;
297 self.load_code_metadata_to_mb(code_metadata, code_metadata_handle);
298 A::send_api_impl().upgrade_contract(
299 sc_address.get_handle().get_raw_handle(),
300 gas,
301 rewa_value.get_handle().get_raw_handle(),
302 code.get_handle().get_raw_handle(),
303 code_metadata_handle,
304 arg_buffer.get_handle().get_raw_handle(),
305 )
306 }
307
308 pub fn execute_on_dest_context_raw(
310 &self,
311 gas: u64,
312 address: &ManagedAddress<A>,
313 value: &BigUint<A>,
314 endpoint_name: &ManagedBuffer<A>,
315 arg_buffer: &ManagedArgBuffer<A>,
316 ) -> ManagedVec<A, ManagedBuffer<A>> {
317 let result_handle = A::static_var_api_impl().next_handle();
318 A::send_api_impl().execute_on_dest_context_raw(
319 gas,
320 address.get_handle().get_raw_handle(),
321 value.get_handle().get_raw_handle(),
322 endpoint_name.get_handle().get_raw_handle(),
323 arg_buffer.get_handle().get_raw_handle(),
324 result_handle,
325 );
326 unsafe { ManagedVec::from_raw_handle(result_handle) }
327 }
328
329 pub fn execute_on_same_context_raw(
330 &self,
331 gas: u64,
332 address: &ManagedAddress<A>,
333 value: &BigUint<A>,
334 endpoint_name: &ManagedBuffer<A>,
335 arg_buffer: &ManagedArgBuffer<A>,
336 ) -> ManagedVec<A, ManagedBuffer<A>> {
337 let result_handle = A::static_var_api_impl().next_handle();
338 A::send_api_impl().execute_on_same_context_raw(
339 gas,
340 address.get_handle().get_raw_handle(),
341 value.get_handle().get_raw_handle(),
342 endpoint_name.get_handle().get_raw_handle(),
343 arg_buffer.get_handle().get_raw_handle(),
344 result_handle,
345 );
346 unsafe { ManagedVec::from_raw_handle(result_handle) }
347 }
348
349 pub fn execute_on_dest_context_readonly_raw(
351 &self,
352 gas: u64,
353 address: &ManagedAddress<A>,
354 endpoint_name: &ManagedBuffer<A>,
355 arg_buffer: &ManagedArgBuffer<A>,
356 ) -> ManagedVec<A, ManagedBuffer<A>> {
357 let result_handle = A::static_var_api_impl().next_handle();
358 A::send_api_impl().execute_on_dest_context_readonly_raw(
359 gas,
360 address.get_handle().get_raw_handle(),
361 endpoint_name.get_handle().get_raw_handle(),
362 arg_buffer.get_handle().get_raw_handle(),
363 result_handle,
364 );
365 unsafe { ManagedVec::from_raw_handle(result_handle) }
366 }
367
368 pub fn call_local_dcdt_built_in_function(
370 &self,
371 gas: u64,
372 function_name: &ManagedBuffer<A>,
373 arg_buffer: &ManagedArgBuffer<A>,
374 ) -> ManagedVec<A, ManagedBuffer<A>> {
375 let own_address_handle: A::ManagedBufferHandle =
377 use_raw_handle(const_handles::MBUF_TEMPORARY_1);
378 A::blockchain_api_impl().load_sc_address_managed(own_address_handle.clone());
379 let rewa_value_handle = A::managed_type_impl().bi_new_zero();
380
381 let result_handle = A::static_var_api_impl().next_handle();
382 A::send_api_impl().execute_on_dest_context_raw(
383 gas,
384 own_address_handle.get_raw_handle(),
385 rewa_value_handle.get_raw_handle(),
386 function_name.get_handle().get_raw_handle(),
387 arg_buffer.get_handle().get_raw_handle(),
388 result_handle,
389 );
390
391 self.clean_return_data();
392 unsafe { ManagedVec::from_raw_handle(result_handle) }
393 }
394
395 pub fn clean_return_data(&self) {
396 A::send_api_impl().clean_return_data()
397 }
398}