use dharitri_codec::TopEncode;
use super::{BigIntApi, BigUintApi, ErrorApi, StorageReadApi, StorageWriteApi};
use crate::{
types::{Address, ArgBuffer, AsyncCall, BoxedBytes, CodeMetadata, TokenIdentifier, Vec},
HexCallDataSerializer,
};
pub const DCT_TRANSFER_STRING: &[u8] = b"DCTTransfer";
pub const DCT_NFT_TRANSFER_STRING: &[u8] = b"DCTNFTTransfer";
#[allow(clippy::too_many_arguments)] pub trait SendApi: ErrorApi + Clone + Sized {
type AmountType: BigUintApi + 'static;
type ProxyBigInt: BigIntApi + 'static;
type ProxyStorage: StorageReadApi + StorageWriteApi + ErrorApi + Clone + 'static;
fn get_sc_address(&self) -> Address;
fn get_gas_left(&self) -> u64;
fn direct_moax(&self, to: &Address, amount: &Self::AmountType, data: &[u8]);
fn direct_moax_execute(
&self,
to: &Address,
amount: &Self::AmountType,
gas_limit: u64,
function: &[u8],
arg_buffer: &ArgBuffer,
) -> Result<(), &'static [u8]>;
fn direct_dct_execute(
&self,
to: &Address,
token: &TokenIdentifier,
amount: &Self::AmountType,
gas_limit: u64,
function: &[u8],
arg_buffer: &ArgBuffer,
) -> Result<(), &'static [u8]>;
fn direct_dct_nft_execute(
&self,
to: &Address,
token: &TokenIdentifier,
nonce: u64,
amount: &Self::AmountType,
gas_limit: u64,
function: &[u8],
arg_buffer: &ArgBuffer,
) -> Result<(), &'static [u8]>;
fn transfer_dct_via_async_call(
&self,
to: &Address,
token: &TokenIdentifier,
amount: &Self::AmountType,
data: &[u8],
) -> ! {
let mut serializer = HexCallDataSerializer::new(DCT_TRANSFER_STRING);
serializer.push_argument_bytes(token.as_dct_identifier());
serializer.push_argument_bytes(amount.to_bytes_be().as_slice());
if !data.is_empty() {
serializer.push_argument_bytes(data);
}
self.async_call_raw(&to, &Self::AmountType::zero(), serializer.as_slice())
}
fn direct(
&self,
to: &Address,
token: &TokenIdentifier,
amount: &Self::AmountType,
data: &[u8],
) {
if token.is_moax() {
self.direct_moax(to, amount, data);
} else {
let _ = self.direct_dct_execute(to, token, amount, 0, data, &ArgBuffer::new());
}
}
fn direct_nft(
&self,
to: &Address,
token: &TokenIdentifier,
nonce: u64,
amount: &Self::AmountType,
data: &[u8],
) {
let _ = self.direct_dct_nft_execute(to, token, nonce, amount, 0, data, &ArgBuffer::new());
}
fn async_call_raw(&self, to: &Address, amount: &Self::AmountType, data: &[u8]) -> !;
fn async_call(&self, async_call: AsyncCall<Self>) -> ! {
self.async_call_raw(
&async_call.to,
&async_call.moax_payment,
async_call.hex_data.as_slice(),
)
}
fn deploy_contract(
&self,
gas: u64,
amount: &Self::AmountType,
code: &BoxedBytes,
code_metadata: CodeMetadata,
arg_buffer: &ArgBuffer,
) -> Address;
fn execute_on_dest_context_raw(
&self,
gas: u64,
address: &Address,
value: &Self::AmountType,
function: &[u8],
arg_buffer: &ArgBuffer,
) -> Vec<BoxedBytes>;
fn execute_on_dest_context_raw_custom_result_range<F>(
&self,
gas: u64,
address: &Address,
value: &Self::AmountType,
function: &[u8],
arg_buffer: &ArgBuffer,
range_closure: F,
) -> Vec<BoxedBytes>
where
F: FnOnce(usize, usize) -> (usize, usize);
fn execute_on_dest_context_by_caller_raw(
&self,
gas: u64,
address: &Address,
value: &Self::AmountType,
function: &[u8],
arg_buffer: &ArgBuffer,
) -> Vec<BoxedBytes>;
fn execute_on_same_context_raw(
&self,
gas: u64,
address: &Address,
value: &Self::AmountType,
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_dct_built_in_function(&self, gas: u64, function: &[u8], arg_buffer: &ArgBuffer);
fn dct_local_mint(&self, token: &TokenIdentifier, amount: &Self::AmountType) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token.as_dct_identifier());
arg_buffer.push_argument_bytes(amount.to_bytes_be().as_slice());
self.call_local_dct_built_in_function(self.get_gas_left(), b"DCTLocalMint", &arg_buffer);
}
fn dct_local_burn(&self, token: &TokenIdentifier, amount: &Self::AmountType) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token.as_dct_identifier());
arg_buffer.push_argument_bytes(amount.to_bytes_be().as_slice());
self.call_local_dct_built_in_function(self.get_gas_left(), b"DCTLocalBurn", &arg_buffer);
}
fn dct_nft_create<T: dharitri_codec::TopEncode>(
&self,
token: &TokenIdentifier,
amount: &Self::AmountType,
name: &BoxedBytes,
royalties: &Self::AmountType,
hash: &BoxedBytes,
attributes: &T,
uris: &[BoxedBytes],
) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token.as_dct_identifier());
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_slice());
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_dct_built_in_function(self.get_gas_left(), b"DCTNFTCreate", &arg_buffer);
}
fn dct_nft_add_quantity(
&self,
token: &TokenIdentifier,
nonce: u64,
amount: &Self::AmountType,
) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token.as_dct_identifier());
arg_buffer.push_argument_bytes(&nonce.to_be_bytes()[..]);
arg_buffer.push_argument_bytes(amount.to_bytes_be().as_slice());
self.call_local_dct_built_in_function(
self.get_gas_left(),
b"DCTNFTAddQuantity",
&arg_buffer,
);
}
fn dct_nft_burn(&self, token: &TokenIdentifier, nonce: u64, amount: &Self::AmountType) {
let mut arg_buffer = ArgBuffer::new();
arg_buffer.push_argument_bytes(token.as_dct_identifier());
arg_buffer.push_argument_bytes(&nonce.to_be_bytes()[..]);
arg_buffer.push_argument_bytes(amount.to_bytes_be().as_slice());
self.call_local_dct_built_in_function(self.get_gas_left(), b"DCTNFTBurn", &arg_buffer);
}
fn transfer_dct_nft_via_async_call(
&self,
from: &Address,
to: &Address,
token: &TokenIdentifier,
nonce: u64,
amount: &Self::AmountType,
data: &[u8],
) {
let mut serializer = HexCallDataSerializer::new(DCT_NFT_TRANSFER_STRING);
serializer.push_argument_bytes(token.as_dct_identifier());
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, &Self::AmountType::zero(), serializer.as_slice());
}
}