@shroud-fi/relayer 0.1.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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -0
  3. package/dist/cjs/constants.d.ts +41 -0
  4. package/dist/cjs/constants.d.ts.map +1 -0
  5. package/dist/cjs/constants.js +49 -0
  6. package/dist/cjs/constants.js.map +1 -0
  7. package/dist/cjs/errors.d.ts +56 -0
  8. package/dist/cjs/errors.d.ts.map +1 -0
  9. package/dist/cjs/errors.js +85 -0
  10. package/dist/cjs/errors.js.map +1 -0
  11. package/dist/cjs/eth-sweep.d.ts +36 -0
  12. package/dist/cjs/eth-sweep.d.ts.map +1 -0
  13. package/dist/cjs/eth-sweep.js +193 -0
  14. package/dist/cjs/eth-sweep.js.map +1 -0
  15. package/dist/cjs/gelato-adapter.d.ts +69 -0
  16. package/dist/cjs/gelato-adapter.d.ts.map +1 -0
  17. package/dist/cjs/gelato-adapter.js +209 -0
  18. package/dist/cjs/gelato-adapter.js.map +1 -0
  19. package/dist/cjs/index.d.ts +7 -0
  20. package/dist/cjs/index.d.ts.map +1 -0
  21. package/dist/cjs/index.js +26 -0
  22. package/dist/cjs/index.js.map +1 -0
  23. package/dist/cjs/package.json +1 -0
  24. package/dist/cjs/relayer.d.ts +23 -0
  25. package/dist/cjs/relayer.d.ts.map +1 -0
  26. package/dist/cjs/relayer.js +149 -0
  27. package/dist/cjs/relayer.js.map +1 -0
  28. package/dist/cjs/signing.d.ts +24 -0
  29. package/dist/cjs/signing.d.ts.map +1 -0
  30. package/dist/cjs/signing.js +155 -0
  31. package/dist/cjs/signing.js.map +1 -0
  32. package/dist/cjs/types.d.ts +88 -0
  33. package/dist/cjs/types.d.ts.map +1 -0
  34. package/dist/cjs/types.js +3 -0
  35. package/dist/cjs/types.js.map +1 -0
  36. package/dist/esm/constants.d.ts +41 -0
  37. package/dist/esm/constants.d.ts.map +1 -0
  38. package/dist/esm/constants.js +46 -0
  39. package/dist/esm/constants.js.map +1 -0
  40. package/dist/esm/errors.d.ts +56 -0
  41. package/dist/esm/errors.d.ts.map +1 -0
  42. package/dist/esm/errors.js +74 -0
  43. package/dist/esm/errors.js.map +1 -0
  44. package/dist/esm/eth-sweep.d.ts +36 -0
  45. package/dist/esm/eth-sweep.d.ts.map +1 -0
  46. package/dist/esm/eth-sweep.js +190 -0
  47. package/dist/esm/eth-sweep.js.map +1 -0
  48. package/dist/esm/gelato-adapter.d.ts +69 -0
  49. package/dist/esm/gelato-adapter.d.ts.map +1 -0
  50. package/dist/esm/gelato-adapter.js +205 -0
  51. package/dist/esm/gelato-adapter.js.map +1 -0
  52. package/dist/esm/index.d.ts +7 -0
  53. package/dist/esm/index.d.ts.map +1 -0
  54. package/dist/esm/index.js +6 -0
  55. package/dist/esm/index.js.map +1 -0
  56. package/dist/esm/relayer.d.ts +23 -0
  57. package/dist/esm/relayer.d.ts.map +1 -0
  58. package/dist/esm/relayer.js +146 -0
  59. package/dist/esm/relayer.js.map +1 -0
  60. package/dist/esm/signing.d.ts +24 -0
  61. package/dist/esm/signing.d.ts.map +1 -0
  62. package/dist/esm/signing.js +152 -0
  63. package/dist/esm/signing.js.map +1 -0
  64. package/dist/esm/types.d.ts +88 -0
  65. package/dist/esm/types.d.ts.map +1 -0
  66. package/dist/esm/types.js +2 -0
  67. package/dist/esm/types.js.map +1 -0
  68. package/dist/tsconfig.cjs.tsbuildinfo +1 -0
  69. package/dist/tsconfig.esm.tsbuildinfo +1 -0
  70. package/dist/tsconfig.tsbuildinfo +1 -0
  71. package/package.json +64 -0
