@nktkas/hyperliquid 0.19.1 → 0.20.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 (136) hide show
  1. package/CONTRIBUTING.md +4 -2
  2. package/README.md +36 -35
  3. package/esm/_dnt.polyfills.d.ts +20 -0
  4. package/esm/_dnt.polyfills.d.ts.map +1 -0
  5. package/esm/_dnt.polyfills.js +12 -0
  6. package/esm/mod.d.ts +3 -0
  7. package/esm/mod.d.ts.map +1 -1
  8. package/esm/mod.js +2 -0
  9. package/esm/src/base.d.ts +1 -47
  10. package/esm/src/base.d.ts.map +1 -1
  11. package/esm/src/base.js +1 -8
  12. package/esm/src/clients/event.d.ts +6 -4
  13. package/esm/src/clients/event.d.ts.map +1 -1
  14. package/esm/src/clients/event.js +58 -77
  15. package/esm/src/clients/public.d.ts +26 -5
  16. package/esm/src/clients/public.d.ts.map +1 -1
  17. package/esm/src/clients/public.js +29 -41
  18. package/esm/src/clients/wallet.d.ts +200 -26
  19. package/esm/src/clients/wallet.d.ts.map +1 -1
  20. package/esm/src/clients/wallet.js +306 -284
  21. package/esm/src/signing.d.ts +80 -5
  22. package/esm/src/signing.d.ts.map +1 -1
  23. package/esm/src/signing.js +96 -7
  24. package/esm/src/transports/base.d.ts +49 -0
  25. package/esm/src/transports/base.d.ts.map +1 -0
  26. package/esm/src/transports/base.js +8 -0
  27. package/esm/src/transports/http/http_transport.d.ts +8 -5
  28. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  29. package/esm/src/transports/http/http_transport.js +15 -62
  30. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +36 -39
  31. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  32. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +18 -25
  33. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  34. package/esm/src/transports/websocket/_reconnecting_websocket.js +80 -179
  35. package/{script/src/transports/websocket/_websocket_request_dispatcher.d.ts → esm/src/transports/websocket/_websocket_async_request.d.ts} +14 -18
  36. package/esm/src/transports/websocket/_websocket_async_request.d.ts.map +1 -0
  37. package/esm/src/transports/websocket/{_websocket_request_dispatcher.js → _websocket_async_request.js} +42 -75
  38. package/esm/src/transports/websocket/websocket_transport.d.ts +38 -28
  39. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  40. package/esm/src/transports/websocket/websocket_transport.js +61 -76
  41. package/esm/src/types/exchange/requests.d.ts +278 -66
  42. package/esm/src/types/exchange/requests.d.ts.map +1 -1
  43. package/esm/src/types/info/assets.d.ts +0 -48
  44. package/esm/src/types/info/assets.d.ts.map +1 -1
  45. package/esm/src/types/info/markets.d.ts +52 -0
  46. package/esm/src/types/info/markets.d.ts.map +1 -0
  47. package/esm/src/types/info/markets.js +1 -0
  48. package/esm/src/types/info/orders.d.ts +1 -1
  49. package/esm/src/types/info/orders.d.ts.map +1 -1
  50. package/esm/src/types/info/requests.d.ts +14 -5
  51. package/esm/src/types/info/requests.d.ts.map +1 -1
  52. package/esm/src/types/mod.d.ts +4 -0
  53. package/esm/src/types/mod.d.ts.map +1 -1
  54. package/esm/src/types/mod.js +3 -1
  55. package/esm/src/types/subscriptions/requests.d.ts +2 -0
  56. package/esm/src/types/subscriptions/requests.d.ts.map +1 -1
  57. package/package.json +12 -9
  58. package/script/_dnt.polyfills.d.ts +20 -0
  59. package/script/_dnt.polyfills.d.ts.map +1 -0
  60. package/script/_dnt.polyfills.js +23 -0
  61. package/script/mod.d.ts +3 -0
  62. package/script/mod.d.ts.map +1 -1
  63. package/script/mod.js +3 -1
  64. package/script/src/base.d.ts +1 -47
  65. package/script/src/base.d.ts.map +1 -1
  66. package/script/src/base.js +2 -10
  67. package/script/src/clients/event.d.ts +6 -4
  68. package/script/src/clients/event.d.ts.map +1 -1
  69. package/script/src/clients/event.js +58 -77
  70. package/script/src/clients/public.d.ts +26 -5
  71. package/script/src/clients/public.d.ts.map +1 -1
  72. package/script/src/clients/public.js +29 -41
  73. package/script/src/clients/wallet.d.ts +200 -26
  74. package/script/src/clients/wallet.d.ts.map +1 -1
  75. package/script/src/clients/wallet.js +305 -283
  76. package/script/src/signing.d.ts +80 -5
  77. package/script/src/signing.d.ts.map +1 -1
  78. package/script/src/signing.js +148 -58
  79. package/script/src/transports/base.d.ts +49 -0
  80. package/script/src/transports/base.d.ts.map +1 -0
  81. package/script/src/transports/base.js +22 -0
  82. package/script/src/transports/http/http_transport.d.ts +8 -5
  83. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  84. package/script/src/transports/http/http_transport.js +16 -63
  85. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +36 -39
  86. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  87. package/script/src/transports/websocket/_reconnecting_websocket.d.ts +18 -25
  88. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  89. package/script/src/transports/websocket/_reconnecting_websocket.js +81 -180
  90. package/{esm/src/transports/websocket/_websocket_request_dispatcher.d.ts → script/src/transports/websocket/_websocket_async_request.d.ts} +14 -18
  91. package/script/src/transports/websocket/_websocket_async_request.d.ts.map +1 -0
  92. package/script/src/transports/websocket/{_websocket_request_dispatcher.js → _websocket_async_request.js} +45 -78
  93. package/script/src/transports/websocket/websocket_transport.d.ts +38 -28
  94. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  95. package/script/src/transports/websocket/websocket_transport.js +63 -78
  96. package/script/src/types/exchange/requests.d.ts +278 -66
  97. package/script/src/types/exchange/requests.d.ts.map +1 -1
  98. package/script/src/types/info/assets.d.ts +0 -48
  99. package/script/src/types/info/assets.d.ts.map +1 -1
  100. package/script/src/types/info/markets.d.ts +52 -0
  101. package/script/src/types/info/markets.d.ts.map +1 -0
  102. package/script/{deps/jsr.io/@noble/hashes/1.8.0/src/crypto.js → src/types/info/markets.js} +0 -2
  103. package/script/src/types/info/orders.d.ts +1 -1
  104. package/script/src/types/info/orders.d.ts.map +1 -1
  105. package/script/src/types/info/requests.d.ts +14 -5
  106. package/script/src/types/info/requests.d.ts.map +1 -1
  107. package/script/src/types/mod.d.ts +4 -0
  108. package/script/src/types/mod.d.ts.map +1 -1
  109. package/script/src/types/mod.js +25 -22
  110. package/script/src/types/subscriptions/requests.d.ts +2 -0
  111. package/script/src/types/subscriptions/requests.d.ts.map +1 -1
  112. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.d.ts +0 -55
  113. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.d.ts.map +0 -1
  114. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.js +0 -66
  115. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.d.ts +0 -2
  116. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.d.ts.map +0 -1
  117. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.js +0 -1
  118. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.d.ts +0 -53
  119. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.d.ts.map +0 -1
  120. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.js +0 -294
  121. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/utils.d.ts +0 -161
  122. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/utils.d.ts.map +0 -1
  123. package/esm/deps/jsr.io/@noble/hashes/1.8.0/src/utils.js +0 -280
  124. package/esm/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +0 -1
  125. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.d.ts +0 -55
  126. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.d.ts.map +0 -1
  127. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/_u64.js +0 -99
  128. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.d.ts +0 -2
  129. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/crypto.d.ts.map +0 -1
  130. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.d.ts +0 -53
  131. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.d.ts.map +0 -1
  132. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/sha3.js +0 -309
  133. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/utils.d.ts +0 -161
  134. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/utils.d.ts.map +0 -1
  135. package/script/deps/jsr.io/@noble/hashes/1.8.0/src/utils.js +0 -322
  136. package/script/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { type MessageBufferStrategy, ReconnectingWebSocket, ReconnectingWebSocketError, type ReconnectingWebSocketOptions } from "./_reconnecting_websocket.js";
