Skip to content

Commit d1011cc

Browse files
committed
support ability to tryAggregate
1 parent 5dc9d4a commit d1011cc

File tree

6 files changed

+248
-39
lines changed

6 files changed

+248
-39
lines changed

README.md

Lines changed: 105 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ let provider = ethers.getDefaultProvider();
7373
// you can use any ethers provider context here this example is
7474
// just shows passing in a default provider, ethers hold providers in
7575
// other context like wallet, signer etc all can be passed in as well.
76-
const multicall = new Multicall({ ethersProvider: wallet.provider });
76+
const multicall = new Multicall({ ethersProvider: wallet.provider, tryAggregate: true });
7777

7878
const contractCallContext: ContractCallContext<{extraContext: string, foo4: boolean}>[] = [
7979
{
@@ -112,7 +112,8 @@ console.log(results);
112112
decoded: true,
113113
reference: 'fooCall',
114114
methodName: 'foo',
115-
methodParameters: [42]
115+
methodParameters: [42],
116+
success: true
116117
}]
117118
},
118119
testContract2: {
@@ -127,7 +128,8 @@ console.log(results);
127128
decoded: true,
128129
reference: 'fooCall',
129130
methodName: 'foo',
130-
methodParameters: [42]
131+
methodParameters: [42],
132+
success: true
131133
}]
132134
}
133135
},
@@ -147,7 +149,7 @@ import Web3 from 'web3';
147149

148150
const web3 = new Web3('https://some.local-or-remote.node:8546');
149151

150-
const multicall = new Multicall({ web3Instance: web3 });
152+
const multicall = new Multicall({ web3Instance: web3, tryAggregate: true });
151153

152154
const contractCallContext: ContractCallContext[] = [
153155
{
@@ -182,7 +184,8 @@ console.log(results);
182184
decoded: true,
183185
reference: 'fooCall',
184186
methodName: 'foo',
185-
methodParameters: [42]
187+
methodParameters: [42],
188+
success: true
186189
}]
187190
},
188191
testContract2: {
@@ -197,7 +200,8 @@ console.log(results);
197200
decoded: true,
198201
reference: 'fooCall',
199202
methodName: 'foo',
200-
methodParameters: [42]
203+
methodParameters: [42],
204+
success: true
201205
}]
202206
}
203207
},
@@ -222,7 +226,7 @@ let provider = ethers.getDefaultProvider();
222226
// you can use any ethers provider context here this example is
223227
// just shows passing in a default provider, ethers hold providers in
224228
// other context like wallet, signer etc all can be passed in as well.
225-
const multicall = new Multicall({ ethersProvider: wallet.provider });
229+
const multicall = new Multicall({ ethersProvider: wallet.provider, tryAggregate: true });
226230

