@0xsequence/relayer 0.31.0 → 0.35.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.
@@ -4,6 +4,7 @@ import { WalletContext } from '@0xsequence/network';
4
4
  import { WalletConfig } from '@0xsequence/config';
5
5
  import { proto } from './rpc-relayer';
6
6
  export interface Relayer {
7
+ simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]>;
7
8
  estimateGasLimits(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<Transaction[]>;
8
9
  gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]>;
9
10
  getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish, blockTag?: providers.BlockTag): Promise<ethers.BigNumberish>;
@@ -15,5 +16,6 @@ export * from './base-relayer';
15
16
  export * from './provider-relayer';
16
17
  export * from './rpc-relayer';
17
18
  export { proto as RpcRelayerProto } from './rpc-relayer';
19
+ export declare type SimulateResult = proto.SimulateResult;
18
20
  export declare type FeeOption = proto.FeeOption;
19
21
  export declare function isRelayer(cand: any): cand is Relayer;
@@ -4,7 +4,7 @@ import { SignedTransactions, Transaction } from '@0xsequence/transactions';
4
4
  import { WalletContext } from '@0xsequence/network';
5
5
  import { WalletConfig } from '@0xsequence/config';
6
6
  import { BaseRelayer, BaseRelayerOptions } from './base-relayer';
7
- import { FeeOption, Relayer } from '.';
7
+ import { FeeOption, Relayer, SimulateResult } from '.';
8
8
  import { Optionals, Mask } from '@0xsequence/utils';
9
9
  export interface ProviderRelayerOptions extends BaseRelayerOptions {
10
10
  provider: Provider;
@@ -22,6 +22,7 @@ export declare abstract class ProviderRelayer extends BaseRelayer implements Rel
22
22
  constructor(options: ProviderRelayerOptions);
23
23
  abstract gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]>;
24
24
  abstract relay(signedTxs: SignedTransactions): Promise<TransactionResponse>;
25
+ simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]>;
25
26
  estimateGasLimits(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<Transaction[]>;
26
27
  getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish, blockTag?: BlockTag): Promise<ethers.BigNumberish>;
27
28
  wait(metaTxnId: string | SignedTransactions, timeout: number): Promise<providers.TransactionResponse & {
@@ -2,7 +2,7 @@ import { TransactionResponse } from '@ethersproject/providers';
2
2
  import { ethers } from 'ethers';
3
3
  import { Transaction, SignedTransactions } from '@0xsequence/transactions';
4
4
  import { BaseRelayer, BaseRelayerOptions } from '../base-relayer';
5
- import { FeeOption, Relayer } from '..';
5
+ import { FeeOption, Relayer, SimulateResult } from '..';
6
6
  import { WalletContext } from '@0xsequence/network';
7
7
  import { WalletConfig } from '@0xsequence/config';
8
8
  import * as proto from './relayer.gen';
@@ -15,6 +15,7 @@ export declare class RpcRelayer extends BaseRelayer implements Relayer {
15
15
  private readonly service;
16
16
  constructor(options: RpcRelayerOptions);
17
17
  waitReceipt(metaTxnHash: string | SignedTransactions, wait?: number): Promise<proto.GetMetaTxnReceiptReturn>;
18
+ simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]>;
18
19
  estimateGasLimits(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<Transaction[]>;
19
20
  gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]>;
20
21
  getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish): Promise<ethers.BigNumberish>;
