@nktkas/hyperliquid 0.23.1 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/CONTRIBUTING.md +3 -2
  2. package/README.md +178 -194
  3. package/esm/mod.d.ts +2 -1
  4. package/esm/mod.d.ts.map +1 -1
  5. package/esm/src/base.d.ts +0 -5
  6. package/esm/src/base.d.ts.map +1 -1
  7. package/esm/src/clients/exchange.d.ts +485 -392
  8. package/esm/src/clients/exchange.d.ts.map +1 -1
  9. package/esm/src/clients/exchange.js +517 -912
  10. package/esm/src/clients/info.d.ts +249 -203
  11. package/esm/src/clients/info.d.ts.map +1 -1
  12. package/esm/src/clients/info.js +258 -368
  13. package/esm/src/clients/multiSign.d.ts +14 -1184
  14. package/esm/src/clients/multiSign.d.ts.map +1 -1
  15. package/esm/src/clients/multiSign.js +37 -2004
  16. package/esm/src/clients/subscription.d.ts +101 -99
  17. package/esm/src/clients/subscription.d.ts.map +1 -1
  18. package/esm/src/clients/subscription.js +107 -152
  19. package/esm/src/signing/_signTypedData/ethers.d.ts +16 -4
  20. package/esm/src/signing/_signTypedData/ethers.d.ts.map +1 -1
  21. package/esm/src/signing/_signTypedData/ethers.js +1 -1
  22. package/esm/src/signing/_signTypedData/mod.d.ts +12 -12
  23. package/esm/src/signing/_signTypedData/mod.d.ts.map +1 -1
  24. package/esm/src/signing/_signTypedData/mod.js +52 -24
  25. package/esm/src/signing/_signTypedData/private_key.d.ts +6 -5
  26. package/esm/src/signing/_signTypedData/private_key.d.ts.map +1 -1
  27. package/esm/src/signing/_signTypedData/private_key.js +40 -19
  28. package/esm/src/signing/_signTypedData/viem.d.ts +27 -6
  29. package/esm/src/signing/_signTypedData/viem.d.ts.map +1 -1
  30. package/esm/src/signing/_signTypedData/viem.js +1 -1
  31. package/esm/src/signing/_sorter.d.ts +18 -19
  32. package/esm/src/signing/_sorter.d.ts.map +1 -1
  33. package/esm/src/signing/_sorter.js +57 -59
  34. package/esm/src/signing/mod.d.ts +179 -129
  35. package/esm/src/signing/mod.d.ts.map +1 -1
  36. package/esm/src/signing/mod.js +184 -132
  37. package/esm/src/transports/base.d.ts +2 -1
  38. package/esm/src/transports/base.d.ts.map +1 -1
  39. package/esm/src/transports/http/http_transport.d.ts +3 -2
  40. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  41. package/esm/src/transports/http/http_transport.js +4 -4
  42. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +14 -6
  43. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  44. package/esm/src/transports/websocket/_hyperliquid_event_target.js +1 -2
  45. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts +2 -1
  46. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  47. package/esm/src/transports/websocket/_reconnecting_websocket.js +1 -0
  48. package/esm/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  49. package/esm/src/transports/websocket/_websocket_async_request.js +17 -21
  50. package/esm/src/transports/websocket/websocket_transport.d.ts +4 -4
  51. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  52. package/esm/src/transports/websocket/websocket_transport.js +6 -6
  53. package/esm/src/types/exchange/requests.d.ts +547 -306
  54. package/esm/src/types/exchange/requests.d.ts.map +1 -1
  55. package/esm/src/types/exchange/responses.d.ts +105 -25
  56. package/esm/src/types/exchange/responses.d.ts.map +1 -1
  57. package/esm/src/types/explorer/requests.d.ts +3 -3
  58. package/esm/src/types/explorer/requests.d.ts.map +1 -1
  59. package/esm/src/types/explorer/responses.d.ts +1 -1
  60. package/esm/src/types/explorer/responses.d.ts.map +1 -1
  61. package/esm/src/types/info/accounts.d.ts +405 -98
  62. package/esm/src/types/info/accounts.d.ts.map +1 -1
  63. package/esm/src/types/info/assets.d.ts +131 -35
  64. package/esm/src/types/info/assets.d.ts.map +1 -1
  65. package/esm/src/types/info/markets.d.ts +29 -8
  66. package/esm/src/types/info/markets.d.ts.map +1 -1
  67. package/esm/src/types/info/orders.d.ts +64 -17
  68. package/esm/src/types/info/orders.d.ts.map +1 -1
  69. package/esm/src/types/info/requests.d.ts +126 -51
  70. package/esm/src/types/info/requests.d.ts.map +1 -1
  71. package/esm/src/types/info/validators.d.ts +44 -14
  72. package/esm/src/types/info/validators.d.ts.map +1 -1
  73. package/esm/src/types/info/vaults.d.ts +25 -10
  74. package/esm/src/types/info/vaults.d.ts.map +1 -1
  75. package/esm/src/types/mod.d.ts +1 -1
  76. package/esm/src/types/mod.d.ts.map +1 -1
  77. package/esm/src/types/subscriptions/requests.d.ts +21 -66
  78. package/esm/src/types/subscriptions/requests.d.ts.map +1 -1
  79. package/esm/src/types/subscriptions/responses.d.ts +46 -55
  80. package/esm/src/types/subscriptions/responses.d.ts.map +1 -1
  81. package/package.json +2 -3
  82. package/script/mod.d.ts +2 -1
  83. package/script/mod.d.ts.map +1 -1
  84. package/script/src/base.d.ts +0 -5
  85. package/script/src/base.d.ts.map +1 -1
  86. package/script/src/clients/exchange.d.ts +485 -392
  87. package/script/src/clients/exchange.d.ts.map +1 -1
  88. package/script/src/clients/exchange.js +516 -911
  89. package/script/src/clients/info.d.ts +249 -203
  90. package/script/src/clients/info.d.ts.map +1 -1
  91. package/script/src/clients/info.js +258 -368
  92. package/script/src/clients/multiSign.d.ts +14 -1184
  93. package/script/src/clients/multiSign.d.ts.map +1 -1
  94. package/script/src/clients/multiSign.js +38 -2005
  95. package/script/src/clients/subscription.d.ts +101 -99
  96. package/script/src/clients/subscription.d.ts.map +1 -1
  97. package/script/src/clients/subscription.js +107 -152
  98. package/script/src/signing/_signTypedData/ethers.d.ts +16 -4
  99. package/script/src/signing/_signTypedData/ethers.d.ts.map +1 -1
  100. package/script/src/signing/_signTypedData/ethers.js +2 -2
  101. package/script/src/signing/_signTypedData/mod.d.ts +12 -12
  102. package/script/src/signing/_signTypedData/mod.d.ts.map +1 -1
  103. package/script/src/signing/_signTypedData/mod.js +51 -26
  104. package/script/src/signing/_signTypedData/private_key.d.ts +6 -5
  105. package/script/src/signing/_signTypedData/private_key.d.ts.map +1 -1
  106. package/script/src/signing/_signTypedData/private_key.js +40 -18
  107. package/script/src/signing/_signTypedData/viem.d.ts +27 -6
  108. package/script/src/signing/_signTypedData/viem.d.ts.map +1 -1
  109. package/script/src/signing/_signTypedData/viem.js +2 -2
  110. package/script/src/signing/_sorter.d.ts +18 -19
  111. package/script/src/signing/_sorter.d.ts.map +1 -1
  112. package/script/src/signing/_sorter.js +57 -59
  113. package/script/src/signing/mod.d.ts +179 -129
  114. package/script/src/signing/mod.d.ts.map +1 -1
  115. package/script/src/signing/mod.js +187 -150
  116. package/script/src/transports/base.d.ts +2 -1
  117. package/script/src/transports/base.d.ts.map +1 -1
  118. package/script/src/transports/http/http_transport.d.ts +3 -2
  119. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  120. package/script/src/transports/http/http_transport.js +4 -4
  121. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +14 -6
  122. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  123. package/script/src/transports/websocket/_hyperliquid_event_target.js +1 -2
  124. package/script/src/transports/websocket/_reconnecting_websocket.d.ts +2 -1
  125. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  126. package/script/src/transports/websocket/_reconnecting_websocket.js +1 -0
  127. package/script/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  128. package/script/src/transports/websocket/_websocket_async_request.js +17 -21
  129. package/script/src/transports/websocket/websocket_transport.d.ts +4 -4
  130. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  131. package/script/src/transports/websocket/websocket_transport.js +6 -6
  132. package/script/src/types/exchange/requests.d.ts +547 -306
  133. package/script/src/types/exchange/requests.d.ts.map +1 -1
  134. package/script/src/types/exchange/responses.d.ts +105 -25
  135. package/script/src/types/exchange/responses.d.ts.map +1 -1
  136. package/script/src/types/explorer/requests.d.ts +3 -3
  137. package/script/src/types/explorer/requests.d.ts.map +1 -1
  138. package/script/src/types/explorer/responses.d.ts +1 -1
  139. package/script/src/types/explorer/responses.d.ts.map +1 -1
  140. package/script/src/types/info/accounts.d.ts +405 -98
  141. package/script/src/types/info/accounts.d.ts.map +1 -1
  142. package/script/src/types/info/assets.d.ts +131 -35
  143. package/script/src/types/info/assets.d.ts.map +1 -1
  144. package/script/src/types/info/markets.d.ts +29 -8
  145. package/script/src/types/info/markets.d.ts.map +1 -1
  146. package/script/src/types/info/orders.d.ts +64 -17
  147. package/script/src/types/info/orders.d.ts.map +1 -1
  148. package/script/src/types/info/requests.d.ts +126 -51
  149. package/script/src/types/info/requests.d.ts.map +1 -1
  150. package/script/src/types/info/validators.d.ts +44 -14
  151. package/script/src/types/info/validators.d.ts.map +1 -1
  152. package/script/src/types/info/vaults.d.ts +25 -10
  153. package/script/src/types/info/vaults.d.ts.map +1 -1
  154. package/script/src/types/mod.d.ts +1 -1
  155. package/script/src/types/mod.d.ts.map +1 -1
  156. package/script/src/types/subscriptions/requests.d.ts +21 -66
  157. package/script/src/types/subscriptions/requests.d.ts.map +1 -1
  158. package/script/src/types/subscriptions/responses.d.ts +46 -55
  159. package/script/src/types/subscriptions/responses.d.ts.map +1 -1
  160. package/esm/src/signing/_signTypedData/window.d.ts +0 -29
  161. package/esm/src/signing/_signTypedData/window.d.ts.map +0 -1
  162. package/esm/src/signing/_signTypedData/window.js +0 -30
  163. package/script/src/signing/_signTypedData/window.d.ts +0 -29
  164. package/script/src/signing/_signTypedData/window.d.ts.map +0 -1
  165. package/script/src/signing/_signTypedData/window.js +0 -34
