@0xsequence/relayer 0.43.33 → 1.0.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.
@@ -1,28 +1,33 @@
1
1
  import { ethers } from 'ethers';
2
- import { Transaction, SignedTransactions, TransactionResponse } from '@0xsequence/transactions';
3
- import { BaseRelayer, BaseRelayerOptions } from '../base-relayer';
4
2
  import { FeeOption, FeeQuote, Relayer, SimulateResult } from '..';
5
- import { WalletContext } from '@0xsequence/network';
6
- import { WalletConfig } from '@0xsequence/config';
7
3
  import * as proto from './relayer.gen';
4
+ import { commons } from '@0xsequence/core';
8
5
  export { proto };
9
- export interface RpcRelayerOptions extends BaseRelayerOptions {
6
+ export interface RpcRelayerOptions {
7
+ provider: ethers.providers.Provider | {
8
+ url: string;
9
+ };
10
10
  url: string;
11
11
  }
12
12
  export declare function isRpcRelayerOptions(obj: any): obj is RpcRelayerOptions;
13
- export declare class RpcRelayer extends BaseRelayer implements Relayer {
13
+ export declare class RpcRelayer implements Relayer {
14
14
  private readonly service;
15
+ readonly provider: ethers.providers.Provider;
15
16
  constructor(options: RpcRelayerOptions);
16
- waitReceipt(metaTxnId: string | SignedTransactions, delay?: number, maxFails?: number, isCancelled?: () => boolean): Promise<proto.GetMetaTxnReceiptReturn>;
17
- simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]>;
18
- getFeeOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<{
17
+ waitReceipt(metaTxnId: string | commons.transaction.SignedTransactionBundle, delay?: number, maxFails?: number, isCancelled?: () => boolean): Promise<proto.GetMetaTxnReceiptReturn>;
18
+ simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise<SimulateResult[]>;
19
+ getFeeOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<{
19
20
  options: FeeOption[];
20
21
  quote?: FeeQuote;
21
22
  }>;
22
- gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]>;
23
- getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish): Promise<ethers.BigNumberish>;
24
- relay(signedTxs: SignedTransactions, quote?: FeeQuote, waitForReceipt?: boolean): Promise<TransactionResponse<RelayerTxReceipt>>;
25
- wait(metaTxnId: string | SignedTransactions, timeout?: number, delay?: number, maxFails?: number): Promise<TransactionResponse<RelayerTxReceipt>>;
23
+ getFeeOptionsRaw(entrypoint: string, data: ethers.utils.BytesLike): Promise<{
24
+ options: FeeOption[];
25
+ quote?: FeeQuote;
26
+ }>;
27
+ gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<FeeOption[]>;
28
+ getNonce(address: string, space?: ethers.BigNumberish): Promise<ethers.BigNumberish>;
29
+ relay(signedTxs: commons.transaction.IntendedTransactionBundle, quote?: FeeQuote, waitForReceipt?: boolean): Promise<commons.transaction.TransactionResponse<RelayerTxReceipt>>;
30
+ wait(metaTxnId: string | commons.transaction.SignedTransactionBundle, timeout?: number, delay?: number, maxFails?: number): Promise<commons.transaction.TransactionResponse<RelayerTxReceipt>>;
26
31
  }
27
32
  export type RelayerTxReceipt = {
28
33
  blockHash: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xsequence/relayer",
3
- "version": "0.43.33",
3
+ "version": "1.0.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",
@@ -9,18 +9,18 @@
9
9
  "author": "Horizon Blockchain Games",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
- "@0xsequence/abi": "^0.43.33",
13
- "@0xsequence/config": "^0.43.33",
14
- "@0xsequence/network": "^0.43.33",
15
- "@0xsequence/transactions": "^0.43.33",
16
- "@0xsequence/utils": "^0.43.33"
12
+ "@0xsequence/abi": "1.0.0",
13
+ "@0xsequence/utils": "1.0.0",
14
+ "@0xsequence/core": "1.0.0"
17
15
  },
18
16
  "peerDependencies": {
19
17
  "ethers": ">=5.5 < 6"
20
18
  },
