@woof-software/contracts-tools-sdk-ethers 0.0.1
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/README.md +8 -0
- package/lib/abis/index.d.ts +2 -0
- package/lib/abis/index.js +2 -0
- package/lib/abis/multicall.abi.json +440 -0
- package/lib/config.d.ts +37 -0
- package/lib/config.js +38 -0
- package/lib/constant.d.ts +12 -0
- package/lib/constant.js +12 -0
- package/lib/contract/base-contract.d.ts +23 -0
- package/lib/contract/base-contract.js +191 -0
- package/lib/contract/contract-create-call-name.d.ts +1 -0
- package/lib/contract/contract-create-call-name.js +1 -0
- package/lib/contract/index.d.ts +1 -0
- package/lib/contract/index.js +1 -0
- package/lib/errors/contracts-errors.d.ts +9 -0
- package/lib/errors/contracts-errors.js +9 -0
- package/lib/errors/index.d.ts +2 -0
- package/lib/errors/index.js +2 -0
- package/lib/errors/multicall-errors.d.ts +8 -0
- package/lib/errors/multicall-errors.js +8 -0
- package/lib/helpers/index.d.ts +6 -0
- package/lib/helpers/index.js +6 -0
- package/lib/helpers/is-parsable.d.ts +2 -0
- package/lib/helpers/is-parsable.js +1 -0
- package/lib/helpers/is-signer.d.ts +2 -0
- package/lib/helpers/is-signer.js +3 -0
- package/lib/helpers/is-static-array.d.ts +2 -0
- package/lib/helpers/is-static-array.js +2 -0
- package/lib/helpers/is-static-method.d.ts +2 -0
- package/lib/helpers/is-static-method.js +4 -0
- package/lib/helpers/priority-call.d.ts +5 -0
- package/lib/helpers/priority-call.js +55 -0
- package/lib/helpers/wait-for-address-txs.d.ts +2 -0
- package/lib/helpers/wait-for-address-txs.js +9 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +5 -0
- package/lib/multicall/index.d.ts +5 -0
- package/lib/multicall/index.js +5 -0
- package/lib/multicall/multicall-error-event-name.d.ts +2 -0
- package/lib/multicall/multicall-error-event-name.js +1 -0
- package/lib/multicall/multicall-generate-tag.d.ts +1 -0
- package/lib/multicall/multicall-generate-tag.js +1 -0
- package/lib/multicall/multicall-normalize-tags.d.ts +2 -0
- package/lib/multicall/multicall-normalize-tags.js +6 -0
- package/lib/multicall/multicall-result-event-name.d.ts +2 -0
- package/lib/multicall/multicall-result-event-name.js +1 -0
- package/lib/multicall/multicall-split-calls.d.ts +2 -0
- package/lib/multicall/multicall-split-calls.js +19 -0
- package/lib/multicall/multicall-unit.d.ts +48 -0
- package/lib/multicall/multicall-unit.js +367 -0
- package/lib/types/call-mutability.d.ts +4 -0
- package/lib/types/call-mutability.js +5 -0
- package/lib/types/contract/contract-auto-methods.d.ts +13 -0
- package/lib/types/contract/contract-auto-methods.js +1 -0
- package/lib/types/contract/contract-call-options.d.ts +9 -0
- package/lib/types/contract/contract-call-options.js +1 -0
- package/lib/types/contract/contract-call.d.ts +10 -0
- package/lib/types/contract/contract-call.js +1 -0
- package/lib/types/contract/contract-get-logs-options.d.ts +5 -0
- package/lib/types/contract/contract-get-logs-options.js +1 -0
- package/lib/types/contract/contract-options.d.ts +12 -0
- package/lib/types/contract/contract-options.js +1 -0
- package/lib/types/contract/dynamic-contract-constructor-args.d.ts +8 -0
- package/lib/types/contract/dynamic-contract-constructor-args.js +1 -0
- package/lib/types/contract/dynamic-contract-constructor.d.ts +3 -0
- package/lib/types/contract/dynamic-contract-constructor.js +1 -0
- package/lib/types/contract/dynamic-contract.d.ts +3 -0
- package/lib/types/contract/dynamic-contract.js +1 -0
- package/lib/types/contract/index.d.ts +6 -0
- package/lib/types/contract/index.js +6 -0
- package/lib/types/index.d.ts +6 -0
- package/lib/types/index.js +6 -0
- package/lib/types/multicall/index.d.ts +5 -0
- package/lib/types/multicall/index.js +5 -0
- package/lib/types/multicall/multicall-decodable-data.d.ts +5 -0
- package/lib/types/multicall/multicall-decodable-data.js +1 -0
- package/lib/types/multicall/multicall-options.d.ts +15 -0
- package/lib/types/multicall/multicall-options.js +1 -0
- package/lib/types/multicall/multicall-response.d.ts +5 -0
- package/lib/types/multicall/multicall-response.js +1 -0
- package/lib/types/multicall/multicall-tags.d.ts +4 -0
- package/lib/types/multicall/multicall-tags.js +1 -0
- package/lib/types/multicall/multicall-wait-options.d.ts +5 -0
- package/lib/types/multicall/multicall-wait-options.js +1 -0
- package/lib/types/priority-call-options.d.ts +8 -0
- package/lib/types/priority-call-options.js +1 -0
- package/lib/types/split-calls.d.ts +9 -0
- package/lib/types/split-calls.js +1 -0
- package/lib/types/state-mutabiity.d.ts +6 -0
- package/lib/types/state-mutabiity.js +7 -0
- package/lib/utils/check-signals.d.ts +1 -0
- package/lib/utils/check-signals.js +4 -0
- package/lib/utils/create-signals-promise.d.ts +1 -0
- package/lib/utils/create-signals-promise.js +8 -0
- package/lib/utils/create-timeout-signal.d.ts +1 -0
- package/lib/utils/create-timeout-signal.js +5 -0
- package/lib/utils/index.d.ts +6 -0
- package/lib/utils/index.js +6 -0
- package/lib/utils/race-with-signals.d.ts +1 -0
- package/lib/utils/race-with-signals.js +9 -0
- package/lib/utils/wait-with-signals.d.ts +1 -0
- package/lib/utils/wait-with-signals.js +18 -0
- package/package.json +44 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import { MulticallAbi } from "../abis";
|
|
3
|
+
import { config } from "../config";
|
|
4
|
+
import { MULTICALL_ADDRESS } from "../constant";
|
|
5
|
+
import { BaseContract } from "../contract";
|
|
6
|
+
import { MULTICALL_ERRORS } from "../errors";
|
|
7
|
+
import { isParsable, isStaticArray } from "../helpers";
|
|
8
|
+
import { CallMutability, } from "../types";
|
|
9
|
+
import { checkSignals, createTimeoutSignal, raceWithSignals, waitWithSignals, } from "../utils";
|
|
10
|
+
import { multicallErrorEventName } from "./multicall-error-event-name";
|
|
11
|
+
import { multicallNormalizeTags } from "./multicall-normalize-tags";
|
|
12
|
+
import { multicallResultEventName } from "./multicall-result-event-name";
|
|
13
|
+
import { multicallSplitCalls } from "./multicall-split-calls";
|
|
14
|
+
const aggregate3 = "aggregate3";
|
|
15
|
+
export class MulticallUnit extends BaseContract {
|
|
16
|
+
constructor(driver, options = {}, multicallAddress = MULTICALL_ADDRESS) {
|
|
17
|
+
const contractOptions = {
|
|
18
|
+
forceMutability: options.forceMutability,
|
|
19
|
+
highPriorityTxs: options.highPriorityTxs,
|
|
20
|
+
priorityOptions: options.priorityOptions,
|
|
21
|
+
signals: options.signals,
|
|
22
|
+
staticCallsTimeoutMs: options.staticCallsTimeoutMs,
|
|
23
|
+
mutableCallsTimeoutMs: options.mutableCallsTimeoutMs,
|
|
24
|
+
};
|
|
25
|
+
super(MulticallAbi, multicallAddress, driver, contractOptions);
|
|
26
|
+
this._units = new Map();
|
|
27
|
+
this._response = [];
|
|
28
|
+
this._rawData = new Map();
|
|
29
|
+
this._callsSuccess = new Map();
|
|
30
|
+
this._isExecuting = false;
|
|
31
|
+
this._emitter = new EventEmitter();
|
|
32
|
+
this._multicallOptions = {};
|
|
33
|
+
this._txResponses = new Map();
|
|
34
|
+
this._txReceipts = new Map();
|
|
35
|
+
this._multicallOptions = {
|
|
36
|
+
maxStaticCallsStack: config.multicallUnit.staticCalls.batchLimit,
|
|
37
|
+
maxMutableCallsStack: config.multicallUnit.mutableCalls.batchLimit,
|
|
38
|
+
waitForTxs: config.multicallUnit.waitForTxs,
|
|
39
|
+
waitCallsTimeoutMs: config.multicallUnit.waitCalls.timeoutMs,
|
|
40
|
+
batchDelayMs: config.multicallUnit.batchDelayMs,
|
|
41
|
+
...options,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
clear() {
|
|
45
|
+
this._units = new Map();
|
|
46
|
+
this._response = [];
|
|
47
|
+
this._rawData = new Map();
|
|
48
|
+
this._callsSuccess = new Map();
|
|
49
|
+
this._lastSuccess = undefined;
|
|
50
|
+
}
|
|
51
|
+
add(contractCall, tags) {
|
|
52
|
+
this._units.set(multicallNormalizeTags(tags), contractCall);
|
|
53
|
+
return tags;
|
|
54
|
+
}
|
|
55
|
+
get tags() {
|
|
56
|
+
return Array.from(this._units.keys()); // The order is guaranteed
|
|
57
|
+
}
|
|
58
|
+
get calls() {
|
|
59
|
+
return Array.from(this._units.values()); // The order is guaranteed
|
|
60
|
+
}
|
|
61
|
+
get response() {
|
|
62
|
+
return this._response;
|
|
63
|
+
}
|
|
64
|
+
get success() {
|
|
65
|
+
return this._lastSuccess;
|
|
66
|
+
}
|
|
67
|
+
get static() {
|
|
68
|
+
if (!this._units.size)
|
|
69
|
+
return true;
|
|
70
|
+
return isStaticArray(this.calls);
|
|
71
|
+
}
|
|
72
|
+
get executing() {
|
|
73
|
+
return this._isExecuting;
|
|
74
|
+
}
|
|
75
|
+
isSuccess(tags) {
|
|
76
|
+
return this._callsSuccess.get(multicallNormalizeTags(tags));
|
|
77
|
+
}
|
|
78
|
+
getRaw(tags) {
|
|
79
|
+
return this._rawData.get(multicallNormalizeTags(tags)) ?? null;
|
|
80
|
+
}
|
|
81
|
+
getSingle(tags) {
|
|
82
|
+
const data = this.getDecodableData(tags);
|
|
83
|
+
if (!data)
|
|
84
|
+
return null;
|
|
85
|
+
const [value] = data.call.contractInterface.decodeFunctionResult(data.call.method, data.rawData);
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
getArray(tags, deep = false) {
|
|
89
|
+
const data = this.getDecodableData(tags);
|
|
90
|
+
if (data === null)
|
|
91
|
+
return null;
|
|
92
|
+
return data.call
|
|
93
|
+
.contractInterface.decodeFunctionResult(data.call.method, data.rawData)
|
|
94
|
+
.toArray(deep);
|
|
95
|
+
}
|
|
96
|
+
async run(options = {}) {
|
|
97
|
+
const runOptions = {
|
|
98
|
+
...this._multicallOptions,
|
|
99
|
+
...options,
|
|
100
|
+
};
|
|
101
|
+
if (this._isExecuting)
|
|
102
|
+
throw MULTICALL_ERRORS.SIMULTANEOUS_INVOCATIONS;
|
|
103
|
+
this._isExecuting = true;
|
|
104
|
+
this._lastSuccess = undefined;
|
|
105
|
+
const tags = this.tags;
|
|
106
|
+
const calls = this.calls;
|
|
107
|
+
this._response = Array(tags.length).fill([undefined, null]);
|
|
108
|
+
try {
|
|
109
|
+
checkSignals(runOptions.signals);
|
|
110
|
+
let staticCalls;
|
|
111
|
+
let staticIndexes;
|
|
112
|
+
let mutableCalls;
|
|
113
|
+
let mutableTags;
|
|
114
|
+
let mutableIndexes;
|
|
115
|
+
if (runOptions.forceMutability) {
|
|
116
|
+
if (runOptions.forceMutability === CallMutability.Static) {
|
|
117
|
+
staticCalls = calls;
|
|
118
|
+
staticIndexes = Array.from({ length: calls.length }, (_, i) => i);
|
|
119
|
+
mutableCalls = [];
|
|
120
|
+
mutableTags = [];
|
|
121
|
+
mutableIndexes = [];
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
staticCalls = [];
|
|
125
|
+
staticIndexes = [];
|
|
126
|
+
mutableCalls = calls;
|
|
127
|
+
mutableTags = tags;
|
|
128
|
+
mutableIndexes = Array.from({ length: calls.length }, (_, i) => i);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
const split = multicallSplitCalls(calls, tags);
|
|
133
|
+
staticCalls = split.staticCalls;
|
|
134
|
+
staticIndexes = split.staticIndexes;
|
|
135
|
+
mutableCalls = split.mutableCalls;
|
|
136
|
+
mutableTags = split.mutableTags;
|
|
137
|
+
mutableIndexes = split.mutableIndexes;
|
|
138
|
+
}
|
|
139
|
+
// Process mutable
|
|
140
|
+
for (let i = 0; i < mutableCalls.length; i += runOptions.maxMutableCallsStack) {
|
|
141
|
+
checkSignals(runOptions.signals);
|
|
142
|
+
const border = Math.min(i + runOptions.maxMutableCallsStack, mutableCalls.length);
|
|
143
|
+
const iterationCalls = mutableCalls.slice(i, border); // half-opened interval
|
|
144
|
+
const iterationTags = mutableTags.slice(i, border);
|
|
145
|
+
const iterationIndexes = mutableIndexes.slice(i, border); // half-opened interval
|
|
146
|
+
const iterationResponse = await this.processMutableCalls(iterationCalls, iterationTags, runOptions);
|
|
147
|
+
this.saveResponse(iterationResponse, iterationIndexes, tags);
|
|
148
|
+
await waitWithSignals(runOptions.batchDelayMs, runOptions.signals);
|
|
149
|
+
}
|
|
150
|
+
// Process static
|
|
151
|
+
for (let i = 0; i < staticCalls.length; i += runOptions.maxStaticCallsStack) {
|
|
152
|
+
checkSignals(runOptions.signals);
|
|
153
|
+
const border = Math.min(i + runOptions.maxStaticCallsStack, staticCalls.length);
|
|
154
|
+
const iterationCalls = staticCalls.slice(i, border); // half-opened interval
|
|
155
|
+
const iterationIndexes = staticIndexes.slice(i, border); // half-opened interval
|
|
156
|
+
const iterationResponse = await this.processStaticCalls(iterationCalls, runOptions);
|
|
157
|
+
this.saveResponse(iterationResponse, iterationIndexes, tags);
|
|
158
|
+
await waitWithSignals(runOptions.batchDelayMs, runOptions.signals);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
this._lastSuccess = false;
|
|
163
|
+
tags.forEach((tag) => this._emitter.emit(multicallErrorEventName(tag), error)); // For unlock all the waiters
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
this._isExecuting = false;
|
|
168
|
+
}
|
|
169
|
+
return this._lastSuccess ?? false;
|
|
170
|
+
}
|
|
171
|
+
async processStaticCalls(iterationCalls, runOptions) {
|
|
172
|
+
const result = await this.call(aggregate3, [iterationCalls], {
|
|
173
|
+
forceMutability: CallMutability.Static,
|
|
174
|
+
signals: runOptions.signals,
|
|
175
|
+
timeoutMs: runOptions.staticCallsTimeoutMs,
|
|
176
|
+
});
|
|
177
|
+
this._lastSuccess = !(this._lastSuccess === false);
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
async processMutableCalls(iterationCalls, iterationTags, runOptions) {
|
|
181
|
+
let result;
|
|
182
|
+
const tx = (await this.call(aggregate3, [iterationCalls], {
|
|
183
|
+
forceMutability: CallMutability.Mutable,
|
|
184
|
+
highPriorityTx: runOptions.highPriorityTxs,
|
|
185
|
+
priorityOptions: runOptions.priorityOptions,
|
|
186
|
+
signals: runOptions.signals,
|
|
187
|
+
timeoutMs: runOptions.mutableCallsTimeoutMs,
|
|
188
|
+
}));
|
|
189
|
+
iterationTags.forEach((tag) => this._txResponses.set(tag, tx));
|
|
190
|
+
if (runOptions.waitForTxs) {
|
|
191
|
+
const receipt = await raceWithSignals(() => tx.wait(), runOptions.signals);
|
|
192
|
+
if (!receipt) {
|
|
193
|
+
result = Array(iterationCalls.length).fill([false, null]);
|
|
194
|
+
this._lastSuccess = false;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
result = Array(iterationCalls.length).fill([true, receipt]);
|
|
198
|
+
this._lastSuccess = !(this._lastSuccess === false);
|
|
199
|
+
iterationTags.forEach((tag) => this._txReceipts.set(tag, receipt));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
result = Array(iterationCalls.length).fill([true, tx]);
|
|
204
|
+
this._lastSuccess = !(this._lastSuccess === false);
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
saveResponse(iterationResponse, iterationIndexes, globalTags) {
|
|
209
|
+
iterationResponse.forEach((el, index) => {
|
|
210
|
+
const [success, data] = el;
|
|
211
|
+
const globalIndex = iterationIndexes[index];
|
|
212
|
+
const tag = globalTags[globalIndex]; // Normalized
|
|
213
|
+
if (!success)
|
|
214
|
+
this._lastSuccess = false;
|
|
215
|
+
if (typeof data === "string")
|
|
216
|
+
this._rawData.set(tag, data);
|
|
217
|
+
this._callsSuccess.set(tag, success);
|
|
218
|
+
this._response[globalIndex] = el;
|
|
219
|
+
this._emitter.emit(multicallResultEventName(tag));
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
getOrThrow(tags, deep = false) {
|
|
223
|
+
const value = this.get(tags, deep);
|
|
224
|
+
if (value === null)
|
|
225
|
+
throw MULTICALL_ERRORS.RESULT_NOT_FOUND;
|
|
226
|
+
return value;
|
|
227
|
+
}
|
|
228
|
+
get(tags, deep = false) {
|
|
229
|
+
const raw = this.getRaw(tags);
|
|
230
|
+
if (raw === null)
|
|
231
|
+
return null;
|
|
232
|
+
// if (typeof raw !== 'string') return raw; // Transaction or Receipt for mutable call
|
|
233
|
+
const data = this.getDecodableData(tags);
|
|
234
|
+
if (!data)
|
|
235
|
+
return null;
|
|
236
|
+
const decoded = data.call.contractInterface.decodeFunctionResult(data.call.method, data.rawData);
|
|
237
|
+
const outputs = data.call.contractInterface.getFunction(data.call.method).outputs;
|
|
238
|
+
if (!outputs || outputs.length === 0) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
// Only one output - returns just single (sometimes can work with arrays (like [address[]]))
|
|
242
|
+
if (outputs.length === 1) {
|
|
243
|
+
return decoded[0];
|
|
244
|
+
}
|
|
245
|
+
// Outputs are named in ABI - object can be formed
|
|
246
|
+
// If output is named - object is preferable
|
|
247
|
+
if (outputs.every((param) => !!param.name)) {
|
|
248
|
+
return decoded.toObject(deep);
|
|
249
|
+
}
|
|
250
|
+
// In other case - return array
|
|
251
|
+
return decoded.toArray(deep);
|
|
252
|
+
}
|
|
253
|
+
getDecodableData(tags) {
|
|
254
|
+
const nTags = multicallNormalizeTags(tags);
|
|
255
|
+
const rawData = this._rawData.get(nTags);
|
|
256
|
+
const call = this._units.get(nTags);
|
|
257
|
+
if (rawData === undefined ||
|
|
258
|
+
!call ||
|
|
259
|
+
!isParsable(call) ||
|
|
260
|
+
!this.isSuccess(nTags)) {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
call,
|
|
265
|
+
rawData,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
async waitRawOrThrow(tags, options) {
|
|
269
|
+
const raw = await this.waitRaw(tags, options);
|
|
270
|
+
if (raw === null)
|
|
271
|
+
throw MULTICALL_ERRORS.RESULT_NOT_FOUND;
|
|
272
|
+
return raw;
|
|
273
|
+
}
|
|
274
|
+
async waitRaw(tags, options) {
|
|
275
|
+
const nTags = multicallNormalizeTags(tags);
|
|
276
|
+
// 1. If result exists - just return
|
|
277
|
+
{
|
|
278
|
+
const result = this._rawData.get(nTags);
|
|
279
|
+
if (result)
|
|
280
|
+
return result;
|
|
281
|
+
}
|
|
282
|
+
if (this._txResponses.has(nTags)) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
// 2. Or wait for event
|
|
286
|
+
await this.wait(tags, options);
|
|
287
|
+
return this.getRaw(nTags);
|
|
288
|
+
}
|
|
289
|
+
wait(tags, options) {
|
|
290
|
+
const signals = options?.signals ?? [];
|
|
291
|
+
if (options?.timeoutMs)
|
|
292
|
+
signals.push(createTimeoutSignal(options.timeoutMs));
|
|
293
|
+
const nTags = multicallNormalizeTags(tags);
|
|
294
|
+
return raceWithSignals(() => new Promise((resolve, reject) => {
|
|
295
|
+
const resultEvent = multicallResultEventName(nTags);
|
|
296
|
+
const errorEvent = multicallErrorEventName(nTags);
|
|
297
|
+
const onResult = () => {
|
|
298
|
+
cleanup();
|
|
299
|
+
resolve();
|
|
300
|
+
};
|
|
301
|
+
const onError = (error) => {
|
|
302
|
+
cleanup();
|
|
303
|
+
reject(error);
|
|
304
|
+
};
|
|
305
|
+
const cleanup = () => {
|
|
306
|
+
this._emitter.removeListener(resultEvent, onResult);
|
|
307
|
+
this._emitter.removeListener(errorEvent, onError);
|
|
308
|
+
};
|
|
309
|
+
this._emitter.once(resultEvent, onResult);
|
|
310
|
+
this._emitter.once(errorEvent, onError);
|
|
311
|
+
}), signals);
|
|
312
|
+
}
|
|
313
|
+
async waitTxOrThrow(tags, options) {
|
|
314
|
+
const tx = await this.waitTx(tags, options);
|
|
315
|
+
if (tx === null)
|
|
316
|
+
throw MULTICALL_ERRORS.RESULT_NOT_FOUND;
|
|
317
|
+
return tx;
|
|
318
|
+
}
|
|
319
|
+
async waitTx(tags, options) {
|
|
320
|
+
const nTags = multicallNormalizeTags(tags);
|
|
321
|
+
// 1. If result exists - just return
|
|
322
|
+
{
|
|
323
|
+
const result = this._txResponses.get(nTags);
|
|
324
|
+
if (result)
|
|
325
|
+
return result;
|
|
326
|
+
}
|
|
327
|
+
if (this._rawData.has(nTags)) {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
// 2. Or wait for event
|
|
331
|
+
await this.wait(tags, options);
|
|
332
|
+
return this.getTxResponse(nTags);
|
|
333
|
+
}
|
|
334
|
+
getTxResponse(tags) {
|
|
335
|
+
return this._txResponses.get(multicallNormalizeTags(tags)) ?? null;
|
|
336
|
+
}
|
|
337
|
+
getTxResponseOrThrow(tags) {
|
|
338
|
+
const response = this.getTxResponse(tags);
|
|
339
|
+
if (response === null)
|
|
340
|
+
throw MULTICALL_ERRORS.RESPONSE_NOT_FOUND;
|
|
341
|
+
return response;
|
|
342
|
+
}
|
|
343
|
+
getTxReceipt(tags) {
|
|
344
|
+
return this._txReceipts.get(multicallNormalizeTags(tags)) ?? null;
|
|
345
|
+
}
|
|
346
|
+
getObjectOrThrow(tags, deep = false) {
|
|
347
|
+
const obj = this.getObject(tags, deep);
|
|
348
|
+
if (obj === null)
|
|
349
|
+
throw MULTICALL_ERRORS.RESULT_NOT_FOUND;
|
|
350
|
+
return obj;
|
|
351
|
+
}
|
|
352
|
+
getObject(tags, deep = false) {
|
|
353
|
+
const data = this.getDecodableData(tags);
|
|
354
|
+
if (data === null)
|
|
355
|
+
return null;
|
|
356
|
+
const decoded = data.call.contractInterface.decodeFunctionResult(data.call.method, data.rawData);
|
|
357
|
+
return decoded.toObject(deep);
|
|
358
|
+
}
|
|
359
|
+
async waitFor(tags, options) {
|
|
360
|
+
const nTags = multicallNormalizeTags(tags);
|
|
361
|
+
if (this._rawData.has(nTags)) {
|
|
362
|
+
return this.get(tags, options?.deep);
|
|
363
|
+
}
|
|
364
|
+
await this.wait(tags, options);
|
|
365
|
+
return this.get(tags, options?.deep);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ContractAutoMethods {
|
|
2
|
+
/**
|
|
3
|
+
* Dynamically generated contract method calls.
|
|
4
|
+
* E.g., `balanceOf(...)`, `name()`, etc.
|
|
5
|
+
* OR
|
|
6
|
+
* Dynamically generated call object getters.
|
|
7
|
+
* E.g., `getBalanceOfCall`, `getNameCall`, etc.
|
|
8
|
+
*
|
|
9
|
+
* @param args - Arguments for the contract method + options/callData.
|
|
10
|
+
* @returns ContractCall OR Promise of the method result.
|
|
11
|
+
*/
|
|
12
|
+
[method: string]: <T = unknown>(...args: any[]) => T;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CallMutability } from "../call-mutability";
|
|
2
|
+
import type { PriorityCallOptions } from "../priority-call-options";
|
|
3
|
+
export interface ContractCallOptions {
|
|
4
|
+
forceMutability?: CallMutability;
|
|
5
|
+
highPriorityTx?: boolean;
|
|
6
|
+
priorityOptions?: PriorityCallOptions;
|
|
7
|
+
signals?: AbortSignal[];
|
|
8
|
+
timeoutMs?: number;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Interface } from "ethers";
|
|
2
|
+
import type { StateMutability } from "../state-mutabiity";
|
|
3
|
+
export interface ContractCall {
|
|
4
|
+
method?: string;
|
|
5
|
+
contractInterface?: Interface;
|
|
6
|
+
target: string;
|
|
7
|
+
allowFailure: boolean;
|
|
8
|
+
callData: string;
|
|
9
|
+
stateMutability: StateMutability;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CallMutability } from "../call-mutability";
|
|
2
|
+
import type { PriorityCallOptions } from "../priority-call-options";
|
|
3
|
+
export interface ContractOptions {
|
|
4
|
+
forceMutability?: CallMutability;
|
|
5
|
+
highPriorityTxs?: boolean;
|
|
6
|
+
priorityOptions?: PriorityCallOptions;
|
|
7
|
+
logsBlocksStep?: number;
|
|
8
|
+
logsDelayMs?: number;
|
|
9
|
+
signals?: AbortSignal[];
|
|
10
|
+
staticCallsTimeoutMs?: number;
|
|
11
|
+
mutableCallsTimeoutMs?: number;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Interface, InterfaceAbi, Provider, Signer } from "ethers";
|
|
2
|
+
import type { ContractOptions } from "./contract-options";
|
|
3
|
+
export interface DynamicContractConstructorArgs {
|
|
4
|
+
abi?: Interface | InterfaceAbi;
|
|
5
|
+
address?: string;
|
|
6
|
+
driver?: Provider | Signer;
|
|
7
|
+
options?: ContractOptions;
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CallMutability } from "../call-mutability";
|
|
2
|
+
import type { PriorityCallOptions } from "../priority-call-options";
|
|
3
|
+
export interface MulticallOptions {
|
|
4
|
+
forceMutability?: CallMutability;
|
|
5
|
+
waitForTxs?: boolean;
|
|
6
|
+
highPriorityTxs?: boolean;
|
|
7
|
+
priorityOptions?: PriorityCallOptions;
|
|
8
|
+
maxStaticCallsStack?: number;
|
|
9
|
+
maxMutableCallsStack?: number;
|
|
10
|
+
signals?: AbortSignal[];
|
|
11
|
+
staticCallsTimeoutMs?: number;
|
|
12
|
+
mutableCallsTimeoutMs?: number;
|
|
13
|
+
waitCallsTimeoutMs?: number;
|
|
14
|
+
batchDelayMs?: number;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ContractCall } from "./contract";
|
|
2
|
+
import type { Tagable } from "./multicall";
|
|
3
|
+
export interface SplitCalls {
|
|
4
|
+
staticCalls: ContractCall[];
|
|
5
|
+
staticIndexes: number[];
|
|
6
|
+
mutableCalls: ContractCall[];
|
|
7
|
+
mutableTags: Tagable[];
|
|
8
|
+
mutableIndexes: number[];
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export var StateMutability;
|
|
2
|
+
(function (StateMutability) {
|
|
3
|
+
StateMutability["View"] = "view";
|
|
4
|
+
StateMutability["Pure"] = "pure";
|
|
5
|
+
StateMutability["NonPayable"] = "nonpayable";
|
|
6
|
+
StateMutability["Payable"] = "payable";
|
|
7
|
+
})(StateMutability || (StateMutability = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function checkSignals(signals: AbortSignal[] | undefined): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createSignalsPromise(signals?: AbortSignal[]): Promise<never>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function createSignalsPromise(signals = []) {
|
|
2
|
+
return new Promise((_, reject) => {
|
|
3
|
+
const onAbort = (signal) => reject(signal.reason || new Error("Operation aborted"));
|
|
4
|
+
for (const signal of signals) {
|
|
5
|
+
signal.addEventListener("abort", () => onAbort(signal), { once: true });
|
|
6
|
+
}
|
|
7
|
+
});
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createTimeoutSignal(ms: number): AbortSignal;
|