2
2
  import { HyperliquidEventTarget } from "./_hyperliquid_event_target.js";
3
- import { WebSocketRequestDispatcher, WebSocketRequestError } from "./_websocket_request_dispatcher.js";
4
- import type { IRequestTransport, ISubscriptionTransport, Subscription } from "../../base.js";
3
+ import { WebSocketAsyncRequest, WebSocketRequestError } from "./_websocket_async_request.js";
4
+ import type { IRequestTransport, ISubscriptionTransport, Subscription } from "../base.js";
5
5
  export { WebSocketRequestError };
6
6
  export { type MessageBufferStrategy, ReconnectingWebSocketError, type ReconnectingWebSocketOptions };
7
7
  /** Configuration options for the WebSocket transport layer. */
@@ -10,44 +10,42 @@ export interface WebSocketTransportOptions {
10
10
  * The WebSocket URL.
11
11
  * - Mainnet:
12
12
  * - API: `wss://api.hyperliquid.xyz/ws`
13
- * - RPC: `wss://rpc.hyperliquid.xyz/ws`
13
+ * - Explorer: `wss://rpc.hyperliquid.xyz/ws`
14
14
  * - Testnet:
15
15
  * - API: `wss://api.hyperliquid-testnet.xyz/ws`
16
- * - RPC: `wss://rpc.hyperliquid-testnet.xyz/ws`
16
+ * - Explorer: `wss://rpc.hyperliquid-testnet.xyz/ws`
17
17
  * @defaultValue `wss://api.hyperliquid.xyz/ws`
18
18
  */
19
19
  url?: string | URL;
20
20
  /**
21
- * Request timeout in ms.
21
+ * Timeout for requests in ms.
22
22
  * Set to `null` to disable.
23
23
  * @defaultValue `10_000`
24
24
  */
25
25
  timeout?: number | null;
26
- /**
27
- * Keep-alive configuration.
28
- * @defaultValue `{ interval: 20_000 }`
29
- */
26
+ /** Keep-alive configuration. */
30
27
  keepAlive?: {
31
28
  /**
32
- * The interval in ms to send keep-alive messages.
29
+ * Interval between sending ping messages in ms.
33
30
  * Set to `null` to disable.
34
- * @defaultValue `20_000`
31
+ * @defaultValue `30_000`
35
32
  */
36
33
  interval?: number | null;
34
+ /**
35
+ * Timeout for the ping request in ms.
36
+ * Set to `null` to disable.
37
+ * same as {@link timeout} for requests.
38
+ */
39
+ timeout?: number | null;
37
40
  };
38
- /**
39
- * Reconnection policy configuration for closed connections.
40
- */
41
+ /** Reconnection policy configuration for closed connections. */
41
42
  reconnect?: ReconnectingWebSocketOptions;
42
43
  }