@@ -0,0 +1,88 @@
1
+ import type { Address, Hex } from 'viem';
2
+ /**
3
+ * Gelato task identifier returned by `sponsoredCallERC2771`.
4
+ * Opaque string the SDK uses to poll status.
5
+ */
6
+ export type GelatoTaskId = string;
7
+ /**
8
+ * Terminal + in-flight states the SDK surfaces to the caller.
9
+ * Mapped from Gelato's `TaskState` plus our own `'submitted'` initial state.
10
+ */
11
+ export type RelayerSweepStatus = 'submitted' | 'pending' | 'success' | 'failed' | 'cancelled';
12
+ /**
13
+ * EIP-2612 permit signature components plus deadline.
14
+ * `v / r / s` are passed verbatim to `sweepERC20WithPermit`.
15
+ *
16
+ * Privacy: never log or serialize this struct — the signature is a
17
+ * spending-authorization credential equivalent to a one-time approval.
18
+ */
19
+ export interface Eip2612PermitSignature {
20
+ readonly v: number;
21
+ readonly r: Hex;
22
+ readonly s: Hex;
23
+ readonly deadline: bigint;
24
+ }
25
+ /**
26
+ * Optional runtime overrides for {@link relayedSweepERC20}.
27
+ *
28
+ * All fields are optional; omitted fields use defaults from `constants.ts`.
29
+ *
30
+ * Privacy: `gelatoApiKey` is forwarded only to the Gelato adapter and never
31
+ * logged. The caller is responsible for sourcing it securely.
32
+ */
33
+ export interface RelayerSweepOptions {
34
+ /** Override the EIP-2612 permit deadline lifetime in seconds. */
35
+ readonly deadlineSecs?: bigint;
36
+ /** Override poll interval (ms) for Gelato task status. */
37
+ readonly pollIntervalMs?: number;
38
+ /** Override hard timeout (ms) for the polling loop. */
39
+ readonly pollTimeoutMs?: number;
40
+ /**
41
+ * Optional Gelato 1Balance sponsor API key. The Gelato SDK requires a
42
+ * non-empty string for sponsored calls; pass it here for production.
43
+ */
44
+ readonly gelatoApiKey?: string;
45
+ /** Cancellation token. Aborts polling early. */
46
+ readonly signal?: AbortSignal;
47
+ }
48
+ /**
49
+ * Receipt for a completed relayed sweep.
50
+ *
51
+ * Privacy invariant: NO `amount` / `feeAmount` / `netAmount` fields.
52
+ * The caller can read pre-/post-sweep balances independently if it needs
53
+ * those values; the SDK never returns plaintext amounts.
54
+ */
55
+ export interface RelayerSweepReceipt {
56
+ readonly taskId: GelatoTaskId;
57
+ readonly txHash: Hex;
58
+ readonly status: RelayerSweepStatus;
59
+ readonly relayerContract: Address;
60
+ readonly token: Address;
61
+ readonly destination: Address;
62
+ readonly blockNumber?: bigint;
63
+ }
64
+ /**
65
+ * Optional runtime overrides for {@link relayedSweepETH}.
66
+ */
67
+ export interface RelayedEthSweepOptions {
68
+ /** Override the EIP-712 EthSweep deadline lifetime in seconds. */
69
+ readonly deadlineSecs?: bigint;
70
+ /** Override hard timeout (ms) for waitForTransactionReceipt. */
71
+ readonly pollTimeoutMs?: number;
72
+ /** Cancellation token. Forwarded to fetch + receipt polling. */
73
+ readonly signal?: AbortSignal;
74
+ }
75
+ /**
76
+ * Receipt for a completed ETH gasless sweep.
77
+ *
78
+ * Same privacy invariant as {@link RelayerSweepReceipt}: NO amount fields.
79
+ */
80
+ export interface RelayedEthSweepReceipt {
81
+ readonly txHash: Hex;
82
+ readonly status: 'success';
83
+ readonly blockNumber: bigint;
84
+ readonly ethRelayerContract: Address;
85
+ readonly destination: Address;
86
+ readonly stealthAddress: Address;
87
+ }
88
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEzC;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,SAAS,GACT,SAAS,GACT,QAAQ,GACR,WAAW,CAAC;AAEhB;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;IAChB,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;IAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,uDAAuD;IACvD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,gDAAgD;IAChD,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAID;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,kEAAkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,gEAAgE;IAChE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,gEAAgE;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import type { Address } from 'viem';
2
+ /**
3
+ * Default EIP-2612 permit deadline lifetime (in seconds).
4
+ *
5
+ * 30 minutes balances:
6
+ * - long enough for Gelato task scheduling + L2 inclusion under congestion
7
+ * - short enough to keep the signed permit window tight (smaller front-run /
8
+ * replay attack window if a permit signature leaks)
9
+ */
10
+ export declare const DEFAULT_PERMIT_DEADLINE_SECS: bigint;
11
+ /** Poll Gelato task status every 2s by default. */
12
+ export declare const DEFAULT_POLL_INTERVAL_MS: number;
13
+ /** Abort polling after 90s by default — well past Base L2 inclusion p99. */
14
+ export declare const DEFAULT_POLL_TIMEOUT_MS: number;
15
+ /**
16
+ * Gelato Trusted Forwarder addresses ("Group A") for ShroudFi-supported chains.
17
+ *
18
+ * Both Base Sepolia (84532) and Base Mainnet (8453) share the same
19
+ * forwarder address per Gelato's Group A deployment.
20
+ *
21
+ * Defense-in-depth: at runtime the SDK reads `ShroudFiRelayer.trustedForwarder()`
22
+ * and asserts equality against this table before submitting any metaTx.
23
+ */
24
+ export declare const GELATO_FORWARDER_BY_CHAIN: Readonly<Record<number, Address>>;
25
+ /**
26
+ * Gelato public task-status endpoint. No auth required.
27
+ * Used as a fallback if the SDK's `getTaskStatus` is unavailable.
28
+ */
29
+ export declare const GELATO_TASK_STATUS_URL: string;
30
+ /**
31
+ * Default EIP-712 EthSweep deadline lifetime (seconds). Matches the ERC-20
32
+ * permit deadline — 30 minutes balances inclusion headroom against a tight
33
+ * replay window if the signature leaks.
34
+ */
35
+ export declare const DEFAULT_ETH_SWEEP_DEADLINE_SECS: bigint;
36
+ /**
37
+ * Chains where the ShroudFiEthRelayer is deployed AND EIP-7702 is active.
38
+ * Base Sepolia (84532) + Base mainnet (8453). Pectra activated on both.
39
+ */
40
+ export declare const ETH_RELAYER_SUPPORTED_CHAINS: ReadonlySet<number>;
41
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,EAAE,MAAc,CAAC;AAE1D,mDAAmD;AACnD,eAAO,MAAM,wBAAwB,EAAE,MAAa,CAAC;AAErD,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,EAAE,MAAe,CAAC;AAEtD;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIpE,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,MACO,CAAC;AAI7C;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,EAAE,MAAc,CAAC;AAE7D;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,WAAW,CAAC,MAAM,CAE3D,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Default EIP-2612 permit deadline lifetime (in seconds).
3
+ *
4
+ * 30 minutes balances:
5
+ * - long enough for Gelato task scheduling + L2 inclusion under congestion
6
+ * - short enough to keep the signed permit window tight (smaller front-run /
7
+ * replay attack window if a permit signature leaks)
8
+ */
9
+ export const DEFAULT_PERMIT_DEADLINE_SECS = 1800n;
10
+ /** Poll Gelato task status every 2s by default. */
11
+ export const DEFAULT_POLL_INTERVAL_MS = 2000;
12
+ /** Abort polling after 90s by default — well past Base L2 inclusion p99. */
13
+ export const DEFAULT_POLL_TIMEOUT_MS = 90_000;
14
+ /**
15
+ * Gelato Trusted Forwarder addresses ("Group A") for ShroudFi-supported chains.
16
+ *
17
+ * Both Base Sepolia (84532) and Base Mainnet (8453) share the same
18
+ * forwarder address per Gelato's Group A deployment.
19
+ *
20
+ * Defense-in-depth: at runtime the SDK reads `ShroudFiRelayer.trustedForwarder()`
21
+ * and asserts equality against this table before submitting any metaTx.
22
+ */
23
+ export const GELATO_FORWARDER_BY_CHAIN = Object.freeze({
24
+ 8453: '0xd8253782c45a12053594b9deB72d8e8aB2Fca54c',
25
+ 84532: '0xd8253782c45a12053594b9deB72d8e8aB2Fca54c',
26
+ });
27
+ /**
28
+ * Gelato public task-status endpoint. No auth required.
29
+ * Used as a fallback if the SDK's `getTaskStatus` is unavailable.
30
+ */
31
+ export const GELATO_TASK_STATUS_URL = 'https://api.gelato.digital/tasks/status/';
32
+ // ─── ETH sweep (P5.1) ─────────────────────────────────────────────────────
33
+ /**
34
+ * Default EIP-712 EthSweep deadline lifetime (seconds). Matches the ERC-20
35
+ * permit deadline — 30 minutes balances inclusion headroom against a tight
36
+ * replay window if the signature leaks.
37
+ */
38
+ export const DEFAULT_ETH_SWEEP_DEADLINE_SECS = 1800n;
39
+ /**
40
+ * Chains where the ShroudFiEthRelayer is deployed AND EIP-7702 is active.
41
+ * Base Sepolia (84532) + Base mainnet (8453). Pectra activated on both.
42
+ */
43
+ export const ETH_RELAYER_SUPPORTED_CHAINS = new Set([
44
+ 8453, 84532,
45
+ ]);
46
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAW,KAAK,CAAC;AAE1D,mDAAmD;AACnD,MAAM,CAAC,MAAM,wBAAwB,GAAW,IAAI,CAAC;AAErD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,uBAAuB,GAAW,MAAM,CAAC;AAEtD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,yBAAyB,GACpC,MAAM,CAAC,MAAM,CAAC;IACZ,IAAI,EAAE,4CAAuD;IAC7D,KAAK,EAAE,4CAAuD;CAC/D,CAAC,CAAC;AAEL;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GACjC,0CAA0C,CAAC;AAE7C,6EAA6E;AAE7E;;;;GAIG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAW,KAAK,CAAC;AAE7D;;;GAGG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAwB,IAAI,GAAG,CAAC;IACvE,IAAI,EAAE,KAAK;CACZ,CAAC,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Base class for all relayer-layer failures. Carries no key or amount
3
+ * material. Mirrors the shape of `@shroud-fi/payments` errors.
4
+ */
5
+ export declare class RelayerError extends Error {
6
+ readonly name: string;
7
+ constructor(message: string);
8
+ }
9
+ /** EIP-2612 permit could not be signed (typed-data path failed). */
10
+ export declare class RelayerSignatureError extends RelayerError {
11
+ readonly name: string;
12
+ constructor();
13
+ }
14
+ /** Gelato accepted/rejected the metaTx submission — no taskId obtained. */
15
+ export declare class RelayerSubmissionError extends RelayerError {
16
+ readonly name: string;
17
+ constructor(tag?: string);
18
+ }
19
+ /**
20
+ * Gelato accepted the task but on-chain execution reverted (or was blacklisted).
21
+ * Carries the lifecycle state but no signature / amount / address bytes.
22
+ */
23
+ export declare class RelayerExecutionFailedError extends RelayerError {
24
+ readonly name: string;
25
+ constructor(state: string);
26
+ }
27
+ /** Polling exceeded the configured timeout. */
28
+ export declare class RelayerTimeoutError extends RelayerError {
29
+ readonly name: string;
30
+ constructor();
31
+ }
32
+ /**
33
+ * On-chain `ShroudFiRelayer.trustedForwarder()` did not match the Gelato
34
+ * forwarder we expected for this chain. Defense-in-depth against deploying
35
+ * against the wrong forwarder.
36
+ */
37
+ export declare class RelayerForwarderMismatchError extends RelayerError {
38
+ readonly name: string;
39
+ constructor();
40
+ }
41
+ /**
42
+ * Stealth address held zero balance of the target token at the time the
43
+ * relayer was asked to sweep it. Distinct from a wallet "insufficient funds"
44
+ * condition — this means the inbound stealth has already been swept (or never
45
+ * funded), so there's nothing left to relay.
46
+ */
47
+ export declare class StealthAddressEmptyError extends RelayerError {
48
+ readonly name: string;
49
+ constructor();
50
+ }
51
+ /** Transport chain is not in the supported Gelato forwarder table. */
52
+ export declare class RelayerInvalidChainError extends RelayerError {
53
+ readonly name: string;
54
+ constructor();
55
+ }
56
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,SAAkB,IAAI,EAAE,MAAM,CAAkB;gBACpC,OAAO,EAAE,MAAM;CAG5B;AAED,oEAAoE;AACpE,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,SAAkB,IAAI,EAAE,MAAM,CAA2B;;CAI1D;AAED,2EAA2E;AAC3E,qBAAa,sBAAuB,SAAQ,YAAY;IACtD,SAAkB,IAAI,EAAE,MAAM,CAA4B;gBAC9C,GAAG,CAAC,EAAE,MAAM;CAOzB;AAED;;;GAGG;AACH,qBAAa,2BAA4B,SAAQ,YAAY;IAC3D,SAAkB,IAAI,EAAE,MAAM,CAAiC;gBACnD,KAAK,EAAE,MAAM;CAG1B;AAED,+CAA+C;AAC/C,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,SAAkB,IAAI,EAAE,MAAM,CAAyB;;CAIxD;AAED;;;;GAIG;AACH,qBAAa,6BAA8B,SAAQ,YAAY;IAC7D,SAAkB,IAAI,EAAE,MAAM,CAAmC;;CAIlE;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,YAAY;IACxD,SAAkB,IAAI,EAAE,MAAM,CAA8B;;CAI7D;AAED,sEAAsE;AACtE,qBAAa,wBAAyB,SAAQ,YAAY;IACxD,SAAkB,IAAI,EAAE,MAAM,CAA8B;;CAI7D"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Base class for all relayer-layer failures. Carries no key or amount
3
+ * material. Mirrors the shape of `@shroud-fi/payments` errors.
4
+ */
5
+ export class RelayerError extends Error {
6
+ name = 'RelayerError';
7
+ constructor(message) {
8
+ super(message);
9
+ }
10
+ }
11
+ /** EIP-2612 permit could not be signed (typed-data path failed). */
12
+ export class RelayerSignatureError extends RelayerError {
13
+ name = 'RelayerSignatureError';
14
+ constructor() {
15
+ super('Failed to sign EIP-2612 permit');
16
+ }
17
+ }
18
+ /** Gelato accepted/rejected the metaTx submission — no taskId obtained. */
19
+ export class RelayerSubmissionError extends RelayerError {
20
+ name = 'RelayerSubmissionError';
21
+ constructor(tag) {
22
+ super(tag === undefined
23
+ ? 'Failed to submit sponsored call to relayer network'
24
+ : `Failed to submit sponsored call to relayer network (${tag})`);
25
+ }
26
+ }
27
+ /**
28
+ * Gelato accepted the task but on-chain execution reverted (or was blacklisted).
29
+ * Carries the lifecycle state but no signature / amount / address bytes.
30
+ */
31
+ export class RelayerExecutionFailedError extends RelayerError {
32
+ name = 'RelayerExecutionFailedError';
33
+ constructor(state) {
34
+ super(`Relayed sweep execution did not succeed (state=${state})`);
35
+ }
36
+ }
37
+ /** Polling exceeded the configured timeout. */
38
+ export class RelayerTimeoutError extends RelayerError {
39
+ name = 'RelayerTimeoutError';
40
+ constructor() {
41
+ super('Timed out waiting for relayer task to reach a terminal state');
42
+ }
43
+ }
44
+ /**
45
+ * On-chain `ShroudFiRelayer.trustedForwarder()` did not match the Gelato
46
+ * forwarder we expected for this chain. Defense-in-depth against deploying
47
+ * against the wrong forwarder.
48
+ */
49
+ export class RelayerForwarderMismatchError extends RelayerError {
50
+ name = 'RelayerForwarderMismatchError';
51
+ constructor() {
52
+ super('Relayer contract trustedForwarder does not match expected Gelato forwarder');
53
+ }
54
+ }
55
+ /**
56
+ * Stealth address held zero balance of the target token at the time the
57
+ * relayer was asked to sweep it. Distinct from a wallet "insufficient funds"
58
+ * condition — this means the inbound stealth has already been swept (or never
59
+ * funded), so there's nothing left to relay.
60
+ */
61
+ export class StealthAddressEmptyError extends RelayerError {
62
+ name = 'StealthAddressEmptyError';
63
+ constructor() {
64
+ super('Stealth address has zero balance of the target token');
65
+ }
66
+ }
67
+ /** Transport chain is not in the supported Gelato forwarder table. */
68
+ export class RelayerInvalidChainError extends RelayerError {
69
+ name = 'RelayerInvalidChainError';
70
+ constructor() {
71
+ super('Transport chain is not supported by the Gelato relayer');
72
+ }
73
+ }
74
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IACnB,IAAI,GAAW,cAAc,CAAC;IAChD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;CACF;AAED,oEAAoE;AACpE,MAAM,OAAO,qBAAsB,SAAQ,YAAY;IACnC,IAAI,GAAW,uBAAuB,CAAC;IACzD;QACE,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAC1C,CAAC;CACF;AAED,2EAA2E;AAC3E,MAAM,OAAO,sBAAuB,SAAQ,YAAY;IACpC,IAAI,GAAW,wBAAwB,CAAC;IAC1D,YAAY,GAAY;QACtB,KAAK,CACH,GAAG,KAAK,SAAS;YACf,CAAC,CAAC,oDAAoD;YACtD,CAAC,CAAC,uDAAuD,GAAG,GAAG,CAClE,CAAC;IACJ,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,2BAA4B,SAAQ,YAAY;IACzC,IAAI,GAAW,6BAA6B,CAAC;IAC/D,YAAY,KAAa;QACvB,KAAK,CAAC,kDAAkD,KAAK,GAAG,CAAC,CAAC;IACpE,CAAC;CACF;AAED,+CAA+C;AAC/C,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IACjC,IAAI,GAAW,qBAAqB,CAAC;IACvD;QACE,KAAK,CAAC,8DAA8D,CAAC,CAAC;IACxE,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,6BAA8B,SAAQ,YAAY;IAC3C,IAAI,GAAW,+BAA+B,CAAC;IACjE;QACE,KAAK,CAAC,4EAA4E,CAAC,CAAC;IACtF,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,wBAAyB,SAAQ,YAAY;IACtC,IAAI,GAAW,0BAA0B,CAAC;IAC5D;QACE,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAChE,CAAC;CACF;AAED,sEAAsE;AACtE,MAAM,OAAO,wBAAyB,SAAQ,YAAY;IACtC,IAAI,GAAW,0BAA0B,CAAC;IAC5D;QACE,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAClE,CAAC;CACF"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * relayedSweepETH — gasless ETH sweep via EIP-7702 + self-host relayer service.
3
+ *
4
+ * Flow:
5
+ * 1. Validate chain is in the supported ETH-relayer table.
6
+ * 2. Read stealth EOA balance; refuse if zero.
7
+ * 3. Read stealth EOA nonce (required for the EIP-7702 auth tuple).
8
+ * 4. Sign an EIP-7702 SET_CODE authorization delegating the stealth EOA to
9
+ * `ethRelayerContract`.
10
+ * 5. Sign an EIP-712 `EthSweep(destination, deadline)` message — the
11
+ * contract verifies this binds the specific destination + deadline so a
12
+ * compromised relayer cannot redirect funds.
13
+ * 6. POST both signatures to the self-host relayer's /relay-eth endpoint.
14
+ * 7. Wait for the on-chain receipt and return.
15
+ *
16
+ * Privacy invariants:
17
+ * - `stealthPrivateKey` never logged, never serialized to any persistent
18
+ * surface. Held in a closure during this call only.
19
+ * - No amount fields in the returned receipt. Callers wanting amount can
20
+ * compare pre/post balances themselves.
21
+ * - Error messages contain no addresses, signature bytes, or chain ids.
22
+ * - The fetch request body is constructed once and discarded. No fetch
23
+ * library that caches request bodies is used (native `fetch` only).
24
+ *
25
+ * Why self-host instead of Gelato:
26
+ * Gelato's 7702 path is bundled into their Smart Wallets product (passkeys,
27
+ * wallet abstraction). It doesn't expose a "submit my pre-signed 7702 auth"
28
+ * endpoint that fits our threat model. Our self-host relayer at
29
+ * api.shroudfi.live already controls its own EOA and can build arbitrary
30
+ * tx types — fewer vendor dependencies, full control of the broadcast path.
31
+ */
32
+ import { type Address, type Hex } from 'viem';
33
+ import type { ShroudFiTransport } from '@shroud-fi/transport';
34
+ import type { RelayedEthSweepOptions, RelayedEthSweepReceipt } from './types.js';
35
+ export declare function relayedSweepETH(transport: ShroudFiTransport, stealthPrivateKey: Hex, destination: Address, ethRelayerContract: Address, relayerServiceUrl: string, options?: RelayedEthSweepOptions): Promise<RelayedEthSweepReceipt>;
36
+ //# sourceMappingURL=eth-sweep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eth-sweep.d.ts","sourceRoot":"","sources":["../../src/eth-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAM9D,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAoCpB,wBAAsB,eAAe,CACnC,SAAS,EAAE,iBAAiB,EAC5B,iBAAiB,EAAE,GAAG,EACtB,WAAW,EAAE,OAAO,EACpB,kBAAkB,EAAE,OAAO,EAC3B,iBAAiB,EAAE,MAAM,EACzB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CAkJjC"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * relayedSweepETH — gasless ETH sweep via EIP-7702 + self-host relayer service.
3
+ *
4
+ * Flow:
5
+ * 1. Validate chain is in the supported ETH-relayer table.
6
+ * 2. Read stealth EOA balance; refuse if zero.
7
+ * 3. Read stealth EOA nonce (required for the EIP-7702 auth tuple).
8
+ * 4. Sign an EIP-7702 SET_CODE authorization delegating the stealth EOA to
9
+ * `ethRelayerContract`.
10
+ * 5. Sign an EIP-712 `EthSweep(destination, deadline)` message — the
11
+ * contract verifies this binds the specific destination + deadline so a
12
+ * compromised relayer cannot redirect funds.
13
+ * 6. POST both signatures to the self-host relayer's /relay-eth endpoint.
14
+ * 7. Wait for the on-chain receipt and return.
15
+ *
16
+ * Privacy invariants:
17
+ * - `stealthPrivateKey` never logged, never serialized to any persistent
18
+ * surface. Held in a closure during this call only.
19
+ * - No amount fields in the returned receipt. Callers wanting amount can
20
+ * compare pre/post balances themselves.
21
+ * - Error messages contain no addresses, signature bytes, or chain ids.
22
+ * - The fetch request body is constructed once and discarded. No fetch
23
+ * library that caches request bodies is used (native `fetch` only).
24
+ *
25
+ * Why self-host instead of Gelato:
26
+ * Gelato's 7702 path is bundled into their Smart Wallets product (passkeys,
27
+ * wallet abstraction). It doesn't expose a "submit my pre-signed 7702 auth"
28
+ * endpoint that fits our threat model. Our self-host relayer at
29
+ * api.shroudfi.live already controls its own EOA and can build arbitrary
30
+ * tx types — fewer vendor dependencies, full control of the broadcast path.
31
+ */
32
+ import { privateKeyToAccount } from 'viem/accounts';
33
+ import { DEFAULT_ETH_SWEEP_DEADLINE_SECS, DEFAULT_POLL_TIMEOUT_MS, ETH_RELAYER_SUPPORTED_CHAINS, } from './constants.js';
34
+ import { RelayerExecutionFailedError, StealthAddressEmptyError, RelayerInvalidChainError, RelayerSignatureError, RelayerSubmissionError, RelayerTimeoutError, } from './errors.js';
35
+ /**
36
+ * EIP-712 typed-data spec for the EthSweep struct. Matches
37
+ * `bytes32 SWEEP_TYPEHASH = keccak256("EthSweep(address destination,uint256 deadline)")`
38
+ * in ShroudFiEthRelayer.sol.
39
+ */
40
+ const ETH_SWEEP_TYPES = {
41
+ EthSweep: [
42
+ { name: 'destination', type: 'address' },
43
+ { name: 'deadline', type: 'uint256' },
44
+ ],
45
+ };
46
+ const ETH_SWEEP_DOMAIN_NAME = 'ShroudFiEthRelayer';
47
+ const ETH_SWEEP_DOMAIN_VERSION = '1';
48
+ function isHex(s) {
49
+ return typeof s === 'string' && /^0x[0-9a-fA-F]+$/.test(s);
50
+ }
51
+ export async function relayedSweepETH(transport, stealthPrivateKey, destination, ethRelayerContract, relayerServiceUrl, options) {
52
+ const chainId = transport.chain.id;
53
+ // 1. Chain support gate.
54
+ if (!ETH_RELAYER_SUPPORTED_CHAINS.has(chainId)) {
55
+ throw new RelayerInvalidChainError();
56
+ }
57
+ const account = privateKeyToAccount(stealthPrivateKey);
58
+ const stealthAddress = account.address;
59
+ // 2. Balance pre-flight.
60
+ const balance = await transport.publicClient.getBalance({
61
+ address: stealthAddress,
62
+ });
63
+ if (balance === 0n) {
64
+ throw new StealthAddressEmptyError();
65
+ }
66
+ // 3. Read stealth EOA's nonce. EIP-7702 auth tuples include the EOA's
67
+ // nonce; mismatches at submission time cause invalid_auth_signature reverts.
68
+ const nonce = await transport.publicClient.getTransactionCount({
69
+ address: stealthAddress,
70
+ });
71
+ // 4. Compute deadline against on-chain block timestamp.
72
+ const lifetime = options?.deadlineSecs ?? DEFAULT_ETH_SWEEP_DEADLINE_SECS;
73
+ const block = await transport.publicClient.getBlock();
74
+ const deadline = block.timestamp + lifetime;
75
+ // 5a. Sign EIP-7702 SET_CODE authorization.
76
+ let authorization;
77
+ try {
78
+ authorization = await account.signAuthorization({
79
+ contractAddress: ethRelayerContract,
80
+ chainId,
81
+ nonce,
82
+ });
83
+ }
84
+ catch {
85
+ throw new RelayerSignatureError();
86
+ }
87
+ // 5b. Sign EIP-712 EthSweep. verifyingContract = stealthAddress because the
88
+ // contract runs as delegated code at the stealth EOA's address. OZ EIP712
89
+ // rebuilds the domain at runtime when address(this) != _cachedThis.
90
+ let signature;
91
+ try {
92
+ signature = await account.signTypedData({
93
+ domain: {
94
+ name: ETH_SWEEP_DOMAIN_NAME,
95
+ version: ETH_SWEEP_DOMAIN_VERSION,
96
+ chainId,
97
+ verifyingContract: stealthAddress,
98
+ },
99
+ types: ETH_SWEEP_TYPES,
100
+ primaryType: 'EthSweep',
101
+ message: { destination, deadline },
102
+ });
103
+ }
104
+ catch {
105
+ throw new RelayerSignatureError();
106
+ }
107
+ // 6. POST to self-host relayer. The relayer reconstructs the 7702
108
+ // SignedAuthorization, builds a type-0x04 transaction, and broadcasts.
109
+ const url = `${relayerServiceUrl.replace(/\/$/, '')}/relay-eth`;
110
+ const body = {
111
+ stealthAddress,
112
+ destination,
113
+ chainId,
114
+ deadline: deadline.toString(),
115
+ signature,
116
+ authorization: {
117
+ address: authorization.address,
118
+ chainId: authorization.chainId,
119
+ nonce: authorization.nonce,
120
+ r: authorization.r,
121
+ s: authorization.s,
122
+ yParity: authorization.yParity,
123
+ },
124
+ };
125
+ let response;
126
+ try {
127
+ const init = {
128
+ method: 'POST',
129
+ headers: { 'Content-Type': 'application/json' },
130
+ body: JSON.stringify(body),
131
+ };
132
+ if (options?.signal !== undefined) {
133
+ init.signal = options.signal;
134
+ }
135
+ response = await fetch(url, init);
136
+ }
137
+ catch {
138
+ throw new RelayerSubmissionError();
139
+ }
140
+ if (!response.ok) {
141
+ let tag;
142
+ try {
143
+ const parsed = (await response.json());
144
+ if (typeof parsed.error === 'string')
145
+ tag = parsed.error;
146
+ }
147
+ catch {
148
+ // body wasn't JSON — fall through with no tag.
149
+ }
150
+ throw new RelayerSubmissionError(tag);
151
+ }
152
+ let parsed;
153
+ try {
154
+ parsed = (await response.json());
155
+ }
156
+ catch {
157
+ throw new RelayerSubmissionError();
158
+ }
159
+ if (parsed.ok !== true || !isHex(parsed.txHash)) {
160
+ const tag = typeof parsed.error === 'string' ? parsed.error : 'unknown';
161
+ throw new RelayerExecutionFailedError(tag);
162
+ }
163
+ const txHash = parsed.txHash;
164
+ // 7. Wait for on-chain confirmation. Relayer responded with a tx hash; the
165
+ // tx is broadcasting but not necessarily mined. Use viem's standard
166
+ // wait-for-receipt with the configured timeout.
167
+ const timeoutMs = options?.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;
168
+ let receipt;
169
+ try {
170
+ receipt = await transport.publicClient.waitForTransactionReceipt({
171
+ hash: txHash,
172
+ timeout: timeoutMs,
173
+ });
174
+ }
175
+ catch {
176
+ throw new RelayerTimeoutError();
177
+ }
178
+ if (receipt.status !== 'success') {
179
+ throw new RelayerExecutionFailedError('reverted');
180
+ }
181
+ return {
182
+ txHash,
183
+ status: 'success',
184
+ blockNumber: receipt.blockNumber,
185
+ ethRelayerContract,
186
+ destination,
187
+ stealthAddress,
188
+ };
189
+ }
190
+ //# sourceMappingURL=eth-sweep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eth-sweep.js","sourceRoot":"","sources":["../../src/eth-sweep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import type { Address, Hex, Chain } from 'viem';
2
+ import type { GelatoTaskId, RelayerSweepStatus } from './types.js';
3
+ /**
4
+ * Parameters for submitting a sponsored (1Balance) ERC-2771 metaTx.
5
+ *
6
+ * `data` must already be ABI-encoded for the target function on `target`.
7
+ * The Gelato relay layer appends the `user` address to the calldata so the
8
+ * `_msgSender()` inside the target contract returns the stealth address.
9
+ *
10
+ * Privacy: `userPrivateKey` is consumed once to construct an ephemeral
11
+ * `walletClient`, which is then handed to the Gelato SDK. It is never logged,
12
+ * stored on `this`, or attached to thrown errors.
13
+ */
14
+ export interface SubmitMetaTxParams {
15
+ readonly chainId: number;
16
+ readonly target: Address;
17
+ readonly data: Hex;
18
+ readonly user: Address;
19
+ readonly userPrivateKey: Hex;
20
+ /**
21
+ * Optional Gelato 1Balance sponsor API key.
22
+ * The SDK requires a string; if absent we forward an empty string and let
23
+ * Gelato reject with a structured error.
24
+ */
25
+ readonly apiKey?: string;
26
+ readonly signal?: AbortSignal;
27
+ /**
28
+ * viem `Chain` to attach to the ephemeral walletClient. Required so viem
29
+ * has a chainId/rpc context for typed-data signing.
30
+ */
31
+ readonly chain: Chain;
32
+ /** RPC URL forwarded to the ephemeral walletClient. */
33
+ readonly rpcUrl?: string;
34
+ }
35
+ /**
36
+ * Normalized Gelato task status surfaced to the SDK caller. Strips PII /
37
+ * un-needed metadata (creation date, gas used, etc.) from the upstream type.
38
+ */
39
+ export interface GelatoTaskStatus {
40
+ readonly taskId: GelatoTaskId;
41
+ readonly state: RelayerSweepStatus;
42
+ readonly txHash?: Hex;
43
+ readonly blockNumber?: bigint;
44
+ readonly lastErrorMsg?: string;
45
+ }
46
+ /**
47
+ * Submit a sponsored ERC-2771 metaTx via Gelato 1Balance.
48
+ *
49
+ * Returns the Gelato `taskId`. Caller is responsible for polling.
50
+ */
51
+ export declare function submitSponsoredCallErc2771(p: SubmitMetaTxParams): Promise<GelatoTaskId>;
52
+ /**
53
+ * Poll Gelato task status until terminal (success / failed / cancelled) or
54
+ * until the timeout expires / the abort signal fires.
55
+ *
56
+ * Strategy:
57
+ * 1. Try the SDK's `getTaskStatus` first (it shares websocket cache).
58
+ * 2. Fall back to direct HTTP if the SDK returns undefined.
59
+ *
60
+ * Errors:
61
+ * - RelayerTimeoutError on timeout / abort
62
+ * - RelayerExecutionFailedError on `failed`/`cancelled` terminal state
63
+ */
64
+ export declare function pollGelatoTaskUntilTerminal(taskId: GelatoTaskId, opts: {
65
+ pollIntervalMs: number;
66
+ pollTimeoutMs: number;
67
+ signal?: AbortSignal;
68
+ }): Promise<GelatoTaskStatus>;
69
+ //# sourceMappingURL=gelato-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gelato-adapter.d.ts","sourceRoot":"","sources":["../../src/gelato-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAOhD,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAOnE;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAYD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,CAAC,EAAE,kBAAkB,GACpB,OAAO,CAAC,YAAY,CAAC,CAgCvB;AA2FD;;;;;;;;;;;GAWG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE;IACJ,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GACA,OAAO,CAAC,gBAAgB,CAAC,CAsD3B"}