@0xsequence/relayer 2.3.35 → 3.0.0-beta.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.
Files changed (84) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/CHANGELOG.md +3862 -0
  3. package/LICENSE +0 -17
  4. package/README.md +1 -2
  5. package/dist/index.d.ts +4 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +3 -0
  8. package/dist/preconditions/codec.d.ts +12 -0
  9. package/dist/preconditions/codec.d.ts.map +1 -0
  10. package/dist/preconditions/codec.js +125 -0
  11. package/dist/preconditions/index.d.ts +4 -0
  12. package/dist/preconditions/index.d.ts.map +1 -0
  13. package/dist/preconditions/index.js +3 -0
  14. package/dist/preconditions/selectors.d.ts +7 -0
  15. package/dist/preconditions/selectors.d.ts.map +1 -0
  16. package/dist/preconditions/selectors.js +27 -0
  17. package/dist/preconditions/types.d.ts +70 -0
  18. package/dist/preconditions/types.d.ts.map +1 -0
  19. package/dist/preconditions/types.js +203 -0
  20. package/dist/relayer/index.d.ts +45 -0
  21. package/dist/relayer/index.d.ts.map +1 -0
  22. package/dist/relayer/index.js +3 -0
  23. package/dist/relayer/relayer.d.ts +26 -0
  24. package/dist/relayer/relayer.d.ts.map +1 -0
  25. package/dist/relayer/relayer.js +7 -0
  26. package/dist/relayer/rpc-relayer/index.d.ts +38 -0
  27. package/dist/relayer/rpc-relayer/index.d.ts.map +1 -0
  28. package/dist/relayer/rpc-relayer/index.js +375 -0
  29. package/dist/{declarations/src → relayer}/rpc-relayer/relayer.gen.d.ts +218 -178
  30. package/dist/relayer/rpc-relayer/relayer.gen.d.ts.map +1 -0
  31. package/dist/relayer/rpc-relayer/relayer.gen.js +1246 -0
  32. package/dist/relayer/standard/abi.d.ts +73 -0
  33. package/dist/relayer/standard/abi.d.ts.map +1 -0
  34. package/dist/relayer/standard/abi.js +10 -0
  35. package/dist/relayer/standard/eip6963.d.ts +31 -0
  36. package/dist/relayer/standard/eip6963.d.ts.map +1 -0
  37. package/dist/relayer/standard/eip6963.js +51 -0
  38. package/dist/relayer/standard/index.d.ts +5 -0
  39. package/dist/relayer/standard/index.d.ts.map +1 -0
  40. package/dist/relayer/standard/index.js +4 -0
  41. package/dist/relayer/standard/local.d.ts +60 -0
  42. package/dist/relayer/standard/local.d.ts.map +1 -0
  43. package/dist/relayer/standard/local.js +285 -0
  44. package/dist/relayer/standard/pk-relayer.d.ts +28 -0
  45. package/dist/relayer/standard/pk-relayer.d.ts.map +1 -0
  46. package/dist/relayer/standard/pk-relayer.js +112 -0
  47. package/dist/relayer/standard/sequence.d.ts +27 -0
  48. package/dist/relayer/standard/sequence.d.ts.map +1 -0
  49. package/dist/relayer/standard/sequence.js +84 -0
  50. package/package.json +28 -25
  51. package/src/index.ts +3 -111
  52. package/src/preconditions/codec.ts +190 -0
  53. package/src/preconditions/index.ts +3 -0
  54. package/src/preconditions/selectors.ts +38 -0
  55. package/src/preconditions/types.ts +201 -0
  56. package/src/relayer/index.ts +60 -0
  57. package/src/relayer/relayer.ts +37 -0
  58. package/src/relayer/rpc-relayer/index.ts +449 -0
  59. package/src/relayer/rpc-relayer/relayer.gen.ts +2268 -0
  60. package/src/relayer/standard/abi.ts +13 -0
  61. package/src/relayer/standard/eip6963.ts +74 -0
  62. package/src/relayer/standard/index.ts +4 -0
  63. package/src/relayer/standard/local.ts +353 -0
  64. package/src/relayer/standard/pk-relayer.ts +138 -0
  65. package/src/relayer/standard/sequence.ts +110 -0
  66. package/test/preconditions/codec.test.ts +531 -0
  67. package/test/preconditions/preconditions.test.ts +283 -0
  68. package/test/preconditions/selectors.test.ts +415 -0
  69. package/test/preconditions/types.test.ts +443 -0
  70. package/test/relayer/relayer.test.ts +355 -0
  71. package/tsconfig.json +10 -0
  72. package/dist/0xsequence-relayer.cjs.d.ts +0 -2
  73. package/dist/0xsequence-relayer.cjs.dev.js +0 -1626
  74. package/dist/0xsequence-relayer.cjs.js +0 -7
  75. package/dist/0xsequence-relayer.cjs.prod.js +0 -1626
  76. package/dist/0xsequence-relayer.esm.js +0 -1613
  77. package/dist/declarations/src/index.d.ts +0 -42
  78. package/dist/declarations/src/local-relayer.d.ts +0 -35
  79. package/dist/declarations/src/provider-relayer.d.ts +0 -47
  80. package/dist/declarations/src/rpc-relayer/index.d.ts +0 -72
  81. package/src/local-relayer.ts +0 -125
  82. package/src/provider-relayer.ts +0 -284
  83. package/src/rpc-relayer/index.ts +0 -380
  84. package/src/rpc-relayer/relayer.gen.ts +0 -1900