43
44
  /** WebSocket implementation of the REST and Subscription transport interfaces. */
44
45
  export declare class WebSocketTransport implements IRequestTransport, ISubscriptionTransport, AsyncDisposable {
45
- /** The interval timer ID for keep-alive messages. */
46
- protected _keepAliveTimer: number | null;
47
- /** The WebSocket request dispatcher instance. */
48
- protected _wsRequester: WebSocketRequestDispatcher;
49
- /** The Hyperliquid event target instance. */
46
+ protected _wsRequester: WebSocketAsyncRequest;
50
47
  protected _hlEvents: HyperliquidEventTarget;
48
+ protected _keepAliveTimeout: ReturnType<typeof setTimeout> | null;
51
49
  /**
52
50
  * Map of active subscriptions.
53
51
  * - Key: Unique subscription identifier based on payload
@@ -63,13 +61,18 @@ export declare class WebSocketTransport implements IRequestTransport, ISubscript
63
61
  * Set to `null` to disable.
64
62
  */
65
63
  timeout: number | null;
66
- /** Keep-alive configuration settings. */
64
+ /** Keep-alive configuration. */
67
65
  readonly keepAlive: {
68
66
  /**
69
- * The interval in ms to send keep-alive messages.
67
+ * Interval between sending ping messages in ms.
70
68
  * Set to `null` to disable.
71
69
  */
72
70
  readonly interval: number | null;
71
+ /**
72
+ * Timeout for the ping request in ms.
73
+ * Set to `null` to disable.
74
+ */
75
+ timeout?: number | null;
73
76
  };
74
77
  /** The WebSocket that is used for communication. */
75
78
  readonly socket: ReconnectingWebSocket;
@@ -80,23 +83,29 @@ export declare class WebSocketTransport implements IRequestTransport, ISubscript
80
83
  constructor(options?: WebSocketTransportOptions);
81
84
  /**
82
85
  * Sends a request to the Hyperliquid API via WebSocket.
86
+ *
87
+ * Note: Explorer requests are not supported in the Hyperliquid WebSocket API.
88
+ *
83
89
  * @param endpoint - The API endpoint to send the request to (`explorer` requests are not supported).
84
90
  * @param payload - The payload to send with the request.
85
91
  * @param signal - An optional abort signal.
86
92
  * @returns A promise that resolves with parsed JSON response body.
87
93
  * @throws {WebSocketRequestError} - An error that occurs when a WebSocket request fails.
88
- * @note Explorer requests are not supported in the Hyperliquid WebSocket API.
89
94
  */
90
- request(type: "info" | "exchange" | "explorer", payload: unknown, signal?: AbortSignal): Promise<unknown>;
95
+ request<T>(type: "info" | "exchange" | "explorer", payload: unknown, signal?: AbortSignal): Promise<T>;
91
96
  /**
92
97
  * Subscribes to a Hyperliquid event channel.
98
+ *
99
+ * Sends a subscription request to the server and listens for events.
100
+ *
93
101
  * @param channel - The event channel to listen to.
94
102
  * @param payload - A payload to send with the subscription request.
95
103
  * @param listener - A function to call when the event is dispatched.
96
104
  * @param signal - An optional abort signal for canceling the subscription request.
97
105
  * @returns A promise that resolves with a {@link Subscription} object to manage the subscription lifecycle.
106
+ * @throws {WebSocketRequestError} - An error that occurs when a WebSocket request fails.
98
107
  */
99
- subscribe(channel: string, payload: unknown, listener: (data: CustomEvent) => void, signal?: AbortSignal): Promise<Subscription>;
108
+ subscribe<T>(channel: string, payload: unknown, listener: (data: CustomEvent<T>) => void, signal?: AbortSignal): Promise<Subscription>;
100
109
  /**
101
110
  * Waits until the WebSocket connection is ready.
102
111
  * @param signal - An optional abort signal.
@@ -109,12 +118,13 @@ export declare class WebSocketTransport implements IRequestTransport, ISubscript
109
118
  * @returns A promise that resolves when the connection is fully closed.
110
119
  */
111
120
  close(signal?: AbortSignal): Promise<void>;
121
+ /** Combines the provided abort signal with the timeout signal. */
122
+ protected _getCombinedTimeoutSignal(signal?: AbortSignal): AbortSignal | undefined;
112
123
  /**
113
- * Combines the provided abort signal with the timeout signal.
114
- * @param signal An optional abort signal.
115
- * @returns A combined abort signal or undefined.
124
+ * Initiate background keep the connection alive.
125
+ * Sends ping only when needed.
116
126
  */
117
- protected _getCombinedTimeoutSignal(signal?: AbortSignal): AbortSignal | undefined;
127
+ protected _keepAlive(): void;
118
128
  [Symbol.asyncDispose](): Promise<void>;
119
129
  }
