Reading data from multiple contracts using Wagmi and React
As a developer, you’re probably familiar with the Wagmi library, which provides an easy-to-use API for interacting with multiple blockchain contracts using Web3.js and Ethers.js. In this article, we’ll look at how to use Wagmi’s useReadContracts
hook to retrieve data from multiple Ethereum contracts simultaneously.
Problem
Let’s say you have a list of 5 contracts with the same ABI (Application Binary Interface), but each contract has its own implementation. You want to get all the data you need from these contracts using Wagmi, but currently useReadContracts only returns information about one contract at a time.
Solution
To solve this problem, we will use the Wagmi useGetContractInstance
hook and create an instance array for each contract. Next, we’ll pass this array to useReadContracts to retrieve data from all contracts at once.
Here’s some code to get you started:
import {ethers} from "ethers";
import { useReadContracts } from "@wagmi/wagmi";
constant abi = [...]; // your OBI contract
// Create an array of instances for each contract
const contractInstances = [
{
identifier: 1,
address: '0x...',
example: ethers.ContractABI.fromWei(abi, ethers.utils.hexToWei('...'))(),
},
{
identifier: 2,
address: '0x...',
example: ethers.ContractABI.fromWei(abi, ethers.utils.hexToWei('...'))(),
},
// ...
];
// Use useGetContractInstance to get an array of contract instances
const contracts = await useReadContracts(contractInstances);
// Now you can get data from all contracts at once using the useGetContractData hook in wagmi
async function fetchData() {
constant data = [];
for (const Contract of Contracts) {
ask {
const result = await useGetContractData(contract.address, abi);
data.push(...result.data);
} catch (error) {
console.error(error);
}
}
data returned;
}
// Use the fetchData function whenever you need to fetch data from multiple contracts
setInterval ( fetchData , 1000 ); // extract every second
Tips and Options
useReadContracts
.const contractInstances = [
{
identifier: 1,
address: '0x...',
example: ethers.ContractABI.fromWei(abi, ethers.utils.hexToWei('...'))(),
},
{
identifier: 2,
address: '0x...',
example: ethers.ContractABI.fromWei(abi, ethers.utils.hexToWei('...'))(),
},
];
useGetContractData
interceptor with an object where the key is the address of the contract and the value is a function that returns data for each contract.const contractInstances = [
{
identifier: 1,
address: '0x...',
example: ethers.ContractABI.fromWei(abi, ethers.utils.hexToWei('...'))(),
},
{
identifier: 2,
address: '0x...',
example: ethers.ContractABI.fromWei(abi, ethers.utils.hexToWei('...'))(),
},
];
constant data = {};
for (const Contract of Contracts) {
data[contract.address] = await useGetContractData(contract.address, abi);
}
Hope this helps! Let me know if you have any questions or need additional help.