utils-blockchain
v1.0.1
Published
The TypeScript utility package designed for solving different problems in dApp development.
Maintainers
Readme
Blockchain Utils
The TypeScript utility package designed for addressing multicall problems in dApp development. Built upon the foundation of the 1inch multicall library.
Install
Node
npm install utils-blockchainYarn
yarn add utils-blockchainMulticall contract addresses
:warning: The MultiCall contract was not audited yet, so use at your OWN RISK! Syndika does not provide any guarantees or assurances!!!
Mainnet
| Name | Address | | -------- | ------------------------------------------ | | Ethereum | 0x8d035edd8e09c3283463dade67cc0d49d6868063 | | BSC | 0x804708de7af615085203fa2b18eae59c5738e2a9 | | Polygon | 0xe38D748a07a6e3f9911Ec53ed434af2aB65716bc |
Testnet
| Name | Address | | ------- | ------------------------------------------ | | Sepolia | 0x069C02e7fF41Fd3d3f0c3fa80Ce0cB3b368aCc31 | | Goerli | 0x20B136D01e87C99F2866f71C2d6Cc027E724AAF7 | | Mumbai | 0xe38D748a07a6e3f9911Ec53ed434af2aB65716bc |
Motivation
The purpose of this utility library is to efficiently execute multiple view calls simultaneously. It accomplishes this by taking a list of requests, dividing them into manageable chunks, and making batched calls to the provider. By reducing the number of requests and optimizing the request-response flow, the library significantly speeds up the process.
For instance, when comparing the time taken for 50 balanceOf requests, the difference in request time between a naive approach and the batch approach is substantial.
$ npm run benchmark
> [email protected] benchmark
> ts-node benchmark/multicall.benchmark.ts
Time spent to make 50 requests using Multicall: 219 ms
----------------------------------------------------------
Time spent to make 50 requests using Promise.all(): 1620 ms
Multicall saved 1401 ms
----------------------------------------------------------
Time spent to make 50 requests using separate calls: 9753 ms
Multicall saved 9534 msYou can play with various parameters by modifying the benchmark script from
benchmark/multicall.banchmark.tsdirectory and observing the difference.
The default multicall parameters are set as follows:
- maxChunkSize: 500
- retriesLimit: 3
- blockNumber: 'latest'
- gasBuffer: 100000
For better understanding of how requests are packed and all trade-offs made when splitting in batches, please refer to 1inch algorithm visualisation.
Library Usage
Initializing multicall service
import { Multicall } from 'utils-blockchain';
const providerURL = 'https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY';
const multicallService = await Multicall.init(providerURL);Request batch generation
import { Contract } from 'ethers';
const contract = new Contract(
'0xdAC17F958D2ee523a2206206994597C13D831ec7', // address of the requested contract
ABI, // abi of the requested contract
new JsonRpcProvider(providerURL) // JSON-RPC or Web3 provider
);
const functionName = 'balanceOf';
const targetTokenOwners = [
'0x1212121212121212121212121212121212121212',
'0x3434343434343434343434343434343434343434',
'0xabcabcabcabcabcabcabcabcabcabcabcabcabca',
];
const batch = await Promise.all(
targetTokenOwners.map(address => {
return multicall.getRequestObject(contract, functionName, [address]);
})
);The batch array is formatted in the following way:
[
{
to: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
data: '0x70a082310000000000000000000000001212121212121212121212121212121212121212',
gas: 146999999
},
{
to: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
data: '0x70a082310000000000000000000000003434343434343434343434343434343434343434',
gas: 146999999
},
{
to: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
data: '0x70a08231000000000000000000000000abcabcabcabcabcabcabcabcabcabcabcabcabca',
gas: 146999999
}
]Multicall request execution
const res = await multicallService.multicall(batch);The response array denotes the balances of the users specified in the request batch.
[
'0x000000000000000000000000000000000000000000000000000000000002528f',
'0x0000000000000000000000000000000000000000000000000000000000000000',
'0x0000000000000000000000000000000000000000000000000000000000000000'
]