@nktkas/hyperliquid 0.22.1 → 0.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +84 -27
  2. package/esm/mod.d.ts +1 -1
  3. package/esm/mod.d.ts.map +1 -1
  4. package/esm/src/clients/exchange.d.ts +136 -166
  5. package/esm/src/clients/exchange.d.ts.map +1 -1
  6. package/esm/src/clients/exchange.js +121 -146
  7. package/esm/src/clients/multiSign.d.ts +121 -280
  8. package/esm/src/clients/multiSign.d.ts.map +1 -1
  9. package/esm/src/clients/multiSign.js +123 -246
  10. package/esm/src/signing/_ethers.d.ts +33 -0
  11. package/esm/src/signing/_ethers.d.ts.map +1 -0
  12. package/esm/src/signing/_ethers.js +12 -0
  13. package/esm/src/signing/_private_key.d.ts +22 -0
  14. package/esm/src/signing/_private_key.d.ts.map +1 -0
  15. package/esm/src/signing/_private_key.js +124 -0
  16. package/esm/src/signing/_sorter.d.ts +154 -0
  17. package/esm/src/signing/_sorter.d.ts.map +1 -0
  18. package/esm/src/{signing.js → signing/_sorter.js} +0 -400
  19. package/esm/src/signing/_viem.d.ts +23 -0
  20. package/esm/src/signing/_viem.d.ts.map +1 -0
  21. package/esm/src/signing/_viem.js +6 -0
  22. package/esm/src/signing/_window.d.ts +23 -0
  23. package/esm/src/signing/_window.d.ts.map +1 -0
  24. package/esm/src/signing/_window.js +29 -0
  25. package/esm/src/signing/mod.d.ts +251 -0
  26. package/esm/src/signing/mod.d.ts.map +1 -0
  27. package/esm/src/signing/mod.js +352 -0
  28. package/package.json +6 -5
  29. package/script/mod.d.ts +1 -1
  30. package/script/mod.d.ts.map +1 -1
  31. package/script/src/clients/exchange.d.ts +136 -166
  32. package/script/src/clients/exchange.d.ts.map +1 -1
  33. package/script/src/clients/exchange.js +205 -230
  34. package/script/src/clients/multiSign.d.ts +121 -280
  35. package/script/src/clients/multiSign.d.ts.map +1 -1
  36. package/script/src/clients/multiSign.js +168 -291
  37. package/script/src/signing/_ethers.d.ts +33 -0
  38. package/script/src/signing/_ethers.d.ts.map +1 -0
  39. package/script/src/signing/_ethers.js +26 -0
  40. package/script/src/signing/_private_key.d.ts +22 -0
  41. package/script/src/signing/_private_key.d.ts.map +1 -0
  42. package/script/src/signing/_private_key.js +138 -0
  43. package/script/src/signing/_sorter.d.ts +154 -0
  44. package/script/src/signing/_sorter.d.ts.map +1 -0
  45. package/script/src/{signing.js → signing/_sorter.js} +1 -409
  46. package/script/src/signing/_viem.d.ts +23 -0
  47. package/script/src/signing/_viem.d.ts.map +1 -0
  48. package/script/src/signing/_viem.js +19 -0
  49. package/script/src/signing/_window.d.ts +23 -0
  50. package/script/src/signing/_window.d.ts.map +1 -0
  51. package/script/src/signing/_window.js +43 -0
  52. package/script/src/signing/mod.d.ts +251 -0
  53. package/script/src/signing/mod.d.ts.map +1 -0
  54. package/script/src/signing/mod.js +387 -0
  55. package/esm/src/signing.d.ts +0 -463
  56. package/esm/src/signing.d.ts.map +0 -1
  57. package/script/src/signing.d.ts +0 -463
  58. package/script/src/signing.d.ts.map +0 -1
