@0xsequence/relayer 0.33.2 → 0.35.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,63 @@
1
1
  # @0xsequence/relayer
2
2
 
3
+ ## 0.35.2
4
+
5
+ ### Patch Changes
6
+
7
+ - - provider: WindowMessageHandler accept optional windowHref
8
+ - Updated dependencies
9
+ - @0xsequence/abi@0.35.2
10
+ - @0xsequence/config@0.35.2
11
+ - @0xsequence/transactions@0.35.2
12
+ - @0xsequence/utils@0.35.2
13
+
14
+ ## 0.35.1
15
+
16
+ ### Patch Changes
17
+
18
+ - wallet: update config on undeployed too
19
+ - Updated dependencies
20
+ - @0xsequence/abi@0.35.1
21
+ - @0xsequence/config@0.35.1
22
+ - @0xsequence/transactions@0.35.1
23
+ - @0xsequence/utils@0.35.1
24
+
25
+ ## 0.35.0
26
+
27
+ ### Minor Changes
28
+
29
+ - - config: add buildStubSignature
30
+ - provider: add checks to signing cases for wallet deployment and config statuses
31
+ - provider: add prompt for wallet deployment
32
+ - relayer: add BaseRelayer.prependWalletDeploy
33
+ - relayer: add Relayer.feeOptions
34
+ - relayer: account for wallet deployment in fee estimation
35
+ - transactions: add fromTransactionish
36
+ - wallet: add Account.prependConfigUpdate
37
+ - wallet: add Account.getFeeOptions
38
+
39
+ ### Patch Changes
40
+
41
+ - Updated dependencies
42
+ - @0xsequence/abi@0.35.0
43
+ - @0xsequence/config@0.35.0
44
+ - @0xsequence/transactions@0.35.0
45
+ - @0xsequence/utils@0.35.0
46
+
47
+ ## 0.34.0
48
+
49
+ ### Minor Changes
50
+
51
+ - - upgrade deps
52
+
53
+ ### Patch Changes
54
+
55
+ - Updated dependencies
56
+ - @0xsequence/abi@0.34.0
57
+ - @0xsequence/config@0.34.0
58
+ - @0xsequence/transactions@0.34.0
59
+ - @0xsequence/utils@0.34.0
60
+
3
61
  ## 0.33.2
4
62
 
5
63
  ### Patch Changes
@@ -3,9 +3,9 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var ethers = require('ethers');
6
- var providers = require('@ethersproject/providers');
7
6
  var abi = require('@0xsequence/abi');
8
7
  var transactions = require('@0xsequence/transactions');
8
+ var providers = require('@ethersproject/providers');
9
9
  var config = require('@0xsequence/config');
10
10
  var utils$1 = require('ethers/lib/utils');
11
11
  var utils = require('@0xsequence/utils');
@@ -66,8 +66,14 @@ class BaseRelayer {
66
66
  };
67
67
  }
68
68
 
69
- async prepareTransactions(config$1, context, signature, ...transactions$1) {
70
- //, gasLimit?: ethers.BigNumberish }> {
69
+ async prependWalletDeploy(signedTransactions) {
70
+ const {
71
+ config: config$1,
72
+ context,
73
+ transactions: transactions$1,
74
+ nonce,
75
+ signature
76
+ } = signedTransactions;
71
77
  const walletAddress = config.addressOf(config$1, context);
72
78
  const walletInterface = new utils$1.Interface(abi.walletContracts.mainModule.abi);
73
79
 
@@ -80,28 +86,61 @@ class BaseRelayer {
80
86
  if (this.bundleCreation && !(await this.isWalletDeployed(walletAddress))) {
81
87
  return {
82
88
  to: context.guestModule,
83
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode([_extends({}, this.prepareWalletDeploy(config$1, context), {
84
- delegateCall: false,
85
- revertOnError: false,
86
- gasLimit: this.creationGasLimit,
87
- value: ethers.ethers.constants.Zero
88
- }), {
89
- delegateCall: false,
90
- revertOnError: true,
91
- gasLimit: ethers.ethers.constants.Zero,
92
- to: walletAddress,
93
- value: ethers.ethers.constants.Zero,
94
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(transactions$1), transactions.readSequenceNonce(...transactions$1), await encodedSignature])
95
- }]), 0, []])
89
+ execute: {
90
+ transactions: [_extends({}, this.prepareWalletDeploy(config$1, context), {
91
+ delegateCall: false,
92
+ revertOnError: false,
93
+ gasLimit: this.creationGasLimit,
94
+ value: ethers.ethers.constants.Zero
95
+ }), {
96
+ delegateCall: false,
97
+ revertOnError: true,
98
+ gasLimit: ethers.ethers.constants.Zero,
99
+ to: walletAddress,
100
+ value: ethers.ethers.constants.Zero,
101
+ data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(transactions$1), nonce, await encodedSignature])
102
+ }],
103
+ nonce: ethers.ethers.constants.Zero,
104
+ signature: '0x'
105
+ }
96
106
  };
97
107
  } else {
98
108
  return {
99
109
  to: walletAddress,
100
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(transactions$1), transactions.readSequenceNonce(...transactions$1), await encodedSignature])
110
+ execute: {
111
+ transactions: transactions$1,
112
+ nonce: ethers.ethers.BigNumber.from(nonce),
113
+ signature: await encodedSignature
114
+ }
101
115
  };
102
116
  }
103
117
  }
104
118
 
119
+ async prepareTransactions(config, context, signature, ...transactions$1) {
120
+ //, gasLimit?: ethers.BigNumberish }> {
121
+ const nonce = transactions.readSequenceNonce(...transactions$1);
122
+
123
+ if (!nonce) {
124
+ throw new Error('Unable to prepare transactions without a defined nonce');
125
+ }
126
+
127
+ const {
128
+ to,
129
+ execute
130
+ } = await this.prependWalletDeploy({
131
+ config,
132
+ context,
133
+ transactions: transactions$1,
134
+ nonce,
135
+ signature
136
+ });
137
+ const walletInterface = new utils$1.Interface(abi.walletContracts.mainModule.abi);
138
+ return {
139
+ to,
140
+ data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature])
141
+ };
142
+ }
143
+
105
144
  }
106
145
 
107
146
  const DEFAULT_GAS_LIMIT = ethers.ethers.BigNumber.from(800000);
@@ -281,18 +320,26 @@ class LocalRelayer extends ProviderRelayer {
281
320
  throw new Error('LocalRelayer requires the context.guestModule address');
282
321
  }
283
322
 
