use alloy_sol_types::SolCall as _;
use tronz_primitives::{Address, U256};
use tronz_provider::{PendingTransaction, TronProvider};
use crate::{
error::{ContractError, Result},
instance::ContractInstance,
trc721::{
ITRC721, decode_address_return, decode_bool_return, decode_string_return,
decode_uint256_return, encode_approve, encode_balance_of, encode_owner_of,
encode_safe_transfer_from, encode_transfer_from,
},
};
pub type Trc721Error = ContractError;
#[derive(Clone)]
pub struct Trc721Instance<P: TronProvider> {
inner: ContractInstance<P>,
}
impl<P: TronProvider> Trc721Instance<P> {
pub fn new(provider: P, address: Address) -> Self {
Self { inner: ContractInstance::new_raw(provider, address) }
}
pub fn address(&self) -> Address {
self.inner.address()
}
pub fn provider(&self) -> &P {
self.inner.provider()
}
pub fn at(self, address: Address) -> Self {
Self { inner: self.inner.at(address) }
}
pub async fn name(&self) -> Result<String, Trc721Error> {
let out = self.inner.call_raw(ITRC721::nameCall {}.abi_encode().into()).call().await?;
Ok(decode_string_return(&out)?)
}
pub async fn symbol(&self) -> Result<String, Trc721Error> {
let out = self.inner.call_raw(ITRC721::symbolCall {}.abi_encode().into()).call().await?;
Ok(decode_string_return(&out)?)
}
pub async fn token_uri(&self, token_id: U256) -> Result<String, Trc721Error> {
let out = self
.inner
.call_raw(ITRC721::tokenURICall { tokenId: token_id }.abi_encode().into())
.call()
.await?;
Ok(decode_string_return(&out)?)
}
pub async fn balance_of(&self, owner: Address) -> Result<U256, Trc721Error> {
let out = self.inner.call_raw(encode_balance_of(owner)).call().await?;
Ok(decode_uint256_return(&out)?)
}
pub async fn owner_of(&self, token_id: U256) -> Result<Address, Trc721Error> {
let out = self.inner.call_raw(encode_owner_of(token_id)).call().await?;
Ok(decode_address_return(&out)?)
}
pub async fn get_approved(&self, token_id: U256) -> Result<Address, Trc721Error> {
let out = self
.inner
.call_raw(ITRC721::getApprovedCall { tokenId: token_id }.abi_encode().into())
.call()
.await?;
Ok(decode_address_return(&out)?)
}
pub async fn is_approved_for_all(
&self,
owner: Address,
operator: Address,
) -> Result<bool, Trc721Error> {
let out = self
.inner
.call_raw(
ITRC721::isApprovedForAllCall { owner: owner.into(), operator: operator.into() }
.abi_encode()
.into(),
)
.call()
.await?;
Ok(decode_bool_return(&out)?)
}
pub async fn transfer_from(
&self,
from: Address,
to: Address,
token_id: U256,
) -> Result<PendingTransaction<P>, Trc721Error> {
self.inner.call_raw(encode_transfer_from(from, to, token_id)).send().await
}
pub async fn safe_transfer_from(
&self,
from: Address,
to: Address,
token_id: U256,
) -> Result<PendingTransaction<P>, Trc721Error> {
self.inner.call_raw(encode_safe_transfer_from(from, to, token_id)).send().await
}
pub async fn approve(
&self,
to: Address,
token_id: U256,
) -> Result<PendingTransaction<P>, Trc721Error> {
self.inner.call_raw(encode_approve(to, token_id)).send().await
}
pub async fn set_approval_for_all(
&self,
operator: Address,
approved: bool,
) -> Result<PendingTransaction<P>, Trc721Error> {
self.inner
.call_raw(
ITRC721::setApprovalForAllCall { operator: operator.into(), approved }
.abi_encode()
.into(),
)
.send()
.await
}
}
pub trait Trc721Ext: TronProvider + Sized {
fn trc721(&self, address: Address) -> Trc721Instance<Self> {
Trc721Instance::new(self.clone(), address)
}
}
impl<P: TronProvider> Trc721Ext for P {}