Last active
June 19, 2025 09:10
-
-
Save AlcibiadesCleinias/822ac93d99648c177344ff576f03ebe9 to your computer and use it in GitHub Desktop.
Multicall3 Contract Client Class on Typescript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Resolve 2 TODOs and use multicall batch client. | |
import type { Interface, Result, ethers } from "ethers"; | |
import { type IMulticall3 } from "../../index.js"; // TODO: use your import (in this example I used typechain types with multicall3 contract) | |
export type Multicall3ContractCall = { target: string, allowFailure: boolean, callData: string }; | |
export type Aggregate3Response = { success: boolean; returnData: string }; | |
export type TxResultsConverter<T> = (result: Result, ...opt: any[]) => T; | |
/* | |
* @description Client to be inherited from to work with Multicall3 contract to perform batch calls. | |
* @dev For more info: https://github.com/mds1/multicall/tree/main. | |
*/ | |
export abstract class Multicall3ContractClient { | |
_caller: ethers.Provider | ethers.Signer; | |
_multicall3Contract: IMulticall3; | |
constructor(caller: ethers.Provider | ethers.Signer, multicall3ContractAddress: string) { | |
this._caller = caller | |
const multicall3Abi = []; // TODO: add abi here | |
this._multicall3Contract = new ethers.Contract(multicall3ContractAddress, multicall3Abi, this._caller) as unknown as IMulticall3; | |
} | |
async _callBatch<ConvertTo>( | |
callsEncoded: Multicall3ContractCall[], | |
callResultsInterface: Interface, | |
contractMethod: string, | |
txResultsConverter: TxResultsConverter<ConvertTo>, | |
): Promise<Array<ConvertTo>> { | |
console.group("[_callBatch]"); | |
console.info('Send batch request with callsEncoded = %s...', JSON.stringify(callsEncoded)) | |
const multicallContractCallResults: Aggregate3Response[] = await this._multicall3Contract.aggregate3.staticCall(callsEncoded); | |
let decodedResults: Array<ConvertTo> = [] | |
console.info("Decode and convert all results with converter %s", txResultsConverter.name) | |
for (const rawResult of multicallContractCallResults) { | |
console.info('Success status: %s', rawResult.success) | |
console.debug('Raw data: %s', rawResult.returnData) | |
const decoded = callResultsInterface.decodeFunctionResult(contractMethod, rawResult.returnData) | |
console.debug('Got after decoding: %s', decoded) | |
decodedResults.push( | |
txResultsConverter(decoded) | |
) | |
} | |
console.groupEnd(); | |
return decodedResults | |
} | |
_decodeToString(result: Result, defaultNoResult: string = ""): string { | |
if (!result) { | |
return defaultNoResult; | |
} | |
return result.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment