use alloy::network::TransactionBuilder;
use alloy::primitives::{Address, Bytes, U256};
use alloy::rpc::types::TransactionRequest;
use alloy::sol_types::SolCall;
use super::wallet::EvmWallet;
use crate::wallet::WalletError;
mod abi {
alloy::sol! {
function balanceOf(address owner) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function decimals() external view returns (uint8);
function symbol() external view returns (string);
}
}
impl EvmWallet {
pub async fn erc20_balance(&self, token: Address, owner: Address) -> Result<U256, WalletError> {
let calldata = abi::balanceOfCall { owner }.abi_encode();
let tx = TransactionRequest::default()
.with_to(token)
.with_input(Bytes::from(calldata));
let result = self.call(tx).await?;
abi::balanceOfCall::abi_decode_returns(&result)
.map_err(|e| WalletError::provider(format!("ERC-20 balanceOf decode failed: {e}")))
}
pub async fn erc20_transfer(
&self,
token: Address,
to: Address,
amount: U256,
) -> Result<String, WalletError> {
let calldata = abi::transferCall { to, amount }.abi_encode();
let tx = TransactionRequest::default()
.with_to(token)
.with_input(Bytes::from(calldata));
self.send_transaction(tx).await
}
pub async fn erc20_decimals(&self, token: Address) -> Result<u8, WalletError> {
let calldata = abi::decimalsCall {}.abi_encode();
let tx = TransactionRequest::default()
.with_to(token)
.with_input(Bytes::from(calldata));
let result = self.call(tx).await?;
abi::decimalsCall::abi_decode_returns(&result)
.map_err(|e| WalletError::provider(format!("ERC-20 decimals decode failed: {e}")))
}
pub async fn erc20_symbol(&self, token: Address) -> Result<String, WalletError> {
let calldata = abi::symbolCall {}.abi_encode();
let tx = TransactionRequest::default()
.with_to(token)
.with_input(Bytes::from(calldata));
let result = self.call(tx).await?;
abi::symbolCall::abi_decode_returns(&result)
.map_err(|e| WalletError::provider(format!("ERC-20 symbol decode failed: {e}")))
}
}