vite-garden
Version:
Vite Garden -- a part of the threed.ai family of JavaScript-friendly food-growing libraries
71 lines (60 loc) • 1.95 kB
text/typescript
import { ref, markRaw } from 'vue'
import { Contract, ContractInterface } from '@ethersproject/contracts'
import { MULTICALL2_ABI, MULTICALL2_ADDRESS } from '../constants'
import { Multicall2 } from '../types/multicall2/Multicall2'
import { Web3Provider, JsonRpcProvider } from '@ethersproject/providers'
import { Result, Interface } from '@ethersproject/abi'
export type ContractCall = {
interface: ContractInterface
address: string
method: string
args?: any[]
}
export function useMulticall(provider: Web3Provider | JsonRpcProvider) {
const results = ref<Result[]>([])
const blockNumber = ref(0)
const multicall = markRaw(
new Contract(MULTICALL2_ADDRESS, MULTICALL2_ABI, provider) as Multicall2,
)
interface Call {
target: string
callData: string
}
async function call(contractCalls: ContractCall[]) {
const calls: Call[] = contractCalls.map((call) => {
const iface = getInterface(call.interface)
return {
target: call.address,
callData: iface.encodeFunctionData(call.method, call.args),
}
})
const { blockNumber: blocNum, returnData } = await tryBlockAndAggregate(
calls,
)
results.value = returnData.map((data, i) => {
if (!data.success)
console.error(`Failed to call ${contractCalls[i].method}`)
const iface = getInterface(contractCalls[i].interface)
return iface.decodeFunctionResult(
contractCalls[i].method,
data.returnData,
)
})
blockNumber.value = blocNum.toNumber()
}
async function tryBlockAndAggregate(calls: Call[]) {
return await multicall.callStatic.tryBlockAndAggregate(false, calls)
}
return {
multicall,
blockNumber,
results,
call,
}
}
function getInterface(contractInterface: ContractInterface): Interface {
if (Interface.isInterface(contractInterface)) {
return contractInterface
}
return new Interface(contractInterface)
}