284
- const txRequest = await this.prepareTransactions(signedTxs.config, signedTxs.context, signedTxs.signature, ...signedTxs.transactions); // TODO: think about computing gas limit individually, summing together and passing across
323
+ const {
324
+ to,
325
+ execute
326
+ } = await this.prependWalletDeploy(signedTxs);
327
+ const walletInterface = new ethers.ethers.utils.Interface(abi.walletContracts.mainModule.abi);
328
+ const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]); // TODO: think about computing gas limit individually, summing together and passing across
285
329
  // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation
286
330
  // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum.add(tx.gasLimit), ethers.BigNumber.from(0))
287
331
  // txRequest.gasLimit = gasLimit
288
332
 
289
- return this.signer.sendTransaction(txRequest);
333
+ return this.signer.sendTransaction({
334
+ to,
335
+ data
336
+ });
290
337
  }
291
338
 
292
339
  }
293
340
 
294
341
  /* eslint-disable */
295
- // sequence-relayer v0.4.0 1598ae8045a4f054fefc0fa3b244f61f75a7c8bd
342
+ // sequence-relayer v0.4.0 7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd
296
343
  // --
297
344
  // This file has been generated by https://github.com/webrpc/webrpc using gen/typescript
298
345
  // Do not edit by hand. Update your webrpc schema and re-generate.
@@ -301,7 +348,7 @@ const WebRPCVersion = 'v1'; // Schema version of your RIDL schema
301
348
 
302
349
  const WebRPCSchemaVersion = 'v0.4.0'; // Schema hash generated from your RIDL schema
303
350
 
304
- const WebRPCSchemaHash = '1598ae8045a4f054fefc0fa3b244f61f75a7c8bd'; //
351
+ const WebRPCSchemaHash = '7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd'; //
305
352
  // Types
306
353
  //
307
354
 
@@ -464,6 +511,16 @@ class Relayer {
464
511
  });
465
512
  };
466
513
 
