@nktkas/hyperliquid 0.23.0 → 0.24.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 (169) hide show
  1. package/CONTRIBUTING.md +3 -2
  2. package/README.md +184 -186
  3. package/esm/mod.d.ts +2 -2
  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 +430 -393
  8. package/esm/src/clients/exchange.d.ts.map +1 -1
  9. package/esm/src/clients/exchange.js +467 -927
  10. package/esm/src/clients/info.d.ts +330 -185
  11. package/esm/src/clients/info.d.ts.map +1 -1
  12. package/esm/src/clients/info.js +348 -334
  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 +95 -93
  17. package/esm/src/clients/subscription.d.ts.map +1 -1
  18. package/esm/src/clients/subscription.js +101 -146
  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 +12 -21
  32. package/esm/src/signing/_sorter.d.ts.map +1 -1
  33. package/esm/src/signing/_sorter.js +30 -63
  34. package/esm/src/signing/mod.d.ts +177 -127
  35. package/esm/src/signing/mod.d.ts.map +1 -1
  36. package/esm/src/signing/mod.js +182 -130
  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 +492 -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 +403 -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 +35 -8
  66. package/esm/src/types/info/markets.d.ts.map +1 -1
  67. package/esm/src/types/info/orders.d.ts +62 -17
  68. package/esm/src/types/info/orders.d.ts.map +1 -1
  69. package/esm/src/types/info/requests.d.ts +194 -76
  70. package/esm/src/types/info/requests.d.ts.map +1 -1
  71. package/{script/src/types/info/delegations.d.ts → esm/src/types/info/validators.d.ts} +45 -15
  72. package/esm/src/types/info/validators.d.ts.map +1 -0
  73. package/esm/src/types/info/vaults.d.ts +32 -10
  74. package/esm/src/types/info/vaults.d.ts.map +1 -1
  75. package/esm/src/types/mod.d.ts +2 -2
  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 -2
  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 +430 -393
  87. package/script/src/clients/exchange.d.ts.map +1 -1
  88. package/script/src/clients/exchange.js +466 -926
  89. package/script/src/clients/info.d.ts +330 -185
  90. package/script/src/clients/info.d.ts.map +1 -1
  91. package/script/src/clients/info.js +348 -334
  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 +95 -93
  96. package/script/src/clients/subscription.d.ts.map +1 -1
  97. package/script/src/clients/subscription.js +101 -146
  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 +12 -21
  111. package/script/src/signing/_sorter.d.ts.map +1 -1
  112. package/script/src/signing/_sorter.js +30 -63
  113. package/script/src/signing/mod.d.ts +177 -127
  114. package/script/src/signing/mod.d.ts.map +1 -1
  115. package/script/src/signing/mod.js +185 -148
  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 +492 -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 +403 -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 +35 -8
  145. package/script/src/types/info/markets.d.ts.map +1 -1
  146. package/script/src/types/info/orders.d.ts +62 -17
  147. package/script/src/types/info/orders.d.ts.map +1 -1
  148. package/script/src/types/info/requests.d.ts +194 -76
  149. package/script/src/types/info/requests.d.ts.map +1 -1
  150. package/{esm/src/types/info/delegations.d.ts → script/src/types/info/validators.d.ts} +45 -15
  151. package/script/src/types/info/validators.d.ts.map +1 -0
  152. package/script/src/types/info/vaults.d.ts +32 -10
  153. package/script/src/types/info/vaults.d.ts.map +1 -1
  154. package/script/src/types/mod.d.ts +2 -2
  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/esm/src/types/info/delegations.d.ts.map +0 -1
  164. package/script/src/signing/_signTypedData/window.d.ts +0 -29
  165. package/script/src/signing/_signTypedData/window.d.ts.map +0 -1
  166. package/script/src/signing/_signTypedData/window.js +0 -34
  167. package/script/src/types/info/delegations.d.ts.map +0 -1
  168. /package/esm/src/types/info/{delegations.js → validators.js} +0 -0
  169. /package/script/src/types/info/{delegations.js → validators.js} +0 -0
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,9 +53,10 @@ 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 v0.76.3 / Expo v52
56
+ // React Native 0.76.3 / Expo v52
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";
60
61
 
