use elrond_codec::TopEncode;
use super::{BigUintApi, ErrorApi};
use crate::hex_call_data::HexCallDataSerializer;
use crate::types::{
Address, ArgBuffer, AsyncCall, BoxedBytes, CodeMetadata, TokenIdentifier, Vec, H256,
};
pub const ESDT_TRANSFER_STRING: &[u8] = b"ESDTTransfer";
pub const ESDT_NFT_TRANSFER_STRING: &[u8] = b"ESDTNFTTransfer";
#[allow(clippy::too_many_arguments)]
pub trait SendApi<BigUint>: ErrorApi + Clone + Sized
where
BigUint: BigUintApi + 'static,
{
fn direct_egld(&self, to: &Address, amount: &BigUint, data: &[u8]);
fn direct_egld_execute(
&self,
to: &Address,
amount: &BigUint,
gas_limit: u64,
function: &[u8],
arg_buffer: &ArgBuffer,
);
fn direct_esdt_via_transf_exec(
&self,
to: &Address,
token: &[u8],
amount: &BigUint,
data: &[u8],
) {
self.direct_esdt_execute(to, token, amount, 0, data, &ArgBuffer::new());
}
fn direct_esdt_execute(
&self,
to: &Address,
token: &[u8],
amount: &BigUint,
gas_limit: u64,
function: &[u8],
arg_buffer: &ArgBuffer,
);
fn direct_esdt_nft_execute(
&self,
to: &Address,
token: &[u8],
nonce: u64,
amount: &BigUint,
gas_limit: u64,
function: &[u8],
arg_buffer: &ArgBuffer,
);
fn direct(&self, to: &Address, token: &TokenIdentifier, amount: &BigUint, data: &[u8]) {
if token.is_egld() {
self.direct_egld(to, amount, data);
} else {
self.direct_esdt_via_transf_exec(to, token.as_esdt_identifier(), amount, data);
}
}
fn direct_esdt_via_async_call(
&self,
to: &Address,
esdt_token_name: &[u8],
amount: &BigUint,
data: &[u8],
) -> ! {
let mut serializer = HexCallDataSerializer::new(ESDT_TRANSFER_STRING);
serializer.push_argument_bytes(esdt_token_name);
serializer.push_argument_bytes(amount.to_bytes_be().as_slice());
if !data.is_empty() {
serializer.push_argument_bytes(data);
}
self.async_call_raw(&to, &BigUint::zero(), serializer.as_slice())
}
fn direct_via_async_call(
&self,
to: &Address,
token: &TokenIdentifier,
amount: &BigUint,
data: &[u8],
) {
if token.is_egld() {
self.direct_egld(to, amount, data);
} else {
self.direct_esdt_via_async_call(to, token.as_esdt_identifier(), amount, data);
}
}
fn async_call_raw(&self, to: &Address, amount: &BigUint, data: &[u8]) -> !;
fn async_call(&self, async_call: AsyncCall<BigUint>) -> ! {
self.async_call_raw(
&async_call.to,
&async_call.egld_payment,
async_call.hex_data.as_slice(),
)
}
fn deploy_contract(
&self,
gas: u64,
amount: &BigUint,
code: &BoxedBytes,
code_metadata: CodeMetadata,
arg_buffer: &ArgBuffer,
) -> Address;
fn execute_on_dest_context_raw(
&self,
gas: u64,
address: &Address,
value: &BigUint,
function: &[u8],
arg_buffer: &ArgBuffer,
) -> Vec<BoxedBytes>;
fn execute_on_dest_context_by_caller_raw(
&self,
gas: u64,
address: &Address,
value: &BigUint,
function: &[u8],
arg_buffer: &ArgBuffer,
) -> Vec<BoxedBytes>;
fn execute_on_same_context_raw(
&self,
gas: u64,
address: &Address,
value: &BigUint,
function: &[u8],
arg_buffer: &ArgBuffer,
);
fn storage_store_tx_hash_key(&self, data: &[u8]);
fn storage_load_tx_hash_key(&self) -> BoxedBytes;
fn call_local_esdt_built_in_function(&self, gas: u64, function: &[u8], arg_buffer: &ArgBuffer);
fn esdt_local_mint(&self, gas: u64, token: &[u8], amount: &BigUint) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token);
arg_buffer.push_argument_bytes(amount.to_bytes_be().as_slice());
self.call_local_esdt_built_in_function(gas, b"ESDTLocalMint", &arg_buffer);
}
fn esdt_local_burn(&self, gas: u64, token: &[u8], amount: &BigUint) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token);
arg_buffer.push_argument_bytes(amount.to_bytes_be().as_slice());
self.call_local_esdt_built_in_function(gas, b"ESDTLocalBurn", &arg_buffer);
}
fn esdt_nft_create<T: elrond_codec::TopEncode>(
&self,
gas: u64,
token: &[u8],
amount: &BigUint,
name: &BoxedBytes,
royalties: &BigUint,
hash: &H256,
attributes: &T,
uris: &[BoxedBytes],
) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token);
arg_buffer.push_argument_bytes(amount.to_bytes_be().as_slice());
arg_buffer.push_argument_bytes(name.as_slice());
arg_buffer.push_argument_bytes(royalties.to_bytes_be().as_slice());
arg_buffer.push_argument_bytes(hash.as_bytes());
let mut top_encoded_attributes = Vec::new();
let _ = attributes.top_encode(&mut top_encoded_attributes);
arg_buffer.push_argument_bytes(top_encoded_attributes.as_slice());
for uri in uris {
let mut top_encoded_uri = Vec::new();
let _ = uri.top_encode(&mut top_encoded_uri);
arg_buffer.push_argument_bytes(top_encoded_uri.as_slice());
}
self.call_local_esdt_built_in_function(gas, b"ESDTNFTCreate", &arg_buffer);
}
fn esdt_nft_add_quantity(&self, gas: u64, token: &[u8], nonce: u64, amount: &BigUint) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token);
arg_buffer.push_argument_bytes(&nonce.to_be_bytes()[..]);
arg_buffer.push_argument_bytes(amount.to_bytes_be().as_slice());
self.call_local_esdt_built_in_function(gas, b"ESDTNFTAddQuantity", &arg_buffer);
}
fn esdt_nft_burn(&self, gas: u64, token: &[u8], nonce: u64, amount: &BigUint) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token);
arg_buffer.push_argument_bytes(&nonce.to_be_bytes()[..]);
arg_buffer.push_argument_bytes(amount.to_bytes_be().as_slice());
self.call_local_esdt_built_in_function(gas, b"ESDTNFTBurn", &arg_buffer);
}
fn direct_esdt_nft_via_async_call(
&self,
from: &Address,
to: &Address,
token: &[u8],
nonce: u64,
amount: &BigUint,
data: &[u8],
) {
let mut serializer = HexCallDataSerializer::new(ESDT_NFT_TRANSFER_STRING);
serializer.push_argument_bytes(token);
serializer.push_argument_bytes(&nonce.to_be_bytes()[..]);
serializer.push_argument_bytes(amount.to_bytes_be().as_slice());
serializer.push_argument_bytes(to.as_bytes());
if !data.is_empty() {
serializer.push_argument_bytes(data);
}
self.async_call_raw(&from, &BigUint::zero(), serializer.as_slice());
}
fn direct_esdt_nft_via_transfer_exec(
&self,
to: &Address,
token: &[u8],
nonce: u64,
amount: &BigUint,
data: &[u8],
) {
self.direct_esdt_nft_execute(to, token, nonce, amount, 0, data, &ArgBuffer::new());
}
}