514
+ this.feeOptions = (args, headers) => {
515
+ return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers)).then(res => {
516
+ return buildResponse(res).then(_data => {
517
+ return {
518
+ options: _data.options
519
+ };
520
+ });
521
+ });
522
+ };
523
+
467
524
  this.getMetaTxnNetworkFeeOptions = (args, headers) => {
468
525
  return this.fetch(this.url('GetMetaTxnNetworkFeeOptions'), createHTTPRequest(args, headers)).then(res => {
469
526
  return buildResponse(res).then(_data => {
@@ -636,23 +693,39 @@ class RpcRelayer extends BaseRelayer {
636
693
  if (feeTokens.isFeeRequired) {
637
694
  const symbols = feeTokens.tokens.map(token => token.symbol).join(', ');
638
695
  utils.logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are required, accepted tokens are ${symbols}`);
639
- const addr = config.addressOf(config$1, context);
640
- const prevNonce = transactions.readSequenceNonce(...transactions$1); // Set temporal nonce to simulate meta-txn
696
+ const wallet = config.addressOf(config$1, context);
697
+ let nonce = transactions.readSequenceNonce(...transactions$1);
641
698
 
642
- if (prevNonce === undefined) {
643
- transactions$1 = transactions.appendNonce(transactions$1, await this.getNonce(config$1, context));
699
+ if (nonce === undefined) {
700
+ nonce = await this.getNonce(config$1, context);
644
701
  }
645
702
 
646
- const coder = ethers.ethers.utils.defaultAbiCoder;
647
- const encoded = coder.encode([transactions.MetaTransactionsType], [transactions.sequenceTxAbiEncode(transactions$1)]);
648
- const res = await this.service.getMetaTxnNetworkFeeOptions({
649
- walletConfig: _extends({}, config$1, {
650
- address: addr
651
- }),
652
- payload: encoded
703
+ if (!this.provider) {
704
+ utils.logger.warn(`[rpc-relayer/gasRefundOptions] provider not set, needed for stub signature`);
705
+ throw new Error('provider is not set');
706
+ }
707
+
708
+ const {
709
+ to,
710
+ execute
711
+ } = await this.prependWalletDeploy({
712
+ config: config$1,
713
+ context,
714
+ transactions: transactions$1,
715
+ nonce,
716
+ signature: config.buildStubSignature(this.provider, config$1)
717
+ });
718
+ const walletInterface = new ethers.ethers.utils.Interface(abi.walletContracts.mainModule.abi);
719
+ const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
720
+ const {
721
+ options
722
+ } = await this.service.feeOptions({
723
+ wallet,
724
+ to,
725
+ data
653
726
  });
654
- utils.logger.info(`[rpc-relayer/gasRefundOptions] got refund options ${JSON.stringify(res.options)}`);
655
- return res.options;
727
+ utils.logger.info(`[rpc-relayer/gasRefundOptions] got refund options ${JSON.stringify(options)}`);
728
+ return options;
656
729
  } else {
657
730
  utils.logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are not required`);
658
731
  return [];
@@ -681,13 +754,18 @@ class RpcRelayer extends BaseRelayer {
681
754
  throw new Error('provider is not set');
682
755
  }
683
756
 
684
- const addr = config.addressOf(signedTxs.config, signedTxs.context);
685
- const prep = await this.prepareTransactions(signedTxs.config, signedTxs.context, signedTxs.signature, ...signedTxs.transactions);
757
+ const {
758
+ to: contract,
759
+ execute
760
+ } = await this.prependWalletDeploy(signedTxs);
761
+ const walletAddress = config.addressOf(signedTxs.config, signedTxs.context);
762
+ const walletInterface = new ethers.ethers.utils.Interface(abi.walletContracts.mainModule.abi);
763
+ const input = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
686
764
  const metaTxn = await this.service.sendMetaTxn({
687
765
  call: {
688
- contract: prep.to,
689
- input: prep.data,
690
- walletAddress: addr
766
+ walletAddress,
767
+ contract,
768
+ input
691
769
  }
692
770
  });
693
771
  utils.logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`);
@@ -3,9 +3,9 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var ethers = require('ethers');
6
- var providers = require('@ethersproject/providers');
7
6
  var abi = require('@0xsequence/abi');
8
7
  var transactions = require('@0xsequence/transactions');
8
+ var providers = require('@ethersproject/providers');
9
9
  var config = require('@0xsequence/config');
10
10
  var utils$1 = require('ethers/lib/utils');
11
11
  var utils = require('@0xsequence/utils');
@@ -66,8 +66,14 @@ class BaseRelayer {
66
66
  };
67
67
  }
68
68
 
69
- async prepareTransactions(config$1, context, signature, ...transactions$1) {
70
- //, gasLimit?: ethers.BigNumberish }> {
69
+ async prependWalletDeploy(signedTransactions) {
70
+ const {
71
+ config: config$1,
72
+ context,
73
+ transactions: transactions$1,
74
+ nonce,
75
+ signature
76
+ } = signedTransactions;
71
77
  const walletAddress = config.addressOf(config$1, context);
72
78
  const walletInterface = new utils$1.Interface(abi.walletContracts.mainModule.abi);
73
79
 
@@ -80,28 +86,61 @@ class BaseRelayer {
80
86
  if (this.bundleCreation && !(await this.isWalletDeployed(walletAddress))) {
81
87
  return {
82
88
  to: context.guestModule,
83
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode([_extends({}, this.prepareWalletDeploy(config$1, context), {
84
- delegateCall: false,
85
- revertOnError: false,
86
- gasLimit: this.creationGasLimit,
87
- value: ethers.ethers.constants.Zero
88
- }), {
89
- delegateCall: false,
90
- revertOnError: true,
91
- gasLimit: ethers.ethers.constants.Zero,
92
- to: walletAddress,
93
- value: ethers.ethers.constants.Zero,
94
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(transactions$1), transactions.readSequenceNonce(...transactions$1), await encodedSignature])
95
- }]), 0, []])
89
+ execute: {
90
+ transactions: [_extends({}, this.prepareWalletDeploy(config$1, context), {
91
+ delegateCall: false,
92
+ revertOnError: false,
93
+ gasLimit: this.creationGasLimit,
94
+ value: ethers.ethers.constants.Zero
95
+ }), {
96
+ delegateCall: false,
97
+ revertOnError: true,
98
+ gasLimit: ethers.ethers.constants.Zero,
99
+ to: walletAddress,
100
+ value: ethers.ethers.constants.Zero,
101
+ data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(transactions$1), nonce, await encodedSignature])
102
+ }],
103
+ nonce: ethers.ethers.constants.Zero,
104
+ signature: '0x'
105
+ }
96
106
  };
97
107
  } else {
98
108
  return {
99
109
  to: walletAddress,
100
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(transactions$1), transactions.readSequenceNonce(...transactions$1), await encodedSignature])
110
+ execute: {
111
+ transactions: transactions$1,
112
+ nonce: ethers.ethers.BigNumber.from(nonce),
113
+ signature: await encodedSignature
114
+ }
101
115
  };
102
116
  }
103
117
  }
104
118
 
119
+ async prepareTransactions(config, context, signature, ...transactions$1) {
120
+ //, gasLimit?: ethers.BigNumberish }> {
121
+ const nonce = transactions.readSequenceNonce(...transactions$1);
122
+
123
+ if (!nonce) {
124
+ throw new Error('Unable to prepare transactions without a defined nonce');
125
+ }
126
+
127
+ const {
128
+ to,
129
+ execute
130
+ } = await this.prependWalletDeploy({
131
+ config,
132
+ context,
133
+ transactions: transactions$1,
134
+ nonce,
135
+ signature
136
+ });
137
+ const walletInterface = new utils$1.Interface(abi.walletContracts.mainModule.abi);
138
+ return {
139
+ to,
140
+ data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature])
141
+ };
142
+ }
143
+
105
144
  }
106
145
 
107
146
  const DEFAULT_GAS_LIMIT = ethers.ethers.BigNumber.from(800000);
@@ -281,18 +320,26 @@ class LocalRelayer extends ProviderRelayer {
281
320
  throw new Error('LocalRelayer requires the context.guestModule address');
282
321
  }
283
322
 
284
- const txRequest = await this.prepareTransactions(signedTxs.config, signedTxs.context, signedTxs.signature, ...signedTxs.transactions); // TODO: think about computing gas limit individually, summing together and passing across
323
+ const {
324
+ to,
325
+ execute
326
+ } = await this.prependWalletDeploy(signedTxs);
327
+ const walletInterface = new ethers.ethers.utils.Interface(abi.walletContracts.mainModule.abi);
328
+ const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]); // TODO: think about computing gas limit individually, summing together and passing across
285
329
  // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation
286
330
  // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum.add(tx.gasLimit), ethers.BigNumber.from(0))
287
331
  // txRequest.gasLimit = gasLimit
288
332
 
289
- return this.signer.sendTransaction(txRequest);
333
+ return this.signer.sendTransaction({
334
+ to,
335
+ data
336
+ });
290
337
  }
291
338
 
292
339
  }
293
340
 
294
341
  /* eslint-disable */
295
- // sequence-relayer v0.4.0 1598ae8045a4f054fefc0fa3b244f61f75a7c8bd
342
+ // sequence-relayer v0.4.0 7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd
296
343
  // --
297
344
  // This file has been generated by https://github.com/webrpc/webrpc using gen/typescript
298
345
  // Do not edit by hand. Update your webrpc schema and re-generate.
@@ -301,7 +348,7 @@ const WebRPCVersion = 'v1'; // Schema version of your RIDL schema
301
348
 
302
349
  const WebRPCSchemaVersion = 'v0.4.0'; // Schema hash generated from your RIDL schema
303
350
 
304
- const WebRPCSchemaHash = '1598ae8045a4f054fefc0fa3b244f61f75a7c8bd'; //
351
+ const WebRPCSchemaHash = '7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd'; //
305
352
  // Types
306
353
  //
307
354
 
@@ -464,6 +511,16 @@ class Relayer {
464
511
  });
465
512
  };
466
513
 
514
+ this.feeOptions = (args, headers) => {
515
+ return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers)).then(res => {
516
+ return buildResponse(res).then(_data => {
517
+ return {
518
+ options: _data.options
519
+ };
520
+ });
521
+ });
522
+ };
523
+
467
524
  this.getMetaTxnNetworkFeeOptions = (args, headers) => {
468
525
  return this.fetch(this.url('GetMetaTxnNetworkFeeOptions'), createHTTPRequest(args, headers)).then(res => {
469
526
  return buildResponse(res).then(_data => {
@@ -636,23 +693,39 @@ class RpcRelayer extends BaseRelayer {
636
693
  if (feeTokens.isFeeRequired) {
637
694
  const symbols = feeTokens.tokens.map(token => token.symbol).join(', ');
638
695
  utils.logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are required, accepted tokens are ${symbols}`);
639
- const addr = config.addressOf(config$1, context);
640
- const prevNonce = transactions.readSequenceNonce(...transactions$1); // Set temporal nonce to simulate meta-txn
696
+ const wallet = config.addressOf(config$1, context);
697
+ let nonce = transactions.readSequenceNonce(...transactions$1);
641
698
 
642
- if (prevNonce === undefined) {
643
- transactions$1 = transactions.appendNonce(transactions$1, await this.getNonce(config$1, context));
699
+ if (nonce === undefined) {
700
+ nonce = await this.getNonce(config$1, context);
644
701
  }
645
702
 
646
- const coder = ethers.ethers.utils.defaultAbiCoder;
647
- const encoded = coder.encode([transactions.MetaTransactionsType], [transactions.sequenceTxAbiEncode(transactions$1)]);
648
- const res = await this.service.getMetaTxnNetworkFeeOptions({
649
- walletConfig: _extends({}, config$1, {
650
- address: addr
651
- }),
652
- payload: encoded
703
+ if (!this.provider) {
704
+ utils.logger.warn(`[rpc-relayer/gasRefundOptions] provider not set, needed for stub signature`);
705
+ throw new Error('provider is not set');
706
+ }
707
+
708
+ const {
709
+ to,
710
+ execute
711
+ } = await this.prependWalletDeploy({
712
+ config: config$1,
713
+ context,
714
+ transactions: transactions$1,
715
+ nonce,
716
+ signature: config.buildStubSignature(this.provider, config$1)
717
+ });
718
+ const walletInterface = new ethers.ethers.utils.Interface(abi.walletContracts.mainModule.abi);
719
+ const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
720
+ const {
721
+ options
722
+ } = await this.service.feeOptions({
723
+ wallet,
724
+ to,
725
+ data
653
726
  });
654
- utils.logger.info(`[rpc-relayer/gasRefundOptions] got refund options ${JSON.stringify(res.options)}`);
655
- return res.options;
727
+ utils.logger.info(`[rpc-relayer/gasRefundOptions] got refund options ${JSON.stringify(options)}`);
728
+ return options;
656
729
  } else {
657
730
  utils.logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are not required`);
658
731
  return [];
@@ -681,13 +754,18 @@ class RpcRelayer extends BaseRelayer {
681
754
  throw new Error('provider is not set');
682
755
  }
683
756
 
684
- const addr = config.addressOf(signedTxs.config, signedTxs.context);
685
- const prep = await this.prepareTransactions(signedTxs.config, signedTxs.context, signedTxs.signature, ...signedTxs.transactions);
757
+ const {
758
+ to: contract,
759
+ execute
760
+ } = await this.prependWalletDeploy(signedTxs);
761
+ const walletAddress = config.addressOf(signedTxs.config, signedTxs.context);
762
+ const walletInterface = new ethers.ethers.utils.Interface(abi.walletContracts.mainModule.abi);
763
+ const input = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [transactions.sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
686
764
  const metaTxn = await this.service.sendMetaTxn({
687
765
  call: {
688
- contract: prep.to,
689
- input: prep.data,
690
- walletAddress: addr
766
+ walletAddress,
767
+ contract,
768
+ input
691
769
  }
692
770
  });
693
771
  utils.logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`);
@@ -1,8 +1,8 @@
1
1
  import { ethers, providers, Signer } from 'ethers';
2
- import { Provider } from '@ethersproject/providers';
3
2
  import { walletContracts } from '@0xsequence/abi';
4
3
  import { sequenceTxAbiEncode, readSequenceNonce, encodeNonce, computeMetaTxnHash, MetaTransactionsType, appendNonce, decodeNonce } from '@0xsequence/transactions';
5
- import { imageHash, addressOf, encodeSignature } from '@0xsequence/config';
4
+ import { Provider } from '@ethersproject/providers';
5
+ import { imageHash, addressOf, encodeSignature, buildStubSignature } from '@0xsequence/config';
6
6
  import { Interface } from 'ethers/lib/utils';
7
7
  import { isBigNumberish, logger } from '@0xsequence/utils';
8
8
  import fetchPonyfill from 'fetch-ponyfill';
@@ -58,8 +58,14 @@ class BaseRelayer {
58
58
  };
59
59
  }
60
60
 
61
- async prepareTransactions(config, context, signature, ...transactions) {
62
- //, gasLimit?: ethers.BigNumberish }> {
61
+ async prependWalletDeploy(signedTransactions) {
62
+ const {
63
+ config,
64
+ context,
65
+ transactions,
66
+ nonce,
67
+ signature
68
+ } = signedTransactions;
63
69
  const walletAddress = addressOf(config, context);
64
70
  const walletInterface = new Interface(walletContracts.mainModule.abi);
65
71
 
@@ -72,28 +78,61 @@ class BaseRelayer {
72
78
  if (this.bundleCreation && !(await this.isWalletDeployed(walletAddress))) {
73
79
  return {
74
80
  to: context.guestModule,
75
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [sequenceTxAbiEncode([_extends({}, this.prepareWalletDeploy(config, context), {
76
- delegateCall: false,
77
- revertOnError: false,
78
- gasLimit: this.creationGasLimit,
79
- value: ethers.constants.Zero
80
- }), {
81
- delegateCall: false,
82
- revertOnError: true,
83
- gasLimit: ethers.constants.Zero,
84
- to: walletAddress,
85
- value: ethers.constants.Zero,
86
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [sequenceTxAbiEncode(transactions), readSequenceNonce(...transactions), await encodedSignature])
87
- }]), 0, []])
81
+ execute: {
82
+ transactions: [_extends({}, this.prepareWalletDeploy(config, context), {
83
+ delegateCall: false,
84
+ revertOnError: false,
85
+ gasLimit: this.creationGasLimit,
86
+ value: ethers.constants.Zero
87
+ }), {
88
+ delegateCall: false,
89
+ revertOnError: true,
90
+ gasLimit: ethers.constants.Zero,
91
+ to: walletAddress,
92
+ value: ethers.constants.Zero,
93
+ data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [sequenceTxAbiEncode(transactions), nonce, await encodedSignature])
94
+ }],
95
+ nonce: ethers.constants.Zero,
96
+ signature: '0x'
97
+ }
88
98
  };
89
99
  } else {
90
100
  return {
91
101
  to: walletAddress,
92
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [sequenceTxAbiEncode(transactions), readSequenceNonce(...transactions), await encodedSignature])
102
+ execute: {
103
+ transactions,
104
+ nonce: ethers.BigNumber.from(nonce),
105
+ signature: await encodedSignature
106
+ }
93
107
  };
94
108
  }
95
109
  }
96
110
 
111
+ async prepareTransactions(config, context, signature, ...transactions) {
112
+ //, gasLimit?: ethers.BigNumberish }> {
113
+ const nonce = readSequenceNonce(...transactions);
114
+
115
+ if (!nonce) {
116
+ throw new Error('Unable to prepare transactions without a defined nonce');
117
+ }
118
+
119
+ const {
120
+ to,
121
+ execute
122
+ } = await this.prependWalletDeploy({
123
+ config,
124
+ context,
125
+ transactions,
126
+ nonce,
127
+ signature
128
+ });
129
+ const walletInterface = new Interface(walletContracts.mainModule.abi);
130
+ return {
131
+ to,
132
+ data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature])
133
+ };
134
+ }
135
+
97
136
  }
98
137
 
99
138
  const DEFAULT_GAS_LIMIT = ethers.BigNumber.from(800000);
@@ -273,18 +312,26 @@ class LocalRelayer extends ProviderRelayer {
273
312
  throw new Error('LocalRelayer requires the context.guestModule address');
274
313
  }
275
314
 
276
- const txRequest = await this.prepareTransactions(signedTxs.config, signedTxs.context, signedTxs.signature, ...signedTxs.transactions); // TODO: think about computing gas limit individually, summing together and passing across
315
+ const {
316
+ to,
317
+ execute
318
+ } = await this.prependWalletDeploy(signedTxs);
319
+ const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi);
320
+ const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]); // TODO: think about computing gas limit individually, summing together and passing across
277
321
  // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation
278
322
  // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum.add(tx.gasLimit), ethers.BigNumber.from(0))
279
323
  // txRequest.gasLimit = gasLimit
280
324
 
281
- return this.signer.sendTransaction(txRequest);
325
+ return this.signer.sendTransaction({
326
+ to,
327
+ data
328
+ });
282
329
  }
283
330
 
284
331
  }
285
332
 
286
333
  /* eslint-disable */
287
- // sequence-relayer v0.4.0 1598ae8045a4f054fefc0fa3b244f61f75a7c8bd
334
+ // sequence-relayer v0.4.0 7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd
288
335
  // --
289
336
  // This file has been generated by https://github.com/webrpc/webrpc using gen/typescript
290
337
  // Do not edit by hand. Update your webrpc schema and re-generate.
@@ -293,7 +340,7 @@ const WebRPCVersion = 'v1'; // Schema version of your RIDL schema
293
340
 
294
341
  const WebRPCSchemaVersion = 'v0.4.0'; // Schema hash generated from your RIDL schema
295
342
 
296
- const WebRPCSchemaHash = '1598ae8045a4f054fefc0fa3b244f61f75a7c8bd'; //
343
+ const WebRPCSchemaHash = '7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd'; //
297
344
  // Types
298
345
  //
299
346
 
@@ -456,6 +503,16 @@ class Relayer {
456
503
  });