120
130
  //# sourceMappingURL=websocket_transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"websocket_transport.d.ts","sourceRoot":"","sources":["../../../../src/src/transports/websocket/websocket_transport.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,4BAA4B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AACvG,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7F,OAAO,EAAE,qBAAqB,EAAE,CAAC;AACjC,OAAO,EAAE,KAAK,qBAAqB,EAAE,0BAA0B,EAAE,KAAK,4BAA4B,EAAE,CAAC;AAErG,+DAA+D;AAC/D,MAAM,WAAW,yBAAyB;IACtC;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;IAEnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;;OAGG;IACH,SAAS,CAAC,EAAE;QACR;;;;WAIG;QACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,CAAC;IAEF;;OAEG;IACH,SAAS,CAAC,EAAE,4BAA4B,CAAC;CAC5C;AAED,kFAAkF;AAClF,qBAAa,kBAAmB,YAAW,iBAAiB,EAAE,sBAAsB,EAAE,eAAe;IACjG,qDAAqD;IACrD,SAAS,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEhD,iDAAiD;IACjD,SAAS,CAAC,YAAY,EAAE,0BAA0B,CAAC;IAEnD,6CAA6C;IAC7C,SAAS,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAE5C;;;;;OAKG;IACH,SAAS,CAAC,cAAc,EAAE,GAAG,CACzB,MAAM,EACN;QACI,SAAS,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,cAAc,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;KACpC,CACJ,CAAa;IAEd;;;OAGG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE;QAChB;;;WAGG;QACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACpC,CAAC;IAEF,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IAEvC;;;OAGG;gBACS,OAAO,CAAC,EAAE,yBAAyB;IAuC/C;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAQzG;;;;;;;OAOG;IACG,SAAS,CACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,EACrC,MAAM,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,YAAY,CAAC;IAgExB;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB1C;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB1C;;;;OAIG;IACH,SAAS,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS;IAQ5E,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/C"}