@@ -0,0 +1,251 @@
1
+ /**
2
+ * This module contains functions for generating Hyperliquid transaction signatures
3
+ * and interfaces to various wallet implementations.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { signL1Action } from "@nktkas/hyperliquid/signing";
8
+ *
9
+ * const action = {
10
+ * type: "cancel",
11
+ * cancels: [{ a: 0, o: 12345 }],
12
+ * };
13
+ * const nonce = Date.now();
14
+ *
15
+ * const signature = await signL1Action({
16
+ * wallet,
17
+ * action,
18
+ * nonce,
19
+ * isTestnet: true, // Change to false for mainnet
20
+ * });
21
+ * ```
22
+ * @example
23
+ * ```ts
24
+ * import { signUserSignedAction } from "@nktkas/hyperliquid/signing";
25
+ *
26
+ * const action = {
27
+ * type: "approveAgent",
28
+ * hyperliquidChain: "Testnet", // "Mainnet" or "Testnet"
29
+ * signatureChainId: "0x66eee",
30
+ * nonce: Date.now(),
31
+ * agentAddress: "0x...",
32
+ * agentName: "Agent",
33
+ * };
34
+ *
35
+ * const signature = await signUserSignedAction({
36
+ * wallet,
37
+ * action,
38
+ * types: {
39
+ * "HyperliquidTransaction:ApproveAgent": [
40
+ * { name: "hyperliquidChain", type: "string" },
41
+ * { name: "agentAddress", type: "address" },
42
+ * { name: "agentName", type: "string" },
43
+ * { name: "nonce", type: "uint64" },
44
+ * ],
45
+ * },
46
+ * chainId: parseInt(action.signatureChainId, 16),
47
+ * });
48
+ * ```
49
+ *
50
+ * @module
51
+ */
52
+ import { type ValueMap, type ValueType } from "../../deps/jsr.io/@std/msgpack/1.0.3/encode.js";
53
+ import { type AbstractEthersSigner, type AbstractEthersV5Signer, isAbstractEthersSigner, isAbstractEthersV5Signer } from "./_ethers.js";
54
+ import { isValidPrivateKey } from "./_private_key.js";
55
+ import { type AbstractViemWalletClient, isAbstractViemWalletClient } from "./_viem.js";
56
+ import { type AbstractWindowEthereum, isAbstractWindowEthereum } from "./_window.js";
57
+ import type { Hex } from "../base.js";
58
+ export { type AbstractEthersSigner, type AbstractEthersV5Signer, type AbstractViemWalletClient, type AbstractWindowEthereum, type Hex, isAbstractEthersSigner, isAbstractEthersV5Signer, isAbstractViemWalletClient, isAbstractWindowEthereum, isValidPrivateKey, type ValueMap, type ValueType, };
59
+ export * from "./_sorter.js";
60
+ /** Abstract interface for a wallet that can sign typed data. */
61
+ export type AbstractWallet = Hex | AbstractViemWalletClient | AbstractEthersSigner | AbstractEthersV5Signer | AbstractWindowEthereum;
62
+ export interface Signature {
63
+ r: Hex;
64
+ s: Hex;
65
+ v: number;
66
+ }
67
+ /**
68
+ * Create a hash of the L1 action.
69
+ *
70
+ * Note: Hash generation depends on the order of the action keys.
71
+ *
72
+ * @param action - The action to be hashed.
73
+ * @param nonce - Unique request identifier (recommended current timestamp in ms).
74
+ * @param vaultAddress - Optional vault address used in the action.
75
+ * @param expiresAfter - Optional expiration time of the action in milliseconds since the epoch.
76
+ * @returns The hash of the action.
77
+ */
78
+ export declare function createL1ActionHash(action: ValueType, nonce: number, vaultAddress?: Hex, expiresAfter?: number): Hex;
79
+ /**
80
+ * Sign an L1 action.
81
+ *
82
+ * Note: Signature generation depends on the order of the action keys.
83
+ * @param args - Arguments for signing the action.
84
+ * @returns The signature components r, s, and v.
85
+ * @example
86
+ * ```ts
87
+ * import { signL1Action } from "@nktkas/hyperliquid/signing";
88
+ *
89
+ * const privateKey = "0x..."; // or `viem`, `ethers`
90
+ *
91
+ * const action = {
92
+ * type: "cancel",
93
+ * cancels: [
94
+ * { a: 0, o: 12345 }, // Asset index and order ID
95
+ * ],
96
+ * };
97
+ * const nonce = Date.now();
98
+ *
99
+ * const signature = await signL1Action({
100
+ * wallet: privateKey,
101
+ * action,
102
+ * nonce,
103
+ * isTestnet: true, // Change to false for mainnet
104
+ * });
105
+ *
106
+ * const response = await fetch("https://api.hyperliquid-testnet.xyz/exchange", {
107
+ * method: "POST",
108
+ * headers: { "Content-Type": "application/json" },
109
+ * body: JSON.stringify({ action, signature, nonce }),
110
+ * });
111
+ * const body = await response.json();
112
+ * ```
113
+ */
114
+ export declare function signL1Action(args: {
115
+ /** Wallet to sign the action. */
116
+ wallet: AbstractWallet;
117
+ /** The action to be signed. */
118
+ action: ValueType;
119
+ /** Unique request identifier (recommended current timestamp in ms). */
120
+ nonce: number;
121
+ /** Indicates if the action is for the testnet. Default is `false`. */
122
+ isTestnet?: boolean;
123
+ /** Optional vault address used in the action. */
124
+ vaultAddress?: Hex;
125
+ /** Optional expiration time of the action in milliseconds since the epoch. */
126
+ expiresAfter?: number;
127
+ }): Promise<Signature>;
128
+ /**
129
+ * Sign a user-signed action.
130
+ *
131
+ * Note: Signature generation depends on the order of types.
132
+ *
133
+ * @param args - Arguments for signing the action.
134
+ * @returns The signature components r, s, and v.
135
+ * @example
136
+ * ```ts
137
+ * import { signUserSignedAction } from "@nktkas/hyperliquid/signing";
138
+ *
139
+ * const privateKey = "0x..."; // or `viem`, `ethers`
140
+ *
141
+ * const action = {
142
+ * type: "approveAgent",
143
+ * hyperliquidChain: "Testnet", // "Mainnet" or "Testnet"
144
+ * signatureChainId: "0x66eee",
145
+ * nonce: Date.now(),
146
+ * agentAddress: "0x...", // Change to your agent address
147
+ * agentName: "Agent",
148
+ * };
149
+ *
150
+ * const signature = await signUserSignedAction({
151
+ * wallet: privateKey,
152
+ * action,
153
+ * types: {
154
+ * "HyperliquidTransaction:ApproveAgent": [
155
+ * { name: "hyperliquidChain", type: "string" },
156
+ * { name: "agentAddress", type: "address" },
157
+ * { name: "agentName", type: "string" },
158
+ * { name: "nonce", type: "uint64" },
159
+ * ],
160
+ * },
161
+ * chainId: parseInt(action.signatureChainId, 16),
162
+ * });
163
+ *
164
+ * const response = await fetch("https://api.hyperliquid-testnet.xyz/exchange", {
165
+ * method: "POST",
166
+ * headers: { "Content-Type": "application/json" },
167
+ * body: JSON.stringify({ action, signature, nonce: action.nonce }),
168
+ * });
169
+ * const body = await response.json();
170
+ * ```
171
+ */
172
+ export declare function signUserSignedAction(args: {
173
+ /** Wallet to sign the action. */
174
+ wallet: AbstractWallet;
175
+ /** The action to be signed. */
176
+ action: Record<string, unknown>;
177
+ /** The types of the action. */
178
+ types: {
179
+ [key: string]: {
180
+ name: string;
181
+ type: string;
182
+ }[];
183
+ };
184
+ /** The chain ID. */
185
+ chainId: number;
186
+ }): Promise<Signature>;
187
+ /**
188
+ * Sign a multi-signature action.
189
+ *
190
+ * Note: Signature generation depends on the order of the action keys.
191
+ *
192
+ * @param args - Arguments for signing the action.
193
+ * @returns The signature components r, s, and v.
194
+ * @example
195
+ * ```ts
196
+ * import { signL1Action, signMultiSigAction } from "@nktkas/hyperliquid/signing";
197
+ * import { privateKeyToAccount } from "viem/accounts";
198
+ *
199
+ * const wallet = privateKeyToAccount("0x...");
200
+ * const multiSigUser = "0x..."; // Multi-sig user address
201
+ *
202
+ * const nonce = Date.now();
203
+ * const action = { // Example action
204
+ * type: "scheduleCancel",
205
+ * time: Date.now() + 10000
206
+ * };
207
+ *
208
+ * // First, create signature from one of the authorized signers
209
+ * const signature = await signL1Action({
210
+ * wallet,
211
+ * action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), action],
212
+ * nonce,
213
+ * isTestnet: true,
214
+ * });
215
+ *
216
+ * // Then use it in the multi-sig action
217
+ * const multiSigSignature = await signMultiSigAction({
218
+ * wallet,
219
+ * action: {
220
+ * type: "multiSig",
221
+ * signatureChainId: "0x66eee",
222
+ * signatures: [signature],
223
+ * payload: {
224
+ * multiSigUser,
225
+ * outerSigner: wallet.address,
226
+ * action,
227
+ * }
228
+ * },
229
+ * nonce,
230
+ * hyperliquidChain: "Testnet",
231
+ * signatureChainId: "0x66eee",
232
+ * });
233
+ * ```
234
+ */
235
+ export declare function signMultiSigAction(args: {
236
+ /** Wallet to sign the action. */
237
+ wallet: AbstractWallet;
238
+ /** The action to be signed. */
239
+ action: ValueMap;
240
+ /** Unique request identifier (recommended current timestamp in ms). */
241
+ nonce: number;
242
+ /** Optional vault address used in the action. */
243
+ vaultAddress?: Hex;
244
+ /** Optional expiration time of the action in milliseconds since the epoch. */
245
+ expiresAfter?: number;
246
+ /** HyperLiquid network ("Mainnet" or "Testnet"). */
247
+ hyperliquidChain: "Mainnet" | "Testnet";
248
+ /** Chain ID used for signing. */
249
+ signatureChainId: Hex;
250
+ }): Promise<Signature>;
251
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../src/src/signing/mod.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,387 @@
1
+ /**
2
+ * This module contains functions for generating Hyperliquid transaction signatures
3
+ * and interfaces to various wallet implementations.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { signL1Action } from "@nktkas/hyperliquid/signing";
8
+ *
9
+ * const action = {
10
+ * type: "cancel",
11
+ * cancels: [{ a: 0, o: 12345 }],
12
+ * };
13
+ * const nonce = Date.now();
14
+ *
15
+ * const signature = await signL1Action({
16
+ * wallet,
17
+ * action,
18
+ * nonce,
19
+ * isTestnet: true, // Change to false for mainnet
20
+ * });
21
+ * ```
22
+ * @example
23
+ * ```ts
24
+ * import { signUserSignedAction } from "@nktkas/hyperliquid/signing";
25
+ *
26
+ * const action = {
27
+ * type: "approveAgent",
28
+ * hyperliquidChain: "Testnet", // "Mainnet" or "Testnet"
29
+ * signatureChainId: "0x66eee",
30
+ * nonce: Date.now(),
31
+ * agentAddress: "0x...",
32
+ * agentName: "Agent",
33
+ * };
34
+ *
35
+ * const signature = await signUserSignedAction({
36
+ * wallet,
37
+ * action,
38
+ * types: {
39
+ * "HyperliquidTransaction:ApproveAgent": [
40
+ * { name: "hyperliquidChain", type: "string" },
41
+ * { name: "agentAddress", type: "address" },
42
+ * { name: "agentName", type: "string" },
43
+ * { name: "nonce", type: "uint64" },
44
+ * ],
45
+ * },
46
+ * chainId: parseInt(action.signatureChainId, 16),
47
+ * });
48
+ * ```
49
+ *
50
+ * @module
51
+ */
52
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
53
+ if (k2 === undefined) k2 = k;
54
+ var desc = Object.getOwnPropertyDescriptor(m, k);
55
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
56
+ desc = { enumerable: true, get: function() { return m[k]; } };
57
+ }
58
+ Object.defineProperty(o, k2, desc);
59
+ }) : (function(o, m, k, k2) {
60
+ if (k2 === undefined) k2 = k;
61
+ o[k2] = m[k];
62
+ }));
63
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
64
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
65
+ };
66
+ (function (factory) {
67
+ if (typeof module === "object" && typeof module.exports === "object") {
68
+ var v = factory(require, exports);
69
+ if (v !== undefined) module.exports = v;
70
+ }
71
+ else if (typeof define === "function" && define.amd) {
72
+ define(["require", "exports", "@noble/hashes/sha3", "../../deps/jsr.io/@std/msgpack/1.0.3/encode.js", "../../deps/jsr.io/@std/encoding/1.0.10/hex.js", "../../deps/jsr.io/@std/bytes/1.0.6/concat.js", "./_ethers.js", "./_private_key.js", "./_viem.js", "./_window.js", "./_sorter.js"], factory);
73
+ }
74
+ })(function (require, exports) {
75
+ "use strict";
76
+ Object.defineProperty(exports, "__esModule", { value: true });
77
+ exports.isValidPrivateKey = exports.isAbstractWindowEthereum = exports.isAbstractViemWalletClient = exports.isAbstractEthersV5Signer = exports.isAbstractEthersSigner = void 0;
78
+ exports.createL1ActionHash = createL1ActionHash;
79
+ exports.signL1Action = signL1Action;
80
+ exports.signUserSignedAction = signUserSignedAction;
81
+ exports.signMultiSigAction = signMultiSigAction;
82
+ const sha3_1 = require("@noble/hashes/sha3");
83
+ const encode_js_1 = require("../../deps/jsr.io/@std/msgpack/1.0.3/encode.js");
84
+ const hex_js_1 = require("../../deps/jsr.io/@std/encoding/1.0.10/hex.js");
85
+ const concat_js_1 = require("../../deps/jsr.io/@std/bytes/1.0.6/concat.js");
86
+ const _ethers_js_1 = require("./_ethers.js");
87
+ Object.defineProperty(exports, "isAbstractEthersSigner", { enumerable: true, get: function () { return _ethers_js_1.isAbstractEthersSigner; } });
88
+ Object.defineProperty(exports, "isAbstractEthersV5Signer", { enumerable: true, get: function () { return _ethers_js_1.isAbstractEthersV5Signer; } });
89
+ const _private_key_js_1 = require("./_private_key.js");
90
+ Object.defineProperty(exports, "isValidPrivateKey", { enumerable: true, get: function () { return _private_key_js_1.isValidPrivateKey; } });
91
+ const _viem_js_1 = require("./_viem.js");
92
+ Object.defineProperty(exports, "isAbstractViemWalletClient", { enumerable: true, get: function () { return _viem_js_1.isAbstractViemWalletClient; } });
93
+ const _window_js_1 = require("./_window.js");
94
+ Object.defineProperty(exports, "isAbstractWindowEthereum", { enumerable: true, get: function () { return _window_js_1.isAbstractWindowEthereum; } });
95
+ __exportStar(require("./_sorter.js"), exports);
96
+ /**
97
+ * Create a hash of the L1 action.
98
+ *
99
+ * Note: Hash generation depends on the order of the action keys.
100
+ *
101
+ * @param action - The action to be hashed.
102
+ * @param nonce - Unique request identifier (recommended current timestamp in ms).
103
+ * @param vaultAddress - Optional vault address used in the action.
104
+ * @param expiresAfter - Optional expiration time of the action in milliseconds since the epoch.
105
+ * @returns The hash of the action.
106
+ */
107
+ function createL1ActionHash(action, nonce, vaultAddress, expiresAfter) {
108
+ // 1. Action
109
+ const actionBytes = (0, encode_js_1.encode)(normalizeIntegersForMsgPack(action));
110
+ // 2. Nonce
111
+ const nonceBytes = new Uint8Array(8);
112
+ new DataView(nonceBytes.buffer).setBigUint64(0, BigInt(nonce));
113
+ // 3. Vault address
114
+ const vaultMarker = vaultAddress ? Uint8Array.of(1) : Uint8Array.of(0);
115
+ const vaultBytes = vaultAddress ? (0, hex_js_1.decodeHex)(vaultAddress.slice(2)) : new Uint8Array();
116
+ // 4. Expires after
117
+ let expiresMarker;
118
+ let expiresBytes;
119
+ if (expiresAfter !== undefined) {
120
+ expiresMarker = Uint8Array.of(0);
121
+ expiresBytes = new Uint8Array(8);
122
+ new DataView(expiresBytes.buffer).setBigUint64(0, BigInt(expiresAfter));
123
+ }
124
+ else {
125
+ expiresMarker = new Uint8Array();
126
+ expiresBytes = new Uint8Array();
127
+ }
128
+ // Create a keccak256 hash
129
+ const bytes = (0, concat_js_1.concat)([
130
+ actionBytes,
131
+ nonceBytes,
132
+ vaultMarker,
133
+ vaultBytes,
134
+ expiresMarker,
135
+ expiresBytes,
136
+ ]);
137
+ const hash = (0, sha3_1.keccak_256)(bytes);
138
+ return `0x${(0, hex_js_1.encodeHex)(hash)}`;
139
+ }
140
+ /** Layer to make {@link https://jsr.io/@std/msgpack | @std/msgpack} compatible with {@link https://github.com/msgpack/msgpack-javascript | @msgpack/msgpack}. */
141
+ function normalizeIntegersForMsgPack(obj) {
142
+ const THIRTY_ONE_BITS = 2147483648;
143
+ const THIRTY_TWO_BITS = 4294967296;
144
+ if (typeof obj === "number" && Number.isInteger(obj) &&
145
+ obj <= Number.MAX_SAFE_INTEGER && obj >= Number.MIN_SAFE_INTEGER &&
146
+ (obj >= THIRTY_TWO_BITS || obj < -THIRTY_ONE_BITS)) {
147
+ return BigInt(obj);
148
+ }
149
+ if (Array.isArray(obj)) {
150
+ return obj.map(normalizeIntegersForMsgPack);
151
+ }
152
+ if (obj && typeof obj === "object" && obj !== null) {
153
+ return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, normalizeIntegersForMsgPack(value)]));
154
+ }
155
+ return obj;
156
+ }
157
+ /**
158
+ * Sign an L1 action.
159
+ *
160
+ * Note: Signature generation depends on the order of the action keys.
161
+ * @param args - Arguments for signing the action.
162
+ * @returns The signature components r, s, and v.
163
+ * @example
164
+ * ```ts
165
+ * import { signL1Action } from "@nktkas/hyperliquid/signing";
166
+ *
167
+ * const privateKey = "0x..."; // or `viem`, `ethers`
168
+ *
169
+ * const action = {
170
+ * type: "cancel",
171
+ * cancels: [
172
+ * { a: 0, o: 12345 }, // Asset index and order ID
173
+ * ],
174
+ * };
175
+ * const nonce = Date.now();
176
+ *
177
+ * const signature = await signL1Action({
178
+ * wallet: privateKey,
179
+ * action,
180
+ * nonce,
181
+ * isTestnet: true, // Change to false for mainnet
182
+ * });
183
+ *
184
+ * const response = await fetch("https://api.hyperliquid-testnet.xyz/exchange", {
185
+ * method: "POST",
186
+ * headers: { "Content-Type": "application/json" },
187
+ * body: JSON.stringify({ action, signature, nonce }),
188
+ * });
189
+ * const body = await response.json();
190
+ * ```
191
+ */
192
+ async function signL1Action(args) {
193
+ const { wallet, action, nonce, isTestnet = false, vaultAddress, expiresAfter, } = args;
194
+ const domain = {
195
+ name: "Exchange",
196
+ version: "1",
197
+ chainId: 1337, // hyperliquid requires a fixed chain
198
+ verifyingContract: "0x0000000000000000000000000000000000000000",
199
+ };
200
+ const types = {
201
+ Agent: [
202
+ { name: "source", type: "string" },
203
+ { name: "connectionId", type: "bytes32" },
204
+ ],
205
+ };
206
+ const actionHash = createL1ActionHash(action, nonce, vaultAddress, expiresAfter);
207
+ const message = {
208
+ source: isTestnet ? "b" : "a",
209
+ connectionId: actionHash,
210
+ };
211
+ const signature = await abstractSignTypedData({ wallet, domain, types, message });
212
+ return splitSignature(signature);
213
+ }
214
+ /**
215
+ * Sign a user-signed action.
216
+ *
217
+ * Note: Signature generation depends on the order of types.
218
+ *
219
+ * @param args - Arguments for signing the action.
220
+ * @returns The signature components r, s, and v.
221
+ * @example
222
+ * ```ts
223
+ * import { signUserSignedAction } from "@nktkas/hyperliquid/signing";
224
+ *
225
+ * const privateKey = "0x..."; // or `viem`, `ethers`
226
+ *
227
+ * const action = {
228
+ * type: "approveAgent",
229
+ * hyperliquidChain: "Testnet", // "Mainnet" or "Testnet"
230
+ * signatureChainId: "0x66eee",
231
+ * nonce: Date.now(),
232
+ * agentAddress: "0x...", // Change to your agent address
233
+ * agentName: "Agent",
234
+ * };
235
+ *
236
+ * const signature = await signUserSignedAction({
237
+ * wallet: privateKey,
238
+ * action,
239
+ * types: {
240
+ * "HyperliquidTransaction:ApproveAgent": [
241
+ * { name: "hyperliquidChain", type: "string" },
242
+ * { name: "agentAddress", type: "address" },
243
+ * { name: "agentName", type: "string" },
244
+ * { name: "nonce", type: "uint64" },
245
+ * ],
246
+ * },
247
+ * chainId: parseInt(action.signatureChainId, 16),
248
+ * });
249
+ *
250
+ * const response = await fetch("https://api.hyperliquid-testnet.xyz/exchange", {
251
+ * method: "POST",
252
+ * headers: { "Content-Type": "application/json" },
253
+ * body: JSON.stringify({ action, signature, nonce: action.nonce }),
254
+ * });
255
+ * const body = await response.json();
256
+ * ```
257
+ */
258
+ async function signUserSignedAction(args) {
259
+ const { wallet, action, types, chainId } = args;
260
+ const domain = {
261
+ name: "HyperliquidSignTransaction",
262
+ version: "1",
263
+ chainId,
264
+ verifyingContract: "0x0000000000000000000000000000000000000000",
265
+ };
266
+ const signature = await abstractSignTypedData({ wallet, domain, types, message: action });
267
+ return splitSignature(signature);
268
+ }
269
+ /**
270
+ * Sign a multi-signature action.
271
+ *
272
+ * Note: Signature generation depends on the order of the action keys.
273
+ *
274
+ * @param args - Arguments for signing the action.
275
+ * @returns The signature components r, s, and v.
276
+ * @example
277
+ * ```ts
278
+ * import { signL1Action, signMultiSigAction } from "@nktkas/hyperliquid/signing";
279
+ * import { privateKeyToAccount } from "viem/accounts";
280
+ *
281
+ * const wallet = privateKeyToAccount("0x...");
282
+ * const multiSigUser = "0x..."; // Multi-sig user address
283
+ *
284
+ * const nonce = Date.now();
285
+ * const action = { // Example action
286
+ * type: "scheduleCancel",
287
+ * time: Date.now() + 10000
288
+ * };
289
+ *
290
+ * // First, create signature from one of the authorized signers
291
+ * const signature = await signL1Action({
292
+ * wallet,
293
+ * action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), action],
294
+ * nonce,
295
+ * isTestnet: true,
296
+ * });
297
+ *
298
+ * // Then use it in the multi-sig action
299
+ * const multiSigSignature = await signMultiSigAction({
300
+ * wallet,
301
+ * action: {
302
+ * type: "multiSig",
303
+ * signatureChainId: "0x66eee",
304
+ * signatures: [signature],
305
+ * payload: {
306
+ * multiSigUser,
307
+ * outerSigner: wallet.address,
308
+ * action,
309
+ * }
310
+ * },
311
+ * nonce,
312
+ * hyperliquidChain: "Testnet",
313
+ * signatureChainId: "0x66eee",
314
+ * });
315
+ * ```
316
+ */
317
+ async function signMultiSigAction(args) {
318
+ const { wallet, action, nonce, hyperliquidChain, signatureChainId, vaultAddress, expiresAfter, } = args;
319
+ const multiSigActionHash = createL1ActionHash(action, nonce, vaultAddress, expiresAfter);
320
+ const message = {
321
+ multiSigActionHash,
322
+ hyperliquidChain,
323
+ signatureChainId,
324
+ nonce,
325
+ };
326
+ return await signUserSignedAction({
327
+ wallet,
328
+ action: message,
329
+ types: {
330
+ "HyperliquidTransaction:SendMultiSig": [
331
+ { name: "hyperliquidChain", type: "string" },
332
+ { name: "multiSigActionHash", type: "bytes32" },
333
+ { name: "nonce", type: "uint64" },
334
+ ],
335
+ },
336
+ chainId: parseInt(signatureChainId, 16),
337
+ });
338
+ }
339
+ /** Signs typed data with the provided wallet using EIP-712. */
340
+ async function abstractSignTypedData(args) {
341
+ const { wallet, domain, types, message } = args;
342
+ if ((0, _private_key_js_1.isValidPrivateKey)(wallet)) {
343
+ return await (0, _private_key_js_1.signTypedDataWithPrivateKey)({
344
+ privateKey: wallet,
345
+ domain,
346
+ types,
347
+ primaryType: Object.keys(types)[0],
348
+ message,
349
+ });
350
+ }
351
+ else if ((0, _viem_js_1.isAbstractViemWalletClient)(wallet)) {
352
+ return await wallet.signTypedData({
353
+ domain,
354
+ types: {
355
+ EIP712Domain: [
356
+ { name: "name", type: "string" },
357
+ { name: "version", type: "string" },
358
+ { name: "chainId", type: "uint256" },
359
+ { name: "verifyingContract", type: "address" },
360
+ ],
361
+ ...types,
362
+ },
363
+ primaryType: Object.keys(types)[0],
364
+ message,
365
+ });
366
+ }
367
+ else if ((0, _ethers_js_1.isAbstractEthersSigner)(wallet)) {
368
+ return await wallet.signTypedData(domain, types, message);
369
+ }
370
+ else if ((0, _ethers_js_1.isAbstractEthersV5Signer)(wallet)) {
371
+ return await wallet._signTypedData(domain, types, message);
372
+ }
373
+ else if ((0, _window_js_1.isAbstractWindowEthereum)(wallet)) {
374
+ return await (0, _window_js_1.signTypedDataWithWindowEthereum)(wallet, domain, types, message);
375
+ }
376
+ else {
377
+ throw new Error("Unsupported wallet for signing typed data");
378
+ }
379
+ }
380
+ /** Splits a signature hexadecimal string into its components. */
381
+ function splitSignature(signature) {
382
+ const r = `0x${signature.slice(2, 66)}`;
383
+ const s = `0x${signature.slice(66, 130)}`;
384
+ const v = parseInt(signature.slice(130, 132), 16);
385
+ return { r, s, v };
386
+ }
387
+ });