diff --git a/contracts/examples/seed-nft-minter/src/distribution_module.rs b/contracts/examples/seed-nft-minter/src/distribution_module.rs index d91d6e6ae2..54f8bf2586 100644 --- a/contracts/examples/seed-nft-minter/src/distribution_module.rs +++ b/contracts/examples/seed-nft-minter/src/distribution_module.rs @@ -36,7 +36,7 @@ pub trait DistributionModule { self.tx() .to(&distribution.address) .raw_call(distribution.endpoint) - .egld_or_single_esdt((token_id.clone(), token_nonce, payment_amount)) + .egld_or_single_esdt(token_id, token_nonce, &payment_amount) .gas(distribution.gas_limit) .transfer_execute(); } diff --git a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs index ad276c32b0..944e3365b6 100644 --- a/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs +++ b/contracts/feature-tests/composability/forwarder-raw/src/forwarder_raw_async.rs @@ -46,7 +46,11 @@ pub trait ForwarderRawAsync: super::forwarder_raw_common::ForwarderRawCommon { .to(to) .raw_call(endpoint_name) .arguments_raw(args.to_arg_buffer()) - .egld_or_single_esdt((payment_token, 0, payment_amount)) + .payment(EgldOrEsdtTokenPayment::new( + payment_token, + 0, + payment_amount, + )) } #[endpoint] diff --git a/contracts/feature-tests/composability/promises-features/src/call_promise_direct.rs b/contracts/feature-tests/composability/promises-features/src/call_promise_direct.rs index e98e9b0c3b..55093fc8d6 100644 --- a/contracts/feature-tests/composability/promises-features/src/call_promise_direct.rs +++ b/contracts/feature-tests/composability/promises-features/src/call_promise_direct.rs @@ -17,7 +17,7 @@ pub trait CallPromisesDirectModule { self.tx() .to(&to) .raw_call(endpoint_name) - .egld_or_single_esdt(payment) + .payment(payment) .arguments_raw(args.to_arg_buffer()) .gas(gas_limit) .async_call_promise() diff --git a/contracts/feature-tests/composability/recursive-caller/src/recursive_caller.rs b/contracts/feature-tests/composability/recursive-caller/src/recursive_caller.rs index 407a681927..94f26e7e8d 100644 --- a/contracts/feature-tests/composability/recursive-caller/src/recursive_caller.rs +++ b/contracts/feature-tests/composability/recursive-caller/src/recursive_caller.rs @@ -25,7 +25,7 @@ pub trait RecursiveCaller { .to(to) .typed(vault_proxy::VaultProxy) .accept_funds() - .egld_or_single_esdt((token_identifier.clone(), 0, amount.clone())) + .egld_or_single_esdt(token_identifier, 0, amount) .async_call() .with_callback(self.callbacks().recursive_send_funds_callback( to, diff --git a/contracts/feature-tests/composability/vault/src/vault.rs b/contracts/feature-tests/composability/vault/src/vault.rs index 9f293bae45..ab22590572 100644 --- a/contracts/feature-tests/composability/vault/src/vault.rs +++ b/contracts/feature-tests/composability/vault/src/vault.rs @@ -153,7 +153,7 @@ pub trait Vault { self.tx() .to(&caller) .raw_call(endpoint_name.clone()) - .egld_or_single_esdt(return_payment.clone()) + .payment(&return_payment) .gas(self.blockchain().get_gas_left() / 2) .transfer_execute() } diff --git a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs index 01ce71d189..5a7f36a722 100644 --- a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs @@ -153,8 +153,9 @@ where #[inline] pub fn get_sc_balance(&self, token: &EgldOrEsdtTokenIdentifier, nonce: u64) -> BigUint { token.map_ref_or_else( - || self.get_balance(&self.get_sc_address()), - |token_identifier| { + (), + |()| self.get_balance(&self.get_sc_address()), + |(), token_identifier| { self.get_esdt_balance(&self.get_sc_address(), token_identifier, nonce) }, ) diff --git a/framework/base/src/types/interaction/tx.rs b/framework/base/src/types/interaction/tx.rs index de33648ba2..1524bb22fe 100644 --- a/framework/base/src/types/interaction/tx.rs +++ b/framework/base/src/types/interaction/tx.rs @@ -1,6 +1,7 @@ use crate::{ api::CallTypeApi, contract_base::BlockchainWrapper, + proxy_imports::{EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPaymentRefs}, types::{ BigUint, CodeMetadata, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, EgldOrMultiEsdtPaymentRefs, EsdtTokenPayment, EsdtTokenPaymentRefs, ManagedAddress, @@ -214,6 +215,20 @@ where }) } + /// Syntactic sugar for `self.payment(EgldOrEsdtTokenPaymentRefs::new(...)`. Takes references. + pub fn egld_or_single_esdt<'a>( + self, + token_identifier: &'a EgldOrEsdtTokenIdentifier, + token_nonce: u64, + amount: &'a BigUint, + ) -> Tx, Gas, Data, RH> { + self.payment(EgldOrEsdtTokenPaymentRefs::new( + token_identifier, + token_nonce, + amount, + )) + } + /// Sets a collection of ESDT transfers as the payment of the transaction. /// /// Equivalend to just ``.payment(payments)`, but only accepts the multi-esdt types. @@ -232,19 +247,12 @@ where self.multi_esdt(payments) } - pub fn egld_or_single_esdt>>( - self, - payment: P, - ) -> Tx, Gas, Data, RH> { - self.payment(payment.into()) - } - /// Backwards compatibility. pub fn with_egld_or_single_esdt_transfer>>( self, payment: P, ) -> Tx, Gas, Data, RH> { - self.egld_or_single_esdt(payment) + self.payment(payment.into()) } pub fn egld_or_multi_esdt>>( diff --git a/framework/base/src/types/interaction/tx_payment.rs b/framework/base/src/types/interaction/tx_payment.rs index aed63a90d4..252204edd8 100644 --- a/framework/base/src/types/interaction/tx_payment.rs +++ b/framework/base/src/types/interaction/tx_payment.rs @@ -1,6 +1,6 @@ mod tx_payment_egld; mod tx_payment_egld_or_esdt; -mod tx_payment_egld_or_esdt_ref; +mod tx_payment_egld_or_esdt_refs; mod tx_payment_egld_or_multi_esdt; mod tx_payment_egld_or_multi_esdt_ref; mod tx_payment_egld_value; @@ -10,7 +10,6 @@ mod tx_payment_single_esdt; mod tx_payment_single_esdt_ref; pub use tx_payment_egld::{Egld, EgldPayment}; -pub use tx_payment_egld_or_esdt_ref::*; pub use tx_payment_egld_value::TxEgldValue; pub use tx_payment_multi_esdt::TxPaymentMultiEsdt; diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt.rs index adc5ef36f9..e70c2919f2 100644 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt.rs +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt.rs @@ -8,7 +8,7 @@ use crate::{ use super::{AnnotatedEgldPayment, FullPaymentData, FunctionCall, TxEgldValue, TxEnv, TxPayment}; -impl TxPayment for EgldOrEsdtTokenPayment +impl TxPayment for &EgldOrEsdtTokenPayment where Env: TxEnv, { @@ -23,13 +23,60 @@ where gas_limit: u64, fc: FunctionCall, ) { - self.map_egld_or_esdt( + self.map_ref_egld_or_esdt( (to, fc), |(to, fc), amount| Egld(amount).perform_transfer_execute(env, to, gas_limit, fc), |(to, fc), esdt_payment| esdt_payment.perform_transfer_execute(env, to, gas_limit, fc), ) } + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, + { + self.map_ref_egld_or_esdt( + (to, fc, f), + |(to, fc, f), amount| Egld(amount).with_normalized(env, from, to, fc, f), + |(to, fc, f), esdt_payment| esdt_payment.with_normalized(env, from, to, fc, f), + ) + } + + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + self.map_ref_egld_or_esdt( + (), + |(), amount| TxPayment::::into_full_payment_data(Egld(amount), env), + |(), esdt_payment| TxPayment::::into_full_payment_data(esdt_payment, env), + ) + } +} + +impl TxPayment for EgldOrEsdtTokenPayment +where + Env: TxEnv, +{ + fn is_no_payment(&self, env: &Env) -> bool { + (&self).is_no_payment(env) + } + + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + (&self).perform_transfer_execute(env, to, gas_limit, fc) + } + fn with_normalized( self, env: &Env, diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_ref.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_ref.rs deleted file mode 100644 index d7dc216308..0000000000 --- a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_ref.rs +++ /dev/null @@ -1,117 +0,0 @@ -use alloc::borrow::ToOwned; - -use crate::{ - api::ManagedTypeApi, - contract_base::SendRawWrapper, - proxy_imports::EgldOrEsdtTokenIdentifier, - types::{ - AnnotatedValue, BigUint, EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, EsdtTokenPayment, - EsdtTokenPaymentRefs, ManagedAddress, ManagedType, ManagedVec, MultiEsdtPayment, TxFrom, - TxToSpecified, - }, -}; - -use super::{ - AnnotatedEgldPayment, Egld, FullPaymentData, FunctionCall, TxEgldValue, TxEnv, TxPayment, -}; - -impl<'a, Env> TxPayment for EgldOrEsdtTokenPaymentRefs<'a, Env::Api> -where - Env: TxEnv, -{ - fn is_no_payment(&self, _env: &Env) -> bool { - self.is_empty() - } - - fn perform_transfer_execute( - self, - env: &Env, - to: &ManagedAddress, - gas_limit: u64, - fc: FunctionCall, - ) { - self.map_egld_or_esdt( - (to, fc), - |(to, fc), amount| Egld(amount).perform_transfer_execute(env, to, gas_limit, fc), - |(to, fc), esdt_payment| esdt_payment.perform_transfer_execute(env, to, gas_limit, fc), - ) - } - - fn with_normalized( - self, - env: &Env, - from: &From, - to: To, - fc: FunctionCall, - f: F, - ) -> R - where - From: TxFrom, - To: TxToSpecified, - F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, - { - self.map_egld_or_esdt( - (to, fc, f), - |(to, fc, f), amount| Egld(amount).with_normalized(env, from, to, fc, f), - |(to, fc, f), esdt_payment| esdt_payment.with_normalized(env, from, to, fc, f), - ) - } - - fn into_full_payment_data(self, env: &Env) -> FullPaymentData { - self.map_egld_or_esdt( - (), - |(), amount| TxPayment::::into_full_payment_data(Egld(amount), env), - |(), esdt_payment| TxPayment::::into_full_payment_data(esdt_payment, env), - ) - } -} - -pub struct EgldOrEsdtTokenPaymentRefs<'a, M: ManagedTypeApi> { - pub token_identifier: &'a EgldOrEsdtTokenIdentifier, - pub token_nonce: u64, - pub amount: &'a BigUint, -} - -impl EgldOrEsdtTokenPayment { - pub fn as_refs(&self) -> EgldOrEsdtTokenPaymentRefs<'_, M> { - EgldOrEsdtTokenPaymentRefs { - token_identifier: &self.token_identifier, - token_nonce: self.token_nonce, - amount: &self.amount, - } - } -} - -impl<'a, M: ManagedTypeApi> EgldOrEsdtTokenPaymentRefs<'a, M> { - pub fn to_owned_payment(&self) -> EgldOrEsdtTokenPayment { - EgldOrEsdtTokenPayment { - token_identifier: self.token_identifier.clone(), - token_nonce: self.token_nonce, - amount: self.amount.clone(), - } - } - - pub fn is_empty(&self) -> bool { - self.amount == &BigUint::zero() - } - - pub fn map_egld_or_esdt(self, context: Context, for_egld: D, for_esdt: F) -> U - where - D: FnOnce(Context, &BigUint) -> U, - F: FnOnce(Context, EgldOrEsdtTokenPaymentRefs) -> U, - { - if self.token_identifier.data.is_some() { - let token_identifier = unsafe { self.token_identifier.clone().data.unwrap_no_check() }; - for_esdt( - context, - EgldOrEsdtTokenPaymentRefs { - token_identifier: &EgldOrEsdtTokenIdentifier::esdt(token_identifier), - token_nonce: self.token_nonce, - amount: self.amount, - }, - ) - } else { - for_egld(context, self.amount) - } - } -} diff --git a/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs new file mode 100644 index 0000000000..76c5a003f2 --- /dev/null +++ b/framework/base/src/types/interaction/tx_payment/tx_payment_egld_or_esdt_refs.rs @@ -0,0 +1,66 @@ +use alloc::borrow::ToOwned; + +use crate::{ + api::ManagedTypeApi, + contract_base::SendRawWrapper, + types::{ + AnnotatedValue, BigUint, EgldOrEsdtTokenIdentifier, EgldOrEsdtTokenPayment, + EgldOrEsdtTokenPaymentRefs, EgldOrMultiEsdtPayment, EsdtTokenPayment, EsdtTokenPaymentRefs, + ManagedAddress, ManagedType, ManagedVec, MultiEsdtPayment, TxFrom, TxToSpecified, + }, +}; + +use super::{ + AnnotatedEgldPayment, Egld, FullPaymentData, FunctionCall, TxEgldValue, TxEnv, TxPayment, +}; + +impl<'a, Env> TxPayment for EgldOrEsdtTokenPaymentRefs<'a, Env::Api> +where + Env: TxEnv, +{ + fn is_no_payment(&self, _env: &Env) -> bool { + self.is_empty() + } + + fn perform_transfer_execute( + self, + env: &Env, + to: &ManagedAddress, + gas_limit: u64, + fc: FunctionCall, + ) { + self.map_egld_or_esdt( + fc, + |fc, amount| Egld(amount).perform_transfer_execute(env, to, gas_limit, fc), + |fc, esdt_payment| esdt_payment.perform_transfer_execute(env, to, gas_limit, fc), + ) + } + + fn with_normalized( + self, + env: &Env, + from: &From, + to: To, + fc: FunctionCall, + f: F, + ) -> R + where + From: TxFrom, + To: TxToSpecified, + F: FnOnce(&ManagedAddress, &BigUint, &FunctionCall) -> R, + { + self.map_egld_or_esdt( + (to, fc, f), + |(to, fc, f), amount| Egld(amount).with_normalized(env, from, to, fc, f), + |(to, fc, f), esdt_payment| esdt_payment.with_normalized(env, from, to, fc, f), + ) + } + + fn into_full_payment_data(self, env: &Env) -> FullPaymentData { + self.map_egld_or_esdt( + (), + |(), amount| TxPayment::::into_full_payment_data(Egld(amount), env), + |(), esdt_payment| TxPayment::::into_full_payment_data(esdt_payment, env), + ) + } +} diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 3635ddaba2..c363853203 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -81,8 +81,9 @@ impl EgldOrEsdtTokenIdentifier { #[inline] pub fn into_name(self) -> ManagedBuffer { self.map_or_else( - || ManagedBuffer::from(&Self::EGLD_REPRESENTATION[..]), - |token_identifier| token_identifier.into_managed_buffer(), + (), + |()| ManagedBuffer::from(&Self::EGLD_REPRESENTATION[..]), + |(), token_identifier| token_identifier.into_managed_buffer(), ) } @@ -91,25 +92,26 @@ impl EgldOrEsdtTokenIdentifier { /// Will fail if it encodes an invalid ESDT token identifier. pub fn is_valid(&self) -> bool { self.map_ref_or_else( - || true, - |token_identifier| token_identifier.is_valid_esdt_identifier(), + (), + |()| true, + |(), token_identifier| token_identifier.is_valid_esdt_identifier(), ) } - pub fn map_or_else(self, for_egld: D, for_esdt: F) -> U + pub fn map_or_else(self, context: Context, for_egld: D, for_esdt: F) -> R where - D: FnOnce() -> U, - F: FnOnce(TokenIdentifier) -> U, + D: FnOnce(Context) -> R, + F: FnOnce(Context, TokenIdentifier) -> R, { - self.data.map_or_else(for_egld, for_esdt) + self.data.map_or_else(context, for_egld, for_esdt) } - pub fn map_ref_or_else(&self, for_egld: D, for_esdt: F) -> U + pub fn map_ref_or_else(&self, context: Context, for_egld: D, for_esdt: F) -> R where - D: FnOnce() -> U, - F: FnOnce(&TokenIdentifier) -> U, + D: FnOnce(Context) -> R, + F: FnOnce(Context, &TokenIdentifier) -> R, { - self.data.map_ref_or_else(for_egld, for_esdt) + self.data.map_ref_or_else(context, for_egld, for_esdt) } pub fn unwrap_esdt(self) -> TokenIdentifier { @@ -142,8 +144,9 @@ impl PartialEq> for EgldOrEsdtTokenIdentif #[inline] fn eq(&self, other: &TokenIdentifier) -> bool { self.map_ref_or_else( - || false, - |self_esdt_token_identifier| self_esdt_token_identifier == other, + (), + |()| false, + |(), self_esdt_token_identifier| self_esdt_token_identifier == other, ) } } diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs index 8d5e692610..ffce0c44e7 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_payment.rs @@ -12,7 +12,7 @@ use crate::codec::{ use crate as multiversx_sc; // needed by the TypeAbi generated code use crate::derive::TypeAbi; -use super::EsdtTokenPayment; +use super::{EsdtTokenPayment, EsdtTokenPaymentRefs}; #[derive( TopDecode, TopEncode, NestedDecode, NestedEncode, TypeAbi, Clone, PartialEq, Eq, Debug, @@ -59,21 +59,46 @@ impl EgldOrEsdtTokenPayment { /// More precisely, since only one of the two closures `for_egld` and `for_esdt` is called, /// it is ok for them to have fully owned access to anything from the environment. /// The compiler doesn't know that only one of them can ever be called, - /// so if we pass context to both closures, it will complain that they are moved twice.. + /// so if we pass context to both closures, it will complain that they are moved twice. pub fn map_egld_or_esdt(self, context: Context, for_egld: D, for_esdt: F) -> U where D: FnOnce(Context, BigUint) -> U, F: FnOnce(Context, EsdtTokenPayment) -> U, { - if self.token_identifier.data.is_some() { - let token_identifier = unsafe { self.token_identifier.data.unwrap_no_check() }; - for_esdt( - context, - EsdtTokenPayment::new(token_identifier, self.token_nonce, self.amount), - ) - } else { - for_egld(context, self.amount) - } + self.token_identifier.map_or_else( + (context, self.amount), + |(context, amount)| for_egld(context, amount), + |(context, amount), token_identifier| { + for_esdt( + context, + EsdtTokenPayment::new(token_identifier, self.token_nonce, amount), + ) + }, + ) + } + + /// Same as `map_egld_or_esdt`, but only takes a reference, + /// and consequently, the closures also only get references. + pub fn map_ref_egld_or_esdt( + &self, + context: Context, + for_egld: D, + for_esdt: F, + ) -> U + where + D: FnOnce(Context, &BigUint) -> U, + F: FnOnce(Context, EsdtTokenPaymentRefs<'_, M>) -> U, + { + self.token_identifier.map_ref_or_else( + context, + |context| for_egld(context, &self.amount), + |context, token_identifier| { + for_esdt( + context, + EsdtTokenPaymentRefs::new(token_identifier, self.token_nonce, &self.amount), + ) + }, + ) } pub fn into_tuple(self) -> (EgldOrEsdtTokenIdentifier, u64, BigUint) { @@ -104,3 +129,59 @@ impl From> for EgldOrEsdtTokenPayment impl CodecFromSelf for EgldOrEsdtTokenPayment where M: ManagedTypeApi {} impl CodecFrom<&[u8]> for EgldOrEsdtTokenPayment where M: ManagedTypeApi {} + +impl EgldOrEsdtTokenPayment { + pub fn as_refs(&self) -> EgldOrEsdtTokenPaymentRefs<'_, M> { + EgldOrEsdtTokenPaymentRefs::new(&self.token_identifier, self.token_nonce, &self.amount) + } +} + +/// Similar to `EgldOrEsdtTokenPayment`, but only contains references. +pub struct EgldOrEsdtTokenPaymentRefs<'a, M: ManagedTypeApi> { + pub token_identifier: &'a EgldOrEsdtTokenIdentifier, + pub token_nonce: u64, + pub amount: &'a BigUint, +} + +impl<'a, M: ManagedTypeApi> EgldOrEsdtTokenPaymentRefs<'a, M> { + pub fn new( + token_identifier: &'a EgldOrEsdtTokenIdentifier, + token_nonce: u64, + amount: &'a BigUint, + ) -> EgldOrEsdtTokenPaymentRefs<'a, M> { + EgldOrEsdtTokenPaymentRefs { + token_identifier, + token_nonce, + amount, + } + } + + pub fn to_owned_payment(&self) -> EgldOrEsdtTokenPayment { + EgldOrEsdtTokenPayment { + token_identifier: self.token_identifier.clone(), + token_nonce: self.token_nonce, + amount: self.amount.clone(), + } + } + + pub fn is_empty(&self) -> bool { + self.amount == &BigUint::zero() + } + + pub fn map_egld_or_esdt(self, context: Context, for_egld: D, for_esdt: F) -> U + where + D: FnOnce(Context, &BigUint) -> U, + F: FnOnce(Context, EsdtTokenPaymentRefs) -> U, + { + self.token_identifier.map_ref_or_else( + context, + |context| for_egld(context, self.amount), + |context, token_identifier| { + for_esdt( + context, + EsdtTokenPaymentRefs::new(token_identifier, self.token_nonce, self.amount), + ) + }, + ) + } +} diff --git a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs index 161c2c1ee3..b074dc9bfe 100644 --- a/framework/base/src/types/managed/wrapped/esdt_token_payment.rs +++ b/framework/base/src/types/managed/wrapped/esdt_token_payment.rs @@ -232,15 +232,23 @@ pub struct EsdtTokenPaymentRefs<'a, M: ManagedTypeApi> { impl EsdtTokenPayment { pub fn as_refs(&self) -> EsdtTokenPaymentRefs<'_, M> { - EsdtTokenPaymentRefs { - token_identifier: &self.token_identifier, - token_nonce: self.token_nonce, - amount: &self.amount, - } + EsdtTokenPaymentRefs::new(&self.token_identifier, self.token_nonce, &self.amount) } } impl<'a, M: ManagedTypeApi> EsdtTokenPaymentRefs<'a, M> { + pub fn new( + token_identifier: &'a TokenIdentifier, + token_nonce: u64, + amount: &'a BigUint, + ) -> Self { + EsdtTokenPaymentRefs { + token_identifier, + token_nonce, + amount, + } + } + /// Will clone the referenced values. pub fn to_owned_payment(&self) -> EsdtTokenPayment { EsdtTokenPayment { diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index 422a5e7753..7dd8ed2dad 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -122,27 +122,27 @@ where } } - pub fn map_or_else(self, default: D, f: F) -> U + pub fn map_or_else(self, context: Context, default: D, f: F) -> R where - D: FnOnce() -> U, - F: FnOnce(T) -> U, + D: FnOnce(Context) -> R, + F: FnOnce(Context, T) -> R, { if self.is_some() { - f(unsafe { self.unwrap_no_check() }) + f(context, unsafe { self.unwrap_no_check() }) } else { - default() + default(context) } } - pub fn map_ref_or_else(&self, default: D, f: F) -> U + pub fn map_ref_or_else(&self, context: Context, default: D, f: F) -> R where - D: FnOnce() -> U, - F: FnOnce(&T) -> U, + D: FnOnce(Context) -> R, + F: FnOnce(Context, &T) -> R, { if self.is_some() { - f(&T::from_handle(self.handle.clone())) + f(context, &T::from_handle(self.handle.clone())) } else { - default() + default(context) } } } diff --git a/framework/base/src/types/managed/wrapped/mod.rs b/framework/base/src/types/managed/wrapped/mod.rs index 5a5e907403..58d706ed62 100644 --- a/framework/base/src/types/managed/wrapped/mod.rs +++ b/framework/base/src/types/managed/wrapped/mod.rs @@ -19,7 +19,7 @@ mod randomness_source; mod token_identifier; pub use egld_or_esdt_token_identifier::EgldOrEsdtTokenIdentifier; -pub use egld_or_esdt_token_payment::EgldOrEsdtTokenPayment; +pub use egld_or_esdt_token_payment::{EgldOrEsdtTokenPayment, EgldOrEsdtTokenPaymentRefs}; pub use egld_or_multi_esdt_payment::{EgldOrMultiEsdtPayment, EgldOrMultiEsdtPaymentRefs}; pub(crate) use encoded_managed_vec_item::EncodedManagedVecItem; pub use esdt_token_data::EsdtTokenData; diff --git a/framework/base/src/types/managed/wrapped/token_identifier.rs b/framework/base/src/types/managed/wrapped/token_identifier.rs index af113dbc4e..53078e09d7 100644 --- a/framework/base/src/types/managed/wrapped/token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/token_identifier.rs @@ -109,8 +109,9 @@ impl PartialEq> for TokenIdentif #[inline] fn eq(&self, other: &EgldOrEsdtTokenIdentifier) -> bool { other.map_ref_or_else( - || false, - |esdt_token_identifier| esdt_token_identifier == self, + (), + |()| false, + |(), esdt_token_identifier| esdt_token_identifier == self, ) } } diff --git a/framework/derive/src/generate/proxy_gen.rs b/framework/derive/src/generate/proxy_gen.rs index 9118c1f748..b904c69f20 100644 --- a/framework/derive/src/generate/proxy_gen.rs +++ b/framework/derive/src/generate/proxy_gen.rs @@ -140,7 +140,7 @@ pub fn generate_proxy_endpoint(m: &Method, endpoint_name: String) -> proc_macro2 payment_init = quote! { .egld(#payment_expr) }; } else { payment_type = quote! { multiversx_sc::types::EgldOrEsdtTokenPayment }; - payment_init = quote! { .egld_or_single_esdt( + payment_init = quote! { .payment( multiversx_sc::types::EgldOrEsdtTokenPayment::new( #token_expr, #nonce_expr,