use alloy_multicall::Multicall;
use alloy_sol_types::sol;
use alloy_primitives::{address, Bytes};
use alloy_dyn_abi::DynSolValue;
use std::result::Result as StdResult;
sol! {
#[derive(Debug, PartialEq)]
#[sol(rpc, abi, extra_methods)]
interface ERC20 {
function totalSupply() external view returns (uint256 totalSupply);
function balanceOf(address owner) external view returns (uint256 balance);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
}
#[tokio::main]
async fn main() {
let rpc_url = "https://rpc.ankr.com/eth".parse().unwrap();
let provider = alloy_provider::ProviderBuilder::new().on_http(rpc_url);
let weth_address = address!("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2");
let mut multicall = Multicall::new(provider.clone(), None).await.unwrap();
let functions = ERC20::abi::functions();
let name_call = functions.get("name").unwrap().first().unwrap();
let total_supply_call = functions.get("totalSupply").unwrap().first().unwrap();
let decimals_call = functions.get("decimals").unwrap().first().unwrap();
let symbol_call = functions.get("symbol").unwrap().first().unwrap();
multicall.add_call(weth_address, total_supply_call, &[], true);
multicall.add_call(weth_address, name_call, &[], true);
multicall.add_call(weth_address, decimals_call, &[], true);
multicall.add_call(weth_address, symbol_call, &[], true);
multicall
.with_call(weth_address, total_supply_call, &[], true)
.with_call(weth_address, name_call, &[], true)
.with_call(weth_address, decimals_call, &[], true)
.with_call(weth_address, symbol_call, &[], true)
.add_get_chain_id();
multicall.set_version(1);
let results = multicall.call().await.unwrap();
assert_results(results);
multicall.set_version(2);
let results = multicall.call().await.unwrap();
assert_results(results);
multicall.set_version(3);
let results = multicall.call().await.unwrap();
assert_results(results);
}
fn assert_results(results: Vec<StdResult<DynSolValue, Bytes>>) {
let name = results.get(1).unwrap().as_ref().unwrap().as_str().unwrap();
let decimals = results.get(2).unwrap().as_ref().unwrap().as_uint().unwrap().0.to::<u8>();
let symbol = results.get(3).unwrap().as_ref().unwrap().as_str().unwrap();
assert_eq!(name, "Wrapped Ether");
assert_eq!(symbol, "WETH");
assert_eq!(decimals, 18);
let name = results.get(5).unwrap().as_ref().unwrap().as_str().unwrap();
let decimals = results.get(6).unwrap().as_ref().unwrap().as_uint().unwrap().0.to::<u8>();
let symbol = results.get(7).unwrap().as_ref().unwrap().as_str().unwrap();
let chain_id = results.get(8).unwrap().as_ref().unwrap().as_uint().unwrap().0.to::<u64>();
assert_eq!(name, "Wrapped Ether");
assert_eq!(symbol, "WETH");
assert_eq!(decimals, 18);
assert_eq!(chain_id, 1);
}