@0xsequence/relayer 0.34.0 → 0.35.3

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.
@@ -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.34.0",
3
+ "version": "0.35.3",
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,10 +17,10 @@
17
17
  "typecheck": "tsc --noEmit"
18
18
  },
19
19
  "dependencies": {
20
- "@0xsequence/abi": "^0.34.0",
21
- "@0xsequence/config": "^0.34.0",
22
- "@0xsequence/transactions": "^0.34.0",
23
- "@0xsequence/utils": "^0.34.0",
20
+ "@0xsequence/abi": "^0.35.3",
21
+ "@0xsequence/config": "^0.35.3",
22
+ "@0xsequence/transactions": "^0.35.3",
23
+ "@0xsequence/utils": "^0.35.3",
24
24
  "@ethersproject/providers": "^5.5.1",
25
25
  "ethers": "^5.5.2",
26
26
  "fetch-ponyfill": "^7.1.0"
@@ -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