21
19
  "devDependencies": {
22
- "@0xsequence/wallet-contracts": "1.10.0",
23
- "ethers": "^5.7.2"
20
+ "@0xsequence/wallet-contracts": "^1.10.0",
21
+ "ethers": "^5.7.2",
22
+ "@0xsequence/signhub": "1.0.0",
23
+ "@0xsequence/tests": "1.0.0"
24
24
  },
25
25
  "files": [
26
26
  "src",
package/src/index.ts CHANGED
@@ -1,48 +1,52 @@
1
1
  import { ethers, providers } from 'ethers'
2
- import { SignedTransactions, Transaction, TransactionResponse } from '@0xsequence/transactions'
3
- import { WalletContext } from '@0xsequence/network'
4
- import { WalletConfig } from '@0xsequence/config'
5
2
  import { proto } from './rpc-relayer'
6
3
 
4
+ import { commons } from '@0xsequence/core'
5
+
7
6
  export interface Relayer {
8
7
  // simulate returns the execution results for a list of transactions.
9
- simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]>
8
+ simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise<SimulateResult[]>
10
9
 
11
10
  // getFeeOptions returns the fee options that the relayer will accept as payment.
12
11
  // If a quote is returned, it may be passed back to the relayer for dispatch.
13
12
  getFeeOptions(
14
- config: WalletConfig,
15
- context: WalletContext,
16
- ...transactions: Transaction[]
13
+ address: string,
14
+ ...transactions: commons.transaction.Transaction[]
17
15
  ): Promise<{ options: FeeOption[], quote?: FeeQuote }>
18
16
 
17
+ // getFeeOptionsRaw returns the fee options that the relayer will accept as payment.
18
+ // If a quote is returned, it may be passed back to the relayer for dispatch.
19
+ // It doesn't make any assumptions about the transaction format.
20
+ getFeeOptionsRaw(
21
+ entrypoint: string,
22
+ data: ethers.utils.BytesLike
23
+ ): Promise<{ options: FeeOption[]; quote?: FeeQuote }>
24
+
19
25
  // gasRefundOptions returns the transactions which can be included to refund a
20
26
  // relayer for submitting your transaction to a network.
21
27
  gasRefundOptions(
22
- config: WalletConfig,
23
- context: WalletContext,
24
- ...transactions: Transaction[]
28
+ address: string,
29
+ ...transactions: commons.transaction.Transaction[]
25
30
  ): Promise<FeeOption[]>
26
31
 
27
32
  // getNonce returns the transaction count/nonce for a wallet, encoded with nonce space.
28
33
  // If space is undefined, the relayer can choose a nonce space to encode the result with.
29
34
  // Otherwise, the relayer must return a nonce encoded for the given nonce space.
30
- getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish, blockTag?: providers.BlockTag): Promise<ethers.BigNumberish>
35
+ getNonce(address: string, space?: ethers.BigNumberish, blockTag?: providers.BlockTag): Promise<ethers.BigNumberish>
31
36
 
32
37
  // relayer will submit the transaction(s) to the network and return the transaction response.
33
38
  // The quote should be the one returned from getFeeOptions, if any.
34
39
  // waitForReceipt must default to true.
35
- relay(signedTxs: SignedTransactions, quote?: FeeQuote, waitForReceipt?: boolean): Promise<TransactionResponse>
40
+ relay(signedTxs: commons.transaction.IntendedTransactionBundle, quote?: FeeQuote, waitForReceipt?: boolean): Promise<commons.transaction.TransactionResponse>
36
41
 
37
42
  // wait for transaction confirmation
38
43
  // timeout is the maximum time to wait for the transaction response
39
44
  // delay is the polling interval, i.e. the time to wait between requests
40
45
  // maxFails is the maximum number of hard failures to tolerate before giving up
41
- wait(metaTxnId: string | SignedTransactions, timeout?: number, delay?: number, maxFails?: number): Promise<TransactionResponse>
46
+ wait(metaTxnId: string | commons.transaction.SignedTransactionBundle, timeout?: number, delay?: number, maxFails?: number): Promise<commons.transaction.TransactionResponse>
42
47
  }
43
48
 
44
49
  export * from './local-relayer'
45
- export * from './base-relayer'
46
50
  export * from './provider-relayer'
47
51
  export * from './rpc-relayer'
48
52
  export { proto as RpcRelayerProto } from './rpc-relayer'
