@nktkas/hyperliquid 0.25.0-beta.3 → 0.25.0-beta.4

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 (223) hide show
  1. package/README.md +108 -116
  2. package/esm/bin/_utils.d.ts +80 -0
  3. package/esm/bin/_utils.d.ts.map +1 -0
  4. package/esm/bin/_utils.js +112 -0
  5. package/esm/bin/_utils.js.map +1 -0
  6. package/esm/bin/cli.js +43 -161
  7. package/esm/bin/cli.js.map +1 -1
  8. package/esm/src/clients/exchange.d.ts +93 -93
  9. package/esm/src/clients/exchange.d.ts.map +1 -1
  10. package/esm/src/clients/exchange.js +63 -58
  11. package/esm/src/clients/exchange.js.map +1 -1
  12. package/esm/src/clients/info.d.ts +113 -113
  13. package/esm/src/clients/info.d.ts.map +1 -1
  14. package/esm/src/clients/info.js +70 -73
  15. package/esm/src/clients/info.js.map +1 -1
  16. package/esm/src/clients/multiSign.d.ts +3 -3
  17. package/esm/src/clients/multiSign.d.ts.map +1 -1
  18. package/esm/src/clients/multiSign.js +4 -2
  19. package/esm/src/clients/multiSign.js.map +1 -1
  20. package/esm/src/clients/subscription.d.ts +23 -23
  21. package/esm/src/clients/subscription.d.ts.map +1 -1
  22. package/esm/src/clients/subscription.js +8 -11
  23. package/esm/src/clients/subscription.js.map +1 -1
  24. package/esm/src/schemas/_base.d.ts +6 -8
  25. package/esm/src/schemas/_base.d.ts.map +1 -1
  26. package/esm/src/schemas/_base.js +5 -28
  27. package/esm/src/schemas/_base.js.map +1 -1
  28. package/esm/src/schemas/exchange/requests.d.ts +1676 -1657
  29. package/esm/src/schemas/exchange/requests.d.ts.map +1 -1
  30. package/esm/src/schemas/exchange/requests.js +195 -199
  31. package/esm/src/schemas/exchange/requests.js.map +1 -1
  32. package/esm/src/schemas/exchange/responses.d.ts +10 -10
  33. package/esm/src/schemas/exchange/responses.js +3 -3
  34. package/esm/src/schemas/exchange/responses.js.map +1 -1
  35. package/esm/src/schemas/explorer/requests.d.ts +2 -2
  36. package/esm/src/schemas/explorer/requests.js +3 -3
  37. package/esm/src/schemas/explorer/requests.js.map +1 -1
  38. package/esm/src/schemas/explorer/responses.d.ts +16 -16
  39. package/esm/src/schemas/explorer/responses.js +3 -3
  40. package/esm/src/schemas/explorer/responses.js.map +1 -1
  41. package/esm/src/schemas/info/accounts.d.ts +298 -298
  42. package/esm/src/schemas/info/accounts.js +24 -24
  43. package/esm/src/schemas/info/accounts.js.map +1 -1
  44. package/esm/src/schemas/info/assets.d.ts +110 -110
  45. package/esm/src/schemas/info/assets.js +9 -9
  46. package/esm/src/schemas/info/assets.js.map +1 -1
  47. package/esm/src/schemas/info/markets.d.ts +25 -25
  48. package/esm/src/schemas/info/markets.js +3 -3
  49. package/esm/src/schemas/info/markets.js.map +1 -1
  50. package/esm/src/schemas/info/orders.d.ts +104 -104
  51. package/esm/src/schemas/info/orders.js +3 -3
  52. package/esm/src/schemas/info/orders.js.map +1 -1
  53. package/esm/src/schemas/info/requests.d.ts +32 -32
  54. package/esm/src/schemas/info/requests.js +55 -55
  55. package/esm/src/schemas/info/requests.js.map +1 -1
  56. package/esm/src/schemas/info/validators.d.ts +27 -27
  57. package/esm/src/schemas/info/validators.js +6 -6
  58. package/esm/src/schemas/info/validators.js.map +1 -1
  59. package/esm/src/schemas/info/vaults.d.ts +46 -46
  60. package/esm/src/schemas/info/vaults.js +10 -10
  61. package/esm/src/schemas/info/vaults.js.map +1 -1
  62. package/esm/src/schemas/subscriptions/requests.d.ts +4 -4
  63. package/esm/src/schemas/subscriptions/requests.js +17 -17
  64. package/esm/src/schemas/subscriptions/requests.js.map +1 -1
  65. package/esm/src/schemas/subscriptions/responses.d.ts +401 -401
  66. package/esm/src/schemas/subscriptions/responses.js +14 -14
  67. package/esm/src/schemas/subscriptions/responses.js.map +1 -1
  68. package/esm/src/signing/mod.js +4 -4
  69. package/esm/src/signing/mod.js.map +1 -1
  70. package/esm/src/signing/signTypedData/private_key.js +16 -16
  71. package/esm/src/signing/signTypedData/private_key.js.map +1 -1
  72. package/esm/src/transports/_polyfills.d.ts +12 -0
  73. package/esm/src/transports/_polyfills.d.ts.map +1 -0
  74. package/esm/src/transports/_polyfills.js +40 -0
  75. package/esm/src/transports/_polyfills.js.map +1 -0
  76. package/esm/src/transports/base.d.ts +6 -6
  77. package/esm/src/transports/base.d.ts.map +1 -1
  78. package/esm/src/transports/http/http_transport.d.ts +11 -4
  79. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  80. package/esm/src/transports/http/http_transport.js +17 -6
  81. package/esm/src/transports/http/http_transport.js.map +1 -1
  82. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +8 -7
  83. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  84. package/esm/src/transports/websocket/_hyperliquid_event_target.js +14 -33
  85. package/esm/src/transports/websocket/_hyperliquid_event_target.js.map +1 -1
  86. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +26 -29
  87. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  88. package/esm/src/transports/websocket/_reconnecting_websocket.js +82 -76
  89. package/esm/src/transports/websocket/_reconnecting_websocket.js.map +1 -1
  90. package/esm/src/transports/websocket/_websocket_async_request.d.ts +6 -0
  91. package/esm/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  92. package/esm/src/transports/websocket/_websocket_async_request.js +49 -41
  93. package/esm/src/transports/websocket/_websocket_async_request.js.map +1 -1
  94. package/esm/src/transports/websocket/websocket_transport.d.ts +48 -70
  95. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  96. package/esm/src/transports/websocket/websocket_transport.js +90 -103
  97. package/esm/src/transports/websocket/websocket_transport.js.map +1 -1
  98. package/package.json +3 -7
  99. package/script/bin/_utils.d.ts +80 -0
  100. package/script/bin/_utils.d.ts.map +1 -0
  101. package/script/bin/_utils.js +116 -0
  102. package/script/bin/_utils.js.map +1 -0
  103. package/script/bin/cli.js +43 -164
  104. package/script/bin/cli.js.map +1 -1
  105. package/script/src/clients/exchange.d.ts +93 -93
  106. package/script/src/clients/exchange.d.ts.map +1 -1
  107. package/script/src/clients/exchange.js +62 -57
  108. package/script/src/clients/exchange.js.map +1 -1
  109. package/script/src/clients/info.d.ts +113 -113
  110. package/script/src/clients/info.d.ts.map +1 -1
  111. package/script/src/clients/info.js +70 -73
  112. package/script/src/clients/info.js.map +1 -1
  113. package/script/src/clients/multiSign.d.ts +3 -3
  114. package/script/src/clients/multiSign.d.ts.map +1 -1
  115. package/script/src/clients/multiSign.js +10 -8
  116. package/script/src/clients/multiSign.js.map +1 -1
  117. package/script/src/clients/subscription.d.ts +23 -23
  118. package/script/src/clients/subscription.d.ts.map +1 -1
  119. package/script/src/clients/subscription.js +8 -11
  120. package/script/src/clients/subscription.js.map +1 -1
  121. package/script/src/schemas/_base.d.ts +6 -8
  122. package/script/src/schemas/_base.d.ts.map +1 -1
  123. package/script/src/schemas/_base.js +6 -29
  124. package/script/src/schemas/_base.js.map +1 -1
  125. package/script/src/schemas/exchange/requests.d.ts +1676 -1657
  126. package/script/src/schemas/exchange/requests.d.ts.map +1 -1
  127. package/script/src/schemas/exchange/requests.js +194 -198
  128. package/script/src/schemas/exchange/requests.js.map +1 -1
  129. package/script/src/schemas/exchange/responses.d.ts +10 -10
  130. package/script/src/schemas/exchange/responses.js +2 -2
  131. package/script/src/schemas/exchange/responses.js.map +1 -1
  132. package/script/src/schemas/explorer/requests.d.ts +2 -2
  133. package/script/src/schemas/explorer/requests.js +2 -2
  134. package/script/src/schemas/explorer/requests.js.map +1 -1
  135. package/script/src/schemas/explorer/responses.d.ts +16 -16
  136. package/script/src/schemas/explorer/responses.js +2 -2
  137. package/script/src/schemas/explorer/responses.js.map +1 -1
  138. package/script/src/schemas/info/accounts.d.ts +298 -298
  139. package/script/src/schemas/info/accounts.js +23 -23
  140. package/script/src/schemas/info/accounts.js.map +1 -1
  141. package/script/src/schemas/info/assets.d.ts +110 -110
  142. package/script/src/schemas/info/assets.js +8 -8
  143. package/script/src/schemas/info/assets.js.map +1 -1
  144. package/script/src/schemas/info/markets.d.ts +25 -25
  145. package/script/src/schemas/info/markets.js +2 -2
  146. package/script/src/schemas/info/markets.js.map +1 -1
  147. package/script/src/schemas/info/orders.d.ts +104 -104
  148. package/script/src/schemas/info/orders.js +2 -2
  149. package/script/src/schemas/info/orders.js.map +1 -1
  150. package/script/src/schemas/info/requests.d.ts +32 -32
  151. package/script/src/schemas/info/requests.js +54 -54
  152. package/script/src/schemas/info/requests.js.map +1 -1
  153. package/script/src/schemas/info/validators.d.ts +27 -27
  154. package/script/src/schemas/info/validators.js +5 -5
  155. package/script/src/schemas/info/validators.js.map +1 -1
  156. package/script/src/schemas/info/vaults.d.ts +46 -46
  157. package/script/src/schemas/info/vaults.js +9 -9
  158. package/script/src/schemas/info/vaults.js.map +1 -1
  159. package/script/src/schemas/subscriptions/requests.d.ts +4 -4
  160. package/script/src/schemas/subscriptions/requests.js +16 -16
  161. package/script/src/schemas/subscriptions/requests.js.map +1 -1
  162. package/script/src/schemas/subscriptions/responses.d.ts +401 -401
  163. package/script/src/schemas/subscriptions/responses.js +13 -13
  164. package/script/src/schemas/subscriptions/responses.js.map +1 -1
  165. package/script/src/signing/mod.js +37 -4
  166. package/script/src/signing/mod.js.map +1 -1
  167. package/script/src/signing/signTypedData/private_key.js +49 -16
  168. package/script/src/signing/signTypedData/private_key.js.map +1 -1
  169. package/script/src/transports/_polyfills.d.ts +12 -0
  170. package/script/src/transports/_polyfills.d.ts.map +1 -0
  171. package/script/src/transports/_polyfills.js +43 -0
  172. package/script/src/transports/_polyfills.js.map +1 -0
  173. package/script/src/transports/base.d.ts +6 -6
  174. package/script/src/transports/base.d.ts.map +1 -1
  175. package/script/src/transports/http/http_transport.d.ts +11 -4
  176. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  177. package/script/src/transports/http/http_transport.js +17 -6
  178. package/script/src/transports/http/http_transport.js.map +1 -1
  179. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +8 -7
  180. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  181. package/script/src/transports/websocket/_hyperliquid_event_target.js +47 -33
  182. package/script/src/transports/websocket/_hyperliquid_event_target.js.map +1 -1
  183. package/script/src/transports/websocket/_reconnecting_websocket.d.ts +26 -29
  184. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  185. package/script/src/transports/websocket/_reconnecting_websocket.js +82 -76
  186. package/script/src/transports/websocket/_reconnecting_websocket.js.map +1 -1
  187. package/script/src/transports/websocket/_websocket_async_request.d.ts +6 -0
  188. package/script/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  189. package/script/src/transports/websocket/_websocket_async_request.js +52 -43
  190. package/script/src/transports/websocket/_websocket_async_request.js.map +1 -1
  191. package/script/src/transports/websocket/websocket_transport.d.ts +48 -70
  192. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  193. package/script/src/transports/websocket/websocket_transport.js +92 -105
  194. package/script/src/transports/websocket/websocket_transport.js.map +1 -1
  195. package/src/bin/_utils.ts +185 -0
  196. package/src/bin/cli.ts +49 -171
  197. package/src/src/clients/exchange.ts +160 -149
  198. package/src/src/clients/info.ts +128 -128
  199. package/src/src/clients/multiSign.ts +15 -13
  200. package/src/src/clients/subscription.ts +32 -32
  201. package/src/src/schemas/_base.ts +18 -40
  202. package/src/src/schemas/exchange/requests.ts +202 -199
  203. package/src/src/schemas/exchange/responses.ts +3 -3
  204. package/src/src/schemas/explorer/requests.ts +3 -3
  205. package/src/src/schemas/explorer/responses.ts +3 -3
  206. package/src/src/schemas/info/accounts.ts +24 -24
  207. package/src/src/schemas/info/assets.ts +9 -9
  208. package/src/src/schemas/info/markets.ts +3 -3
  209. package/src/src/schemas/info/orders.ts +3 -3
  210. package/src/src/schemas/info/requests.ts +55 -55
  211. package/src/src/schemas/info/validators.ts +6 -6
  212. package/src/src/schemas/info/vaults.ts +10 -10
  213. package/src/src/schemas/subscriptions/requests.ts +17 -17
  214. package/src/src/schemas/subscriptions/responses.ts +14 -14
  215. package/src/src/signing/mod.ts +4 -4
  216. package/src/src/signing/signTypedData/private_key.ts +17 -17
  217. package/src/src/transports/_polyfills.ts +41 -0
  218. package/src/src/transports/base.ts +6 -6
  219. package/src/src/transports/http/http_transport.ts +25 -14
  220. package/src/src/transports/websocket/_hyperliquid_event_target.ts +24 -51
  221. package/src/src/transports/websocket/_reconnecting_websocket.ts +107 -119
  222. package/src/src/transports/websocket/_websocket_async_request.ts +57 -59
  223. package/src/src/transports/websocket/websocket_transport.ts +126 -167
