@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ShroudFi contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # @shroud-fi/relayer
2
+
3
+ > Gasless sweep client for ShroudFi. ERC-20 via Gelato + EIP-2612 permit; ETH via EIP-7702.
4
+
5
+ [![npm](https://img.shields.io/npm/v/@shroud-fi/relayer.svg)](https://www.npmjs.com/package/@shroud-fi/relayer)
6
+ [![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
7
+
8
+ ```bash
9
+ npm i @shroud-fi/relayer viem
10
+ ```
11
+
12
+ ## What it does
13
+
14
+ `@shroud-fi/relayer` is the client side of a gasless sweep. A stealth address that holds USDC or ETH but **no ETH for gas** can still extract its funds — the relayer pays gas, the recipient pays a 1% fee.
15
+
16
+ - **ERC-20 path:** signs an EIP-2612 `permit` + ERC-2771 metaTx, submits via Gelato 1Balance. The Gelato sponsor EOA broadcasts; the stealth EOA never needs ETH.
17
+ - **ETH path:** signs an EIP-7702 authorization that delegates the stealth EOA's code to `ShroudFiEthRelayer`, then calls `sweepETH(destination, fee)` in a single tx.
18
+
19
+ The recipient pays a 1% fee at sweep time — taken inside the contract execution, not at send time, so the sender's graph stays clean.
20
+
21
+ ## Quick start
22
+
23
+ ```ts
24
+ import { relayedSweepERC20 } from '@shroud-fi/relayer';
25
+
26
+ const receipt = await relayedSweepERC20({
27
+ transport,
28
+ stealthPrivateKey,
29
+ token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC Base
30
+ destination: '0xYourDestination',
31
+ relayerContract: '0x44f35ED32516AE8247aF5ec4ED5d5BEb501631d1', // ShroudFi mainnet
32
+ });
33
+
34
+ // receipt: { txHash, gasUsed, taskStatus } — no plaintext amount field
35
+ ```
36
+
37
+ ## Exports
38
+
39
+ | Symbol | Purpose |
40
+ |---|---|
41
+ | `relayedSweepERC20(args)` | Gasless ERC-20 sweep via Gelato 1Balance. |
42
+ | `relayedSweepETH(args)` | Gasless ETH sweep via EIP-7702 delegated relayer. |
43
+ | `RelayerSweepReceipt` | Result type — no plaintext amount field by design. |
44
+ | `StealthAddressEmptyError` | Distinguishes "already swept" from wallet insufficiency. |
45
+ | `RelayerInsufficientBalanceError` | Despite the name, this means the **stealth address is empty**, not the relayer. |
46
+
47
+ Full API reference: [shroudfi.live/sdk#relayer](https://shroudfi.live/sdk#relayer)
48
+
49
+ ## Direct sweep escape hatch
50
+
51
+ `@shroud-fi/payments` provides `sweepETH` / `sweepERC20` for the fee-free direct path. The relayer is opt-in — agents that already hold ETH can sweep without paying the 1%.
52
+
53
+ ## License
54
+
55
+ MIT — see [LICENSE](./LICENSE).
56
+
57
+ Part of the [ShroudFi](https://shroudfi.live) privacy SDK for AI agents on Base.
@@ -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,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ETH_RELAYER_SUPPORTED_CHAINS = exports.DEFAULT_ETH_SWEEP_DEADLINE_SECS = exports.GELATO_TASK_STATUS_URL = exports.GELATO_FORWARDER_BY_CHAIN = exports.DEFAULT_POLL_TIMEOUT_MS = exports.DEFAULT_POLL_INTERVAL_MS = exports.DEFAULT_PERMIT_DEADLINE_SECS = void 0;
4
+ /**
5
+ * Default EIP-2612 permit deadline lifetime (in seconds).
6
+ *
7
+ * 30 minutes balances:
8
+ * - long enough for Gelato task scheduling + L2 inclusion under congestion
9
+ * - short enough to keep the signed permit window tight (smaller front-run /
10
+ * replay attack window if a permit signature leaks)
11
+ */
12
+ exports.DEFAULT_PERMIT_DEADLINE_SECS = 1800n;
13
+ /** Poll Gelato task status every 2s by default. */
14
+ exports.DEFAULT_POLL_INTERVAL_MS = 2000;
15
+ /** Abort polling after 90s by default — well past Base L2 inclusion p99. */
16
+ exports.DEFAULT_POLL_TIMEOUT_MS = 90_000;
17
+ /**
18
+ * Gelato Trusted Forwarder addresses ("Group A") for ShroudFi-supported chains.
19
+ *
20
+ * Both Base Sepolia (84532) and Base Mainnet (8453) share the same
21
+ * forwarder address per Gelato's Group A deployment.
22
+ *
23
+ * Defense-in-depth: at runtime the SDK reads `ShroudFiRelayer.trustedForwarder()`
24
+ * and asserts equality against this table before submitting any metaTx.
25
+ */
26
+ exports.GELATO_FORWARDER_BY_CHAIN = Object.freeze({
27
+ 8453: '0xd8253782c45a12053594b9deB72d8e8aB2Fca54c',
28
+ 84532: '0xd8253782c45a12053594b9deB72d8e8aB2Fca54c',
29
+ });
30
+ /**
31
+ * Gelato public task-status endpoint. No auth required.
32
+ * Used as a fallback if the SDK's `getTaskStatus` is unavailable.
33
+ */
34
+ exports.GELATO_TASK_STATUS_URL = 'https://api.gelato.digital/tasks/status/';
35
+ // ─── ETH sweep (P5.1) ─────────────────────────────────────────────────────
36
+ /**
37
+ * Default EIP-712 EthSweep deadline lifetime (seconds). Matches the ERC-20
38
+ * permit deadline — 30 minutes balances inclusion headroom against a tight
39
+ * replay window if the signature leaks.
40
+ */
41
+ exports.DEFAULT_ETH_SWEEP_DEADLINE_SECS = 1800n;
42
+ /**
43
+ * Chains where the ShroudFiEthRelayer is deployed AND EIP-7702 is active.
44
+ * Base Sepolia (84532) + Base mainnet (8453). Pectra activated on both.
45
+ */
46
+ exports.ETH_RELAYER_SUPPORTED_CHAINS = new Set([
47
+ 8453, 84532,
48
+ ]);
49
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";;;AAEA;;;;;;;GAOG;AACU,QAAA,4BAA4B,GAAW,KAAK,CAAC;AAE1D,mDAAmD;AACtC,QAAA,wBAAwB,GAAW,IAAI,CAAC;AAErD,4EAA4E;AAC/D,QAAA,uBAAuB,GAAW,MAAM,CAAC;AAEtD;;;;;;;;GAQG;AACU,QAAA,yBAAyB,GACpC,MAAM,CAAC,MAAM,CAAC;IACZ,IAAI,EAAE,4CAAuD;IAC7D,KAAK,EAAE,4CAAuD;CAC/D,CAAC,CAAC;AAEL;;;GAGG;AACU,QAAA,sBAAsB,GACjC,0CAA0C,CAAC;AAE7C,6EAA6E;AAE7E;;;;GAIG;AACU,QAAA,+BAA+B,GAAW,KAAK,CAAC;AAE7D;;;GAGG;AACU,QAAA,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,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RelayerInvalidChainError = exports.StealthAddressEmptyError = exports.RelayerForwarderMismatchError = exports.RelayerTimeoutError = exports.RelayerExecutionFailedError = exports.RelayerSubmissionError = exports.RelayerSignatureError = exports.RelayerError = void 0;
4
+ /**
5
+ * Base class for all relayer-layer failures. Carries no key or amount
6
+ * material. Mirrors the shape of `@shroud-fi/payments` errors.
7
+ */
8
+ class RelayerError extends Error {
9
+ name = 'RelayerError';
10
+ constructor(message) {
11
+ super(message);
12
+ }
13
+ }
14
+ exports.RelayerError = RelayerError;
15
+ /** EIP-2612 permit could not be signed (typed-data path failed). */
16
+ class RelayerSignatureError extends RelayerError {
17
+ name = 'RelayerSignatureError';
18
+ constructor() {
19
+ super('Failed to sign EIP-2612 permit');
20
+ }
21
+ }
22
+ exports.RelayerSignatureError = RelayerSignatureError;
23
+ /** Gelato accepted/rejected the metaTx submission — no taskId obtained. */
24
+ class RelayerSubmissionError extends RelayerError {
25
+ name = 'RelayerSubmissionError';
26
+ constructor(tag) {
27
+ super(tag === undefined
28
+ ? 'Failed to submit sponsored call to relayer network'
29
+ : `Failed to submit sponsored call to relayer network (${tag})`);
30
+ }
31
+ }
32
+ exports.RelayerSubmissionError = RelayerSubmissionError;
33
+ /**
34
+ * Gelato accepted the task but on-chain execution reverted (or was blacklisted).
35
+ * Carries the lifecycle state but no signature / amount / address bytes.
36
+ */
37
+ class RelayerExecutionFailedError extends RelayerError {
38
+ name = 'RelayerExecutionFailedError';
39
+ constructor(state) {
40
+ super(`Relayed sweep execution did not succeed (state=${state})`);
41
+ }
42
+ }
43
+ exports.RelayerExecutionFailedError = RelayerExecutionFailedError;
44
+ /** Polling exceeded the configured timeout. */
45
+ class RelayerTimeoutError extends RelayerError {
46
+ name = 'RelayerTimeoutError';
47
+ constructor() {
48
+ super('Timed out waiting for relayer task to reach a terminal state');
49
+ }
50
+ }
51
+ exports.RelayerTimeoutError = RelayerTimeoutError;
52
+ /**
53
+ * On-chain `ShroudFiRelayer.trustedForwarder()` did not match the Gelato
54
+ * forwarder we expected for this chain. Defense-in-depth against deploying
55
+ * against the wrong forwarder.
56
+ */
57
+ class RelayerForwarderMismatchError extends RelayerError {
58
+ name = 'RelayerForwarderMismatchError';
59
+ constructor() {
60
+ super('Relayer contract trustedForwarder does not match expected Gelato forwarder');
61
+ }
62
+ }
63
+ exports.RelayerForwarderMismatchError = RelayerForwarderMismatchError;
64
+ /**
65
+ * Stealth address held zero balance of the target token at the time the
66
+ * relayer was asked to sweep it. Distinct from a wallet "insufficient funds"
67
+ * condition — this means the inbound stealth has already been swept (or never
68
+ * funded), so there's nothing left to relay.
69
+ */
70
+ class StealthAddressEmptyError extends RelayerError {
71
+ name = 'StealthAddressEmptyError';
72
+ constructor() {
73
+ super('Stealth address has zero balance of the target token');
74
+ }
75
+ }
76
+ exports.StealthAddressEmptyError = StealthAddressEmptyError;
77
+ /** Transport chain is not in the supported Gelato forwarder table. */
78
+ class RelayerInvalidChainError extends RelayerError {
79
+ name = 'RelayerInvalidChainError';
80
+ constructor() {
81
+ super('Transport chain is not supported by the Gelato relayer');
82
+ }
83
+ }
84
+ exports.RelayerInvalidChainError = RelayerInvalidChainError;
85
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,MAAa,YAAa,SAAQ,KAAK;IACnB,IAAI,GAAW,cAAc,CAAC;IAChD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;CACF;AALD,oCAKC;AAED,oEAAoE;AACpE,MAAa,qBAAsB,SAAQ,YAAY;IACnC,IAAI,GAAW,uBAAuB,CAAC;IACzD;QACE,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAC1C,CAAC;CACF;AALD,sDAKC;AAED,2EAA2E;AAC3E,MAAa,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;AATD,wDASC;AAED;;;GAGG;AACH,MAAa,2BAA4B,SAAQ,YAAY;IACzC,IAAI,GAAW,6BAA6B,CAAC;IAC/D,YAAY,KAAa;QACvB,KAAK,CAAC,kDAAkD,KAAK,GAAG,CAAC,CAAC;IACpE,CAAC;CACF;AALD,kEAKC;AAED,+CAA+C;AAC/C,MAAa,mBAAoB,SAAQ,YAAY;IACjC,IAAI,GAAW,qBAAqB,CAAC;IACvD;QACE,KAAK,CAAC,8DAA8D,CAAC,CAAC;IACxE,CAAC;CACF;AALD,kDAKC;AAED;;;;GAIG;AACH,MAAa,6BAA8B,SAAQ,YAAY;IAC3C,IAAI,GAAW,+BAA+B,CAAC;IACjE;QACE,KAAK,CAAC,4EAA4E,CAAC,CAAC;IACtF,CAAC;CACF;AALD,sEAKC;AAED;;;;;GAKG;AACH,MAAa,wBAAyB,SAAQ,YAAY;IACtC,IAAI,GAAW,0BAA0B,CAAC;IAC5D;QACE,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAChE,CAAC;CACF;AALD,4DAKC;AAED,sEAAsE;AACtE,MAAa,wBAAyB,SAAQ,YAAY;IACtC,IAAI,GAAW,0BAA0B,CAAC;IAC5D;QACE,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAClE,CAAC;CACF;AALD,4DAKC"}
@@ -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,193 @@
1
+ "use strict";
2
+ /**
3
+ * relayedSweepETH — gasless ETH sweep via EIP-7702 + self-host relayer service.
4
+ *
5
+ * Flow:
6
+ * 1. Validate chain is in the supported ETH-relayer table.
7
+ * 2. Read stealth EOA balance; refuse if zero.
8
+ * 3. Read stealth EOA nonce (required for the EIP-7702 auth tuple).
9
+ * 4. Sign an EIP-7702 SET_CODE authorization delegating the stealth EOA to
10
+ * `ethRelayerContract`.
11
+ * 5. Sign an EIP-712 `EthSweep(destination, deadline)` message — the
12
+ * contract verifies this binds the specific destination + deadline so a
13
+ * compromised relayer cannot redirect funds.
14
+ * 6. POST both signatures to the self-host relayer's /relay-eth endpoint.
15
+ * 7. Wait for the on-chain receipt and return.
16
+ *
17
+ * Privacy invariants:
18
+ * - `stealthPrivateKey` never logged, never serialized to any persistent
19
+ * surface. Held in a closure during this call only.
20
+ * - No amount fields in the returned receipt. Callers wanting amount can
21
+ * compare pre/post balances themselves.
22
+ * - Error messages contain no addresses, signature bytes, or chain ids.
23
+ * - The fetch request body is constructed once and discarded. No fetch
24
+ * library that caches request bodies is used (native `fetch` only).
25
+ *
26
+ * Why self-host instead of Gelato:
27
+ * Gelato's 7702 path is bundled into their Smart Wallets product (passkeys,
28
+ * wallet abstraction). It doesn't expose a "submit my pre-signed 7702 auth"
29
+ * endpoint that fits our threat model. Our self-host relayer at
30
+ * api.shroudfi.live already controls its own EOA and can build arbitrary
31
+ * tx types — fewer vendor dependencies, full control of the broadcast path.
32
+ */
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.relayedSweepETH = relayedSweepETH;
35
+ const accounts_1 = require("viem/accounts");
36
+ const constants_js_1 = require("./constants.js");
37
+ const errors_js_1 = require("./errors.js");
38
+ /**
39
+ * EIP-712 typed-data spec for the EthSweep struct. Matches
40
+ * `bytes32 SWEEP_TYPEHASH = keccak256("EthSweep(address destination,uint256 deadline)")`
41
+ * in ShroudFiEthRelayer.sol.
42
+ */
43
+ const ETH_SWEEP_TYPES = {
44
+ EthSweep: [
45
+ { name: 'destination', type: 'address' },
46
+ { name: 'deadline', type: 'uint256' },
47
+ ],
48
+ };
49
+ const ETH_SWEEP_DOMAIN_NAME = 'ShroudFiEthRelayer';
50
+ const ETH_SWEEP_DOMAIN_VERSION = '1';
51
+ function isHex(s) {
52
+ return typeof s === 'string' && /^0x[0-9a-fA-F]+$/.test(s);
53
+ }
54
+ async function relayedSweepETH(transport, stealthPrivateKey, destination, ethRelayerContract, relayerServiceUrl, options) {
55
+ const chainId = transport.chain.id;
56
+ // 1. Chain support gate.
57
+ if (!constants_js_1.ETH_RELAYER_SUPPORTED_CHAINS.has(chainId)) {
58
+ throw new errors_js_1.RelayerInvalidChainError();
59
+ }
60
+ const account = (0, accounts_1.privateKeyToAccount)(stealthPrivateKey);
61
+ const stealthAddress = account.address;
62
+ // 2. Balance pre-flight.
63
+ const balance = await transport.publicClient.getBalance({
64
+ address: stealthAddress,
65
+ });
66
+ if (balance === 0n) {
67
+ throw new errors_js_1.StealthAddressEmptyError();
68
+ }
69
+ // 3. Read stealth EOA's nonce. EIP-7702 auth tuples include the EOA's
70
+ // nonce; mismatches at submission time cause invalid_auth_signature reverts.
71
+ const nonce = await transport.publicClient.getTransactionCount({
72
+ address: stealthAddress,
73
+ });
74
+ // 4. Compute deadline against on-chain block timestamp.
75
+ const lifetime = options?.deadlineSecs ?? constants_js_1.DEFAULT_ETH_SWEEP_DEADLINE_SECS;
76
+ const block = await transport.publicClient.getBlock();
77
+ const deadline = block.timestamp + lifetime;
78
+ // 5a. Sign EIP-7702 SET_CODE authorization.
79
+ let authorization;
80
+ try {
81
+ authorization = await account.signAuthorization({
82
+ contractAddress: ethRelayerContract,
83
+ chainId,
84
+ nonce,
85
+ });
86
+ }
87
+ catch {
88
+ throw new errors_js_1.RelayerSignatureError();
89
+ }
90
+ // 5b. Sign EIP-712 EthSweep. verifyingContract = stealthAddress because the
91
+ // contract runs as delegated code at the stealth EOA's address. OZ EIP712
92
+ // rebuilds the domain at runtime when address(this) != _cachedThis.
93
+ let signature;
94
+ try {
95
+ signature = await account.signTypedData({
96
+ domain: {
97
+ name: ETH_SWEEP_DOMAIN_NAME,
98
+ version: ETH_SWEEP_DOMAIN_VERSION,
99
+ chainId,
100
+ verifyingContract: stealthAddress,
101
+ },
102
+ types: ETH_SWEEP_TYPES,
103
+ primaryType: 'EthSweep',
104
+ message: { destination, deadline },
105
+ });
106
+ }
107
+ catch {
108
+ throw new errors_js_1.RelayerSignatureError();
109
+ }
110
+ // 6. POST to self-host relayer. The relayer reconstructs the 7702
111
+ // SignedAuthorization, builds a type-0x04 transaction, and broadcasts.
112
+ const url = `${relayerServiceUrl.replace(/\/$/, '')}/relay-eth`;
113
+ const body = {
114
+ stealthAddress,
115
+ destination,
116
+ chainId,
117
+ deadline: deadline.toString(),
118
+ signature,
119
+ authorization: {
120
+ address: authorization.address,
121
+ chainId: authorization.chainId,
122
+ nonce: authorization.nonce,
123
+ r: authorization.r,
124
+ s: authorization.s,
125
+ yParity: authorization.yParity,
126
+ },
127
+ };
128
+ let response;
129
+ try {
130
+ const init = {
131
+ method: 'POST',
132
+ headers: { 'Content-Type': 'application/json' },
133
+ body: JSON.stringify(body),
134
+ };
135
+ if (options?.signal !== undefined) {
136
+ init.signal = options.signal;
137
+ }
138
+ response = await fetch(url, init);
139
+ }
140
+ catch {
141
+ throw new errors_js_1.RelayerSubmissionError();
142
+ }
143
+ if (!response.ok) {
144
+ let tag;
145
+ try {
146
+ const parsed = (await response.json());
147
+ if (typeof parsed.error === 'string')
148
+ tag = parsed.error;
149
+ }
150
+ catch {
151
+ // body wasn't JSON — fall through with no tag.
152
+ }
153
+ throw new errors_js_1.RelayerSubmissionError(tag);
154
+ }
155
+ let parsed;
156
+ try {
157
+ parsed = (await response.json());
158
+ }
159
+ catch {
160
+ throw new errors_js_1.RelayerSubmissionError();
161
+ }
162
+ if (parsed.ok !== true || !isHex(parsed.txHash)) {
163
+ const tag = typeof parsed.error === 'string' ? parsed.error : 'unknown';
164
+ throw new errors_js_1.RelayerExecutionFailedError(tag);
165
+ }
166
+ const txHash = parsed.txHash;
167
+ // 7. Wait for on-chain confirmation. Relayer responded with a tx hash; the
168
+ // tx is broadcasting but not necessarily mined. Use viem's standard
169
+ // wait-for-receipt with the configured timeout.
170
+ const timeoutMs = options?.pollTimeoutMs ?? constants_js_1.DEFAULT_POLL_TIMEOUT_MS;
171
+ let receipt;
172
+ try {
173
+ receipt = await transport.publicClient.waitForTransactionReceipt({
174
+ hash: txHash,
175
+ timeout: timeoutMs,
176
+ });
177
+ }
178
+ catch {
179
+ throw new errors_js_1.RelayerTimeoutError();
180
+ }
181
+ if (receipt.status !== 'success') {
182
+ throw new errors_js_1.RelayerExecutionFailedError('reverted');
183
+ }
184
+ return {
185
+ txHash,
186
+ status: 'success',
187
+ blockNumber: receipt.blockNumber,
188
+ ethRelayerContract,
189
+ destination,
190
+ stealthAddress,
191
+ };
192
+ }
193
+ //# 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"}