@@ -1,11 +1,8 @@
1
- import { Signer as AbstractSigner, ethers, providers } from 'ethers'
2
- import { walletContracts } from '@0xsequence/abi'
3
- import { SignedTransactions, Transaction, sequenceTxAbiEncode, TransactionResponse } from '@0xsequence/transactions'
4
- import { WalletContext } from '@0xsequence/network'
5
- import { WalletConfig } from '@0xsequence/config'
1
+ import { Signer as AbstractSigner, providers, BytesLike } from 'ethers'
6
2
  import { logger } from '@0xsequence/utils'
7
3
  import { FeeOption, FeeQuote, Relayer } from '.'
8
4
  import { ProviderRelayer, ProviderRelayerOptions } from './provider-relayer'
5
+ import { commons } from '@0xsequence/core'
9
6
 
10
7
  export type LocalRelayerOptions = Omit<ProviderRelayerOptions, "provider"> & {
11
8
  signer: AbstractSigner
@@ -25,30 +22,22 @@ export class LocalRelayer extends ProviderRelayer implements Relayer {
25
22
  if (!this.signer.provider) throw new Error("Signer must have a provider")
26
23
  }
27
24
 
28
- async deployWallet(config: WalletConfig, context: WalletContext): Promise<TransactionResponse> {
29
- // NOTE: on hardhat some tests fail on HookCallerMock when not passing gasLimit directly as below,
30
- // and using eth_gasEstimate. Perhaps review HookCallerMock.sol and fix it to avoid what looks
31
- // like an infinite loop?
32
- const walletDeployTxn = this.prepareWalletDeploy(config, context)
33
-
34
- // NOTE: for hardhat to pass, we have to set the gasLimit directly, as its unable to estimate
35
- return this.signer.sendTransaction({ ...walletDeployTxn, gasLimit: ethers.constants.Two.pow(17) } )
36
- }
37
-
38
25
  async getFeeOptions(
39
- _config: WalletConfig,
40
- _context: WalletContext,
41
- ..._transactions: Transaction[]
26
+ _address: string,
27
+ ..._transactions: commons.transaction.Transaction[]
42
28
  ): Promise<{ options: FeeOption[] }> {
43
29
  return { options: [] }
44
30
  }
45
31
 
32
+ async getFeeOptionsRaw(_entrypoint: string, _data: BytesLike): Promise<{ options: FeeOption[] }> {
33
+ return { options: [] }
34
+ }
35
+
46
36
  async gasRefundOptions(
47
- config: WalletConfig,
48
- context: WalletContext,
49
- ...transactions: Transaction[]
37
+ address: string,
38
+ ...transactions:commons.transaction.Transaction[]
50
39
  ): Promise<FeeOption[]> {
51
- const { options } = await this.getFeeOptions(config, context, ...transactions)
40
+ const { options } = await this.getFeeOptions(address, ...transactions)
52
41
  return options
53
42
  }
54
43
 
@@ -56,33 +45,30 @@ export class LocalRelayer extends ProviderRelayer implements Relayer {
56
45
  this.txnOptions = transactionRequest
57
46
  }
58
47
 
59
- async relay(signedTxs: SignedTransactions, quote?: FeeQuote, waitForReceipt: boolean = true): Promise<TransactionResponse<providers.TransactionReceipt>> {
48
+ async relay(
49
+ signedTxs: commons.transaction.IntendedTransactionBundle,
50
+ quote?: FeeQuote, waitForReceipt: boolean = true
51
+ ): Promise<commons.transaction.TransactionResponse<providers.TransactionReceipt>> {
60
52
  if (quote !== undefined) {
61
53
  logger.warn(`LocalRelayer doesn't accept fee quotes`)
62
54
  }
63
-
64
- if (!signedTxs.context.guestModule || signedTxs.context.guestModule.length !== 42) {
65
- throw new Error('LocalRelayer requires the context.guestModule address')
66
- }
67
-
68
- const { to, execute } = await this.prependWalletDeploy(signedTxs)
69
-
70
- const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi)
71
- const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [
72
- sequenceTxAbiEncode(execute.transactions),
73
- execute.nonce,
74
- execute.signature
75
- ])
55
+
56
+ const data = commons.transaction.encodeBundleExecData(signedTxs)
76
57
 
77
58
  // TODO: think about computing gas limit individually, summing together and passing across
78
59
  // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation
79
60
  // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum.add(tx.gasLimit), ethers.BigNumber.from(0))
80
61
  // txRequest.gasLimit = gasLimit
81
62
 
82
- const responsePromise = this.signer.sendTransaction({ to, data, ...this.txnOptions })
63
+ const responsePromise = this.signer.sendTransaction({
64
+ to: signedTxs.entrypoint,
65
+ data,
66
+ ...this.txnOptions,
67
+ gasLimit: 9000000
68
+ })
83
69
 
84
70
  if (waitForReceipt) {
85
- const response: TransactionResponse = await responsePromise
71
+ const response: commons.transaction.TransactionResponse = await responsePromise
86
72
  response.receipt = await response.wait()
87
73
  return response
88
74
  } else {
@@ -1,22 +1,19 @@
1
1
  import { ethers, providers } from 'ethers'
2
2
  import { walletContracts } from '@0xsequence/abi'
3
- import { computeMetaTxnHash, encodeNonce, SignedTransactions, Transaction, TransactionResponse } from '@0xsequence/transactions'
4
- import { WalletContext } from '@0xsequence/network'
5
- import { WalletConfig, addressOf } from '@0xsequence/config'
6
- import { BaseRelayer, BaseRelayerOptions } from './base-relayer'
7
3
  import { FeeOption, FeeQuote, Relayer, SimulateResult } from '.'
8
- import { logger, Optionals, Mask } from '@0xsequence/utils'
4
+ import { logger, Optionals } from '@0xsequence/utils'
5
+ import { commons } from '@0xsequence/core'
9
6
 
10
7
  const DEFAULT_GAS_LIMIT = ethers.BigNumber.from(800000)
11
8
 
12
- export interface ProviderRelayerOptions extends BaseRelayerOptions {
9
+ export interface ProviderRelayerOptions {
13
10
  provider: providers.Provider,
14
11
  waitPollRate?: number,
15
12
  deltaBlocksLog?: number,
16
13
  fromBlockLog?: number
17
14
  }
18
15
 
19
- export const ProviderRelayerDefaults: Required<Optionals<Mask<ProviderRelayerOptions, BaseRelayerOptions>>> = {
16
+ export const ProviderRelayerDefaults: Required<Optionals<ProviderRelayerOptions>> = {
20
17
  waitPollRate: 1000,
21
18
  deltaBlocksLog: 12,
22
19
  fromBlockLog: -1024
@@ -26,36 +23,35 @@ export function isProviderRelayerOptions(obj: any): obj is ProviderRelayerOption
26
23
  return obj.provider !== undefined && providers.Provider.isProvider(obj.provider)
27
24
  }
28
25
 
29
- export abstract class ProviderRelayer extends BaseRelayer implements Relayer {
26
+ export abstract class ProviderRelayer implements Relayer {
30
27
  public provider: providers.Provider
31
28
  public waitPollRate: number
32
29
  public deltaBlocksLog: number
33
30
  public fromBlockLog: number
34
31
 
35
32
  constructor(options: ProviderRelayerOptions) {
36
- super(options)
37
33
  const opts = { ...ProviderRelayerDefaults, ...options }
38
34
  this.provider = opts.provider
39
- this.waitPollRate = opts.waitPollRate
40
- this.deltaBlocksLog = opts.deltaBlocksLog
41
- this.fromBlockLog = opts.fromBlockLog
42
35
  }
43
36
 
44
37
  abstract getFeeOptions(
45
- config: WalletConfig,
46
- context: WalletContext,
47
- ...transactions: Transaction[]
38
+ address: string,
39
+ ...transactions: commons.transaction.Transaction[]
40
+ ): Promise<{ options: FeeOption[], quote?: FeeQuote }>
41
+
42
+ abstract getFeeOptionsRaw(
43
+ entrypoint: string,
44
+ data: ethers.utils.BytesLike
48
45
  ): Promise<{ options: FeeOption[], quote?: FeeQuote }>
49
46
 
50
47
  abstract gasRefundOptions(
51
- config: WalletConfig,
52
- context: WalletContext,
53
- ...transactions: Transaction[]
48
+ address: string,
49
+ ...transactions: commons.transaction.Transaction[]
54
50
  ): Promise<FeeOption[]>
55
51
 
56
- abstract relay(signedTxs: SignedTransactions, quote?: FeeQuote, waitForReceipt?: boolean): Promise<TransactionResponse>
52
+ abstract relay(signedTxs: commons.transaction.IntendedTransactionBundle, quote?: FeeQuote, waitForReceipt?: boolean): Promise<commons.transaction.TransactionResponse>
57
53
 
58
- async simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]> {
54
+ async simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise<SimulateResult[]> {
59
55
  return (await Promise.all(transactions.map(async tx => {
60
56
  // Respect gasLimit request of the transaction (as long as its not 0)
61
57
  if (tx.gasLimit && !ethers.BigNumber.from(tx.gasLimit || 0).eq(ethers.constants.Zero)) {
@@ -68,7 +64,7 @@ export abstract class ProviderRelayer extends BaseRelayer implements Relayer {
68
64
  }
69
65
 
70
66
  // Fee can't be estimated for self-called if wallet hasn't been deployed
71
- if (tx.to === wallet && !(await this.isWalletDeployed(wallet))) {
67
+ if (tx.to === wallet && await this.provider.getCode(wallet).then((code) => ethers.utils.arrayify(code).length === 0)) {
72
68
  return DEFAULT_GAS_LIMIT
73
69
  }
74
70
 
@@ -93,8 +89,7 @@ export abstract class ProviderRelayer extends BaseRelayer implements Relayer {
93
89
  }
94
90
 
95
91
  async getNonce(
96
- config: WalletConfig,
97
- context: WalletContext,
92
+ address: string,
98
93
  space?: ethers.BigNumberish,
99
94
  blockTag?: providers.BlockTag
100
95
  ): Promise<ethers.BigNumberish> {
@@ -102,9 +97,7 @@ export abstract class ProviderRelayer extends BaseRelayer implements Relayer {
102
97
  throw new Error('provider is not set')
103
98
  }
104
99
 
105
- const addr = addressOf(config, context)
106
-
107
- if ((await this.provider.getCode(addr)) === '0x') {
100
+ if ((await this.provider.getCode(address)) === '0x') {
108
101
  return 0
109
102
  }
110
103
 
@@ -112,21 +105,19 @@ export abstract class ProviderRelayer extends BaseRelayer implements Relayer {
112
105
  space = 0
113
106
  }
114
107
 
115
- const module = new ethers.Contract(addr, walletContracts.mainModule.abi, this.provider)
108
+ const module = new ethers.Contract(address, walletContracts.mainModule.abi, this.provider)
116
109
  const nonce = await module.readNonce(space, { blockTag: blockTag })
117
- return encodeNonce(space, nonce)
110
+ return commons.transaction.encodeNonce(space, nonce)
118
111
  }
119
112
 
120
113
  async wait(
121
- metaTxnId: string | SignedTransactions,
114
+ metaTxnId: string | commons.transaction.SignedTransactionBundle,
122
115
  timeout?: number,
123
116
  delay: number = this.waitPollRate,
124
117
  maxFails: number = 5
125
118
  ): Promise<providers.TransactionResponse & { receipt: providers.TransactionReceipt }> {
126
119
  if (typeof metaTxnId !== 'string') {
127
- logger.info('computing id', metaTxnId.config, metaTxnId.context, metaTxnId.chainId, ...metaTxnId.transactions)
128
-
129
- metaTxnId = computeMetaTxnHash(addressOf(metaTxnId.config, metaTxnId.context), metaTxnId.chainId, ...metaTxnId.transactions)
120
+ metaTxnId = commons.transaction.intendedTransactionID(metaTxnId)
130
121
  }
131
122
 
132
123
  let timedOut = false
@@ -1,22 +1,8 @@
1
1
  import { ethers } from 'ethers'
2
- import { walletContracts } from '@0xsequence/abi'
3
- import {
4
- Transaction,
5
- readSequenceNonce,
6
- appendNonce,
7
- MetaTransactionsType,
8
- sequenceTxAbiEncode,
9
- SignedTransactions,
10
- computeMetaTxnHash,
11
- decodeNonce,
12
- TransactionResponse
13
- } from '@0xsequence/transactions'
14
- import { BaseRelayer, BaseRelayerOptions } from '../base-relayer'
15
2
  import { FeeOption, FeeQuote, Relayer, SimulateResult } from '..'
16
- import { WalletContext } from '@0xsequence/network'
17
- import { WalletConfig, addressOf, buildStubSignature } from '@0xsequence/config'
18
- import { logger } from '@0xsequence/utils'
19
3
  import * as proto from './relayer.gen'
4
+ import { commons } from '@0xsequence/core'
5
+ import { getDefaultConnectionInfo, logger } from '@0xsequence/utils'
20
6
 
21
7
  export { proto }
22
8
 
@@ -29,34 +15,41 @@ const FINAL_STATUSES = [
29
15
 
30
16
  const FAILED_STATUSES = [proto.ETHTxnStatus.DROPPED, proto.ETHTxnStatus.PARTIALLY_FAILED, proto.ETHTxnStatus.FAILED]
31
17
 
32
- export interface RpcRelayerOptions extends BaseRelayerOptions {
18
+ export interface RpcRelayerOptions {
19
+ provider: ethers.providers.Provider | { url: string }
33
20
  url: string
34
21
  }
35
22
 
36
23
  export function isRpcRelayerOptions(obj: any): obj is RpcRelayerOptions {
37
- return obj.url !== undefined && typeof obj.url === 'string'
24
+ return (
25
+ obj.url !== undefined &&
26
+ typeof obj.url === 'string' &&
27
+ obj.provider !== undefined &&
28
+ ethers.providers.Provider.isProvider(obj.provider)
29
+ )
38
30
  }
39
31
 
40
32
  const fetch = typeof global === 'object' ? global.fetch : window.fetch
41
33
 
42
- export class RpcRelayer extends BaseRelayer implements Relayer {
34
+ export class RpcRelayer implements Relayer {
43
35
  private readonly service: proto.Relayer
36
+ public readonly provider: ethers.providers.Provider
44
37
 
45
38
  constructor(options: RpcRelayerOptions) {
46
- super(options)
47
39
  this.service = new proto.Relayer(options.url, fetch)
40
+ this.provider = ethers.providers.Provider.isProvider(options.provider)
41
+ ? options.provider
42
+ : new ethers.providers.StaticJsonRpcProvider(getDefaultConnectionInfo(options.provider.url))
48
43
  }
49
44
 
50
45
  async waitReceipt(
51
- metaTxnId: string | SignedTransactions,
46
+ metaTxnId: string | commons.transaction.SignedTransactionBundle,
52
47
  delay: number = 1000,
53
48
  maxFails: number = 5,
54
49
  isCancelled?: () => boolean
55
50
  ): Promise<proto.GetMetaTxnReceiptReturn> {
56
51
  if (typeof metaTxnId !== 'string') {
57
- logger.info('computing id', metaTxnId.config, metaTxnId.context, metaTxnId.chainId, ...metaTxnId.transactions)
58
-
59
- metaTxnId = computeMetaTxnHash(addressOf(metaTxnId.config, metaTxnId.context), metaTxnId.chainId, ...metaTxnId.transactions)
52
+ metaTxnId = commons.transaction.intendedTransactionID(metaTxnId)
60
53
  }
61
54
 
62
55
  logger.info(`[rpc-relayer/waitReceipt] waiting for ${metaTxnId}`)
@@ -91,16 +84,18 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
91
84
  throw new Error(`Cancelled waiting for transaction receipt ${metaTxnId}`)
92
85
  }
93
86
 
94
- async simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]> {
87
+ async simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise<SimulateResult[]> {
95
88
  const coder = ethers.utils.defaultAbiCoder
96
- const encoded = coder.encode([MetaTransactionsType], [sequenceTxAbiEncode(transactions)])
89
+ const encoded = coder.encode(
90
+ [commons.transaction.MetaTransactionsType],
91
+ [commons.transaction.sequenceTxAbiEncode(transactions)]
92
+ )
97
93
  return (await this.service.simulate({ wallet, transactions: encoded })).results
98
94
  }
99
95
 
100
96
  async getFeeOptions(
101
- config: WalletConfig,
102
- context: WalletContext,
103
- ...transactions: Transaction[]
97
+ address: string,
98
+ ...transactions: commons.transaction.Transaction[]
104
99
  ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> {
105
100
  // NOTE/TODO: for a given `service` the feeTokens will not change between execution, so we should memoize this value
106
101
  // for a short-period of time, perhaps for 1 day or in memory. Perhaps one day we can make this happen automatically
@@ -111,35 +106,23 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
111
106
  const symbols = feeTokens.tokens.map(token => token.symbol).join(', ')
112
107
  logger.info(`[rpc-relayer/getFeeOptions] relayer fees are required, accepted tokens are ${symbols}`)
113
108
 
114
- const wallet = addressOf(config, context)
115
-
116
- let nonce = readSequenceNonce(...transactions)
117
- if (nonce === undefined) {
118
- nonce = await this.getNonce(config, context)
119
- }
109
+ const nonce = await this.getNonce(address)
120
110
 
121
111
  if (!this.provider) {
122
112
  logger.warn(`[rpc-relayer/getFeeOptions] provider not set, needed for stub signature`)
123
113
  throw new Error('provider is not set')
124
114
  }
125
115
 
126
- const { to, execute } = await this.prependWalletDeploy({
127
- config,
128
- context,
129
- transactions,
130
- nonce,
131
- signature: buildStubSignature(this.provider, config)
116
+ const { options, quote } = await this.service.feeOptions({
117
+ wallet: address,
118
+ to: address,
119
+ data: commons.transaction.encodeBundleExecData({
120
+ entrypoint: address,
121
+ transactions,
122
+ nonce
123
+ })
132
124
  })
133
125
 
134
- const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi)
135
- const data = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [
136
- sequenceTxAbiEncode(execute.transactions),
137
- execute.nonce,
138
- execute.signature
139
- ])
140
-
141
- const { options, quote } = await this.service.feeOptions({ wallet, to, data })
142
-
143
126
  logger.info(`[rpc-relayer/getFeeOptions] got refund options ${JSON.stringify(options)}`)
144
127
  return { options, quote: { _tag: 'FeeQuote', _quote: quote } }
145
128
  } else {
@@ -148,27 +131,36 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
148
131
  }
149
132
  }
150
133
 
151
- async gasRefundOptions(config: WalletConfig, context: WalletContext, ...transactions: Transaction[]): Promise<FeeOption[]> {
152
- const { options } = await this.getFeeOptions(config, context, ...transactions)
134
+ async getFeeOptionsRaw(entrypoint: string, data: ethers.utils.BytesLike): Promise<{ options: FeeOption[]; quote?: FeeQuote }> {
135
+ const { options, quote } = await this.service.feeOptions({
136
+ wallet: entrypoint,
137
+ to: entrypoint,
138
+ data: ethers.utils.hexlify(data)
139
+ })
140
+
141
+ return { options, quote: { _tag: 'FeeQuote', _quote: quote } }
142
+ }
143
+
144
+ async gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<FeeOption[]> {
145
+ const { options } = await this.getFeeOptions(address, ...transactions)
153
146
  return options
154
147
  }
155
148
 
156
- async getNonce(config: WalletConfig, context: WalletContext, space?: ethers.BigNumberish): Promise<ethers.BigNumberish> {
157
- const addr = addressOf(config, context)
158
- logger.info(`[rpc-relayer/getNonce] get nonce for wallet ${addr} space: ${space}`)
149
+ async getNonce(address: string, space?: ethers.BigNumberish): Promise<ethers.BigNumberish> {
150
+ logger.info(`[rpc-relayer/getNonce] get nonce for wallet ${address} space: ${space}`)
159
151
  const encodedNonce = space !== undefined ? ethers.BigNumber.from(space).toHexString() : undefined
160
- const resp = await this.service.getMetaTxnNonce({ walletContractAddress: addr, space: encodedNonce })
152
+ const resp = await this.service.getMetaTxnNonce({ walletContractAddress: address, space: encodedNonce })
161
153
  const nonce = ethers.BigNumber.from(resp.nonce)
162
- const [decodedSpace, decodedNonce] = decodeNonce(nonce)
163
- logger.info(`[rpc-relayer/getNonce] got next nonce for wallet ${addr} ${decodedNonce} space: ${decodedSpace}`)
154
+ const [decodedSpace, decodedNonce] = commons.transaction.decodeNonce(nonce)
155
+ logger.info(`[rpc-relayer/getNonce] got next nonce for wallet ${address} ${decodedNonce} space: ${decodedSpace}`)
164
156
  return nonce
165
157
  }
166
158
 
167
159
  async relay(
168
- signedTxs: SignedTransactions,
160
+ signedTxs: commons.transaction.IntendedTransactionBundle,
169
161
  quote?: FeeQuote,
170
162
  waitForReceipt: boolean = true
171
- ): Promise<TransactionResponse<RelayerTxReceipt>> {
163
+ ): Promise<commons.transaction.TransactionResponse<RelayerTxReceipt>> {
172
164
  logger.info(
173
165
  `[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)} with quote ${JSON.stringify(quote)}`
174
166
  )
@@ -187,27 +179,25 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
187
179
  throw new Error('provider is not set')
188
180
  }
189
181
 
190
- const { to: contract, execute } = await this.prependWalletDeploy(signedTxs)
191
-
192
- const walletAddress = addressOf(signedTxs.config, signedTxs.context)
193
- const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi)
194
- const input = walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [
195
- sequenceTxAbiEncode(execute.transactions),
196
- execute.nonce,
197
- execute.signature
198
- ])
199
-
200
- const metaTxn = await this.service.sendMetaTxn({ call: { walletAddress, contract, input }, quote: typecheckedQuote })
182
+ const data = commons.transaction.encodeBundleExecData(signedTxs)
183
+ const metaTxn = await this.service.sendMetaTxn({
184
+ call: {
185
+ walletAddress: signedTxs.intent.wallet,
186
+ contract: signedTxs.entrypoint,
187
+ input: data
188
+ },
189
+ quote: typecheckedQuote
190
+ })
201
191
 
202
192
  logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`)
203
193
 
204
194
  if (waitForReceipt) {
205
- return this.wait(metaTxn.txnHash)
195
+ return this.wait(signedTxs.intent.id)
206
196
  } else {
207
197
  const response = {
208
- hash: metaTxn.txnHash,
198
+ hash: signedTxs.intent.id,
209
199
  confirmations: 0,
210
- from: walletAddress,
200
+ from: signedTxs.intent.wallet,
211
201
  wait: (_confirmations?: number): Promise<ethers.providers.TransactionReceipt> => Promise.reject(new Error('impossible'))
212
202
  }
213
203
 
@@ -216,7 +206,7 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
216
206
  throw new Error('cannot wait for receipt, relayer has no provider set')
217
207
  }
218
208
 
219
- const waitResponse = await this.wait(metaTxn.txnHash)
209
+ const waitResponse = await this.wait(signedTxs.intent.id)
220
210
  const transactionHash = waitResponse.receipt?.transactionHash
221
211
 
222
212
  if (!transactionHash) {
@@ -230,16 +220,16 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
230
220
 
231
221
  response.wait = wait
232
222
 
233
- return response as TransactionResponse
223
+ return response as commons.transaction.TransactionResponse
234
224
  }
235
225
  }
236
226
 
237
227
  async wait(
238
- metaTxnId: string | SignedTransactions,
228
+ metaTxnId: string | commons.transaction.SignedTransactionBundle,
239
229
  timeout?: number,
240
230
  delay: number = 1000,
241
231
  maxFails: number = 5
242
- ): Promise<TransactionResponse<RelayerTxReceipt>> {
232
+ ): Promise<commons.transaction.TransactionResponse<RelayerTxReceipt>> {
243
233
  let timedOut = false
244
234
 
245
235
  const { receipt } = await (timeout !== undefined
@@ -264,12 +254,12 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
264
254
  blockHash: txReceipt.blockHash,
265
255
  blockNumber: ethers.BigNumber.from(txReceipt.blockNumber).toNumber(),
266
256
  confirmations: 1,
267
- from: typeof metaTxnId === 'string' ? undefined : addressOf(metaTxnId.config, metaTxnId.context),
257
+ from: typeof metaTxnId === 'string' ? undefined : metaTxnId.intent.wallet,
268
258
  hash: txReceipt.transactionHash,
269
259
  raw: receipt.txnReceipt,
270
260
  receipt: txReceipt, // extended type which is Sequence-specific. Contains the decoded metaTxReceipt
271
261
  wait: async (confirmations?: number) => this.provider!.waitForTransaction(txReceipt.transactionHash, confirmations)
272
- } as TransactionResponse
262
+ } as commons.transaction.TransactionResponse
273
263
  }
274
264
  }
275
265