1use alloy_network::Ethereum;
2use alloy_primitives::Address;
3use alloy_primitives::U256;
4use alloy_provider::PendingTransactionBuilder;
5use alloy_provider::Provider;
6use alloy_sol_types::sol;
7
8use crate::ERC20::ERC20Instance;
9
10#[derive(Clone, Debug)]
12pub struct Erc20<P: Provider<Ethereum>> {
13 instance: ERC20Instance<P>,
14}
15
16impl<P: Provider<Ethereum>> Erc20<P> {
17 pub fn new(address: Address, provider: P) -> Self {
18 Self {
19 instance: ERC20Instance::new(address, provider),
20 }
21 }
22
23 pub async fn balance_of(&self, address: Address) -> Result<U256, alloy_contract::Error> {
24 self.instance.balanceOf(address).call().await
25 }
26
27 pub async fn allowance(
28 &self,
29 owner: Address,
30 spender: Address,
31 ) -> Result<U256, alloy_contract::Error> {
32 self.instance.allowance(owner, spender).call().await
33 }
34
35 pub async fn decimals(&self) -> Result<u8, alloy_contract::Error> {
36 self.instance.decimals().call().await
37 }
38
39 pub async fn approve(
40 &self,
41 owner: Address,
42 spender: Address,
43 amount: U256,
44 ) -> Result<PendingTransactionBuilder<Ethereum>, alloy_contract::Error> {
45 self.instance
46 .approve(spender, amount)
47 .from(owner)
48 .send()
49 .await
50 }
51
52 pub async fn transfer(
53 &self,
54 from: Address,
55 to: Address,
56 amount: U256,
57 ) -> Result<PendingTransactionBuilder<Ethereum>, alloy_contract::Error> {
58 self.instance.transfer(to, amount).from(from).send().await
59 }
60}
61
62sol!(
63 #[allow(clippy::too_many_arguments)]
64 #[allow(missing_docs)]
65 #[sol(rpc)]
66 ERC20,
67 "abi/erc20.json"
68);