package/README.md CHANGED
@@ -23,7 +23,7 @@ runtimes, written in TypeScript.
23
23
  > [!NOTE]
24
24
  > While this library is in TypeScript, it can also be used in JavaScript and supports ESM/CommonJS.
25
25
 
26
- ### Node.js (choose your package manager)
26
+ ### Node.js v20+ (choose your package manager)
27
27
 
28
28
  ```
29
29
  npm i @nktkas/hyperliquid
@@ -33,7 +33,21 @@ pnpm add @nktkas/hyperliquid
33
33
  yarn add @nktkas/hyperliquid
34
34
  ```
35
35
 
36
- ### Deno
36
+ If you are using **Node.js v20 specifically** and intend to use [`WebSocketTransport`](#websocket-transport), you need
37
+ to install the [`ws`](https://www.npmjs.com/package/ws) package and pass the `WebSocket` class to the constructor:
38
+
39
+ ```ts
40
+ import WebSocket from "ws"; // install `ws` package
41
+ import * as hl from "@nktkas/hyperliquid";
42
+
43
+ const transport = new hl.WebSocketTransport({
44
+ reconnect: {
45
+ WebSocket, // pass `WebSocket` class from `ws` package
46
+ },
47
+ });
48
+ ```
49
+
50
+ ### Deno v2.0+
37
51
 
38
52
  ```
39
53
  deno add jsr:@nktkas/hyperliquid
@@ -41,79 +55,41 @@ deno add jsr:@nktkas/hyperliquid
41
55
 
42
56
  ### Web
43
57
 
58
+ The SDK is fully browser-compatible; integrate it via CDN or bundle it with your application.
59
+
44
60
  ```html
45
61
  <script type="module">
46
62
  import * as hl from "https://esm.sh/jsr/@nktkas/hyperliquid";
47
63
  </script>
48
64
  ```
49
65
 
50
- ### React Native
51
-
52
- <details>
53
- <summary>For React Native, you need to import polyfills before importing the SDK:</summary>
54
-
55
- ```js
56
- // React Native v0.79 / Expo v53
57
- // Issues:
58
- // - signing: does not support private keys directly, use `viem` or `ethers`
59
-
60
- import "event-target-polyfill"; // for `WebSocketTransport`
61
- // or
62
- // import { Event, EventTarget } from "event-target-shim";
63
- // if (!globalThis.EventTarget || !globalThis.Event) {
64
- // globalThis.EventTarget = EventTarget;
65
- // globalThis.Event = Event;
66
- // }
66
+ ### React Native v0.74.5 / Expo v51
67
67
 
68
- if (!globalThis.CustomEvent) { // for `WebSocketTransport`
69
- globalThis.CustomEvent = function (type, params) {
70
- params = params || {};
71
- const event = new Event(type, params);
72
- event.detail = params.detail || null;
73
- return event;
74
- };
75
- }
68
+ For React Native, you need to import polyfills before importing the SDK:
76
69
 
77
- if (!Promise.withResolvers) { // for `WebSocketTransport`
78
- Promise.withResolvers = function () {
79
- let resolve, reject;
80
- const promise = new Promise((res, rej) => {
81
- resolve = res;
82
- reject = rej;
83
- });
84
- return { promise, resolve, reject };
85
- };
86
- }
70
+ ```ts
71
+ import "fast-text-encoding"; // `TextEncoder` (utf-8)
72
+ import "event-target-polyfill"; // `EventTarget`, `Event`
73
+ import * as hl from "@nktkas/hyperliquid";
74
+ ```
87
75
 
88
- if (!AbortSignal.any) {
89
- AbortSignal.any = function (signals) {
90
- const controller = new AbortController();
91
- for (const signal of signals) {
92
- if (signal.aborted) {
93
- controller.abort(signal.reason);
94
- return controller.signal;
95
- }
96
- signal.addEventListener("abort", () => {
97
- controller.abort(signal.reason);
98
- }, { once: true, signal: controller.signal });
99
- }
100
- return controller.signal;
101
- };
102
- }
76
+ <details>
77
+ <summary>Issues:</summary>
103
78
 
104
- if (!AbortSignal.timeout) {
105
- AbortSignal.timeout = function (delay) {
106
- const controller = new AbortController();
107
- setTimeout(() => controller.abort(), delay);
108
- return controller.signal;
109
- };
110
- }
111
- ```
79
+ - signing: doesn't support a private key directly as a wallet, use `viem` or `ethers` instead
112
80
 
113
81
  </details>
114
82
 
115
83
  ## Quick Start
116
84
 
85
+ ### CLI
86
+
87
+ The SDK includes a command-line interface for quick interactions with Hyperliquid API without writing code.
88
+
89
+ ```bash
90
+ npx @nktkas/hyperliquid --help
91
+ ```
92
+
117
93
  ### [Info endpoint](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint)
118
94
 
119
95
  ```ts
@@ -189,6 +165,7 @@ const multiSignClient = new hl.MultiSignClient({
189
165
  multiSignAddress: "0x...",
190
166
  signers: [
191
167
  "0x...", // `viem`, `ethers`, or private key directly
168
+ // ... more signers
192
169
  ],
193
170
  });
194
171
 
@@ -196,14 +173,6 @@ const multiSignClient = new hl.MultiSignClient({
196
173
  await multiSignClient.approveAgent({ agentAddress: "0x..." });
197
174
  ```
198
175
 
199
- ### CLI
200
-
201
- The SDK includes a command-line interface for quick interactions with Hyperliquid API without writing code.
202
-
203
- ```bash
204
- npx @nktkas/hyperliquid --help
205
- ```
206
-
207
176
  ## Usage
208
177
 
209
178
  ### 1) Initialize Transport
@@ -214,10 +183,10 @@ First, choose and configure your transport layer (more details in the [API Refer
214
183
  import * as hl from "@nktkas/hyperliquid";
215
184
 
216
185
  // 1. HTTP Transport: suitable for one-time requests or serverless environments
217
- const httpTransport = new hl.HttpTransport({...}); // Accepts optional parameters (e.g. isTestnet, timeout, etc.)
186
+ const httpTransport = new hl.HttpTransport({ ... }); // Accepts optional parameters (e.g. isTestnet, timeout, etc.)
218
187
 
219
188
  // 2. WebSocket Transport: has better network latency than HTTP transport
220
- const wsTransport = new hl.WebSocketTransport({...}); // Accepts optional parameters (e.g. url, isTestnet, timeout, reconnect, etc.)
189
+ const wsTransport = new hl.WebSocketTransport({ ... }); // Accepts optional parameters (e.g. url, isTestnet, timeout, reconnect, etc.)
221
190
  ```
222
191
 
223
192
  ### 2) Initialize Client
@@ -635,7 +604,7 @@ class MultiSignClient extends ExchangeClient {
635
604
  multiSignAddress: Hex;
636
605
  signers: [
637
606
  AbstractWallet, // first is leader for multi-sign transaction (signs transaction 2 times)
638
- ...AbstractWallet[], // may be additional signers
607
+ ...AbstractWallet[], // ... more signers
639
608
  ];
640
609
  },
641
610
  );
@@ -650,63 +619,77 @@ Transport acts as a layer between class requests and Hyperliquid servers.
650
619
 
651
620
  #### HTTP Transport
652
621
 
653
- **Features:**
654
-
655
- - Uses [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for requests. Can be configured using
656
- [`fetchOptions`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit).
657
- - Automatically determines the target URL based on the request + `isTestnet` flag.
622
+ Uses [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for requests.
658
623
 
659
624
  ```ts
660
625
  class HttpTransport {
661
626
  constructor(options?: {
662
- isTestnet?: boolean; // Whether to use testnet url (default: false)
663
- timeout?: number; // Request timeout in ms (default: 10_000)
664
- server?: { // Custom server URLs
627
+ /** Whether to use testnet url (default: false) */
628
+ isTestnet?: boolean;
629
+ /** Request timeout in ms (default: 10_000) */
630
+ timeout?: number;
631
+ /** Custom server URLs */
632
+ server?: {
665
633
  mainnet?: { api?: string | URL; rpc?: string | URL };
666
634
  testnet?: { api?: string | URL; rpc?: string | URL };
667
635
  };
668
- fetchOptions?: RequestInit; // A custom fetch options
669
- onRequest?: (request: Request) => MaybePromise<Request | void | null | undefined>; // A callback before request is sent
670
- onResponse?: (response: Response) => MaybePromise<Response | void | null | undefined>; // A callback after response is received
636
+ /** Custom fetch options */
637
+ fetchOptions?: RequestInit;
638
+ /** Callback before request is sent */
639
+ onRequest?: (request: Request) => MaybePromise<Request | void | null | undefined>;
640
+ /** Callback after response is received */
641
+ onResponse?: (response: Response) => MaybePromise<Response | void | null | undefined>;
642
+ /** Callback on error during fetching */
643
+ onError?: (error: unknown) => MaybePromise<Error | void | null | undefined>;
671
644
  });
672
645
  }
673
646
  ```
674
647
 
675
648
  #### WebSocket Transport
676
649
 
650
+ Uses [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) for requests. Supports
651
+ [subscriptions](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions) and
652
+ [post requests](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/post-requests).
653
+
677
654
  **Features:**
678
655
 
679
- - Uses [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) for requests.
680
- - Supports [subscriptions](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions)
681
- and [post requests](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/post-requests).
682
656
  - Automatically restores connection after loss and resubscribes to previous subscriptions.
683
657
  - Smart keep alive (pings only when idle).
684
658
  - Lazy initialization with message buffering during connection establishment.
685
659
 
686
660
  **Limitations:**
687
661
 
688
- - Cannot mix api/explorer endpoints or mainnet/testnet in single connection. Need to create separate instances for
689
- different endpoints.
690
- - Cannot send explorer post-requests via WebSocket. Use [HTTP transport](#http-transport).
662
+ - 1 instance = 1 immutable endpoint. Cannot mix api/explorer endpoints or mainnet/testnet in single connection. Need to
663
+ create separate instances for different endpoints.
664
+ - Cannot send explorer post-requests via WebSocket.
691
665
 
692
666
  ```ts
693
667
  class WebSocketTransport {
694
668
  constructor(options?: {
695
- url?: string | URL; // WebSocket URL (default: "wss://api.hyperliquid.xyz/ws")
696
- isTestnet?: boolean; // Indicates this transport uses testnet endpoint (default: false)
697
- timeout?: number; // Request timeout in ms (default: 10_000)
698
- keepAlive?: {
699
- interval?: number; // Ping interval in ms (default: 30_000)
700
- timeout?: number; // Pong timeout in ms (default: same as `timeout` for requests)
701
- };
669
+ /** Indicates this transport uses testnet endpoint (default: false) */
670
+ isTestnet?: boolean;
671
+ /**
672
+ * Custom WebSocket endpoint for API and Subscription requests.
673
+ * (default: `wss://api.hyperliquid.xyz` for mainnet, `wss://api.testnet.hyperliquid.xyz` for testnet)
674
+ */
675
+ url?: string | URL;
676
+ /** Timeout for requests in ms (default: 10_000) */
677
+ timeout?: number;
678
+ /** Interval between sending ping messages in ms (default: 30_000) */
679
+ keepAliveInterval?: number;
680
+ /** Reconnection policy configuration for closed connections */
702
681
  reconnect?: {
703
- maxRetries?: number; // Maximum number of reconnection attempts (default: 3)
704
- connectionTimeout?: number; // Connection timeout in ms (default: 10_000)
705
- connectionDelay?: number | ((attempt: number) => number | Promise<number>); // Delay between reconnection (default: Exponential backoff (max 10s))
706
- shouldReconnect?: (event: CloseEvent) => boolean | Promise<boolean>; // Custom reconnection logic (default: Always reconnect)
707
- messageBuffer?: MessageBufferStrategy; // Message buffering strategy between reconnection (default: FIFO buffer)
682
+ /** Custom WebSocket constructor (default: global WebSocket) */
683
+ WebSocket?: new (url: string | URL) => WebSocket;
684
+ /** Maximum number of reconnection attempts (default: 3) */
685
+ maxRetries?: number;
686
+ /** Maximum time in ms to wait for a connection to open (default: 10_000) */
687
+ connectionTimeout?: number;
688
+ /** Delay before reconnection in ms (default: Exponential backoff (max 10s)) */
689
+ reconnectionDelay?: number | ((attempt: number) => number);
708
690
  };
709
- autoResubscribe?: boolean; // Whether to automatically resubscribe to events after reconnection (default: true)
691
+ /** Enable automatic re-subscription to Hyperliquid subscription after reconnection (default: true) */
692
+ resubscribe?: boolean;
710
693
  });
711
694
  ready(signal?: AbortSignal): Promise<void>;
712
695
  close(signal?: AbortSignal): Promise<void>;
@@ -715,10 +698,25 @@ class WebSocketTransport {
715
698
 
716
699
  ### Errors
717
700
 
718
- - [`HyperliquidError`](src/errors.ts#L2) - Base error class for all SDK errors.
719
- - [`TransportError`](src/transports/base.ts#L49) - Thrown when a transport layer error occurs.
720
- - [`ApiRequestError`](src/clients//exchange.ts#L294) - Thrown when an API request fails.
721
- - [`SchemaError`](src/schemas/mod.ts#L79) - Thrown when a schema validation error occurs.
701
+ All SDK errors extend from `HyperliquidError` base class for unified error handling:
702
+
703
+ ```ts
704
+ import { ApiRequestError, HyperliquidError, SchemaError, TransportError } from "@nktkas/hyperliquid";
705
+
706
+ try {
707
+ await exchClient.order({ ... });
708
+ } catch (error) {
709
+ if (error instanceof SchemaError) {
710
+ // Invalid data format (before sending request)
711
+ } else if (error instanceof ApiRequestError) {
712
+ // API returned error (e.g., insufficient funds)
713
+ } else if (error instanceof TransportError) {
714
+ // Network/connection failure (e.g., timeout)
715
+ } else if (error instanceof HyperliquidError) {
716
+ // Some other Hyperliquid SDK error
717
+ }
718
+ }
719
+ ```
722
720
 
723
721
  ## Additional Import Points
724
722
 
@@ -759,7 +757,7 @@ Also valibot schema can be converted to JSON Schema:
759
757
  import { OrderRequest } from "@nktkas/hyperliquid/schemas";
760
758
  import { toJsonSchema } from "@valibot/to-json-schema";
761
759
 
762
- const schema = toJsonSchema(OrderRequest, { errorMode: "ignore" });
760
+ const schema = toJsonSchema(OrderRequest, { errorMode: "ignore", typeMode: "output" });
763
761
 
764
762
  console.log(JSON.stringify(schema, null, 2));
765
763
  // {
@@ -875,19 +873,13 @@ with `tif: "Ioc"` and price that guarantee immediate execution:
875
873
  - For buys: set limit price >= current best ask
876
874
  - For sells: set limit price <= current best bid
877
875
 
878
- ### How to use the [Agent Wallet](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/nonces-and-api-wallets#api-wallets) / [Vault](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#subaccounts-and-vaults) / [Sub-Account](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#subaccounts-and-vaults) in `ExchangeClient`?
879
-
880
- **Agent Wallet**: Use agent's private key in constructor instead of master account's private key.
881
-
882
- **Vault and Sub-Account**: Pass vault or sub-account address via `vaultAddress` options to methods or set
883
- `defaultVaultAddress` in constructor.
876
+ ### How to use the [Agent Wallet](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/nonces-and-api-wallets#api-wallets) in [`ExchangeClient`](#exchangeclient)?
884
877
 
885
- ### How to use Testnet?
878
+ Use agent's private key in constructor instead of master account's private key.
886
879
 
887
- [**HttpTransport**](#http-transport): Set the `isTestnet` flag to `true`.
880
+ ### How to use the [Vault](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#subaccounts-and-vaults) / [Sub-Account](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#subaccounts-and-vaults) in [`ExchangeClient`](#exchangeclient)?
888
881
 
889
- [**WebSocketTransport**](#websocket-transport): Set the `isTestnet` flag to `true` and provide the testnet `url` when
890
- initializing the transport.
882
+ Pass vault or sub-account address via `vaultAddress` options to methods or set `defaultVaultAddress` in constructor.
891
883
 
892
884
  ## Contributing
893
885
 
@@ -0,0 +1,80 @@
1
+ export type RawArgs = {
2
+ [key: string]: string | undefined;
3
+ } & {
4
+ _: string[];
5
+ };
6
+ export type ParseOptions = {
7
+ /**
8
+ * Consider these keys as flags (no value expected).
9
+ * Value going after a flag will be treated as a positional argument.
10
+ */
11
+ flags?: string[];
12
+ };
13
+ /**
14
+ * Parse command-line arguments into a key-value object.
15
+ * Does not transform values.
16
+ */
17
+ export declare function parseArgs(args: string[], options?: ParseOptions): RawArgs;
18
+ export interface TransformOptions {
19
+ /**
20
+ * Transform rule for flags (keys without values).
21
+ * @value `undefined`
22
+ * @default "true"
23
+ */
24
+ flag?: "true" | "false" | ((key: string) => "true" | "false");
25
+ /**
26
+ * Transform rule for null values.
27
+ * @value `"null"` (case insensitive)
28
+ * @default "null"
29
+ */
30
+ null?: "null" | "string" | ((key: string, value: string) => "null" | "string");
31
+ /**
32
+ * Transform rule for boolean values.
33
+ * @value `"true"`, `"false"` (case insensitive)
34
+ * @default "bool"
35
+ */
36
+ bool?: "bool" | "string" | ((key: string, value: string) => "bool" | "string");
37
+ /**
38
+ * Transform rule for hexadecimal values.
39
+ * @value `"0xff"`, `"0X1A"` (case insensitive) (0x prefix required)
40
+ * @default "string"
41
+ */
42
+ hex?: "string" | "number" | ((key: string, value: string) => "string" | "number");
43
+ /**
44
+ * Transform rule for special numeric values.
45
+ * @value `"Infinity"`, `"-Infinity"`, `"NaN"`, `"-NaN"` (case insensitive)
46
+ * @default "string"
47
+ */
48
+ specialNumber?: "string" | "number" | ((key: string, value: string) => "string" | "number");
49
+ /**
50
+ * Transform rule for numeric values.
51
+ * @value `"123"`, `"12.3"`, `"1e+2"`, `"+123"`, `"-123"` (anything that can be parsed by `Number(value)`) (excludes hex values)
52
+ * @default "number"
53
+ */
54
+ number?: "number" | "string" | ((key: string, value: string) => "number" | "string");
55
+ /**
56
+ * Transform rule for JSON object/array values.
57
+ * @value `"{ \"a\": 1 }"`, `"[invalid array string]"` (anything that begins with `{` and ends with `}` or begins with `[` and ends with `]`)
58
+ * @default "object"
59
+ */
60
+ json?: "object" | "string" | ((key: string, value: string) => "object" | "string");
61
+ }
62
+ export interface Args {
63
+ [key: string]: string | number | boolean | null | Record<string, unknown> | unknown[];
64
+ _: string[];
65
+ }
66
+ /**
67
+ * Transform raw args (string values) into typed args based on rules.
68
+ *
69
+ * Order of transformation:
70
+ * 1. flag (`undefined`)
71
+ * 2. null (`"null"`)
72
+ * 3. boolean (`"true"`, `"false"`)
73
+ * 4. hex (`"0x..."`)
74
+ * 5. special number (`"Infinity"`, `"-Infinity"`, `"NaN", "-NaN"`)
75
+ * 6. number (numeric strings)
76
+ * 7. json (object/array strings)
77
+ * 8. string (default)
78
+ */
79
+ export declare function transformArgs(args: RawArgs, options?: TransformOptions): Args;
80
+ //# sourceMappingURL=_utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_utils.d.ts","sourceRoot":"","sources":["../../src/bin/_utils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACrC,GAAG;IACA,CAAC,EAAE,MAAM,EAAE,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CA8BzE;AAED,MAAM,WAAW,gBAAgB;IAC7B;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,CAAC;IAC9D;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,QAAQ,CAAC,CAAC;IAC/E;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,QAAQ,CAAC,CAAC;IAC/E;;;;OAIG;IACH,GAAG,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,QAAQ,GAAG,QAAQ,CAAC,CAAC;IAClF;;;;OAIG;IACH,aAAa,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,QAAQ,GAAG,QAAQ,CAAC,CAAC;IAC5F;;;;OAIG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,QAAQ,GAAG,QAAQ,CAAC,CAAC;IACrF;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,QAAQ,GAAG,QAAQ,CAAC,CAAC;CACtF;AAED,MAAM,WAAW,IAAI;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,CAAC;IACtF,CAAC,EAAE,MAAM,EAAE,CAAC;CACf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAuE7E"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Parse command-line arguments into a key-value object.
3
+ * Does not transform values.
4
+ */
5
+ export function parseArgs(args, options) {
6
+ const result = { _: [] };
7
+ for (let i = 0; i < args.length; i++) {
8
+ const arg = args[i];
9
+ const nextArg = args[i + 1];
10
+ if (arg.startsWith("-")) {
11
+ if (arg === "-_" || arg === "--_")
12
+ continue; // Skip reserved key "_"
13
+ const isLong = arg.startsWith("--");
14
+ let keyPart = arg.slice(isLong ? 2 : 1);
15
+ let value;
16
+ const eqIndex = keyPart.indexOf("=");
17
+ if (eqIndex !== -1) {
18
+ value = keyPart.substring(eqIndex + 1);
19
+ keyPart = keyPart.substring(0, eqIndex);
20
+ }
21
+ else if (!options?.flags?.includes(keyPart) && // Skip if key is defined as flag and don't expect value
22
+ typeof nextArg === "string" && (!nextArg.startsWith("-") || !isNaN(parseFloat(nextArg)))) {
23
+ value = nextArg;
24
+ i++; // Skip next arg as it's consumed as value for current key
25
+ }
26
+ result[keyPart] = value;
27
+ }
28
+ else {
29
+ result._.push(arg);
30
+ }
31
+ }
32
+ return result;
33
+ }
34
+ /**
35
+ * Transform raw args (string values) into typed args based on rules.
36
+ *
37
+ * Order of transformation:
38
+ * 1. flag (`undefined`)
39
+ * 2. null (`"null"`)
40
+ * 3. boolean (`"true"`, `"false"`)
41
+ * 4. hex (`"0x..."`)
42
+ * 5. special number (`"Infinity"`, `"-Infinity"`, `"NaN", "-NaN"`)
43
+ * 6. number (numeric strings)
44
+ * 7. json (object/array strings)
45
+ * 8. string (default)
46
+ */
47
+ export function transformArgs(args, options) {
48
+ const opts = {
49
+ flag: "true",
50
+ null: "null",
51
+ bool: "bool",
52
+ hex: "string",
53
+ specialNumber: "string",
54
+ number: "number",
55
+ json: "object",
56
+ ...options,
57
+ };
58
+ const result = { _: args._ };
59
+ for (const key in args) {
60
+ if (key === "_")
61
+ continue; // Skip the positional args array
62
+ const value = args[key];
63
+ // Transformation logic
64
+ let transformedValue;
65
+ // flag
66
+ if (value === undefined) {
67
+ const action = typeof opts.flag === "function" ? opts.flag(key) : opts.flag;
68
+ transformedValue = action === "true" ? true : false;
69
+ } // null
70
+ else if (value.toLowerCase() === "null") {
71
+ const action = typeof opts.null === "function" ? opts.null(key, value) : opts.null;
72
+ transformedValue = action === "null" ? null : value;
73
+ } // boolean
74
+ else if (value.toLowerCase() === "true" || value.toLowerCase() === "false") {
75
+ const action = typeof opts.bool === "function" ? opts.bool(key, value) : opts.bool;
76
+ transformedValue = action === "bool" ? value.toLowerCase() === "true" : value;
77
+ } // hex
78
+ else if ((value.startsWith("0x") || value.startsWith("0X")) && !isNaN(parseInt(value, 16))) {
79
+ const action = typeof opts.hex === "function" ? opts.hex(key, value) : opts.hex;
80
+ transformedValue = action === "string" ? value : parseInt(value, 16);
81
+ } // special number
82
+ else if (value.toLowerCase() === "infinity" || value.toLowerCase() === "-infinity" ||
83
+ value.toLowerCase() === "nan" || value.toLowerCase() === "-nan") {
84
+ const action = typeof opts.specialNumber === "function"
85
+ ? opts.specialNumber(key, value)
86
+ : opts.specialNumber;
87
+ transformedValue = action === "string" ? value : Number(value);
88
+ } // number
89
+ else if (!isNaN(Number(value))) {
90
+ const action = typeof opts.number === "function" ? opts.number(key, value) : opts.number;
91
+ transformedValue = action === "number" ? Number(value) : value;
92
+ } // json object/array
93
+ else if ((value.startsWith("{") && value.endsWith("}")) ||
94
+ (value.startsWith("[") && value.endsWith("]"))) {
95
+ const action = typeof opts.json === "function" ? opts.json(key, value) : opts.json;
96
+ try {
97
+ transformedValue = action === "object"
98
+ ? JSON.parse(value)
99
+ : value;
100
+ }
101
+ catch {
102
+ transformedValue = value;
103
+ }
104
+ } // string (default)
105
+ else {
106
+ transformedValue = value;
107
+ }
108
+ result[key] = transformedValue;
109
+ }
110
+ return result;
111
+ }
112
+ //# sourceMappingURL=_utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_utils.js","sourceRoot":"","sources":["../../src/bin/_utils.ts"],"names":[],"mappings":"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"}