227231
// this is showing you having the same context for all `ContractCallContext` but you can also make this have
228232
// different context for each `ContractCallContext`, as `ContractCallContext<TContext>` takes generic `TContext`.
@@ -273,7 +277,8 @@ console.log(results);
273277
decoded: true,
274278
reference: 'fooCall',
275279
methodName: 'foo',
276-
methodParameters: [42]
280+
methodParameters: [42],
281+
success: true
277282
}]
278283
},
279284
testContract2: {
@@ -292,7 +297,87 @@ console.log(results);
292297
decoded: true,
293298
reference: 'fooCall',
294299
methodName: 'foo',
295-
methodParameters: [42]
300+
methodParameters: [42],
301+
success: true
302+
}]
303+
}
304+
},
305+
blockNumber: 10994677
306+
}
307+
```
308+
309+
### try aggregate
310+
311+
By default if you dont turn `tryAggregate` to true if 1 `eth_call` fails in your multicall the whole result will throw. If you turn `tryAggregate` to true it means if 1 of your `eth_call` methods fail it still return you the rest of the results. It will still be in the same order as you expect but you have a `success` boolean to check if it passed or failed.
312+
313+
```ts
314+
import {
315+
Multicall,
316+
ContractCallResults,
317+
ContractCallContext,
318+
} from 'ethereum-multicall';
319+
320+
const multicall = new Multicall({ nodeUrl: 'https://some.local-or-remote.node:8546', tryAggregate: true });
321+
322+
const contractCallContext: ContractCallContext[] = [
323+
{
324+
reference: 'testContract',
325+
contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3',
326+
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' }] } ],
327+
calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }, { reference: 'fooCall_fail', methodName: 'foo_fail', methodParameters: [42] }]
328+
},
329+
{
330+
reference: 'testContract2',
331+
contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318',
332+
abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256', name: "path", "type": "address[]" }] } ],
333+
calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }]
334+
}
335+
];
336+
337+
const results: ContractCallResults = await multicall.call(contractCallContext);
338+
console.log(results);
339+
340+
// results:
341+
{
342+
results: {
343+
testContract: {
344+
originalContractCallContext: {
345+
reference: 'testContract',
346+
contractAddress: '0x6795b15f3b16Cf8fB3E56499bbC07F6261e9b0C3',
347+
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' }] } ],
348+
calls: [{ reference: 'fooCall', methodName: 'foo', methodParameters: [42] }, { reference: 'fooCall_fail', methodName: 'foo_fail', methodParameters: [42] }]
349+
},
350+
callsReturnContext: [{
351+
returnValues: [{ amounts: BigNumber }],
352+
decoded: true,
353+
reference: 'fooCall',
354+
methodName: 'foo',
355+
methodParameters: [42],
356+
success: true
357+
},
358+
{
359+
returnValues: [],
360+
decoded: false,
361+
reference: 'fooCall_fail',
362+
methodName: 'foo_fail',
363+
methodParameters: [42],
364+
success: false
365+
}]
366+
},
367+
testContract2: {
368+
originalContractCallContext: {
369+
reference: 'testContract2',
370+
contractAddress: '0x66BF8e2E890eA0392e158e77C6381b34E0771318',
371+
abi: [ { name: 'fooTwo', type: 'function', inputs: [ { name: 'example', type: 'uint256' } ], outputs: [ { name: 'amounts', type: 'uint256[]' ] } ],
372+
calls: [{ reference: 'fooTwoCall', methodName: 'fooTwo', methodParameters: [42] }]
373+
},
374+
callsReturnContext: [{
375+
returnValues: [{ amounts: [BigNumber, BigNumber, BigNumber] }],
376+
decoded: true,
377+
reference: 'fooCall',
378+
methodName: 'foo',
379+
methodParameters: [42],
380+
success: true
296381
}]
297382
}
298383
},
@@ -309,7 +394,7 @@ import {
309394
ContractCallContext,
310395
} from 'ethereum-multicall';
311396

312-
const multicall = new Multicall({ nodeUrl: 'https://some.local-or-remote.node:8546' });
397+
const multicall = new Multicall({ nodeUrl: 'https://some.local-or-remote.node:8546', tryAggregate: true });
313398

314399
const contractCallContext: ContractCallContext[] = [
315400
{
@@ -344,7 +429,8 @@ console.log(results);
344429
decoded: true,
345430
reference: 'fooCall',
346431
methodName: 'foo',
347-
methodParameters: [42]
432+
methodParameters: [42],
433+
success: true
348434
}]
349435
},
350436
testContract2: {
@@ -359,7 +445,8 @@ console.log(results);
359445
decoded: true,
360446
reference: 'fooCall',
361447
methodName: 'foo',
362-
methodParameters: [42]
448+
methodParameters: [42],
449+
success: true
363450
}]
364451
}
365452
},
@@ -371,17 +458,17 @@ console.log(results);
371458
372459
by default it looks at your network from the provider you passed in and makes the contract address to that:
373460
374-
- mainnet > '0xeefba1e63905ef1d7acba5a8513c70307c1ce441'
375-
- kovan > '0x2cc8688c5f75e365aaeeb4ea8d6a480405a48d2a'
376-
- rinkeby > '0x42ad527de7d4e9d9d011ac45b31d8551f8fe9821'
377-
- ropsten > '0x53c43764255c17bd724f74c4ef150724ac50a3ed'
378-
- binance smart chain > '0x949f41e8a6197f2a19854f813fd361bab9aa7d2d'
461+
- mainnet > '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696'
462+
- kovan > '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696'
463+
- rinkeby > '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696'
464+
- ropsten > '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696'
465+
- binance smart chain > '0xaf379c844f87a7b47ee6fe5e4a9720988eaea0af'
379466
380467
If you wanted this to point at a different multicall contract address just pass that in the options when creating the multicall instance, example:
381468
382469
```ts
383470
const multicall = new Multicall({
384-
multicallCustomContractAddress: '0x5Eb3fa2DFECdDe21C950813C665E9364fa609bD2',
471+
multicallCustomContractAddress: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696',
385472
// your rest of your config depending on the provider your using.
386473
});
387474
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ethereum-multicall",
3-
"version": "2.1.1",
3+
"version": "2.2.0",
44
"description": "Multicall allows multiple smart contract constant function calls to be grouped into a single call and the results aggregated into a single result",
55
"main": "dist/index.js",
66
"scripts": {

src/models/aggregate-response.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ export interface AggregateResponse {
33
results: Array<{
44
contractContextIndex: number;
55
methodResults: Array<{
6-
// tslint:disable-next-line: no-any
7-
returnData: any;
86
contractMethodIndex: number;
7+
// tslint:disable-next-line: no-any
8+
result: any;
99
}>;
1010
}>;
1111
}

src/models/call-return-context.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ export interface CallReturnContext extends CallContext {
77
* This stats if it could decode the result or not
88
*/
99
decoded: boolean;
10+
11+
/**
12+
* If this context was successful, this will always be try
13+
* if you dont use the try aggregate logic
14+
*/
15+
success: boolean;
1016
}
1117

1218
// tslint:disable-next-line: no-any

src/models/multicall-options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Provider } from '@ethersproject/providers';
22

33
interface MulticallOptionsBase {
44
multicallCustomContractAddress?: string;
5+
tryAggregate?: boolean;
56
}
67

78
export interface MulticallOptionsWeb3 extends MulticallOptionsBase {

0 commit comments

Comments
 (0)