@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.
- package/.turbo/turbo-build.log +5 -0
- package/CHANGELOG.md +3862 -0
- package/LICENSE +0 -17
- package/README.md +1 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/preconditions/codec.d.ts +12 -0
- package/dist/preconditions/codec.d.ts.map +1 -0
- package/dist/preconditions/codec.js +125 -0
- package/dist/preconditions/index.d.ts +4 -0
- package/dist/preconditions/index.d.ts.map +1 -0
- package/dist/preconditions/index.js +3 -0
- package/dist/preconditions/selectors.d.ts +7 -0
- package/dist/preconditions/selectors.d.ts.map +1 -0
- package/dist/preconditions/selectors.js +27 -0
- package/dist/preconditions/types.d.ts +70 -0
- package/dist/preconditions/types.d.ts.map +1 -0
- package/dist/preconditions/types.js +203 -0
- package/dist/relayer/index.d.ts +45 -0
- package/dist/relayer/index.d.ts.map +1 -0
- package/dist/relayer/index.js +3 -0
- package/dist/relayer/relayer.d.ts +26 -0
- package/dist/relayer/relayer.d.ts.map +1 -0
- package/dist/relayer/relayer.js +7 -0
- package/dist/relayer/rpc-relayer/index.d.ts +38 -0
- package/dist/relayer/rpc-relayer/index.d.ts.map +1 -0
- package/dist/relayer/rpc-relayer/index.js +375 -0
- package/dist/{declarations/src → relayer}/rpc-relayer/relayer.gen.d.ts +218 -178
- package/dist/relayer/rpc-relayer/relayer.gen.d.ts.map +1 -0
- package/dist/relayer/rpc-relayer/relayer.gen.js +1246 -0
- package/dist/relayer/standard/abi.d.ts +73 -0
- package/dist/relayer/standard/abi.d.ts.map +1 -0
- package/dist/relayer/standard/abi.js +10 -0
- package/dist/relayer/standard/eip6963.d.ts +31 -0
- package/dist/relayer/standard/eip6963.d.ts.map +1 -0
- package/dist/relayer/standard/eip6963.js +51 -0
- package/dist/relayer/standard/index.d.ts +5 -0
- package/dist/relayer/standard/index.d.ts.map +1 -0
- package/dist/relayer/standard/index.js +4 -0
- package/dist/relayer/standard/local.d.ts +60 -0
- package/dist/relayer/standard/local.d.ts.map +1 -0
- package/dist/relayer/standard/local.js +285 -0
- package/dist/relayer/standard/pk-relayer.d.ts +28 -0
- package/dist/relayer/standard/pk-relayer.d.ts.map +1 -0
- package/dist/relayer/standard/pk-relayer.js +112 -0
- package/dist/relayer/standard/sequence.d.ts +27 -0
- package/dist/relayer/standard/sequence.d.ts.map +1 -0
- package/dist/relayer/standard/sequence.js +84 -0
- package/package.json +28 -25
- package/src/index.ts +3 -111
- package/src/preconditions/codec.ts +190 -0
- package/src/preconditions/index.ts +3 -0
- package/src/preconditions/selectors.ts +38 -0
- package/src/preconditions/types.ts +201 -0
- package/src/relayer/index.ts +60 -0
- package/src/relayer/relayer.ts +37 -0
- package/src/relayer/rpc-relayer/index.ts +449 -0
- package/src/relayer/rpc-relayer/relayer.gen.ts +2268 -0
- package/src/relayer/standard/abi.ts +13 -0
- package/src/relayer/standard/eip6963.ts +74 -0
- package/src/relayer/standard/index.ts +4 -0
- package/src/relayer/standard/local.ts +353 -0
- package/src/relayer/standard/pk-relayer.ts +138 -0
- package/src/relayer/standard/sequence.ts +110 -0
- package/test/preconditions/codec.test.ts +531 -0
- package/test/preconditions/preconditions.test.ts +283 -0
- package/test/preconditions/selectors.test.ts +415 -0
- package/test/preconditions/types.test.ts +443 -0
- package/test/relayer/relayer.test.ts +355 -0
- package/tsconfig.json +10 -0
- package/dist/0xsequence-relayer.cjs.d.ts +0 -2
- package/dist/0xsequence-relayer.cjs.dev.js +0 -1626
- package/dist/0xsequence-relayer.cjs.js +0 -7
- package/dist/0xsequence-relayer.cjs.prod.js +0 -1626
- package/dist/0xsequence-relayer.esm.js +0 -1613
- package/dist/declarations/src/index.d.ts +0 -42
- package/dist/declarations/src/local-relayer.d.ts +0 -35
- package/dist/declarations/src/provider-relayer.d.ts +0 -47
- package/dist/declarations/src/rpc-relayer/index.d.ts +0 -72
- package/src/local-relayer.ts +0 -125
- package/src/provider-relayer.ts +0 -284
- package/src/rpc-relayer/index.ts +0 -380
- 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
|
-
};
|
package/src/local-relayer.ts
DELETED
|
@@ -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
|
-
}
|
package/src/provider-relayer.ts
DELETED
|
@@ -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
|
-
}
|