@@ -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 = "fc9652e2bc0c3df8d1ce0b4a8e24ab8790e4dae2";
3
+ export declare const WebRPCSchemaHash = "7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd";
4
4
  export declare enum ETHTxnStatus {
5
5
  UNKNOWN = "UNKNOWN",
6
6
  DROPPED = "DROPPED",
@@ -79,6 +79,10 @@ export interface MetaTxnLog {
79
79
  metaTxnID?: string;
80
80
  txnStatus: ETHTxnStatus;
81
81
  txnRevertReason: string;
82
+ requeues: number;
83
+ queuedAt: string;
84
+ sentAt: string;
85
+ minedAt: string;
82
86
  target: string;
83
87
  input: string;
84
88
  txnArgs: {
@@ -145,6 +149,14 @@ export interface SentTransactionsFilter {
145
149
  pending?: boolean;
146
150
  failed?: boolean;
147
151
  }
152
+ export interface SimulateResult {
153
+ executed: boolean;
154
+ succeeded: boolean;
155
+ result?: string;
156
+ reason?: string;
157
+ gasUsed: number;
158
+ gasLimit: number;
159
+ }
148
160
  export interface FeeOption {
149
161
  token: FeeToken;
150
162
  to: string;
@@ -184,8 +196,10 @@ export interface Relayer {
184
196
  sendMetaTxn(args: SendMetaTxnArgs, headers?: object): Promise<SendMetaTxnReturn>;
185
197
  getMetaTxnNonce(args: GetMetaTxnNonceArgs, headers?: object): Promise<GetMetaTxnNonceReturn>;
186
198
  getMetaTxnReceipt(args: GetMetaTxnReceiptArgs, headers?: object): Promise<GetMetaTxnReceiptReturn>;
199
+ simulate(args: SimulateArgs, headers?: object): Promise<SimulateReturn>;
187
200
  updateMetaTxnGasLimits(args: UpdateMetaTxnGasLimitsArgs, headers?: object): Promise<UpdateMetaTxnGasLimitsReturn>;
188
201
  feeTokens(headers?: object): Promise<FeeTokensReturn>;
202
+ feeOptions(args: FeeOptionsArgs, headers?: object): Promise<FeeOptionsReturn>;
189
203
  getMetaTxnNetworkFeeOptions(args: GetMetaTxnNetworkFeeOptionsArgs, headers?: object): Promise<GetMetaTxnNetworkFeeOptionsReturn>;
190
204
  sentTransactions(args: SentTransactionsArgs, headers?: object): Promise<SentTransactionsReturn>;
191
205
  pendingTransactions(args: PendingTransactionsArgs, headers?: object): Promise<PendingTransactionsReturn>;
@@ -235,6 +249,13 @@ export interface GetMetaTxnReceiptArgs {
235
249
  export interface GetMetaTxnReceiptReturn {
236
250
  receipt: MetaTxnReceipt;
237
251
  }
252
+ export interface SimulateArgs {
253
+ wallet: string;
254
+ transactions: string;
255
+ }
256
+ export interface SimulateReturn {
257
+ results: Array<SimulateResult>;
258
+ }
238
259
  export interface UpdateMetaTxnGasLimitsArgs {
239
260
  walletAddress: string;
240
261
  walletConfig: WalletConfig;
@@ -249,6 +270,14 @@ export interface FeeTokensReturn {
249
270
  isFeeRequired: boolean;
250
271
  tokens: Array<FeeToken>;
251
272
  }
273
+ export interface FeeOptionsArgs {
274
+ wallet: string;
275
+ to: string;
276
+ data: string;
277
+ }
278
+ export interface FeeOptionsReturn {
279
+ options: Array<FeeOption>;
280
+ }
252
281
  export interface GetMetaTxnNetworkFeeOptionsArgs {
253
282
  walletConfig: WalletConfig;
254
283
  payload: string;
@@ -285,8 +314,10 @@ export declare class Relayer implements Relayer {
285
314
  sendMetaTxn: (args: SendMetaTxnArgs, headers?: object | undefined) => Promise<SendMetaTxnReturn>;
286
315
  getMetaTxnNonce: (args: GetMetaTxnNonceArgs, headers?: object | undefined) => Promise<GetMetaTxnNonceReturn>;
287
316
  getMetaTxnReceipt: (args: GetMetaTxnReceiptArgs, headers?: object | undefined) => Promise<GetMetaTxnReceiptReturn>;
317
+ simulate: (args: SimulateArgs, headers?: object | undefined) => Promise<SimulateReturn>;
288
318
  updateMetaTxnGasLimits: (args: UpdateMetaTxnGasLimitsArgs, headers?: object | undefined) => Promise<UpdateMetaTxnGasLimitsReturn>;
289
319
  feeTokens: (headers?: object | undefined) => Promise<FeeTokensReturn>;
320
+ feeOptions: (args: FeeOptionsArgs, headers?: object | undefined) => Promise<FeeOptionsReturn>;
290
321
  getMetaTxnNetworkFeeOptions: (args: GetMetaTxnNetworkFeeOptionsArgs, headers?: object | undefined) => Promise<GetMetaTxnNetworkFeeOptionsReturn>;
291
322
  sentTransactions: (args: SentTransactionsArgs, headers?: object | undefined) => Promise<SentTransactionsReturn>;
292
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.31.0",
3
+ "version": "0.35.0",
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.31.0",
23
- "@0xsequence/utils": "^0.31.0",
24
- "@ethersproject/providers": "^5.5.0",
25
- "ethers": "^5.5.1",
20
+ "@0xsequence/abi": "^0.35.0",
21
+ "@0xsequence/config": "^0.35.0",
22
+ "@0xsequence/transactions": "^0.35.0",
23
+ "@0xsequence/utils": "^0.35.0",
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
  }
package/src/index.ts CHANGED
@@ -5,6 +5,8 @@ import { WalletConfig } from '@0xsequence/config'
5
5
  import { proto } from './rpc-relayer'
6
6
 
7
7
  export interface Relayer {
8
+ // simulate returns the execution results for a list of transactions.
9
+ simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]>
8
10
 
9
11
  // estimateGasLimits will estimate the gas utilization from the transaction
10
12
  // before submission.
@@ -39,6 +41,7 @@ export * from './base-relayer'
39
41
  export * from './provider-relayer'
40
42
  export * from './rpc-relayer'
41
43
  export { proto as RpcRelayerProto } from './rpc-relayer'
44
+ export type SimulateResult = proto.SimulateResult
42
45
  export type FeeOption = proto.FeeOption
43
46
 
44
47
  export function isRelayer(cand: any): cand is Relayer {
@@ -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
  }
@@ -5,7 +5,7 @@ import { computeMetaTxnHash, encodeNonce, SignedTransactions, Transaction } from
5
5
  import { WalletContext } from '@0xsequence/network'
6
6
  import { WalletConfig, addressOf } from '@0xsequence/config'
7
7
  import { BaseRelayer, BaseRelayerOptions } from './base-relayer'
8
- import { FeeOption, Relayer } from '.'
8
+ import { FeeOption, Relayer, SimulateResult } from '.'
9
9
  import { Optionals, Mask } from '@0xsequence/utils'
10
10
 
11
11
  const DEFAULT_GAS_LIMIT = ethers.BigNumber.from(800000)
@@ -45,14 +45,8 @@ export abstract class ProviderRelayer extends BaseRelayer implements Relayer {
45
45
  abstract gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]>
46
46
  abstract relay(signedTxs: SignedTransactions): Promise<TransactionResponse>
47
47
 
48
- async estimateGasLimits(
49
- config: WalletConfig,
50
- context: WalletContext,
51
- ...transactions: Transaction[]
52
- ): Promise<Transaction[]> {
53
- const walletAddr = addressOf(config, context)
54
-
55
- const gasCosts = await Promise.all(transactions.map(async tx => {
48
+ async simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]> {
49
+ return (await Promise.all(transactions.map(async tx => {
56
50
  // Respect gasLimit request of the transaction (as long as its not 0)
57
51
  if (tx.gasLimit && !ethers.BigNumber.from(tx.gasLimit || 0).eq(ethers.constants.Zero)) {
58
52
  return tx.gasLimit
@@ -64,7 +58,7 @@ export abstract class ProviderRelayer extends BaseRelayer implements Relayer {
64
58
  }
65
59
 
66
60
  // Fee can't be estimated for self-called if wallet hasn't been deployed
67
- if (tx.to === walletAddr && !(await this.isWalletDeployed(walletAddr))) {
61
+ if (tx.to === wallet && !(await this.isWalletDeployed(wallet))) {
68
62
  return DEFAULT_GAS_LIMIT
69
63
  }
70
64
 
@@ -75,17 +69,27 @@ export abstract class ProviderRelayer extends BaseRelayer implements Relayer {
75
69
  // TODO: If the wallet address has been deployed, gas limits can be
76
70
  // estimated with more accurately by using self-calls with the batch transactions one by one
77
71
  return this.provider.estimateGas({
78
- from: walletAddr,
72
+ from: wallet,
79
73
  to: tx.to,
80
74
  data: tx.data,
81
75
  value: tx.value
82
76
  })
77
+ }))).map(gasLimit => ({
78
+ executed: true,
79
+ succeeded: true,
80
+ gasLimit: ethers.BigNumber.from(gasLimit).toNumber(),
81
+ gasUsed: ethers.BigNumber.from(gasLimit).toNumber()
83
82
  }))
83
+ }
84
84
 
85
- return transactions.map((t, i) => {
86
- t.gasLimit = gasCosts[i]
87
- return t
88
- })
85
+ async estimateGasLimits(
86
+ config: WalletConfig,
87
+ context: WalletContext,
88
+ ...transactions: Transaction[]
89
+ ): Promise<Transaction[]> {
90
+ const walletAddr = addressOf(config, context)
91
+ const results = await this.simulate(walletAddr, ...transactions)
92
+ return transactions.map((t, i) => ({ ...t, gasLimit: results[i].gasLimit }))
89
93
  }
90
94
 
91
95
  async getNonce(
@@ -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,
@@ -12,9 +13,9 @@ import {
12
13
  decodeNonce
13
14
  } from '@0xsequence/transactions'
14
15
  import { BaseRelayer, BaseRelayerOptions } from '../base-relayer'
15
- import { FeeOption, Relayer } from '..'
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
 
@@ -66,6 +67,12 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
66
67
  return result
67
68
  }
68
69
 
70
+ async simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]> {
71
+ const coder = ethers.utils.defaultAbiCoder
72
+ const encoded = coder.encode([MetaTransactionsType], [sequenceTxAbiEncode(transactions)])
73
+ return (await this.service.simulate({ wallet, transactions: encoded })).results
74
+ }
75
+
69
76
  async estimateGasLimits(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<Transaction[]> {
70
77
  logger.info(`[rpc-relayer/estimateGasLimits] estimate gas limits request ${JSON.stringify(transactions)}`)
71
78
 
@@ -116,23 +123,37 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
116
123
  const symbols = feeTokens.tokens.map(token => token.symbol).join(', ')
117
124
  logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are required, accepted tokens are ${symbols}`)
118
125
 
119
- const addr = addressOf(config, context)
120
- const prevNonce = readSequenceNonce(...transactions)
126
+ const wallet = addressOf(config, context)
127
+
128
+ let nonce = readSequenceNonce(...transactions)
129
+ if (nonce === undefined) {
130
+ nonce = await this.getNonce(config, context)
131
+ }
121
132
 
122
- // Set temporal nonce to simulate meta-txn
123
- if (prevNonce === undefined) {
124
- transactions = appendNonce(transactions, await this.getNonce(config, context))
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')
125
136
  }
126
137
 
127
- const coder = ethers.utils.defaultAbiCoder
128
- const encoded = coder.encode([MetaTransactionsType], [sequenceTxAbiEncode(transactions)])
129
- const res = await this.service.getMetaTxnNetworkFeeOptions({
130
- walletConfig: { ...config, address: addr },
131
- payload: encoded
138
+ const { to, execute } = await this.prependWalletDeploy({
139
+ config,
140
+ context,
141
+ transactions,
142
+ nonce,
143
+ signature: buildStubSignature(this.provider, config)
132
144
  })
133
145
 
134
- logger.info(`[rpc-relayer/gasRefundOptions] got refund options ${JSON.stringify(res.options)}`)
135
- 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
136
157
  } else {
137
158
  logger.info(`[rpc-relayer/gasRefundOptions] relayer fees are not required`)
138
159
  return []
@@ -158,20 +179,17 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
158
179
  throw new Error('provider is not set')
159
180
  }
160
181
 
161
- const addr = addressOf(signedTxs.config, signedTxs.context)
162
- const prep = await this.prepareTransactions(
163
- signedTxs.config,
164
- signedTxs.context,
165
- signedTxs.signature,
166
- ...signedTxs.transactions
167
- )
168
- const metaTxn = await this.service.sendMetaTxn({
169
- call: {
170
- contract: prep.to,
171
- input: prep.data,
172
- walletAddress: addr
173
- }
174
- })
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 } })
175
193
 
176
194
  logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`)
177
195
 
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable */
2
- // sequence-relayer v0.4.0 fc9652e2bc0c3df8d1ce0b4a8e24ab8790e4dae2
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 = 'fc9652e2bc0c3df8d1ce0b4a8e24ab8790e4dae2'
14
+ export const WebRPCSchemaHash = '7dbfaf5c04cf28e9259ff1a9bf3274c8d73be5dd'
15
15
 
16
16
  //
17
17
  // Types
@@ -105,6 +105,10 @@ export interface MetaTxnLog {
105
105
  metaTxnID?: string
106
106
  txnStatus: ETHTxnStatus
107
107
  txnRevertReason: string
108
+ requeues: number
109
+ queuedAt: string
110
+ sentAt: string
111
+ minedAt: string
108
112
  target: string
109
113
  input: string
110
114
  txnArgs: { [key: string]: any }
@@ -173,6 +177,15 @@ export interface SentTransactionsFilter {
173
177
  failed?: boolean
174
178
  }
175
179
 
180
+ export interface SimulateResult {
181
+ executed: boolean
182
+ succeeded: boolean
183
+ result?: string
184
+ reason?: string
185
+ gasUsed: number
186
+ gasLimit: number
187
+ }
188
+
176
189
  export interface FeeOption {
177
190
  token: FeeToken
178
191
  to: string
@@ -216,8 +229,10 @@ export interface Relayer {
216
229
  sendMetaTxn(args: SendMetaTxnArgs, headers?: object): Promise<SendMetaTxnReturn>
217
230
  getMetaTxnNonce(args: GetMetaTxnNonceArgs, headers?: object): Promise<GetMetaTxnNonceReturn>
218
231
  getMetaTxnReceipt(args: GetMetaTxnReceiptArgs, headers?: object): Promise<GetMetaTxnReceiptReturn>
232
+ simulate(args: SimulateArgs, headers?: object): Promise<SimulateReturn>
219
233
  updateMetaTxnGasLimits(args: UpdateMetaTxnGasLimitsArgs, headers?: object): Promise<UpdateMetaTxnGasLimitsReturn>
220
234
  feeTokens(headers?: object): Promise<FeeTokensReturn>
235
+ feeOptions(args: FeeOptionsArgs, headers?: object): Promise<FeeOptionsReturn>
221
236
  getMetaTxnNetworkFeeOptions(args: GetMetaTxnNetworkFeeOptionsArgs, headers?: object): Promise<GetMetaTxnNetworkFeeOptionsReturn>
222
237
  sentTransactions(args: SentTransactionsArgs, headers?: object): Promise<SentTransactionsReturn>
223
238
  pendingTransactions(args: PendingTransactionsArgs, headers?: object): Promise<PendingTransactionsReturn>
@@ -271,6 +286,14 @@ export interface GetMetaTxnReceiptArgs {
271
286
  export interface GetMetaTxnReceiptReturn {
272
287
  receipt: MetaTxnReceipt
273
288
  }
289
+ export interface SimulateArgs {
290
+ wallet: string
291
+ transactions: string
292
+ }
293
+
294
+ export interface SimulateReturn {
295
+ results: Array<SimulateResult>
296
+ }
274
297
  export interface UpdateMetaTxnGasLimitsArgs {
275
298
  walletAddress: string
276
299
  walletConfig: WalletConfig
@@ -286,6 +309,15 @@ export interface FeeTokensReturn {
286
309
  isFeeRequired: boolean
287
310
  tokens: Array<FeeToken>
288
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
+ }
289
321
  export interface GetMetaTxnNetworkFeeOptionsArgs {
290
322
  walletConfig: WalletConfig
291
323
  payload: string
@@ -410,6 +442,16 @@ export class Relayer implements Relayer {
410
442
  })
411
443
  }
412
444
 
445
+ simulate = (args: SimulateArgs, headers?: object): Promise<SimulateReturn> => {
446
+ return this.fetch(this.url('Simulate'), createHTTPRequest(args, headers)).then(res => {
447
+ return buildResponse(res).then(_data => {
448
+ return {
449
+ results: <Array<SimulateResult>>_data.results
450
+ }
451
+ })
452
+ })
453
+ }
454
+
413
455
  updateMetaTxnGasLimits = (args: UpdateMetaTxnGasLimitsArgs, headers?: object): Promise<UpdateMetaTxnGasLimitsReturn> => {
414
456
  return this.fetch(this.url('UpdateMetaTxnGasLimits'), createHTTPRequest(args, headers)).then(res => {
415
457
  return buildResponse(res).then(_data => {
@@ -431,6 +473,16 @@ export class Relayer implements Relayer {
431
473
  })
432
474
  }
433
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
+
434
486
  getMetaTxnNetworkFeeOptions = (
435
487
  args: GetMetaTxnNetworkFeeOptionsArgs,
436
488
  headers?: object