@nktkas/hyperliquid 0.23.1 → 0.24.1

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 (165) hide show
  1. package/CONTRIBUTING.md +3 -2
  2. package/README.md +178 -194
  3. package/esm/mod.d.ts +2 -1
  4. package/esm/mod.d.ts.map +1 -1
  5. package/esm/src/base.d.ts +0 -5
  6. package/esm/src/base.d.ts.map +1 -1
  7. package/esm/src/clients/exchange.d.ts +485 -392
  8. package/esm/src/clients/exchange.d.ts.map +1 -1
  9. package/esm/src/clients/exchange.js +517 -912
  10. package/esm/src/clients/info.d.ts +249 -203
  11. package/esm/src/clients/info.d.ts.map +1 -1
  12. package/esm/src/clients/info.js +258 -368
  13. package/esm/src/clients/multiSign.d.ts +14 -1184
  14. package/esm/src/clients/multiSign.d.ts.map +1 -1
  15. package/esm/src/clients/multiSign.js +37 -2004
  16. package/esm/src/clients/subscription.d.ts +101 -99
  17. package/esm/src/clients/subscription.d.ts.map +1 -1
  18. package/esm/src/clients/subscription.js +107 -152
  19. package/esm/src/signing/_signTypedData/ethers.d.ts +16 -4
  20. package/esm/src/signing/_signTypedData/ethers.d.ts.map +1 -1
  21. package/esm/src/signing/_signTypedData/ethers.js +1 -1
  22. package/esm/src/signing/_signTypedData/mod.d.ts +12 -12
  23. package/esm/src/signing/_signTypedData/mod.d.ts.map +1 -1
  24. package/esm/src/signing/_signTypedData/mod.js +52 -24
  25. package/esm/src/signing/_signTypedData/private_key.d.ts +6 -5
  26. package/esm/src/signing/_signTypedData/private_key.d.ts.map +1 -1
  27. package/esm/src/signing/_signTypedData/private_key.js +40 -19
  28. package/esm/src/signing/_signTypedData/viem.d.ts +27 -6
  29. package/esm/src/signing/_signTypedData/viem.d.ts.map +1 -1
  30. package/esm/src/signing/_signTypedData/viem.js +1 -1
  31. package/esm/src/signing/_sorter.d.ts +18 -19
  32. package/esm/src/signing/_sorter.d.ts.map +1 -1
  33. package/esm/src/signing/_sorter.js +57 -59
  34. package/esm/src/signing/mod.d.ts +179 -129
  35. package/esm/src/signing/mod.d.ts.map +1 -1
  36. package/esm/src/signing/mod.js +184 -132
  37. package/esm/src/transports/base.d.ts +2 -1
  38. package/esm/src/transports/base.d.ts.map +1 -1
  39. package/esm/src/transports/http/http_transport.d.ts +3 -2
  40. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  41. package/esm/src/transports/http/http_transport.js +4 -4
  42. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +14 -6
  43. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  44. package/esm/src/transports/websocket/_hyperliquid_event_target.js +1 -2
  45. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +2 -1
  46. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  47. package/esm/src/transports/websocket/_reconnecting_websocket.js +1 -0
  48. package/esm/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  49. package/esm/src/transports/websocket/_websocket_async_request.js +17 -21
  50. package/esm/src/transports/websocket/websocket_transport.d.ts +4 -4
  51. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  52. package/esm/src/transports/websocket/websocket_transport.js +6 -6
  53. package/esm/src/types/exchange/requests.d.ts +547 -306
  54. package/esm/src/types/exchange/requests.d.ts.map +1 -1
  55. package/esm/src/types/exchange/responses.d.ts +105 -25
  56. package/esm/src/types/exchange/responses.d.ts.map +1 -1
  57. package/esm/src/types/explorer/requests.d.ts +3 -3
  58. package/esm/src/types/explorer/requests.d.ts.map +1 -1
  59. package/esm/src/types/explorer/responses.d.ts +1 -1
  60. package/esm/src/types/explorer/responses.d.ts.map +1 -1
  61. package/esm/src/types/info/accounts.d.ts +405 -98
  62. package/esm/src/types/info/accounts.d.ts.map +1 -1
  63. package/esm/src/types/info/assets.d.ts +131 -35
  64. package/esm/src/types/info/assets.d.ts.map +1 -1
  65. package/esm/src/types/info/markets.d.ts +29 -8
  66. package/esm/src/types/info/markets.d.ts.map +1 -1
  67. package/esm/src/types/info/orders.d.ts +64 -17
  68. package/esm/src/types/info/orders.d.ts.map +1 -1
  69. package/esm/src/types/info/requests.d.ts +126 -51
  70. package/esm/src/types/info/requests.d.ts.map +1 -1
  71. package/esm/src/types/info/validators.d.ts +44 -14
  72. package/esm/src/types/info/validators.d.ts.map +1 -1
  73. package/esm/src/types/info/vaults.d.ts +25 -10
  74. package/esm/src/types/info/vaults.d.ts.map +1 -1
  75. package/esm/src/types/mod.d.ts +1 -1
  76. package/esm/src/types/mod.d.ts.map +1 -1
  77. package/esm/src/types/subscriptions/requests.d.ts +21 -66
  78. package/esm/src/types/subscriptions/requests.d.ts.map +1 -1
  79. package/esm/src/types/subscriptions/responses.d.ts +46 -55
  80. package/esm/src/types/subscriptions/responses.d.ts.map +1 -1
  81. package/package.json +2 -3
  82. package/script/mod.d.ts +2 -1
  83. package/script/mod.d.ts.map +1 -1
  84. package/script/src/base.d.ts +0 -5
  85. package/script/src/base.d.ts.map +1 -1
  86. package/script/src/clients/exchange.d.ts +485 -392
  87. package/script/src/clients/exchange.d.ts.map +1 -1
  88. package/script/src/clients/exchange.js +516 -911
  89. package/script/src/clients/info.d.ts +249 -203
  90. package/script/src/clients/info.d.ts.map +1 -1
  91. package/script/src/clients/info.js +258 -368
  92. package/script/src/clients/multiSign.d.ts +14 -1184
  93. package/script/src/clients/multiSign.d.ts.map +1 -1
  94. package/script/src/clients/multiSign.js +38 -2005
  95. package/script/src/clients/subscription.d.ts +101 -99
  96. package/script/src/clients/subscription.d.ts.map +1 -1
  97. package/script/src/clients/subscription.js +107 -152
  98. package/script/src/signing/_signTypedData/ethers.d.ts +16 -4
  99. package/script/src/signing/_signTypedData/ethers.d.ts.map +1 -1
  100. package/script/src/signing/_signTypedData/ethers.js +2 -2
  101. package/script/src/signing/_signTypedData/mod.d.ts +12 -12
  102. package/script/src/signing/_signTypedData/mod.d.ts.map +1 -1
  103. package/script/src/signing/_signTypedData/mod.js +51 -26
  104. package/script/src/signing/_signTypedData/private_key.d.ts +6 -5
  105. package/script/src/signing/_signTypedData/private_key.d.ts.map +1 -1
  106. package/script/src/signing/_signTypedData/private_key.js +40 -18
  107. package/script/src/signing/_signTypedData/viem.d.ts +27 -6
  108. package/script/src/signing/_signTypedData/viem.d.ts.map +1 -1
  109. package/script/src/signing/_signTypedData/viem.js +2 -2
  110. package/script/src/signing/_sorter.d.ts +18 -19
  111. package/script/src/signing/_sorter.d.ts.map +1 -1
  112. package/script/src/signing/_sorter.js +57 -59
  113. package/script/src/signing/mod.d.ts +179 -129
  114. package/script/src/signing/mod.d.ts.map +1 -1
  115. package/script/src/signing/mod.js +187 -150
  116. package/script/src/transports/base.d.ts +2 -1
  117. package/script/src/transports/base.d.ts.map +1 -1
  118. package/script/src/transports/http/http_transport.d.ts +3 -2
  119. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  120. package/script/src/transports/http/http_transport.js +4 -4
  121. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +14 -6
  122. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  123. package/script/src/transports/websocket/_hyperliquid_event_target.js +1 -2
  124. package/script/src/transports/websocket/_reconnecting_websocket.d.ts +2 -1
  125. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  126. package/script/src/transports/websocket/_reconnecting_websocket.js +1 -0
  127. package/script/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  128. package/script/src/transports/websocket/_websocket_async_request.js +17 -21
  129. package/script/src/transports/websocket/websocket_transport.d.ts +4 -4
  130. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  131. package/script/src/transports/websocket/websocket_transport.js +6 -6
  132. package/script/src/types/exchange/requests.d.ts +547 -306
  133. package/script/src/types/exchange/requests.d.ts.map +1 -1
  134. package/script/src/types/exchange/responses.d.ts +105 -25
  135. package/script/src/types/exchange/responses.d.ts.map +1 -1
  136. package/script/src/types/explorer/requests.d.ts +3 -3
  137. package/script/src/types/explorer/requests.d.ts.map +1 -1
  138. package/script/src/types/explorer/responses.d.ts +1 -1
  139. package/script/src/types/explorer/responses.d.ts.map +1 -1
  140. package/script/src/types/info/accounts.d.ts +405 -98
  141. package/script/src/types/info/accounts.d.ts.map +1 -1
  142. package/script/src/types/info/assets.d.ts +131 -35
  143. package/script/src/types/info/assets.d.ts.map +1 -1
  144. package/script/src/types/info/markets.d.ts +29 -8
  145. package/script/src/types/info/markets.d.ts.map +1 -1
  146. package/script/src/types/info/orders.d.ts +64 -17
  147. package/script/src/types/info/orders.d.ts.map +1 -1
  148. package/script/src/types/info/requests.d.ts +126 -51
  149. package/script/src/types/info/requests.d.ts.map +1 -1
  150. package/script/src/types/info/validators.d.ts +44 -14
  151. package/script/src/types/info/validators.d.ts.map +1 -1
  152. package/script/src/types/info/vaults.d.ts +25 -10
  153. package/script/src/types/info/vaults.d.ts.map +1 -1
  154. package/script/src/types/mod.d.ts +1 -1
  155. package/script/src/types/mod.d.ts.map +1 -1
  156. package/script/src/types/subscriptions/requests.d.ts +21 -66
  157. package/script/src/types/subscriptions/requests.d.ts.map +1 -1
  158. package/script/src/types/subscriptions/responses.d.ts +46 -55
  159. package/script/src/types/subscriptions/responses.d.ts.map +1 -1
  160. package/esm/src/signing/_signTypedData/window.d.ts +0 -29
  161. package/esm/src/signing/_signTypedData/window.d.ts.map +0 -1
  162. package/esm/src/signing/_signTypedData/window.js +0 -30
  163. package/script/src/signing/_signTypedData/window.d.ts +0 -29
  164. package/script/src/signing/_signTypedData/window.d.ts.map +0 -1
  165. package/script/src/signing/_signTypedData/window.js +0 -34
