multiversx_sc/io/
call_value_init.rs

1use crate::{
2    api::{
3        CallValueApi, CallValueApiImpl, ErrorApi, ErrorApiImpl, ManagedBufferApiImpl,
4        ManagedTypeApi, const_handles, use_raw_handle,
5    },
6    contract_base::CallValueWrapper,
7    err_msg,
8    types::{
9        BigUint, EgldOrEsdtTokenIdentifier, EsdtTokenPayment, ManagedRef, ManagedType, ManagedVec,
10    },
11};
12
13/// Called initially in the generated code whenever no payable annotation is provided.
14pub fn not_payable<A>()
15where
16    A: CallValueApi,
17{
18    A::call_value_api_impl().check_not_payable();
19}
20
21/// Called initially in the generated code whenever `#[payable("*")]` annotation is provided.
22pub fn payable_any<A>()
23where
24    A: CallValueApi,
25{
26}
27
28/// Called initially in the generated code whenever `#[payable("EGLD")]` annotation is provided.
29pub fn payable_egld<A>()
30where
31    A: CallValueApi + ErrorApi + ManagedTypeApi,
32{
33    // will crash if anything other than (single) EGLD was transferred
34    let _ = CallValueWrapper::<A>::new().egld();
35}
36
37/// Called initially in the generated code whenever `#[payable("<token identifier>")]` annotation is provided.
38///
39/// Was never really used, expected to be deprecated/removed.
40pub fn payable_single_specific_token<A>(expected_token_identifier: &str)
41where
42    A: CallValueApi + ManagedTypeApi + ErrorApi,
43{
44    let transfers = CallValueWrapper::<A>::new().all_esdt_transfers();
45    if transfers.len() != 1 {
46        A::error_api_impl().signal_error(err_msg::SINGLE_ESDT_EXPECTED.as_bytes());
47    }
48    let expected_token_handle: A::ManagedBufferHandle =
49        use_raw_handle(const_handles::MBUF_TEMPORARY_1);
50    A::managed_type_impl().mb_overwrite(
51        expected_token_handle.clone(),
52        expected_token_identifier.as_bytes(),
53    );
54    let transfer = transfers.get(0);
55    if !A::managed_type_impl().mb_eq(
56        transfer.token_identifier.get_handle(),
57        expected_token_handle,
58    ) {
59        A::error_api_impl().signal_error(err_msg::BAD_TOKEN_PROVIDED.as_bytes());
60    }
61}
62
63/// Initializes an argument annotated with `#[payment_amount]` or `#[payment]`.
64pub fn arg_payment_amount<A>() -> BigUint<A>
65where
66    A: CallValueApi + ManagedTypeApi,
67{
68    CallValueWrapper::<A>::new().egld_or_single_esdt().amount
69}
70
71/// Initializes an argument annotated with `#[payment_token]`.
72pub fn arg_payment_token<A>() -> EgldOrEsdtTokenIdentifier<A>
73where
74    A: CallValueApi + ManagedTypeApi,
75{
76    CallValueWrapper::<A>::new()
77        .egld_or_single_esdt()
78        .token_identifier
79}
80
81/// Initializes an argument annotated with `#[payment_nonce]`.
82pub fn arg_payment_nonce<A>() -> u64
83where
84    A: CallValueApi + ManagedTypeApi,
85{
86    CallValueWrapper::<A>::new()
87        .egld_or_single_esdt()
88        .token_nonce
89}
90
91/// Initializes an argument annotated with `#[payment_multi]`.
92pub fn arg_payment_multi<A>() -> ManagedRef<'static, A, ManagedVec<A, EsdtTokenPayment<A>>>
93where
94    A: CallValueApi + ManagedTypeApi,
95{
96    CallValueWrapper::<A>::new().all_esdt_transfers()
97}