package/README.md CHANGED
@@ -6,16 +6,16 @@
6
6
  [![bundlephobia](https://img.shields.io/bundlephobia/minzip/@nktkas/hyperliquid?style=flat-square)](https://bundlephobia.com/package/@nktkas/hyperliquid)
7
7
 
8
8
  Unofficial [Hyperliquid API](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api) SDK for all major JS
9
- runtimes, written in TypeScript and provided with tests.
9
+ runtimes, written in TypeScript.
10
10
 
11
11
  ## Features
12
12
 
13
13
  - 🖋️ **Typed**: Source code is 100% TypeScript.
14
- - 🧪 **Tested**: Good code coverage and type-safe API responses.
14
+ - 🧪 **Tested**: Good code coverage and type relevance.
15
15
  - 📦 **Minimal dependencies**: A few small trusted dependencies.
16
16
  - 🌐 **Cross-Environment Support**: Compatible with all major JS runtimes.
17
- - 🔧 **Integratable**: Easy to use with [viem](https://github.com/wevm/viem),
18
- [ethers](https://github.com/ethers-io/ethers.js) and other wallet libraries.
17
+ - 🔧 **Integratable**: Easy to use with wallet providers ([viem](https://github.com/wevm/viem),
18
+ [ethers](https://github.com/ethers-io/ethers.js), private key directly).
19
19
  - 📚 **Documented**: JSDoc annotations with usage examples in source code.
20
20
 
21
21
  ## Installation
@@ -53,16 +53,11 @@ deno add jsr:@nktkas/hyperliquid
53
53
  <summary>For React Native, you need to import polyfills before importing the SDK:</summary>
54
54
 
55
55
  ```js
56
- // React Native 0.76.3 / Expo v52
56
+ // React Native v0.79 / Expo v53
57
57
  // Issues:
58
- // - signing: does not support private keys directly, use viem or ethers
58
+ // - signing: does not support private keys directly, use `viem` or `ethers`
59
59
 
60
- import { Event, EventTarget } from "event-target-shim";
61
-
62
- if (!globalThis.EventTarget || !globalThis.Event) {
63
- globalThis.EventTarget = EventTarget;
64
- globalThis.Event = Event;
65
- }
60
+ import "event-target-polyfill";
66
61
 
67
62
  if (!globalThis.CustomEvent) {
68
63
  globalThis.CustomEvent = function (type, params) {
@@ -97,27 +92,34 @@ if (!Promise.withResolvers) {
97
92
 
98
93
  ## Quick Start
99
94
 
100
- #### Info endpoint
95
+ ### [Info endpoint](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint)
101
96
 
102
97
  ```ts
98
+ // 1. Import module
103
99
  import * as hl from "@nktkas/hyperliquid";
104
100
 
105
- const transport = new hl.HttpTransport();
106
- const infoClient = new hl.InfoClient({ transport });
101
+ // 2. Set up client with transport
102
+ const infoClient = new hl.InfoClient({
103
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
104
+ });
107
105
 
106
+ // 3. Query data
108
107
  const openOrders = await infoClient.openOrders({ user: "0x..." });
109
108
  ```
110
109
 
111
- #### Exchange endpoint
110
+ ### [Exchange endpoint](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint)
112
111
 
113
112
  ```ts
113
+ // 1. Import module
114
114
  import * as hl from "@nktkas/hyperliquid";
115
115
 
116
- const privateKey = "0x..."; // or `viem`, `ethers`
117
-
118
- const transport = new hl.HttpTransport();
119
- const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
116
+ // 2. Set up client with wallet and transport
117
+ const exchClient = new hl.ExchangeClient({
118
+ wallet: "0x...", // `viem`, `ethers`, or private key directly
119
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
120
+ });
120
121
 
122
+ // 3. Execute an action
121
123
  const result = await exchClient.order({
122
124
  orders: [{
123
125
  a: 0,
@@ -135,38 +137,41 @@ const result = await exchClient.order({
135
137
  });
136
138
  ```
137
139
 
138
- #### Subscription
140
+ ### [Subscription](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions)
139
141
 
140
142
  ```ts
143
+ // 1. Import module
141
144
  import * as hl from "@nktkas/hyperliquid";
142
145
 
143
- const transport = new hl.WebSocketTransport();
144
- const subsClient = new hl.SubscriptionClient({ transport });
146
+ // 2. Set up client with transport
147
+ const subsClient = new hl.SubscriptionClient({
148
+ transport: new hl.WebSocketTransport(),
149
+ });
145
150
 
151
+ // 3. Subscribe to events
146
152
  const sub = await subsClient.allMids((event) => {
147
153
  console.log(event);
148
154
  });
149
-
150
- await sub.unsubscribe(); // unsubscribe from the event
155
+ await sub.unsubscribe();
151
156
  ```
152
157
 
153
- #### Multi-Sign
158
+ ### [Multi-Sign](https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig)
154
159
 
155
160
  ```ts
161
+ // 1. Import module
156
162
  import * as hl from "@nktkas/hyperliquid";
157
163
 
158
- const multiSignAddress = "0x...";
159
- const signers = [
160
- "0x...", // Private key; or any other wallet libraries
161
- ] as const;
162
-
163
- const transport = new hl.HttpTransport();
164
- const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers }); // extends `ExchangeClient`
165
-
166
- const data = await multiSignClient.approveAgent({ // same API as `ExchangeClient`
167
- agentAddress: "0x...",
168
- agentName: "agentName",
164
+ // 2. Set up client with transport, multi-sign address, and signers
165
+ const multiSignClient = new hl.MultiSignClient({
166
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
167
+ multiSignAddress: "0x...",
168
+ signers: [
169
+ "0x...", // `viem`, `ethers`, or private key directly
170
+ ],
169
171
  });
172
+
173
+ // 3. Execute an action (same as `ExchangeClient`)
174
+ await multiSignClient.approveAgent({ agentAddress: "0x..." });
170
175
  ```
171
176
 
172
177
  ## Usage
@@ -179,26 +184,27 @@ First, choose and configure your transport layer (more details in the [API Refer
179
184
  import * as hl from "@nktkas/hyperliquid";
180
185
 
181
186
  // 1. HTTP Transport: suitable for one-time requests or serverless environments
182
- const httpTransport = new hl.HttpTransport(); // Accepts optional parameters (e.g. isTestnet, timeout, etc.)
187
+ const httpTransport = new hl.HttpTransport({...}); // Accepts optional parameters (e.g. isTestnet, timeout, etc.)
183
188
 
184
189
  // 2. WebSocket Transport: has better network latency than HTTP transport
185
- const wsTransport = new hl.WebSocketTransport(); // Accepts optional parameters (e.g. url, timeout, reconnect, etc.)
190
+ const wsTransport = new hl.WebSocketTransport({...}); // Accepts optional parameters (e.g. url, timeout, reconnect, etc.)
186
191
  ```
187
192
 
188
193
  ### 2) Initialize Client
189
194
 
190
195
  Next, initialize a client with the transport layer (more details in the [API Reference](#clients)):
191
196
 
192
- #### Create InfoClient
197
+ #### Create [InfoClient](#infoclient)
193
198
 
194
199
  ```ts
195
200
  import * as hl from "@nktkas/hyperliquid";
196
201
 
197
- const transport = new hl.HttpTransport(); // or `WebSocketTransport`
198
- const infoClient = new hl.InfoClient({ transport });
202
+ const infoClient = new hl.InfoClient({
203
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
204
+ });
199
205
  ```
200
206
 
201
- #### Create ExchangeClient
207
+ #### Create [ExchangeClient](#exchangeclient)
202
208
 
203
209
  ```ts
204
210
  import * as hl from "@nktkas/hyperliquid";
@@ -210,104 +216,104 @@ const transport = new hl.HttpTransport(); // or `WebSocketTransport`
210
216
 
211
217
  // 1. Using private key directly
212
218
  const privateKey = "0x...";
213
- const exchClient_privateKey = new hl.ExchangeClient({ wallet: privateKey, transport });
219
+ const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
214
220
 
215
221
  // 2. Using Viem
216
222
  const viemAccount = privateKeyToAccount("0x...");
217
- const exchClient_viem = new hl.ExchangeClient({ wallet: viemAccount, transport });
223
+ const exchClient = new hl.ExchangeClient({ wallet: viemAccount, transport });
218
224
 
219
- // 3. Using Ethers (or Ethers V5)
225
+ // 3. Using Ethers (V5 or V6)
220
226
  const ethersWallet = new ethers.Wallet("0x...");
221
- const exchClient_ethers = new hl.ExchangeClient({ wallet: ethersWallet, transport });
227
+ const exchClient = new hl.ExchangeClient({ wallet: ethersWallet, transport });
222
228
 
223
229
  // 4. Using external wallet (e.g. MetaMask) via Viem
224
- const [account] = await window.ethereum.request({ method: "eth_requestAccounts" });
230
+ const [account] = await window.ethereum.request({ method: "eth_requestAccounts" }) as `0x${string}`[];
225
231
  const externalWallet = createWalletClient({ account, transport: custom(window.ethereum) });
226
- const exchClient_viemMetamask = new hl.ExchangeClient({ wallet: externalWallet, transport });
227
-
228
- // 5. Using external wallet (e.g. MetaMask) via `window.ethereum`
229
- const exchClient_windowMetamask = new hl.ExchangeClient({ wallet: window.ethereum, transport });
232
+ const exchClient = new hl.ExchangeClient({ wallet: externalWallet, transport });
230
233
  ```
231
234
 
232
- #### Create SubscriptionClient
235
+ #### Create [SubscriptionClient](#subscriptionclient)
233
236
 
234
237
  ```ts
235
238
  import * as hl from "@nktkas/hyperliquid";
236
239
 
237
- const transport = new hl.WebSocketTransport(); // only `WebSocketTransport`
238
- const subsClient = new hl.SubscriptionClient({ transport });
240
+ const subsClient = new hl.SubscriptionClient({
241
+ transport: new hl.WebSocketTransport(),
242
+ });
239
243
  ```
240
244
 
241
- #### Create MultiSignClient
245
+ #### Create [MultiSignClient](#multisignclient)
242
246
 
243
247
  ```ts
244
248
  import * as hl from "@nktkas/hyperliquid";
245
249
  import { privateKeyToAccount } from "viem/accounts";
246
250
  import { ethers } from "ethers";
247
251
 
248
- const multiSignAddress = "0x...";
249
- const signers = [
250
- privateKeyToAccount("0x..."), // first is leader for multi-sign transaction, must contain own address
251
- new ethers.Wallet("0x..."),
252
- { // can be a custom async wallet
253
- async signTypedData(params: {
254
- domain: {
255
- name: string;
256
- version: string;
257
- chainId: number;
258
- verifyingContract: Hex;
259
- };
260
- types: {
261
- [key: string]: {
252
+ const multiSignClient = new hl.MultiSignClient({
253
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
254
+ multiSignAddress: "0x...",
255
+ signers: [
256
+ privateKeyToAccount("0x..."), // first is leader for multi-sign transaction (signs transaction 2 times)
257
+ new ethers.Wallet("0x..."),
258
+ { // can be a custom async wallet
259
+ async signTypedData(params: {
260
+ domain: {
262
261
  name: string;
263
- type: string;
264
- }[];
265
- };
266
- primaryType: string;
267
- message: Record<string, unknown>;
268
- }): Promise<Hex> {
269
- // Custom signer logic
270
- return "0x..."; // return hex signature
262
+ version: string;
263
+ chainId: number;
264
+ verifyingContract: Hex;
265
+ };
266
+ types: {
267
+ [key: string]: {
268
+ name: string;
269
+ type: string;
270
+ }[];
271
+ };
272
+ primaryType: string;
273
+ message: Record<string, unknown>;
274
+ }): Promise<Hex> {
275
+ // Custom signer logic
276
+ return "0x..."; // return hex signature
277
+ },
271
278
  },
272
- },
273
- "0x...", // private key directly
274
- ];
275
-
276
- const transport = new hl.HttpTransport();
277
- const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers }); // extends `ExchangeClient`
279
+ "0x...", // private key directly
280
+ // ... more signers
281
+ ],
282
+ });
278
283
  ```
279
284
 
280
285
  ### 3) Use Client
281
286
 
282
287
  Finally, use client methods to interact with the Hyperliquid API (more details in the [API Reference](#clients)):
283
288
 
284
- #### Example of using an InfoClient
289
+ #### Example of using an [InfoClient](#infoclient)
285
290
 
286
291
  ```ts
287
292
  import * as hl from "@nktkas/hyperliquid";
288
293
 
289
- const transport = new hl.HttpTransport();
290
- const infoClient = new hl.InfoClient({ transport });
294
+ const infoClient = new hl.InfoClient({
295
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
296
+ });
291
297
 
292
298
  // L2 Book
293
- const l2Book = await infoClient.l2Book({ coin: "BTC" });
299
+ const l2Book = await infoClient.l2Book({ coin: "ETH" });
294
300
 
295
- // Account clearinghouse state
301
+ // User clearinghouse state
296
302
  const clearinghouseState = await infoClient.clearinghouseState({ user: "0x..." });
297
303
 
298
- // Open orders
304
+ // User open orders
299
305
  const openOrders = await infoClient.openOrders({ user: "0x..." });
300
306
  ```
301
307
 
302
- #### Example of using an ExchangeClient
308
+ #### Example of using an [ExchangeClient](#exchangeclient)
303
309
 
304
310
  ```ts
305
311
  import * as hl from "@nktkas/hyperliquid";
306
312
 
307
- const privateKey = "0x..."; // or `viem`, `ethers`
308
-
309
- const transport = new hl.HttpTransport();
310
- const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
313
+ const exchClient = new hl.ExchangeClient({
314
+ wallet: "0x...", // `viem`, `ethers`, or private key directly
315
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
316
+ });
311
317
 
312
318
  // Place an orders
313
319
  const result = await exchClient.order({
@@ -327,28 +333,23 @@ const result = await exchClient.order({
327
333
  });
328
334
 
329
335
  // Approve an agent
330
- const result = await exchClient.approveAgent({
331
- agentAddress: "0x...",
332
- agentName: "agentName",
333
- });
336
+ const result = await exchClient.approveAgent({ agentAddress: "0x..." });
334
337
 
335
338
  // Withdraw funds
336
- const result = await exchClient.withdraw3({
337
- destination: account.address,
338
- amount: "100",
339
- });
339
+ const result = await exchClient.withdraw3({ destination: "0x...", amount: "100" });
340
340
  ```
341
341
 
342
- #### Example of using a SubscriptionClient
342
+ #### Example of using a [SubscriptionClient](#subscriptionclient)
343
343
 
344
344
  ```ts
345
345
  import * as hl from "@nktkas/hyperliquid";
346
346
 
347
- const transport = new hl.WebSocketTransport();
348
- const subsClient = new hl.SubscriptionClient({ transport });
347
+ const subsClient = new hl.SubscriptionClient({
348
+ transport: new hl.WebSocketTransport(),
349
+ });
349
350
 
350
351
  // L2 Book updates
351
- await subsClient.l2Book({ coin: "BTC" }, (data) => {
352
+ await subsClient.l2Book({ coin: "ETH" }, (data) => {
352
353
  console.log(data);
353
354
  });
354
355
 
@@ -358,54 +359,26 @@ await subsClient.userFills({ user: "0x..." }, (data) => {
358
359
  });
359
360
 
360
361
  // Candle updates
361
- const sub = await subsClient.candle({ coin: "BTC", interval: "1h" }, (data) => {
362
+ await subsClient.candle({ coin: "ETH", interval: "1h" }, (data) => {
362
363
  console.log(data);
363
364
  });
364
365
  ```
365
366
 
366
- #### Example of using a MultiSignClient
367
+ #### Example of using a [MultiSignClient](#multisignclient)
367
368
 
368
369
  ```ts
369
370
  import * as hl from "@nktkas/hyperliquid";
370
371
 
371
- const multiSignAddress = "0x...";
372
- const signers = [
373
- "0x...", // Private keys
374
- ] as const;
375
-
376
- const transport = new hl.HttpTransport();
377
- const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
378
-
379
- // Interaction is the same as with `ExchangeClient`
380
-
381
- // Place an orders
382
- const result = await multiSignClient.order({
383
- orders: [{
384
- a: 0,
385
- b: true,
386
- p: "30000",
387
- s: "0.1",
388
- r: false,
389
- t: {
390
- limit: {
391
- tif: "Gtc",
392
- },
393
- },
394
- }],
395
- grouping: "na",
396
- });
397
-
398
- // Approve an agent
399
- const result = await multiSignClient.approveAgent({
400
- agentAddress: "0x...",
401
- agentName: "agentName",
372
+ const multiSignClient = new hl.MultiSignClient({
373
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
374
+ multiSignAddress: "0x...",
375
+ signers: [
376
+ "0x...", // `viem`, `ethers`, or private key directly
377
+ // ... more signers
378
+ ],
402
379
  });
403
380
 
404
- // Withdraw funds
405
- const result = await multiSignClient.withdraw3({
406
- destination: account.address,
407
- amount: "100",
408
- });
381
+ // Interaction is the same as with `ExchangeClient`
409
382
  ```
410
383
 
411
384
  ## API Reference
@@ -414,9 +387,6 @@ const result = await multiSignClient.withdraw3({
414
387
 
415
388
  A client is an interface through which you can interact with the Hyperliquid API.
416
389
 
417
- The client is responsible for formatting an action, creating a signature correctly, sending a request, and validating a
418
- response.
419
-
420
390
  #### InfoClient
421
391
 
422
392
  ```ts
@@ -442,9 +412,11 @@ class InfoClient {
442
412
  spotDeployState(args: SpotDeployStateParameters): Promise<SpotDeployState>;
443
413
  spotMeta(): Promise<SpotMeta>;
444
414
  spotMetaAndAssetCtxs(): Promise<SpotMetaAndAssetCtxs>;
415
+ spotPairDeployAuctionStatus(): Promise<DeployAuctionStatus>;
445
416
  tokenDetails(args: TokenDetailsParameters): Promise<TokenDetails>;
446
417
 
447
418
  // Account
419
+ activeAssetData(args: ActiveAssetDataParameters): Promise<ActiveAssetData>;
448
420
  clearinghouseState(args: ClearinghouseStateParameters): Promise<PerpsClearinghouseState>;
449
421
  extraAgents(args: ExtraAgentsParameters): Promise<ExtraAgent[]>;
450
422
  isVip(args: IsVipParameters): Promise<boolean>;
@@ -503,16 +475,11 @@ class InfoClient {
503
475
  class ExchangeClient {
504
476
  constructor(args: {
505
477
  transport: HttpTransport | WebSocketTransport;
506
- wallet:
507
- | Hex // Private key directly
508
- | AbstractViemWalletClient // viem
509
- | AbstractEthersSigner // ethers
510
- | AbstractEthersV5Signer // ethers v5
511
- | AbstractWindowEthereum; // window.ethereum (EIP-1193)
478
+ wallet: AbstractWallet; // `viem`, `ethers` (v5 or v6), or private key directly
512
479
  isTestnet?: boolean; // Whether to use testnet (default: false)
513
480
  defaultVaultAddress?: Hex; // Vault address used by default if not provided in method call
514
- signatureChainId?: Hex | (() => MaybePromise<Hex>); // Chain ID used for signing (default: trying to guess based on wallet and `isTestnet`)
515
- nonceManager?: () => MaybePromise<number>; // Function to get the next nonce (default: auto-incrementing `Date.now()`)
481
+ signatureChainId?: Hex | (() => MaybePromise<Hex>); // Chain ID used for signing (default: get chain id from wallet otherwise `0x1`)
482
+ nonceManager?: () => MaybePromise<number>; // Function to get the next nonce (default: monotonically incrementing `Date.now()`)
516
483
  });
517
484
 
518
485
  // Order
@@ -533,15 +500,16 @@ class ExchangeClient {
533
500
  claimRewards(): Promise<SuccessResponse>;
534
501
  createSubAccount(args: CreateSubAccountParameters): Promise<CreateSubAccountResponse>;
535
502
  evmUserModify(args: EvmUserModifyParameters): Promise<SuccessResponse>;
503
+ noop(): Promise<SuccessResponse>;
536
504
  registerReferrer(args: RegisterReferrerParameters): Promise<SuccessResponse>;
537
505
  reserveRequestWeight(args: ReserveRequestWeightParameters): Promise<SuccessResponse>;
538
506
  setDisplayName(args: SetDisplayNameParameters): Promise<SuccessResponse>;
539
507
  setReferrer(args: SetReferrerParameters): Promise<SuccessResponse>;
508
+ subAccountModify(args: SubAccountModifyParameters): Promise<SuccessResponse>;
540
509
  spotUser(args: SpotUserParameters): Promise<SuccessResponse>;
541
510
 
542
511
  // Transfer
543
- perpDexClassTransfer(args: PerpDexClassTransferParameters): Promise<SuccessResponse>;
544
- perpDexTransfer(args: PerpDexTransferParameters): Promise<SuccessResponse>;
512
+ sendAsset(args: SendAssetParameters): Promise<SuccessResponse>;
545
513
  spotSend(args: SpotSendParameters): Promise<SuccessResponse>;
546
514
  subAccountSpotTransfer(args: SubAccountSpotTransferParameters): Promise<SuccessResponse>;
547
515
  subAccountTransfer(args: SubAccountTransferParameters): Promise<SuccessResponse>;
@@ -585,7 +553,6 @@ class SubscriptionClient {
585
553
 
586
554
  // Market
587
555
  activeAssetCtx(args: EventActiveAssetCtxParameters, listener: (data: WsActiveAssetCtx | WsActiveSpotAssetCtx) => void): Promise<Subscription>;
588
- activeAssetData(args: EventActiveAssetDataParameters, listener: (data: WsActiveAssetData) => void): Promise<Subscription>;
589
556
  allMids(listener: (data: WsAllMids) => void): Promise<Subscription>;
590
557
  bbo(args: EventBboParameters, listener: (data: WsBbo) => void): Promise<Subscription>;
591
558
  candle(args: EventCandleParameters, listener: (data: Candle) => void): Promise<Subscription>;
@@ -593,6 +560,7 @@ class SubscriptionClient {
593
560
  trades(args: EventTradesParameters, listener: (data: WsTrade[]) => void): Promise<Subscription>;
594
561
 
595
562
  // Account
563
+ activeAssetData(args: EventActiveAssetDataParameters, listener: (data: ActiveAssetData) => void): Promise<Subscription>;
596
564
  notification(args: EventNotificationParameters, listener: (data: WsNotification) => void): Promise<Subscription>;
597
565
  userEvents(args: EventUserEventsParameters, listener: (data: WsUserEvent) => void): Promise<Subscription>;
598
566
  userFundings(args: EventUserFundingsParameters, listener: (data: WsUserFundings) => void): Promise<Subscription>;
@@ -605,7 +573,7 @@ class SubscriptionClient {
605
573
  userTwapHistory(args: EventUserTwapHistory, listener: (data: WsUserTwapHistory) => void): Promise<Subscription>;
606
574
  userTwapSliceFills(args: EventUserTwapSliceFills, listener: (data: WsUserTwapSliceFills) => void): Promise<Subscription>;
607
575
 
608
- // Explorer
576
+ // Explorer (RPC endpoint)
609
577
  explorerBlock(listener: (data: WsBlockDetails[]) => void): Promise<Subscription>;
610
578
  explorerTxs(listener: (data: TxDetails[]) => void): Promise<Subscription>;
611
579
  }
@@ -618,12 +586,12 @@ class SubscriptionClient {
618
586
  class MultiSignClient extends ExchangeClient {
619
587
  constructor(
620
588
  args:
621
- & Omit<ExchangeClientParameters, "wallet"> // Instead of `wallet`, you should specify the following parameters:
589
+ & Omit<ExchangeClientParameters, "wallet"> // instead of `wallet`, you should specify the following parameters:
622
590
  & {
623
- multiSignAddress: Hex; // Multi-signature address
624
- signers: [ // Array of signers
625
- AbstractWalletWithAddress, // First signer is the leader of a multi-sign transaction
626
- ...AbstractWallet[], // Any number of additional signers
591
+ multiSignAddress: Hex;
592
+ signers: [
593
+ AbstractWallet, // first is leader for multi-sign transaction (signs transaction 2 times)
594
+ ...AbstractWallet[], // may be additional signers
627
595
  ];
628
596
  },
629
597
  );
@@ -638,7 +606,11 @@ Transport acts as a layer between class requests and Hyperliquid servers.
638
606
 
639
607
  #### HTTP Transport
640
608
 
641
- HTTP transport is suitable for one-off requests or serverless environments.
609
+ **Features:**
610
+
611
+ - Uses [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for requests. Can be configured using
612
+ [`fetchOptions`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit).
613
+ - Automatically determines the target URL based on the request + `isTestnet` flag.
642
614
 
643
615
  ```ts
644
616
  class HttpTransport {
@@ -658,7 +630,20 @@ class HttpTransport {
658
630
 
659
631
  #### WebSocket Transport
660
632
 
661
- WebSocket transport has better network latency than HTTP transport.
633
+ **Features:**
634
+
635
+ - Uses [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) for requests.
636
+ - Supports [subscriptions](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions)
637
+ and [post requests](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/post-requests).
638
+ - Automatically restores connection after loss and resubscribes to previous subscriptions.
639
+ - Smart keep alive (pings only when idle).
640
+ - Lazy initialization with message buffering during connection establishment.
641
+
642
+ **Limitations:**
643
+
644
+ - Cannot mix api/explorer endpoints or mainnet/testnet in single connection. Need to create separate instances for
645
+ different endpoints.
646
+ - Cannot send explorer post-requests via WebSocket. Use [HTTP transport](#http-transport).
662
647
 
663
648
  ```ts
664
649
  class WebSocketTransport {
@@ -687,33 +672,28 @@ class WebSocketTransport {
687
672
 
688
673
  ### `/types`
689
674
 
690
- The import point gives access to all Hyperliquid-related types, including the base types on which class methods are
691
- based.
675
+ The import point gives access to all request/response types associated with Hyperliquid API.
692
676
 
693
677
  ### `/signing`
694
678
 
695
- The import point gives access to functions that generate signatures for Hyperliquid transactions.
679
+ The import point gives access to functions that generate signatures for Hyperliquid API actions.
696
680
 
697
- ### Examples
698
-
699
- #### Cancel order yourself
681
+ #### L1 Action
700
682
 
701
683
  ```ts
702
684
  import { actionSorter, signL1Action } from "@nktkas/hyperliquid/signing";
703
685
 
704
- const privateKey = "0x..."; // or `viem`, `ethers`
705
-
706
- const nonce = Date.now();
707
- const action = {
686
+ const action = actionSorter.cancel({
708
687
  type: "cancel",
709
688
  cancels: [
710
689
  { a: 0, o: 12345 },
711
690
  ],
712
- } as const;
691
+ });
692
+ const nonce = Date.now();
713
693
 
714
694
  const signature = await signL1Action({
715
- wallet: privateKey,
716
- action: actionSorter[action.type](action),
695
+ wallet: "0x...", // `viem`, `ethers`, or private key directly
696
+ action,
717
697
  nonce,
718
698
  });
719
699
 
@@ -721,29 +701,27 @@ const signature = await signL1Action({
721
701
  const response = await fetch("https://api.hyperliquid.xyz/exchange", {
722
702
  method: "POST",
723
703
  headers: { "Content-Type": "application/json" },
724
- body: JSON.stringify({ action, signature, nonce }),
704
+ body: JSON.stringify({ action, signature, nonce }), // recommended to send the same formatted action
725
705
  });
726
706
  const body = await response.json();
727
707
  ```
728
708
 
729
- #### Approve agent yourself
709
+ #### User Signed Action
730
710
 
731
711
  ```ts
732
- import { signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
733
-
734
- const privateKey = "0x..."; // or `viem`, `ethers`
712
+ import { actionSorter, signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
735
713
 
736
- const action = {
714
+ const action = actionSorter.approveAgent({
737
715
  type: "approveAgent",
738
716
  signatureChainId: "0x66eee",
739
717
  hyperliquidChain: "Mainnet",
740
718
  agentAddress: "0x...",
741
719
  agentName: "Agent",
742
720
  nonce: Date.now(),
743
- } as const;
721
+ });
744
722
 
745
723
  const signature = await signUserSignedAction({
746
- wallet: privateKey,
724
+ wallet: "0x...", // `viem`, `ethers`, or private key directly
747
725
  action,
748
726
  types: userSignedActionEip712Types[action.type],
749
727
  });
@@ -752,7 +730,7 @@ const signature = await signUserSignedAction({
752
730
  const response = await fetch("https://api.hyperliquid.xyz/exchange", {
753
731
  method: "POST",
754
732
  headers: { "Content-Type": "application/json" },
755
- body: JSON.stringify({ action, signature, nonce: action.nonce }),
733
+ body: JSON.stringify({ action, signature, nonce: action.nonce }), // recommended to send the same formatted action
756
734
  });
757
735
  const body = await response.json();
758
736
  ```
@@ -761,22 +739,28 @@ const body = await response.json();
761
739
 
762
740
  ### How to execute an L1 action via an external wallet (e.g. MetaMask)?
763
741
 
764
- Hyperliquid requires chain `1337` for L1 actions (open order, change leverage, etc.). There are two ways to execute an
765
- L1 action through an external wallet:
742
+ Hyperliquid requires chain `1337` for L1 action signatures. To handle this with external wallets:
766
743
 
767
744
  - (recommended) Create an
768
745
  [Agent Wallet](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/nonces-and-api-wallets#api-wallets)
769
746
  and execute all L1 actions through it
770
- - Change the user's chain to `1337`, however, the user will sign unreadable data
747
+ - Change a user's chain to `1337`, however, the user will sign unreadable data
771
748
 
772
749
  ### How to create a market order?
773
750
 
774
- Hyperliquid doesn't have traditional market orders, but you can achieve market-like execution by placing limit orders
775
- with `tif: "Ioc"` and prices that guarantee immediate execution:
751
+ Hyperliquid doesn't have traditional market orders, but you can achieve market-like execution by placing limit order
752
+ with `tif: "Ioc"` and price that guarantee immediate execution:
776
753
 
777
754
  - For buys: set limit price >= current best ask
778
755
  - For sells: set limit price <= current best bid
779
756
 
757
+ ### 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`?
758
+
759
+ **Agent Wallet**: Use agent's private key in constructor instead of master account's private key.
760
+
761
+ **Vault and Sub-Account**: Pass vault or sub-account address via `vaultAddress` options to methods or set
762
+ `defaultVaultAddress` in constructor.
763
+
780
764
  ## Contributing
781
765
 
782
766
  We appreciate your help! To contribute, please read the [contributing instructions](CONTRIBUTING.md).