@subsquid/evm-typegen 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/multicall.d.ts +48 -212
- package/lib/multicall.d.ts.map +1 -1
- package/lib/multicall.js +100 -178
- package/lib/multicall.js.map +1 -1
- package/package.json +3 -3
- package/src/multicall.ts +149 -197
package/lib/multicall.d.ts
CHANGED
|
@@ -1,216 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import {ContractBase, Func} from './abi.support'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const abi = new ethers.Interface([
|
|
8
|
-
{
|
|
9
|
-
type: 'function',
|
|
10
|
-
name: 'aggregate',
|
|
11
|
-
stateMutability: 'nonpayable',
|
|
12
|
-
inputs: [
|
|
13
|
-
{
|
|
14
|
-
name: 'calls',
|
|
15
|
-
type: 'tuple[]',
|
|
16
|
-
components: [
|
|
17
|
-
{name: 'target', type: 'address'},
|
|
18
|
-
{name: 'callData', type: 'bytes'},
|
|
19
|
-
]
|
|
20
|
-
}
|
|
21
|
-
],
|
|
22
|
-
outputs: [
|
|
23
|
-
{name: 'blockNumber', type: 'uint256'},
|
|
24
|
-
{name: 'returnData', type: 'bytes[]'},
|
|
25
|
-
]
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
name: 'tryAggregate',
|
|
29
|
-
type: 'function',
|
|
30
|
-
stateMutability: 'nonpayable',
|
|
31
|
-
inputs: [
|
|
32
|
-
{name: 'requireSuccess', type: 'bool'},
|
|
33
|
-
{
|
|
34
|
-
name: 'calls',
|
|
35
|
-
type: 'tuple[]',
|
|
36
|
-
components: [
|
|
37
|
-
{name: 'target', type: 'address'},
|
|
38
|
-
{name: 'callData', type: 'bytes'},
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
],
|
|
42
|
-
outputs: [
|
|
43
|
-
{
|
|
44
|
-
name: 'returnData',
|
|
45
|
-
type: 'tuple[]',
|
|
46
|
-
components: [
|
|
47
|
-
{name: 'success', type: 'bool'},
|
|
48
|
-
{name: 'returnData', type: 'bytes'},
|
|
49
|
-
]
|
|
50
|
-
},
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
])
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
type AnyFunc = Func<any, {}, any>
|
|
57
|
-
type Call = [address: string, bytes: string]
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const aggregate = new Func<[calls: Call[]], {}, {blockNumber: bigint, returnData: string[]}>(
|
|
61
|
-
abi, abi.getFunction('aggregate')!.selector
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const try_aggregate = new Func<[requireSuccess: boolean, calls: Array<[target: string, callData: string]>], {}, Array<{success: boolean, returnData: string}>>(
|
|
66
|
-
abi, abi.getFunction('tryAggregate')!.selector
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
|
|
1
|
+
import * as p from '@subsquid/evm-codec';
|
|
2
|
+
import { ContractBase, AbiFunction } from '@subsquid/evm-abi';
|
|
3
|
+
import { Codec, Struct } from "@subsquid/evm-codec";
|
|
70
4
|
export type MulticallResult<T> = {
|
|
71
|
-
success: true
|
|
72
|
-
value: T
|
|
5
|
+
success: true;
|
|
6
|
+
value: T;
|
|
73
7
|
} | {
|
|
74
|
-
success: false
|
|
75
|
-
returnData?: string
|
|
76
|
-
value?: undefined
|
|
8
|
+
success: false;
|
|
9
|
+
returnData?: string;
|
|
10
|
+
value?: undefined;
|
|
11
|
+
};
|
|
12
|
+
type AnyFunc = AbiFunction<any, any>;
|
|
13
|
+
type AggregateTuple<T extends AnyFunc = AnyFunc> = [func: T, address: string, args: T extends AbiFunction<infer U, any> ? U : never];
|
|
14
|
+
export declare class Multicall extends ContractBase {
|
|
15
|
+
static aggregate: AbiFunction<{
|
|
16
|
+
readonly calls: p.Codec<{
|
|
17
|
+
readonly target: string;
|
|
18
|
+
readonly callData: string | Uint8Array;
|
|
19
|
+
}[], {
|
|
20
|
+
readonly target: string;
|
|
21
|
+
readonly callData: string;
|
|
22
|
+
}[]>;
|
|
23
|
+
}, {
|
|
24
|
+
readonly blockNumber: p.Codec<number | bigint, bigint>;
|
|
25
|
+
readonly returnData: p.Codec<(string | Uint8Array)[], string[]>;
|
|
26
|
+
}>;
|
|
27
|
+
static tryAggregate: AbiFunction<{
|
|
28
|
+
readonly requireSuccess: p.Codec<boolean, boolean>;
|
|
29
|
+
readonly calls: p.Codec<{
|
|
30
|
+
readonly target: string;
|
|
31
|
+
readonly callData: string | Uint8Array;
|
|
32
|
+
}[], {
|
|
33
|
+
readonly target: string;
|
|
34
|
+
readonly callData: string;
|
|
35
|
+
}[]>;
|
|
36
|
+
}, p.Codec<{
|
|
37
|
+
readonly success: boolean;
|
|
38
|
+
readonly returnData: string | Uint8Array;
|
|
39
|
+
}[], {
|
|
40
|
+
readonly success: boolean;
|
|
41
|
+
readonly returnData: string;
|
|
42
|
+
}[]>>;
|
|
43
|
+
aggregate<Args extends Struct, R extends Struct | Codec<any, any>>(func: AbiFunction<Args, R>, address: string, calls: Args[], paging?: number): Promise<R[]>;
|
|
44
|
+
aggregate<Args extends Struct, R extends Struct | Codec<any, any>>(func: AbiFunction<Args, R>, calls: [address: string, args: Args][], paging?: number): Promise<R[]>;
|
|
45
|
+
aggregate(calls: AggregateTuple[], paging?: number): Promise<any[]>;
|
|
46
|
+
tryAggregate<Args extends Struct, R extends Struct | Codec<any, any>>(func: AbiFunction<Args, R>, address: string, calls: Args[], paging?: number): Promise<MulticallResult<R>[]>;
|
|
47
|
+
tryAggregate<Args extends Struct, R extends Struct | Codec<any, any>>(func: AbiFunction<Args, R>, calls: [address: string, args: Args][], paging?: number): Promise<MulticallResult<R>[]>;
|
|
48
|
+
tryAggregate(calls: AggregateTuple[], paging?: number): Promise<MulticallResult<any>[]>;
|
|
49
|
+
private makeCalls;
|
|
77
50
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
export class Multicall extends ContractBase {
|
|
81
|
-
static aggregate = aggregate
|
|
82
|
-
static try_aggregate = try_aggregate
|
|
83
|
-
|
|
84
|
-
aggregate<Args extends any[], R>(
|
|
85
|
-
func: Func<Args, {}, R>,
|
|
86
|
-
address: string,
|
|
87
|
-
calls: Args[],
|
|
88
|
-
paging?: number
|
|
89
|
-
): Promise<R[]>
|
|
90
|
-
|
|
91
|
-
aggregate<Args extends any[], R>(
|
|
92
|
-
func: Func<Args, {}, R>,
|
|
93
|
-
calls: [address: string, args: Args][],
|
|
94
|
-
paging?: number
|
|
95
|
-
): Promise<R[]>
|
|
96
|
-
|
|
97
|
-
aggregate(
|
|
98
|
-
calls: [func: AnyFunc, address: string, args: any[]][],
|
|
99
|
-
paging?: number
|
|
100
|
-
): Promise<any[]>
|
|
101
|
-
|
|
102
|
-
async aggregate(...args: any[]): Promise<any[]> {
|
|
103
|
-
let [calls, funcs, page] = this.makeCalls(args)
|
|
104
|
-
let size = calls.length
|
|
105
|
-
let results = new Array(size)
|
|
106
|
-
for (let [from, to] of splitIntoPages(size, page)) {
|
|
107
|
-
let {returnData} = await this.eth_call(aggregate, [calls.slice(from, to)])
|
|
108
|
-
for (let i = from; i < to; i++) {
|
|
109
|
-
let data = returnData[i - from]
|
|
110
|
-
results[i] = funcs[i].decodeResult(data)
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return results
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
tryAggregate<Args extends any[], R>(
|
|
117
|
-
func: Func<Args, {}, R>,
|
|
118
|
-
address: string,
|
|
119
|
-
calls: Args[],
|
|
120
|
-
paging?: number
|
|
121
|
-
): Promise<MulticallResult<R>[]>
|
|
122
|
-
|
|
123
|
-
tryAggregate<Args extends any[], R>(
|
|
124
|
-
func: Func<Args, {}, R>,
|
|
125
|
-
calls: [address: string, args: Args][],
|
|
126
|
-
paging?: number
|
|
127
|
-
): Promise<MulticallResult<R>[]>
|
|
128
|
-
|
|
129
|
-
tryAggregate(
|
|
130
|
-
calls: [func: AnyFunc, address: string, args: any[]][],
|
|
131
|
-
paging?: number
|
|
132
|
-
): Promise<MulticallResult<any>[]>
|
|
133
|
-
|
|
134
|
-
async tryAggregate(...args: any[]): Promise<any[]> {
|
|
135
|
-
let [calls, funcs, page] = this.makeCalls(args)
|
|
136
|
-
let size = calls.length
|
|
137
|
-
let results = new Array(size)
|
|
138
|
-
for (let [from, to] of splitIntoPages(size, page)) {
|
|
139
|
-
let response = await this.eth_call(try_aggregate, [false, calls.slice(from, to)])
|
|
140
|
-
for (let i = from; i < to; i++) {
|
|
141
|
-
let res = response[i - from]
|
|
142
|
-
if (res.success) {
|
|
143
|
-
try {
|
|
144
|
-
results[i] = {
|
|
145
|
-
success: true,
|
|
146
|
-
value: funcs[i].decodeResult(res.returnData)
|
|
147
|
-
}
|
|
148
|
-
} catch(err: any) {
|
|
149
|
-
results[i] = {success: false, returnData: res.returnData}
|
|
150
|
-
}
|
|
151
|
-
} else {
|
|
152
|
-
results[i] = {success: false}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return results
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
private makeCalls(args: any[]): [calls: Call[], funcs: AnyFunc[], page: number] {
|
|
160
|
-
let page = typeof args[args.length-1] == 'number' ? args.pop()! : Number.MAX_SAFE_INTEGER
|
|
161
|
-
switch(args.length) {
|
|
162
|
-
case 1: {
|
|
163
|
-
let list: [func: AnyFunc, address: string, args: any[]][] = args[0]
|
|
164
|
-
let calls = new Array(list.length)
|
|
165
|
-
let funcs = new Array(list.length)
|
|
166
|
-
for (let i = 0; i < list.length; i++) {
|
|
167
|
-
let [func, address, args] = list[i]
|
|
168
|
-
calls[i] = [address, func.encode(args)]
|
|
169
|
-
funcs[i] = func
|
|
170
|
-
}
|
|
171
|
-
return [calls, funcs, page]
|
|
172
|
-
}
|
|
173
|
-
case 2: {
|
|
174
|
-
let func: AnyFunc = args[0]
|
|
175
|
-
let list: [address: string, args: any[]][] = args[1]
|
|
176
|
-
let calls = new Array(list.length)
|
|
177
|
-
let funcs = new Array(list.length)
|
|
178
|
-
for (let i = 0; i < list.length; i++) {
|
|
179
|
-
let [address, args] = list[i]
|
|
180
|
-
calls[i] = [address, func.encode(args)]
|
|
181
|
-
funcs[i] = func
|
|
182
|
-
}
|
|
183
|
-
return [calls, funcs, page]
|
|
184
|
-
}
|
|
185
|
-
case 3: {
|
|
186
|
-
let func: AnyFunc = args[0]
|
|
187
|
-
let address: string = args[1]
|
|
188
|
-
let list: any[][] = args[2]
|
|
189
|
-
let calls = new Array(list.length)
|
|
190
|
-
let funcs = new Array(list.length)
|
|
191
|
-
for (let i = 0; i < list.length; i++) {
|
|
192
|
-
let args = list[i]
|
|
193
|
-
calls[i] = [address, func.encode(args)]
|
|
194
|
-
funcs[i] = func
|
|
195
|
-
}
|
|
196
|
-
return [calls, funcs, page]
|
|
197
|
-
}
|
|
198
|
-
default:
|
|
199
|
-
throw new Error('unexpected number of arguments')
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
function* splitIntoPages(size: number, page: number): Iterable<[from: number, to: number]> {
|
|
206
|
-
let from = 0
|
|
207
|
-
while (size) {
|
|
208
|
-
let step = Math.min(page, size)
|
|
209
|
-
let to = from + step
|
|
210
|
-
yield [from, to]
|
|
211
|
-
size -= step
|
|
212
|
-
from = to
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
*/
|
|
51
|
+
export {};
|
|
216
52
|
//# sourceMappingURL=multicall.d.ts.map
|
package/lib/multicall.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multicall.d.ts","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"multicall.d.ts","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,qBAAqB,CAAA;AACxC,OAAO,EAAM,YAAY,EAAE,WAAW,EAAC,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAC,KAAK,EAAE,MAAM,EAAC,MAAM,qBAAqB,CAAC;AAclD,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAC/B,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,CAAC,CAAA;CACT,GAAG;IACF,OAAO,EAAE,KAAK,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB,CAAA;AAED,KAAK,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;AACpC,KAAK,cAAc,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,SAAS,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAA;AAGpI,qBAAa,SAAU,SAAQ,YAAY;IACzC,MAAM,CAAC,SAAS;;;;;;;;;;;OAAY;IAC5B,MAAM,CAAC,YAAY;;;;;;;;;;;;;;;UAAe;IAElC,SAAS,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAC/D,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,EAAE,CAAC;IAEf,SAAS,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAC/D,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EACtC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,EAAE,CAAC;IAEf,SAAS,CACP,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,EAAE,CAAC;IAgBjB,YAAY,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAClE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhC,YAAY,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAClE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EACtC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhC,YAAY,CACV,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;IA8BlC,OAAO,CAAC,SAAS;CA2ClB"}
|
package/lib/multicall.js
CHANGED
|
@@ -1,217 +1,139 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const abi = new ethers.Interface([
|
|
9
|
-
{
|
|
10
|
-
type: 'function',
|
|
11
|
-
name: 'aggregate',
|
|
12
|
-
stateMutability: 'nonpayable',
|
|
13
|
-
inputs: [
|
|
14
|
-
{
|
|
15
|
-
name: 'calls',
|
|
16
|
-
type: 'tuple[]',
|
|
17
|
-
components: [
|
|
18
|
-
{name: 'target', type: 'address'},
|
|
19
|
-
{name: 'callData', type: 'bytes'},
|
|
20
|
-
]
|
|
21
|
-
}
|
|
22
|
-
],
|
|
23
|
-
outputs: [
|
|
24
|
-
{name: 'blockNumber', type: 'uint256'},
|
|
25
|
-
{name: 'returnData', type: 'bytes[]'},
|
|
26
|
-
]
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
name: 'tryAggregate',
|
|
30
|
-
type: 'function',
|
|
31
|
-
stateMutability: 'nonpayable',
|
|
32
|
-
inputs: [
|
|
33
|
-
{name: 'requireSuccess', type: 'bool'},
|
|
34
|
-
{
|
|
35
|
-
name: 'calls',
|
|
36
|
-
type: 'tuple[]',
|
|
37
|
-
components: [
|
|
38
|
-
{name: 'target', type: 'address'},
|
|
39
|
-
{name: 'callData', type: 'bytes'},
|
|
40
|
-
]
|
|
41
|
-
}
|
|
42
|
-
],
|
|
43
|
-
outputs: [
|
|
44
|
-
{
|
|
45
|
-
name: 'returnData',
|
|
46
|
-
type: 'tuple[]',
|
|
47
|
-
components: [
|
|
48
|
-
{name: 'success', type: 'bool'},
|
|
49
|
-
{name: 'returnData', type: 'bytes'},
|
|
50
|
-
]
|
|
51
|
-
},
|
|
52
|
-
]
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
53
7
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
calls
|
|
89
|
-
|
|
90
|
-
): Promise<R[]>
|
|
91
|
-
|
|
92
|
-
aggregate<Args extends any[], R>(
|
|
93
|
-
func: Func<Args, {}, R>,
|
|
94
|
-
calls: [address: string, args: Args][],
|
|
95
|
-
paging?: number
|
|
96
|
-
): Promise<R[]>
|
|
97
|
-
|
|
98
|
-
aggregate(
|
|
99
|
-
calls: [func: AnyFunc, address: string, args: any[]][],
|
|
100
|
-
paging?: number
|
|
101
|
-
): Promise<any[]>
|
|
102
|
-
|
|
103
|
-
async aggregate(...args: any[]): Promise<any[]> {
|
|
104
|
-
let [calls, funcs, page] = this.makeCalls(args)
|
|
105
|
-
let size = calls.length
|
|
106
|
-
let results = new Array(size)
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.Multicall = void 0;
|
|
27
|
+
const p = __importStar(require("@subsquid/evm-codec"));
|
|
28
|
+
const evm_abi_1 = require("@subsquid/evm-abi");
|
|
29
|
+
const aggregate = (0, evm_abi_1.fun)('0x252dba42', {
|
|
30
|
+
calls: p.array(p.struct({
|
|
31
|
+
target: p.address,
|
|
32
|
+
callData: p.bytes
|
|
33
|
+
}))
|
|
34
|
+
}, { blockNumber: p.uint256, returnData: p.array(p.bytes) });
|
|
35
|
+
const tryAggregate = (0, evm_abi_1.fun)('0xbce38bd7', {
|
|
36
|
+
requireSuccess: p.bool,
|
|
37
|
+
calls: p.array(p.struct({ target: p.address, callData: p.bytes }))
|
|
38
|
+
}, p.array(p.struct({ success: p.bool, returnData: p.bytes })));
|
|
39
|
+
class Multicall extends evm_abi_1.ContractBase {
|
|
40
|
+
async aggregate(...args) {
|
|
41
|
+
let [calls, funcs, page] = this.makeCalls(args);
|
|
42
|
+
let size = calls.length;
|
|
43
|
+
let results = new Array(size);
|
|
107
44
|
for (let [from, to] of splitIntoPages(size, page)) {
|
|
108
|
-
let {returnData} = await this.eth_call(aggregate,
|
|
45
|
+
let { returnData } = await this.eth_call(aggregate, { calls: calls.slice(from, to) });
|
|
109
46
|
for (let i = from; i < to; i++) {
|
|
110
|
-
let data = returnData[i - from]
|
|
111
|
-
results[i] = funcs[i].decodeResult(data)
|
|
47
|
+
let data = returnData[i - from];
|
|
48
|
+
results[i] = funcs[i].decodeResult(data);
|
|
112
49
|
}
|
|
113
50
|
}
|
|
114
|
-
return results
|
|
51
|
+
return results;
|
|
115
52
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
calls: Args[],
|
|
121
|
-
paging?: number
|
|
122
|
-
): Promise<MulticallResult<R>[]>
|
|
123
|
-
|
|
124
|
-
tryAggregate<Args extends any[], R>(
|
|
125
|
-
func: Func<Args, {}, R>,
|
|
126
|
-
calls: [address: string, args: Args][],
|
|
127
|
-
paging?: number
|
|
128
|
-
): Promise<MulticallResult<R>[]>
|
|
129
|
-
|
|
130
|
-
tryAggregate(
|
|
131
|
-
calls: [func: AnyFunc, address: string, args: any[]][],
|
|
132
|
-
paging?: number
|
|
133
|
-
): Promise<MulticallResult<any>[]>
|
|
134
|
-
|
|
135
|
-
async tryAggregate(...args: any[]): Promise<any[]> {
|
|
136
|
-
let [calls, funcs, page] = this.makeCalls(args)
|
|
137
|
-
let size = calls.length
|
|
138
|
-
let results = new Array(size)
|
|
53
|
+
async tryAggregate(...args) {
|
|
54
|
+
let [calls, funcs, page] = this.makeCalls(args);
|
|
55
|
+
let size = calls.length;
|
|
56
|
+
let results = new Array(size);
|
|
139
57
|
for (let [from, to] of splitIntoPages(size, page)) {
|
|
140
|
-
let response = await this.eth_call(
|
|
58
|
+
let response = await this.eth_call(tryAggregate, {
|
|
59
|
+
requireSuccess: false,
|
|
60
|
+
calls: calls.slice(from, to)
|
|
61
|
+
});
|
|
141
62
|
for (let i = from; i < to; i++) {
|
|
142
|
-
let res = response[i - from]
|
|
63
|
+
let res = response[i - from];
|
|
143
64
|
if (res.success) {
|
|
144
65
|
try {
|
|
145
66
|
results[i] = {
|
|
146
67
|
success: true,
|
|
147
68
|
value: funcs[i].decodeResult(res.returnData)
|
|
148
|
-
}
|
|
149
|
-
} catch(err: any) {
|
|
150
|
-
results[i] = {success: false, returnData: res.returnData}
|
|
69
|
+
};
|
|
151
70
|
}
|
|
152
|
-
|
|
153
|
-
|
|
71
|
+
catch (err) {
|
|
72
|
+
results[i] = { success: false, returnData: res.returnData };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
results[i] = { success: false };
|
|
154
77
|
}
|
|
155
78
|
}
|
|
156
79
|
}
|
|
157
|
-
return results
|
|
80
|
+
return results;
|
|
158
81
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
switch(args.length) {
|
|
82
|
+
makeCalls(args) {
|
|
83
|
+
let page = typeof args[args.length - 1] == 'number' ? args.pop() : Number.MAX_SAFE_INTEGER;
|
|
84
|
+
switch (args.length) {
|
|
163
85
|
case 1: {
|
|
164
|
-
let list
|
|
165
|
-
let calls = new Array(list.length)
|
|
166
|
-
let funcs = new Array(list.length)
|
|
86
|
+
let list = args[0];
|
|
87
|
+
let calls = new Array(list.length);
|
|
88
|
+
let funcs = new Array(list.length);
|
|
167
89
|
for (let i = 0; i < list.length; i++) {
|
|
168
|
-
let [func, address, args] = list[i]
|
|
169
|
-
calls[i] =
|
|
170
|
-
funcs[i] = func
|
|
90
|
+
let [func, address, args] = list[i];
|
|
91
|
+
calls[i] = { target: address, callData: func.encode(args) };
|
|
92
|
+
funcs[i] = func;
|
|
171
93
|
}
|
|
172
|
-
return [calls, funcs, page]
|
|
94
|
+
return [calls, funcs, page];
|
|
173
95
|
}
|
|
174
96
|
case 2: {
|
|
175
|
-
let func
|
|
176
|
-
let list
|
|
177
|
-
let calls = new Array(list.length)
|
|
178
|
-
let funcs = new Array(list.length)
|
|
97
|
+
let func = args[0];
|
|
98
|
+
let list = args[1];
|
|
99
|
+
let calls = new Array(list.length);
|
|
100
|
+
let funcs = new Array(list.length);
|
|
179
101
|
for (let i = 0; i < list.length; i++) {
|
|
180
|
-
let [address, args] = list[i]
|
|
181
|
-
calls[i] =
|
|
182
|
-
funcs[i] = func
|
|
102
|
+
let [address, args] = list[i];
|
|
103
|
+
calls[i] = { target: address, callData: func.encode(args) };
|
|
104
|
+
funcs[i] = func;
|
|
183
105
|
}
|
|
184
|
-
return [calls, funcs, page]
|
|
106
|
+
return [calls, funcs, page];
|
|
185
107
|
}
|
|
186
108
|
case 3: {
|
|
187
|
-
let func
|
|
188
|
-
let address
|
|
189
|
-
let list
|
|
190
|
-
let calls = new Array(list.length)
|
|
191
|
-
let funcs = new Array(list.length)
|
|
109
|
+
let func = args[0];
|
|
110
|
+
let address = args[1];
|
|
111
|
+
let list = args[2];
|
|
112
|
+
let calls = new Array(list.length);
|
|
113
|
+
let funcs = new Array(list.length);
|
|
192
114
|
for (let i = 0; i < list.length; i++) {
|
|
193
|
-
let args = list[i]
|
|
194
|
-
calls[i] =
|
|
195
|
-
funcs[i] = func
|
|
115
|
+
let args = list[i];
|
|
116
|
+
calls[i] = { target: address, callData: func.encode(args) };
|
|
117
|
+
funcs[i] = func;
|
|
196
118
|
}
|
|
197
|
-
return [calls, funcs, page]
|
|
119
|
+
return [calls, funcs, page];
|
|
198
120
|
}
|
|
199
121
|
default:
|
|
200
|
-
throw new Error('unexpected number of arguments')
|
|
122
|
+
throw new Error('unexpected number of arguments');
|
|
201
123
|
}
|
|
202
124
|
}
|
|
203
125
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
126
|
+
exports.Multicall = Multicall;
|
|
127
|
+
Multicall.aggregate = aggregate;
|
|
128
|
+
Multicall.tryAggregate = tryAggregate;
|
|
129
|
+
function* splitIntoPages(size, page) {
|
|
130
|
+
let from = 0;
|
|
208
131
|
while (size) {
|
|
209
|
-
let step = Math.min(page, size)
|
|
210
|
-
let to = from + step
|
|
211
|
-
yield [from, to]
|
|
212
|
-
size -= step
|
|
213
|
-
from = to
|
|
132
|
+
let step = Math.min(page, size);
|
|
133
|
+
let to = from + step;
|
|
134
|
+
yield [from, to];
|
|
135
|
+
size -= step;
|
|
136
|
+
from = to;
|
|
214
137
|
}
|
|
215
138
|
}
|
|
216
|
-
*/
|
|
217
139
|
//# sourceMappingURL=multicall.js.map
|
package/lib/multicall.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multicall.js","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"multicall.js","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@subsquid/evm-typegen",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "CLI for generating typescript types and decode implementations for evm logs",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"repository": "git@github.com:subsquid/squid.git",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"@subsquid/util-internal": "^3.2.0",
|
|
22
22
|
"@subsquid/util-internal-code-printer": "^1.2.2",
|
|
23
23
|
"@subsquid/util-internal-commander": "^1.4.0",
|
|
24
|
-
"@subsquid/evm-codec": "^0.
|
|
25
|
-
"@subsquid/evm-abi": "^0.1
|
|
24
|
+
"@subsquid/evm-codec": "^0.2.0",
|
|
25
|
+
"@subsquid/evm-abi": "^0.2.1",
|
|
26
26
|
"commander": "^11.1.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
package/src/multicall.ts
CHANGED
|
@@ -1,215 +1,167 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
components: [
|
|
17
|
-
{name: 'target', type: 'address'},
|
|
18
|
-
{name: 'callData', type: 'bytes'},
|
|
19
|
-
]
|
|
20
|
-
}
|
|
21
|
-
],
|
|
22
|
-
outputs: [
|
|
23
|
-
{name: 'blockNumber', type: 'uint256'},
|
|
24
|
-
{name: 'returnData', type: 'bytes[]'},
|
|
25
|
-
]
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
name: 'tryAggregate',
|
|
29
|
-
type: 'function',
|
|
30
|
-
stateMutability: 'nonpayable',
|
|
31
|
-
inputs: [
|
|
32
|
-
{name: 'requireSuccess', type: 'bool'},
|
|
33
|
-
{
|
|
34
|
-
name: 'calls',
|
|
35
|
-
type: 'tuple[]',
|
|
36
|
-
components: [
|
|
37
|
-
{name: 'target', type: 'address'},
|
|
38
|
-
{name: 'callData', type: 'bytes'},
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
],
|
|
42
|
-
outputs: [
|
|
43
|
-
{
|
|
44
|
-
name: 'returnData',
|
|
45
|
-
type: 'tuple[]',
|
|
46
|
-
components: [
|
|
47
|
-
{name: 'success', type: 'bool'},
|
|
48
|
-
{name: 'returnData', type: 'bytes'},
|
|
49
|
-
]
|
|
50
|
-
},
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
])
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
type AnyFunc = Func<any, {}, any>
|
|
57
|
-
type Call = [address: string, bytes: string]
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const aggregate = new Func<[calls: Call[]], {}, {blockNumber: bigint, returnData: string[]}>(
|
|
61
|
-
abi, abi.getFunction('aggregate')!.selector
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const try_aggregate = new Func<[requireSuccess: boolean, calls: Array<[target: string, callData: string]>], {}, Array<{success: boolean, returnData: string}>>(
|
|
66
|
-
abi, abi.getFunction('tryAggregate')!.selector
|
|
67
|
-
)
|
|
68
|
-
|
|
1
|
+
import * as p from '@subsquid/evm-codec'
|
|
2
|
+
import {fun, ContractBase, AbiFunction} from '@subsquid/evm-abi'
|
|
3
|
+
import {Codec, Struct} from "@subsquid/evm-codec";
|
|
4
|
+
|
|
5
|
+
const aggregate = fun('0x252dba42', {
|
|
6
|
+
calls: p.array(p.struct({
|
|
7
|
+
target: p.address,
|
|
8
|
+
callData: p.bytes
|
|
9
|
+
}))
|
|
10
|
+
}, {blockNumber: p.uint256, returnData: p.array(p.bytes)})
|
|
11
|
+
|
|
12
|
+
const tryAggregate = fun('0xbce38bd7', {
|
|
13
|
+
requireSuccess: p.bool,
|
|
14
|
+
calls: p.array(p.struct({target: p.address, callData: p.bytes}))
|
|
15
|
+
}, p.array(p.struct({success: p.bool, returnData: p.bytes})))
|
|
69
16
|
|
|
70
17
|
export type MulticallResult<T> = {
|
|
71
|
-
|
|
72
|
-
|
|
18
|
+
success: true
|
|
19
|
+
value: T
|
|
73
20
|
} | {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
21
|
+
success: false
|
|
22
|
+
returnData?: string
|
|
23
|
+
value?: undefined
|
|
77
24
|
}
|
|
78
25
|
|
|
26
|
+
type AnyFunc = AbiFunction<any, any>
|
|
27
|
+
type AggregateTuple<T extends AnyFunc = AnyFunc> = [func: T, address: string, args: T extends AbiFunction<infer U, any> ? U : never]
|
|
28
|
+
type Call = {target: string, callData: string}
|
|
79
29
|
|
|
80
30
|
export class Multicall extends ContractBase {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
return results
|
|
31
|
+
static aggregate = aggregate
|
|
32
|
+
static tryAggregate = tryAggregate
|
|
33
|
+
|
|
34
|
+
aggregate<Args extends Struct, R extends Struct | Codec<any, any>>(
|
|
35
|
+
func: AbiFunction<Args, R>,
|
|
36
|
+
address: string,
|
|
37
|
+
calls: Args[],
|
|
38
|
+
paging?: number
|
|
39
|
+
): Promise<R[]>
|
|
40
|
+
|
|
41
|
+
aggregate<Args extends Struct, R extends Struct | Codec<any, any>>(
|
|
42
|
+
func: AbiFunction<Args, R>,
|
|
43
|
+
calls: [address: string, args: Args][],
|
|
44
|
+
paging?: number
|
|
45
|
+
): Promise<R[]>
|
|
46
|
+
|
|
47
|
+
aggregate(
|
|
48
|
+
calls: AggregateTuple[],
|
|
49
|
+
paging?: number
|
|
50
|
+
): Promise<any[]>
|
|
51
|
+
|
|
52
|
+
async aggregate(...args: any[]): Promise<any[]> {
|
|
53
|
+
let [calls, funcs, page] = this.makeCalls(args)
|
|
54
|
+
let size = calls.length
|
|
55
|
+
let results = new Array(size)
|
|
56
|
+
for (let [from, to] of splitIntoPages(size, page)) {
|
|
57
|
+
let {returnData} = await this.eth_call(aggregate, {calls: calls.slice(from, to)})
|
|
58
|
+
for (let i = from; i < to; i++) {
|
|
59
|
+
let data = returnData[i - from]
|
|
60
|
+
results[i] = funcs[i].decodeResult(data)
|
|
61
|
+
}
|
|
114
62
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
results[i] = {success: false}
|
|
153
|
-
}
|
|
63
|
+
return results
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
tryAggregate<Args extends Struct, R extends Struct | Codec<any, any>>(
|
|
67
|
+
func: AbiFunction<Args, R>,
|
|
68
|
+
address: string,
|
|
69
|
+
calls: Args[],
|
|
70
|
+
paging?: number
|
|
71
|
+
): Promise<MulticallResult<R>[]>
|
|
72
|
+
|
|
73
|
+
tryAggregate<Args extends Struct, R extends Struct | Codec<any, any>>(
|
|
74
|
+
func: AbiFunction<Args, R>,
|
|
75
|
+
calls: [address: string, args: Args][],
|
|
76
|
+
paging?: number
|
|
77
|
+
): Promise<MulticallResult<R>[]>
|
|
78
|
+
|
|
79
|
+
tryAggregate(
|
|
80
|
+
calls: AggregateTuple[],
|
|
81
|
+
paging?: number
|
|
82
|
+
): Promise<MulticallResult<any>[]>
|
|
83
|
+
|
|
84
|
+
async tryAggregate(...args: any[]): Promise<any[]> {
|
|
85
|
+
let [calls, funcs, page] = this.makeCalls(args)
|
|
86
|
+
let size = calls.length
|
|
87
|
+
let results = new Array(size)
|
|
88
|
+
for (let [from, to] of splitIntoPages(size, page)) {
|
|
89
|
+
let response = await this.eth_call(tryAggregate, {
|
|
90
|
+
requireSuccess: false,
|
|
91
|
+
calls: calls.slice(from, to)
|
|
92
|
+
})
|
|
93
|
+
for (let i = from; i < to; i++) {
|
|
94
|
+
let res = response[i - from]
|
|
95
|
+
if (res.success) {
|
|
96
|
+
try {
|
|
97
|
+
results[i] = {
|
|
98
|
+
success: true,
|
|
99
|
+
value: funcs[i].decodeResult(res.returnData)
|
|
154
100
|
}
|
|
101
|
+
} catch (err: any) {
|
|
102
|
+
results[i] = {success: false, returnData: res.returnData}
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
results[i] = {success: false}
|
|
155
106
|
}
|
|
156
|
-
|
|
107
|
+
}
|
|
157
108
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
case 3: {
|
|
186
|
-
let func: AnyFunc = args[0]
|
|
187
|
-
let address: string = args[1]
|
|
188
|
-
let list: any[][] = args[2]
|
|
189
|
-
let calls = new Array(list.length)
|
|
190
|
-
let funcs = new Array(list.length)
|
|
191
|
-
for (let i = 0; i < list.length; i++) {
|
|
192
|
-
let args = list[i]
|
|
193
|
-
calls[i] = [address, func.encode(args)]
|
|
194
|
-
funcs[i] = func
|
|
195
|
-
}
|
|
196
|
-
return [calls, funcs, page]
|
|
197
|
-
}
|
|
198
|
-
default:
|
|
199
|
-
throw new Error('unexpected number of arguments')
|
|
109
|
+
return results
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private makeCalls(args: any[]): [calls: Call[], funcs: AnyFunc[], page: number] {
|
|
113
|
+
let page = typeof args[args.length - 1] == 'number' ? args.pop()! : Number.MAX_SAFE_INTEGER
|
|
114
|
+
switch (args.length) {
|
|
115
|
+
case 1: {
|
|
116
|
+
let list: AggregateTuple[] = args[0]
|
|
117
|
+
let calls: Call[] = new Array(list.length)
|
|
118
|
+
let funcs = new Array(list.length)
|
|
119
|
+
for (let i = 0; i < list.length; i++) {
|
|
120
|
+
let [func, address, args] = list[i]
|
|
121
|
+
calls[i] = {target: address, callData: func.encode(args)}
|
|
122
|
+
funcs[i] = func
|
|
123
|
+
}
|
|
124
|
+
return [calls, funcs, page]
|
|
125
|
+
}
|
|
126
|
+
case 2: {
|
|
127
|
+
let func: AnyFunc = args[0]
|
|
128
|
+
let list: [address: string, args: any][] = args[1]
|
|
129
|
+
let calls: Call[] = new Array(list.length)
|
|
130
|
+
let funcs = new Array(list.length)
|
|
131
|
+
for (let i = 0; i < list.length; i++) {
|
|
132
|
+
let [address, args] = list[i]
|
|
133
|
+
calls[i] = {target: address, callData: func.encode(args)}
|
|
134
|
+
funcs[i] = func
|
|
200
135
|
}
|
|
136
|
+
return [calls, funcs, page]
|
|
137
|
+
}
|
|
138
|
+
case 3: {
|
|
139
|
+
let func: AnyFunc = args[0]
|
|
140
|
+
let address: string = args[1]
|
|
141
|
+
let list: any = args[2]
|
|
142
|
+
let calls: Call[] = new Array(list.length)
|
|
143
|
+
let funcs = new Array(list.length)
|
|
144
|
+
for (let i = 0; i < list.length; i++) {
|
|
145
|
+
let args = list[i]
|
|
146
|
+
calls[i] = {target: address, callData: func.encode(args)}
|
|
147
|
+
funcs[i] = func
|
|
148
|
+
}
|
|
149
|
+
return [calls, funcs, page]
|
|
150
|
+
}
|
|
151
|
+
default:
|
|
152
|
+
throw new Error('unexpected number of arguments')
|
|
201
153
|
}
|
|
154
|
+
}
|
|
202
155
|
}
|
|
203
156
|
|
|
204
157
|
|
|
205
158
|
function* splitIntoPages(size: number, page: number): Iterable<[from: number, to: number]> {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
159
|
+
let from = 0
|
|
160
|
+
while (size) {
|
|
161
|
+
let step = Math.min(page, size)
|
|
162
|
+
let to = from + step
|
|
163
|
+
yield [from, to]
|
|
164
|
+
size -= step
|
|
165
|
+
from = to
|
|
166
|
+
}
|
|
214
167
|
}
|
|
215
|
-
*/
|