@nktkas/hyperliquid 0.15.4 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +47 -89
  2. package/esm/src/base.d.ts +1 -0
  3. package/esm/src/base.d.ts.map +1 -1
  4. package/esm/src/clients/public.d.ts +6 -6
  5. package/esm/src/clients/public.d.ts.map +1 -1
  6. package/esm/src/clients/public.js +237 -54
  7. package/esm/src/clients/wallet.d.ts +121 -94
  8. package/esm/src/clients/wallet.d.ts.map +1 -1
  9. package/esm/src/clients/wallet.js +303 -206
  10. package/esm/src/signing.d.ts +117 -34
  11. package/esm/src/signing.d.ts.map +1 -1
  12. package/esm/src/signing.js +83 -19
  13. package/esm/src/transports/http/http_transport.d.ts +15 -27
  14. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  15. package/esm/src/transports/http/http_transport.js +20 -15
  16. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +1 -3
  17. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  18. package/esm/src/transports/websocket/websocket_transport.d.ts +6 -2
  19. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  20. package/esm/src/types/exchange/requests.d.ts +28 -14
  21. package/esm/src/types/exchange/requests.d.ts.map +1 -1
  22. package/esm/src/types/info/accounts.d.ts +4 -0
  23. package/esm/src/types/info/accounts.d.ts.map +1 -1
  24. package/esm/src/types/info/assets.d.ts +2 -0
  25. package/esm/src/types/info/assets.d.ts.map +1 -1
  26. package/esm/src/types/info/orders.d.ts +28 -20
  27. package/esm/src/types/info/orders.d.ts.map +1 -1
  28. package/esm/src/types/info/requests.d.ts +36 -18
  29. package/esm/src/types/info/requests.d.ts.map +1 -1
  30. package/esm/src/types/info/vaults.d.ts +2 -0
  31. package/esm/src/types/info/vaults.d.ts.map +1 -1
  32. package/esm/src/types/mod.d.ts +23 -0
  33. package/esm/src/types/mod.d.ts.map +1 -1
  34. package/esm/src/types/mod.js +23 -0
  35. package/package.json +4 -1
  36. package/script/src/base.d.ts +1 -0
  37. package/script/src/base.d.ts.map +1 -1
  38. package/script/src/clients/public.d.ts +6 -6
  39. package/script/src/clients/public.d.ts.map +1 -1
  40. package/script/src/clients/public.js +237 -54
  41. package/script/src/clients/wallet.d.ts +121 -94
  42. package/script/src/clients/wallet.d.ts.map +1 -1
  43. package/script/src/clients/wallet.js +302 -205
  44. package/script/src/signing.d.ts +117 -34
  45. package/script/src/signing.d.ts.map +1 -1
  46. package/script/src/signing.js +84 -15
  47. package/script/src/transports/http/http_transport.d.ts +15 -27
  48. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  49. package/script/src/transports/http/http_transport.js +20 -15
  50. package/script/src/transports/websocket/_reconnecting_websocket.d.ts +1 -3
  51. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  52. package/script/src/transports/websocket/websocket_transport.d.ts +6 -2
  53. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  54. package/script/src/types/exchange/requests.d.ts +28 -14
  55. package/script/src/types/exchange/requests.d.ts.map +1 -1
  56. package/script/src/types/info/accounts.d.ts +4 -0
  57. package/script/src/types/info/accounts.d.ts.map +1 -1
  58. package/script/src/types/info/assets.d.ts +2 -0
  59. package/script/src/types/info/assets.d.ts.map +1 -1
  60. package/script/src/types/info/orders.d.ts +28 -20
  61. package/script/src/types/info/orders.d.ts.map +1 -1
  62. package/script/src/types/info/requests.d.ts +36 -18
  63. package/script/src/types/info/requests.d.ts.map +1 -1
  64. package/script/src/types/info/vaults.d.ts +2 -0
  65. package/script/src/types/info/vaults.d.ts.map +1 -1
  66. package/script/src/types/mod.d.ts +23 -0
  67. package/script/src/types/mod.d.ts.map +1 -1
  68. package/script/src/types/mod.js +23 -0
@@ -53,23 +53,38 @@
53
53
  }
54
54
  exports.ApiRequestError = ApiRequestError;
55
55
  // ——————————————— Client ———————————————
