@nktkas/hyperliquid 0.16.0 → 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 (50) hide show
  1. package/README.md +44 -92
  2. package/esm/src/clients/wallet.d.ts +117 -90
  3. package/esm/src/clients/wallet.d.ts.map +1 -1
  4. package/esm/src/clients/wallet.js +278 -222
  5. package/esm/src/signing.d.ts +105 -32
  6. package/esm/src/signing.d.ts.map +1 -1
  7. package/esm/src/signing.js +79 -15
  8. package/esm/src/transports/http/http_transport.d.ts +14 -24
  9. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  10. package/esm/src/transports/http/http_transport.js +20 -15
  11. package/esm/src/transports/websocket/websocket_transport.d.ts +6 -2
  12. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  13. package/esm/src/types/exchange/requests.d.ts +28 -14
  14. package/esm/src/types/exchange/requests.d.ts.map +1 -1
  15. package/esm/src/types/info/accounts.d.ts +4 -0
  16. package/esm/src/types/info/accounts.d.ts.map +1 -1
  17. package/esm/src/types/info/assets.d.ts +2 -0
  18. package/esm/src/types/info/assets.d.ts.map +1 -1
  19. package/esm/src/types/info/orders.d.ts +28 -20
  20. package/esm/src/types/info/orders.d.ts.map +1 -1
  21. package/esm/src/types/info/vaults.d.ts +2 -0
  22. package/esm/src/types/info/vaults.d.ts.map +1 -1
  23. package/esm/src/types/mod.d.ts +23 -0
  24. package/esm/src/types/mod.d.ts.map +1 -1
  25. package/esm/src/types/mod.js +23 -0
  26. package/package.json +4 -1
  27. package/script/src/clients/wallet.d.ts +117 -90
  28. package/script/src/clients/wallet.d.ts.map +1 -1
  29. package/script/src/clients/wallet.js +278 -222
  30. package/script/src/signing.d.ts +105 -32
  31. package/script/src/signing.d.ts.map +1 -1
  32. package/script/src/signing.js +80 -16
  33. package/script/src/transports/http/http_transport.d.ts +14 -24
  34. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  35. package/script/src/transports/http/http_transport.js +20 -15
  36. package/script/src/transports/websocket/websocket_transport.d.ts +6 -2
  37. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  38. package/script/src/types/exchange/requests.d.ts +28 -14
  39. package/script/src/types/exchange/requests.d.ts.map +1 -1
  40. package/script/src/types/info/accounts.d.ts +4 -0
  41. package/script/src/types/info/accounts.d.ts.map +1 -1
  42. package/script/src/types/info/assets.d.ts +2 -0
  43. package/script/src/types/info/assets.d.ts.map +1 -1
  44. package/script/src/types/info/orders.d.ts +28 -20
  45. package/script/src/types/info/orders.d.ts.map +1 -1
  46. package/script/src/types/info/vaults.d.ts +2 -0
  47. package/script/src/types/info/vaults.d.ts.map +1 -1
  48. package/script/src/types/mod.d.ts +23 -0
  49. package/script/src/types/mod.d.ts.map +1 -1
  50. 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,41 +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 ?? (async () => {
170
- // Trying to get chain id of the wallet
171
- if ((0, signing_js_1.isAbstractViemWalletClient)(this.wallet)) {
172
- if ("getChainId" in this.wallet && typeof this.wallet.getChainId === "function") {
173
- const chainId = await this.wallet.getChainId();
174
- return `0x${chainId.toString(16)}`;
175
- }
176
- }
177
- else if ((0, signing_js_1.isAbstractEthersSigner)(this.wallet) || (0, signing_js_1.isAbstractEthersV5Signer)(this.wallet)) {
178
- if ("provider" in this.wallet &&
179
- typeof this.wallet.provider === "object" && this.wallet.provider !== null &&
180
- "getNetwork" in this.wallet.provider &&
181
- typeof this.wallet.provider.getNetwork === "function") {
182
- const network = await this.wallet.provider.getNetwork();
183
- return `0x${network.chainId.toString(16)}`;
184
- }
185
- }
186
- else if ((0, signing_js_1.isAbstractWindowEthereum)(this.wallet)) {
187
- const [chainId] = await this.wallet.request({ method: "eth_chainId", params: [] });
188
- return chainId;
189
- }
190
- // Trying to guess chain id based on isTestnet
191
- return this.isTestnet ? "0x66eee" : "0xa4b1";
192
- });
184
+ this.signatureChainId = args.signatureChainId ?? this._guessSignatureChainId;
185
+ this.nonceManager = args.nonceManager ?? new NonceManager().getNonce;
193
186
  }