@@ -6,7 +6,7 @@ export const actionSorter = {
6
6
  signatureChainId: action.signatureChainId,
7
7
  hyperliquidChain: action.hyperliquidChain,
8
8
  agentAddress: action.agentAddress.toLowerCase(),
9
- agentName: action.agentName ?? "",
9
+ agentName: action.agentName,
10
10
  nonce: action.nonce,
11
11
  };
12
12
  },
@@ -91,7 +91,10 @@ export const actionSorter = {
91
91
  type: action.type,
92
92
  signatureChainId: action.signatureChainId,
93
93
  hyperliquidChain: action.hyperliquidChain,
94
- signers: action.signers, // key order is not important
94
+ signers: typeof action.signers === "string" ? action.signers : JSON.stringify(action.signers === null ? action.signers : {
95
+ authorizedUsers: action.signers.authorizedUsers,
96
+ threshold: action.signers.threshold,
97
+ }),
95
98
  nonce: action.nonce,
96
99
  };
97
100
  },
@@ -129,13 +132,13 @@ export const actionSorter = {
129
132
  return {
130
133
  type: action.type,
131
134
  changeProfile: {
132
- node_ip: action.changeProfile.node_ip ?? null,
133
- name: action.changeProfile.name ?? null,
134
- description: action.changeProfile.description ?? null,
135
+ node_ip: action.changeProfile.node_ip,
136
+ name: action.changeProfile.name,
137
+ description: action.changeProfile.description,
135
138
  unjailed: action.changeProfile.unjailed,
136
- disable_delegations: action.changeProfile.disable_delegations ?? null,
137
- commission_bps: action.changeProfile.commission_bps ?? null,
138
- signer: action.changeProfile.signer?.toLowerCase() ?? null,
139
+ disable_delegations: action.changeProfile.disable_delegations,
140
+ commission_bps: action.changeProfile.commission_bps,
141
+ signer: action.changeProfile.signer?.toLowerCase(),
139
142
  },
140
143
  };
141
144
  }