56
- /**
57
- * Wallet client for interacting with the Hyperliquid API.
58
- * @typeParam T The transport used to connect to the Hyperliquid API.
59
- * @typeParam W The WalletClient/Account ([viem](https://viem.sh/docs/clients/wallet)) or Signer ([ethers.js](https://docs.ethers.io/v6/api/providers/#Signer)) used for signing transactions.
60
- */
61
- class WalletClient {
62
- /** Gets the next nonce for signing transactions. */
63
- get _nonce() {
56
+ /** Nonce manager for generating unique nonces for signing transactions. */
57
+ class NonceManager {
58
+ constructor() {
59
+ /** The last nonce used for signing transactions. */
60
+ Object.defineProperty(this, "lastNonce", {
61
+ enumerable: true,
62
+ configurable: true,
63
+ writable: true,
64
+ value: 0
65
+ });
66
+ }
67
+ /**
68
+ * Gets the next nonce for signing transactions.
69
+ * @returns The next nonce.
70
+ */
71
+ getNonce() {
64
72
  let nonce = Date.now();
65
- if (nonce <= this._lastNonce) {
66
- nonce = ++this._lastNonce;
73
+ if (nonce <= this.lastNonce) {
74
+ nonce = ++this.lastNonce;
67
75
  }
68
76
  else {
69
- this._lastNonce = nonce;
77
+ this.lastNonce = nonce;
70
78
  }
71
79
  return nonce;
72
80
  }
81
+ }
82
+ /**
83
+ * Wallet client for interacting with the Hyperliquid API.
84
+ * @typeParam T The transport used to connect to the Hyperliquid API.
85
+ * @typeParam W The WalletClient/Account ([viem](https://viem.sh/docs/clients/wallet)) or Signer ([ethers.js](https://docs.ethers.io/v6/api/providers/#Signer)) used for signing transactions.
86
+ */
87
+ class WalletClient {
73
88
  /**
74
89
  * Initialises a new instance.
75
90
  * @param args - The parameters for the client.
@@ -155,18 +170,19 @@
155
170
  writable: true,
156
171
  value: void 0
157
172
  });
158
- /** The last nonce used for signing transactions. */
159
- Object.defineProperty(this, "_lastNonce", {
173
+ /** Function to get the next nonce for signing transactions. */
174
+ Object.defineProperty(this, "nonceManager", {
160
175
  enumerable: true,
161
176
  configurable: true,
162
177
  writable: true,
163
- value: 0
178
+ value: void 0
164
179
  });
165
180
  this.transport = args.transport;
166
181
  this.wallet = args.wallet;
167
182
  this.isTestnet = args.isTestnet ?? false;
168
183
  this.defaultVaultAddress = args.defaultVaultAddress;
169
- this.signatureChainId = args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1");
184
+ this.signatureChainId = args.signatureChainId ?? this._guessSignatureChainId;
185
+ this.nonceManager = args.nonceManager ?? new NonceManager().getNonce;
170
186
  }
171
187
  // ——————————————— Exchange API ———————————————
172
188
  /**
@@ -198,8 +214,10 @@
198
214
  ...args,
199
215
  type: "approveAgent",
200
216
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
201
- signatureChainId: this.signatureChainId,
202
- nonce: args.nonce ?? this._nonce,
217
+ signatureChainId: typeof this.signatureChainId === "string"
218
+ ? this.signatureChainId
219
+ : await this.signatureChainId(),
220
+ nonce: await this.nonceManager(),
203
221
  };
204
222
  // Sign the action
205
223
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -251,8 +269,10 @@
251
269
  ...args,
252
270
  type: "approveBuilderFee",
253
271
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
254
- signatureChainId: this.signatureChainId,
255
- nonce: args.nonce ?? this._nonce,
272
+ signatureChainId: typeof this.signatureChainId === "string"
273
+ ? this.signatureChainId
274
+ : await this.signatureChainId(),
275
+ nonce: await this.nonceManager(),
256
276
  };
257
277
  // Sign the action
258
278
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -314,8 +334,9 @@
314
334
  */
315
335
  async batchModify(args, signal) {
316
336
  // Destructure the parameters
317
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
337
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
318
338
  // Construct an action
339
+ const nonce = await this.nonceManager();
319
340
  const action = {
320
341
  type: "batchModify",
321
342
  modifies: actionArgs.modifies.map((modify) => {
@@ -390,8 +411,9 @@
390
411
  */
391
412
  async cancel(args, signal) {
392
413
  // Destructure the parameters
393
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
414
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
394
415
  // Construct an action
416
+ const nonce = await this.nonceManager();
395
417
  const action = {
396
418
  type: "cancel",
397
419
  cancels: actionArgs.cancels.map((cancel) => ({
@@ -414,6 +436,58 @@
414
436
  this._validateResponse(response);
415
437
  return response;
416
438
  }
439
+ /**
440
+ * Cancel order(s) by cloid.
441
+ * @param args - The parameters for the request.
442
+ * @param signal - An optional abort signal.
443
+ * @returns Successful variant of {@link CancelResponse} without error statuses.
444
+ * @throws {ApiRequestError} When the API returns an error response.
445
+ *
446
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
447
+ * @example
448
+ * ```ts
449
+ * import * as hl from "@nktkas/hyperliquid";
450
+ * import { privateKeyToAccount } from "viem/accounts";
451
+ *
452
+ * const wallet = privateKeyToAccount("0x...");
453
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
454
+ * const client = new hl.WalletClient({ wallet, transport });
455
+ *
456
+ * const result = await client.cancelByCloid({
457
+ * cancels: [{
458
+ * asset: 0,
459
+ * cloid: "0x...", // Client Order ID
460
+ * }],
461
+ * });
462
+ * ```
463
+ */
464
+ async cancelByCloid(args, signal) {
465
+ // Destructure the parameters
466
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
467
+ // Construct an action
468
+ const nonce = await this.nonceManager();
469
+ const action = {
470
+ type: "cancelByCloid",
471
+ cancels: actionArgs.cancels.map((cancel) => ({
472
+ asset: cancel.asset,
473
+ cloid: cancel.cloid,
474
+ })),
475
+ };
476
+ // Sign the action
477
+ const signature = await (0, signing_js_1.signL1Action)({
478
+ wallet: this.wallet,
479
+ action,
480
+ nonce,
481
+ isTestnet: this.isTestnet,
482
+ vaultAddress,
483
+ });
484
+ // Send a request
485
+ const request = { action, signature, nonce, vaultAddress };
486
+ const response = await this.transport.request("exchange", request, signal);
487
+ // Validate a response
488
+ this._validateResponse(response);
489
+ return response;
490
+ }
417
491
  /**
418
492
  * Deposit into staking balance.
419
493
  * @param args - The parameters for the request.
@@ -440,8 +514,10 @@
440
514
  ...args,
441
515
  type: "cDeposit",
442
516
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
443
- signatureChainId: this.signatureChainId,
444
- nonce: args.nonce ?? this._nonce,
517
+ signatureChainId: typeof this.signatureChainId === "string"
518
+ ? this.signatureChainId
519
+ : await this.signatureChainId(),
520
+ nonce: await this.nonceManager(),
445
521
  };
446
522
  // Sign the action
447
523
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -483,10 +559,9 @@
483
559
  * const result = await client.claimRewards();
484
560
  * ```
485
561
  */
486
- async claimRewards(args = {}, signal) {
487
- // Destructure the parameters
488
- const { nonce = this._nonce, } = args;
562
+ async claimRewards(signal) {
489
563
  // Construct an action
564
+ const nonce = await this.nonceManager();
490
565
  const sortedAction = { type: "claimRewards" };
491
566
  // Sign the action
492
567
  const signature = await (0, signing_js_1.signL1Action)({
@@ -503,13 +578,13 @@
503
578
  return response;
504
579
  }
505
580
  /**
506
- * Cancel order(s) by cloid.
581
+ * Create a sub-account.
507
582
  * @param args - The parameters for the request.
508
583
  * @param signal - An optional abort signal.
509
- * @returns Successful variant of {@link CancelResponse} without error statuses.
584
+ * @returns Response for creating a sub-account.
510
585
  * @throws {ApiRequestError} When the API returns an error response.
511
586
  *
512
- * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
587
+ * @see null - no documentation
513
588
  * @example
514
589
  * ```ts
515
590
  * import * as hl from "@nktkas/hyperliquid";
@@ -519,24 +594,15 @@
519
594
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
520
595
  * const client = new hl.WalletClient({ wallet, transport });
521
596
  *
522
- * const result = await client.cancelByCloid({
523
- * cancels: [{
524
- * asset: 0,
525
- * cloid: "0x...", // Client Order ID
526
- * }],
527
- * });
597
+ * const result = await client.createSubAccount({ name: "subAccountName" });
528
598
  * ```
529
599
  */
530
- async cancelByCloid(args, signal) {
531
- // Destructure the parameters
532
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
600
+ async createSubAccount(args, signal) {
533
601
  // Construct an action
602
+ const nonce = await this.nonceManager();
534
603
  const action = {
535
- type: "cancelByCloid",
536
- cancels: actionArgs.cancels.map((cancel) => ({
537
- asset: cancel.asset,
538
- cloid: cancel.cloid,
539
- })),
604
+ type: "createSubAccount",
605
+ name: args.name,
540
606
  };
541
607
  // Sign the action
542
608
  const signature = await (0, signing_js_1.signL1Action)({
@@ -544,72 +610,22 @@
544
610
  action,
545
611
  nonce,
546
612
  isTestnet: this.isTestnet,
547
- vaultAddress,
548
613
  });
549
614
  // Send a request
550
- const request = { action, signature, nonce, vaultAddress };
551
- const response = await this.transport.request("exchange", request, signal);
552
- // Validate a response
553
- this._validateResponse(response);
554
- return response;
555
- }
556
- /**
557
- * Withdraw from staking balance.
558
- * @param args - The parameters for the request.
559
- * @param signal - An optional abort signal.
560
- * @returns Successful response without specific data.
561
- * @throws {ApiRequestError} When the API returns an error response.
562
- *
563
- * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#withdraw-from-staking
564
- * @example
565
- * ```ts
566
- * import * as hl from "@nktkas/hyperliquid";
567
- * import { privateKeyToAccount } from "viem/accounts";
568
- *
569
- * const wallet = privateKeyToAccount("0x...");
570
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
571
- * const client = new hl.WalletClient({ wallet, transport });
572
- *
573
- * const result = await client.cWithdraw({ wei: 1 * 1e8 });
574
- * ```
575
- */
576
- async cWithdraw(args, signal) {
577
- // Construct an action
578
- const action = {
579
- ...args,
580
- type: "cWithdraw",
581
- hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
582
- signatureChainId: this.signatureChainId,
583
- nonce: args.nonce ?? this._nonce,
584
- };
585
- // Sign the action
586
- const signature = await (0, signing_js_1.signUserSignedAction)({
587
- wallet: this.wallet,
588
- action,
589
- types: {
590
- "HyperliquidTransaction:CWithdraw": [
591
- { name: "hyperliquidChain", type: "string" },
592
- { name: "wei", type: "uint64" },
593
- { name: "nonce", type: "uint64" },
594
- ],
595
- },
596
- chainId: parseInt(action.signatureChainId, 16),
597
- });
598
- // Send a request
599
- const request = { action, signature, nonce: action.nonce };
615
+ const request = { action, signature, nonce };
600
616
  const response = await this.transport.request("exchange", request, signal);
601
617
  // Validate a response
602
618
  this._validateResponse(response);
603
619
  return response;
604
620
  }
605
621
  /**
606
- * Configure block type for EVM transactions.
622
+ * Create a vault.
607
623
  * @param args - The parameters for the request.
608
624
  * @param signal - An optional abort signal.
609
- * @returns Response for creating a sub-account.
625
+ * @returns Response for creating a vault.
610
626
  * @throws {ApiRequestError} When the API returns an error response.
611
627
  *
612
- * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm/dual-block-architecture
628
+ * @see null - no documentation
613
629
  * @example
614
630
  * ```ts
615
631
  * import * as hl from "@nktkas/hyperliquid";
@@ -619,16 +635,22 @@
619
635
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
620
636
  * const client = new hl.WalletClient({ wallet, transport });
621
637
  *
622
- * const result = await client.evmUserModify({ usingBigBlocks: true });
638
+ * const result = await client.createVault({
639
+ * name: "VaultName",
640
+ * description: "This is an example of a vault description",
641
+ * initialUsd: 100 * 1e6,
642
+ * });
623
643
  * ```
624
644
  */
625
- async evmUserModify(args, signal) {
626
- // Destructure the parameters
627
- const { nonce = this._nonce, ...actionArgs } = args;
645
+ async createVault(args, signal) {
628
646
  // Construct an action
647
+ const nonce = await this.nonceManager();
629
648
  const action = {
630
- type: "evmUserModify",
631
- usingBigBlocks: actionArgs.usingBigBlocks,
649
+ type: "createVault",
650
+ name: args.name,
651
+ description: args.description,
652
+ initialUsd: args.initialUsd,
653
+ nonce,
632
654
  };
633
655
  // Sign the action
634
656
  const signature = await (0, signing_js_1.signL1Action)({
@@ -645,13 +667,13 @@
645
667
  return response;
646
668
  }
647
669
  /**
648
- * Create a sub-account.
670
+ * Withdraw from staking balance.
649
671
  * @param args - The parameters for the request.
650
672
  * @param signal - An optional abort signal.
651
- * @returns Response for creating a sub-account.
673
+ * @returns Successful response without specific data.
652
674
  * @throws {ApiRequestError} When the API returns an error response.
653
675
  *
654
- * @see null - no documentation
676
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#withdraw-from-staking
655
677
  * @example
656
678
  * ```ts
657
679
  * import * as hl from "@nktkas/hyperliquid";
@@ -661,39 +683,48 @@
661
683
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
662
684
  * const client = new hl.WalletClient({ wallet, transport });
663
685
  *
664
- * const result = await client.createSubAccount({ name: "subAccountName" });
686
+ * const result = await client.cWithdraw({ wei: 1 * 1e8 });
665
687
  * ```
666
688
  */
667
- async createSubAccount(args, signal) {
668
- // Destructure the parameters
669
- const { nonce = this._nonce, ...actionArgs } = args;
689
+ async cWithdraw(args, signal) {
670
690
  // Construct an action
671
691
  const action = {
672
- type: "createSubAccount",
673
- name: actionArgs.name,
692
+ ...args,
693
+ type: "cWithdraw",
694
+ hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
695
+ signatureChainId: typeof this.signatureChainId === "string"
696
+ ? this.signatureChainId
697
+ : await this.signatureChainId(),
698
+ nonce: await this.nonceManager(),
674
699
  };
675
700
  // Sign the action
676
- const signature = await (0, signing_js_1.signL1Action)({
701
+ const signature = await (0, signing_js_1.signUserSignedAction)({
677
702
  wallet: this.wallet,
678
703
  action,
679
- nonce,
680
- isTestnet: this.isTestnet,
704
+ types: {
705
+ "HyperliquidTransaction:CWithdraw": [
706
+ { name: "hyperliquidChain", type: "string" },
707
+ { name: "wei", type: "uint64" },
708
+ { name: "nonce", type: "uint64" },
709
+ ],
710
+ },
711
+ chainId: parseInt(action.signatureChainId, 16),
681
712
  });
682
713
  // Send a request
683
- const request = { action, signature, nonce };
714
+ const request = { action, signature, nonce: action.nonce };
684
715
  const response = await this.transport.request("exchange", request, signal);
685
716
  // Validate a response
686
717
  this._validateResponse(response);
687
718
  return response;
688
719
  }
689
720
  /**
690
- * Create a vault.
721
+ * Configure block type for EVM transactions.
691
722
  * @param args - The parameters for the request.
692
723
  * @param signal - An optional abort signal.
693
- * @returns Response for creating a vault.
724
+ * @returns Response for creating a sub-account.
694
725
  * @throws {ApiRequestError} When the API returns an error response.
695
726
  *
696
- * @see null - no documentation
727
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm/dual-block-architecture
697
728
  * @example
698
729
  * ```ts
699
730
  * import * as hl from "@nktkas/hyperliquid";
@@ -703,23 +734,15 @@
703
734
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
704
735
  * const client = new hl.WalletClient({ wallet, transport });
705
736
  *
706
- * const result = await client.createVault({
707
- * name: "VaultName",
708
- * description: "This is an example of a vault description",
709
- * initialUsd: 100 * 1e6,
710
- * });
737
+ * const result = await client.evmUserModify({ usingBigBlocks: true });
711
738
  * ```
712
739
  */
713
- async createVault(args, signal) {
714
- // Destructure the parameters
715
- const { nonce = this._nonce, ...actionArgs } = args;
740
+ async evmUserModify(args, signal) {
716
741
  // Construct an action
742
+ const nonce = await this.nonceManager();
717
743
  const action = {
718
- type: "createVault",
719
- name: actionArgs.name,
720
- description: actionArgs.description,
721
- initialUsd: actionArgs.initialUsd,
722
- nonce,
744
+ type: "evmUserModify",
745
+ usingBigBlocks: args.usingBigBlocks,
723
746
  };
724
747
  // Sign the action
725
748
  const signature = await (0, signing_js_1.signL1Action)({
@@ -772,8 +795,9 @@
772
795
  */
773
796
  async modify(args, signal) {
774
797
  // Destructure the parameters
775
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
798
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
776
799
  // Construct an action
800
+ const nonce = await this.nonceManager();
777
801
  const action = {
778
802
  type: "modify",
779
803
  oid: actionArgs.oid,
@@ -853,8 +877,9 @@
853
877
  */
854
878
  async order(args, signal) {
855
879
  // Destructure the parameters
856
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
880
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
857
881
  // Construct an action
882
+ const nonce = await this.nonceManager();
858
883
  const action = {
859
884
  type: "order",
860
885
  orders: actionArgs.orders.map((order) => {
@@ -908,6 +933,47 @@
908
933
  this._validateResponse(response);
909
934
  return response;
910
935
  }
936
+ /**
937
+ * Reserve additional rate-limited actions for a fee.
938
+ * @param args - The parameters for the request.
939
+ * @param signal - An optional abort signal.
940
+ * @returns Successful response indicating the weight reservation.
941
+ * @throws {ApiRequestError} When the API returns an error response.
942
+ *
943
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#reserve-additional-actions
944
+ * @example
945
+ * ```ts
946
+ * import * as hl from "@nktkas/hyperliquid";
947
+ * import { privateKeyToAccount } from "viem/accounts";
948
+ *
949
+ * const wallet = privateKeyToAccount("0x...");
950
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
951
+ * const client = new hl.WalletClient({ wallet, transport });
952
+ *
953
+ * const result = await client.reserveRequestWeight({ weight: 10 });
954
+ * ```
955
+ */
956
+ async reserveRequestWeight(args, signal) {
957
+ // Construct an action
958
+ const nonce = await this.nonceManager();
959
+ const action = {
960
+ type: "reserveRequestWeight",
961
+ weight: args.weight,
962
+ };
963
+ // Sign the action
964
+ const signature = await (0, signing_js_1.signL1Action)({
965
+ wallet: this.wallet,
966
+ action,
967
+ nonce,
968
+ isTestnet: this.isTestnet,
969
+ });
970
+ // Send a request
971
+ const request = { action, signature, nonce };
972
+ const response = await this.transport.request("exchange", request, signal);
973
+ // Validate a response
974
+ this._validateResponse(response);
975
+ return response;
976
+ }
911
977
  /**
912
978
  * Schedule a time to cancel all open orders.
913
979
  * @param args - The parameters for the request.
@@ -930,8 +996,9 @@
930
996
  */
931
997
  async scheduleCancel(args = {}, signal) {
932
998
  // Destructure the parameters
933
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
999
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
934
1000
  // Construct an action
1001
+ const nonce = await this.nonceManager();
935
1002
  const action = {
936
1003
  type: "scheduleCancel",
937
1004
  time: actionArgs.time,
@@ -974,12 +1041,11 @@
974
1041
  * ```
975
1042
  */
976
1043
  async setDisplayName(args, signal) {
977
- // Destructure the parameters
978
- const { nonce = this._nonce, ...actionArgs } = args;
979
1044
  // Construct an action
1045
+ const nonce = await this.nonceManager();
980
1046
  const action = {
981
1047
  type: "setDisplayName",
982
- displayName: actionArgs.displayName,
1048
+ displayName: args.displayName,
983
1049
  };
984
1050
  // Sign the action
985
1051
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1016,12 +1082,11 @@
1016
1082
  * ```
1017
1083
  */
1018
1084
  async setReferrer(args, signal) {
1019
- // Destructure the parameters
1020
- const { nonce = this._nonce, ...actionArgs } = args;
1021
1085
  // Construct an action
1086
+ const nonce = await this.nonceManager();
1022
1087
  const action = {
1023
1088
  type: "setReferrer",
1024
- code: actionArgs.code,
1089
+ code: args.code,
1025
1090
  };
1026
1091
  // Sign the action
1027
1092
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1070,48 +1135,47 @@
1070
1135
  * ```
1071
1136
  */
1072
1137
  async spotDeploy(args, signal) {
1073
- // Destructure the parameters
1074
- const { nonce = this._nonce, ...actionArgs } = args;
1075
1138
  // Construct an action
1139
+ const nonce = await this.nonceManager();
1076
1140
  let action;
1077
- if ("registerToken2" in actionArgs) {
1141
+ if ("registerToken2" in args) {
1078
1142
  action = {
1079
1143
  type: "spotDeploy",
1080
1144
  registerToken2: {
1081
1145
  spec: {
1082
- name: actionArgs.registerToken2.spec.name,
1083
- szDecimals: actionArgs.registerToken2.spec.szDecimals,
1084
- weiDecimals: actionArgs.registerToken2.spec.weiDecimals,
1146
+ name: args.registerToken2.spec.name,
1147
+ szDecimals: args.registerToken2.spec.szDecimals,
1148
+ weiDecimals: args.registerToken2.spec.weiDecimals,
1085
1149
  },
1086
- maxGas: actionArgs.registerToken2.maxGas,
1087
- fullName: actionArgs.registerToken2.fullName,
1150
+ maxGas: args.registerToken2.maxGas,
1151
+ fullName: args.registerToken2.fullName,
1088
1152
  },
1089
1153
  };
1090
1154
  }
1091
- else if ("userGenesis" in actionArgs) {
1155
+ else if ("userGenesis" in args) {
1092
1156
  action = {
1093
1157
  type: "spotDeploy",
1094
1158
  userGenesis: {
1095
- token: actionArgs.userGenesis.token,
1096
- userAndWei: actionArgs.userGenesis.userAndWei,
1097
- existingTokenAndWei: actionArgs.userGenesis.existingTokenAndWei,
1159
+ token: args.userGenesis.token,
1160
+ userAndWei: args.userGenesis.userAndWei,
1161
+ existingTokenAndWei: args.userGenesis.existingTokenAndWei,
1098
1162
  },
1099
1163
  };
1100
1164
  }
1101
- else if ("genesis" in actionArgs) {
1165
+ else if ("genesis" in args) {
1102
1166
  action = {
1103
1167
  type: "spotDeploy",
1104
1168
  genesis: {
1105
- token: actionArgs.genesis.token,
1106
- maxSupply: actionArgs.genesis.maxSupply,
1169
+ token: args.genesis.token,
1170
+ maxSupply: args.genesis.maxSupply,
1107
1171
  },
1108
1172
  };
1109
1173
  }
1110
- else if ("registerSpot" in actionArgs) {
1174
+ else if ("registerSpot" in args) {
1111
1175
  action = {
1112
1176
  type: "spotDeploy",
1113
1177
  registerSpot: {
1114
- tokens: actionArgs.registerSpot.tokens,
1178
+ tokens: args.registerSpot.tokens,
1115
1179
  },
1116
1180
  };
1117
1181
  }
@@ -1119,11 +1183,11 @@
1119
1183
  action = {
1120
1184
  type: "spotDeploy",
1121
1185
  registerHyperliquidity: {
1122
- spot: actionArgs.registerHyperliquidity.spot,
1123
- startPx: actionArgs.registerHyperliquidity.startPx,
1124
- orderSz: actionArgs.registerHyperliquidity.orderSz,
1125
- nOrders: actionArgs.registerHyperliquidity.nOrders,
1126
- nSeededLevels: actionArgs.registerHyperliquidity.nSeededLevels,
1186
+ spot: args.registerHyperliquidity.spot,
1187
+ startPx: args.registerHyperliquidity.startPx,
1188
+ orderSz: args.registerHyperliquidity.orderSz,
1189
+ nOrders: args.registerHyperliquidity.nOrders,
1190
+ nSeededLevels: args.registerHyperliquidity.nSeededLevels,
1127
1191
  },
1128
1192
  };
1129
1193
  }
@@ -1171,8 +1235,10 @@
1171
1235
  ...args,
1172
1236
  type: "spotSend",
1173
1237
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
1174
- signatureChainId: this.signatureChainId,
1175
- time: args.time ?? this._nonce,
1238
+ signatureChainId: typeof this.signatureChainId === "string"
1239
+ ? this.signatureChainId
1240
+ : await this.signatureChainId(),
1241
+ time: await this.nonceManager(),
1176
1242
  };
1177
1243
  // Sign the action
1178
1244
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1219,13 +1285,12 @@
1219
1285
  * ```
1220
1286
  */
1221
1287
  async spotUser(args, signal) {
1222
- // Destructure the parameters
1223
- const { nonce = this._nonce, ...actionArgs } = args;
1224
1288
  // Construct an action
1289
+ const nonce = await this.nonceManager();
1225
1290
  const action = {
1226
1291
  type: "spotUser",
1227
1292
  toggleSpotDusting: {
1228
- optOut: actionArgs.toggleSpotDusting.optOut,
1293
+ optOut: args.toggleSpotDusting.optOut,
1229
1294
  },
1230
1295
  };
1231
1296
  // Sign the action
@@ -1268,15 +1333,14 @@
1268
1333
  * ```
1269
1334
  */
1270
1335
  async subAccountSpotTransfer(args, signal) {
1271
- // Destructure the parameters
1272
- const { nonce = this._nonce, ...actionArgs } = args;
1273
1336
  // Construct an action
1337
+ const nonce = await this.nonceManager();
1274
1338
  const action = {
1275
1339
  type: "subAccountSpotTransfer",
1276
- subAccountUser: actionArgs.subAccountUser,
1277
- isDeposit: actionArgs.isDeposit,
1278
- token: actionArgs.token,
1279
- amount: actionArgs.amount,
1340
+ subAccountUser: args.subAccountUser,
1341
+ isDeposit: args.isDeposit,
1342
+ token: args.token,
1343
+ amount: args.amount,
1280
1344
  };
1281
1345
  // Sign the action
1282
1346
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1317,14 +1381,13 @@
1317
1381
  * ```
1318
1382
  */
1319
1383
  async subAccountTransfer(args, signal) {
1320
- // Destructure the parameters
1321
- const { nonce = this._nonce, ...actionArgs } = args;
1322
1384
  // Construct an action
1385
+ const nonce = await this.nonceManager();
1323
1386
  const action = {
1324
1387
  type: "subAccountTransfer",
1325
- subAccountUser: actionArgs.subAccountUser,
1326
- isDeposit: actionArgs.isDeposit,
1327
- usd: actionArgs.usd,
1388
+ subAccountUser: args.subAccountUser,
1389
+ isDeposit: args.isDeposit,
1390
+ usd: args.usd,
1328
1391
  };
1329
1392
  // Sign the action
1330
1393
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1370,8 +1433,10 @@
1370
1433
  ...args,
1371
1434
  type: "tokenDelegate",
1372
1435
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
1373
- signatureChainId: this.signatureChainId,
1374
- nonce: args.nonce ?? this._nonce,
1436
+ signatureChainId: typeof this.signatureChainId === "string"
1437
+ ? this.signatureChainId
1438
+ : await this.signatureChainId(),
1439
+ nonce: await this.nonceManager(),
1375
1440
  };
1376
1441
  // Sign the action
1377
1442
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1420,8 +1485,9 @@
1420
1485
  */
1421
1486
  async twapCancel(args, signal) {
1422
1487
  // Destructure the parameters
1423
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
1488
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
1424
1489
  // Construct an action
1490
+ const nonce = await this.nonceManager();
1425
1491
  const action = {
1426
1492
  type: "twapCancel",
1427
1493
  a: actionArgs.a,
@@ -1471,8 +1537,9 @@
1471
1537
  */
1472
1538
  async twapOrder(args, signal) {
1473
1539
  // Destructure the parameters
1474
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
1540
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
1475
1541
  // Construct an action
1542
+ const nonce = await this.nonceManager();
1476
1543
  const action = {
1477
1544
  type: "twapOrder",
1478
1545
  twap: {
@@ -1525,8 +1592,9 @@
1525
1592
  */
1526
1593
  async updateIsolatedMargin(args, signal) {
1527
1594
  // Destructure the parameters
1528
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
1595
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
1529
1596
  // Construct an action
1597
+ const nonce = await this.nonceManager();
1530
1598
  const action = {
1531
1599
  type: "updateIsolatedMargin",
1532
1600
  asset: actionArgs.asset,
@@ -1574,8 +1642,9 @@
1574
1642
  */
1575
1643
  async updateLeverage(args, signal) {
1576
1644
  // Destructure the parameters
1577
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
1645
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
1578
1646
  // Construct an action
1647
+ const nonce = await this.nonceManager();
1579
1648
  const action = {
1580
1649
  type: "updateLeverage",
1581
1650
  asset: actionArgs.asset,
@@ -1626,8 +1695,10 @@
1626
1695
  ...args,
1627
1696
  type: "usdClassTransfer",
1628
1697
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
1629
- signatureChainId: this.signatureChainId,
1630
- nonce: args.nonce ?? this._nonce,
1698
+ signatureChainId: typeof this.signatureChainId === "string"
1699
+ ? this.signatureChainId
1700
+ : await this.signatureChainId(),
1701
+ nonce: await this.nonceManager(),
1631
1702
  };
1632
1703
  // Sign the action
1633
1704
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1679,8 +1750,10 @@
1679
1750
  ...args,
1680
1751
  type: "usdSend",
1681
1752
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
1682
- signatureChainId: this.signatureChainId,
1683
- time: args.time ?? this._nonce,
1753
+ signatureChainId: typeof this.signatureChainId === "string"
1754
+ ? this.signatureChainId
1755
+ : await this.signatureChainId(),
1756
+ time: await this.nonceManager(),
1684
1757
  };
1685
1758
  // Sign the action
1686
1759
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1727,13 +1800,12 @@
1727
1800
  * ```
1728
1801
  */
1729
1802
  async vaultDistribute(args, signal) {
1730
- // Destructure the parameters
1731
- const { nonce = this._nonce, ...actionArgs } = args;
1732
1803
  // Construct an action
1804
+ const nonce = await this.nonceManager();
1733
1805
  const action = {
1734
1806
  type: "vaultDistribute",
1735
- vaultAddress: actionArgs.vaultAddress,
1736
- usd: actionArgs.usd,
1807
+ vaultAddress: args.vaultAddress,
1808
+ usd: args.usd,
1737
1809
  };
1738
1810
  // Sign the action
1739
1811
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1774,14 +1846,13 @@
1774
1846
  * ```
1775
1847
  */
1776
1848
  async vaultModify(args, signal) {
1777
- // Destructure the parameters
1778
- const { nonce = this._nonce, ...actionArgs } = args;
1779
1849
  // Construct an action
1850
+ const nonce = await this.nonceManager();
1780
1851
  const action = {
1781
1852
  type: "vaultModify",
1782
- vaultAddress: actionArgs.vaultAddress,
1783
- allowDeposits: actionArgs.allowDeposits,
1784
- alwaysCloseOnWithdraw: actionArgs.alwaysCloseOnWithdraw,
1853
+ vaultAddress: args.vaultAddress,
1854
+ allowDeposits: args.allowDeposits,
1855
+ alwaysCloseOnWithdraw: args.alwaysCloseOnWithdraw,
1785
1856
  };
1786
1857
  // Sign the action
1787
1858
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1822,14 +1893,13 @@
1822
1893
  * ```
1823
1894
  */
1824
1895
  async vaultTransfer(args, signal) {
1825
- // Destructure the parameters
1826
- const { nonce = this._nonce, ...actionArgs } = args;
1827
1896
  // Construct an action
1897
+ const nonce = await this.nonceManager();
1828
1898
  const action = {
1829
1899
  type: "vaultTransfer",
1830
- vaultAddress: actionArgs.vaultAddress,
1831
- isDeposit: actionArgs.isDeposit,
1832
- usd: actionArgs.usd,
1900
+ vaultAddress: args.vaultAddress,
1901
+ isDeposit: args.isDeposit,
1902
+ usd: args.usd,
1833
1903
  };
1834
1904
  // Sign the action
1835
1905
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1874,8 +1944,10 @@
1874
1944
  ...args,
1875
1945
  type: "withdraw3",
1876
1946
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
1877
- signatureChainId: this.signatureChainId,
1878
- time: args.time ?? this._nonce,
1947
+ signatureChainId: typeof this.signatureChainId === "string"
1948
+ ? this.signatureChainId
1949
+ : await this.signatureChainId(),
1950
+ time: await this.nonceManager(),
1879
1951
  };
1880
1952
  // Sign the action
1881
1953
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1907,6 +1979,31 @@
1907
1979
  const newFrac = fracPart.replace(/0+$/, "");
1908
1980
  return newFrac ? `${intPart}.${newFrac}` : intPart;
1909
1981
  }
1982
+ /** Guesses the chain ID based on the wallet type or the isTestnet flag. */
1983
+ async _guessSignatureChainId() {
1984
+ // Trying to get chain ID of the wallet
1985
+ if ((0, signing_js_1.isAbstractViemWalletClient)(this.wallet)) {
1986
+ if ("getChainId" in this.wallet && typeof this.wallet.getChainId === "function") {
1987
+ const chainId = await this.wallet.getChainId();
1988
+ return `0x${chainId.toString(16)}`;
1989
+ }
1990
+ }
1991
+ else if ((0, signing_js_1.isAbstractEthersSigner)(this.wallet) || (0, signing_js_1.isAbstractEthersV5Signer)(this.wallet)) {
1992
+ if ("provider" in this.wallet &&
1993
+ typeof this.wallet.provider === "object" && this.wallet.provider !== null &&
1994
+ "getNetwork" in this.wallet.provider &&
1995
+ typeof this.wallet.provider.getNetwork === "function") {
1996
+ const network = await this.wallet.provider.getNetwork();
1997
+ return `0x${network.chainId.toString(16)}`;
1998
+ }
1999
+ }
2000
+ else if ((0, signing_js_1.isAbstractWindowEthereum)(this.wallet)) {
2001
+ const [chainId] = await this.wallet.request({ method: "eth_chainId", params: [] });
2002
+ return chainId;
2003
+ }
2004
+ // Attempt to guess chain ID based on isTestnet
2005
+ return this.isTestnet ? "0x66eee" : "0xa4b1";
2006
+ }
1910
2007
  /** Validate a response from the API. */
1911
2008
  _validateResponse(response) {
1912
2009
  if (response.status === "err") {