@0xsequence/relayer 0.42.10 → 0.43.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/dist/0xsequence-relayer.cjs.dev.js +59 -151
- package/dist/0xsequence-relayer.cjs.prod.js +59 -151
- package/dist/0xsequence-relayer.esm.js +60 -148
- package/dist/declarations/src/base-relayer.d.ts +1 -1
- package/dist/declarations/src/local-relayer.d.ts +3 -4
- package/dist/declarations/src/provider-relayer.d.ts +3 -4
- package/dist/declarations/src/rpc-relayer/relayer.gen.d.ts +20 -1
- package/package.json +11 -10
- package/src/base-relayer.ts +4 -5
- package/src/local-relayer.ts +4 -5
- package/src/provider-relayer.ts +4 -5
- package/src/rpc-relayer/index.ts +1 -2
- package/src/rpc-relayer/relayer.gen.ts +190 -95
|
@@ -6,30 +6,20 @@ var ethers = require('ethers');
|
|
|
6
6
|
var abi = require('@0xsequence/abi');
|
|
7
7
|
var transactions = require('@0xsequence/transactions');
|
|
8
8
|
var utils = require('@0xsequence/utils');
|
|
9
|
-
var providers = require('@ethersproject/providers');
|
|
10
9
|
var config = require('@0xsequence/config');
|
|
11
|
-
var utils$1 = require('ethers/lib/utils');
|
|
12
|
-
var fetchPonyfill = require('fetch-ponyfill');
|
|
13
|
-
|
|
14
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
15
|
-
|
|
16
|
-
var fetchPonyfill__default = /*#__PURE__*/_interopDefault(fetchPonyfill);
|
|
17
10
|
|
|
18
11
|
function _extends() {
|
|
19
|
-
_extends = Object.assign
|
|
12
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
20
13
|
for (var i = 1; i < arguments.length; i++) {
|
|
21
14
|
var source = arguments[i];
|
|
22
|
-
|
|
23
15
|
for (var key in source) {
|
|
24
16
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
25
17
|
target[key] = source[key];
|
|
26
18
|
}
|
|
27
19
|
}
|
|
28
20
|
}
|
|
29
|
-
|
|
30
21
|
return target;
|
|
31
22
|
};
|
|
32
|
-
|
|
33
23
|
return _extends.apply(this, arguments);
|
|
34
24
|
}
|
|
35
25
|
|
|
@@ -45,27 +35,22 @@ class BaseRelayer {
|
|
|
45
35
|
this.provider = void 0;
|
|
46
36
|
this.bundleCreation = void 0;
|
|
47
37
|
this.creationGasLimit = void 0;
|
|
48
|
-
|
|
49
38
|
const opts = _extends({}, BaseRelayerDefaults, options);
|
|
50
|
-
|
|
51
39
|
this.bundleCreation = opts.bundleCreation;
|
|
52
40
|
this.provider = opts.provider;
|
|
53
41
|
this.creationGasLimit = ethers.ethers.BigNumber.from(opts.creationGasLimit);
|
|
54
42
|
}
|
|
55
|
-
|
|
56
43
|
async isWalletDeployed(walletAddress) {
|
|
57
44
|
if (!this.provider) throw new Error('Bundled creation provider not found');
|
|
58
45
|
return (await this.provider.getCode(walletAddress)) !== '0x';
|
|
59
46
|
}
|
|
60
|
-
|
|
61
47
|
prepareWalletDeploy(config$1, context) {
|
|
62
|
-
const factoryInterface = new utils
|
|
48
|
+
const factoryInterface = new ethers.utils.Interface(abi.walletContracts.factory.abi);
|
|
63
49
|
return {
|
|
64
50
|
to: context.factory,
|
|
65
51
|
data: factoryInterface.encodeFunctionData(factoryInterface.getFunction('deploy'), [context.mainModule, config.imageHash(config$1)])
|
|
66
52
|
};
|
|
67
53
|
}
|
|
68
|
-
|
|
69
54
|
async prependWalletDeploy(signedTransactions) {
|
|
70
55
|
const {
|
|
71
56
|
config: config$1,
|
|
@@ -75,14 +60,12 @@ class BaseRelayer {
|
|
|
75
60
|
signature
|
|
76
61
|
} = signedTransactions;
|
|
77
62
|
const walletAddress = config.addressOf(config$1, context);
|
|
78
|
-
const walletInterface = new utils
|
|
79
|
-
|
|
63
|
+
const walletInterface = new ethers.utils.Interface(abi.walletContracts.mainModule.abi);
|
|
80
64
|
const encodedSignature = async function () {
|
|
81
65
|
const sig = await signature;
|
|
82
66
|
if (typeof sig === 'string') return sig;
|
|
83
67
|
return config.encodeSignature(sig);
|
|
84
68
|
}();
|
|
85
|
-
|
|
86
69
|
if (this.bundleCreation && !(await this.isWalletDeployed(walletAddress))) {
|
|
87
70
|
return {
|
|
88
71
|
to: context.guestModule,
|
|
@@ -115,15 +98,12 @@ class BaseRelayer {
|
|
|
115
98
|
};
|
|
116
99
|
}
|
|
117
100
|
}
|
|
118
|
-
|
|
119
101
|
async prepareTransactions(config, context, signature, ...transactions$1) {
|
|
120
102
|
//, gasLimit?: ethers.BigNumberish }> {
|
|
121
103
|
const nonce = transactions.readSequenceNonce(...transactions$1);
|
|
122
|
-
|
|
123
104
|
if (!nonce) {
|
|
124
105
|
throw new Error('Unable to prepare transactions without a defined nonce');
|
|
125
106
|
}
|
|
126
|
-
|
|
127
107
|
const {
|
|
128
108
|
to,
|
|
129
109
|
execute
|
|
@@ -134,13 +114,12 @@ class BaseRelayer {
|
|
|
134
114
|
nonce,
|
|
135
115
|
signature
|
|
136
116
|
});
|
|
137
|
-
const walletInterface = new utils
|
|
117
|
+
const walletInterface = new ethers.utils.Interface(abi.walletContracts.mainModule.abi);
|
|
138
118
|
return {
|
|
139
119
|
to,
|
|
140
120
|
data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature])
|
|
141
121
|
};
|
|
142
122
|
}
|
|
143
|
-
|
|
144
123
|
}
|
|
145
124
|
|
|
146
125
|
const DEFAULT_GAS_LIMIT = ethers.ethers.BigNumber.from(800000);
|
|
@@ -150,7 +129,7 @@ const ProviderRelayerDefaults = {
|
|
|
150
129
|
fromBlockLog: -1024
|
|
151
130
|
};
|
|
152
131
|
function isProviderRelayerOptions(obj) {
|
|
153
|
-
return obj.provider !== undefined && providers.Provider.isProvider(obj.provider);
|
|
132
|
+
return obj.provider !== undefined && ethers.providers.Provider.isProvider(obj.provider);
|
|
154
133
|
}
|
|
155
134
|
class ProviderRelayer extends BaseRelayer {
|
|
156
135
|
constructor(options) {
|
|
@@ -159,40 +138,35 @@ class ProviderRelayer extends BaseRelayer {
|
|
|
159
138
|
this.waitPollRate = void 0;
|
|
160
139
|
this.deltaBlocksLog = void 0;
|
|
161
140
|
this.fromBlockLog = void 0;
|
|
162
|
-
|
|
163
141
|
const opts = _extends({}, ProviderRelayerDefaults, options);
|
|
164
|
-
|
|
165
142
|
this.provider = opts.provider;
|
|
166
143
|
this.waitPollRate = opts.waitPollRate;
|
|
167
144
|
this.deltaBlocksLog = opts.deltaBlocksLog;
|
|
168
145
|
this.fromBlockLog = opts.fromBlockLog;
|
|
169
146
|
}
|
|
170
|
-
|
|
171
147
|
async simulate(wallet, ...transactions) {
|
|
172
148
|
var _this = this;
|
|
173
|
-
|
|
174
149
|
return (await Promise.all(transactions.map(async function (tx) {
|
|
175
150
|
// Respect gasLimit request of the transaction (as long as its not 0)
|
|
176
151
|
if (tx.gasLimit && !ethers.ethers.BigNumber.from(tx.gasLimit || 0).eq(ethers.ethers.constants.Zero)) {
|
|
177
152
|
return tx.gasLimit;
|
|
178
|
-
}
|
|
179
|
-
|
|
153
|
+
}
|
|
180
154
|
|
|
155
|
+
// Fee can't be estimated locally for delegateCalls
|
|
181
156
|
if (tx.delegateCall) {
|
|
182
157
|
return DEFAULT_GAS_LIMIT;
|
|
183
|
-
}
|
|
184
|
-
|
|
158
|
+
}
|
|
185
159
|
|
|
160
|
+
// Fee can't be estimated for self-called if wallet hasn't been deployed
|
|
186
161
|
if (tx.to === wallet && !(await _this.isWalletDeployed(wallet))) {
|
|
187
162
|
return DEFAULT_GAS_LIMIT;
|
|
188
163
|
}
|
|
189
|
-
|
|
190
164
|
if (!_this.provider) {
|
|
191
165
|
throw new Error('signer.provider is not set, but is required');
|
|
192
|
-
}
|
|
193
|
-
// estimated with more accurately by using self-calls with the batch transactions one by one
|
|
194
|
-
|
|
166
|
+
}
|
|
195
167
|
|
|
168
|
+
// TODO: If the wallet address has been deployed, gas limits can be
|
|
169
|
+
// estimated with more accurately by using self-calls with the batch transactions one by one
|
|
196
170
|
return _this.provider.estimateGas({
|
|
197
171
|
from: wallet,
|
|
198
172
|
to: tx.to,
|
|
@@ -206,48 +180,37 @@ class ProviderRelayer extends BaseRelayer {
|
|
|
206
180
|
gasLimit: ethers.ethers.BigNumber.from(gasLimit).toNumber()
|
|
207
181
|
}));
|
|
208
182
|
}
|
|
209
|
-
|
|
210
183
|
async getNonce(config$1, context, space, blockTag) {
|
|
211
184
|
if (!this.provider) {
|
|
212
185
|
throw new Error('provider is not set');
|
|
213
186
|
}
|
|
214
|
-
|
|
215
187
|
const addr = config.addressOf(config$1, context);
|
|
216
|
-
|
|
217
188
|
if ((await this.provider.getCode(addr)) === '0x') {
|
|
218
189
|
return 0;
|
|
219
190
|
}
|
|
220
|
-
|
|
221
191
|
if (space === undefined) {
|
|
222
192
|
space = 0;
|
|
223
193
|
}
|
|
224
|
-
|
|
225
194
|
const module = new ethers.ethers.Contract(addr, abi.walletContracts.mainModule.abi, this.provider);
|
|
226
195
|
const nonce = await module.readNonce(space, {
|
|
227
196
|
blockTag: blockTag
|
|
228
197
|
});
|
|
229
198
|
return transactions.encodeNonce(space, nonce);
|
|
230
199
|
}
|
|
231
|
-
|
|
232
200
|
async wait(metaTxnId, timeout, delay = this.waitPollRate, maxFails = 5) {
|
|
233
201
|
var _this2 = this;
|
|
234
|
-
|
|
235
202
|
if (typeof metaTxnId !== 'string') {
|
|
236
203
|
utils.logger.info('computing id', metaTxnId.config, metaTxnId.context, metaTxnId.chainId, ...metaTxnId.transactions);
|
|
237
204
|
metaTxnId = transactions.computeMetaTxnHash(config.addressOf(metaTxnId.config, metaTxnId.context), metaTxnId.chainId, ...metaTxnId.transactions);
|
|
238
205
|
}
|
|
239
|
-
|
|
240
206
|
let timedOut = false;
|
|
241
|
-
|
|
242
207
|
const retry = async function retry(f, errorMessage) {
|
|
243
208
|
let fails = 0;
|
|
244
|
-
|
|
245
209
|
while (!timedOut) {
|
|
246
210
|
try {
|
|
247
211
|
return await f();
|
|
248
212
|
} catch (error) {
|
|
249
213
|
fails++;
|
|
250
|
-
|
|
251
214
|
if (maxFails !== undefined && fails >= maxFails) {
|
|
252
215
|
utils.logger.error(`giving up after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`, error);
|
|
253
216
|
throw error;
|
|
@@ -255,31 +218,24 @@ class ProviderRelayer extends BaseRelayer {
|
|
|
255
218
|
utils.logger.warn(`attempt #${fails} failed${errorMessage ? `: ${errorMessage}` : ''}`, error);
|
|
256
219
|
}
|
|
257
220
|
}
|
|
258
|
-
|
|
259
221
|
if (delay > 0) {
|
|
260
222
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
261
223
|
}
|
|
262
224
|
}
|
|
263
|
-
|
|
264
225
|
throw new Error(`timed out after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`);
|
|
265
226
|
};
|
|
266
|
-
|
|
267
227
|
const waitReceipt = async function waitReceipt() {
|
|
268
228
|
// Transactions can only get executed on nonce change
|
|
269
229
|
// get all nonce changes and look for metaTxnIds in between logs
|
|
270
230
|
let lastBlock = _this2.fromBlockLog;
|
|
271
|
-
|
|
272
231
|
if (lastBlock < 0) {
|
|
273
232
|
const block = await retry(() => _this2.provider.getBlockNumber(), 'unable to get latest block number');
|
|
274
233
|
lastBlock = block + lastBlock;
|
|
275
234
|
}
|
|
276
|
-
|
|
277
235
|
if (typeof metaTxnId !== 'string') {
|
|
278
236
|
throw new Error('impossible');
|
|
279
237
|
}
|
|
280
|
-
|
|
281
238
|
const normalMetaTxnId = metaTxnId.replace('0x', '');
|
|
282
|
-
|
|
283
239
|
while (!timedOut) {
|
|
284
240
|
const block = await retry(() => _this2.provider.getBlockNumber(), 'unable to get latest block number');
|
|
285
241
|
const logs = await retry(() => _this2.provider.getLogs({
|
|
@@ -288,28 +244,30 @@ class ProviderRelayer extends BaseRelayer {
|
|
|
288
244
|
// Nonce change event topic
|
|
289
245
|
topics: ['0x1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881']
|
|
290
246
|
}), `unable to get NonceChange logs for blocks ${Math.max(0, lastBlock - _this2.deltaBlocksLog)} to ${block}`);
|
|
291
|
-
lastBlock = block;
|
|
247
|
+
lastBlock = block;
|
|
292
248
|
|
|
293
|
-
|
|
249
|
+
// Get receipts of all transactions
|
|
250
|
+
const txs = await Promise.all(logs.map(l => retry(() => _this2.provider.getTransactionReceipt(l.transactionHash), `unable to get receipt for transaction ${l.transactionHash}`)));
|
|
294
251
|
|
|
295
|
-
|
|
296
|
-
|
|
252
|
+
// Find a transaction with a TxExecuted log
|
|
253
|
+
const found = txs.find(tx => tx.logs.find(l => l.topics.length === 0 && l.data.replace('0x', '') === normalMetaTxnId || l.topics.length === 1 &&
|
|
254
|
+
// TxFailed event topic
|
|
255
|
+
l.topics[0] === '0x3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd7' && l.data.length >= 64 && l.data.replace('0x', '').startsWith(normalMetaTxnId)));
|
|
297
256
|
|
|
257
|
+
// If found return that
|
|
298
258
|
if (found) {
|
|
299
259
|
return _extends({
|
|
300
260
|
receipt: found
|
|
301
261
|
}, await retry(() => _this2.provider.getTransaction(found.transactionHash), `unable to get transaction ${found.transactionHash}`));
|
|
302
|
-
}
|
|
303
|
-
|
|
262
|
+
}
|
|
304
263
|
|
|
264
|
+
// Otherwise wait and try again
|
|
305
265
|
if (!timedOut) {
|
|
306
266
|
await new Promise(r => setTimeout(r, delay));
|
|
307
267
|
}
|
|
308
268
|
}
|
|
309
|
-
|
|
310
269
|
throw new Error(`Timeout waiting for transaction receipt ${metaTxnId}`);
|
|
311
270
|
};
|
|
312
|
-
|
|
313
271
|
if (timeout !== undefined) {
|
|
314
272
|
return Promise.race([waitReceipt(), new Promise((_, reject) => setTimeout(() => {
|
|
315
273
|
timedOut = true;
|
|
@@ -319,7 +277,6 @@ class ProviderRelayer extends BaseRelayer {
|
|
|
319
277
|
return waitReceipt();
|
|
320
278
|
}
|
|
321
279
|
}
|
|
322
|
-
|
|
323
280
|
}
|
|
324
281
|
|
|
325
282
|
function isLocalRelayerOptions(obj) {
|
|
@@ -337,50 +294,46 @@ class LocalRelayer extends ProviderRelayer {
|
|
|
337
294
|
this.signer = ethers.Signer.isSigner(options) ? options : options.signer;
|
|
338
295
|
if (!this.signer.provider) throw new Error("Signer must have a provider");
|
|
339
296
|
}
|
|
340
|
-
|
|
341
297
|
async deployWallet(config, context) {
|
|
342
298
|
// NOTE: on hardhat some tests fail on HookCallerMock when not passing gasLimit directly as below,
|
|
343
299
|
// and using eth_gasEstimate. Perhaps review HookCallerMock.sol and fix it to avoid what looks
|
|
344
300
|
// like an infinite loop?
|
|
345
|
-
const walletDeployTxn = this.prepareWalletDeploy(config, context);
|
|
301
|
+
const walletDeployTxn = this.prepareWalletDeploy(config, context);
|
|
346
302
|
|
|
303
|
+
// NOTE: for hardhat to pass, we have to set the gasLimit directly, as its unable to estimate
|
|
347
304
|
return this.signer.sendTransaction(_extends({}, walletDeployTxn, {
|
|
348
305
|
gasLimit: ethers.ethers.constants.Two.pow(17)
|
|
349
306
|
}));
|
|
350
307
|
}
|
|
351
|
-
|
|
352
308
|
async getFeeOptions(_config, _context, ..._transactions) {
|
|
353
309
|
return {
|
|
354
310
|
options: []
|
|
355
311
|
};
|
|
356
312
|
}
|
|
357
|
-
|
|
358
313
|
async gasRefundOptions(config, context, ...transactions) {
|
|
359
314
|
const {
|
|
360
315
|
options
|
|
361
316
|
} = await this.getFeeOptions(config, context, ...transactions);
|
|
362
317
|
return options;
|
|
363
318
|
}
|
|
364
|
-
|
|
365
319
|
setTransactionOptions(transactionRequest) {
|
|
366
320
|
this.txnOptions = transactionRequest;
|
|
367
321
|
}
|
|
368
|
-
|
|
369
322
|
async relay(signedTxs, quote, waitForReceipt = true) {
|
|
370
323
|
if (quote !== undefined) {
|
|
371
324
|
utils.logger.warn(`LocalRelayer doesn't accept fee quotes`);
|
|
372
325
|
}
|
|
373
|
-
|
|
374
326
|
if (!signedTxs.context.guestModule || signedTxs.context.guestModule.length !== 42) {
|
|
375
327
|
throw new Error('LocalRelayer requires the context.guestModule address');
|
|
376
328
|
}
|
|
377
|
-
|
|
378
329
|
const {
|
|
379
330
|
to,
|
|
380
331
|
execute
|
|
381
332
|
} = await this.prependWalletDeploy(signedTxs);
|
|
382
333
|
const walletInterface = new ethers.ethers.utils.Interface(abi.walletContracts.mainModule.abi);
|
|
383
|
-
const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
|
|
334
|
+
const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
|
|
335
|
+
|
|
336
|
+
// TODO: think about computing gas limit individually, summing together and passing across
|
|
384
337
|
// NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation
|
|
385
338
|
// const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum.add(tx.gasLimit), ethers.BigNumber.from(0))
|
|
386
339
|
// txRequest.gasLimit = gasLimit
|
|
@@ -389,7 +342,6 @@ class LocalRelayer extends ProviderRelayer {
|
|
|
389
342
|
to,
|
|
390
343
|
data
|
|
391
344
|
}, this.txnOptions));
|
|
392
|
-
|
|
393
345
|
if (waitForReceipt) {
|
|
394
346
|
const response = await responsePromise;
|
|
395
347
|
response.receipt = await response.wait();
|
|
@@ -398,25 +350,28 @@ class LocalRelayer extends ProviderRelayer {
|
|
|
398
350
|
return responsePromise;
|
|
399
351
|
}
|
|
400
352
|
}
|
|
401
|
-
|
|
402
353
|
}
|
|
403
354
|
|
|
404
355
|
/* eslint-disable */
|
|
405
|
-
// sequence-relayer v0.4.0
|
|
356
|
+
// sequence-relayer v0.4.0 dd44f90f38fc726a1f1430cfece544c3316f6b4f
|
|
406
357
|
// --
|
|
407
|
-
//
|
|
408
|
-
//
|
|
358
|
+
// Code generated by webrpc-gen@v0.7.0 with typescript generator. DO NOT EDIT.
|
|
359
|
+
//
|
|
360
|
+
// webrpc-gen -schema=relayer.ridl -target=typescript -client -out=./clients/relayer.gen.ts
|
|
361
|
+
|
|
409
362
|
// WebRPC description and code-gen version
|
|
410
|
-
const WebRPCVersion =
|
|
363
|
+
const WebRPCVersion = "v1";
|
|
411
364
|
|
|
412
|
-
|
|
365
|
+
// Schema version of your RIDL schema
|
|
366
|
+
const WebRPCSchemaVersion = "v0.4.0";
|
|
413
367
|
|
|
414
|
-
|
|
368
|
+
// Schema hash generated from your RIDL schema
|
|
369
|
+
const WebRPCSchemaHash = "dd44f90f38fc726a1f1430cfece544c3316f6b4f";
|
|
370
|
+
|
|
371
|
+
//
|
|
415
372
|
// Types
|
|
416
373
|
//
|
|
417
|
-
|
|
418
374
|
let ETHTxnStatus;
|
|
419
|
-
|
|
420
375
|
(function (ETHTxnStatus) {
|
|
421
376
|
ETHTxnStatus["UNKNOWN"] = "UNKNOWN";
|
|
422
377
|
ETHTxnStatus["DROPPED"] = "DROPPED";
|
|
@@ -426,9 +381,7 @@ let ETHTxnStatus;
|
|
|
426
381
|
ETHTxnStatus["PARTIALLY_FAILED"] = "PARTIALLY_FAILED";
|
|
427
382
|
ETHTxnStatus["FAILED"] = "FAILED";
|
|
428
383
|
})(ETHTxnStatus || (ETHTxnStatus = {}));
|
|
429
|
-
|
|
430
384
|
let TransferType;
|
|
431
|
-
|
|
432
385
|
(function (TransferType) {
|
|
433
386
|
TransferType["SEND"] = "SEND";
|
|
434
387
|
TransferType["RECEIVE"] = "RECEIVE";
|
|
@@ -437,22 +390,17 @@ let TransferType;
|
|
|
437
390
|
TransferType["BURN"] = "BURN";
|
|
438
391
|
TransferType["UNKNOWN"] = "UNKNOWN";
|
|
439
392
|
})(TransferType || (TransferType = {}));
|
|
440
|
-
|
|
441
393
|
let FeeTokenType;
|
|
442
|
-
|
|
443
394
|
(function (FeeTokenType) {
|
|
444
395
|
FeeTokenType["UNKNOWN"] = "UNKNOWN";
|
|
445
396
|
FeeTokenType["ERC20_TOKEN"] = "ERC20_TOKEN";
|
|
446
397
|
FeeTokenType["ERC1155_TOKEN"] = "ERC1155_TOKEN";
|
|
447
398
|
})(FeeTokenType || (FeeTokenType = {}));
|
|
448
|
-
|
|
449
399
|
let SortOrder;
|
|
450
|
-
|
|
451
400
|
(function (SortOrder) {
|
|
452
401
|
SortOrder["DESC"] = "DESC";
|
|
453
402
|
SortOrder["ASC"] = "ASC";
|
|
454
403
|
})(SortOrder || (SortOrder = {}));
|
|
455
|
-
|
|
456
404
|
//
|
|
457
405
|
// Client
|
|
458
406
|
//
|
|
@@ -461,7 +409,6 @@ class Relayer {
|
|
|
461
409
|
this.hostname = void 0;
|
|
462
410
|
this.fetch = void 0;
|
|
463
411
|
this.path = '/rpc/Relayer/';
|
|
464
|
-
|
|
465
412
|
this.ping = headers => {
|
|
466
413
|
return this.fetch(this.url('Ping'), createHTTPRequest({}, headers)).then(res => {
|
|
467
414
|
return buildResponse(res).then(_data => {
|
|
@@ -471,7 +418,6 @@ class Relayer {
|
|
|
471
418
|
});
|
|
472
419
|
});
|
|
473
420
|
};
|
|
474
|
-
|
|
475
421
|
this.version = headers => {
|
|
476
422
|
return this.fetch(this.url('Version'), createHTTPRequest({}, headers)).then(res => {
|
|
477
423
|
return buildResponse(res).then(_data => {
|
|
@@ -481,7 +427,6 @@ class Relayer {
|
|
|
481
427
|
});
|
|
482
428
|
});
|
|
483
429
|
};
|
|
484
|
-
|
|
485
430
|
this.runtimeStatus = headers => {
|
|
486
431
|
return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers)).then(res => {
|
|
487
432
|
return buildResponse(res).then(_data => {
|
|
@@ -491,7 +436,6 @@ class Relayer {
|
|
|
491
436
|
});
|
|
492
437
|
});
|
|
493
438
|
};
|
|
494
|
-
|
|
495
439
|
this.getSequenceContext = headers => {
|
|
496
440
|
return this.fetch(this.url('GetSequenceContext'), createHTTPRequest({}, headers)).then(res => {
|
|
497
441
|
return buildResponse(res).then(_data => {
|
|
@@ -501,7 +445,6 @@ class Relayer {
|
|
|
501
445
|
});
|
|
502
446
|
});
|
|
503
447
|
};
|
|
504
|
-
|
|
505
448
|
this.getChainID = headers => {
|
|
506
449
|
return this.fetch(this.url('GetChainID'), createHTTPRequest({}, headers)).then(res => {
|
|
507
450
|
return buildResponse(res).then(_data => {
|
|
@@ -511,7 +454,6 @@ class Relayer {
|
|
|
511
454
|
});
|
|
512
455
|
});
|
|
513
456
|
};
|
|
514
|
-
|
|
515
457
|
this.sendMetaTxn = (args, headers) => {
|
|
516
458
|
return this.fetch(this.url('SendMetaTxn'), createHTTPRequest(args, headers)).then(res => {
|
|
517
459
|
return buildResponse(res).then(_data => {
|
|
@@ -522,7 +464,6 @@ class Relayer {
|
|
|
522
464
|
});
|
|
523
465
|
});
|
|
524
466
|
};
|
|
525
|
-
|
|
526
467
|
this.getMetaTxnNonce = (args, headers) => {
|
|
527
468
|
return this.fetch(this.url('GetMetaTxnNonce'), createHTTPRequest(args, headers)).then(res => {
|
|
528
469
|
return buildResponse(res).then(_data => {
|
|
@@ -532,7 +473,6 @@ class Relayer {
|
|
|
532
473
|
});
|
|
533
474
|
});
|
|
534
475
|
};
|
|
535
|
-
|
|
536
476
|
this.getMetaTxnReceipt = (args, headers) => {
|
|
537
477
|
return this.fetch(this.url('GetMetaTxnReceipt'), createHTTPRequest(args, headers)).then(res => {
|
|
538
478
|
return buildResponse(res).then(_data => {
|
|
@@ -542,7 +482,6 @@ class Relayer {
|
|
|
542
482
|
});
|
|
543
483
|
});
|
|
544
484
|
};
|
|
545
|
-
|
|
546
485
|
this.simulate = (args, headers) => {
|
|
547
486
|
return this.fetch(this.url('Simulate'), createHTTPRequest(args, headers)).then(res => {
|
|
548
487
|
return buildResponse(res).then(_data => {
|
|
@@ -552,7 +491,15 @@ class Relayer {
|
|
|
552
491
|
});
|
|
553
492
|
});
|
|
554
493
|
};
|
|
555
|
-
|
|
494
|
+
this.updateMetaTxnGasLimits = (args, headers) => {
|
|
495
|
+
return this.fetch(this.url('UpdateMetaTxnGasLimits'), createHTTPRequest(args, headers)).then(res => {
|
|
496
|
+
return buildResponse(res).then(_data => {
|
|
497
|
+
return {
|
|
498
|
+
payload: _data.payload
|
|
499
|
+
};
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
};
|
|
556
503
|
this.feeTokens = headers => {
|
|
557
504
|
return this.fetch(this.url('FeeTokens'), createHTTPRequest({}, headers)).then(res => {
|
|
558
505
|
return buildResponse(res).then(_data => {
|
|
@@ -563,7 +510,6 @@ class Relayer {
|
|
|
563
510
|
});
|
|
564
511
|
});
|
|
565
512
|
};
|
|
566
|
-
|
|
567
513
|
this.feeOptions = (args, headers) => {
|
|
568
514
|
return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers)).then(res => {
|
|
569
515
|
return buildResponse(res).then(_data => {
|
|
@@ -574,7 +520,15 @@ class Relayer {
|
|
|
574
520
|
});
|
|
575
521
|
});
|
|
576
522
|
};
|
|
577
|
-
|
|
523
|
+
this.getMetaTxnNetworkFeeOptions = (args, headers) => {
|
|
524
|
+
return this.fetch(this.url('GetMetaTxnNetworkFeeOptions'), createHTTPRequest(args, headers)).then(res => {
|
|
525
|
+
return buildResponse(res).then(_data => {
|
|
526
|
+
return {
|
|
527
|
+
options: _data.options
|
|
528
|
+
};
|
|
529
|
+
});
|
|
530
|
+
});
|
|
531
|
+
};
|
|
578
532
|
this.sentTransactions = (args, headers) => {
|
|
579
533
|
return this.fetch(this.url('SentTransactions'), createHTTPRequest(args, headers)).then(res => {
|
|
580
534
|
return buildResponse(res).then(_data => {
|
|
@@ -585,7 +539,6 @@ class Relayer {
|
|
|
585
539
|
});
|
|
586
540
|
});
|
|
587
541
|
};
|
|
588
|
-
|
|
589
542
|
this.pendingTransactions = (args, headers) => {
|
|
590
543
|
return this.fetch(this.url('PendingTransactions'), createHTTPRequest(args, headers)).then(res => {
|
|
591
544
|
return buildResponse(res).then(_data => {
|
|
@@ -596,7 +549,6 @@ class Relayer {
|
|
|
596
549
|
});
|
|
597
550
|
});
|
|
598
551
|
};
|
|
599
|
-
|
|
600
552
|
this.listGasSponsors = (args, headers) => {
|
|
601
553
|
return this.fetch(this.url('ListGasSponsors'), createHTTPRequest(args, headers)).then(res => {
|
|
602
554
|
return buildResponse(res).then(_data => {
|
|
@@ -607,7 +559,6 @@ class Relayer {
|
|
|
607
559
|
});
|
|
608
560
|
});
|
|
609
561
|
};
|
|
610
|
-
|
|
611
562
|
this.addGasSponsor = (args, headers) => {
|
|
612
563
|
return this.fetch(this.url('AddGasSponsor'), createHTTPRequest(args, headers)).then(res => {
|
|
613
564
|
return buildResponse(res).then(_data => {
|
|
@@ -618,7 +569,6 @@ class Relayer {
|
|
|
618
569
|
});
|
|
619
570
|
});
|
|
620
571
|
};
|
|
621
|
-
|
|
622
572
|
this.updateGasSponsor = (args, headers) => {
|
|
623
573
|
return this.fetch(this.url('UpdateGasSponsor'), createHTTPRequest(args, headers)).then(res => {
|
|
624
574
|
return buildResponse(res).then(_data => {
|
|
@@ -629,7 +579,6 @@ class Relayer {
|
|
|
629
579
|
});
|
|
630
580
|
});
|
|
631
581
|
};
|
|
632
|
-
|
|
633
582
|
this.reportGasSponsorUsage = (args, headers) => {
|
|
634
583
|
return this.fetch(this.url('ReportGasSponsorUsage'), createHTTPRequest(args, headers)).then(res => {
|
|
635
584
|
return buildResponse(res).then(_data => {
|
|
@@ -639,17 +588,13 @@ class Relayer {
|
|
|
639
588
|
});
|
|
640
589
|
});
|
|
641
590
|
};
|
|
642
|
-
|
|
643
591
|
this.hostname = hostname;
|
|
644
|
-
this.fetch = fetch;
|
|
592
|
+
this.fetch = (input, init) => fetch(input, init);
|
|
645
593
|
}
|
|
646
|
-
|
|
647
594
|
url(name) {
|
|
648
595
|
return this.hostname + this.path + name;
|
|
649
596
|
}
|
|
650
|
-
|
|
651
597
|
}
|
|
652
|
-
|
|
653
598
|
const createHTTPRequest = (body = {}, headers = {}) => {
|
|
654
599
|
return {
|
|
655
600
|
method: 'POST',
|
|
@@ -659,11 +604,9 @@ const createHTTPRequest = (body = {}, headers = {}) => {
|
|
|
659
604
|
body: JSON.stringify(body || {})
|
|
660
605
|
};
|
|
661
606
|
};
|
|
662
|
-
|
|
663
607
|
const buildResponse = res => {
|
|
664
608
|
return res.text().then(text => {
|
|
665
609
|
let data;
|
|
666
|
-
|
|
667
610
|
try {
|
|
668
611
|
data = JSON.parse(text);
|
|
669
612
|
} catch (err) {
|
|
@@ -673,7 +616,6 @@ const buildResponse = res => {
|
|
|
673
616
|
status: res.status
|
|
674
617
|
};
|
|
675
618
|
}
|
|
676
|
-
|
|
677
619
|
if (!res.ok) {
|
|
678
620
|
throw data; // webrpc error response
|
|
679
621
|
}
|
|
@@ -703,18 +645,15 @@ class RpcRelayer extends BaseRelayer {
|
|
|
703
645
|
constructor(options) {
|
|
704
646
|
super(options);
|
|
705
647
|
this.service = void 0;
|
|
706
|
-
this.service = new Relayer(options.url,
|
|
648
|
+
this.service = new Relayer(options.url, global.fetch);
|
|
707
649
|
}
|
|
708
|
-
|
|
709
650
|
async waitReceipt(metaTxnId, delay = 1000, maxFails = 5, isCancelled) {
|
|
710
651
|
if (typeof metaTxnId !== 'string') {
|
|
711
652
|
utils.logger.info('computing id', metaTxnId.config, metaTxnId.context, metaTxnId.chainId, ...metaTxnId.transactions);
|
|
712
653
|
metaTxnId = transactions.computeMetaTxnHash(config.addressOf(metaTxnId.config, metaTxnId.context), metaTxnId.chainId, ...metaTxnId.transactions);
|
|
713
654
|
}
|
|
714
|
-
|
|
715
655
|
utils.logger.info(`[rpc-relayer/waitReceipt] waiting for ${metaTxnId}`);
|
|
716
656
|
let fails = 0;
|
|
717
|
-
|
|
718
657
|
while (isCancelled === undefined || !isCancelled()) {
|
|
719
658
|
try {
|
|
720
659
|
const {
|
|
@@ -722,7 +661,6 @@ class RpcRelayer extends BaseRelayer {
|
|
|
722
661
|
} = await this.service.getMetaTxnReceipt({
|
|
723
662
|
metaTxID: metaTxnId
|
|
724
663
|
});
|
|
725
|
-
|
|
726
664
|
if (receipt && receipt.txnReceipt && receipt.txnReceipt !== 'null' && FINAL_STATUSES.includes(receipt.status)) {
|
|
727
665
|
return {
|
|
728
666
|
receipt
|
|
@@ -730,20 +668,16 @@ class RpcRelayer extends BaseRelayer {
|
|
|
730
668
|
}
|
|
731
669
|
} catch (e) {
|
|
732
670
|
fails++;
|
|
733
|
-
|
|
734
671
|
if (fails === maxFails) {
|
|
735
672
|
throw e;
|
|
736
673
|
}
|
|
737
674
|
}
|
|
738
|
-
|
|
739
675
|
if (isCancelled === undefined || !isCancelled()) {
|
|
740
676
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
741
677
|
}
|
|
742
678
|
}
|
|
743
|
-
|
|
744
679
|
throw new Error(`Cancelled waiting for transaction receipt ${metaTxnId}`);
|
|
745
680
|
}
|
|
746
|
-
|
|
747
681
|
async simulate(wallet, ...transactions$1) {
|
|
748
682
|
const coder = ethers.ethers.utils.defaultAbiCoder;
|
|
749
683
|
const encoded = coder.encode([transactions.MetaTransactionsType], [transactions.sequenceTxAbiEncode(transactions$1)]);
|
|
@@ -752,28 +686,23 @@ class RpcRelayer extends BaseRelayer {
|
|
|
752
686
|
transactions: encoded
|
|
753
687
|
})).results;
|
|
754
688
|
}
|
|
755
|
-
|
|
756
689
|
async getFeeOptions(config$1, context, ...transactions$1) {
|
|
757
690
|
// NOTE/TODO: for a given `service` the feeTokens will not change between execution, so we should memoize this value
|
|
758
691
|
// for a short-period of time, perhaps for 1 day or in memory. Perhaps one day we can make this happen automatically
|
|
759
692
|
// with http cache response for this endpoint and service-worker.. lots of approaches
|
|
760
693
|
const feeTokens = await this.service.feeTokens();
|
|
761
|
-
|
|
762
694
|
if (feeTokens.isFeeRequired) {
|
|
763
695
|
const symbols = feeTokens.tokens.map(token => token.symbol).join(', ');
|
|
764
696
|
utils.logger.info(`[rpc-relayer/getFeeOptions] relayer fees are required, accepted tokens are ${symbols}`);
|
|
765
697
|
const wallet = config.addressOf(config$1, context);
|
|
766
698
|
let nonce = transactions.readSequenceNonce(...transactions$1);
|
|
767
|
-
|
|
768
699
|
if (nonce === undefined) {
|
|
769
700
|
nonce = await this.getNonce(config$1, context);
|
|
770
701
|
}
|
|
771
|
-
|
|
772
702
|
if (!this.provider) {
|
|
773
703
|
utils.logger.warn(`[rpc-relayer/getFeeOptions] provider not set, needed for stub signature`);
|
|
774
704
|
throw new Error('provider is not set');
|
|
775
705
|
}
|
|
776
|
-
|
|
777
706
|
const {
|
|
778
707
|
to,
|
|
779
708
|
execute
|
|
@@ -809,14 +738,12 @@ class RpcRelayer extends BaseRelayer {
|
|
|
809
738
|
};
|
|
810
739
|
}
|
|
811
740
|
}
|
|
812
|
-
|
|
813
741
|
async gasRefundOptions(config, context, ...transactions) {
|
|
814
742
|
const {
|
|
815
743
|
options
|
|
816
744
|
} = await this.getFeeOptions(config, context, ...transactions);
|
|
817
745
|
return options;
|
|
818
746
|
}
|
|
819
|
-
|
|
820
747
|
async getNonce(config$1, context, space) {
|
|
821
748
|
const addr = config.addressOf(config$1, context);
|
|
822
749
|
utils.logger.info(`[rpc-relayer/getNonce] get nonce for wallet ${addr} space: ${space}`);
|
|
@@ -830,13 +757,10 @@ class RpcRelayer extends BaseRelayer {
|
|
|
830
757
|
utils.logger.info(`[rpc-relayer/getNonce] got next nonce for wallet ${addr} ${decodedNonce} space: ${decodedSpace}`);
|
|
831
758
|
return nonce;
|
|
832
759
|
}
|
|
833
|
-
|
|
834
760
|
async relay(signedTxs, quote, waitForReceipt = true) {
|
|
835
761
|
var _this = this;
|
|
836
|
-
|
|
837
762
|
utils.logger.info(`[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)} with quote ${JSON.stringify(quote)}`);
|
|
838
763
|
let typecheckedQuote;
|
|
839
|
-
|
|
840
764
|
if (quote !== undefined) {
|
|
841
765
|
if (typeof quote._quote === 'string') {
|
|
842
766
|
typecheckedQuote = quote._quote;
|
|
@@ -844,12 +768,10 @@ class RpcRelayer extends BaseRelayer {
|
|
|
844
768
|
utils.logger.warn('[rpc-relayer/relay] ignoring invalid fee quote');
|
|
845
769
|
}
|
|
846
770
|
}
|
|
847
|
-
|
|
848
771
|
if (!this.provider) {
|
|
849
772
|
utils.logger.warn(`[rpc-relayer/relay] provider not set, failed relay`);
|
|
850
773
|
throw new Error('provider is not set');
|
|
851
774
|
}
|
|
852
|
-
|
|
853
775
|
const {
|
|
854
776
|
to: contract,
|
|
855
777
|
execute
|
|
@@ -866,7 +788,6 @@ class RpcRelayer extends BaseRelayer {
|
|
|
866
788
|
quote: typecheckedQuote
|
|
867
789
|
});
|
|
868
790
|
utils.logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`);
|
|
869
|
-
|
|
870
791
|
if (waitForReceipt) {
|
|
871
792
|
return this.wait(metaTxn.txnHash);
|
|
872
793
|
} else {
|
|
@@ -876,33 +797,25 @@ class RpcRelayer extends BaseRelayer {
|
|
|
876
797
|
from: walletAddress,
|
|
877
798
|
wait: _confirmations => Promise.reject(new Error('impossible'))
|
|
878
799
|
};
|
|
879
|
-
|
|
880
800
|
const wait = async function wait(confirmations) {
|
|
881
801
|
var _waitResponse$receipt;
|
|
882
|
-
|
|
883
802
|
if (!_this.provider) {
|
|
884
803
|
throw new Error('cannot wait for receipt, relayer has no provider set');
|
|
885
804
|
}
|
|
886
|
-
|
|
887
805
|
const waitResponse = await _this.wait(metaTxn.txnHash);
|
|
888
806
|
const transactionHash = (_waitResponse$receipt = waitResponse.receipt) == null ? void 0 : _waitResponse$receipt.transactionHash;
|
|
889
|
-
|
|
890
807
|
if (!transactionHash) {
|
|
891
808
|
throw new Error('cannot wait for receipt, unknown native transaction hash');
|
|
892
809
|
}
|
|
893
|
-
|
|
894
810
|
Object.assign(response, waitResponse);
|
|
895
811
|
return _this.provider.waitForTransaction(transactionHash, confirmations);
|
|
896
812
|
};
|
|
897
|
-
|
|
898
813
|
response.wait = wait;
|
|
899
814
|
return response;
|
|
900
815
|
}
|
|
901
816
|
}
|
|
902
|
-
|
|
903
817
|
async wait(metaTxnId, timeout, delay = 1000, maxFails = 5) {
|
|
904
818
|
var _this2 = this;
|
|
905
|
-
|
|
906
819
|
let timedOut = false;
|
|
907
820
|
const {
|
|
908
821
|
receipt
|
|
@@ -910,11 +823,9 @@ class RpcRelayer extends BaseRelayer {
|
|
|
910
823
|
timedOut = true;
|
|
911
824
|
reject(`Timeout waiting for transaction receipt ${metaTxnId}`);
|
|
912
825
|
}, timeout))]) : this.waitReceipt(metaTxnId, delay, maxFails));
|
|
913
|
-
|
|
914
826
|
if (!receipt.txnReceipt || FAILED_STATUSES.includes(receipt.status)) {
|
|
915
827
|
throw new MetaTransactionResponseException(receipt);
|
|
916
828
|
}
|
|
917
|
-
|
|
918
829
|
const txReceipt = JSON.parse(receipt.txnReceipt);
|
|
919
830
|
return {
|
|
920
831
|
blockHash: txReceipt.blockHash,
|
|
@@ -930,14 +841,11 @@ class RpcRelayer extends BaseRelayer {
|
|
|
930
841
|
}
|
|
931
842
|
};
|
|
932
843
|
}
|
|
933
|
-
|
|
934
844
|
}
|
|
935
|
-
|
|
936
845
|
class MetaTransactionResponseException {
|
|
937
846
|
constructor(receipt) {
|
|
938
847
|
this.receipt = receipt;
|
|
939
848
|
}
|
|
940
|
-
|
|
941
849
|
}
|
|
942
850
|
|
|
943
851
|
function isRelayer(cand) {
|