@metamask-previews/transaction-pay-controller 18.2.0-preview-4f74a56 → 19.0.0-preview-5231be986
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/CHANGELOG.md +12 -2
- package/dist/strategy/relay/constants.cjs +3 -1
- package/dist/strategy/relay/constants.cjs.map +1 -1
- package/dist/strategy/relay/constants.d.cts +2 -0
- package/dist/strategy/relay/constants.d.cts.map +1 -1
- package/dist/strategy/relay/constants.d.mts +2 -0
- package/dist/strategy/relay/constants.d.mts.map +1 -1
- package/dist/strategy/relay/constants.mjs +2 -0
- package/dist/strategy/relay/constants.mjs.map +1 -1
- package/dist/strategy/relay/hyperliquid-withdraw.cjs +194 -0
- package/dist/strategy/relay/hyperliquid-withdraw.cjs.map +1 -0
- package/dist/strategy/relay/hyperliquid-withdraw.d.cts +18 -0
- package/dist/strategy/relay/hyperliquid-withdraw.d.cts.map +1 -0
- package/dist/strategy/relay/hyperliquid-withdraw.d.mts +18 -0
- package/dist/strategy/relay/hyperliquid-withdraw.d.mts.map +1 -0
- package/dist/strategy/relay/hyperliquid-withdraw.mjs +190 -0
- package/dist/strategy/relay/hyperliquid-withdraw.mjs.map +1 -0
- package/dist/strategy/relay/relay-submit.cjs +8 -1
- package/dist/strategy/relay/relay-submit.cjs.map +1 -1
- package/dist/strategy/relay/relay-submit.d.cts.map +1 -1
- package/dist/strategy/relay/relay-submit.d.mts.map +1 -1
- package/dist/strategy/relay/relay-submit.mjs +8 -1
- package/dist/strategy/relay/relay-submit.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +2 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +2 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
## [
|
|
10
|
+
## [19.0.0]
|
|
11
11
|
|
|
12
12
|
### Added
|
|
13
13
|
|
|
14
|
+
- **BREAKING:** Add `KeyringControllerSignTypedMessageAction` to `AllowedActions` for HyperLiquid EIP-712 signing ([#8314](https://github.com/MetaMask/core/pull/8314))
|
|
15
|
+
- Clients must now provide `KeyringController:signTypedMessage` permission when constructing the controller messenger
|
|
16
|
+
- Add HyperLiquid withdrawal submission via Relay ([#8314](https://github.com/MetaMask/core/pull/8314))
|
|
14
17
|
- Add HyperLiquid source quote support for Relay strategy ([#8285](https://github.com/MetaMask/core/pull/8285))
|
|
18
|
+
- Bump `@metamask/assets-controller` from `^3.2.0` to `^3.2.1` ([#8325](https://github.com/MetaMask/core/pull/8325))
|
|
19
|
+
- Bump `@metamask/assets-controllers` from `^102.0.0` to `^103.0.0` ([#8325](https://github.com/MetaMask/core/pull/8325))
|
|
20
|
+
- Bump `@metamask/bridge-controller` from `^69.2.2` to `^69.2.3` ([#8325](https://github.com/MetaMask/core/pull/8325))
|
|
21
|
+
- Bump `@metamask/bridge-status-controller` from `^70.0.2` to `^70.0.3` ([#8325](https://github.com/MetaMask/core/pull/8325))
|
|
22
|
+
|
|
23
|
+
## [18.2.0]
|
|
15
24
|
|
|
16
25
|
### Changed
|
|
17
26
|
|
|
@@ -584,7 +593,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
584
593
|
|
|
585
594
|
- Initial release ([#6820](https://github.com/MetaMask/core/pull/6820))
|
|
586
595
|
|
|
587
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@
|
|
596
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@19.0.0...HEAD
|
|
597
|
+
[19.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@18.2.0...@metamask/transaction-pay-controller@19.0.0
|
|
588
598
|
[18.2.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@18.1.0...@metamask/transaction-pay-controller@18.2.0
|
|
589
599
|
[18.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@18.0.0...@metamask/transaction-pay-controller@18.1.0
|
|
590
600
|
[18.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-pay-controller@17.1.0...@metamask/transaction-pay-controller@18.0.0
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RELAY_DEPOSIT_TYPES = exports.RELAY_PENDING_STATUSES = exports.RELAY_FAILURE_STATUSES = exports.TOKEN_TRANSFER_FOUR_BYTE = exports.RELAY_POLLING_INTERVAL = exports.RELAY_STATUS_URL = exports.RELAY_QUOTE_URL = exports.RELAY_EXECUTE_URL = exports.RELAY_URL_BASE = void 0;
|
|
3
|
+
exports.RELAY_DEPOSIT_TYPES = exports.RELAY_PENDING_STATUSES = exports.RELAY_FAILURE_STATUSES = exports.TOKEN_TRANSFER_FOUR_BYTE = exports.RELAY_POLLING_INTERVAL = exports.HYPERLIQUID_EXCHANGE_URL = exports.RELAY_STATUS_URL = exports.RELAY_QUOTE_URL = exports.RELAY_EXECUTE_URL = exports.RELAY_AUTHORIZE_URL = exports.RELAY_URL_BASE = void 0;
|
|
4
4
|
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
5
5
|
exports.RELAY_URL_BASE = 'https://api.relay.link';
|
|
6
|
+
exports.RELAY_AUTHORIZE_URL = `${exports.RELAY_URL_BASE}/authorize`;
|
|
6
7
|
exports.RELAY_EXECUTE_URL = `${exports.RELAY_URL_BASE}/execute`;
|
|
7
8
|
exports.RELAY_QUOTE_URL = `${exports.RELAY_URL_BASE}/quote`;
|
|
8
9
|
exports.RELAY_STATUS_URL = `${exports.RELAY_URL_BASE}/intents/status/v3`;
|
|
10
|
+
exports.HYPERLIQUID_EXCHANGE_URL = 'https://api.hyperliquid.xyz/exchange';
|
|
9
11
|
exports.RELAY_POLLING_INTERVAL = 1000; // 1 Second
|
|
10
12
|
exports.TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';
|
|
11
13
|
exports.RELAY_FAILURE_STATUSES = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":";;;AAAA,6EAAmE;AAItD,QAAA,cAAc,GAAG,wBAAwB,CAAC;AAC1C,QAAA,iBAAiB,GAAG,GAAG,sBAAc,UAAU,CAAC;AAChD,QAAA,eAAe,GAAG,GAAG,sBAAc,QAAQ,CAAC;AAC5C,QAAA,gBAAgB,GAAG,GAAG,sBAAc,oBAAoB,CAAC;AACzD,QAAA,sBAAsB,GAAG,IAAI,CAAC,CAAC,WAAW;AAC1C,QAAA,wBAAwB,GAAG,YAAY,CAAC;AAExC,QAAA,sBAAsB,GAAkB;IACnD,SAAS;IACT,QAAQ;IACR,UAAU;CACX,CAAC;AAEW,QAAA,sBAAsB,GAAkB;IACnD,SAAS;IACT,YAAY;IACZ,SAAS;IACT,WAAW;IACX,SAAS;CACV,CAAC;AAEW,QAAA,mBAAmB,GAAoC;IAClE,CAAC,wCAAe,CAAC,cAAc,CAAC,EAAE,wCAAe,CAAC,mBAAmB;IACrE,CAAC,wCAAe,CAAC,YAAY,CAAC,EAAE,wCAAe,CAAC,iBAAiB;CAClE,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nimport type { RelayStatus } from './types';\n\nexport const RELAY_URL_BASE = 'https://api.relay.link';\nexport const RELAY_EXECUTE_URL = `${RELAY_URL_BASE}/execute`;\nexport const RELAY_QUOTE_URL = `${RELAY_URL_BASE}/quote`;\nexport const RELAY_STATUS_URL = `${RELAY_URL_BASE}/intents/status/v3`;\nexport const RELAY_POLLING_INTERVAL = 1000; // 1 Second\nexport const TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';\n\nexport const RELAY_FAILURE_STATUSES: RelayStatus[] = [\n 'failure',\n 'refund',\n 'refunded',\n];\n\nexport const RELAY_PENDING_STATUSES: RelayStatus[] = [\n 'delayed',\n 'depositing',\n 'pending',\n 'submitted',\n 'waiting',\n];\n\nexport const RELAY_DEPOSIT_TYPES: Record<string, TransactionType> = {\n [TransactionType.predictDeposit]: TransactionType.predictRelayDeposit,\n [TransactionType.perpsDeposit]: TransactionType.perpsRelayDeposit,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"constants.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":";;;AAAA,6EAAmE;AAItD,QAAA,cAAc,GAAG,wBAAwB,CAAC;AAC1C,QAAA,mBAAmB,GAAG,GAAG,sBAAc,YAAY,CAAC;AACpD,QAAA,iBAAiB,GAAG,GAAG,sBAAc,UAAU,CAAC;AAChD,QAAA,eAAe,GAAG,GAAG,sBAAc,QAAQ,CAAC;AAC5C,QAAA,gBAAgB,GAAG,GAAG,sBAAc,oBAAoB,CAAC;AACzD,QAAA,wBAAwB,GAAG,sCAAsC,CAAC;AAClE,QAAA,sBAAsB,GAAG,IAAI,CAAC,CAAC,WAAW;AAC1C,QAAA,wBAAwB,GAAG,YAAY,CAAC;AAExC,QAAA,sBAAsB,GAAkB;IACnD,SAAS;IACT,QAAQ;IACR,UAAU;CACX,CAAC;AAEW,QAAA,sBAAsB,GAAkB;IACnD,SAAS;IACT,YAAY;IACZ,SAAS;IACT,WAAW;IACX,SAAS;CACV,CAAC;AAEW,QAAA,mBAAmB,GAAoC;IAClE,CAAC,wCAAe,CAAC,cAAc,CAAC,EAAE,wCAAe,CAAC,mBAAmB;IACrE,CAAC,wCAAe,CAAC,YAAY,CAAC,EAAE,wCAAe,CAAC,iBAAiB;CAClE,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nimport type { RelayStatus } from './types';\n\nexport const RELAY_URL_BASE = 'https://api.relay.link';\nexport const RELAY_AUTHORIZE_URL = `${RELAY_URL_BASE}/authorize`;\nexport const RELAY_EXECUTE_URL = `${RELAY_URL_BASE}/execute`;\nexport const RELAY_QUOTE_URL = `${RELAY_URL_BASE}/quote`;\nexport const RELAY_STATUS_URL = `${RELAY_URL_BASE}/intents/status/v3`;\nexport const HYPERLIQUID_EXCHANGE_URL = 'https://api.hyperliquid.xyz/exchange';\nexport const RELAY_POLLING_INTERVAL = 1000; // 1 Second\nexport const TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';\n\nexport const RELAY_FAILURE_STATUSES: RelayStatus[] = [\n 'failure',\n 'refund',\n 'refunded',\n];\n\nexport const RELAY_PENDING_STATUSES: RelayStatus[] = [\n 'delayed',\n 'depositing',\n 'pending',\n 'submitted',\n 'waiting',\n];\n\nexport const RELAY_DEPOSIT_TYPES: Record<string, TransactionType> = {\n [TransactionType.predictDeposit]: TransactionType.predictRelayDeposit,\n [TransactionType.perpsDeposit]: TransactionType.perpsRelayDeposit,\n};\n"]}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { TransactionType } from "@metamask/transaction-controller";
|
|
2
2
|
import type { RelayStatus } from "./types.cjs";
|
|
3
3
|
export declare const RELAY_URL_BASE = "https://api.relay.link";
|
|
4
|
+
export declare const RELAY_AUTHORIZE_URL = "https://api.relay.link/authorize";
|
|
4
5
|
export declare const RELAY_EXECUTE_URL = "https://api.relay.link/execute";
|
|
5
6
|
export declare const RELAY_QUOTE_URL = "https://api.relay.link/quote";
|
|
6
7
|
export declare const RELAY_STATUS_URL = "https://api.relay.link/intents/status/v3";
|
|
8
|
+
export declare const HYPERLIQUID_EXCHANGE_URL = "https://api.hyperliquid.xyz/exchange";
|
|
7
9
|
export declare const RELAY_POLLING_INTERVAL = 1000;
|
|
8
10
|
export declare const TOKEN_TRANSFER_FOUR_BYTE = "0xa9059cbb";
|
|
9
11
|
export declare const RELAY_FAILURE_STATUSES: RelayStatus[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAgB;AAE3C,eAAO,MAAM,cAAc,2BAA2B,CAAC;AACvD,eAAO,MAAM,iBAAiB,mCAA8B,CAAC;AAC7D,eAAO,MAAM,eAAe,iCAA4B,CAAC;AACzD,eAAO,MAAM,gBAAgB,6CAAwC,CAAC;AACtE,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAC3C,eAAO,MAAM,wBAAwB,eAAe,CAAC;AAErD,eAAO,MAAM,sBAAsB,EAAE,WAAW,EAI/C,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,WAAW,EAM/C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAG/D,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAgB;AAE3C,eAAO,MAAM,cAAc,2BAA2B,CAAC;AACvD,eAAO,MAAM,mBAAmB,qCAAgC,CAAC;AACjE,eAAO,MAAM,iBAAiB,mCAA8B,CAAC;AAC7D,eAAO,MAAM,eAAe,iCAA4B,CAAC;AACzD,eAAO,MAAM,gBAAgB,6CAAwC,CAAC;AACtE,eAAO,MAAM,wBAAwB,yCAAyC,CAAC;AAC/E,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAC3C,eAAO,MAAM,wBAAwB,eAAe,CAAC;AAErD,eAAO,MAAM,sBAAsB,EAAE,WAAW,EAI/C,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,WAAW,EAM/C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAG/D,CAAC"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { TransactionType } from "@metamask/transaction-controller";
|
|
2
2
|
import type { RelayStatus } from "./types.mjs";
|
|
3
3
|
export declare const RELAY_URL_BASE = "https://api.relay.link";
|
|
4
|
+
export declare const RELAY_AUTHORIZE_URL = "https://api.relay.link/authorize";
|
|
4
5
|
export declare const RELAY_EXECUTE_URL = "https://api.relay.link/execute";
|
|
5
6
|
export declare const RELAY_QUOTE_URL = "https://api.relay.link/quote";
|
|
6
7
|
export declare const RELAY_STATUS_URL = "https://api.relay.link/intents/status/v3";
|
|
8
|
+
export declare const HYPERLIQUID_EXCHANGE_URL = "https://api.hyperliquid.xyz/exchange";
|
|
7
9
|
export declare const RELAY_POLLING_INTERVAL = 1000;
|
|
8
10
|
export declare const TOKEN_TRANSFER_FOUR_BYTE = "0xa9059cbb";
|
|
9
11
|
export declare const RELAY_FAILURE_STATUSES: RelayStatus[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAgB;AAE3C,eAAO,MAAM,cAAc,2BAA2B,CAAC;AACvD,eAAO,MAAM,iBAAiB,mCAA8B,CAAC;AAC7D,eAAO,MAAM,eAAe,iCAA4B,CAAC;AACzD,eAAO,MAAM,gBAAgB,6CAAwC,CAAC;AACtE,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAC3C,eAAO,MAAM,wBAAwB,eAAe,CAAC;AAErD,eAAO,MAAM,sBAAsB,EAAE,WAAW,EAI/C,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,WAAW,EAM/C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAG/D,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAgB;AAE3C,eAAO,MAAM,cAAc,2BAA2B,CAAC;AACvD,eAAO,MAAM,mBAAmB,qCAAgC,CAAC;AACjE,eAAO,MAAM,iBAAiB,mCAA8B,CAAC;AAC7D,eAAO,MAAM,eAAe,iCAA4B,CAAC;AACzD,eAAO,MAAM,gBAAgB,6CAAwC,CAAC;AACtE,eAAO,MAAM,wBAAwB,yCAAyC,CAAC;AAC/E,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAC3C,eAAO,MAAM,wBAAwB,eAAe,CAAC;AAErD,eAAO,MAAM,sBAAsB,EAAE,WAAW,EAI/C,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,WAAW,EAM/C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAG/D,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { TransactionType } from "@metamask/transaction-controller";
|
|
2
2
|
export const RELAY_URL_BASE = 'https://api.relay.link';
|
|
3
|
+
export const RELAY_AUTHORIZE_URL = `${RELAY_URL_BASE}/authorize`;
|
|
3
4
|
export const RELAY_EXECUTE_URL = `${RELAY_URL_BASE}/execute`;
|
|
4
5
|
export const RELAY_QUOTE_URL = `${RELAY_URL_BASE}/quote`;
|
|
5
6
|
export const RELAY_STATUS_URL = `${RELAY_URL_BASE}/intents/status/v3`;
|
|
7
|
+
export const HYPERLIQUID_EXCHANGE_URL = 'https://api.hyperliquid.xyz/exchange';
|
|
6
8
|
export const RELAY_POLLING_INTERVAL = 1000; // 1 Second
|
|
7
9
|
export const TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';
|
|
8
10
|
export const RELAY_FAILURE_STATUSES = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAInE,MAAM,CAAC,MAAM,cAAc,GAAG,wBAAwB,CAAC;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,cAAc,UAAU,CAAC;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,cAAc,QAAQ,CAAC;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,cAAc,oBAAoB,CAAC;AACtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,CAAC,WAAW;AACvD,MAAM,CAAC,MAAM,wBAAwB,GAAG,YAAY,CAAC;AAErD,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,SAAS;IACT,QAAQ;IACR,UAAU;CACX,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,SAAS;IACT,YAAY;IACZ,SAAS;IACT,WAAW;IACX,SAAS;CACV,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAoC;IAClE,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC,mBAAmB;IACrE,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,eAAe,CAAC,iBAAiB;CAClE,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nimport type { RelayStatus } from './types';\n\nexport const RELAY_URL_BASE = 'https://api.relay.link';\nexport const RELAY_EXECUTE_URL = `${RELAY_URL_BASE}/execute`;\nexport const RELAY_QUOTE_URL = `${RELAY_URL_BASE}/quote`;\nexport const RELAY_STATUS_URL = `${RELAY_URL_BASE}/intents/status/v3`;\nexport const RELAY_POLLING_INTERVAL = 1000; // 1 Second\nexport const TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';\n\nexport const RELAY_FAILURE_STATUSES: RelayStatus[] = [\n 'failure',\n 'refund',\n 'refunded',\n];\n\nexport const RELAY_PENDING_STATUSES: RelayStatus[] = [\n 'delayed',\n 'depositing',\n 'pending',\n 'submitted',\n 'waiting',\n];\n\nexport const RELAY_DEPOSIT_TYPES: Record<string, TransactionType> = {\n [TransactionType.predictDeposit]: TransactionType.predictRelayDeposit,\n [TransactionType.perpsDeposit]: TransactionType.perpsRelayDeposit,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,yCAAyC;AAInE,MAAM,CAAC,MAAM,cAAc,GAAG,wBAAwB,CAAC;AACvD,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,cAAc,YAAY,CAAC;AACjE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,cAAc,UAAU,CAAC;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,cAAc,QAAQ,CAAC;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,cAAc,oBAAoB,CAAC;AACtE,MAAM,CAAC,MAAM,wBAAwB,GAAG,sCAAsC,CAAC;AAC/E,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,CAAC,WAAW;AACvD,MAAM,CAAC,MAAM,wBAAwB,GAAG,YAAY,CAAC;AAErD,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,SAAS;IACT,QAAQ;IACR,UAAU;CACX,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,SAAS;IACT,YAAY;IACZ,SAAS;IACT,WAAW;IACX,SAAS;CACV,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAoC;IAClE,CAAC,eAAe,CAAC,cAAc,CAAC,EAAE,eAAe,CAAC,mBAAmB;IACrE,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,eAAe,CAAC,iBAAiB;CAClE,CAAC","sourcesContent":["import { TransactionType } from '@metamask/transaction-controller';\n\nimport type { RelayStatus } from './types';\n\nexport const RELAY_URL_BASE = 'https://api.relay.link';\nexport const RELAY_AUTHORIZE_URL = `${RELAY_URL_BASE}/authorize`;\nexport const RELAY_EXECUTE_URL = `${RELAY_URL_BASE}/execute`;\nexport const RELAY_QUOTE_URL = `${RELAY_URL_BASE}/quote`;\nexport const RELAY_STATUS_URL = `${RELAY_URL_BASE}/intents/status/v3`;\nexport const HYPERLIQUID_EXCHANGE_URL = 'https://api.hyperliquid.xyz/exchange';\nexport const RELAY_POLLING_INTERVAL = 1000; // 1 Second\nexport const TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';\n\nexport const RELAY_FAILURE_STATUSES: RelayStatus[] = [\n 'failure',\n 'refund',\n 'refunded',\n];\n\nexport const RELAY_PENDING_STATUSES: RelayStatus[] = [\n 'delayed',\n 'depositing',\n 'pending',\n 'submitted',\n 'waiting',\n];\n\nexport const RELAY_DEPOSIT_TYPES: Record<string, TransactionType> = {\n [TransactionType.predictDeposit]: TransactionType.predictRelayDeposit,\n [TransactionType.perpsDeposit]: TransactionType.perpsRelayDeposit,\n};\n"]}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.submitHyperliquidWithdraw = void 0;
|
|
4
|
+
const controller_utils_1 = require("@metamask/controller-utils");
|
|
5
|
+
const keyring_controller_1 = require("@metamask/keyring-controller");
|
|
6
|
+
const utils_1 = require("@metamask/utils");
|
|
7
|
+
const constants_1 = require("./constants.cjs");
|
|
8
|
+
const constants_2 = require("../../constants.cjs");
|
|
9
|
+
const logger_1 = require("../../logger.cjs");
|
|
10
|
+
const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'hyperliquid-withdraw');
|
|
11
|
+
const DOMAIN_FIELD_MAP = {
|
|
12
|
+
name: { name: 'name', type: 'string' },
|
|
13
|
+
version: { name: 'version', type: 'string' },
|
|
14
|
+
chainId: { name: 'chainId', type: 'uint256' },
|
|
15
|
+
verifyingContract: { name: 'verifyingContract', type: 'address' },
|
|
16
|
+
salt: { name: 'salt', type: 'bytes32' },
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Submit a HyperLiquid 2-step withdrawal via Relay.
|
|
20
|
+
*
|
|
21
|
+
* Step 1 (authorize): Sign an EIP-712 nonce-mapping message, POST to Relay /authorize.
|
|
22
|
+
* Step 2 (deposit): Sign an EIP-712 HyperliquidSignTransaction, POST to HyperLiquid exchange.
|
|
23
|
+
*
|
|
24
|
+
* Both signatures are silent (no user confirmation). Both steps share the same nonce
|
|
25
|
+
* from the Relay quote response.
|
|
26
|
+
*
|
|
27
|
+
* @param quote - Relay quote containing the 2-step flow.
|
|
28
|
+
* @param from - User's account address.
|
|
29
|
+
* @param messenger - Controller messenger (for KeyringController:signTypedMessage).
|
|
30
|
+
*/
|
|
31
|
+
async function submitHyperliquidWithdraw(quote, from, messenger) {
|
|
32
|
+
const { steps } = quote.original;
|
|
33
|
+
log('Starting HyperLiquid withdrawal', {
|
|
34
|
+
stepCount: steps.length,
|
|
35
|
+
stepIds: steps.map((step) => step.id),
|
|
36
|
+
});
|
|
37
|
+
const authorizeStep = steps.find((step) => step.kind === 'signature' && step.id === 'authorize');
|
|
38
|
+
const depositStep = steps.find((step) => step.id === 'deposit');
|
|
39
|
+
if (!authorizeStep || !depositStep) {
|
|
40
|
+
throw new Error(`Expected authorize and deposit steps for HyperLiquid withdrawal, got: ${steps.map((step) => `${step.id}(${step.kind})`).join(', ')}`);
|
|
41
|
+
}
|
|
42
|
+
// Step 1: Authorize (nonce-mapping signature -> POST to Relay /authorize)
|
|
43
|
+
await executeAuthorizeStep(authorizeStep, from, messenger);
|
|
44
|
+
// Step 2: Deposit (HyperLiquid sendAsset -> POST to HyperLiquid exchange)
|
|
45
|
+
await executeDepositStep(depositStep, from, messenger);
|
|
46
|
+
log('HyperLiquid withdrawal submitted successfully');
|
|
47
|
+
}
|
|
48
|
+
exports.submitHyperliquidWithdraw = submitHyperliquidWithdraw;
|
|
49
|
+
/**
|
|
50
|
+
* Derive the EIP712Domain type array from a domain object.
|
|
51
|
+
* eth-sig-util defaults to EIP712Domain: [] when absent, breaking
|
|
52
|
+
* the domain separator hash. This ensures it matches ethers.js behavior.
|
|
53
|
+
*
|
|
54
|
+
* @param domain - The EIP-712 domain object.
|
|
55
|
+
* @returns The EIP712Domain type array in canonical order.
|
|
56
|
+
*/
|
|
57
|
+
function deriveEIP712DomainType(domain) {
|
|
58
|
+
return Object.keys(DOMAIN_FIELD_MAP)
|
|
59
|
+
.filter((key) => key in domain)
|
|
60
|
+
.map((key) => DOMAIN_FIELD_MAP[key]);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Execute the authorize step: sign EIP-712 nonce-mapping and POST to Relay.
|
|
64
|
+
*
|
|
65
|
+
* @param step - The authorize signature step from the Relay quote.
|
|
66
|
+
* @param from - User's account address.
|
|
67
|
+
* @param messenger - Controller messenger for signing.
|
|
68
|
+
*/
|
|
69
|
+
async function executeAuthorizeStep(step, from, messenger) {
|
|
70
|
+
if (step.items.length !== 1) {
|
|
71
|
+
throw new Error(`Expected exactly 1 authorize item, got ${step.items.length}`);
|
|
72
|
+
}
|
|
73
|
+
const item = step.items[0];
|
|
74
|
+
if (!item) {
|
|
75
|
+
throw new Error('Authorize step has no items');
|
|
76
|
+
}
|
|
77
|
+
const { sign, post } = item.data;
|
|
78
|
+
const typedData = {
|
|
79
|
+
domain: sign.domain,
|
|
80
|
+
types: {
|
|
81
|
+
...sign.types,
|
|
82
|
+
EIP712Domain: deriveEIP712DomainType(sign.domain),
|
|
83
|
+
},
|
|
84
|
+
primaryType: sign.primaryType,
|
|
85
|
+
message: sign.value,
|
|
86
|
+
};
|
|
87
|
+
log('Signing authorize (nonce-mapping)', { domain: sign.domain });
|
|
88
|
+
const signature = await messenger.call('KeyringController:signTypedMessage', {
|
|
89
|
+
from,
|
|
90
|
+
data: JSON.stringify(typedData),
|
|
91
|
+
}, keyring_controller_1.SignTypedDataVersion.V4);
|
|
92
|
+
log('Posting authorize signature to Relay');
|
|
93
|
+
const authorizeUrl = `${constants_1.RELAY_AUTHORIZE_URL}?signature=${signature}`;
|
|
94
|
+
try {
|
|
95
|
+
const response = await (0, controller_utils_1.successfulFetch)(authorizeUrl, {
|
|
96
|
+
method: post.method,
|
|
97
|
+
headers: { 'Content-Type': 'application/json' },
|
|
98
|
+
body: JSON.stringify(post.body),
|
|
99
|
+
});
|
|
100
|
+
const result = await response.json();
|
|
101
|
+
log('Authorize response', result);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
throw new Error(`HyperLiquid authorize failed: ${error.message}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Execute the deposit step: sign HyperLiquid sendAsset and POST to HL exchange.
|
|
109
|
+
*
|
|
110
|
+
* The signature data must be constructed from the step's eip712Types and action
|
|
111
|
+
* parameters, following the Relay HyperLiquid integration spec.
|
|
112
|
+
*
|
|
113
|
+
* @param step - The deposit step from the Relay quote.
|
|
114
|
+
* @param from - User's account address.
|
|
115
|
+
* @param messenger - Controller messenger for signing.
|
|
116
|
+
*/
|
|
117
|
+
async function executeDepositStep(step, from, messenger) {
|
|
118
|
+
const items = step.items;
|
|
119
|
+
if (items.length !== 1) {
|
|
120
|
+
throw new Error(`Expected exactly 1 deposit item, got ${items.length}`);
|
|
121
|
+
}
|
|
122
|
+
const item = items[0];
|
|
123
|
+
if (!item) {
|
|
124
|
+
throw new Error('Deposit step has no items');
|
|
125
|
+
}
|
|
126
|
+
const { data } = item;
|
|
127
|
+
const action = data.action;
|
|
128
|
+
const nonce = data.nonce;
|
|
129
|
+
const eip712Types = data.eip712Types;
|
|
130
|
+
const eip712PrimaryType = data.eip712PrimaryType;
|
|
131
|
+
// HyperLiquid's EIP-712 signing spec requires Arbitrum's chain ID in the
|
|
132
|
+
// domain and message. This does not affect which chain the withdrawal
|
|
133
|
+
// targets — the destination chain is determined by the Relay quote.
|
|
134
|
+
const chainId = Number(constants_2.CHAIN_ID_ARBITRUM);
|
|
135
|
+
const domain = {
|
|
136
|
+
name: 'HyperliquidSignTransaction',
|
|
137
|
+
version: '1',
|
|
138
|
+
chainId,
|
|
139
|
+
verifyingContract: '0x0000000000000000000000000000000000000000',
|
|
140
|
+
};
|
|
141
|
+
const signatureData = {
|
|
142
|
+
domain,
|
|
143
|
+
types: {
|
|
144
|
+
...eip712Types,
|
|
145
|
+
EIP712Domain: deriveEIP712DomainType(domain),
|
|
146
|
+
},
|
|
147
|
+
primaryType: eip712PrimaryType,
|
|
148
|
+
message: {
|
|
149
|
+
...action.parameters,
|
|
150
|
+
type: action.type,
|
|
151
|
+
signatureChainId: `0x${chainId.toString(16)}`,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
log('Signing HyperLiquid deposit (sendAsset)', {
|
|
155
|
+
nonce,
|
|
156
|
+
action: action.type,
|
|
157
|
+
});
|
|
158
|
+
const signature = await messenger.call('KeyringController:signTypedMessage', {
|
|
159
|
+
from,
|
|
160
|
+
data: JSON.stringify(signatureData),
|
|
161
|
+
}, keyring_controller_1.SignTypedDataVersion.V4);
|
|
162
|
+
// eslint-disable-next-line id-length
|
|
163
|
+
const r = signature.slice(0, 66);
|
|
164
|
+
// eslint-disable-next-line id-length
|
|
165
|
+
const s = `0x${signature.slice(66, 130)}`;
|
|
166
|
+
// eslint-disable-next-line id-length
|
|
167
|
+
const v = parseInt(signature.slice(130, 132), 16);
|
|
168
|
+
log('Posting deposit to HyperLiquid exchange');
|
|
169
|
+
let result;
|
|
170
|
+
try {
|
|
171
|
+
const response = await (0, controller_utils_1.successfulFetch)(constants_1.HYPERLIQUID_EXCHANGE_URL, {
|
|
172
|
+
method: 'POST',
|
|
173
|
+
headers: { 'Content-Type': 'application/json' },
|
|
174
|
+
body: JSON.stringify({
|
|
175
|
+
action: {
|
|
176
|
+
...action.parameters,
|
|
177
|
+
type: action.type,
|
|
178
|
+
signatureChainId: `0x${chainId.toString(16)}`,
|
|
179
|
+
},
|
|
180
|
+
nonce,
|
|
181
|
+
signature: { r, s, v },
|
|
182
|
+
}),
|
|
183
|
+
});
|
|
184
|
+
result = await response.json();
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
throw new Error(`HyperLiquid deposit failed: ${error.message}`);
|
|
188
|
+
}
|
|
189
|
+
if (result?.status !== 'ok') {
|
|
190
|
+
throw new Error(`HyperLiquid deposit failed: ${JSON.stringify(result)}`);
|
|
191
|
+
}
|
|
192
|
+
log('HyperLiquid deposit response', result);
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=hyperliquid-withdraw.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperliquid-withdraw.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/hyperliquid-withdraw.ts"],"names":[],"mappings":";;;AAAA,iEAA6D;AAC7D,qEAAoE;AAEpE,2CAAqD;AAErD,+CAA4E;AAE5E,mDAAoD;AACpD,6CAA6C;AAM7C,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,sBAAsB,CAAC,CAAC;AAItE,MAAM,gBAAgB,GAAsC;IAC1D,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;IACtC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC5C,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IAC7C,iBAAiB,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE;IACjE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE;CACxC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACI,KAAK,UAAU,yBAAyB,CAC7C,KAAsC,EACtC,IAAS,EACT,SAA4C;IAE5C,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC;IAEjC,GAAG,CAAC,iCAAiC,EAAE;QACrC,SAAS,EAAE,KAAK,CAAC,MAAM;QACvB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;KACtC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAC9B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,EAAE,KAAK,WAAW,CAC7B,CAAC;IAEpC,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;IAEhE,IAAI,CAAC,aAAa,IAAI,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,yEAAyE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtI,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,MAAM,oBAAoB,CAAC,aAAa,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAE3D,0EAA0E;IAC1E,MAAM,kBAAkB,CAAC,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAEvD,GAAG,CAAC,+CAA+C,CAAC,CAAC;AACvD,CAAC;AA/BD,8DA+BC;AAED;;;;;;;GAOG;AACH,SAAS,sBAAsB,CAC7B,MAA+B;IAE/B,OAAO,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC;SACjC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,MAAM,CAAC;SAC9B,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,oBAAoB,CACjC,IAAwB,EACxB,IAAS,EACT,SAA4C;IAE5C,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,0CAA0C,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAC9D,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;IAEjC,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE;YACL,GAAG,IAAI,CAAC,KAAK;YACb,YAAY,EAAE,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC;SAClD;QACD,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,OAAO,EAAE,IAAI,CAAC,KAAK;KACpB,CAAC;IAEF,GAAG,CAAC,mCAAmC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAElE,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,IAAI,CACpC,oCAAoC,EACpC;QACE,IAAI;QACJ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;KAChC,EACD,yCAAoB,CAAC,EAAE,CACxB,CAAC;IAEF,GAAG,CAAC,sCAAsC,CAAC,CAAC;IAE5C,MAAM,YAAY,GAAG,GAAG,+BAAmB,cAAc,SAAS,EAAE,CAAC;IAErE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAA,kCAAe,EAAC,YAAY,EAAE;YACnD,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;SAChC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAErC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,iCAAkC,KAAe,CAAC,OAAO,EAAE,CAC5D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,kBAAkB,CAC/B,IAAyE,EACzE,IAAS,EACT,SAA4C;IAE5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAA4C,CAAC;IAEhE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,wCAAwC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAEtB,MAAM,MAAM,GAAG,IAAI,CAAC,MAGnB,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAe,CAAC;IACnC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAsC,CAAC;IAChE,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAA2B,CAAC;IAE3D,yEAAyE;IACzE,sEAAsE;IACtE,oEAAoE;IACpE,MAAM,OAAO,GAAG,MAAM,CAAC,6BAAiB,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,4BAA4B;QAClC,OAAO,EAAE,GAAG;QACZ,OAAO;QACP,iBAAiB,EAAE,4CAA4C;KAChE,CAAC;IAEF,MAAM,aAAa,GAAG;QACpB,MAAM;QACN,KAAK,EAAE;YACL,GAAG,WAAW;YACd,YAAY,EAAE,sBAAsB,CAAC,MAAM,CAAC;SAC7C;QACD,WAAW,EAAE,iBAAiB;QAC9B,OAAO,EAAE;YACP,GAAG,MAAM,CAAC,UAAU;YACpB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,gBAAgB,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;SAC9C;KACF,CAAC;IAEF,GAAG,CAAC,yCAAyC,EAAE;QAC7C,KAAK;QACL,MAAM,EAAE,MAAM,CAAC,IAAI;KACpB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,IAAI,CACpC,oCAAoC,EACpC;QACE,IAAI;QACJ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;KACpC,EACD,yCAAoB,CAAC,EAAE,CACxB,CAAC;IAEF,qCAAqC;IACrC,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjC,qCAAqC;IACrC,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;IAC1C,qCAAqC;IACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IAElD,GAAG,CAAC,yCAAyC,CAAC,CAAC;IAE/C,IAAI,MAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAA,kCAAe,EAAC,oCAAwB,EAAE;YAC/D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,MAAM,EAAE;oBACN,GAAG,MAAM,CAAC,UAAU;oBACpB,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,gBAAgB,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;iBAC9C;gBACD,KAAK;gBACL,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;aACvB,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+BAAgC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,IAAK,MAA8B,EAAE,MAAM,KAAK,IAAI,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,GAAG,CAAC,8BAA8B,EAAE,MAAM,CAAC,CAAC;AAC9C,CAAC","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\nimport { SignTypedDataVersion } from '@metamask/keyring-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { RELAY_AUTHORIZE_URL, HYPERLIQUID_EXCHANGE_URL } from './constants';\nimport type { RelayQuote, RelaySignatureStep } from './types';\nimport { CHAIN_ID_ARBITRUM } from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\n\nconst log = createModuleLogger(projectLogger, 'hyperliquid-withdraw');\n\ntype EIP712DomainField = { name: string; type: string };\n\nconst DOMAIN_FIELD_MAP: Record<string, EIP712DomainField> = {\n name: { name: 'name', type: 'string' },\n version: { name: 'version', type: 'string' },\n chainId: { name: 'chainId', type: 'uint256' },\n verifyingContract: { name: 'verifyingContract', type: 'address' },\n salt: { name: 'salt', type: 'bytes32' },\n};\n\n/**\n * Submit a HyperLiquid 2-step withdrawal via Relay.\n *\n * Step 1 (authorize): Sign an EIP-712 nonce-mapping message, POST to Relay /authorize.\n * Step 2 (deposit): Sign an EIP-712 HyperliquidSignTransaction, POST to HyperLiquid exchange.\n *\n * Both signatures are silent (no user confirmation). Both steps share the same nonce\n * from the Relay quote response.\n *\n * @param quote - Relay quote containing the 2-step flow.\n * @param from - User's account address.\n * @param messenger - Controller messenger (for KeyringController:signTypedMessage).\n */\nexport async function submitHyperliquidWithdraw(\n quote: TransactionPayQuote<RelayQuote>,\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { steps } = quote.original;\n\n log('Starting HyperLiquid withdrawal', {\n stepCount: steps.length,\n stepIds: steps.map((step) => step.id),\n });\n\n const authorizeStep = steps.find(\n (step) => step.kind === 'signature' && step.id === 'authorize',\n ) as RelaySignatureStep | undefined;\n\n const depositStep = steps.find((step) => step.id === 'deposit');\n\n if (!authorizeStep || !depositStep) {\n throw new Error(\n `Expected authorize and deposit steps for HyperLiquid withdrawal, got: ${steps.map((step) => `${step.id}(${step.kind})`).join(', ')}`,\n );\n }\n\n // Step 1: Authorize (nonce-mapping signature -> POST to Relay /authorize)\n await executeAuthorizeStep(authorizeStep, from, messenger);\n\n // Step 2: Deposit (HyperLiquid sendAsset -> POST to HyperLiquid exchange)\n await executeDepositStep(depositStep, from, messenger);\n\n log('HyperLiquid withdrawal submitted successfully');\n}\n\n/**\n * Derive the EIP712Domain type array from a domain object.\n * eth-sig-util defaults to EIP712Domain: [] when absent, breaking\n * the domain separator hash. This ensures it matches ethers.js behavior.\n *\n * @param domain - The EIP-712 domain object.\n * @returns The EIP712Domain type array in canonical order.\n */\nfunction deriveEIP712DomainType(\n domain: Record<string, unknown>,\n): EIP712DomainField[] {\n return Object.keys(DOMAIN_FIELD_MAP)\n .filter((key) => key in domain)\n .map((key) => DOMAIN_FIELD_MAP[key]);\n}\n\n/**\n * Execute the authorize step: sign EIP-712 nonce-mapping and POST to Relay.\n *\n * @param step - The authorize signature step from the Relay quote.\n * @param from - User's account address.\n * @param messenger - Controller messenger for signing.\n */\nasync function executeAuthorizeStep(\n step: RelaySignatureStep,\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n if (step.items.length !== 1) {\n throw new Error(\n `Expected exactly 1 authorize item, got ${step.items.length}`,\n );\n }\n\n const item = step.items[0];\n if (!item) {\n throw new Error('Authorize step has no items');\n }\n\n const { sign, post } = item.data;\n\n const typedData = {\n domain: sign.domain,\n types: {\n ...sign.types,\n EIP712Domain: deriveEIP712DomainType(sign.domain),\n },\n primaryType: sign.primaryType,\n message: sign.value,\n };\n\n log('Signing authorize (nonce-mapping)', { domain: sign.domain });\n\n const signature = await messenger.call(\n 'KeyringController:signTypedMessage',\n {\n from,\n data: JSON.stringify(typedData),\n },\n SignTypedDataVersion.V4,\n );\n\n log('Posting authorize signature to Relay');\n\n const authorizeUrl = `${RELAY_AUTHORIZE_URL}?signature=${signature}`;\n\n try {\n const response = await successfulFetch(authorizeUrl, {\n method: post.method,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(post.body),\n });\n\n const result = await response.json();\n\n log('Authorize response', result);\n } catch (error) {\n throw new Error(\n `HyperLiquid authorize failed: ${(error as Error).message}`,\n );\n }\n}\n\n/**\n * Execute the deposit step: sign HyperLiquid sendAsset and POST to HL exchange.\n *\n * The signature data must be constructed from the step's eip712Types and action\n * parameters, following the Relay HyperLiquid integration spec.\n *\n * @param step - The deposit step from the Relay quote.\n * @param from - User's account address.\n * @param messenger - Controller messenger for signing.\n */\nasync function executeDepositStep(\n step: RelaySignatureStep | { id: string; kind: string; items: unknown[] },\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const items = step.items as { data: Record<string, unknown> }[];\n\n if (items.length !== 1) {\n throw new Error(`Expected exactly 1 deposit item, got ${items.length}`);\n }\n\n const item = items[0];\n if (!item) {\n throw new Error('Deposit step has no items');\n }\n\n const { data } = item;\n\n const action = data.action as {\n type: string;\n parameters: Record<string, unknown>;\n };\n const nonce = data.nonce as number;\n const eip712Types = data.eip712Types as Record<string, unknown>;\n const eip712PrimaryType = data.eip712PrimaryType as string;\n\n // HyperLiquid's EIP-712 signing spec requires Arbitrum's chain ID in the\n // domain and message. This does not affect which chain the withdrawal\n // targets — the destination chain is determined by the Relay quote.\n const chainId = Number(CHAIN_ID_ARBITRUM);\n\n const domain = {\n name: 'HyperliquidSignTransaction',\n version: '1',\n chainId,\n verifyingContract: '0x0000000000000000000000000000000000000000',\n };\n\n const signatureData = {\n domain,\n types: {\n ...eip712Types,\n EIP712Domain: deriveEIP712DomainType(domain),\n },\n primaryType: eip712PrimaryType,\n message: {\n ...action.parameters,\n type: action.type,\n signatureChainId: `0x${chainId.toString(16)}`,\n },\n };\n\n log('Signing HyperLiquid deposit (sendAsset)', {\n nonce,\n action: action.type,\n });\n\n const signature = await messenger.call(\n 'KeyringController:signTypedMessage',\n {\n from,\n data: JSON.stringify(signatureData),\n },\n SignTypedDataVersion.V4,\n );\n\n // eslint-disable-next-line id-length\n const r = signature.slice(0, 66);\n // eslint-disable-next-line id-length\n const s = `0x${signature.slice(66, 130)}`;\n // eslint-disable-next-line id-length\n const v = parseInt(signature.slice(130, 132), 16);\n\n log('Posting deposit to HyperLiquid exchange');\n\n let result: unknown;\n\n try {\n const response = await successfulFetch(HYPERLIQUID_EXCHANGE_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n action: {\n ...action.parameters,\n type: action.type,\n signatureChainId: `0x${chainId.toString(16)}`,\n },\n nonce,\n signature: { r, s, v },\n }),\n });\n\n result = await response.json();\n } catch (error) {\n throw new Error(`HyperLiquid deposit failed: ${(error as Error).message}`);\n }\n\n if ((result as { status?: string })?.status !== 'ok') {\n throw new Error(`HyperLiquid deposit failed: ${JSON.stringify(result)}`);\n }\n\n log('HyperLiquid deposit response', result);\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Hex } from "@metamask/utils";
|
|
2
|
+
import type { RelayQuote } from "./types.cjs";
|
|
3
|
+
import type { TransactionPayControllerMessenger, TransactionPayQuote } from "../../types.cjs";
|
|
4
|
+
/**
|
|
5
|
+
* Submit a HyperLiquid 2-step withdrawal via Relay.
|
|
6
|
+
*
|
|
7
|
+
* Step 1 (authorize): Sign an EIP-712 nonce-mapping message, POST to Relay /authorize.
|
|
8
|
+
* Step 2 (deposit): Sign an EIP-712 HyperliquidSignTransaction, POST to HyperLiquid exchange.
|
|
9
|
+
*
|
|
10
|
+
* Both signatures are silent (no user confirmation). Both steps share the same nonce
|
|
11
|
+
* from the Relay quote response.
|
|
12
|
+
*
|
|
13
|
+
* @param quote - Relay quote containing the 2-step flow.
|
|
14
|
+
* @param from - User's account address.
|
|
15
|
+
* @param messenger - Controller messenger (for KeyringController:signTypedMessage).
|
|
16
|
+
*/
|
|
17
|
+
export declare function submitHyperliquidWithdraw(quote: TransactionPayQuote<RelayQuote>, from: Hex, messenger: TransactionPayControllerMessenger): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=hyperliquid-withdraw.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperliquid-withdraw.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/hyperliquid-withdraw.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAI3C,OAAO,KAAK,EAAE,UAAU,EAAsB,oBAAgB;AAG9D,OAAO,KAAK,EACV,iCAAiC,EACjC,mBAAmB,EACpB,wBAAoB;AAcrB;;;;;;;;;;;;GAYG;AACH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,EACtC,IAAI,EAAE,GAAG,EACT,SAAS,EAAE,iCAAiC,GAC3C,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Hex } from "@metamask/utils";
|
|
2
|
+
import type { RelayQuote } from "./types.mjs";
|
|
3
|
+
import type { TransactionPayControllerMessenger, TransactionPayQuote } from "../../types.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* Submit a HyperLiquid 2-step withdrawal via Relay.
|
|
6
|
+
*
|
|
7
|
+
* Step 1 (authorize): Sign an EIP-712 nonce-mapping message, POST to Relay /authorize.
|
|
8
|
+
* Step 2 (deposit): Sign an EIP-712 HyperliquidSignTransaction, POST to HyperLiquid exchange.
|
|
9
|
+
*
|
|
10
|
+
* Both signatures are silent (no user confirmation). Both steps share the same nonce
|
|
11
|
+
* from the Relay quote response.
|
|
12
|
+
*
|
|
13
|
+
* @param quote - Relay quote containing the 2-step flow.
|
|
14
|
+
* @param from - User's account address.
|
|
15
|
+
* @param messenger - Controller messenger (for KeyringController:signTypedMessage).
|
|
16
|
+
*/
|
|
17
|
+
export declare function submitHyperliquidWithdraw(quote: TransactionPayQuote<RelayQuote>, from: Hex, messenger: TransactionPayControllerMessenger): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=hyperliquid-withdraw.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperliquid-withdraw.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/hyperliquid-withdraw.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAI3C,OAAO,KAAK,EAAE,UAAU,EAAsB,oBAAgB;AAG9D,OAAO,KAAK,EACV,iCAAiC,EACjC,mBAAmB,EACpB,wBAAoB;AAcrB;;;;;;;;;;;;GAYG;AACH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,EACtC,IAAI,EAAE,GAAG,EACT,SAAS,EAAE,iCAAiC,GAC3C,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { successfulFetch } from "@metamask/controller-utils";
|
|
2
|
+
import { SignTypedDataVersion } from "@metamask/keyring-controller";
|
|
3
|
+
import { createModuleLogger } from "@metamask/utils";
|
|
4
|
+
import { RELAY_AUTHORIZE_URL, HYPERLIQUID_EXCHANGE_URL } from "./constants.mjs";
|
|
5
|
+
import { CHAIN_ID_ARBITRUM } from "../../constants.mjs";
|
|
6
|
+
import { projectLogger } from "../../logger.mjs";
|
|
7
|
+
const log = createModuleLogger(projectLogger, 'hyperliquid-withdraw');
|
|
8
|
+
const DOMAIN_FIELD_MAP = {
|
|
9
|
+
name: { name: 'name', type: 'string' },
|
|
10
|
+
version: { name: 'version', type: 'string' },
|
|
11
|
+
chainId: { name: 'chainId', type: 'uint256' },
|
|
12
|
+
verifyingContract: { name: 'verifyingContract', type: 'address' },
|
|
13
|
+
salt: { name: 'salt', type: 'bytes32' },
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Submit a HyperLiquid 2-step withdrawal via Relay.
|
|
17
|
+
*
|
|
18
|
+
* Step 1 (authorize): Sign an EIP-712 nonce-mapping message, POST to Relay /authorize.
|
|
19
|
+
* Step 2 (deposit): Sign an EIP-712 HyperliquidSignTransaction, POST to HyperLiquid exchange.
|
|
20
|
+
*
|
|
21
|
+
* Both signatures are silent (no user confirmation). Both steps share the same nonce
|
|
22
|
+
* from the Relay quote response.
|
|
23
|
+
*
|
|
24
|
+
* @param quote - Relay quote containing the 2-step flow.
|
|
25
|
+
* @param from - User's account address.
|
|
26
|
+
* @param messenger - Controller messenger (for KeyringController:signTypedMessage).
|
|
27
|
+
*/
|
|
28
|
+
export async function submitHyperliquidWithdraw(quote, from, messenger) {
|
|
29
|
+
const { steps } = quote.original;
|
|
30
|
+
log('Starting HyperLiquid withdrawal', {
|
|
31
|
+
stepCount: steps.length,
|
|
32
|
+
stepIds: steps.map((step) => step.id),
|
|
33
|
+
});
|
|
34
|
+
const authorizeStep = steps.find((step) => step.kind === 'signature' && step.id === 'authorize');
|
|
35
|
+
const depositStep = steps.find((step) => step.id === 'deposit');
|
|
36
|
+
if (!authorizeStep || !depositStep) {
|
|
37
|
+
throw new Error(`Expected authorize and deposit steps for HyperLiquid withdrawal, got: ${steps.map((step) => `${step.id}(${step.kind})`).join(', ')}`);
|
|
38
|
+
}
|
|
39
|
+
// Step 1: Authorize (nonce-mapping signature -> POST to Relay /authorize)
|
|
40
|
+
await executeAuthorizeStep(authorizeStep, from, messenger);
|
|
41
|
+
// Step 2: Deposit (HyperLiquid sendAsset -> POST to HyperLiquid exchange)
|
|
42
|
+
await executeDepositStep(depositStep, from, messenger);
|
|
43
|
+
log('HyperLiquid withdrawal submitted successfully');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Derive the EIP712Domain type array from a domain object.
|
|
47
|
+
* eth-sig-util defaults to EIP712Domain: [] when absent, breaking
|
|
48
|
+
* the domain separator hash. This ensures it matches ethers.js behavior.
|
|
49
|
+
*
|
|
50
|
+
* @param domain - The EIP-712 domain object.
|
|
51
|
+
* @returns The EIP712Domain type array in canonical order.
|
|
52
|
+
*/
|
|
53
|
+
function deriveEIP712DomainType(domain) {
|
|
54
|
+
return Object.keys(DOMAIN_FIELD_MAP)
|
|
55
|
+
.filter((key) => key in domain)
|
|
56
|
+
.map((key) => DOMAIN_FIELD_MAP[key]);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Execute the authorize step: sign EIP-712 nonce-mapping and POST to Relay.
|
|
60
|
+
*
|
|
61
|
+
* @param step - The authorize signature step from the Relay quote.
|
|
62
|
+
* @param from - User's account address.
|
|
63
|
+
* @param messenger - Controller messenger for signing.
|
|
64
|
+
*/
|
|
65
|
+
async function executeAuthorizeStep(step, from, messenger) {
|
|
66
|
+
if (step.items.length !== 1) {
|
|
67
|
+
throw new Error(`Expected exactly 1 authorize item, got ${step.items.length}`);
|
|
68
|
+
}
|
|
69
|
+
const item = step.items[0];
|
|
70
|
+
if (!item) {
|
|
71
|
+
throw new Error('Authorize step has no items');
|
|
72
|
+
}
|
|
73
|
+
const { sign, post } = item.data;
|
|
74
|
+
const typedData = {
|
|
75
|
+
domain: sign.domain,
|
|
76
|
+
types: {
|
|
77
|
+
...sign.types,
|
|
78
|
+
EIP712Domain: deriveEIP712DomainType(sign.domain),
|
|
79
|
+
},
|
|
80
|
+
primaryType: sign.primaryType,
|
|
81
|
+
message: sign.value,
|
|
82
|
+
};
|
|
83
|
+
log('Signing authorize (nonce-mapping)', { domain: sign.domain });
|
|
84
|
+
const signature = await messenger.call('KeyringController:signTypedMessage', {
|
|
85
|
+
from,
|
|
86
|
+
data: JSON.stringify(typedData),
|
|
87
|
+
}, SignTypedDataVersion.V4);
|
|
88
|
+
log('Posting authorize signature to Relay');
|
|
89
|
+
const authorizeUrl = `${RELAY_AUTHORIZE_URL}?signature=${signature}`;
|
|
90
|
+
try {
|
|
91
|
+
const response = await successfulFetch(authorizeUrl, {
|
|
92
|
+
method: post.method,
|
|
93
|
+
headers: { 'Content-Type': 'application/json' },
|
|
94
|
+
body: JSON.stringify(post.body),
|
|
95
|
+
});
|
|
96
|
+
const result = await response.json();
|
|
97
|
+
log('Authorize response', result);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
throw new Error(`HyperLiquid authorize failed: ${error.message}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Execute the deposit step: sign HyperLiquid sendAsset and POST to HL exchange.
|
|
105
|
+
*
|
|
106
|
+
* The signature data must be constructed from the step's eip712Types and action
|
|
107
|
+
* parameters, following the Relay HyperLiquid integration spec.
|
|
108
|
+
*
|
|
109
|
+
* @param step - The deposit step from the Relay quote.
|
|
110
|
+
* @param from - User's account address.
|
|
111
|
+
* @param messenger - Controller messenger for signing.
|
|
112
|
+
*/
|
|
113
|
+
async function executeDepositStep(step, from, messenger) {
|
|
114
|
+
const items = step.items;
|
|
115
|
+
if (items.length !== 1) {
|
|
116
|
+
throw new Error(`Expected exactly 1 deposit item, got ${items.length}`);
|
|
117
|
+
}
|
|
118
|
+
const item = items[0];
|
|
119
|
+
if (!item) {
|
|
120
|
+
throw new Error('Deposit step has no items');
|
|
121
|
+
}
|
|
122
|
+
const { data } = item;
|
|
123
|
+
const action = data.action;
|
|
124
|
+
const nonce = data.nonce;
|
|
125
|
+
const eip712Types = data.eip712Types;
|
|
126
|
+
const eip712PrimaryType = data.eip712PrimaryType;
|
|
127
|
+
// HyperLiquid's EIP-712 signing spec requires Arbitrum's chain ID in the
|
|
128
|
+
// domain and message. This does not affect which chain the withdrawal
|
|
129
|
+
// targets — the destination chain is determined by the Relay quote.
|
|
130
|
+
const chainId = Number(CHAIN_ID_ARBITRUM);
|
|
131
|
+
const domain = {
|
|
132
|
+
name: 'HyperliquidSignTransaction',
|
|
133
|
+
version: '1',
|
|
134
|
+
chainId,
|
|
135
|
+
verifyingContract: '0x0000000000000000000000000000000000000000',
|
|
136
|
+
};
|
|
137
|
+
const signatureData = {
|
|
138
|
+
domain,
|
|
139
|
+
types: {
|
|
140
|
+
...eip712Types,
|
|
141
|
+
EIP712Domain: deriveEIP712DomainType(domain),
|
|
142
|
+
},
|
|
143
|
+
primaryType: eip712PrimaryType,
|
|
144
|
+
message: {
|
|
145
|
+
...action.parameters,
|
|
146
|
+
type: action.type,
|
|
147
|
+
signatureChainId: `0x${chainId.toString(16)}`,
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
log('Signing HyperLiquid deposit (sendAsset)', {
|
|
151
|
+
nonce,
|
|
152
|
+
action: action.type,
|
|
153
|
+
});
|
|
154
|
+
const signature = await messenger.call('KeyringController:signTypedMessage', {
|
|
155
|
+
from,
|
|
156
|
+
data: JSON.stringify(signatureData),
|
|
157
|
+
}, SignTypedDataVersion.V4);
|
|
158
|
+
// eslint-disable-next-line id-length
|
|
159
|
+
const r = signature.slice(0, 66);
|
|
160
|
+
// eslint-disable-next-line id-length
|
|
161
|
+
const s = `0x${signature.slice(66, 130)}`;
|
|
162
|
+
// eslint-disable-next-line id-length
|
|
163
|
+
const v = parseInt(signature.slice(130, 132), 16);
|
|
164
|
+
log('Posting deposit to HyperLiquid exchange');
|
|
165
|
+
let result;
|
|
166
|
+
try {
|
|
167
|
+
const response = await successfulFetch(HYPERLIQUID_EXCHANGE_URL, {
|
|
168
|
+
method: 'POST',
|
|
169
|
+
headers: { 'Content-Type': 'application/json' },
|
|
170
|
+
body: JSON.stringify({
|
|
171
|
+
action: {
|
|
172
|
+
...action.parameters,
|
|
173
|
+
type: action.type,
|
|
174
|
+
signatureChainId: `0x${chainId.toString(16)}`,
|
|
175
|
+
},
|
|
176
|
+
nonce,
|
|
177
|
+
signature: { r, s, v },
|
|
178
|
+
}),
|
|
179
|
+
});
|
|
180
|
+
result = await response.json();
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
throw new Error(`HyperLiquid deposit failed: ${error.message}`);
|
|
184
|
+
}
|
|
185
|
+
if (result?.status !== 'ok') {
|
|
186
|
+
throw new Error(`HyperLiquid deposit failed: ${JSON.stringify(result)}`);
|
|
187
|
+
}
|
|
188
|
+
log('HyperLiquid deposit response', result);
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=hyperliquid-withdraw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyperliquid-withdraw.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/hyperliquid-withdraw.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\nimport { SignTypedDataVersion } from '@metamask/keyring-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { RELAY_AUTHORIZE_URL, HYPERLIQUID_EXCHANGE_URL } from './constants';\nimport type { RelayQuote, RelaySignatureStep } from './types';\nimport { CHAIN_ID_ARBITRUM } from '../../constants';\nimport { projectLogger } from '../../logger';\nimport type {\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\n\nconst log = createModuleLogger(projectLogger, 'hyperliquid-withdraw');\n\ntype EIP712DomainField = { name: string; type: string };\n\nconst DOMAIN_FIELD_MAP: Record<string, EIP712DomainField> = {\n name: { name: 'name', type: 'string' },\n version: { name: 'version', type: 'string' },\n chainId: { name: 'chainId', type: 'uint256' },\n verifyingContract: { name: 'verifyingContract', type: 'address' },\n salt: { name: 'salt', type: 'bytes32' },\n};\n\n/**\n * Submit a HyperLiquid 2-step withdrawal via Relay.\n *\n * Step 1 (authorize): Sign an EIP-712 nonce-mapping message, POST to Relay /authorize.\n * Step 2 (deposit): Sign an EIP-712 HyperliquidSignTransaction, POST to HyperLiquid exchange.\n *\n * Both signatures are silent (no user confirmation). Both steps share the same nonce\n * from the Relay quote response.\n *\n * @param quote - Relay quote containing the 2-step flow.\n * @param from - User's account address.\n * @param messenger - Controller messenger (for KeyringController:signTypedMessage).\n */\nexport async function submitHyperliquidWithdraw(\n quote: TransactionPayQuote<RelayQuote>,\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { steps } = quote.original;\n\n log('Starting HyperLiquid withdrawal', {\n stepCount: steps.length,\n stepIds: steps.map((step) => step.id),\n });\n\n const authorizeStep = steps.find(\n (step) => step.kind === 'signature' && step.id === 'authorize',\n ) as RelaySignatureStep | undefined;\n\n const depositStep = steps.find((step) => step.id === 'deposit');\n\n if (!authorizeStep || !depositStep) {\n throw new Error(\n `Expected authorize and deposit steps for HyperLiquid withdrawal, got: ${steps.map((step) => `${step.id}(${step.kind})`).join(', ')}`,\n );\n }\n\n // Step 1: Authorize (nonce-mapping signature -> POST to Relay /authorize)\n await executeAuthorizeStep(authorizeStep, from, messenger);\n\n // Step 2: Deposit (HyperLiquid sendAsset -> POST to HyperLiquid exchange)\n await executeDepositStep(depositStep, from, messenger);\n\n log('HyperLiquid withdrawal submitted successfully');\n}\n\n/**\n * Derive the EIP712Domain type array from a domain object.\n * eth-sig-util defaults to EIP712Domain: [] when absent, breaking\n * the domain separator hash. This ensures it matches ethers.js behavior.\n *\n * @param domain - The EIP-712 domain object.\n * @returns The EIP712Domain type array in canonical order.\n */\nfunction deriveEIP712DomainType(\n domain: Record<string, unknown>,\n): EIP712DomainField[] {\n return Object.keys(DOMAIN_FIELD_MAP)\n .filter((key) => key in domain)\n .map((key) => DOMAIN_FIELD_MAP[key]);\n}\n\n/**\n * Execute the authorize step: sign EIP-712 nonce-mapping and POST to Relay.\n *\n * @param step - The authorize signature step from the Relay quote.\n * @param from - User's account address.\n * @param messenger - Controller messenger for signing.\n */\nasync function executeAuthorizeStep(\n step: RelaySignatureStep,\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n if (step.items.length !== 1) {\n throw new Error(\n `Expected exactly 1 authorize item, got ${step.items.length}`,\n );\n }\n\n const item = step.items[0];\n if (!item) {\n throw new Error('Authorize step has no items');\n }\n\n const { sign, post } = item.data;\n\n const typedData = {\n domain: sign.domain,\n types: {\n ...sign.types,\n EIP712Domain: deriveEIP712DomainType(sign.domain),\n },\n primaryType: sign.primaryType,\n message: sign.value,\n };\n\n log('Signing authorize (nonce-mapping)', { domain: sign.domain });\n\n const signature = await messenger.call(\n 'KeyringController:signTypedMessage',\n {\n from,\n data: JSON.stringify(typedData),\n },\n SignTypedDataVersion.V4,\n );\n\n log('Posting authorize signature to Relay');\n\n const authorizeUrl = `${RELAY_AUTHORIZE_URL}?signature=${signature}`;\n\n try {\n const response = await successfulFetch(authorizeUrl, {\n method: post.method,\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(post.body),\n });\n\n const result = await response.json();\n\n log('Authorize response', result);\n } catch (error) {\n throw new Error(\n `HyperLiquid authorize failed: ${(error as Error).message}`,\n );\n }\n}\n\n/**\n * Execute the deposit step: sign HyperLiquid sendAsset and POST to HL exchange.\n *\n * The signature data must be constructed from the step's eip712Types and action\n * parameters, following the Relay HyperLiquid integration spec.\n *\n * @param step - The deposit step from the Relay quote.\n * @param from - User's account address.\n * @param messenger - Controller messenger for signing.\n */\nasync function executeDepositStep(\n step: RelaySignatureStep | { id: string; kind: string; items: unknown[] },\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const items = step.items as { data: Record<string, unknown> }[];\n\n if (items.length !== 1) {\n throw new Error(`Expected exactly 1 deposit item, got ${items.length}`);\n }\n\n const item = items[0];\n if (!item) {\n throw new Error('Deposit step has no items');\n }\n\n const { data } = item;\n\n const action = data.action as {\n type: string;\n parameters: Record<string, unknown>;\n };\n const nonce = data.nonce as number;\n const eip712Types = data.eip712Types as Record<string, unknown>;\n const eip712PrimaryType = data.eip712PrimaryType as string;\n\n // HyperLiquid's EIP-712 signing spec requires Arbitrum's chain ID in the\n // domain and message. This does not affect which chain the withdrawal\n // targets — the destination chain is determined by the Relay quote.\n const chainId = Number(CHAIN_ID_ARBITRUM);\n\n const domain = {\n name: 'HyperliquidSignTransaction',\n version: '1',\n chainId,\n verifyingContract: '0x0000000000000000000000000000000000000000',\n };\n\n const signatureData = {\n domain,\n types: {\n ...eip712Types,\n EIP712Domain: deriveEIP712DomainType(domain),\n },\n primaryType: eip712PrimaryType,\n message: {\n ...action.parameters,\n type: action.type,\n signatureChainId: `0x${chainId.toString(16)}`,\n },\n };\n\n log('Signing HyperLiquid deposit (sendAsset)', {\n nonce,\n action: action.type,\n });\n\n const signature = await messenger.call(\n 'KeyringController:signTypedMessage',\n {\n from,\n data: JSON.stringify(signatureData),\n },\n SignTypedDataVersion.V4,\n );\n\n // eslint-disable-next-line id-length\n const r = signature.slice(0, 66);\n // eslint-disable-next-line id-length\n const s = `0x${signature.slice(66, 130)}`;\n // eslint-disable-next-line id-length\n const v = parseInt(signature.slice(130, 132), 16);\n\n log('Posting deposit to HyperLiquid exchange');\n\n let result: unknown;\n\n try {\n const response = await successfulFetch(HYPERLIQUID_EXCHANGE_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n action: {\n ...action.parameters,\n type: action.type,\n signatureChainId: `0x${chainId.toString(16)}`,\n },\n nonce,\n signature: { r, s, v },\n }),\n });\n\n result = await response.json();\n } catch (error) {\n throw new Error(`HyperLiquid deposit failed: ${(error as Error).message}`);\n }\n\n if ((result as { status?: string })?.status !== 'ok') {\n throw new Error(`HyperLiquid deposit failed: ${JSON.stringify(result)}`);\n }\n\n log('HyperLiquid deposit response', result);\n}\n"]}
|