@@ -158,7 +161,7 @@ export const actionSorter = {
158
161
  },
159
162
  };
160
163
  }
161
- else { // "unregister" in action
164
+ else {
162
165
  return {
163
166
  type: action.type,
164
167
  unregister: action.unregister,
@@ -222,10 +225,17 @@ export const actionSorter = {
222
225
  payload: {
223
226
  multiSigUser: action.payload.multiSigUser.toLowerCase(),
224
227
  outerSigner: action.payload.outerSigner.toLowerCase(),
225
- action: structuredClone(action.payload.action),
228
+ action: actionSorter[action.payload.action.type](
229
+ // @ts-ignore - TypeScript cannot infer the type correctly
230
+ action.payload.action),
226
231
  },
227
232
  };
228
233
  },
234
+ noop: (action) => {
235
+ return {
236
+ type: action.type,
237
+ };
238
+ },
229
239
  order: (action) => {
230
240
  const sortedAction = {
231
241
  type: action.type,
@@ -272,7 +282,7 @@ export const actionSorter = {
272
282
  return {
273
283
  type: action.type,
274
284
  registerAsset: {
275
- maxGas: action.registerAsset.maxGas ?? null,
285
+ maxGas: action.registerAsset.maxGas,
276
286
  assetRequest: {
277
287
  coin: action.registerAsset.assetRequest.coin,
278
288
  szDecimals: action.registerAsset.assetRequest.szDecimals,
@@ -285,9 +295,9 @@ export const actionSorter = {
285
295
  ? {
286
296
  fullName: action.registerAsset.schema.fullName,
287
297
  collateralToken: action.registerAsset.schema.collateralToken,
288
- oracleUpdater: action.registerAsset.schema.oracleUpdater?.toLowerCase() ?? null,
298
+ oracleUpdater: action.registerAsset.schema.oracleUpdater?.toLowerCase(),
289
299
  }
290
- : null,
300
+ : action.registerAsset.schema,
291
301
  },
292
302
  };
293
303
  }
@@ -297,34 +307,11 @@ export const actionSorter = {
297
307
  setOracle: {
298
308
  dex: action.setOracle.dex,
299
309
  oraclePxs: action.setOracle.oraclePxs.map((el) => [...el]),
300
- markPxs: action.setOracle.markPxs.map((el) => [...el]),
310
+ markPxs: action.setOracle.markPxs.map((el) => el.map((el2) => [...el2])),
301
311
  },
302
312
  };
303
313
  }
304
314
  },
305
- PerpDexClassTransfer: (action) => {
306
- return {
307
- type: action.type,
308
- signatureChainId: action.signatureChainId,
309
- hyperliquidChain: action.hyperliquidChain,
310
- dex: action.dex,
311
- token: action.token,
312
- amount: action.amount,
313
- toPerp: action.toPerp,
314
- nonce: action.nonce,
315
- };
316
- },
317
- PerpDexTransfer: (action) => {
318
- return {
319
- type: action.type,
320
- signatureChainId: action.signatureChainId,
321
- hyperliquidChain: action.hyperliquidChain,
322
- sourceDex: action.sourceDex,
323
- destinationDex: action.destinationDex,
324
- amount: action.amount,
325
- nonce: action.nonce,
326
- };
327
- },
328
315
  registerReferrer: (action) => {
329
316
  return {
330
317
  type: action.type,
@@ -346,6 +333,20 @@ export const actionSorter = {
346
333
  delete sortedAction.time;
347
334
  return sortedAction;
348
335
  },
336
+ sendAsset: (action) => {
337
+ return {
338
+ type: action.type,
339
+ signatureChainId: action.signatureChainId,
340
+ hyperliquidChain: action.hyperliquidChain,
341
+ destination: action.destination.toLowerCase(),
342
+ sourceDex: action.sourceDex,
343
+ destinationDex: action.destinationDex,
344
+ token: action.token,
345
+ amount: action.amount,
346
+ fromSubAccount: action.fromSubAccount.toLowerCase(),
347
+ nonce: action.nonce,
348
+ };
349
+ },
349
350
  setDisplayName: (action) => {
350
351
  return {
351
352
  type: action.type,
@@ -368,9 +369,8 @@ export const actionSorter = {
368
369
  noHyperliquidity: action.genesis.noHyperliquidity,
369
370
  },
370
371
  };
371
- if (sortedAction.genesis.noHyperliquidity === undefined) {
372
+ if (sortedAction.genesis.noHyperliquidity === undefined)
372
373
  delete sortedAction.genesis.noHyperliquidity;
373
- }
374
374
  return sortedAction;
375
375
  }
376
376
  else if ("registerHyperliquidity" in action) {
@@ -410,9 +410,8 @@ export const actionSorter = {
410
410
  fullName: action.registerToken2.fullName,
411
411
  },
412
412
  };
413
- if (sortedAction.registerToken2.fullName === undefined) {
413
+ if (sortedAction.registerToken2.fullName === undefined)
414
414
  delete sortedAction.registerToken2.fullName;
415
- }
416
415
  return sortedAction;
417
416
  }
418
417
  else if ("setDeployerTradingFeeShare" in action) {
@@ -424,7 +423,7 @@ export const actionSorter = {
424
423
  },
425
424
  };
426
425
  }
427
- else { // "userGenesis" in action
426
+ else {
428
427
  const sortedAction = {
429
428
  type: action.type,
430
429
  userGenesis: {
@@ -434,9 +433,8 @@ export const actionSorter = {
434
433
  blacklistUsers: action.userGenesis.blacklistUsers?.map((el) => [...el]),
435
434
  },
436
435
  };
437
- if (sortedAction.userGenesis.blacklistUsers === undefined) {
436
+ if (sortedAction.userGenesis.blacklistUsers === undefined)
438
437
  delete sortedAction.userGenesis.blacklistUsers;
439
- }
440
438
  return sortedAction;
441
439
  }
442
440
  },
@@ -459,6 +457,13 @@ export const actionSorter = {
459
457
  },
460
458
  };
461
459
  },
460
+ subAccountModify: (action) => {
461
+ return {
462
+ type: action.type,
463
+ subAccountUser: action.subAccountUser.toLowerCase(),
464
+ name: action.name,
465
+ };
466
+ },
462
467
  subAccountSpotTransfer: (action) => {
463
468
  return {
464
469
  type: action.type,
@@ -624,29 +629,22 @@ export const userSignedActionEip712Types = {
624
629
  { name: "nonce", type: "uint64" },
625
630
  ],
626
631
  },
627
- PerpDexClassTransfer: {
628
- "HyperliquidTransaction:PerpDexClassTransfer": [
632
+ multiSig: {
633
+ "HyperliquidTransaction:SendMultiSig": [
629
634
  { name: "hyperliquidChain", type: "string" },
630
- { name: "dex", type: "string" },
631
- { name: "token", type: "string" },
632
- { name: "amount", type: "string" },
633
- { name: "toPerp", type: "bool" },
635
+ { name: "multiSigActionHash", type: "bytes32" },
634
636
  { name: "nonce", type: "uint64" },
635
637
  ],
636
638
  },
637
- PerpDexTransfer: {
638
- "HyperliquidTransaction:PerpDexTransfer": [
639
+ sendAsset: {
640
+ "HyperliquidTransaction:SendAsset": [
639
641
  { name: "hyperliquidChain", type: "string" },
642
+ { name: "destination", type: "string" },
640
643
  { name: "sourceDex", type: "string" },
641
644
  { name: "destinationDex", type: "string" },
645
+ { name: "token", type: "string" },
642
646
  { name: "amount", type: "string" },
643
- { name: "nonce", type: "uint64" },
644
- ],
645
- },
646
- multiSig: {
647
- "HyperliquidTransaction:SendMultiSig": [
648
- { name: "hyperliquidChain", type: "string" },
649
- { name: "multiSigActionHash", type: "bytes32" },
647
+ { name: "fromSubAccount", type: "string" },
650
648
  { name: "nonce", type: "uint64" },
651
649
  ],
652
650
  },
@@ -6,108 +6,135 @@
6
6
  * ```ts
7
7
  * import { actionSorter, signL1Action } from "@nktkas/hyperliquid/signing";
8
8
  *
9
- * const privateKey = "0x..."; // or `viem`, `ethers`
9
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly`
10
10
  *
11
+ * const action = actionSorter.cancel({
12
+ * type: "cancel",
13
+ * cancels: [
14
+ * { a: 0, o: 12345 },
15
+ * ],
16
+ * });
11
17
  * const nonce = Date.now();
12
- * const action = {
13
- * type: "cancel",
14
- * cancels: [
15
- * { a: 0, o: 12345 },
16
- * ],
17
- * } as const;
18
- *
19
- * const signature = await signL1Action({
20
- * wallet: privateKey,
21
- * action: actionSorter[action.type](action),
22
- * nonce,
18
+ *
19
+ * const signature = await signL1Action({ wallet: privateKey, action, nonce });
20
+ *
21
+ * // Send the signed action to the Hyperliquid API
22
+ * const response = await fetch("https://api.hyperliquid.xyz/exchange", {
23
+ * method: "POST",
24
+ * headers: { "Content-Type": "application/json" },
25
+ * body: JSON.stringify({ action, signature, nonce }), // recommended to send the same formatted action
23
26
  * });
27
+ * const body = await response.json();
24
28
  * ```
25
29
  *
26
30
  * @example Signing a user-signed action
27
31
  * ```ts
28
- * import { signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
32
+ * import { actionSorter, signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
29
33
  *
30
- * const privateKey = "0x..."; // or `viem`, `ethers`
34
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly`
31
35
  *
32
- * const action = {
33
- * type: "approveAgent",
34
- * signatureChainId: "0x66eee",
35
- * hyperliquidChain: "Mainnet",
36
- * agentAddress: "0x...",
37
- * agentName: "Agent",
38
- * nonce: Date.now(),
39
- * } as const;
36
+ * const action = actionSorter.approveAgent({
37
+ * type: "approveAgent",
38
+ * signatureChainId: "0x66eee",
39
+ * hyperliquidChain: "Mainnet",
40
+ * agentAddress: "0x...",
41
+ * agentName: "Agent",
42
+ * nonce: Date.now(),
43
+ * });
40
44
  *
41
45
  * const signature = await signUserSignedAction({
42
- * wallet: privateKey,
43
- * action,
44
- * types: userSignedActionEip712Types[action.type],
46
+ * wallet: privateKey,
47
+ * action,
48
+ * types: userSignedActionEip712Types[action.type],
49
+ * });
50
+ *
51
+ * // Send the signed action to the Hyperliquid API
52
+ * const response = await fetch("https://api.hyperliquid.xyz/exchange", {
53
+ * method: "POST",
54
+ * headers: { "Content-Type": "application/json" },
55
+ * body: JSON.stringify({ action, signature, nonce: action.nonce }), // recommended to send the same formatted action
45
56
  * });
57
+ * const body = await response.json();
46
58
  * ```
47
59
  *
48
60
  * @example Signing a multi-signature action
49
61
  * ```ts
50
62
  * import { actionSorter, signL1Action, signMultiSigAction } from "@nktkas/hyperliquid/signing";
51
- * import { privateKeyToAccount } from "viem/accounts";
63
+ * import { privateKeyToAccount } from "npm:viem/accounts";
52
64
  *
53
- * const wallet = privateKeyToAccount("0x..."); // or `ethers`, private key with address
65
+ * const wallet = privateKeyToAccount("0x..."); // or `ethers`, private key directly
54
66
  * const multiSigUser = "0x...";
55
67
  *
68
+ * const action = actionSorter.scheduleCancel({
69
+ * type: "scheduleCancel",
70
+ * time: Date.now() + 10000,
71
+ * });
56
72
  * const nonce = Date.now();
57
- * const action = {
58
- * type: "scheduleCancel",
59
- * time: Date.now() + 10000,
60
- * } as const;
61
- *
62
- * // First, create the required number of signatures
63
- * const signature = await signL1Action({
64
- * wallet,
65
- * action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), actionSorter[action.type](action)],
73
+ *
74
+ * // Create the required number of signatures
75
+ * const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
76
+ * return await signL1Action({
77
+ * wallet: signerPrivKey as `0x${string}`,
78
+ * action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), action],
66
79
  * nonce,
67
- * });
80
+ * });
81
+ * }));
82
+ *
83
+ * // or user-signed action
84
+ * // const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
85
+ * // return await signUserSignedAction({
86
+ * // wallet: signerPrivKey as `0x${string}`,
87
+ * // action: {
88
+ * // ...action,
89
+ * // payloadMultiSigUser: multiSigUser,
90
+ * // outerSigner: wallet.address,
91
+ * // },
92
+ * // types: userSignedActionEip712Types[action.type],
93
+ * // });
94
+ * // }));
68
95
  *
69
96
  * // Then use signatures in the multi-sig action
70
- * const multiSigSignature = await signMultiSigAction({
71
- * wallet,
72
- * action: {
73
- * signatureChainId: "0x66eee",
74
- * signatures: [signature],
75
- * payload: {
76
- * multiSigUser,
77
- * outerSigner: wallet.address,
78
- * action,
79
- * },
80
- * },
81
- * nonce,
97
+ * const multiSigAction = actionSorter.multiSig({
98
+ * type: "multiSig",
99
+ * signatureChainId: "0x66eee",
100
+ * signatures,
101
+ * payload: {
102
+ * multiSigUser,
103
+ * outerSigner: wallet.address,
104
+ * action,
105
+ * },
106
+ * });
107
+ * const multiSigSignature = await signMultiSigAction({ wallet, action: multiSigAction, nonce });
108
+ *
109
+ * // Send the multi-sig action to the Hyperliquid API
110
+ * const response = await fetch("https://api.hyperliquid.xyz/exchange", {
111
+ * method: "POST",
112
+ * headers: { "Content-Type": "application/json" },
113
+ * body: JSON.stringify({ action: multiSigAction, signature: multiSigSignature, nonce }), // recommended to send the same formatted action
82
114
  * });
115
+ * const body = await response.json();
83
116
  * ```
84
117
  *
85
118
  * @module
86
119
  */
87
- import type { Hex } from "../base.js";
88
- import { type AbstractEthersSigner, type AbstractEthersV5Signer, type AbstractViemWalletClient, type AbstractWallet, type AbstractWindowEthereum, isAbstractEthersSigner, isAbstractEthersV5Signer, isAbstractViemWalletClient, isAbstractWindowEthereum, isValidPrivateKey, type Signature } from "./_signTypedData/mod.js";
89
- export { type AbstractEthersSigner, type AbstractEthersV5Signer, type AbstractViemWalletClient, type AbstractWallet, type AbstractWindowEthereum, type Hex, isAbstractEthersSigner, isAbstractEthersV5Signer, isAbstractViemWalletClient, isAbstractWindowEthereum, isValidPrivateKey, type Signature, };
90
- export * from "./_sorter.js";
120
+ import { type AbstractWallet, getWalletAddress, getWalletChainId, type Signature } from "./_signTypedData/mod.js";
121
+ import { actionSorter, userSignedActionEip712Types } from "./_sorter.js";
122
+ export { type AbstractWallet, actionSorter, getWalletAddress, getWalletChainId, type Signature, userSignedActionEip712Types, };
91
123
  /**
92
124
  * Create a hash of the L1 action.
93
125
  * @example
94
126
  * ```ts
95
127
  * import { actionSorter, createL1ActionHash } from "@nktkas/hyperliquid/signing";
96
128
  *
97
- * const action = {
98
- * type: "cancel",
99
- * cancels: [
100
- * { a: 0, o: 12345 },
101
- * ],
102
- * } as const;
129
+ * const action = actionSorter.cancel({
130
+ * type: "cancel",
131
+ * cancels: [
132
+ * { a: 0, o: 12345 },
133
+ * ],
134
+ * });
103
135
  * const nonce = Date.now();
104
136
  *
105
- * const actionHash = createL1ActionHash({
106
- * action: actionSorter[action.type](action),
107
- * nonce,
108
- * vaultAddress: "0x...", // optional
109
- * expiresAfter: Date.now() + 10_000, // optional
110
- * });
137
+ * const actionHash = createL1ActionHash({ action, nonce });
111
138
  * ```
112
139
  */
113
140
  export declare function createL1ActionHash(args: {
@@ -116,37 +143,33 @@ export declare function createL1ActionHash(args: {
116
143
  /** The current timestamp in ms. */
117
144
  nonce: number;
118
145
  /** Optional vault address used in the action. */
119
- vaultAddress?: Hex;
146
+ vaultAddress?: `0x${string}`;
120
147
  /** Optional expiration time of the action in ms since the epoch. */
121
148
  expiresAfter?: number;
122
- }): Hex;
149
+ }): `0x${string}`;
123
150
  /**
124
151
  * Sign an L1 action.
125
152
  * @example
126
153
  * ```ts
127
154
  * import { actionSorter, signL1Action } from "@nktkas/hyperliquid/signing";
128
155
  *
129
- * const privateKey = "0x..."; // or `viem`, `ethers`
156
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly`
130
157
  *
131
- * const nonce = Date.now();
132
- * const action = {
133
- * type: "cancel",
134
- * cancels: [
135
- * { a: 0, o: 12345 },
136
- * ],
137
- * } as const;
138
- *
139
- * const signature = await signL1Action({
140
- * wallet: privateKey,
141
- * action: actionSorter[action.type](action),
142
- * nonce,
158
+ * const action = actionSorter.cancel({
159
+ * type: "cancel",
160
+ * cancels: [
161
+ * { a: 0, o: 12345 },
162
+ * ],
143
163
  * });
164
+ * const nonce = Date.now();
165
+ *
166
+ * const signature = await signL1Action({ wallet: privateKey, action, nonce });
144
167
  *
145
168
  * // Send the signed action to the Hyperliquid API
146
169
  * const response = await fetch("https://api.hyperliquid.xyz/exchange", {
147
- * method: "POST",
148
- * headers: { "Content-Type": "application/json" },
149
- * body: JSON.stringify({ action, signature, nonce }),
170
+ * method: "POST",
171
+ * headers: { "Content-Type": "application/json" },
172
+ * body: JSON.stringify({ action, signature, nonce }), // recommended to send the same formatted action
150
173
  * });
151
174
  * const body = await response.json();
152
175
  * ```
@@ -161,7 +184,7 @@ export declare function signL1Action(args: {
161
184
  /** Indicates if the action is for the testnet. (default: false) */
162
185
  isTestnet?: boolean;
163
186
  /** Optional vault address used in the action. */
164
- vaultAddress?: Hex;
187
+ vaultAddress?: `0x${string}`;
165
188
  /** Optional expiration time of the action in ms since the epoch. */
166
189
  expiresAfter?: number;
167
190
  }): Promise<Signature>;
@@ -169,30 +192,30 @@ export declare function signL1Action(args: {
169
192
  * Sign a user-signed action.
170
193
  * @example
171
194
  * ```ts
172
- * import { signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
195
+ * import { actionSorter, signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
173
196
  *
174
- * const privateKey = "0x..."; // or `viem`, `ethers`
197
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly`
175
198
  *
176
- * const action = {
177
- * type: "approveAgent",
178
- * signatureChainId: "0x66eee",
179
- * hyperliquidChain: "Mainnet",
180
- * agentAddress: "0x...",
181
- * agentName: "Agent",
182
- * nonce: Date.now(),
183
- * } as const;
199
+ * const action = actionSorter.approveAgent({
200
+ * type: "approveAgent",
201
+ * signatureChainId: "0x66eee",
202
+ * hyperliquidChain: "Mainnet",
203
+ * agentAddress: "0x...",
204
+ * agentName: "Agent",
205
+ * nonce: Date.now(),
206
+ * });
184
207
  *
185
208
  * const signature = await signUserSignedAction({
186
- * wallet: privateKey,
187
- * action,
188
- * types: userSignedActionEip712Types[action.type],
209
+ * wallet: privateKey,
210
+ * action,
211
+ * types: userSignedActionEip712Types[action.type],
189
212
  * });
190
213
  *
191
214
  * // Send the signed action to the Hyperliquid API
192
215
  * const response = await fetch("https://api.hyperliquid.xyz/exchange", {
193
- * method: "POST",
194
- * headers: { "Content-Type": "application/json" },
195
- * body: JSON.stringify({ action, signature, nonce: action.nonce }),
216
+ * method: "POST",
217
+ * headers: { "Content-Type": "application/json" },
218
+ * body: JSON.stringify({ action, signature, nonce: action.nonce }), // recommended to send the same formatted action
196
219
  * });
197
220
  * const body = await response.json();
198
221
  * ```
@@ -200,11 +223,17 @@ export declare function signL1Action(args: {
200
223
  export declare function signUserSignedAction(args: {
201
224
  /** Wallet to sign the action. */
202
225
  wallet: AbstractWallet;
203
- /** The action to be signed. */
226
+ /** The action to be signed (hex strings must be in lower case). */
204
227
  action: {
205
- signatureChainId: Hex;
228
+ signatureChainId: `0x${string}`;
206
229
  [key: string]: unknown;
207
- };
230
+ } & ({
231
+ payloadMultiSigUser: `0x${string}`;
232
+ outerSigner: `0x${string}`;
233
+ } | {
234
+ payloadMultiSigUser?: undefined;
235
+ outerSigner?: undefined;
236
+ });
208
237
  /** The types of the action (hash depends on key order). */
209
238
  types: {
210
239
  [key: string]: {
@@ -218,38 +247,59 @@ export declare function signUserSignedAction(args: {
218
247
  * @example
219
248
  * ```ts
220
249
  * import { actionSorter, signL1Action, signMultiSigAction } from "@nktkas/hyperliquid/signing";
221
- * import { privateKeyToAccount } from "viem/accounts";
250
+ * import { privateKeyToAccount } from "npm:viem/accounts";
222
251
  *
223
- * const wallet = privateKeyToAccount("0x..."); // or `ethers`, private key with address
252
+ * const wallet = privateKeyToAccount("0x..."); // or ethers, private key directly
224
253
  * const multiSigUser = "0x...";
225
254
  *
255
+ * const action = actionSorter.scheduleCancel({
256
+ * type: "scheduleCancel",
257
+ * time: Date.now() + 10000,
258
+ * });
226
259
  * const nonce = Date.now();
227
- * const action = {
228
- * type: "scheduleCancel",
229
- * time: Date.now() + 10000,
230
- * } as const;
231
- *
232
- * // First, create the required number of signatures
233
- * const signature = await signL1Action({
234
- * wallet,
235
- * action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), actionSorter[action.type](action)],
260
+ *
261
+ * // Create the required number of signatures
262
+ * const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
263
+ * return await signL1Action({
264
+ * wallet: signerPrivKey as `0x${string}`,
265
+ * action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), action],
236
266
  * nonce,
237
- * });
267
+ * });
268
+ * }));
269
+ *
270
+ * // or user-signed action
271
+ * // const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
272
+ * // return await signUserSignedAction({
273
+ * // wallet: signerPrivKey as `0x${string}`,
274
+ * // action: {
275
+ * // ...action,
276
+ * // payloadMultiSigUser: multiSigUser,
277
+ * // outerSigner: wallet.address,
278
+ * // },
279
+ * // types: userSignedActionEip712Types[action.type],
280
+ * // });
281
+ * // }));
238
282
  *
239
283
  * // Then use signatures in the multi-sig action
240
- * const multiSigSignature = await signMultiSigAction({
241
- * wallet,
242
- * action: {
243
- * signatureChainId: "0x66eee",
244
- * signatures: [signature],
245
- * payload: {
246
- * multiSigUser,
247
- * outerSigner: wallet.address,
248
- * action,
249
- * },
250
- * },
251
- * nonce,
284
+ * const multiSigAction = actionSorter.multiSig({
285
+ * type: "multiSig",
286
+ * signatureChainId: "0x66eee",
287
+ * signatures,
288
+ * payload: {
289
+ * multiSigUser,
290
+ * outerSigner: wallet.address,
291
+ * action,
292
+ * },
252
293
  * });
294
+ * const multiSigSignature = await signMultiSigAction({ wallet, action: multiSigAction, nonce });
295
+ *
296
+ * // Send the multi-sig action to the Hyperliquid API
297
+ * const response = await fetch("https://api.hyperliquid.xyz/exchange", {
298
+ * method: "POST",
299
+ * headers: { "Content-Type": "application/json" },
300
+ * body: JSON.stringify({ action: multiSigAction, signature: multiSigSignature, nonce }), // recommended to send the same formatted action
301
+ * });
302
+ * const body = await response.json();
253
303
  * ```
254
304
  */
255
305
  export declare function signMultiSigAction(args: {
@@ -257,7 +307,7 @@ export declare function signMultiSigAction(args: {
257
307
  wallet: AbstractWallet;
258
308
  /** The action to be signed (hash depends on key order). */
259
309
  action: {
260
- signatureChainId: Hex;
310
+ signatureChainId: `0x${string}`;
261
311
  [key: string]: unknown;
262
312
  };
263
313
  /** The current timestamp in ms. */
@@ -265,7 +315,7 @@ export declare function signMultiSigAction(args: {
265
315
  /** Indicates if the action is for the testnet. (default: false) */
266
316
  isTestnet?: boolean;
267
317
  /** Optional vault address used in the action. */
268
- vaultAddress?: Hex;
318
+ vaultAddress?: `0x${string}`;
269
319
  /** Optional expiration time of the action in ms since the epoch. */
270
320
  expiresAfter?: number;
271
321
  }): Promise<Signature>;