### Ethers Integration Example Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Demonstrates initializing Multicall with an ethers provider and executing contract calls. Handles multiple contract calls and logs the results. Ensure you have ethers.js installed. ```typescript import { Multicall, ContractCallResults, ContractCallContext, } from 'ethereum-multicall'; import { ethers } from 'ethers'; let provider = ethers.getDefaultProvider(); // you can use any ethers provider context here this example is // just shows passing in a default provider, ethers hold providers in // other context like wallet, signer etc all can be passed in as well. const multicall = new Multicall({ ethersProvider: provider, tryAggregate: true }); const contractCallContext: ContractCallContext[] = [ { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }] }, { reference: 'testContract2', contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318', abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256', name: "path", "type": "address[]" }] } ], calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }] } ]; const results: ContractCallResults = await multicall.call(contractCallContext); console.log(results); // results: { results: { testContract: { originalContractCallContext: { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }] }, callsReturnContext: [{ returnValues: [{ amounts: BigNumber }], decoded: true, reference: 'fooCall', methodName: 'foo', methodParameters: [42], success: true }] }, testContract2: { originalContractCallContext: { reference: 'testContract2', contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318', abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256[]' ] } ], calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }] }, callsReturnContext: [{ returnValues: [{ amounts: [BigNumber, BigNumber, BigNumber] }], decoded: true, reference: 'fooCall', methodName: 'foo', methodParameters: [42], success: true }] } }, blockNumber: 10994677 } ``` -------------------------------- ### Install ethereum-multicall with npm Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Use this command to add the library to your project using npm. ```bash $ npm install ethereum-multicall ``` -------------------------------- ### Install ethereum-multicall with yarn Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Use this command to add the library to your project using yarn. ```bash $ yarn add ethereum-multicall ``` -------------------------------- ### Web3 Usage Example with Ethereum Multicall Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Demonstrates how to use the ethereum-multicall library with a Web3.js instance to make multiple contract calls in a single transaction. Ensure you have the necessary imports and a Web3 instance configured. ```typescript import { Multicall, ContractCallResults, ContractCallContext, } from 'ethereum-multicall'; import Web3 from 'web3'; const web3 = new Web3('https://some.local-or-remote.node:8546'); const multicall = new Multicall({ web3Instance: web3, tryAggregate: true }); const contractCallContext: ContractCallContext[] = [ { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }] }, { reference: 'testContract2', contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318', abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256', name: "path", "type": "address[]" }] } ], calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }] } ]; const results: ContractCallResults = await multicall.call(contractCallContext); console.log(results); // results: { results: { testContract: { originalContractCallContext: { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }] }, callsReturnContext: [{ returnValues: [{ amounts: BigNumber }], decoded: true, reference: 'fooCall', methodName: 'foo', methodParameters: [42], success: true }] }, testContract2: { originalContractCallContext: { reference: 'testContract2', contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318', abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256[]' ] } ], calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }] }, callsReturnContext: [{ returnValues: [{ amounts: [BigNumber, BigNumber, BigNumber] }], decoded: true, reference: 'fooCall', methodName: 'foo', methodParameters: [42], success: true }] } }, blockNumber: 10994677 } ``` -------------------------------- ### Custom JSON-RPC Provider Usage Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Example demonstrating how to use a custom JSON-RPC provider with the Multicall instance. Ensure all necessary contract ABIs and call details are correctly provided. ```typescript import { Multicall, ContractCallResults, ContractCallContext, } from 'ethereum-multicall'; const multicall = new Multicall({ nodeUrl: 'https://some.local-or-remote.node:8546', tryAggregate: true }); const contractCallContext: ContractCallContext[] = [ { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }] }, { reference: 'testContract2', contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318', abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256', name: "path", "type": "address[]" }] } ], calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }] } ]; const results: ContractCallResults = await multicall.call(contractCallContext); console.log(results); // results: { results: { testContract: { originalContractCallContext: { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }] }, callsReturnContext: [{ returnValues: [{ amounts: BigNumber }], decoded: true, reference: 'fooCall', methodName: 'foo', methodParameters: [42], success: true }] }, testContract2: { originalContractCallContext: { reference: 'testContract2', contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318', abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256[]' ] } ], calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }] }, callsReturnContext: [{ returnValues: [{ amounts: [BigNumber, BigNumber, BigNumber] }], decoded: true, reference: 'fooCall', methodName: 'foo', methodParameters: [42], success: true }] } }, blockNumber: 10994677 } ``` -------------------------------- ### Define Contract Call Context for Overloaded Methods Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md When dealing with overloaded contract methods, use the full typed signature in 'methodName' and provide appropriate 'methodParameters'. This example demonstrates calling 'getVirtualPrice' with and without an input parameter. ```javascript const contractCallContext = { reference: 'upV2Controller', contractAddress: '0x19891DdF6F393C02E484D7a942d4BF8C0dB1d001', abi: [ { inputs: [], name: 'getVirtualPrice', outputs: [ { internalType: 'uint256', name: '', type: 'uint256', }, ], stateMutability: 'view', type: 'function', }, { inputs: [ { internalType: 'uint256', name: 'sentValue', type: 'uint256', }, ], name: 'getVirtualPrice', outputs: [ { internalType: 'uint256', name: '', type: 'uint256', }, ], stateMutability: 'view', type: 'function', }, ], calls: [ { reference: 'getVirtualPriceWithInput', methodName: 'getVirtualPrice(uint256)', methodParameters: ['0xFFFFFFFFFFFFF'], }, { reference: 'getVirtualPriceWithoutInput', methodName: 'getVirtualPrice()', methodParameters: [], }, ], }; ``` -------------------------------- ### Import ethereum-multicall (ES5/ES6) Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Standard CommonJS import for Node.js environments. ```javascript const ethereumMulticall = require('ethereum-multicall'); ``` -------------------------------- ### Create Multicall instance with Web3 Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Instantiates the Multicall class using a Web3 instance. The network is resolved via `web3.eth.net.getId()`. ```APIDOC ## new Multicall(options) - Create a Multicall instance with Web3 ### Description Instantiates the `Multicall` class using a Web3 instance. The network is resolved via `web3.eth.net.getId()`. ### Method ```typescript new Multicall({ web3Instance: Web3, tryAggregate?: boolean, multicallCustomContractAddress?: string }) ``` ### Parameters #### Options - **web3Instance** (Web3) - Required - The Web3 instance. - **tryAggregate** (boolean) - Optional - If true, individual call failures do not reject the entire batch. - **multicallCustomContractAddress** (string) - Optional - Override the default Multicall3 contract address. ### Request Example ```typescript import { Multicall } from 'ethereum-multicall'; import Web3 from 'web3'; const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_INFURA_KEY'); const multicall = new Multicall({ web3Instance: web3, tryAggregate: true, }); ``` ``` -------------------------------- ### Using tryAggregate in Multicall Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Demonstrates how to configure and execute a multicall with `tryAggregate` enabled. This allows for partial success, where individual failed calls do not halt the entire multicall. Ensure you are using a Multicall2 deployment for this functionality. ```typescript import { Multicall, ContractCallResults, ContractCallContext, } from 'ethereum-multicall'; const multicall = new Multicall({ nodeUrl: 'https://some.local-or-remote.node:8546', tryAggregate: true }); const contractCallContext: ContractCallContext[] = [ { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] }, { name: 'foo_fail', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }, { reference: 'fooCall_fail', methodName: 'foo_fail', methodParameters: [42] }] }, { reference: 'testContract2', contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318', abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256', name: "path", "type": "address[]" }] } ], calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }] } ]; const results: ContractCallResults = await multicall.call(contractCallContext); console.log(results); // results: { results: { testContract: { originalContractCallContext: { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] }, { name: 'foo_fail', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }, { reference: 'fooCall_fail', methodName: 'foo_fail', methodParameters: [42] }] }, callsReturnContext: [{ returnValues: [{ amounts: BigNumber }], decoded: true, reference: 'fooCall', methodName: 'foo', methodParameters: [42], success: true }, { returnValues: [], decoded: false, reference: 'fooCall_fail', methodName: 'foo_fail', methodParameters: [42], success: false }] }, testContract2: { originalContractCallContext: { reference: 'testContract2', contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318', abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256[]' ] } ], calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }] }, callsReturnContext: [{ returnValues: [{ amounts: [BigNumber, BigNumber, BigNumber] }], decoded: true, reference: 'fooCall', methodName: 'foo', methodParameters: [42], success: true }] } }, blockNumber: 10994677 } ``` -------------------------------- ### Create Multicall Instance with Web3 Instance Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Instantiate the Multicall class using a Web3 instance. The network is resolved via `web3.eth.net.getId()`. Ensure `tryAggregate` is set if partial call failures should not halt the entire batch. ```typescript import { Multicall } from 'ethereum-multicall'; import Web3 from 'web3'; const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_INFURA_KEY'); const multicall = new Multicall({ web3Instance: web3, tryAggregate: true, }); ``` -------------------------------- ### Import ethereum-multicall core classes (ES6/TypeScript) Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Import necessary classes for using ethereum-multicall in modern JavaScript or TypeScript projects. ```typescript import { Multicall, ContractCallResults, ContractCallContext, } from 'ethereum-multicall'; ``` -------------------------------- ### Import ethereum-multicall (ES3) Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Use this import statement for older JavaScript environments that support CommonJS modules. ```javascript var ethereumMulticall = require('ethereum-multicall'); ``` -------------------------------- ### Create Multicall instance with a custom JSON RPC node URL Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Instantiates the Multicall class by passing a raw node URL. Internally, the library creates an `ethers.providers.JsonRpcProvider` from the URL. ```APIDOC ## new Multicall(options) - Create a Multicall instance with a custom JSON RPC node URL ### Description Instantiates the `Multicall` class by passing a raw node URL. Internally, the library creates an `ethers.providers.JsonRpcProvider` from the URL. ### Method ```typescript new Multicall({ nodeUrl: string, tryAggregate?: boolean, multicallCustomContractAddress?: string }) ``` ### Parameters #### Options - **nodeUrl** (string) - Required - The URL of the JSON RPC node. - **tryAggregate** (boolean) - Optional - If true, individual call failures do not reject the entire batch. - **multicallCustomContractAddress** (string) - Optional - Override the default Multicall3 contract address. ### Request Example ```typescript import { Multicall } from 'ethereum-multicall'; const multicall = new Multicall({ nodeUrl: 'https://bsc-dataseed.binance.org/', tryAggregate: true, }); ``` ``` -------------------------------- ### Create Multicall Instance with Ethers Provider Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Instantiate the Multicall class using an ethers.js provider. This provider is used to determine the network's chain ID and submit batched calls. Setting `tryAggregate: true` allows individual call failures without rejecting the entire batch. ```typescript import { Multicall, ContractCallContext, ContractCallResults } from 'ethereum-multicall'; import { ethers } from 'ethers'; const provider = ethers.getDefaultProvider('homestead'); const multicall = new Multicall({ ethersProvider: provider, tryAggregate: true, // optional: override the default Multicall3 contract address // multicallCustomContractAddress: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696', }); ``` -------------------------------- ### Create Multicall Instance with Custom JSON RPC Node URL Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Instantiate the Multicall class by providing a raw node URL. The library internally creates an ethers.js JsonRpcProvider from this URL. `tryAggregate: true` is recommended for resilience against individual call failures. ```typescript import { Multicall } from 'ethereum-multicall'; const multicall = new Multicall({ nodeUrl: 'https://bsc-dataseed.binance.org/', tryAggregate: true, }); ``` -------------------------------- ### Create Multicall instance with ethers provider Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Instantiates the Multicall class using an ethers.js provider. The provider is used to determine the connected network's chain ID and to submit the batched call. `tryAggregate: true` means individual call failures do not throw for the whole batch. ```APIDOC ## new Multicall(options) - Create a Multicall instance with ethers provider ### Description Instantiates the `Multicall` class using an ethers.js provider. The provider is used to determine the connected network's chain ID and to submit the batched call. `tryAggregate: true` means individual call failures do not throw for the whole batch. ### Method ```typescript new Multicall({ ethersProvider: Provider, tryAggregate?: boolean, multicallCustomContractAddress?: string }) ``` ### Parameters #### Options - **ethersProvider** (ethers.Provider) - Required - The ethers.js provider instance. - **tryAggregate** (boolean) - Optional - If true, individual call failures do not reject the entire batch. - **multicallCustomContractAddress** (string) - Optional - Override the default Multicall3 contract address. ### Request Example ```typescript import { Multicall, ContractCallContext, ContractCallResults } from 'ethereum-multicall'; import { ethers } from 'ethers'; const provider = ethers.getDefaultProvider('homestead'); const multicall = new Multicall({ ethersProvider: provider, tryAggregate: true, // optional: override the default Multicall3 contract address // multicallCustomContractAddress: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696', }); ``` ``` -------------------------------- ### Batch Multiple Contract Calls with multicall.call Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Use this method to batch multiple contract calls into a single request. Each call context requires a reference, contract address, ABI, and a list of methods to invoke with their parameters. The results are returned keyed by the reference strings. ```typescript import { Multicall, ContractCallContext, ContractCallResults } from 'ethereum-multicall'; import { ethers } from 'ethers'; const provider = ethers.getDefaultProvider('homestead'); const multicall = new Multicall({ ethersProvider: provider, tryAggregate: true }); const ERC20_ABI = [ { name: 'balanceOf', type: 'function', inputs: [{ name: 'account', type: 'address' }], outputs: [{ name: '', type: 'uint256' }] }, { name: 'totalSupply', type: 'function', inputs: [], outputs: [{ name: '', type: 'uint256' }] }, { name: 'decimals', type: 'function', inputs: [], outputs: [{ name: '', type: 'uint8' }] }, ]; const USDC_ADDRESS = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; const DAI_ADDRESS = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; const WALLET = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'; const contractCallContexts: ContractCallContext[] = [ { reference: 'usdc', contractAddress: USDC_ADDRESS, abi: ERC20_ABI, calls: [ { reference: 'balance', methodName: 'balanceOf', methodParameters: [WALLET] }, { reference: 'totalSupply', methodName: 'totalSupply', methodParameters: [] }, { reference: 'decimals', methodName: 'decimals', methodParameters: [] }, ], }, { reference: 'dai', contractAddress: DAI_ADDRESS, abi: ERC20_ABI, calls: [ { reference: 'balance', methodName: 'balanceOf', methodParameters: [WALLET] }, { reference: 'totalSupply', methodName: 'totalSupply', methodParameters: [] }, ], }, ]; const results: ContractCallResults = await multicall.call(contractCallContexts); // Access USDC balance const usdcBalance = results.results['usdc'].callsReturnContext.find(c => c.reference === 'balance'); console.log('USDC balance raw:', usdcBalance?.returnValues[0].toString()); // e.g. "12500000" (6 decimals) // Access DAI total supply const daiSupply = results.results['dai'].callsReturnContext.find(c => c.reference === 'totalSupply'); console.log('DAI total supply:', daiSupply?.returnValues[0].toString()); console.log('Block number:', results.blockNumber); // Block number: 19800000 ``` -------------------------------- ### Batch multiple contract calls Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt This method allows you to batch multiple contract calls into a single transaction. It accepts a single `ContractCallContext` or an array of them. Each context specifies the target contract, its ABI, and the methods to call. The results are returned decoded and keyed by a reference string, along with the block number. ```APIDOC ## multicall.call(contractCallContexts) ### Description Batch multiple contract calls into a single transaction for efficiency. This method accepts a single `ContractCallContext` or an array of them. Each context defines a `reference` key, the target `contractAddress`, its `abi`, and a `calls` array of methods to invoke. ### Parameters #### Request Body - **contractCallContexts** (ContractCallContext[] | ContractCallContext) - Required - An array of contract call contexts or a single context. - **reference** (string) - Required - A unique identifier for this contract call context. - **contractAddress** (string) - Required - The address of the contract to call. - **abi** (object[]) - Required - The ABI of the contract. - **calls** (object[]) - Required - An array of calls to make on the contract. - **reference** (string) - Required - A unique identifier for this specific call within the context. - **methodName** (string) - Required - The name of the contract method to call. - **methodParameters** (any[]) - Required - An array of parameters to pass to the method. ### Response #### Success Response (200) - **results** (ContractCallResults) - An object containing the decoded return values keyed by the supplied `reference` strings. - **results** (object) - An object where keys are the `reference` strings from `contractCallContexts`. - **callsReturnContext** (object[]) - An array of results for each call made within this context. - **reference** (string) - The reference string for the call. - **returnValues** (any[]) - An array of decoded return values from the contract method. - **blockNumber** (number) - The block number at which the calls were executed. ### Request Example ```typescript const contractCallContexts: ContractCallContext[] = [ { reference: 'usdc', contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', abi: ERC20_ABI, calls: [ { reference: 'balance', methodName: 'balanceOf', methodParameters: [WALLET] }, { reference: 'totalSupply', methodName: 'totalSupply', methodParameters: [] }, { reference: 'decimals', methodName: 'decimals', methodParameters: [] }, ], }, { reference: 'dai', contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F', abi: ERC20_ABI, calls: [ { reference: 'balance', methodName: 'balanceOf', methodParameters: [WALLET] }, { reference: 'totalSupply', methodName: 'totalSupply', methodParameters: [] }, ], }, ]; const results: ContractCallResults = await multicall.call(contractCallContexts); ``` ### Response Example ```json { "results": { "usdc": { "callsReturnContext": [ { "reference": "balance", "returnValues": ["12500000"] }, { "reference": "totalSupply", "returnValues": ["1000000000000000000000000"] }, { "reference": "decimals", "returnValues": ["6"] } ] }, "dai": { "callsReturnContext": [ { "reference": "balance", "returnValues": ["5000000000000000000000000"] }, { "reference": "totalSupply", "returnValues": ["1000000000000000000000000000000"] } ] } }, "blockNumber": 19800000 } ``` ``` -------------------------------- ### Handle individual call failures with tryAggregate Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt When `tryAggregate` is enabled, failed individual `eth_call` operations within a batch do not halt the entire process. Instead, they are returned with `success: false` and `returnValues: []`, allowing successful calls to be processed normally. ```typescript import { Multicall, ContractCallContext, ContractCallResults } from 'ethereum-multicall'; import { ethers } from 'ethers'; const provider = ethers.getDefaultProvider('homestead'); const multicall = new Multicall({ ethersProvider: provider, tryAggregate: true }); const contractCallContext: ContractCallContext = { reference: 'mixedResults', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'workingMethod', type: 'function', inputs: [], outputs: [{ name: '', type: 'uint256' }] }, { name: 'revertingMethod', type: 'function', inputs: [], outputs: [{ name: '', type: 'uint256' }] }, ], calls: [ { reference: 'goodCall', methodName: 'workingMethod', methodParameters: [] }, { reference: 'badCall', methodName: 'revertingMethod', methodParameters: [] }, ], }; const results: ContractCallResults = await multicall.call(contractCallContext); const callReturns = results.results['mixedResults'].callsReturnContext; callReturns.forEach(ctx => { if (ctx.success) { console.log(`${ctx.reference} succeeded:`, ctx.returnValues[0].toString()); } else { console.log(`${ctx.reference} failed (success=false, decoded=false)`); } }); // goodCall succeeded: 42 // badCall failed (success=false, decoded=false) ``` -------------------------------- ### Specify Call Block Number with Ethereum Multicall Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Shows how to specify a particular block number for multicall requests using the optional second argument of the `multicall.call` method. This is compatible with both Ethers and Web3 providers. ```typescript import { Multicall, ContractCallResults, ContractCallContext, } from 'ethereum-multicall'; import Web3 from 'web3'; const web3 = new Web3('https://some.local-or-remote.node:8546'); const multicall = new Multicall({ web3Instance: web3, tryAggregate: true }); const contractCallContext: ContractCallContext[] = [ { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }] } ]; const results: ContractCallResults = await multicall.call(contractCallContext,{ blockNumber: '14571050' }); console.log(results); // results: it will have the same block as requested { results: { testContract: { originalContractCallContext: { reference: 'testContract', contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3', abi: [ { name: 'foo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256' }] } ], calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }] }, callsReturnContext: [{ returnValues: [{ amounts: BigNumber }], decoded: true, reference: 'fooCall', methodName: 'foo', methodParameters: [42], success: true }] }, }, blockNumber: 14571050 } ``` -------------------------------- ### Handle Overloaded Methods with Full Signatures Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt When contracts have overloaded functions, use their full typed signature strings to specify which overload to call. This ensures correct function resolution. ```typescript import { Multicall, ContractCallContext, ContractCallResults } from 'ethereum-multicall'; import { ethers } from 'ethers'; const provider = ethers.getDefaultProvider('homestead'); const multicall = new Multicall({ ethersProvider: provider, tryAggregate: true }); const contractCallContext: ContractCallContext = { reference: 'curvePool', contractAddress: '0x19891DdF6F393C02E484D7a942d4BF8C0dB1d001', abi: [ { inputs: [], name: 'getVirtualPrice', outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], stateMutability: 'view', type: 'function', }, { inputs: [{ internalType: 'uint256', name: 'sentValue', type: 'uint256' }], name: 'getVirtualPrice', outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], stateMutability: 'view', type: 'function', }, ], calls: [ // Use the full typed signature to target the overload with no arguments { reference: 'priceNoArgs', methodName: 'getVirtualPrice()', methodParameters: [] }, // Use the full typed signature to target the overload that takes a uint256 { reference: 'priceWithArgs', methodName: 'getVirtualPrice(uint256)', methodParameters: ['0xFFFFFFFFFFFFF'] }, ], }; const results: ContractCallResults = await multicall.call(contractCallContext); const calls = results.results['curvePool'].callsReturnContext; console.log('Price (no args):', calls.find(c => c.reference === 'priceNoArgs')?.returnValues[0].toString()); console.log('Price (with args):', calls.find(c => c.reference === 'priceWithArgs')?.returnValues[0].toString()); ``` -------------------------------- ### Interact Directly with Multicall Contract using Static ABI Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Utilize the static ABI of the Multicall contract to interact with it directly using ethers. This allows calling methods like `aggregate` outside the library's `call()` method. ```typescript import { Multicall } from 'ethereum-multicall'; import { ethers } from 'ethers'; const provider = ethers.getDefaultProvider('homestead'); // Use the static ABI to instantiate a raw ethers Contract const multicallContract = new ethers.Contract( '0xcA11bde05977b3631167028862bE2a173976CA11', Multicall.ABI, provider ); // Call aggregate directly const calls = [ { target: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', callData: '0x18160ddd', // totalSupply() selector }, ]; const [blockNumber, returnData] = await multicallContract.callStatic.aggregate(calls); console.log('Block:', blockNumber.toString()); console.log('Raw return data:', returnData); ``` -------------------------------- ### Use Custom Multicall Contract Address Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Specify a custom Multicall contract address during instantiation for unsupported networks or specific deployments. Requires a Web3 instance. ```typescript import { Multicall, ContractCallContext, ContractCallResults } from 'ethereum-multicall'; import Web3 from 'web3'; // Example: a private or unsupported EVM chain const web3 = new Web3('https://rpc.my-private-chain.io'); const multicall = new Multicall({ web3Instance: web3, tryAggregate: true, multicallCustomContractAddress: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696', }); const contractCallContext: ContractCallContext = { reference: 'myContract', contractAddress: '0xAbCdEf0123456789AbCdEf0123456789AbCdEf01', abi: [ { name: 'getValue', type: 'function', inputs: [], outputs: [{ name: '', type: 'uint256' }] }, ], calls: [ { reference: 'getValue', methodName: 'getValue', methodParameters: [] }, ], }; const results: ContractCallResults = await multicall.call(contractCallContext); console.log(results.results['myContract'].callsReturnContext[0].returnValues[0].toString()); ``` -------------------------------- ### Query historical state at a specific block Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt This overload of the `multicall.call` method allows you to query contract states at a specific historical block number. By providing an optional `blockNumber` in the `ContractCallOptions`, you can ensure that all returned values are from that exact block. ```APIDOC ## multicall.call(contexts, { blockNumber }) ### Description Query historical state at a specific block. An optional second argument of type `ContractCallOptions` lets you specify a `blockNumber` string. Both ethers and Web3 providers are supported. All returned values are guaranteed to be from that exact block. ### Parameters #### Request Body - **contexts** (ContractCallContext[] | ContractCallContext) - Required - An array of contract call contexts or a single context. - **reference** (string) - Required - A unique identifier for this contract call context. - **contractAddress** (string) - Required - The address of the contract to call. - **abi** (object[]) - Required - The ABI of the contract. - **calls** (object[]) - Required - An array of calls to make on the contract. - **reference** (string) - Required - A unique identifier for this specific call within the context. - **methodName** (string) - Required - The name of the contract method to call. - **methodParameters** (any[]) - Required - An array of parameters to pass to the method. #### Request Body Options - **blockNumber** (string) - Optional - The block number at which to query the state. If not provided, the latest block is used. ### Response #### Success Response (200) - **results** (ContractCallResults) - An object containing the decoded return values keyed by the supplied `reference` strings. - **results** (object) - An object where keys are the `reference` strings from `contractCallContexts`. - **callsReturnContext** (object[]) - An array of results for each call made within this context. - **reference** (string) - The reference string for the call. - **returnValues** (any[]) - An array of decoded return values from the contract method. - **blockNumber** (number) - The block number at which the calls were executed. ### Request Example ```typescript const contractCallContext: ContractCallContext = { reference: 'uniswapPair', contractAddress: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc', abi: [ { name: 'getReserves', type: 'function', inputs: [], outputs: [ { name: '_reserve0', type: 'uint112' }, { name: '_reserve1', type: 'uint112' }, { name: '_blockTimestampLast', type: 'uint32' }, ]}, ], calls: [ { reference: 'reserves', methodName: 'getReserves', methodParameters: [] }, ], }; // Fetch state as it was at block 17_000_000 const results: ContractCallResults = await multicall.call(contractCallContext, { blockNumber: '17000000', }); ``` ### Response Example ```json { "results": { "uniswapPair": { "callsReturnContext": [ { "reference": "reserves", "returnValues": ["123456789012345678901234567890", "987654321098765432109876543210", "1678886400"] } ] } }, "blockNumber": 17000000 } ``` ``` -------------------------------- ### Query Historical State at a Specific Block with multicall.call Source: https://context7.com/joshstevens19/ethereum-multicall/llms.txt Query contract states at a specific historical block by providing an optional `blockNumber` in the `ContractCallOptions`. This is useful for analyzing past states of the blockchain. Both ethers and Web3 providers are supported. ```typescript import { Multicall, ContractCallContext, ContractCallResults } from 'ethereum-multicall'; import { ethers } from 'ethers'; const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY'); const multicall = new Multicall({ ethersProvider: provider, tryAggregate: false }); const contractCallContext: ContractCallContext = { reference: 'uniswapPair', contractAddress: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc', // USDC/ETH pair abi: [ { name: 'getReserves', type: 'function', inputs: [], outputs: [ { name: '_reserve0', type: 'uint112' }, { name: '_reserve1', type: 'uint112' }, { name: '_blockTimestampLast', type: 'uint32' }, ]}, ], calls: [ { reference: 'reserves', methodName: 'getReserves', methodParameters: [] }, ], }; // Fetch state as it was at block 17_000_000 const results: ContractCallResults = await multicall.call(contractCallContext, { blockNumber: '17000000', }); const reservesCtx = results.results['uniswapPair'].callsReturnContext[0]; console.log('reserve0:', reservesCtx.returnValues[0].toString()); console.log('reserve1:', reservesCtx.returnValues[1].toString()); console.log('Returned block:', results.blockNumber); // 17000000 ``` -------------------------------- ### Specify Custom Multicall Contract Address Source: https://github.com/joshstevens19/ethereum-multicall/blob/master/README.md Configure the Multicall instance to use a specific multicall contract address. This is useful if you are not using the default address deployed on most networks. ```typescript const multicall = new Multicall({ multicallCustomContractAddress: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696', // your rest of your config depending on the provider your using. }); ```