457
504
  };
458
505
 
506
+ this.feeOptions = (args, headers) => {
507
+ return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers)).then(res => {
508
+ return buildResponse(res).then(_data => {
509
+ return {
510
+ options: _data.options
511
+ };
512
+ });
513
+ });
514
+ };
515
+
459
516
  this.getMetaTxnNetworkFeeOptions = (args, headers) => {
460
517
  return this.fetch(this.url('GetMetaTxnNetworkFeeOptions'), createHTTPRequest(args, headers)).then(res => {
461
518
  return buildResponse(res).then(_data => {
@@ -628,23 +685,39 @@ class RpcRelayer extends BaseRelayer {
628
685
  if (feeTokens.isFeeRequired) {
629
686
  const symbols = feeTokens.tokens.map(token => token.symbol).join(', ');
630
687
  logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are required, accepted tokens are ${symbols}`);
631
- const addr = addressOf(config, context);
632
- const prevNonce = readSequenceNonce(...transactions); // Set temporal nonce to simulate meta-txn
688
+ const wallet = addressOf(config, context);
689
+ let nonce = readSequenceNonce(...transactions);
633
690
 
634
- if (prevNonce === undefined) {
635
- transactions = appendNonce(transactions, await this.getNonce(config, context));
691
+ if (nonce === undefined) {
692
+ nonce = await this.getNonce(config, context);
636
693
  }
637
694
 
638
- const coder = ethers.utils.defaultAbiCoder;
639
- const encoded = coder.encode([MetaTransactionsType], [sequenceTxAbiEncode(transactions)]);
640
- const res = await this.service.getMetaTxnNetworkFeeOptions({
641
- walletConfig: _extends({}, config, {
642
- address: addr
643
- }),
644
- payload: encoded
695
+ if (!this.provider) {
696
+ logger.warn(`[rpc-relayer/gasRefundOptions] provider not set, needed for stub signature`);
697
+ throw new Error('provider is not set');
698
+ }
699
+
700
+ const {
701
+ to,
702
+ execute
703
+ } = await this.prependWalletDeploy({
704
+ config,
705
+ context,
706
+ transactions,
707
+ nonce,
708
+ signature: buildStubSignature(this.provider, config)
645
709
  });
646
- logger.info(`[rpc-relayer/gasRefundOptions] got refund options ${JSON.stringify(res.options)}`);
647
- return res.options;
710
+ const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi);
711
+ const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
712
+ const {
713
+ options
714
+ } = await this.service.feeOptions({
715
+ wallet,
716
+ to,
717
+ data
718
+ });
719
+ logger.info(`[rpc-relayer/gasRefundOptions] got refund options ${JSON.stringify(options)}`);
720
+ return options;
648
721
  } else {
649
722
  logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are not required`);
650
723
  return [];
@@ -673,13 +746,18 @@ class RpcRelayer extends BaseRelayer {
673
746
  throw new Error('provider is not set');
674
747
  }
675
748
 
676
- const addr = addressOf(signedTxs.config, signedTxs.context);
677
- const prep = await this.prepareTransactions(signedTxs.config, signedTxs.context, signedTxs.signature, ...signedTxs.transactions);
749
+ const {
750
+ to: contract,
751
+ execute
752
+ } = await this.prependWalletDeploy(signedTxs);
753
+ const walletAddress = addressOf(signedTxs.config, signedTxs.context);
754
+ const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi);
755
+ const input = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [sequenceTxAbiEncode(execute.transactions), execute.nonce, execute.signature]);
678
756
  const metaTxn = await this.service.sendMetaTxn({
679
757
  call: {
680
- contract: prep.to,
681
- input: prep.data,
682
- walletAddress: addr
758
+ walletAddress,
759
+ contract,
760
+ input
683
761
  }
684
762
  });
685
763
  logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`);
@@ -1,7 +1,7 @@
1
1
  import { ethers, providers } from "ethers";
2
2
  import { WalletContext } from '@0xsequence/network';
3
3
  import { WalletConfig, DecodedSignature } from '@0xsequence/config';
4
- import { Transaction } from '@0xsequence/transactions';
4
+ import { SignedTransactions, Transaction } from '@0xsequence/transactions';
5
5
  import { Optionals } from '@0xsequence/utils';
6
6
  import { Provider } from "@ethersproject/providers";
7
7
  export interface BaseRelayerOptions {
@@ -21,6 +21,14 @@ export declare class BaseRelayer {
21
21
  to: string;
22
22
  data: string;
23
23
  };
24
+ prependWalletDeploy(signedTransactions: Pick<SignedTransactions, 'config' | 'context' | 'transactions' | 'nonce' | 'signature'>): Promise<{
25
+ to: string;
26
+ execute: {
27
+ transactions: Transaction[];
28
+ nonce: ethers.BigNumber;
29
+ signature: string;
30
+ };
31
+ }>;
24
32
  prepareTransactions(config: WalletConfig, context: WalletContext, signature: string | Promise<string> | DecodedSignature | Promise<DecodedSignature>, ...transactions: Transaction[]): Promise<{
25
33
  to: string;
26
34
  data: string;
@@ -1,6 +1,6 @@
1
1
  export declare const WebRPCVersion = "v1";
2
2
  export declare const WebRPCSchemaVersion = "v0.4.0";
3
- export declare const WebRPCSchemaHash = "1598ae8045a4f054fefc0fa3b244f61f75a7c8bd";
3
+ export declare const WebRPCSchemaHash = "7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd";
4
4
  export declare enum ETHTxnStatus {
5
5
  UNKNOWN = "UNKNOWN",
6
6
  DROPPED = "DROPPED",
@@ -80,6 +80,9 @@ export interface MetaTxnLog {
80
80
  txnStatus: ETHTxnStatus;
81
81
  txnRevertReason: string;
82
82
  requeues: number;
83
+ queuedAt: string;
84
+ sentAt: string;
85
+ minedAt: string;
83
86
  target: string;
84
87
  input: string;
85
88
  txnArgs: {
@@ -196,6 +199,7 @@ export interface Relayer {
196
199
  simulate(args: SimulateArgs, headers?: object): Promise<SimulateReturn>;
197
200
  updateMetaTxnGasLimits(args: UpdateMetaTxnGasLimitsArgs, headers?: object): Promise<UpdateMetaTxnGasLimitsReturn>;
198
201
  feeTokens(headers?: object): Promise<FeeTokensReturn>;
202
+ feeOptions(args: FeeOptionsArgs, headers?: object): Promise<FeeOptionsReturn>;
199
203
  getMetaTxnNetworkFeeOptions(args: GetMetaTxnNetworkFeeOptionsArgs, headers?: object): Promise<GetMetaTxnNetworkFeeOptionsReturn>;
200
204
  sentTransactions(args: SentTransactionsArgs, headers?: object): Promise<SentTransactionsReturn>;
201
205
  pendingTransactions(args: PendingTransactionsArgs, headers?: object): Promise<PendingTransactionsReturn>;
@@ -266,6 +270,14 @@ export interface FeeTokensReturn {
266
270
  isFeeRequired: boolean;
267
271
  tokens: Array<FeeToken>;
268
272
  }
273
+ export interface FeeOptionsArgs {
274
+ wallet: string;
275
+ to: string;
276
+ data: string;
277
+ }
278
+ export interface FeeOptionsReturn {
279
+ options: Array<FeeOption>;
280
+ }
269
281
  export interface GetMetaTxnNetworkFeeOptionsArgs {
270
282
  walletConfig: WalletConfig;
271
283
  payload: string;
@@ -305,6 +317,7 @@ export declare class Relayer implements Relayer {
305
317
  simulate: (args: SimulateArgs, headers?: object | undefined) => Promise<SimulateReturn>;
306
318
  updateMetaTxnGasLimits: (args: UpdateMetaTxnGasLimitsArgs, headers?: object | undefined) => Promise<UpdateMetaTxnGasLimitsReturn>;
307
319
  feeTokens: (headers?: object | undefined) => Promise<FeeTokensReturn>;
320
+ feeOptions: (args: FeeOptionsArgs, headers?: object | undefined) => Promise<FeeOptionsReturn>;
308
321
  getMetaTxnNetworkFeeOptions: (args: GetMetaTxnNetworkFeeOptionsArgs, headers?: object | undefined) => Promise<GetMetaTxnNetworkFeeOptionsReturn>;
309
322
  sentTransactions: (args: SentTransactionsArgs, headers?: object | undefined) => Promise<SentTransactionsReturn>;
310
323
  pendingTransactions: (args: PendingTransactionsArgs, headers?: object | undefined) => Promise<PendingTransactionsReturn>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xsequence/relayer",
3
- "version": "0.33.2",
3
+ "version": "0.35.2",
4
4
  "description": "relayer sub-package for Sequence",
5
5
  "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/relayer",
6
6
  "source": "src/index.ts",
@@ -17,12 +17,12 @@
17
17
  "typecheck": "tsc --noEmit"
18
18
  },
19
19
  "dependencies": {
20
- "@0xsequence/abi": "^0.31.0",
21
- "@0xsequence/config": "^0.31.0",
22
- "@0xsequence/transactions": "^0.33.2",
23
- "@0xsequence/utils": "^0.31.0",
24
- "@ethersproject/providers": "^5.5.0",
25
- "ethers": "^5.5.1",
20
+ "@0xsequence/abi": "^0.35.2",
21
+ "@0xsequence/config": "^0.35.2",
22
+ "@0xsequence/transactions": "^0.35.2",
23
+ "@0xsequence/utils": "^0.35.2",
24
+ "@ethersproject/providers": "^5.5.1",
25
+ "ethers": "^5.5.2",
26
26
  "fetch-ponyfill": "^7.1.0"
27
27
  },
28
28
  "peerDependencies": {},
@@ -3,7 +3,7 @@ import { Interface } from "ethers/lib/utils"
3
3
  import { walletContracts } from '@0xsequence/abi'
4
4
  import { WalletContext } from '@0xsequence/network'
5
5
  import { WalletConfig, addressOf, imageHash, DecodedSignature, encodeSignature } from '@0xsequence/config'
6
- import { Transaction, sequenceTxAbiEncode, readSequenceNonce } from '@0xsequence/transactions'
6
+ import { SignedTransactions, Transaction, sequenceTxAbiEncode, readSequenceNonce } from '@0xsequence/transactions'
7
7
  import { isBigNumberish, Optionals } from '@0xsequence/utils'
8
8
  import { Provider } from "@ethersproject/providers"
9
9
 
@@ -58,12 +58,10 @@ export class BaseRelayer {
58
58
  }
59
59
  }
60
60
 
61
- async prepareTransactions(
62
- config: WalletConfig,
63
- context: WalletContext,
64
- signature: string | Promise<string> | DecodedSignature | Promise<DecodedSignature>,
65
- ...transactions: Transaction[]
66
- ): Promise<{ to: string, data: string }> { //, gasLimit?: ethers.BigNumberish }> {
61
+ async prependWalletDeploy(
62
+ signedTransactions: Pick<SignedTransactions, 'config' | 'context' | 'transactions' | 'nonce' | 'signature'>
63
+ ): Promise<{ to: string, execute: { transactions: Transaction[], nonce: ethers.BigNumber, signature: string } }> {
64
+ const { config, context, transactions, nonce, signature } = signedTransactions
67
65
  const walletAddress = addressOf(config, context)
68
66
  const walletInterface = new Interface(walletContracts.mainModule.abi)
69
67
 
@@ -77,8 +75,8 @@ export class BaseRelayer {
77
75
  if (this.bundleCreation && !(await this.isWalletDeployed(walletAddress))) {
78
76
  return {
79
77
  to: context.guestModule!,
80
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [
81
- sequenceTxAbiEncode([
78
+ execute: {
79
+ transactions: [
82
80
  {
83
81
  ...this.prepareWalletDeploy(config, context),
84
82
  delegateCall: false,
@@ -95,25 +93,46 @@ export class BaseRelayer {
95
93
  data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'),
96
94
  [
97
95
  sequenceTxAbiEncode(transactions),
98
- readSequenceNonce(...transactions),
96
+ nonce,
99
97
  await encodedSignature
100
98
  ]
101
99
  )
102
100
  }
103
- ]), 0, []
104
- ])
101
+ ],
102
+ nonce: ethers.constants.Zero,
103
+ signature: '0x'
104
+ }
105
105
  }
106
106
  } else {
107
107
  return {
108
108
  to: walletAddress,
109
- data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'),
110
- [
111
- sequenceTxAbiEncode(transactions),
112
- readSequenceNonce(...transactions),
113
- await encodedSignature
114
- ]
115
- )
109
+ execute: {
110
+ transactions,
111
+ nonce: ethers.BigNumber.from(nonce),
112
+ signature: await encodedSignature
113
+ }
116
114
  }
117
115
  }
118
116
  }
117
+
118
+ async prepareTransactions(
119
+ config: WalletConfig,
120
+ context: WalletContext,
121
+ signature: string | Promise<string> | DecodedSignature | Promise<DecodedSignature>,
122
+ ...transactions: Transaction[]
123
+ ): Promise<{ to: string, data: string }> { //, gasLimit?: ethers.BigNumberish }> {
124
+ const nonce = readSequenceNonce(...transactions)
125
+ if (!nonce) {
126
+ throw new Error('Unable to prepare transactions without a defined nonce')
127
+ }
128
+ const { to, execute } = await this.prependWalletDeploy({ config, context, transactions, nonce, signature })
129
+ const walletInterface = new Interface(walletContracts.mainModule.abi)
130
+ return {
131
+ to, data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [
132
+ sequenceTxAbiEncode(execute.transactions),
133
+ execute.nonce,
134
+ execute.signature
135
+ ])
136
+ }
137
+ }
119
138
  }
@@ -1,6 +1,7 @@
1
1
  import { TransactionResponse } from '@ethersproject/providers'
2
2
  import { Signer as AbstractSigner, ethers } from 'ethers'
3
- import { SignedTransactions, Transaction } from '@0xsequence/transactions'
3
+ import { walletContracts } from '@0xsequence/abi'
4
+ import { SignedTransactions, Transaction, sequenceTxAbiEncode } from '@0xsequence/transactions'
4
5
  import { WalletContext } from '@0xsequence/network'
5
6
  import { WalletConfig } from '@0xsequence/config'
6
7
  import { FeeOption, Relayer } from '.'
@@ -46,13 +47,20 @@ export class LocalRelayer extends ProviderRelayer implements Relayer {
46
47
  throw new Error('LocalRelayer requires the context.guestModule address')
47
48
  }
48
49
 
49
- const txRequest = await this.prepareTransactions(signedTxs.config, signedTxs.context, signedTxs.signature, ...signedTxs.transactions)
50
+ const { to, execute } = await this.prependWalletDeploy(signedTxs)
51
+
52
+ const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi)
53
+ const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [
54
+ sequenceTxAbiEncode(execute.transactions),
55
+ execute.nonce,
56
+ execute.signature
57
+ ])
50
58
 
51
59
  // TODO: think about computing gas limit individually, summing together and passing across
52
60
  // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation
53
61
  // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum.add(tx.gasLimit), ethers.BigNumber.from(0))
54
62
  // txRequest.gasLimit = gasLimit
55
63
 
56
- return this.signer.sendTransaction(txRequest)
64
+ return this.signer.sendTransaction({ to, data })
57
65
  }
58
66
  }
@@ -1,6 +1,7 @@
1
1
  import { TransactionResponse } from '@ethersproject/providers'
2
2
  import { ethers } from 'ethers'
3
3
  import fetchPonyfill from 'fetch-ponyfill'
4
+ import { walletContracts } from '@0xsequence/abi'
4
5
  import {
5
6
  Transaction,
6
7
  readSequenceNonce,
@@ -14,7 +15,7 @@ import {
14
15
  import { BaseRelayer, BaseRelayerOptions } from '../base-relayer'
15
16
  import { FeeOption, Relayer, SimulateResult } from '..'
16
17
  import { WalletContext } from '@0xsequence/network'
17
- import { WalletConfig, addressOf } from '@0xsequence/config'
18
+ import { WalletConfig, addressOf, buildStubSignature } from '@0xsequence/config'
18
19
  import { logger } from '@0xsequence/utils'
19
20
  import * as proto from './relayer.gen'
20
21
 
@@ -122,23 +123,37 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
122
123
  const symbols = feeTokens.tokens.map(token => token.symbol).join(', ')
123
124
  logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are required, accepted tokens are ${symbols}`)
124
125
 
125
- const addr = addressOf(config, context)
126
- const prevNonce = readSequenceNonce(...transactions)
126
+ const wallet = addressOf(config, context)
127
127
 
128
- // Set temporal nonce to simulate meta-txn
129
- if (prevNonce === undefined) {
130
- transactions = appendNonce(transactions, await this.getNonce(config, context))
128
+ let nonce = readSequenceNonce(...transactions)
129
+ if (nonce === undefined) {
130
+ nonce = await this.getNonce(config, context)
131
131
  }
132
132
 
133
- const coder = ethers.utils.defaultAbiCoder
134
- const encoded = coder.encode([MetaTransactionsType], [sequenceTxAbiEncode(transactions)])
135
- const res = await this.service.getMetaTxnNetworkFeeOptions({
136
- walletConfig: { ...config, address: addr },
137
- payload: encoded
133
+ if (!this.provider) {
134
+ logger.warn(`[rpc-relayer/gasRefundOptions] provider not set, needed for stub signature`)
135
+ throw new Error('provider is not set')
136
+ }
137
+
138
+ const { to, execute } = await this.prependWalletDeploy({
139
+ config,
140
+ context,
141
+ transactions,
142
+ nonce,
143
+ signature: buildStubSignature(this.provider, config)
138
144
  })
139
145
 
140
- logger.info(`[rpc-relayer/gasRefundOptions] got refund options ${JSON.stringify(res.options)}`)
141
- return res.options
146
+ const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi)
147
+ const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [
148
+ sequenceTxAbiEncode(execute.transactions),
149
+ execute.nonce,
150
+ execute.signature
151
+ ])
152
+
153
+ const { options } = await this.service.feeOptions({ wallet, to, data })
154
+
155
+ logger.info(`[rpc-relayer/gasRefundOptions] got refund options ${JSON.stringify(options)}`)
156
+ return options
142
157
  } else {
143
158
  logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are not required`)
144
159
  return []
@@ -164,20 +179,17 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
164
179
  throw new Error('provider is not set')
165
180
  }
166
181
 
167
- const addr = addressOf(signedTxs.config, signedTxs.context)
168
- const prep = await this.prepareTransactions(
169
- signedTxs.config,
170
- signedTxs.context,
171
- signedTxs.signature,
172
- ...signedTxs.transactions
173
- )
174
- const metaTxn = await this.service.sendMetaTxn({
175
- call: {
176
- contract: prep.to,
177
- input: prep.data,
178
- walletAddress: addr
179
- }
180
- })
182
+ const { to: contract, execute } = await this.prependWalletDeploy(signedTxs)
183
+
184
+ const walletAddress = addressOf(signedTxs.config, signedTxs.context)
185
+ const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi)
186
+ const input = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [
187
+ sequenceTxAbiEncode(execute.transactions),
188
+ execute.nonce,
189
+ execute.signature
190
+ ])
191
+
192
+ const metaTxn = await this.service.sendMetaTxn({ call: { walletAddress, contract, input } })
181
193
 
182
194
  logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`)
183
195
 
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable */
2
- // sequence-relayer v0.4.0 1598ae8045a4f054fefc0fa3b244f61f75a7c8bd
2
+ // sequence-relayer v0.4.0 7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd
3
3
  // --
4
4
  // This file has been generated by https://github.com/webrpc/webrpc using gen/typescript
5
5
  // Do not edit by hand. Update your webrpc schema and re-generate.
@@ -11,7 +11,7 @@ export const WebRPCVersion = 'v1'
11
11
  export const WebRPCSchemaVersion = 'v0.4.0'
12
12
 
13
13
  // Schema hash generated from your RIDL schema
14
- export const WebRPCSchemaHash = '1598ae8045a4f054fefc0fa3b244f61f75a7c8bd'
14
+ export const WebRPCSchemaHash = '7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd'
15
15
 
16
16
  //
17
17
  // Types
@@ -106,6 +106,9 @@ export interface MetaTxnLog {
106
106
  txnStatus: ETHTxnStatus
107
107
  txnRevertReason: string
108
108
  requeues: number
109
+ queuedAt: string
110
+ sentAt: string
111
+ minedAt: string
109
112
  target: string
110
113
  input: string
111
114
  txnArgs: { [key: string]: any }
@@ -229,6 +232,7 @@ export interface Relayer {
229
232
  simulate(args: SimulateArgs, headers?: object): Promise<SimulateReturn>
230
233
  updateMetaTxnGasLimits(args: UpdateMetaTxnGasLimitsArgs, headers?: object): Promise<UpdateMetaTxnGasLimitsReturn>
231
234
  feeTokens(headers?: object): Promise<FeeTokensReturn>
235
+ feeOptions(args: FeeOptionsArgs, headers?: object): Promise<FeeOptionsReturn>
232
236
  getMetaTxnNetworkFeeOptions(args: GetMetaTxnNetworkFeeOptionsArgs, headers?: object): Promise<GetMetaTxnNetworkFeeOptionsReturn>
233
237
  sentTransactions(args: SentTransactionsArgs, headers?: object): Promise<SentTransactionsReturn>
234
238
  pendingTransactions(args: PendingTransactionsArgs, headers?: object): Promise<PendingTransactionsReturn>
@@ -305,6 +309,15 @@ export interface FeeTokensReturn {
305
309
  isFeeRequired: boolean
306
310
  tokens: Array<FeeToken>
307
311
  }
312
+ export interface FeeOptionsArgs {
313
+ wallet: string
314
+ to: string
315
+ data: string
316
+ }
317
+
318
+ export interface FeeOptionsReturn {
319
+ options: Array<FeeOption>
320
+ }
308
321
  export interface GetMetaTxnNetworkFeeOptionsArgs {
309
322
  walletConfig: WalletConfig
310
323
  payload: string
@@ -460,6 +473,16 @@ export class Relayer implements Relayer {
460
473
  })
461
474
  }
462
475
 
476
+ feeOptions = (args: FeeOptionsArgs, headers?: object): Promise<FeeOptionsReturn> => {
477
+ return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers)).then(res => {
478
+ return buildResponse(res).then(_data => {
479
+ return {
480
+ options: <Array<FeeOption>>_data.options
481
+ }
482
+ })
483
+ })
484
+ }
485
+
463
486
  getMetaTxnNetworkFeeOptions = (
464
487
  args: GetMetaTxnNetworkFeeOptionsArgs,
465
488
  headers?: object