1
+ {"version":3,"file":"websocket_transport.d.ts","sourceRoot":"","sources":["../../../../src/src/transports/websocket/websocket_transport.ts"],"names":[],"mappings":"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"}
@@ -1,93 +1,52 @@
1
1
  import { ReconnectingWebSocket, ReconnectingWebSocketError, } from "./_reconnecting_websocket.js";
2
2
  import { HyperliquidEventTarget } from "./_hyperliquid_event_target.js";
3
- import { WebSocketRequestDispatcher, WebSocketRequestError } from "./_websocket_request_dispatcher.js";
3
+ import { WebSocketAsyncRequest, WebSocketRequestError } from "./_websocket_async_request.js";
4
4
  export { WebSocketRequestError };
5
5
  export { ReconnectingWebSocketError };
6
6
  /** WebSocket implementation of the REST and Subscription transport interfaces. */
7
7
  export class WebSocketTransport {
8
+ _wsRequester;
9
+ _hlEvents;
10
+ _keepAliveTimeout = null;
11
+ /**
12
+ * Map of active subscriptions.
13
+ * - Key: Unique subscription identifier based on payload
14
+ * - Value: Subscription info containing the subscription request promise
15
+ * and a map of listeners to their metadata (channel + unsubscribe function).
16
+ */
17
+ _subscriptions = new Map();
18
+ /**
19
+ * Request timeout in ms.
20
+ * Set to `null` to disable.
21
+ */
22
+ timeout;
23
+ /** Keep-alive configuration. */
24
+ keepAlive;
25
+ /** The WebSocket that is used for communication. */
26
+ socket;
8
27
  /**
9
28
  * Creates a new WebSocket transport instance.
10
29
  * @param options - Configuration options for the WebSocket transport layer.
11
30
  */
12
31
  constructor(options) {
13
- /** The interval timer ID for keep-alive messages. */
14
- Object.defineProperty(this, "_keepAliveTimer", {
15
- enumerable: true,
16
- configurable: true,
17
- writable: true,
18
- value: null
19
- });
20
- /** The WebSocket request dispatcher instance. */
21
- Object.defineProperty(this, "_wsRequester", {
22
- enumerable: true,
23
- configurable: true,
24
- writable: true,
25
- value: void 0
26
- });
27
- /** The Hyperliquid event target instance. */
28
- Object.defineProperty(this, "_hlEvents", {
29
- enumerable: true,
30
- configurable: true,
31
- writable: true,
32
- value: void 0
33
- });
34
- /**
35
- * Map of active subscriptions.
36
- * - Key: Unique subscription identifier based on payload
37
- * - Value: Subscription info containing the subscription request promise
38
- * and a map of listeners to their metadata (channel + unsubscribe function).
39
- */
40
- Object.defineProperty(this, "_subscriptions", {
41
- enumerable: true,
42
- configurable: true,
43
- writable: true,
44
- value: new Map()
45
- });
46
- /**
47
- * Request timeout in ms.
48
- * Set to `null` to disable.
49
- */
50
- Object.defineProperty(this, "timeout", {
51
- enumerable: true,
52
- configurable: true,
53
- writable: true,
54
- value: void 0
55
- });
56
- /** Keep-alive configuration settings. */
57
- Object.defineProperty(this, "keepAlive", {
58
- enumerable: true,
59
- configurable: true,
60
- writable: true,
61
- value: void 0
62
- });
63
- /** The WebSocket that is used for communication. */
64
- Object.defineProperty(this, "socket", {
65
- enumerable: true,
66
- configurable: true,
67
- writable: true,
68
- value: void 0
69
- });
70
32
  this.socket = new ReconnectingWebSocket(options?.url ?? "wss://api.hyperliquid.xyz/ws", undefined, options?.reconnect);
71
33
  this._hlEvents = new HyperliquidEventTarget(this.socket);
72
- this._wsRequester = new WebSocketRequestDispatcher(this.socket, this._hlEvents);
34
+ this._wsRequester = new WebSocketAsyncRequest(this.socket, this._hlEvents);
73
35
  this.timeout = options?.timeout === undefined ? 10_000 : options.timeout;
74
36
  this.keepAlive = {
75
- interval: options?.keepAlive?.interval === undefined ? 20_000 : options.keepAlive.interval,
37
+ interval: options?.keepAlive?.interval === undefined ? 30_000 : options.keepAlive?.interval,
38
+ timeout: options?.keepAlive?.timeout === undefined ? this.timeout : options.keepAlive?.timeout,
76
39
  };
77
40
  // Initialize listeners
78
41
  this.socket.addEventListener("open", () => {
79
- // Start keep-alive timer
80
- if (this.keepAlive.interval && this._keepAliveTimer === null) {
81
- this._keepAliveTimer = setInterval(() => {
82
- this.socket.send(JSON.stringify({ method: "ping" }));
83
- }, this.keepAlive.interval);
84
- }
42
+ // Start keep-alive handler
43
+ this._keepAlive();
85
44
  });
86
45
  this.socket.addEventListener("close", () => {
87
46
  // Clear keep-alive timer
88
- if (this._keepAliveTimer !== null) {
89
- clearInterval(this._keepAliveTimer);
90
- this._keepAliveTimer = null;
47
+ if (this._keepAliveTimeout !== null) {
48
+ clearTimeout(this._keepAliveTimeout);
49
+ this._keepAliveTimeout = null;
91
50
  }
92
51
  // Clear all subscriptions
93
52
  for (const subscriptionInfo of this._subscriptions.values()) {
@@ -99,12 +58,14 @@ export class WebSocketTransport {
99
58
  }
100
59
  /**
101
60
  * Sends a request to the Hyperliquid API via WebSocket.
61
+ *
62
+ * Note: Explorer requests are not supported in the Hyperliquid WebSocket API.
63
+ *
102
64
  * @param endpoint - The API endpoint to send the request to (`explorer` requests are not supported).
103
65
  * @param payload - The payload to send with the request.
104
66
  * @param signal - An optional abort signal.
105
67
  * @returns A promise that resolves with parsed JSON response body.
106
68
  * @throws {WebSocketRequestError} - An error that occurs when a WebSocket request fails.
107
- * @note Explorer requests are not supported in the Hyperliquid WebSocket API.
108
69
  */
109
70
  request(type, payload, signal) {
110
71
  const combinedTimeoutSignal = this._getCombinedTimeoutSignal(signal);
@@ -115,15 +76,19 @@ export class WebSocketTransport {
115
76
  }
116
77
  /**
117
78
  * Subscribes to a Hyperliquid event channel.
79
+ *
80
+ * Sends a subscription request to the server and listens for events.
81
+ *
118
82
  * @param channel - The event channel to listen to.
119
83
  * @param payload - A payload to send with the subscription request.
120
84
  * @param listener - A function to call when the event is dispatched.
121
85
  * @param signal - An optional abort signal for canceling the subscription request.
122
86
  * @returns A promise that resolves with a {@link Subscription} object to manage the subscription lifecycle.
87
+ * @throws {WebSocketRequestError} - An error that occurs when a WebSocket request fails.
123
88
  */
124
89
  async subscribe(channel, payload, listener, signal) {
125
90
  // Create a unique identifier for the subscription
126
- const id = WebSocketRequestDispatcher.requestToId(payload);
91
+ const id = WebSocketAsyncRequest.requestToId(payload);
127
92
  // Initialize new subscription, if it doesn't exist
128
93
  let subscription = this._subscriptions.get(id);
129
94
  if (!subscription) {
@@ -224,11 +189,7 @@ export class WebSocketTransport {
224
189
  this.socket.close();
225
190
  });
226
191
  }
227
- /**
228
- * Combines the provided abort signal with the timeout signal.
229
- * @param signal An optional abort signal.
230
- * @returns A combined abort signal or undefined.
231
- */
192
+ /** Combines the provided abort signal with the timeout signal. */
232
193
  _getCombinedTimeoutSignal(signal) {
233
194
  const timeoutSignal = this.timeout ? AbortSignal.timeout(this.timeout) : undefined;
234
195
  const combinedSignal = signal && timeoutSignal
@@ -236,6 +197,30 @@ export class WebSocketTransport {
236
197
  : signal ?? timeoutSignal;
237
198
  return combinedSignal;
238
199
  }
200
+ /**
201
+ * Initiate background keep the connection alive.
202
+ * Sends ping only when needed.
203
+ */
204
+ _keepAlive() {
205
+ if (this.keepAlive.interval === null || this._keepAliveTimeout)
206
+ return;
207
+ const tick = async () => {
208
+ if (this.socket.readyState !== ReconnectingWebSocket.OPEN || !this._keepAliveTimeout)
209
+ return;
210
+ // Check if the last request was sent more than the keep-alive interval ago
211
+ if (Date.now() - this._wsRequester.lastRequestTime >= this.keepAlive.interval) {
212
+ const timeoutSignal = this.keepAlive.timeout ? AbortSignal.timeout(this.keepAlive.timeout) : undefined;
213
+ await this._wsRequester.request("ping", timeoutSignal)
214
+ .catch(() => undefined); // Ignore errors
215
+ }
216
+ // Schedule the next ping
217
+ if (this.socket.readyState === ReconnectingWebSocket.OPEN && this._keepAliveTimeout) {
218
+ const nextDelay = this.keepAlive.interval - (Date.now() - this._wsRequester.lastRequestTime);
219
+ this._keepAliveTimeout = setTimeout(tick, nextDelay);
220
+ }
221
+ };
222
+ this._keepAliveTimeout = setTimeout(tick, this.keepAlive.interval);
223
+ }
239
224
  async [Symbol.asyncDispose]() {
240
225
  await this.close();
241
226
  }