194
187
  // ——————————————— Exchange API ———————————————
195
188
  /**
@@ -224,7 +217,7 @@
224
217
  signatureChainId: typeof this.signatureChainId === "string"
225
218
  ? this.signatureChainId
226
219
  : await this.signatureChainId(),
227
- nonce: args.nonce ?? this._nonce,
220
+ nonce: await this.nonceManager(),
228
221
  };
229
222
  // Sign the action
230
223
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -279,7 +272,7 @@
279
272
  signatureChainId: typeof this.signatureChainId === "string"
280
273
  ? this.signatureChainId
281
274
  : await this.signatureChainId(),
282
- nonce: args.nonce ?? this._nonce,
275
+ nonce: await this.nonceManager(),
283
276
  };
284
277
  // Sign the action
285
278
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -341,8 +334,9 @@
341
334
  */
342
335
  async batchModify(args, signal) {
343
336
  // Destructure the parameters
344
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
337
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
345
338
  // Construct an action
339
+ const nonce = await this.nonceManager();
346
340
  const action = {
347
341
  type: "batchModify",
348
342
  modifies: actionArgs.modifies.map((modify) => {
@@ -417,8 +411,9 @@
417
411
  */
418
412
  async cancel(args, signal) {
419
413
  // Destructure the parameters
420
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
414
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
421
415
  // Construct an action
416
+ const nonce = await this.nonceManager();
422
417
  const action = {
423
418
  type: "cancel",
424
419
  cancels: actionArgs.cancels.map((cancel) => ({
@@ -441,6 +436,58 @@
441
436
  this._validateResponse(response);
442
437
  return response;
443
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
+ }
444
491
  /**
445
492
  * Deposit into staking balance.
446
493
  * @param args - The parameters for the request.
@@ -470,7 +517,7 @@
470
517
  signatureChainId: typeof this.signatureChainId === "string"
471
518
  ? this.signatureChainId
472
519
  : await this.signatureChainId(),
473
- nonce: args.nonce ?? this._nonce,
520
+ nonce: await this.nonceManager(),
474
521
  };
475
522
  // Sign the action
476
523
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -512,10 +559,9 @@
512
559
  * const result = await client.claimRewards();
513
560
  * ```
514
561
  */
515
- async claimRewards(args = {}, signal) {
516
- // Destructure the parameters
517
- const { nonce = this._nonce, } = args;
562
+ async claimRewards(signal) {
518
563
  // Construct an action
564
+ const nonce = await this.nonceManager();
519
565
  const sortedAction = { type: "claimRewards" };
520
566
  // Sign the action
521
567
  const signature = await (0, signing_js_1.signL1Action)({
@@ -532,13 +578,13 @@
532
578
  return response;
533
579
  }
534
580
  /**
535
- * Cancel order(s) by cloid.
581
+ * Create a sub-account.
536
582
  * @param args - The parameters for the request.
537
583
  * @param signal - An optional abort signal.
538
- * @returns Successful variant of {@link CancelResponse} without error statuses.
584
+ * @returns Response for creating a sub-account.
539
585
  * @throws {ApiRequestError} When the API returns an error response.
540
586
  *
541
- * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
587
+ * @see null - no documentation
542
588
  * @example
543
589
  * ```ts
544
590
  * import * as hl from "@nktkas/hyperliquid";
@@ -548,24 +594,15 @@
548
594
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
549
595
  * const client = new hl.WalletClient({ wallet, transport });
550
596
  *
551
- * const result = await client.cancelByCloid({
552
- * cancels: [{
553
- * asset: 0,
554
- * cloid: "0x...", // Client Order ID
555
- * }],
556
- * });
597
+ * const result = await client.createSubAccount({ name: "subAccountName" });
557
598
  * ```
558
599
  */
559
- async cancelByCloid(args, signal) {
560
- // Destructure the parameters
561
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
600
+ async createSubAccount(args, signal) {
562
601
  // Construct an action
602
+ const nonce = await this.nonceManager();
563
603
  const action = {
564
- type: "cancelByCloid",
565
- cancels: actionArgs.cancels.map((cancel) => ({
566
- asset: cancel.asset,
567
- cloid: cancel.cloid,
568
- })),
604
+ type: "createSubAccount",
605
+ name: args.name,
569
606
  };
570
607
  // Sign the action
571
608
  const signature = await (0, signing_js_1.signL1Action)({
@@ -573,74 +610,22 @@
573
610
  action,
574
611
  nonce,
575
612
  isTestnet: this.isTestnet,
576
- vaultAddress,
577
613
  });
578
614
  // Send a request
579
- const request = { action, signature, nonce, vaultAddress };
580
- const response = await this.transport.request("exchange", request, signal);
581
- // Validate a response
582
- this._validateResponse(response);
583
- return response;
584
- }
585
- /**
586
- * Withdraw from staking balance.
587
- * @param args - The parameters for the request.
588
- * @param signal - An optional abort signal.
589
- * @returns Successful response without specific data.
590
- * @throws {ApiRequestError} When the API returns an error response.
591
- *
592
- * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#withdraw-from-staking
593
- * @example
594
- * ```ts
595
- * import * as hl from "@nktkas/hyperliquid";
596
- * import { privateKeyToAccount } from "viem/accounts";
597
- *
598
- * const wallet = privateKeyToAccount("0x...");
599
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
600
- * const client = new hl.WalletClient({ wallet, transport });
601
- *
602
- * const result = await client.cWithdraw({ wei: 1 * 1e8 });
603
- * ```
604
- */
605
- async cWithdraw(args, signal) {
606
- // Construct an action
607
- const action = {
608
- ...args,
609
- type: "cWithdraw",
610
- hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
611
- signatureChainId: typeof this.signatureChainId === "string"
612
- ? this.signatureChainId
613
- : await this.signatureChainId(),
614
- nonce: args.nonce ?? this._nonce,
615
- };
616
- // Sign the action
617
- const signature = await (0, signing_js_1.signUserSignedAction)({
618
- wallet: this.wallet,
619
- action,
620
- types: {
621
- "HyperliquidTransaction:CWithdraw": [
622
- { name: "hyperliquidChain", type: "string" },
623
- { name: "wei", type: "uint64" },
624
- { name: "nonce", type: "uint64" },
625
- ],
626
- },
627
- chainId: parseInt(action.signatureChainId, 16),
628
- });
629
- // Send a request
630
- const request = { action, signature, nonce: action.nonce };
615
+ const request = { action, signature, nonce };
631
616
  const response = await this.transport.request("exchange", request, signal);
632
617
  // Validate a response
633
618
  this._validateResponse(response);
634
619
  return response;
635
620
  }
636
621
  /**
637
- * Configure block type for EVM transactions.
622
+ * Create a vault.
638
623
  * @param args - The parameters for the request.
639
624
  * @param signal - An optional abort signal.
640
- * @returns Response for creating a sub-account.
625
+ * @returns Response for creating a vault.
641
626
  * @throws {ApiRequestError} When the API returns an error response.
642
627
  *
643
- * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm/dual-block-architecture
628
+ * @see null - no documentation
644
629
  * @example
645
630
  * ```ts
646
631
  * import * as hl from "@nktkas/hyperliquid";
@@ -650,16 +635,22 @@
650
635
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
651
636
  * const client = new hl.WalletClient({ wallet, transport });
652
637
  *
653
- * 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
+ * });
654
643
  * ```
655
644
  */
656
- async evmUserModify(args, signal) {
657
- // Destructure the parameters
658
- const { nonce = this._nonce, ...actionArgs } = args;
645
+ async createVault(args, signal) {
659
646
  // Construct an action
647
+ const nonce = await this.nonceManager();
660
648
  const action = {
661
- type: "evmUserModify",
662
- usingBigBlocks: actionArgs.usingBigBlocks,
649
+ type: "createVault",
650
+ name: args.name,
651
+ description: args.description,
652
+ initialUsd: args.initialUsd,
653
+ nonce,
663
654
  };
664
655
  // Sign the action
665
656
  const signature = await (0, signing_js_1.signL1Action)({
@@ -676,13 +667,13 @@
676
667
  return response;
677
668
  }
678
669
  /**
679
- * Create a sub-account.
670
+ * Withdraw from staking balance.
680
671
  * @param args - The parameters for the request.
681
672
  * @param signal - An optional abort signal.
682
- * @returns Response for creating a sub-account.
673
+ * @returns Successful response without specific data.
683
674
  * @throws {ApiRequestError} When the API returns an error response.
684
675
  *
685
- * @see null - no documentation
676
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#withdraw-from-staking
686
677
  * @example
687
678
  * ```ts
688
679
  * import * as hl from "@nktkas/hyperliquid";
@@ -692,39 +683,48 @@
692
683
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
693
684
  * const client = new hl.WalletClient({ wallet, transport });
694
685
  *
695
- * const result = await client.createSubAccount({ name: "subAccountName" });
686
+ * const result = await client.cWithdraw({ wei: 1 * 1e8 });
696
687
  * ```
697
688
  */
698
- async createSubAccount(args, signal) {
699
- // Destructure the parameters
700
- const { nonce = this._nonce, ...actionArgs } = args;
689
+ async cWithdraw(args, signal) {
701
690
  // Construct an action
702
691
  const action = {
703
- type: "createSubAccount",
704
- 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(),
705
699
  };
706
700
  // Sign the action
707
- const signature = await (0, signing_js_1.signL1Action)({
701
+ const signature = await (0, signing_js_1.signUserSignedAction)({
708
702
  wallet: this.wallet,
709
703
  action,
710
- nonce,
711
- 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),
712
712
  });
713
713
  // Send a request
714
- const request = { action, signature, nonce };
714
+ const request = { action, signature, nonce: action.nonce };
715
715
  const response = await this.transport.request("exchange", request, signal);
716
716
  // Validate a response
717
717
  this._validateResponse(response);
718
718
  return response;
719
719
  }
720
720
  /**
721
- * Create a vault.
721
+ * Configure block type for EVM transactions.
722
722
  * @param args - The parameters for the request.
723
723
  * @param signal - An optional abort signal.
724
- * @returns Response for creating a vault.
724
+ * @returns Response for creating a sub-account.
725
725
  * @throws {ApiRequestError} When the API returns an error response.
726
726
  *
727
- * @see null - no documentation
727
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm/dual-block-architecture
728
728
  * @example
729
729
  * ```ts
730
730
  * import * as hl from "@nktkas/hyperliquid";
@@ -734,23 +734,15 @@
734
734
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
735
735
  * const client = new hl.WalletClient({ wallet, transport });
736
736
  *
737
- * const result = await client.createVault({
738
- * name: "VaultName",
739
- * description: "This is an example of a vault description",
740
- * initialUsd: 100 * 1e6,
741
- * });
737
+ * const result = await client.evmUserModify({ usingBigBlocks: true });
742
738
  * ```
743
739
  */
744
- async createVault(args, signal) {
745
- // Destructure the parameters
746
- const { nonce = this._nonce, ...actionArgs } = args;
740
+ async evmUserModify(args, signal) {
747
741
  // Construct an action
742
+ const nonce = await this.nonceManager();
748
743
  const action = {
749
- type: "createVault",
750
- name: actionArgs.name,
751
- description: actionArgs.description,
752
- initialUsd: actionArgs.initialUsd,
753
- nonce,
744
+ type: "evmUserModify",
745
+ usingBigBlocks: args.usingBigBlocks,
754
746
  };
755
747
  // Sign the action
756
748
  const signature = await (0, signing_js_1.signL1Action)({
@@ -803,8 +795,9 @@
803
795
  */
804
796
  async modify(args, signal) {
805
797
  // Destructure the parameters
806
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
798
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
807
799
  // Construct an action
800
+ const nonce = await this.nonceManager();
808
801
  const action = {
809
802
  type: "modify",
810
803
  oid: actionArgs.oid,
@@ -884,8 +877,9 @@
884
877
  */
885
878
  async order(args, signal) {
886
879
  // Destructure the parameters
887
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
880
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
888
881
  // Construct an action
882
+ const nonce = await this.nonceManager();
889
883
  const action = {
890
884
  type: "order",
891
885
  orders: actionArgs.orders.map((order) => {
@@ -939,6 +933,47 @@
939
933
  this._validateResponse(response);
940
934
  return response;
941
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
+ }
942
977
  /**
943
978
  * Schedule a time to cancel all open orders.
944
979
  * @param args - The parameters for the request.
@@ -961,8 +996,9 @@
961
996
  */
962
997
  async scheduleCancel(args = {}, signal) {
963
998
  // Destructure the parameters
964
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
999
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
965
1000
  // Construct an action
1001
+ const nonce = await this.nonceManager();
966
1002
  const action = {
967
1003
  type: "scheduleCancel",
968
1004
  time: actionArgs.time,
@@ -1005,12 +1041,11 @@
1005
1041
  * ```
1006
1042
  */
1007
1043
  async setDisplayName(args, signal) {
1008
- // Destructure the parameters
1009
- const { nonce = this._nonce, ...actionArgs } = args;
1010
1044
  // Construct an action
1045
+ const nonce = await this.nonceManager();
1011
1046
  const action = {
1012
1047
  type: "setDisplayName",
1013
- displayName: actionArgs.displayName,
1048
+ displayName: args.displayName,
1014
1049
  };
1015
1050
  // Sign the action
1016
1051
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1047,12 +1082,11 @@
1047
1082
  * ```
1048
1083
  */
1049
1084
  async setReferrer(args, signal) {
1050
- // Destructure the parameters
1051
- const { nonce = this._nonce, ...actionArgs } = args;
1052
1085
  // Construct an action
1086
+ const nonce = await this.nonceManager();
1053
1087
  const action = {
1054
1088
  type: "setReferrer",
1055
- code: actionArgs.code,
1089
+ code: args.code,
1056
1090
  };
1057
1091
  // Sign the action
1058
1092
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1101,48 +1135,47 @@
1101
1135
  * ```
1102
1136
  */
1103
1137
  async spotDeploy(args, signal) {
1104
- // Destructure the parameters
1105
- const { nonce = this._nonce, ...actionArgs } = args;
1106
1138
  // Construct an action
1139
+ const nonce = await this.nonceManager();
1107
1140
  let action;
1108
- if ("registerToken2" in actionArgs) {
1141
+ if ("registerToken2" in args) {
1109
1142
  action = {
1110
1143
  type: "spotDeploy",
1111
1144
  registerToken2: {
1112
1145
  spec: {
1113
- name: actionArgs.registerToken2.spec.name,
1114
- szDecimals: actionArgs.registerToken2.spec.szDecimals,
1115
- weiDecimals: actionArgs.registerToken2.spec.weiDecimals,
1146
+ name: args.registerToken2.spec.name,
1147
+ szDecimals: args.registerToken2.spec.szDecimals,
1148
+ weiDecimals: args.registerToken2.spec.weiDecimals,
1116
1149
  },
1117
- maxGas: actionArgs.registerToken2.maxGas,
1118
- fullName: actionArgs.registerToken2.fullName,
1150
+ maxGas: args.registerToken2.maxGas,
1151
+ fullName: args.registerToken2.fullName,
1119
1152
  },
1120
1153
  };
1121
1154
  }
1122
- else if ("userGenesis" in actionArgs) {
1155
+ else if ("userGenesis" in args) {
1123
1156
  action = {
1124
1157
  type: "spotDeploy",
1125
1158
  userGenesis: {
1126
- token: actionArgs.userGenesis.token,
1127
- userAndWei: actionArgs.userGenesis.userAndWei,
1128
- existingTokenAndWei: actionArgs.userGenesis.existingTokenAndWei,
1159
+ token: args.userGenesis.token,
1160
+ userAndWei: args.userGenesis.userAndWei,
1161
+ existingTokenAndWei: args.userGenesis.existingTokenAndWei,
1129
1162
  },
1130
1163
  };
1131
1164
  }
1132
- else if ("genesis" in actionArgs) {
1165
+ else if ("genesis" in args) {
1133
1166
  action = {
1134
1167
  type: "spotDeploy",
1135
1168
  genesis: {
1136
- token: actionArgs.genesis.token,
1137
- maxSupply: actionArgs.genesis.maxSupply,
1169
+ token: args.genesis.token,
1170
+ maxSupply: args.genesis.maxSupply,
1138
1171
  },
1139
1172
  };
1140
1173
  }
1141
- else if ("registerSpot" in actionArgs) {
1174
+ else if ("registerSpot" in args) {
1142
1175
  action = {
1143
1176
  type: "spotDeploy",
1144
1177
  registerSpot: {
1145
- tokens: actionArgs.registerSpot.tokens,
1178
+ tokens: args.registerSpot.tokens,
1146
1179
  },
1147
1180
  };
1148
1181
  }
@@ -1150,11 +1183,11 @@
1150
1183
  action = {
1151
1184
  type: "spotDeploy",
1152
1185
  registerHyperliquidity: {
1153
- spot: actionArgs.registerHyperliquidity.spot,
1154
- startPx: actionArgs.registerHyperliquidity.startPx,
1155
- orderSz: actionArgs.registerHyperliquidity.orderSz,
1156
- nOrders: actionArgs.registerHyperliquidity.nOrders,
1157
- 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,
1158
1191
  },
1159
1192
  };
1160
1193
  }
@@ -1205,7 +1238,7 @@
1205
1238
  signatureChainId: typeof this.signatureChainId === "string"
1206
1239
  ? this.signatureChainId
1207
1240
  : await this.signatureChainId(),
1208
- time: args.time ?? this._nonce,
1241
+ time: await this.nonceManager(),
1209
1242
  };
1210
1243
  // Sign the action
1211
1244
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1252,13 +1285,12 @@
1252
1285
  * ```
1253
1286
  */
1254
1287
  async spotUser(args, signal) {
1255
- // Destructure the parameters
1256
- const { nonce = this._nonce, ...actionArgs } = args;
1257
1288
  // Construct an action
1289
+ const nonce = await this.nonceManager();
1258
1290
  const action = {
1259
1291
  type: "spotUser",
1260
1292
  toggleSpotDusting: {
1261
- optOut: actionArgs.toggleSpotDusting.optOut,
1293
+ optOut: args.toggleSpotDusting.optOut,
1262
1294
  },
1263
1295
  };
1264
1296
  // Sign the action
@@ -1301,15 +1333,14 @@
1301
1333
  * ```
1302
1334
  */
1303
1335
  async subAccountSpotTransfer(args, signal) {
1304
- // Destructure the parameters
1305
- const { nonce = this._nonce, ...actionArgs } = args;
1306
1336
  // Construct an action
1337
+ const nonce = await this.nonceManager();
1307
1338
  const action = {
1308
1339
  type: "subAccountSpotTransfer",
1309
- subAccountUser: actionArgs.subAccountUser,
1310
- isDeposit: actionArgs.isDeposit,
1311
- token: actionArgs.token,
1312
- amount: actionArgs.amount,
1340
+ subAccountUser: args.subAccountUser,
1341
+ isDeposit: args.isDeposit,
1342
+ token: args.token,
1343
+ amount: args.amount,
1313
1344
  };
1314
1345
  // Sign the action
1315
1346
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1350,14 +1381,13 @@
1350
1381
  * ```
1351
1382
  */
1352
1383
  async subAccountTransfer(args, signal) {
1353
- // Destructure the parameters
1354
- const { nonce = this._nonce, ...actionArgs } = args;
1355
1384
  // Construct an action
1385
+ const nonce = await this.nonceManager();
1356
1386
  const action = {
1357
1387
  type: "subAccountTransfer",
1358
- subAccountUser: actionArgs.subAccountUser,
1359
- isDeposit: actionArgs.isDeposit,
1360
- usd: actionArgs.usd,
1388
+ subAccountUser: args.subAccountUser,
1389
+ isDeposit: args.isDeposit,
1390
+ usd: args.usd,
1361
1391
  };
1362
1392
  // Sign the action
1363
1393
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1406,7 +1436,7 @@
1406
1436
  signatureChainId: typeof this.signatureChainId === "string"
1407
1437
  ? this.signatureChainId
1408
1438
  : await this.signatureChainId(),
1409
- nonce: args.nonce ?? this._nonce,
1439
+ nonce: await this.nonceManager(),
1410
1440
  };
1411
1441
  // Sign the action
1412
1442
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1455,8 +1485,9 @@
1455
1485
  */
1456
1486
  async twapCancel(args, signal) {
1457
1487
  // Destructure the parameters
1458
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
1488
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
1459
1489
  // Construct an action
1490
+ const nonce = await this.nonceManager();
1460
1491
  const action = {
1461
1492
  type: "twapCancel",
1462
1493
  a: actionArgs.a,
@@ -1506,8 +1537,9 @@
1506
1537
  */
1507
1538
  async twapOrder(args, signal) {
1508
1539
  // Destructure the parameters
1509
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
1540
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
1510
1541
  // Construct an action
1542
+ const nonce = await this.nonceManager();
1511
1543
  const action = {
1512
1544
  type: "twapOrder",
1513
1545
  twap: {
@@ -1560,8 +1592,9 @@
1560
1592
  */
1561
1593
  async updateIsolatedMargin(args, signal) {
1562
1594
  // Destructure the parameters
1563
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
1595
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
1564
1596
  // Construct an action
1597
+ const nonce = await this.nonceManager();
1565
1598
  const action = {
1566
1599
  type: "updateIsolatedMargin",
1567
1600
  asset: actionArgs.asset,
@@ -1609,8 +1642,9 @@
1609
1642
  */
1610
1643
  async updateLeverage(args, signal) {
1611
1644
  // Destructure the parameters
1612
- const { vaultAddress = this.defaultVaultAddress, nonce = this._nonce, ...actionArgs } = args;
1645
+ const { vaultAddress = this.defaultVaultAddress, ...actionArgs } = args;
1613
1646
  // Construct an action
1647
+ const nonce = await this.nonceManager();
1614
1648
  const action = {
1615
1649
  type: "updateLeverage",
1616
1650
  asset: actionArgs.asset,
@@ -1664,7 +1698,7 @@
1664
1698
  signatureChainId: typeof this.signatureChainId === "string"
1665
1699
  ? this.signatureChainId
1666
1700
  : await this.signatureChainId(),
1667
- nonce: args.nonce ?? this._nonce,
1701
+ nonce: await this.nonceManager(),
1668
1702
  };
1669
1703
  // Sign the action
1670
1704
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1719,7 +1753,7 @@
1719
1753
  signatureChainId: typeof this.signatureChainId === "string"
1720
1754
  ? this.signatureChainId
1721
1755
  : await this.signatureChainId(),
1722
- time: args.time ?? this._nonce,
1756
+ time: await this.nonceManager(),
1723
1757
  };
1724
1758
  // Sign the action
1725
1759
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1766,13 +1800,12 @@
1766
1800
  * ```
1767
1801
  */
1768
1802
  async vaultDistribute(args, signal) {
1769
- // Destructure the parameters
1770
- const { nonce = this._nonce, ...actionArgs } = args;
1771
1803
  // Construct an action
1804
+ const nonce = await this.nonceManager();
1772
1805
  const action = {
1773
1806
  type: "vaultDistribute",
1774
- vaultAddress: actionArgs.vaultAddress,
1775
- usd: actionArgs.usd,
1807
+ vaultAddress: args.vaultAddress,
1808
+ usd: args.usd,
1776
1809
  };
1777
1810
  // Sign the action
1778
1811
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1813,14 +1846,13 @@
1813
1846
  * ```
1814
1847
  */
1815
1848
  async vaultModify(args, signal) {
1816
- // Destructure the parameters
1817
- const { nonce = this._nonce, ...actionArgs } = args;
1818
1849
  // Construct an action
1850
+ const nonce = await this.nonceManager();
1819
1851
  const action = {
1820
1852
  type: "vaultModify",
1821
- vaultAddress: actionArgs.vaultAddress,
1822
- allowDeposits: actionArgs.allowDeposits,
1823
- alwaysCloseOnWithdraw: actionArgs.alwaysCloseOnWithdraw,
1853
+ vaultAddress: args.vaultAddress,
1854
+ allowDeposits: args.allowDeposits,
1855
+ alwaysCloseOnWithdraw: args.alwaysCloseOnWithdraw,
1824
1856
  };
1825
1857
  // Sign the action
1826
1858
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1861,14 +1893,13 @@
1861
1893
  * ```
1862
1894
  */
1863
1895
  async vaultTransfer(args, signal) {
1864
- // Destructure the parameters
1865
- const { nonce = this._nonce, ...actionArgs } = args;
1866
1896
  // Construct an action
1897
+ const nonce = await this.nonceManager();
1867
1898
  const action = {
1868
1899
  type: "vaultTransfer",
1869
- vaultAddress: actionArgs.vaultAddress,
1870
- isDeposit: actionArgs.isDeposit,
1871
- usd: actionArgs.usd,
1900
+ vaultAddress: args.vaultAddress,
1901
+ isDeposit: args.isDeposit,
1902
+ usd: args.usd,
1872
1903
  };
1873
1904
  // Sign the action
1874
1905
  const signature = await (0, signing_js_1.signL1Action)({
@@ -1916,7 +1947,7 @@
1916
1947
  signatureChainId: typeof this.signatureChainId === "string"
1917
1948
  ? this.signatureChainId
1918
1949
  : await this.signatureChainId(),
1919
- time: args.time ?? this._nonce,
1950
+ time: await this.nonceManager(),
1920
1951
  };
1921
1952
  // Sign the action
1922
1953
  const signature = await (0, signing_js_1.signUserSignedAction)({
@@ -1948,6 +1979,31 @@
1948
1979
  const newFrac = fracPart.replace(/0+$/, "");
1949
1980
  return newFrac ? `${intPart}.${newFrac}` : intPart;
1950
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
+ }
1951
2007
  /** Validate a response from the API. */
1952
2008
  _validateResponse(response) {
1953
2009
  if (response.status === "err") {