use alloy_network::Ethereum;
use alloy_primitives::{Address, U256};
use alloy_provider::Provider;
use alloy_rpc_types::TransactionRequest;
use alloy_sol_types::sol;
use tracing::{debug, info};
use Erc20::Erc20Instance;
pub struct Erc20Contract<P: Provider<Ethereum>> {
instance: Erc20Instance<P>,
}
impl<P: Provider<Ethereum>> Erc20Contract<P> {
pub fn new(address: Address, provider: P) -> Self {
debug!(
contract_address = %address,
event = "erc20_contract_initialized"
);
Self {
instance: Erc20Instance::new(address, provider),
}
}
pub async fn allowance(
&self,
owner: Address,
spender: Address,
) -> Result<U256, alloy_contract::Error> {
debug!(
owner = %owner,
spender = %spender,
contract_address = %self.instance.address(),
event = "checking_allowance"
);
let result = self.instance.allowance(owner, spender).call().await?;
info!(
owner = %owner,
spender = %spender,
allowance = %result,
contract_address = %self.instance.address(),
event = "allowance_retrieved"
);
Ok(result)
}
pub fn approve_transaction(
&self,
from: Address,
spender: Address,
amount: U256,
) -> TransactionRequest {
info!(
from = %from,
spender = %spender,
amount = %amount,
contract_address = %self.instance.address(),
event = "approve_transaction_created"
);
self.instance
.approve(spender, amount)
.from(from)
.into_transaction_request()
}
pub async fn balance_of(&self, account: Address) -> Result<U256, alloy_contract::Error> {
debug!(
account = %account,
contract_address = %self.instance.address(),
event = "checking_balance"
);
let result = self.instance.balanceOf(account).call().await?;
info!(
account = %account,
balance = %result,
contract_address = %self.instance.address(),
event = "balance_retrieved"
);
Ok(result)
}
pub fn address(&self) -> Address {
*self.instance.address()
}
}
sol!(
#[allow(missing_docs)]
#[sol(rpc)]
contract Erc20 {
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
}
);