61
62
  if (!globalThis.EventTarget || !globalThis.Event) {
@@ -90,48 +91,40 @@ if (!Promise.withResolvers) {
90
91
  return { promise, resolve, reject };
91
92
  };
92
93
  }
93
-
94
- if (!ArrayBuffer.prototype.transfer) {
95
- ArrayBuffer.prototype.transfer = function (newByteLength) {
96
- const length = newByteLength ?? this.byteLength;
97
- const newBuffer = new ArrayBuffer(length);
98
- const oldView = new Uint8Array(this);
99
- const newView = new Uint8Array(newBuffer);
100
-
101
- newView.set(oldView.subarray(0, Math.min(oldView.length, length)));
102
-
103
- Object.defineProperty(this, "byteLength", { value: 0 });
104
-
105
- return newBuffer;
106
- };
107
- }
108
94
  ```
109
95
 
110
96
  </details>
111
97
 
112
98
  ## Quick Start
113
99
 
114
- #### Info endpoint
100
+ ### [Info endpoint](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint)
115
101
 
116
102
  ```ts
103
+ // 1. Import module
117
104
  import * as hl from "@nktkas/hyperliquid";
118
105
 
119
- const transport = new hl.HttpTransport();
120
- const infoClient = new hl.InfoClient({ transport });
106
+ // 1. Set up client with transport
107
+ const infoClient = new hl.InfoClient({
108
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
109
+ });
121
110
 
111
+ // 3. Query data
122
112
  const openOrders = await infoClient.openOrders({ user: "0x..." });
123
113
  ```
124
114
 
125
- #### Exchange endpoint
115
+ ### [Exchange endpoint](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint)
126
116
 
127
117
  ```ts
118
+ // 1. Import module
128
119
  import * as hl from "@nktkas/hyperliquid";
129
120
 
130
- const privateKey = "0x..."; // or `viem`, `ethers`
131
-
132
- const transport = new hl.HttpTransport();
133
- const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
121
+ // 2. Set up client with wallet and transport
122
+ const exchClient = new hl.ExchangeClient({
123
+ wallet: "0x...", // `viem`, `ethers`, or private key directly
124
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
125
+ });
134
126
 