@@ -1,42 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import { proto } from "./rpc-relayer/index.js";
3
- import { commons } from '@0xsequence/core';
4
- export interface Relayer {
5
- simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise<SimulateResult[]>;
6
- getFeeOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<{
7
- options: FeeOption[];
8
- quote?: FeeQuote;
9
- }>;
10
- getFeeOptionsRaw(entrypoint: string, data: ethers.BytesLike, options?: {
11
- simulate?: boolean;
12
- }): Promise<{
13
- options: FeeOption[];
14
- quote?: FeeQuote;
15
- }>;
16
- gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<FeeOption[]>;
17
- listGasSponsors(args: proto.ListGasSponsorsArgs): Promise<proto.ListGasSponsorsReturn>;
18
- addGasSponsor(args: proto.AddGasSponsorArgs): Promise<proto.AddGasSponsorReturn>;
19
- updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise<proto.UpdateGasSponsorReturn>;
20
- removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise<proto.RemoveGasSponsorReturn>;
21
- getNonce(address: string, space?: ethers.BigNumberish, blockTag?: ethers.BlockTag): Promise<ethers.BigNumberish>;
22
- relay(signedTxs: commons.transaction.IntendedTransactionBundle, quote?: FeeQuote, waitForReceipt?: boolean, projectAccessKey?: string): Promise<commons.transaction.TransactionResponse>;
23
- wait(metaTxnId: string | commons.transaction.SignedTransactionBundle, timeout?: number, delay?: number, maxFails?: number): Promise<commons.transaction.TransactionResponse>;
24
- getMetaTransactions(projectId: number, page?: proto.Page): Promise<{
25
- page: proto.Page;
26
- transactions: proto.MetaTxnLog[];
27
- }>;
28
- getTransactionCost(projectId: number, from: string, to: string): Promise<{
29
- cost: number;
30
- }>;
31
- }
32
- export * from "./local-relayer.js";
33
- export * from "./provider-relayer.js";
34
- export * from "./rpc-relayer/index.js";
35
- export { proto as RpcRelayerProto } from "./rpc-relayer/index.js";
36
- export type SimulateResult = proto.SimulateResult;
37
- export type FeeOption = proto.FeeOption;
38
- export interface FeeQuote {
39
- _tag: 'FeeQuote';
40
- _quote: unknown;
41
- }
42
- export declare function isRelayer(cand: any): cand is Relayer;
@@ -1,35 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import { FeeOption, FeeQuote, proto, Relayer } from "./index.js";
3
- import { ProviderRelayer, ProviderRelayerOptions } from "./provider-relayer.js";
4
- import { commons } from '@0xsequence/core';
5
- export type LocalRelayerOptions = Omit<ProviderRelayerOptions, 'provider'> & {
6
- signer: ethers.Signer;
7
- };
8
- export declare function isLocalRelayerOptions(obj: any): obj is LocalRelayerOptions;
9
- export declare class LocalRelayer extends ProviderRelayer implements Relayer {
10
- private signer;
11
- private txnOptions;
12
- constructor(options: LocalRelayerOptions | ethers.AbstractSigner);
13
- getFeeOptions(_address: string, ..._transactions: commons.transaction.Transaction[]): Promise<{
14
- options: FeeOption[];
15
- }>;
16
- getFeeOptionsRaw(_entrypoint: string, _data: ethers.BytesLike, _options?: {
17
- simulate?: boolean;
18
- }): Promise<{
19
- options: FeeOption[];
20
- }>;
21
- gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<FeeOption[]>;
22
- setTransactionOptions(transactionRequest: ethers.TransactionRequest): void;
23
- relay(signedTxs: commons.transaction.IntendedTransactionBundle, quote?: FeeQuote, waitForReceipt?: boolean): Promise<commons.transaction.TransactionResponse<ethers.TransactionReceipt>>;
24
- getMetaTransactions(projectId: number, page?: proto.Page): Promise<{
25
- page: proto.Page;
26
- transactions: proto.MetaTxnLog[];
27
- }>;
28
- getTransactionCost(projectId: number, from: string, to: string): Promise<{
29
- cost: number;
30
- }>;
31
- listGasSponsors(args: proto.ListGasSponsorsArgs): Promise<proto.ListGasSponsorsReturn>;
32
- addGasSponsor(args: proto.AddGasSponsorArgs): Promise<proto.AddGasSponsorReturn>;
33
- updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise<proto.UpdateGasSponsorReturn>;
34
- removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise<proto.RemoveGasSponsorReturn>;
35
- }
@@ -1,47 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import { FeeOption, FeeQuote, proto, Relayer, SimulateResult } from "./index.js";
3
- import { Optionals } from '@0xsequence/utils';
4
- import { commons } from '@0xsequence/core';
5
- export interface ProviderRelayerOptions {
6
- provider: ethers.Provider;
7
- waitPollRate?: number;
8
- deltaBlocksLog?: number;
9
- fromBlockLog?: number;
10
- }
11
- export declare const ProviderRelayerDefaults: Required<Optionals<ProviderRelayerOptions>>;
12
- export declare function isProviderRelayerOptions(obj: any): obj is ProviderRelayerOptions;
13
- export declare abstract class ProviderRelayer implements Relayer {
14
- provider: ethers.Provider;
15
- waitPollRate: number;
16
- deltaBlocksLog: number;
17
- fromBlockLog: number;
18
- constructor(options: ProviderRelayerOptions);
19
- abstract getFeeOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<{
20
- options: FeeOption[];
21
- quote?: FeeQuote;
22
- }>;
23
- abstract getFeeOptionsRaw(entrypoint: string, data: ethers.BytesLike, options?: {
24
- simulate?: boolean;
25
- }): Promise<{
26
- options: FeeOption[];
27
- quote?: FeeQuote;
28
- }>;
29
- abstract gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<FeeOption[]>;
30
- abstract relay(signedTxs: commons.transaction.IntendedTransactionBundle, quote?: FeeQuote, waitForReceipt?: boolean): Promise<commons.transaction.TransactionResponse>;
31
- abstract getTransactionCost(projectId: number, from: string, to: string): Promise<{
32
- cost: number;
33
- }>;
34
- abstract getMetaTransactions(projectId: number, page?: proto.Page): Promise<{
35
- page: proto.Page;
36
- transactions: proto.MetaTxnLog[];
37
- }>;
38
- abstract listGasSponsors(args: proto.ListGasSponsorsArgs): Promise<proto.ListGasSponsorsReturn>;
39
- abstract addGasSponsor(args: proto.AddGasSponsorArgs): Promise<proto.AddGasSponsorReturn>;
40
- abstract updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise<proto.UpdateGasSponsorReturn>;
41
- abstract removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise<proto.RemoveGasSponsorReturn>;
42
- simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise<SimulateResult[]>;
43
- getNonce(address: string, space?: ethers.BigNumberish, blockTag?: ethers.BlockTag): Promise<ethers.BigNumberish>;
44
- wait(metaTxnId: string | commons.transaction.SignedTransactionBundle, timeoutDuration?: number, delay?: number, maxFails?: number): Promise<ethers.TransactionResponse & {
45
- receipt: ethers.TransactionReceipt;
46
- }>;
47
- }
@@ -1,72 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import { FeeOption, FeeQuote, Relayer, SimulateResult } from "../index.js";
3
- import * as proto from "./relayer.gen.js";
4
- import { commons } from '@0xsequence/core';
5
- export { proto };
6
- export interface RpcRelayerOptions {
7
- provider: ethers.AbstractProvider | {
8
- url: string;
9
- };
10
- url: string;
11
- projectAccessKey?: string;
12
- jwtAuth?: string;
13
- }
14
- export declare function isRpcRelayerOptions(obj: any): obj is RpcRelayerOptions;
15
- export declare class RpcRelayer implements Relayer {
16
- options: RpcRelayerOptions;
17
- private readonly service;
18
- readonly provider: ethers.Provider;
19
- constructor(options: RpcRelayerOptions);
20
- _fetch: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
21
- waitReceipt(metaTxnId: string | commons.transaction.SignedTransactionBundle, delay?: number, maxFails?: number, isCancelled?: () => boolean): Promise<proto.GetMetaTxnReceiptReturn>;
22
- simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise<SimulateResult[]>;
23
- getFeeOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<{
24
- options: FeeOption[];
25
- quote?: FeeQuote;
26
- }>;
27
- getFeeOptionsRaw(entrypoint: string, data: ethers.BytesLike, options?: {
28
- simulate?: boolean;
29
- projectAccessKey?: string;
30
- }): Promise<{
31
- options: FeeOption[];
32
- quote?: FeeQuote;
33
- }>;
34
- gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<FeeOption[]>;
35
- getNonce(address: string, space?: ethers.BigNumberish): Promise<ethers.BigNumberish>;
36
- relay(signedTxs: commons.transaction.IntendedTransactionBundle, quote?: FeeQuote, waitForReceipt?: boolean, projectAccessKey?: string): Promise<commons.transaction.TransactionResponse<RelayerTxReceipt>>;
37
- wait(metaTxnId: string | commons.transaction.SignedTransactionBundle, timeout?: number, delay?: number, maxFails?: number): Promise<commons.transaction.TransactionResponse<RelayerTxReceipt>>;
38
- getMetaTransactions(projectId: number, page?: proto.Page): Promise<{
39
- page: proto.Page;
40
- transactions: proto.MetaTxnLog[];
41
- }>;
42
- getTransactionCost(projectId: number, from: string, to: string): Promise<{
43
- cost: number;
44
- }>;
45
- listGasSponsors(args: proto.ListGasSponsorsArgs): Promise<proto.ListGasSponsorsReturn>;
46
- addGasSponsor(args: proto.AddGasSponsorArgs): Promise<proto.AddGasSponsorReturn>;
47
- updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise<proto.UpdateGasSponsorReturn>;
48
- removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise<proto.RemoveGasSponsorReturn>;
49
- }
50
- export type RelayerTxReceipt = {
51
- blockHash: string;
52
- blockNumber: string;
53
- contractAddress: string;
54
- cumulativeGasUsed: string;
55
- gasUsed: string;
56
- logs: {
57
- address: string;
58
- blockHash: string;
59
- blockNumber: string;
60
- data: string;
61
- logIndex: string;
62
- removed: boolean;
63
- topics: string[];
64
- transactionHash: string;
65
- transactionIndex: string;
66
- }[];
67
- logsBloom: string;
68
- root: string;
69
- status: string;
70
- transactionHash: string;
71
- transactionIndex: string;
72
- };
@@ -1,125 +0,0 @@
1
- import { ethers } from 'ethers'
2
- import { logger } from '@0xsequence/utils'
3
- import { FeeOption, FeeQuote, proto, Relayer } from '.'
4
- import { ProviderRelayer, ProviderRelayerOptions } from './provider-relayer'
5
- import { commons } from '@0xsequence/core'
6
-
7
- export type LocalRelayerOptions = Omit<ProviderRelayerOptions, 'provider'> & {
8
- signer: ethers.Signer
9
- }
10
-
11
- export function isLocalRelayerOptions(obj: any): obj is LocalRelayerOptions {
12
- return typeof obj === 'object' && isAbstractSigner(obj.signer)
13
- }
14
-
15
- export class LocalRelayer extends ProviderRelayer implements Relayer {
16
- private signer: ethers.Signer
17
- private txnOptions: ethers.TransactionRequest
18
-
19
- constructor(options: LocalRelayerOptions | ethers.AbstractSigner) {
20
- super(isAbstractSigner(options) ? { provider: options.provider! } : { ...options, provider: options.signer.provider! })
21
- this.signer = isAbstractSigner(options) ? options : options.signer
22
- if (!this.signer.provider) throw new Error('Signer must have a provider')
23
- }
24
-
25
- async getFeeOptions(_address: string, ..._transactions: commons.transaction.Transaction[]): Promise<{ options: FeeOption[] }> {
26
- return { options: [] }
27
- }
28
-
29
- async getFeeOptionsRaw(
30
- _entrypoint: string,
31
- _data: ethers.BytesLike,
32
- _options?: {
33
- simulate?: boolean
34
- }
35
- ): Promise<{ options: FeeOption[] }> {
36
- return { options: [] }
37
- }
38
-
39
- async gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<FeeOption[]> {
40
- const { options } = await this.getFeeOptions(address, ...transactions)
41
- return options
42
- }
43
-
44
- setTransactionOptions(transactionRequest: ethers.TransactionRequest) {
45
- this.txnOptions = transactionRequest
46
- }
47
-
48
- async relay(
49
- signedTxs: commons.transaction.IntendedTransactionBundle,
50
- quote?: FeeQuote,
51
- waitForReceipt: boolean = true
52
- ): Promise<commons.transaction.TransactionResponse<ethers.TransactionReceipt>> {
53
- if (quote !== undefined) {
54
- logger.warn(`LocalRelayer doesn't accept fee quotes`)
55
- }
56
-
57
- const data = commons.transaction.encodeBundleExecData(signedTxs)
58
-
59
- // TODO: think about computing gas limit individually, summing together and passing across
60
- // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation
61
- // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum + tx.gasLimit, 0n)
62
- // txRequest.gasLimit = gasLimit
63
-
64
- const responsePromise = this.signer.sendTransaction({
65
- to: signedTxs.entrypoint,
66
- data,
67
- ...this.txnOptions,
68
- gasLimit: 9000000
69
- })
70
-
71
- if (waitForReceipt) {
72
- const response: commons.transaction.TransactionResponse = await responsePromise
73
- response.receipt = await response.wait()
74
- return response
75
- } else {
76
- return responsePromise
77
- }
78
- }
79
-
80
- async getMetaTransactions(
81
- projectId: number,
82
- page?: proto.Page
83
- ): Promise<{
84
- page: proto.Page
85
- transactions: proto.MetaTxnLog[]
86
- }> {
87
- return { page: { page: 0, pageSize: 100 }, transactions: [] }
88
- }
89
-
90
- async getTransactionCost(
91
- projectId: number,
92
- from: string,
93
- to: string
94
- ): Promise<{
95
- cost: number
96
- }> {
97
- return { cost: 0 }
98
- }
99
-
100
- async listGasSponsors(args: proto.ListGasSponsorsArgs): Promise<proto.ListGasSponsorsReturn> {
101
- return { page: { page: 0, pageSize: 100 }, gasSponsors: [] }
102
- }
103
-
104
- async addGasSponsor(args: proto.AddGasSponsorArgs): Promise<proto.AddGasSponsorReturn> {
105
- return { status: true, gasSponsor: {} as proto.GasSponsor }
106
- }
107
-
108
- async updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise<proto.UpdateGasSponsorReturn> {
109
- return { status: true, gasSponsor: {} as proto.GasSponsor }
110
- }
111
-
112
- async removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise<proto.RemoveGasSponsorReturn> {
113
- return { status: true }
114
- }
115
- }
116
-
117
- function isAbstractSigner(signer: any): signer is ethers.AbstractSigner {
118
- return (
119
- signer &&
120
- typeof signer === 'object' &&
121
- typeof signer.provider === 'object' &&
122
- typeof signer.getAddress === 'function' &&
123
- typeof signer.connect === 'function'
124
- )
125
- }
@@ -1,284 +0,0 @@
1
- import { ethers } from 'ethers'
2
- import { walletContracts } from '@0xsequence/abi'
3
- import { FeeOption, FeeQuote, proto, Relayer, SimulateResult } from '.'
4
- import { logger, Optionals } from '@0xsequence/utils'
5
- import { commons } from '@0xsequence/core'
6
-
7
- const DEFAULT_GAS_LIMIT = 800000n
8
-
9
- export interface ProviderRelayerOptions {
10
- provider: ethers.Provider
11
- waitPollRate?: number
12
- deltaBlocksLog?: number
13
- fromBlockLog?: number
14
- }
15
-
16
- export const ProviderRelayerDefaults: Required<Optionals<ProviderRelayerOptions>> = {
17
- waitPollRate: 1000,
18
- deltaBlocksLog: 12,
19
- fromBlockLog: -1024
20
- }
21
-
22
- export function isProviderRelayerOptions(obj: any): obj is ProviderRelayerOptions {
23
- return typeof obj === 'object' && isAbstractProvider(obj.provider)
24
- }
25
-
26
- export abstract class ProviderRelayer implements Relayer {
27
- public provider: ethers.Provider
28
- public waitPollRate: number
29
- public deltaBlocksLog: number
30
- public fromBlockLog: number
31
-
32
- constructor(options: ProviderRelayerOptions) {
33
- const opts = { ...ProviderRelayerDefaults, ...options }
34
-
35
- this.provider = opts.provider
36
- this.waitPollRate = opts.waitPollRate
37
- this.deltaBlocksLog = opts.deltaBlocksLog
38
- this.fromBlockLog = opts.fromBlockLog
39
- }
40
-
41
- abstract getFeeOptions(
42
- address: string,
43
- ...transactions: commons.transaction.Transaction[]
44
- ): Promise<{ options: FeeOption[]; quote?: FeeQuote }>
45
-
46
- abstract getFeeOptionsRaw(
47
- entrypoint: string,
48
- data: ethers.BytesLike,
49
- options?: {
50
- simulate?: boolean
51
- }
52
- ): Promise<{ options: FeeOption[]; quote?: FeeQuote }>
53
-
54
- abstract gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise<FeeOption[]>
55
-
56
- abstract relay(
57
- signedTxs: commons.transaction.IntendedTransactionBundle,
58
- quote?: FeeQuote,
59
- waitForReceipt?: boolean
60
- ): Promise<commons.transaction.TransactionResponse>
61
-
62
- abstract getTransactionCost(
63
- projectId: number,
64
- from: string,
65
- to: string
66
- ): Promise<{
67
- cost: number
68
- }>
69
-
70
- abstract getMetaTransactions(
71
- projectId: number,
72
- page?: proto.Page
73
- ): Promise<{
74
- page: proto.Page
75
- transactions: proto.MetaTxnLog[]
76
- }>
77
-
78
- abstract listGasSponsors(args: proto.ListGasSponsorsArgs): Promise<proto.ListGasSponsorsReturn>
79
-
80
- abstract addGasSponsor(args: proto.AddGasSponsorArgs): Promise<proto.AddGasSponsorReturn>
81
-
82
- abstract updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise<proto.UpdateGasSponsorReturn>
83
-
84
- abstract removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise<proto.RemoveGasSponsorReturn>
85
-
86
- async simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise<SimulateResult[]> {
87
- return (
88
- await Promise.all(
89
- transactions.map(async tx => {
90
- // Respect gasLimit request of the transaction (as long as its not 0)
91
- if (tx.gasLimit && BigInt(tx.gasLimit || 0) !== 0n) {
92
- return tx.gasLimit
93
- }
94
-
95
- // Fee can't be estimated locally for delegateCalls
96
- if (tx.delegateCall) {
97
- return DEFAULT_GAS_LIMIT
98
- }
99
-
100
- // Fee can't be estimated for self-called if wallet hasn't been deployed
101
- if (tx.to === wallet && (await this.provider.getCode(wallet).then(code => ethers.getBytes(code).length === 0))) {
102
- return DEFAULT_GAS_LIMIT
103
- }
104
-
105
- if (!this.provider) {
106
- throw new Error('signer.provider is not set, but is required')
107
- }
108
-
109
- // TODO: If the wallet address has been deployed, gas limits can be
110
- // estimated with more accurately by using self-calls with the batch transactions one by one
111
- return this.provider.estimateGas({
112
- from: wallet,
113
- to: tx.to,
114
- data: tx.data,
115
- value: tx.value
116
- })
117
- })
118
- )
119
- ).map(gasLimit => ({
120
- executed: true,
121
- succeeded: true,
122
- gasUsed: Number(gasLimit),
123
- gasLimit: Number(gasLimit)
124
- }))
125
- }
126
-
127
- async getNonce(address: string, space?: ethers.BigNumberish, blockTag?: ethers.BlockTag): Promise<ethers.BigNumberish> {
128
- if (!this.provider) {
129
- throw new Error('provider is not set')
130
- }
131
-
132
- if ((await this.provider.getCode(address)) === '0x') {
133
- return 0
134
- }
135
-
136
- if (space === undefined) {
137
- space = 0
138
- }
139
-
140
- const module = new ethers.Contract(address, walletContracts.mainModule.abi, this.provider)
141
- const nonce = await module.readNonce(space, { blockTag: blockTag })
142
- return commons.transaction.encodeNonce(space, nonce)
143
- }
144
-
145
- async wait(
146
- metaTxnId: string | commons.transaction.SignedTransactionBundle,
147
- timeoutDuration?: number,
148
- delay: number = this.waitPollRate,
149
- maxFails: number = 5
150
- ): Promise<ethers.TransactionResponse & { receipt: ethers.TransactionReceipt }> {
151
- if (typeof metaTxnId !== 'string') {
152
- metaTxnId = commons.transaction.intendedTransactionID(metaTxnId)
153
- }
154
-
155
- let timedOut = false
156
-
157
- const retry = async <T>(f: () => Promise<T>, errorMessage: string): Promise<T> => {
158
- let fails = 0
159
-
160
- while (!timedOut) {
161
- try {
162
- return await f()
163
- } catch (error) {
164
- fails++
165
-
166
- if (maxFails !== undefined && fails >= maxFails) {
167
- logger.error(`giving up after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`, error)
168
- throw error
169
- } else {
170
- logger.warn(`attempt #${fails} failed${errorMessage ? `: ${errorMessage}` : ''}`, error)
171
- }
172
- }
173
-
174
- if (delay > 0) {
175
- await new Promise(resolve => setTimeout(resolve, delay))
176
- }
177
- }
178
-
179
- throw new Error(`timed out after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`)
180
- }
181
-
182
- const waitReceipt = async (): Promise<ethers.TransactionResponse & { receipt: ethers.TransactionReceipt }> => {
183
- // Transactions can only get executed on nonce change
184
- // get all nonce changes and look for metaTxnIds in between logs
185
- let lastBlock: number = this.fromBlockLog
186
-
187
- if (lastBlock < 0) {
188
- const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number')
189
- lastBlock = block + lastBlock
190
- }
191
-
192
- if (typeof metaTxnId !== 'string') {
193
- throw new Error('impossible')
194
- }
195
-
196
- const normalMetaTxnId = metaTxnId.replace('0x', '')
197
-
198
- while (!timedOut) {
199
- const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number')
200
-
201
- const logs = await retry(
202
- () =>
203
- this.provider.getLogs({
204
- fromBlock: Math.max(0, lastBlock - this.deltaBlocksLog),
205
- toBlock: block,
206
- // Nonce change event topic
207
- topics: ['0x1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881']
208
- }),
209
- `unable to get NonceChange logs for blocks ${Math.max(0, lastBlock - this.deltaBlocksLog)} to ${block}`
210
- )
211
-
212
- lastBlock = block
213
-
214
- // Get receipts of all transactions
215
- const txs = await Promise.all(
216
- logs.map(l =>
217
- retry(
218
- () => this.provider.getTransactionReceipt(l.transactionHash),
219
- `unable to get receipt for transaction ${l.transactionHash}`
220
- )
221
- )
222
- )
223
-
224
- // Find a transaction with a TxExecuted log
225
- const found = txs.find(tx =>
226
- tx?.logs.find(
227
- l =>
228
- (l.topics.length === 0 && l.data.replace('0x', '') === normalMetaTxnId) ||
229
- (l.topics.length === 1 &&
230
- // TxFailed event topic
231
- l.topics[0] === '0x3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd7' &&
232
- l.data.length >= 64 &&
233
- l.data.replace('0x', '').startsWith(normalMetaTxnId))
234
- )
235
- )
236
-
237
- // If found return that
238
- if (found) {
239
- const response = await retry(() => this.provider.getTransaction(found.hash), `unable to get transaction ${found.hash}`)
240
- if (!response) {
241
- throw new Error(`Transaction response not found for ${metaTxnId}`)
242
- }
243
-
244
- // NOTE: we have to do this, because ethers-v6 uses private fields
245
- // and we can't just extend the class and override the method, so
246
- // we just modify the response object directly by adding the receipt to it.
247
- const out: any = response
248
- out.receipt = found
249
- return out
250
- }
251
-
252
- // Otherwise wait and try again
253
- if (!timedOut) {
254
- await new Promise(r => setTimeout(r, delay))
255
- }
256
- }
257
-
258
- throw new Error(`Timeout waiting for transaction receipt ${metaTxnId}`)
259
- }
260
-
261
- if (timeoutDuration !== undefined) {
262
- return Promise.race([
263
- waitReceipt(),
264
- new Promise<ethers.TransactionResponse & { receipt: ethers.TransactionReceipt }>((_, reject) =>
265
- setTimeout(() => {
266
- timedOut = true
267
- reject(`Timeout waiting for transaction receipt ${metaTxnId}`)
268
- }, timeoutDuration)
269
- )
270
- ])
271
- } else {
272
- return waitReceipt()
273
- }
274
- }
275
- }
276
-
277
- function isAbstractProvider(provider: any): provider is ethers.AbstractProvider {
278
- return (
279
- provider &&
280
- typeof provider === 'object' &&
281
- typeof provider.getNetwork === 'function' &&
282
- typeof provider.getBlockNumber === 'function'
283
- )
284
- }