127
+ // 3. Execute an action
135
128
  const result = await exchClient.order({
136
129
  orders: [{
137
130
  a: 0,
@@ -149,38 +142,41 @@ const result = await exchClient.order({
149
142
  });
150
143
  ```
151
144
 
152
- #### Subscription
145
+ ### [Subscription](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions)
153
146
 
154
147
  ```ts
148
+ // 1. Import module
155
149
  import * as hl from "@nktkas/hyperliquid";
156
150
 
157
- const transport = new hl.WebSocketTransport();
158
- const subsClient = new hl.SubscriptionClient({ transport });
151
+ // 2. Set up client with transport
152
+ const subsClient = new hl.SubscriptionClient({
153
+ transport: new hl.WebSocketTransport(),
154
+ });
159
155
 
156
+ // 3. Subscribe to events
160
157
  const sub = await subsClient.allMids((event) => {
161
158
  console.log(event);
162
159
  });
163
-
164
- await sub.unsubscribe(); // unsubscribe from the event
160
+ await sub.unsubscribe();
165
161
  ```
166
162
 
167
- #### Multi-Sign
163
+ ### [Multi-Sign](https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig)
168
164
 
169
165
  ```ts
166
+ // 1. Import module
170
167
  import * as hl from "@nktkas/hyperliquid";
171
168
 
172
- const multiSignAddress = "0x...";
173
- const signers = [
174
- "0x...", // Private key; or any other wallet libraries
175
- ] as const;
176
-
177
- const transport = new hl.HttpTransport();
178
- const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers }); // extends `ExchangeClient`
179
-
180
- const data = await multiSignClient.approveAgent({ // same API as `ExchangeClient`
181
- agentAddress: "0x...",
182
- agentName: "agentName",
169
+ // 2. Set up client with
170
+ const multiSignClient = new hl.MultiSignClient({
171
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
172
+ multiSignAddress: "0x...",
173
+ signers: [
174
+ "0x...", // `viem`, `ethers`, or private key directly
175
+ ],
183
176
  });
177
+
178
+ // 3. Execute an action
179
+ const data = await multiSignClient.approveAgent({ agentAddress: "0x..." });
184
180
  ```
185
181
 
186
182
  ## Usage
@@ -193,26 +189,27 @@ First, choose and configure your transport layer (more details in the [API Refer
193
189
  import * as hl from "@nktkas/hyperliquid";
194
190
 
195
191
  // 1. HTTP Transport: suitable for one-time requests or serverless environments
196
- const httpTransport = new hl.HttpTransport(); // Accepts optional parameters (e.g. isTestnet, timeout, etc.)
192
+ const httpTransport = new hl.HttpTransport({...}); // Accepts optional parameters (e.g. isTestnet, timeout, etc.)
197
193
 
198
194
  // 2. WebSocket Transport: has better network latency than HTTP transport
199
- const wsTransport = new hl.WebSocketTransport(); // Accepts optional parameters (e.g. url, timeout, reconnect, etc.)
195
+ const wsTransport = new hl.WebSocketTransport({...}); // Accepts optional parameters (e.g. url, timeout, reconnect, etc.)
200
196
  ```
201
197
 
202
198
  ### 2) Initialize Client
203
199
 
204
200
  Next, initialize a client with the transport layer (more details in the [API Reference](#clients)):
205
201
 
206
- #### Create InfoClient
202
+ #### Create [InfoClient](#infoclient)
207
203
 
208
204
  ```ts
209
205
  import * as hl from "@nktkas/hyperliquid";
210
206
 
211
- const transport = new hl.HttpTransport(); // or `WebSocketTransport`
212
- const infoClient = new hl.InfoClient({ transport });
207
+ const infoClient = new hl.InfoClient({
208
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
209
+ });
213
210
  ```
214
211
 
215
- #### Create ExchangeClient
212
+ #### Create [ExchangeClient](#exchangeclient)
216
213
 
217
214
  ```ts
218
215
  import * as hl from "@nktkas/hyperliquid";
@@ -230,7 +227,7 @@ const exchClient_privateKey = new hl.ExchangeClient({ wallet: privateKey, transp
230
227
  const viemAccount = privateKeyToAccount("0x...");
231
228
  const exchClient_viem = new hl.ExchangeClient({ wallet: viemAccount, transport });
232
229
 
233
- // 3. Using Ethers (or Ethers V5)
230
+ // 3. Using Ethers (V5 or V6)
234
231
  const ethersWallet = new ethers.Wallet("0x...");
235
232
  const exchClient_ethers = new hl.ExchangeClient({ wallet: ethersWallet, transport });
236
233
 
@@ -238,70 +235,69 @@ const exchClient_ethers = new hl.ExchangeClient({ wallet: ethersWallet, transpor
238
235
  const [account] = await window.ethereum.request({ method: "eth_requestAccounts" });
239
236
  const externalWallet = createWalletClient({ account, transport: custom(window.ethereum) });
240
237
  const exchClient_viemMetamask = new hl.ExchangeClient({ wallet: externalWallet, transport });
241
-
242
- // 5. Using external wallet (e.g. MetaMask) via `window.ethereum`
243
- const exchClient_windowMetamask = new hl.ExchangeClient({ wallet: window.ethereum, transport });
244
238
  ```
245
239
 
246
- #### Create SubscriptionClient
240
+ #### Create [SubscriptionClient](#subscriptionclient)
247
241
 
248
242
  ```ts
249
243
  import * as hl from "@nktkas/hyperliquid";
250
244
 
251
- const transport = new hl.WebSocketTransport(); // only `WebSocketTransport`
252
- const subsClient = new hl.SubscriptionClient({ transport });
245
+ const subsClient = new hl.SubscriptionClient({
246
+ transport: new hl.WebSocketTransport(),
247
+ });
253
248
  ```
254
249
 
255
- #### Create MultiSignClient
250
+ #### Create [MultiSignClient](#multisignclient)
256
251
 
257
252
  ```ts
258
253
  import * as hl from "@nktkas/hyperliquid";
259
254
  import { privateKeyToAccount } from "viem/accounts";
260
255
  import { ethers } from "ethers";
261
256
 
262
- const multiSignAddress = "0x...";
263
- const signers = [
264
- privateKeyToAccount("0x..."), // first is leader for multi-sign transaction, must contain own address
265
- new ethers.Wallet("0x..."),
266
- { // can be a custom async wallet
267
- async signTypedData(params: {
268
- domain: {
269
- name: string;
270
- version: string;
271
- chainId: number;
272
- verifyingContract: Hex;
273
- };
274
- types: {
275
- [key: string]: {
257
+ const multiSignClient = new hl.MultiSignClient({
258
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
259
+ multiSignAddress: "0x...",
260
+ signers: [
261
+ privateKeyToAccount("0x..."), // first is leader for multi-sign transaction (signs transaction 2 times)
262
+ new ethers.Wallet("0x..."),
263
+ { // can be a custom async wallet
264
+ async signTypedData(params: {
265
+ domain: {
276
266
  name: string;
277
- type: string;
278
- }[];
279
- };
280
- primaryType: string;
281
- message: Record<string, unknown>;
282
- }): Promise<Hex> {
283
- // Custom signer logic
284
- return "0x..."; // return hex signature
267
+ version: string;
268
+ chainId: number;
269
+ verifyingContract: `0x${string}`;
270
+ };
271
+ types: {
272
+ [key: string]: {
273
+ name: string;
274
+ type: string;
275
+ }[];
276
+ };
277
+ primaryType: string;
278
+ message: Record<string, unknown>;
279
+ }): Promise<`0x${string}`> {
280
+ // Custom signer logic
281
+ return "0x..."; // return hex signature
282
+ },
285
283
  },
286
- },
287
- "0x...", // private key directly
288
- ];
289
-
290
- const transport = new hl.HttpTransport();
291
- const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers }); // extends `ExchangeClient`
284
+ "0x...", // private key directly
285
+ ],
286
+ });
292
287
  ```
293
288
 
294
289
  ### 3) Use Client
295
290
 
296
291
  Finally, use client methods to interact with the Hyperliquid API (more details in the [API Reference](#clients)):
297
292
 
298
- #### Example of using an InfoClient
293
+ #### Example of using an [InfoClient](#infoclient)
299
294
 
300
295
  ```ts
301
296
  import * as hl from "@nktkas/hyperliquid";
302
297
 
303
- const transport = new hl.HttpTransport();
304
- const infoClient = new hl.InfoClient({ transport });
298
+ const infoClient = new hl.InfoClient({
299
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
300
+ });
305
301
 
306
302
  // L2 Book
307
303
  const l2Book = await infoClient.l2Book({ coin: "BTC" });
@@ -313,15 +309,15 @@ const clearinghouseState = await infoClient.clearinghouseState({ user: "0x..." }
313
309
  const openOrders = await infoClient.openOrders({ user: "0x..." });
314
310
  ```
315
311
 
316
- #### Example of using an ExchangeClient
312
+ #### Example of using an [ExchangeClient](#exchangeclient)
317
313
 
318
314
  ```ts
319
315
  import * as hl from "@nktkas/hyperliquid";
320
316
 
321
- const privateKey = "0x..."; // or `viem`, `ethers`
322
-
323
- const transport = new hl.HttpTransport();
324
- const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
317
+ const exchClient = new hl.ExchangeClient({
318
+ wallet: "0x...", // `viem`, `ethers`, or private key directly
319
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
320
+ });
325
321
 
326
322
  // Place an orders
327
323
  const result = await exchClient.order({
@@ -341,25 +337,20 @@ const result = await exchClient.order({
341
337
  });
342
338
 
343
339
  // Approve an agent
344
- const result = await exchClient.approveAgent({
345
- agentAddress: "0x...",
346
- agentName: "agentName",
347
- });
340
+ const result = await exchClient.approveAgent({ agentAddress: "0x..." });
348
341
 
349
342
  // Withdraw funds
350
- const result = await exchClient.withdraw3({
351
- destination: account.address,
352
- amount: "100",
353
- });
343
+ const result = await exchClient.withdraw3({ destination: "0x...", amount: "100" });
354
344
  ```
355
345
 
356
- #### Example of using a SubscriptionClient
346
+ #### Example of using a [SubscriptionClient](#subscriptionclient)
357
347
 
358
348
  ```ts
359
349
  import * as hl from "@nktkas/hyperliquid";
360
350
 
361
- const transport = new hl.WebSocketTransport();
362
- const subsClient = new hl.SubscriptionClient({ transport });
351
+ const subsClient = new hl.SubscriptionClient({
352
+ transport: new hl.WebSocketTransport(),
353
+ });
363
354
 
364
355
  // L2 Book updates
365
356
  await subsClient.l2Book({ coin: "BTC" }, (data) => {
@@ -372,54 +363,25 @@ await subsClient.userFills({ user: "0x..." }, (data) => {
372
363
  });
373
364
 
374
365
  // Candle updates
375
- const sub = await subsClient.candle({ coin: "BTC", interval: "1h" }, (data) => {
366
+ await subsClient.candle({ coin: "BTC", interval: "1h" }, (data) => {
376
367
  console.log(data);
377
368
  });
378
369
  ```
379
370
 
380
- #### Example of using a MultiSignClient
371
+ #### Example of using a [MultiSignClient](#multisignclient)
381
372
 
382
373
  ```ts
383
374
  import * as hl from "@nktkas/hyperliquid";
384
375
 
385
- const multiSignAddress = "0x...";
386
- const signers = [
387
- "0x...", // Private keys
388
- ] as const;
389
-
390
- const transport = new hl.HttpTransport();
391
- const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
392
-
393
- // Interaction is the same as with `ExchangeClient`
394
-
395
- // Place an orders
396
- const result = await multiSignClient.order({
397
- orders: [{
398
- a: 0,
399
- b: true,
400
- p: "30000",
401
- s: "0.1",
402
- r: false,
403
- t: {
404
- limit: {
405
- tif: "Gtc",
406
- },
407
- },
408
- }],
409
- grouping: "na",
410
- });
411
-
412
- // Approve an agent
413
- const result = await multiSignClient.approveAgent({
414
- agentAddress: "0x...",
415
- agentName: "agentName",
376
+ const multiSignClient = new hl.MultiSignClient({
377
+ transport: new hl.HttpTransport(), // or `WebSocketTransport`
378
+ multiSignAddress: "0x...",
379
+ signers: [
380
+ "0x...", // `viem`, `ethers`, or private key directly
381
+ ],
416
382
  });
417
383
 
418
- // Withdraw funds
419
- const result = await multiSignClient.withdraw3({
420
- destination: account.address,
421
- amount: "100",
422
- });
384
+ // Interaction is the same as with `ExchangeClient`
423
385
  ```
424
386
 
425
387
  ## API Reference
@@ -428,9 +390,6 @@ const result = await multiSignClient.withdraw3({
428
390
 
429
391
  A client is an interface through which you can interact with the Hyperliquid API.
430
392
 
431
- The client is responsible for formatting an action, creating a signature correctly, sending a request, and validating a
432
- response.
433
-
434
393
  #### InfoClient
435
394
 
436
395
  ```ts
@@ -444,6 +403,9 @@ class InfoClient {
444
403
  candleSnapshot(args: CandleSnapshotParameters): Promise<Candle[]>;
445
404
  fundingHistory(args: FundingHistoryParameters): Promise<FundingHistory[]>;
446
405
  l2Book(args: L2BookParameters): Promise<Book>;
406
+ liquidatable(): Promise<unknown[]>;
407
+ marginTable(args: MarginTableParameters): Promise<MarginTable>;
408
+ maxMarketOrderNtls(): Promise<[number, string][]>;
447
409
  meta(): Promise<PerpsMeta>;
448
410
  metaAndAssetCtxs(): Promise<PerpsMetaAndAssetCtxs>;
449
411
  perpDeployAuctionStatus(): Promise<DeployAuctionStatus>;
@@ -484,18 +446,23 @@ class InfoClient {
484
446
  userTwapSliceFills(args: UserTwapSliceFillsParameters): Promise<TwapSliceFill[]>;
485
447
  userTwapSliceFillsByTime(args: UserTwapSliceFillsByTimeParameters): Promise<TwapSliceFill[]>;
486
448
 
487
- // Staking
449
+ // Validator
488
450
  delegations(args: DelegationsParameters): Promise<Delegation[]>;
489
451
  delegatorHistory(args: DelegatorHistoryParameters): Promise<DelegatorUpdate[]>;
490
452
  delegatorRewards(args: DelegatorRewardsParameters): Promise<DelegatorReward[]>;
491
453
  delegatorSummary(args: DelegatorSummaryParameters): Promise<DelegatorSummary>;
454
+ validatorL1Votes(): Promise<unknown[]>;
492
455
  validatorSummaries(): Promise<ValidatorSummary[]>;
493
456
 
494
457
  // Vault
458
+ leadingVaults(args: LeadingVaultsParameters): Promise<VaultLeading[]>;
495
459
  userVaultEquities(args: UserVaultEquitiesParameters): Promise<VaultEquity[]>;
496
460
  vaultDetails(args: VaultDetailsParameters): Promise<VaultDetails | null>;
497
461
  vaultSummaries(): Promise<VaultSummary[]>;
498
462
 
463
+ // Server
464
+ exchangeStatus(): Promise<ExchangeStatus>;
465
+
499
466
  // Explorer (RPC endpoint)
500
467
  blockDetails(args: BlockDetailsParameters): Promise<BlockDetails>;
501
468
  txDetails(args: TxDetailsParameters): Promise<TxDetails>;
@@ -509,16 +476,11 @@ class InfoClient {
509
476
  class ExchangeClient {
510
477
  constructor(args: {
511
478
  transport: HttpTransport | WebSocketTransport;
512
- wallet:
513
- | Hex // Private key directly
514
- | AbstractViemWalletClient // viem
515
- | AbstractEthersSigner // ethers
516
- | AbstractEthersV5Signer // ethers v5
517
- | AbstractWindowEthereum; // window.ethereum (EIP-1193)
479
+ wallet: AbstractWallet; // `viem`, `ethers` (v5 or v6), or private key directly
518
480
  isTestnet?: boolean; // Whether to use testnet (default: false)
519
- defaultVaultAddress?: Hex; // Vault address used by default if not provided in method call
520
- signatureChainId?: Hex | (() => MaybePromise<Hex>); // Chain ID used for signing (default: trying to guess based on wallet and isTestnet)
521
- nonceManager?: () => MaybePromise<number>; // Function to get the next nonce (default: auto-incrementing Date.now())
481
+ defaultVaultAddress?: `0x${string}`; // Vault address used by default if not provided in method call
482
+ signatureChainId?: `0x${string}` | (() => MaybePromise<`0x${string}`>); // Chain ID used for signing (default: get chain id from wallet otherwise `0x1`)
483
+ nonceManager?: () => MaybePromise<number>; // Function to get the next nonce (default: monotonically incrementing `Date.now()`)
522
484
  });
523
485
 
524
486
  // Order
@@ -537,18 +499,16 @@ class ExchangeClient {
537
499
  approveAgent(args: ApproveAgentParameters): Promise<SuccessResponse>;
538
500
  approveBuilderFee(args: ApproveBuilderFeeParameters): Promise<SuccessResponse>;
539
501
  claimRewards(): Promise<SuccessResponse>;
540
- convertToMultiSigUser(args: ConvertToMultiSigUserParameters): Promise<SuccessResponse>;
541
502
  createSubAccount(args: CreateSubAccountParameters): Promise<CreateSubAccountResponse>;
542
503
  evmUserModify(args: EvmUserModifyParameters): Promise<SuccessResponse>;
543
504
  registerReferrer(args: RegisterReferrerParameters): Promise<SuccessResponse>;
544
505
  reserveRequestWeight(args: ReserveRequestWeightParameters): Promise<SuccessResponse>;
545
506
  setDisplayName(args: SetDisplayNameParameters): Promise<SuccessResponse>;
546
507
  setReferrer(args: SetReferrerParameters): Promise<SuccessResponse>;
508
+ subAccountModify(args: SubAccountModifyParameters): Promise<SuccessResponse>;
547
509
  spotUser(args: SpotUserParameters): Promise<SuccessResponse>;
548
510
 
549
511
  // Transfer
550
- perpDexClassTransfer(args: PerpDexClassTransferParameters): Promise<SuccessResponse>;
551
- perpDexTransfer(args: PerpDexTransferParameters): Promise<SuccessResponse>;
552
512
  spotSend(args: SpotSendParameters): Promise<SuccessResponse>;
553
513
  subAccountSpotTransfer(args: SubAccountSpotTransferParameters): Promise<SuccessResponse>;
554
514
  subAccountTransfer(args: SubAccountTransferParameters): Promise<SuccessResponse>;
@@ -572,6 +532,7 @@ class ExchangeClient {
572
532
  vaultTransfer(args: VaultTransferParameters): Promise<SuccessResponse>;
573
533
 
574
534
  // Multi-Sign
535
+ convertToMultiSigUser(args: ConvertToMultiSigUserParameters): Promise<SuccessResponse>;
575
536
  multiSig(args: MultiSigParameters): Promise<BaseExchangeResponse>;
576
537
 
577
538
  // Validator
@@ -591,7 +552,7 @@ class SubscriptionClient {
591
552
 
592
553
  // Market
593
554
  activeAssetCtx(args: EventActiveAssetCtxParameters, listener: (data: WsActiveAssetCtx | WsActiveSpotAssetCtx) => void): Promise<Subscription>;
594
- activeAssetData(args: EventActiveAssetDataParameters, listener: (data: WsActiveAssetData) => void): Promise<Subscription>;
555
+ activeAssetData(args: EventActiveAssetDataParameters, listener: (data: ActiveAssetData) => void): Promise<Subscription>;
595
556
  allMids(listener: (data: WsAllMids) => void): Promise<Subscription>;
596
557
  bbo(args: EventBboParameters, listener: (data: WsBbo) => void): Promise<Subscription>;
597
558
  candle(args: EventCandleParameters, listener: (data: Candle) => void): Promise<Subscription>;
@@ -611,7 +572,7 @@ class SubscriptionClient {
611
572
  userTwapHistory(args: EventUserTwapHistory, listener: (data: WsUserTwapHistory) => void): Promise<Subscription>;
612
573
  userTwapSliceFills(args: EventUserTwapSliceFills, listener: (data: WsUserTwapSliceFills) => void): Promise<Subscription>;
613
574
 
614
- // Explorer
575
+ // Explorer (RPC endpoint)
615
576
  explorerBlock(listener: (data: WsBlockDetails[]) => void): Promise<Subscription>;
616
577
  explorerTxs(listener: (data: TxDetails[]) => void): Promise<Subscription>;
617
578
  }
@@ -624,13 +585,10 @@ class SubscriptionClient {
624
585
  class MultiSignClient extends ExchangeClient {
625
586
  constructor(
626
587
  args:
627
- & Omit<ExchangeClientParameters, "wallet"> // Instead of `wallet`, you should specify the following parameters:
588
+ & Omit<ExchangeClientParameters, "wallet"> // instead of `wallet`, you should specify the following parameters:
628
589
  & {
629
- multiSignAddress: Hex; // Multi-signature address
630
- signers: [ // Array of signers
631
- AbstractWalletWithAddress, // First signer is the leader of a multi-sign transaction
632
- ...AbstractWallet[], // Any number of additional signers
633
- ];
590
+ multiSignAddress: `0x${string}`;
591
+ signers: [AbstractWallet, ...AbstractWallet[]];
634
592
  },
635
593
  );
636
594
 
@@ -644,7 +602,11 @@ Transport acts as a layer between class requests and Hyperliquid servers.
644
602
 
645
603
  #### HTTP Transport
646
604
 
647
- HTTP transport is suitable for one-off requests or serverless environments.
605
+ **Features:**
606
+
607
+ - Uses [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for requests. Can be configured using
608
+ [`fetchOptions`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit).
609
+ - Automatically determines the target URL based on the request + `isTestnet` flag.
648
610
 
649
611
  ```ts
650
612
  class HttpTransport {
@@ -664,7 +626,20 @@ class HttpTransport {
664
626
 
665
627
  #### WebSocket Transport
666
628
 
667
- WebSocket transport has better network latency than HTTP transport.
629
+ **Features:**
630
+
631
+ - Uses [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) for requests.
632
+ - Supports [subscriptions](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions)
633
+ and [post requests](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/post-requests).
634
+ - Automatically restores connection after loss and resubscribes to previous subscriptions.
635
+ - Smart keep alive (pings only when idle).
636
+ - Lazy initialization with message buffering during connection establishment.
637
+
638
+ **Limitations:**
639
+
640
+ - Cannot mix api/explorer endpoints or mainnet/testnet in single connection. Need to create separate instances for
641
+ different endpoints.
642
+ - Cannot send explorer post-requests via WebSocket. Use [HTTP transport](#http-transport).
668
643
 
669
644
  ```ts
670
645
  class WebSocketTransport {
@@ -707,27 +682,23 @@ The import point gives access to functions that generate signatures for Hyperliq
707
682
  ```ts
708
683
  import { actionSorter, signL1Action } from "@nktkas/hyperliquid/signing";
709
684
 
710
- const privateKey = "0x..."; // or `viem`, `ethers`
685
+ const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
711
686
 
712
- const nonce = Date.now();
713
- const action = {
687
+ const action = actionSorter.cancel({
714
688
  type: "cancel",
715
689
  cancels: [
716
690
  { a: 0, o: 12345 },
717
691
  ],
718
- } as const;
719
-
720
- const signature = await signL1Action({
721
- wallet: privateKey,
722
- action: actionSorter[action.type](action),
723
- nonce,
724
692
  });
693
+ const nonce = Date.now();
694
+
695
+ const signature = await signL1Action({ wallet: privateKey, action, nonce });
725
696
 
726
697
  // Send the signed action to the Hyperliquid API
727
698
  const response = await fetch("https://api.hyperliquid.xyz/exchange", {
728
699
  method: "POST",
729
700
  headers: { "Content-Type": "application/json" },
730
- body: JSON.stringify({ action, signature, nonce }),
701
+ body: JSON.stringify({ action, signature, nonce }), // recommended to send the same formatted action
731
702
  });
732
703
  const body = await response.json();
733
704
  ```
@@ -735,18 +706,18 @@ const body = await response.json();
735
706
  #### Approve agent yourself
736
707
 
737
708
  ```ts
738
- import { signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
709
+ import { actionSorter, signUserSignedAction, userSignedActionEip712Types } from "@nktkas/hyperliquid/signing";
739
710
 
740
- const privateKey = "0x..."; // or `viem`, `ethers`
711
+ const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
741
712
 
742
- const action = {
713
+ const action = actionSorter.approveAgent({
743
714
  type: "approveAgent",
744
715
  signatureChainId: "0x66eee",
745
716
  hyperliquidChain: "Mainnet",
746
717
  agentAddress: "0x...",
747
718
  agentName: "Agent",
748
719
  nonce: Date.now(),
749
- } as const;
720
+ });
750
721
 
751
722
  const signature = await signUserSignedAction({
752
723
  wallet: privateKey,
@@ -758,11 +729,38 @@ const signature = await signUserSignedAction({
758
729
  const response = await fetch("https://api.hyperliquid.xyz/exchange", {
759
730
  method: "POST",
760
731
  headers: { "Content-Type": "application/json" },
761
- body: JSON.stringify({ action, signature, nonce: action.nonce }),
732
+ body: JSON.stringify({ action, signature, nonce: action.nonce }), // recommended to send the same formatted action
762
733
  });
763
734
  const body = await response.json();
764
735
  ```
765
736
 
737
+ ## FAQ
738
+
739
+ ### How to execute an L1 action via an external wallet (e.g. MetaMask)?
740
+
741
+ Hyperliquid requires chain `1337` for L1 actions (open order, change leverage, etc.). There are two ways to execute an
742
+ L1 action through an external wallet:
743
+
744
+ - (recommended) Create an
745
+ [Agent Wallet](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/nonces-and-api-wallets#api-wallets)
746
+ and execute all L1 actions through it
747
+ - Change the user's chain to `1337`, however, the user will sign unreadable data
748
+
749
+ ### How to create a market order?
750
+
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:
753
+
754
+ - For buys: set limit price >= current best ask
755
+ - For sells: set limit price <= current best bid
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
+
766
764
  ## Contributing
767
765
 
768
766
  We appreciate your help! To contribute, please read the [contributing instructions](CONTRIBUTING.md).