@nktkas/hyperliquid 0.13.2 → 0.15.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 (164) hide show
  1. package/CONTRIBUTING.md +4 -7
  2. package/README.md +297 -103
  3. package/esm/mod.d.ts +3 -12
  4. package/esm/mod.d.ts.map +1 -1
  5. package/esm/mod.js +2 -2
  6. package/esm/src/{transports/base.d.ts → base.d.ts} +11 -14
  7. package/esm/src/base.d.ts.map +1 -0
  8. package/esm/src/base.js +14 -0
  9. package/esm/src/clients/event.d.ts +4 -4
  10. package/esm/src/clients/event.d.ts.map +1 -1
  11. package/esm/src/clients/event.js +2 -2
  12. package/esm/src/clients/public.d.ts +109 -6
  13. package/esm/src/clients/public.d.ts.map +1 -1
  14. package/esm/src/clients/public.js +106 -3
  15. package/esm/src/clients/wallet.d.ts +232 -29
  16. package/esm/src/clients/wallet.d.ts.map +1 -1
  17. package/esm/src/clients/wallet.js +859 -243
  18. package/esm/src/signing.d.ts +135 -0
  19. package/esm/src/signing.d.ts.map +1 -0
  20. package/esm/src/signing.js +188 -0
  21. package/esm/src/transports/http/http_transport.d.ts +2 -4
  22. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  23. package/esm/src/transports/http/http_transport.js +8 -13
  24. package/{script/src/transports/websocket/hyperliquid_event_target.d.ts → esm/src/transports/websocket/_hyperliquid_event_target.d.ts} +7 -15
  25. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -0
  26. package/esm/src/transports/websocket/{hyperliquid_event_target.js → _hyperliquid_event_target.js} +4 -22
  27. package/esm/src/transports/websocket/{reconnecting_websocket.d.ts → _reconnecting_websocket.d.ts} +26 -26
  28. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -0
  29. package/esm/src/transports/websocket/{reconnecting_websocket.js → _reconnecting_websocket.js} +91 -76
  30. package/esm/src/transports/websocket/{websocket_request_dispatcher.d.ts → _websocket_request_dispatcher.d.ts} +3 -7
  31. package/esm/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +1 -0
  32. package/esm/src/transports/websocket/{websocket_request_dispatcher.js → _websocket_request_dispatcher.js} +3 -7
  33. package/esm/src/transports/websocket/websocket_transport.d.ts +13 -16
  34. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  35. package/esm/src/transports/websocket/websocket_transport.js +49 -49
  36. package/esm/src/types/exchange/requests.d.ts +172 -20
  37. package/esm/src/types/exchange/requests.d.ts.map +1 -1
  38. package/esm/src/types/exchange/responses.d.ts +32 -32
  39. package/esm/src/types/exchange/responses.d.ts.map +1 -1
  40. package/esm/src/types/explorer/requests.d.ts +12 -12
  41. package/esm/src/types/explorer/requests.d.ts.map +1 -1
  42. package/esm/src/types/explorer/responses.d.ts +36 -1
  43. package/esm/src/types/explorer/responses.d.ts.map +1 -1
  44. package/esm/src/types/info/accounts.d.ts +130 -105
  45. package/esm/src/types/info/accounts.d.ts.map +1 -1
  46. package/esm/src/types/info/assets.d.ts +154 -152
  47. package/esm/src/types/info/assets.d.ts.map +1 -1
  48. package/esm/src/types/info/delegations.d.ts +20 -20
  49. package/esm/src/types/info/delegations.d.ts.map +1 -1
  50. package/esm/src/types/info/orders.d.ts +55 -55
  51. package/esm/src/types/info/orders.d.ts.map +1 -1
  52. package/esm/src/types/info/requests.d.ts +73 -10
  53. package/esm/src/types/info/requests.d.ts.map +1 -1
  54. package/esm/src/types/info/vaults.d.ts +1 -1
  55. package/esm/src/types/info/vaults.d.ts.map +1 -1
  56. package/esm/src/types/mod.d.ts +14 -0
  57. package/esm/src/types/mod.d.ts.map +1 -0
  58. package/esm/src/types/subscriptions/requests.d.ts +1 -1
  59. package/esm/src/types/subscriptions/requests.d.ts.map +1 -1
  60. package/{script/src/types/subscriptions/common.d.ts → esm/src/types/subscriptions/responses.d.ts} +16 -4
  61. package/esm/src/types/subscriptions/responses.d.ts.map +1 -0
  62. package/package.json +20 -4
  63. package/script/mod.d.ts +3 -12
  64. package/script/mod.d.ts.map +1 -1
  65. package/script/mod.js +3 -5
  66. package/script/src/{transports/base.d.ts → base.d.ts} +11 -14
  67. package/script/src/base.d.ts.map +1 -0
  68. package/script/src/{transports/base.js → base.js} +13 -12
  69. package/script/src/clients/event.d.ts +4 -4
  70. package/script/src/clients/event.d.ts.map +1 -1
  71. package/script/src/clients/event.js +2 -2
  72. package/script/src/clients/public.d.ts +109 -6
  73. package/script/src/clients/public.d.ts.map +1 -1
  74. package/script/src/clients/public.js +106 -3
  75. package/script/src/clients/wallet.d.ts +232 -29
  76. package/script/src/clients/wallet.d.ts.map +1 -1
  77. package/script/src/clients/wallet.js +860 -244
  78. package/script/src/signing.d.ts +135 -0
  79. package/script/src/signing.d.ts.map +1 -0
  80. package/script/src/signing.js +203 -0
  81. package/script/src/transports/http/http_transport.d.ts +2 -4
  82. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  83. package/script/src/transports/http/http_transport.js +9 -14
  84. package/{esm/src/transports/websocket/hyperliquid_event_target.d.ts → script/src/transports/websocket/_hyperliquid_event_target.d.ts} +7 -15
  85. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -0
  86. package/script/src/transports/websocket/{hyperliquid_event_target.js → _hyperliquid_event_target.js} +4 -22
  87. package/script/src/transports/websocket/{reconnecting_websocket.d.ts → _reconnecting_websocket.d.ts} +26 -26
  88. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -0
  89. package/script/src/transports/websocket/{reconnecting_websocket.js → _reconnecting_websocket.js} +94 -78
  90. package/script/src/transports/websocket/{websocket_request_dispatcher.d.ts → _websocket_request_dispatcher.d.ts} +3 -7
  91. package/script/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +1 -0
  92. package/script/src/transports/websocket/{websocket_request_dispatcher.js → _websocket_request_dispatcher.js} +4 -8
  93. package/script/src/transports/websocket/websocket_transport.d.ts +13 -16
  94. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  95. package/script/src/transports/websocket/websocket_transport.js +55 -55
  96. package/script/src/types/exchange/requests.d.ts +172 -20
  97. package/script/src/types/exchange/requests.d.ts.map +1 -1
  98. package/script/src/types/exchange/responses.d.ts +32 -32
  99. package/script/src/types/exchange/responses.d.ts.map +1 -1
  100. package/script/src/types/explorer/requests.d.ts +12 -12
  101. package/script/src/types/explorer/requests.d.ts.map +1 -1
  102. package/script/src/types/explorer/responses.d.ts +36 -1
  103. package/script/src/types/explorer/responses.d.ts.map +1 -1
  104. package/script/src/types/info/accounts.d.ts +130 -105
  105. package/script/src/types/info/accounts.d.ts.map +1 -1
  106. package/script/src/types/info/assets.d.ts +154 -152
  107. package/script/src/types/info/assets.d.ts.map +1 -1
  108. package/script/src/types/info/delegations.d.ts +20 -20
  109. package/script/src/types/info/delegations.d.ts.map +1 -1
  110. package/script/src/types/info/orders.d.ts +55 -55
  111. package/script/src/types/info/orders.d.ts.map +1 -1
  112. package/script/src/types/info/requests.d.ts +73 -10
  113. package/script/src/types/info/requests.d.ts.map +1 -1
  114. package/script/src/types/info/vaults.d.ts +1 -1
  115. package/script/src/types/info/vaults.d.ts.map +1 -1
  116. package/script/src/types/mod.d.ts +14 -0
  117. package/script/src/types/mod.d.ts.map +1 -0
  118. package/script/src/types/subscriptions/requests.d.ts +1 -1
  119. package/script/src/types/subscriptions/requests.d.ts.map +1 -1
  120. package/{esm/src/types/subscriptions/common.d.ts → script/src/types/subscriptions/responses.d.ts} +16 -4
  121. package/script/src/types/subscriptions/responses.d.ts.map +1 -0
  122. package/esm/src/transports/base.d.ts.map +0 -1
  123. package/esm/src/transports/base.js +0 -14
  124. package/esm/src/transports/websocket/hyperliquid_event_target.d.ts.map +0 -1
  125. package/esm/src/transports/websocket/reconnecting_websocket.d.ts.map +0 -1
  126. package/esm/src/transports/websocket/websocket_request_dispatcher.d.ts.map +0 -1
  127. package/esm/src/types/common.d.ts +0 -3
  128. package/esm/src/types/common.d.ts.map +0 -1
  129. package/esm/src/types/exchange/common.d.ts +0 -36
  130. package/esm/src/types/exchange/common.d.ts.map +0 -1
  131. package/esm/src/types/explorer/common.d.ts +0 -37
  132. package/esm/src/types/explorer/common.d.ts.map +0 -1
  133. package/esm/src/types/explorer/common.js +0 -1
  134. package/esm/src/types/subscriptions/common.d.ts.map +0 -1
  135. package/esm/src/types/subscriptions/common.js +0 -1
  136. package/esm/src/utils/key_sort.d.ts +0 -21
  137. package/esm/src/utils/key_sort.d.ts.map +0 -1
  138. package/esm/src/utils/key_sort.js +0 -124
  139. package/esm/src/utils/signing.d.ts +0 -109
  140. package/esm/src/utils/signing.d.ts.map +0 -1
  141. package/esm/src/utils/signing.js +0 -164
  142. package/script/src/transports/base.d.ts.map +0 -1
  143. package/script/src/transports/websocket/hyperliquid_event_target.d.ts.map +0 -1
  144. package/script/src/transports/websocket/reconnecting_websocket.d.ts.map +0 -1
  145. package/script/src/transports/websocket/websocket_request_dispatcher.d.ts.map +0 -1
  146. package/script/src/types/common.d.ts +0 -3
  147. package/script/src/types/common.d.ts.map +0 -1
  148. package/script/src/types/exchange/common.d.ts +0 -36
  149. package/script/src/types/exchange/common.d.ts.map +0 -1
  150. package/script/src/types/explorer/common.d.ts +0 -37
  151. package/script/src/types/explorer/common.d.ts.map +0 -1
  152. package/script/src/types/explorer/common.js +0 -12
  153. package/script/src/types/subscriptions/common.d.ts.map +0 -1
  154. package/script/src/types/subscriptions/common.js +0 -12
  155. package/script/src/utils/key_sort.d.ts +0 -21
  156. package/script/src/utils/key_sort.d.ts.map +0 -1
  157. package/script/src/utils/key_sort.js +0 -137
  158. package/script/src/utils/signing.d.ts +0 -109
  159. package/script/src/utils/signing.d.ts.map +0 -1
  160. package/script/src/utils/signing.js +0 -182
  161. /package/esm/src/types/{common.js → mod.js} +0 -0
  162. /package/esm/src/types/{exchange/common.js → subscriptions/responses.js} +0 -0
  163. /package/script/src/types/{common.js → mod.js} +0 -0
  164. /package/script/src/types/{exchange/common.js → subscriptions/responses.js} +0 -0
@@ -1,17 +1,18 @@
1
- import { sorters } from "../utils/key_sort.js";
2
- import { signL1Action, signUserSignedAction, } from "../utils/signing.js";
1
+ import { HyperliquidError } from "../base.js";
2
+ import { signL1Action, signUserSignedAction, } from "../signing.js";
3
3
  // ——————————————— Errors ———————————————
4
4
  /** Error thrown when the API returns an error response. */
5
- export class ApiRequestError extends Error {
5
+ export class ApiRequestError extends HyperliquidError {
6
6
  constructor(response) {
7
7
  let message = "Cannot process API request";
8
8
  if (response.status === "err") {
9
+ // For ErrorResponse
9
10
  message += `: ${response.response}`;
10
11
  }
11
12
  else {
12
13
  if ("statuses" in response.response.data) {
13
- const errors = response.response.data.statuses
14
- .reduce((acc, status, index) => {
14
+ // For OrderResponse, CancelResponse
15
+ const errors = response.response.data.statuses.reduce((acc, status, index) => {
15
16
  if (typeof status === "object" && "error" in status) {
16
17
  acc.push(`Order ${index} failed: ${status.error}`);
17
18
  }
@@ -22,6 +23,7 @@ export class ApiRequestError extends Error {
22
23
  }
23
24
  }
24
25
  else {
26
+ // For TwapOrderResponse, TwapCancelResponse
25
27
  if (typeof response.response.data.status === "object" && "error" in response.response.data.status) {
26
28
  message += `: ${response.response.data.status.error}`;
27
29
  }
@@ -40,8 +42,8 @@ export class ApiRequestError extends Error {
40
42
  // ——————————————— Client ———————————————
41
43
  /**
42
44
  * Wallet client for interacting with the Hyperliquid API.
43
- * @typeParam T - The transport used to connect to the Hyperliquid API.
44
- * @typeParam W - The WalletClient/Account ([viem](https://viem.sh/docs/clients/wallet)) or Signer ([ethers.js](https://docs.ethers.io/v6/api/providers/#Signer)) used for signing transactions.
45
+ * @typeParam T The transport used to connect to the Hyperliquid API.
46
+ * @typeParam W The WalletClient/Account ([viem](https://viem.sh/docs/clients/wallet)) or Signer ([ethers.js](https://docs.ethers.io/v6/api/providers/#Signer)) used for signing transactions.
45
47
  */
46
48
  export class WalletClient {
47
49
  /**
@@ -59,7 +61,7 @@ export class WalletClient {
59
61
  * const client = new hl.WalletClient({ wallet, transport });
60
62
  * ```
61
63
  *
62
- * @example Private key via [ethers.js](https://docs.ethers.org/v6/api/wallet/#Wallet)
64
+ * @example Private key via [ethers.js](https://docs.ethers.org/v6/api/wallet/#Wallet) or [ethers.js v5](https://docs.ethers.org/v5/api/signer/#Wallet)
63
65
  * ```ts
64
66
  * import * as hl from "@nktkas/hyperliquid";
65
67
  * import { ethers } from "ethers";
@@ -81,6 +83,14 @@ export class WalletClient {
81
83
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
82
84
  * const client = new hl.WalletClient({ wallet, transport });
83
85
  * ```
86
+ *
87
+ * @example External wallet (e.g. MetaMask) via `window.ethereum` directly
88
+ * ```ts
89
+ * import * as hl from "@nktkas/hyperliquid";
90
+ *
91
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
92
+ * const client = new hl.WalletClient({ wallet: window.ethereum, transport });
93
+ * ```
84
94
  */
85
95
  constructor(args) {
86
96
  /** The transport used to connect to the Hyperliquid API. */
@@ -90,7 +100,10 @@ export class WalletClient {
90
100
  writable: true,
91
101
  value: void 0
92
102
  });
93
- /** The WalletClient/Account ([viem](https://viem.sh/docs/clients/wallet)) or Signer ([ethers.js](https://docs.ethers.org/v6/api/providers/#Signer)) used for signing transactions. */
103
+ /**
104
+ * The [viem](https://viem.sh/docs/clients/wallet) or [ethers.js](https://docs.ethers.org/v6/api/providers/#Signer)
105
+ * used for signing transactions.
106
+ */
94
107
  Object.defineProperty(this, "wallet", {
95
108
  enumerable: true,
96
109
  configurable: true,
@@ -111,10 +124,21 @@ export class WalletClient {
111
124
  writable: true,
112
125
  value: void 0
113
126
  });
127
+ /**
128
+ * The network that will be used to sign transactions.
129
+ * Must match the network of the {@link wallet}.
130
+ */
131
+ Object.defineProperty(this, "signatureChainId", {
132
+ enumerable: true,
133
+ configurable: true,
134
+ writable: true,
135
+ value: void 0
136
+ });
114
137
  this.transport = args.transport;
115
138
  this.wallet = args.wallet;
116
139
  this.isTestnet = args.isTestnet ?? false;
117
140
  this.defaultVaultAddress = args.defaultVaultAddress;
141
+ this.signatureChainId = args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1");
118
142
  }
119
143
  // ———————————————Actions———————————————
120
144
  /**
@@ -138,29 +162,35 @@ export class WalletClient {
138
162
  * agentAddress: "0x...",
139
163
  * agentName: "agentName",
140
164
  * });
165
+ * ```
141
166
  */
142
167
  async approveAgent(args, signal) {
168
+ // Construct an action
143
169
  const action = {
144
170
  ...args,
145
171
  type: "approveAgent",
146
172
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
147
- signatureChainId: args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1"),
173
+ signatureChainId: this.signatureChainId,
148
174
  nonce: args.nonce ?? Date.now(),
149
175
  };
150
- const signature = await signUserSignedAction(this.wallet, action, {
151
- "HyperliquidTransaction:ApproveAgent": [
152
- { name: "hyperliquidChain", type: "string" },
153
- { name: "agentAddress", type: "address" },
154
- { name: "agentName", type: "string" },
155
- { name: "nonce", type: "uint64" },
156
- ],
157
- }, parseInt(action.signatureChainId, 16));
158
- const request = {
176
+ // Sign the action
177
+ const signature = await signUserSignedAction({
178
+ wallet: this.wallet,
159
179
  action,
160
- signature,
161
- nonce: action.nonce,
162
- };
163
- const response = await this.transport.request("action", request, signal);
180
+ types: {
181
+ "HyperliquidTransaction:ApproveAgent": [
182
+ { name: "hyperliquidChain", type: "string" },
183
+ { name: "agentAddress", type: "address" },
184
+ { name: "agentName", type: "string" },
185
+ { name: "nonce", type: "uint64" },
186
+ ],
187
+ },
188
+ chainId: parseInt(action.signatureChainId, 16),
189
+ });
190
+ // Send a request
191
+ const request = { action, signature, nonce: action.nonce };
192
+ const response = await this.transport.request("exchange", request, signal);
193
+ // Validate a response
164
194
  this._validateResponse(response);
165
195
  return response;
166
196
  }
@@ -185,29 +215,35 @@ export class WalletClient {
185
215
  * maxFeeRate: "0.01%",
186
216
  * builder: "0x...",
187
217
  * });
218
+ * ```
188
219
  */
189
220
  async approveBuilderFee(args, signal) {
221
+ // Construct an action
190
222
  const action = {
191
223
  ...args,
192
224
  type: "approveBuilderFee",
193
225
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
194
- signatureChainId: args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1"),
226
+ signatureChainId: this.signatureChainId,
195
227
  nonce: args.nonce ?? Date.now(),
196
228
  };
197
- const signature = await signUserSignedAction(this.wallet, action, {
198
- "HyperliquidTransaction:ApproveBuilderFee": [
199
- { name: "hyperliquidChain", type: "string" },
200
- { name: "maxFeeRate", type: "string" },
201
- { name: "builder", type: "address" },
202
- { name: "nonce", type: "uint64" },
203
- ],
204
- }, parseInt(action.signatureChainId, 16));
205
- const request = {
229
+ // Sign the action
230
+ const signature = await signUserSignedAction({
231
+ wallet: this.wallet,
206
232
  action,
207
- signature,
208
- nonce: action.nonce,
209
- };
210
- const response = await this.transport.request("action", request, signal);
233
+ types: {
234
+ "HyperliquidTransaction:ApproveBuilderFee": [
235
+ { name: "hyperliquidChain", type: "string" },
236
+ { name: "maxFeeRate", type: "string" },
237
+ { name: "builder", type: "address" },
238
+ { name: "nonce", type: "uint64" },
239
+ ],
240
+ },
241
+ chainId: parseInt(action.signatureChainId, 16),
242
+ });
243
+ // Send a request
244
+ const request = { action, signature, nonce: action.nonce };
245
+ const response = await this.transport.request("exchange", request, signal);
246
+ // Validate a response
211
247
  this._validateResponse(response);
212
248
  return response;
213
249
  }
@@ -249,16 +285,53 @@ export class WalletClient {
249
285
  * ```
250
286
  */
251
287
  async batchModify(args, signal) {
288
+ // Destructure the parameters
252
289
  const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
253
- const sortedAction = sorters.batchModify({ type: "batchModify", ...actionArgs });
254
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
255
- const request = {
256
- action: sortedAction,
257
- signature,
290
+ // Construct an action
291
+ const action = {
292
+ type: "batchModify",
293
+ modifies: actionArgs.modifies.map((modify) => {
294
+ const sortedModify = {
295
+ oid: modify.oid,
296
+ order: {
297
+ a: modify.order.a,
298
+ b: modify.order.b,
299
+ p: modify.order.p,
300
+ s: modify.order.s,
301
+ r: modify.order.r,
302
+ t: "limit" in modify.order.t
303
+ ? {
304
+ limit: {
305
+ tif: modify.order.t.limit.tif,
306
+ },
307
+ }
308
+ : {
309
+ trigger: {
310
+ isMarket: modify.order.t.trigger.isMarket,
311
+ triggerPx: modify.order.t.trigger.triggerPx,
312
+ tpsl: modify.order.t.trigger.tpsl,
313
+ },
314
+ },
315
+ c: modify.order.c,
316
+ },
317
+ };
318
+ if (sortedModify.order.c === undefined)
319
+ delete sortedModify.order.c;
320
+ return sortedModify;
321
+ }),
322
+ };
323
+ // Sign the action
324
+ const signature = await signL1Action({
325
+ wallet: this.wallet,
326
+ action,
258
327
  nonce,
328
+ isTestnet: this.isTestnet,
259
329
  vaultAddress,
260
- };
261
- const response = await this.transport.request("action", request, signal);
330
+ });
331
+ // Send a request
332
+ const request = { action, signature, nonce, vaultAddress };
333
+ const response = await this.transport.request("exchange", request, signal);
334
+ // Validate a response
262
335
  this._validateResponse(response);
263
336
  return response;
264
337
  }
@@ -288,16 +361,28 @@ export class WalletClient {
288
361
  * ```
289
362
  */
290
363
  async cancel(args, signal) {
364
+ // Destructure the parameters
291
365
  const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
292
- const sortedAction = sorters.cancel({ type: "cancel", ...actionArgs });
293
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
294
- const request = {
295
- action: sortedAction,
296
- signature,
366
+ // Construct an action
367
+ const action = {
368
+ type: "cancel",
369
+ cancels: actionArgs.cancels.map((cancel) => ({
370
+ a: cancel.a,
371
+ o: cancel.o,
372
+ })),
373
+ };
374
+ // Sign the action
375
+ const signature = await signL1Action({
376
+ wallet: this.wallet,
377
+ action,
297
378
  nonce,
379
+ isTestnet: this.isTestnet,
298
380
  vaultAddress,
299
- };
300
- const response = await this.transport.request("action", request, signal);
381
+ });
382
+ // Send a request
383
+ const request = { action, signature, nonce, vaultAddress };
384
+ const response = await this.transport.request("exchange", request, signal);
385
+ // Validate a response
301
386
  this._validateResponse(response);
302
387
  return response;
303
388
  }
@@ -318,30 +403,74 @@ export class WalletClient {
318
403
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
319
404
  * const client = new hl.WalletClient({ wallet, transport });
320
405
  *
321
- * const result = await client.cDeposit({ wei: 100000000 });
406
+ * const result = await client.cDeposit({ wei: 1 * 1e8 });
322
407
  * ```
323
408
  */
324
409
  async cDeposit(args, signal) {
410
+ // Construct an action
325
411
  const action = {
326
412
  ...args,
327
413
  type: "cDeposit",
328
414
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
329
- signatureChainId: args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1"),
415
+ signatureChainId: this.signatureChainId,
330
416
  nonce: args.nonce ?? Date.now(),
331
417
  };
332
- const signature = await signUserSignedAction(this.wallet, action, {
333
- "HyperliquidTransaction:CDeposit": [
334
- { name: "hyperliquidChain", type: "string" },
335
- { name: "wei", type: "uint64" },
336
- { name: "nonce", type: "uint64" },
337
- ],
338
- }, parseInt(action.signatureChainId, 16));
339
- const request = {
418
+ // Sign the action
419
+ const signature = await signUserSignedAction({
420
+ wallet: this.wallet,
340
421
  action,
341
- signature,
342
- nonce: action.nonce,
343
- };
344
- const response = await this.transport.request("action", request, signal);
422
+ types: {
423
+ "HyperliquidTransaction:CDeposit": [
424
+ { name: "hyperliquidChain", type: "string" },
425
+ { name: "wei", type: "uint64" },
426
+ { name: "nonce", type: "uint64" },
427
+ ],
428
+ },
429
+ chainId: parseInt(action.signatureChainId, 16),
430
+ });
431
+ // Send a request
432
+ const request = { action, signature, nonce: action.nonce };
433
+ const response = await this.transport.request("exchange", request, signal);
434
+ // Validate a response
435
+ this._validateResponse(response);
436
+ return response;
437
+ }
438
+ /**
439
+ * Claim rewards from referral program.
440
+ * @param args - The parameters for the request.
441
+ * @param signal - An optional abort signal.
442
+ * @returns Successful response without specific data.
443
+ * @throws {ApiRequestError} When the API returns an error response.
444
+ *
445
+ * @see null - no documentation
446
+ * @example
447
+ * ```ts
448
+ * import * as hl from "@nktkas/hyperliquid";
449
+ * import { privateKeyToAccount } from "viem/accounts";
450
+ *
451
+ * const wallet = privateKeyToAccount("0x...");
452
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
453
+ * const client = new hl.WalletClient({ wallet, transport });
454
+ *
455
+ * const result = await client.claimRewards();
456
+ * ```
457
+ */
458
+ async claimRewards(args = {}, signal) {
459
+ // Destructure the parameters
460
+ const { nonce = Date.now() } = args;
461
+ // Construct an action
462
+ const sortedAction = { type: "claimRewards" };
463
+ // Sign the action
464
+ const signature = await signL1Action({
465
+ wallet: this.wallet,
466
+ action: sortedAction,
467
+ nonce,
468
+ isTestnet: this.isTestnet,
469
+ });
470
+ // Send a request
471
+ const request = { action: sortedAction, signature, nonce };
472
+ const response = await this.transport.request("exchange", request, signal);
473
+ // Validate a response
345
474
  this._validateResponse(response);
346
475
  return response;
347
476
  }
@@ -371,16 +500,28 @@ export class WalletClient {
371
500
  * ```
372
501
  */
373
502
  async cancelByCloid(args, signal) {
503
+ // Destructure the parameters
374
504
  const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
375
- const sortedAction = sorters.cancelByCloid({ type: "cancelByCloid", ...actionArgs });
376
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
377
- const request = {
378
- action: sortedAction,
379
- signature,
505
+ // Construct an action
506
+ const action = {
507
+ type: "cancelByCloid",
508
+ cancels: actionArgs.cancels.map((cancel) => ({
509
+ asset: cancel.asset,
510
+ cloid: cancel.cloid,
511
+ })),
512
+ };
513
+ // Sign the action
514
+ const signature = await signL1Action({
515
+ wallet: this.wallet,
516
+ action,
380
517
  nonce,
518
+ isTestnet: this.isTestnet,
381
519
  vaultAddress,
382
- };
383
- const response = await this.transport.request("action", request, signal);
520
+ });
521
+ // Send a request
522
+ const request = { action, signature, nonce, vaultAddress };
523
+ const response = await this.transport.request("exchange", request, signal);
524
+ // Validate a response
384
525
  this._validateResponse(response);
385
526
  return response;
386
527
  }
@@ -401,30 +542,77 @@ export class WalletClient {
401
542
  * const transport = new hl.HttpTransport(); // or WebSocketTransport
402
543
  * const client = new hl.WalletClient({ wallet, transport });
403
544
  *
404
- * const result = await client.cWithdraw({ wei: 100000000 });
545
+ * const result = await client.cWithdraw({ wei: 1 * 1e8 });
405
546
  * ```
406
547
  */
407
548
  async cWithdraw(args, signal) {
549
+ // Construct an action
408
550
  const action = {
409
551
  ...args,
410
552
  type: "cWithdraw",
411
553
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
412
- signatureChainId: args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1"),
554
+ signatureChainId: this.signatureChainId,
413
555
  nonce: args.nonce ?? Date.now(),
414
556
  };
415
- const signature = await signUserSignedAction(this.wallet, action, {
416
- "HyperliquidTransaction:CWithdraw": [
417
- { name: "hyperliquidChain", type: "string" },
418
- { name: "wei", type: "uint64" },
419
- { name: "nonce", type: "uint64" },
420
- ],
421
- }, parseInt(action.signatureChainId, 16));
422
- const request = {
557
+ // Sign the action
558
+ const signature = await signUserSignedAction({
559
+ wallet: this.wallet,
423
560
  action,
424
- signature,
425
- nonce: action.nonce,
561
+ types: {
562
+ "HyperliquidTransaction:CWithdraw": [
563
+ { name: "hyperliquidChain", type: "string" },
564
+ { name: "wei", type: "uint64" },
565
+ { name: "nonce", type: "uint64" },
566
+ ],
567
+ },
568
+ chainId: parseInt(action.signatureChainId, 16),
569
+ });
570
+ // Send a request
571
+ const request = { action, signature, nonce: action.nonce };
572
+ const response = await this.transport.request("exchange", request, signal);
573
+ // Validate a response
574
+ this._validateResponse(response);
575
+ return response;
576
+ }
577
+ /**
578
+ * Configure block type for EVM transactions.
579
+ * @param args - The parameters for the request.
580
+ * @param signal - An optional abort signal.
581
+ * @returns Response for creating a sub-account.
582
+ * @throws {ApiRequestError} When the API returns an error response.
583
+ *
584
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm/dual-block-architecture
585
+ * @example
586
+ * ```ts
587
+ * import * as hl from "@nktkas/hyperliquid";
588
+ * import { privateKeyToAccount } from "viem/accounts";
589
+ *
590
+ * const wallet = privateKeyToAccount("0x...");
591
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
592
+ * const client = new hl.WalletClient({ wallet, transport });
593
+ *
594
+ * const result = await client.evmUserModify({ usingBigBlocks: true });
595
+ * ```
596
+ */
597
+ async evmUserModify(args, signal) {
598
+ // Destructure the parameters
599
+ const { nonce = Date.now(), ...actionArgs } = args;
600
+ // Construct an action
601
+ const action = {
602
+ type: "evmUserModify",
603
+ usingBigBlocks: actionArgs.usingBigBlocks,
426
604
  };
427
- const response = await this.transport.request("action", request, signal);
605
+ // Sign the action
606
+ const signature = await signL1Action({
607
+ wallet: this.wallet,
608
+ action,
609
+ nonce,
610
+ isTestnet: this.isTestnet,
611
+ });
612
+ // Send a request
613
+ const request = { action, signature, nonce };
614
+ const response = await this.transport.request("exchange", request, signal);
615
+ // Validate a response
428
616
  this._validateResponse(response);
429
617
  return response;
430
618
  }
@@ -449,15 +637,24 @@ export class WalletClient {
449
637
  * ```
450
638
  */
451
639
  async createSubAccount(args, signal) {
640
+ // Destructure the parameters
452
641
  const { nonce = Date.now(), ...actionArgs } = args;
453
- const sortedAction = sorters.createSubAccount({ type: "createSubAccount", ...actionArgs });
454
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce);
455
- const request = {
456
- action: sortedAction,
457
- signature,
458
- nonce,
642
+ // Construct an action
643
+ const action = {
644
+ type: "createSubAccount",
645
+ name: actionArgs.name,
459
646
  };
460
- const response = await this.transport.request("action", request, signal);
647
+ // Sign the action
648
+ const signature = await signL1Action({
649
+ wallet: this.wallet,
650
+ action,
651
+ nonce,
652
+ isTestnet: this.isTestnet,
653
+ });
654
+ // Send a request
655
+ const request = { action, signature, nonce };
656
+ const response = await this.transport.request("exchange", request, signal);
657
+ // Validate a response
461
658
  this._validateResponse(response);
462
659
  return response;
463
660
  }
@@ -497,16 +694,48 @@ export class WalletClient {
497
694
  * ```
498
695
  */
499
696
  async modify(args, signal) {
697
+ // Destructure the parameters
500
698
  const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
501
- const sortedAction = sorters.modify({ type: "modify", ...actionArgs });
502
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
503
- const request = {
504
- action: sortedAction,
505
- signature,
699
+ // Construct an action
700
+ const action = {
701
+ type: "modify",
702
+ oid: actionArgs.oid,
703
+ order: {
704
+ a: actionArgs.order.a,
705
+ b: actionArgs.order.b,
706
+ p: actionArgs.order.p,
707
+ s: actionArgs.order.s,
708
+ r: actionArgs.order.r,
709
+ t: "limit" in actionArgs.order.t
710
+ ? {
711
+ limit: {
712
+ tif: actionArgs.order.t.limit.tif,
713
+ },
714
+ }
715
+ : {
716
+ trigger: {
717
+ isMarket: actionArgs.order.t.trigger.isMarket,
718
+ triggerPx: actionArgs.order.t.trigger.triggerPx,
719
+ tpsl: actionArgs.order.t.trigger.tpsl,
720
+ },
721
+ },
722
+ c: actionArgs.order.c,
723
+ },
724
+ };
725
+ if (action.order.c === undefined)
726
+ delete action.order.c;
727
+ // Sign the action
728
+ const signature = await signL1Action({
729
+ wallet: this.wallet,
730
+ action,
506
731
  nonce,
732
+ isTestnet: this.isTestnet,
507
733
  vaultAddress,
508
- };
509
- const response = await this.transport.request("action", request, signal);
734
+ });
735
+ // Send a request
736
+ const request = { action, signature, nonce, vaultAddress };
737
+ const response = await this.transport.request("exchange", request, signal);
738
+ // Validate a response
510
739
  this._validateResponse(response);
511
740
  return response;
512
741
  }
@@ -546,19 +775,59 @@ export class WalletClient {
546
775
  * ```
547
776
  */
548
777
  async order(args, signal) {
549
- const clonedArgs = structuredClone(args); // Clone to prevent mutation of original object
550
- const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = clonedArgs;
551
- if (actionArgs.builder)
552
- actionArgs.builder.b = actionArgs.builder.b.toLowerCase();
553
- const sortedAction = sorters.order({ type: "order", ...actionArgs });
554
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
555
- const request = {
556
- action: sortedAction,
557
- signature,
778
+ // Destructure the parameters
779
+ const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
780
+ // Construct an action
781
+ const action = {
782
+ type: "order",
783
+ orders: actionArgs.orders.map((order) => {
784
+ const sortedOrder = {
785
+ a: order.a,
786
+ b: order.b,
787
+ p: order.p,
788
+ s: order.s,
789
+ r: order.r,
790
+ t: "limit" in order.t
791
+ ? {
792
+ limit: {
793
+ tif: order.t.limit.tif,
794
+ },
795
+ }
796
+ : {
797
+ trigger: {
798
+ isMarket: order.t.trigger.isMarket,
799
+ triggerPx: order.t.trigger.triggerPx,
800
+ tpsl: order.t.trigger.tpsl,
801
+ },
802
+ },
803
+ c: order.c,
804
+ };
805
+ if (order.c === undefined)
806
+ delete sortedOrder.c;
807
+ return sortedOrder;
808
+ }),
809
+ grouping: actionArgs.grouping,
810
+ builder: actionArgs.builder
811
+ ? {
812
+ b: actionArgs.builder.b.toLowerCase(),
813
+ f: actionArgs.builder.f,
814
+ }
815
+ : actionArgs.builder,
816
+ };
817
+ if (action.builder === undefined)
818
+ delete action.builder;
819
+ // Sign the action
820
+ const signature = await signL1Action({
821
+ wallet: this.wallet,
822
+ action,
558
823
  nonce,
824
+ isTestnet: this.isTestnet,
559
825
  vaultAddress,
560
- };
561
- const response = await this.transport.request("action", request, signal);
826
+ });
827
+ // Send a request
828
+ const request = { action, signature, nonce, vaultAddress };
829
+ const response = await this.transport.request("exchange", request, signal);
830
+ // Validate a response
562
831
  this._validateResponse(response);
563
832
  return response;
564
833
  }
@@ -583,16 +852,69 @@ export class WalletClient {
583
852
  * ```
584
853
  */
585
854
  async scheduleCancel(args = {}, signal) {
855
+ // Destructure the parameters
586
856
  const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
587
- const sortedAction = sorters.scheduleCancel({ type: "scheduleCancel", ...actionArgs });
588
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
589
- const request = {
590
- action: sortedAction,
591
- signature,
857
+ // Construct an action
858
+ const action = {
859
+ type: "scheduleCancel",
860
+ time: actionArgs.time,
861
+ };
862
+ if (action.time === undefined)
863
+ delete action.time;
864
+ // Sign the action
865
+ const signature = await signL1Action({
866
+ wallet: this.wallet,
867
+ action,
592
868
  nonce,
869
+ isTestnet: this.isTestnet,
593
870
  vaultAddress,
871
+ });
872
+ // Send a request
873
+ const request = { action, signature, nonce, vaultAddress };
874
+ const response = await this.transport.request("exchange", request, signal);
875
+ // Validate a response
876
+ this._validateResponse(response);
877
+ return response;
878
+ }
879
+ /**
880
+ * Set the display name in the leaderboard.
881
+ * @param args - The parameters for the request.
882
+ * @param signal - An optional abort signal.
883
+ * @returns Successful response without specific data.
884
+ * @throws {ApiRequestError} When the API returns an error response.
885
+ *
886
+ * @see null - no documentation
887
+ * @example
888
+ * ```ts
889
+ * import * as hl from "@nktkas/hyperliquid";
890
+ * import { privateKeyToAccount } from "viem/accounts";
891
+ *
892
+ * const wallet = privateKeyToAccount("0x...");
893
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
894
+ * const client = new hl.WalletClient({ wallet, transport });
895
+ *
896
+ * const result = await client.setDisplayName({ displayName: "My Name" });
897
+ * ```
898
+ */
899
+ async setDisplayName(args, signal) {
900
+ // Destructure the parameters
901
+ const { nonce = Date.now(), ...actionArgs } = args;
902
+ // Construct an action
903
+ const action = {
904
+ type: "setDisplayName",
905
+ displayName: actionArgs.displayName,
594
906
  };
595
- const response = await this.transport.request("action", request, signal);
907
+ // Sign the action
908
+ const signature = await signL1Action({
909
+ wallet: this.wallet,
910
+ action,
911
+ nonce,
912
+ isTestnet: this.isTestnet,
913
+ });
914
+ // Send a request
915
+ const request = { action, signature, nonce };
916
+ const response = await this.transport.request("exchange", request, signal);
917
+ // Validate a response
596
918
  this._validateResponse(response);
597
919
  return response;
598
920
  }
@@ -617,15 +939,24 @@ export class WalletClient {
617
939
  * ```
618
940
  */
619
941
  async setReferrer(args, signal) {
942
+ // Destructure the parameters
620
943
  const { nonce = Date.now(), ...actionArgs } = args;
621
- const sortedAction = sorters.setReferrer({ type: "setReferrer", ...actionArgs });
622
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce);
623
- const request = {
624
- action: sortedAction,
625
- signature,
626
- nonce,
944
+ // Construct an action
945
+ const action = {
946
+ type: "setReferrer",
947
+ code: actionArgs.code,
627
948
  };
628
- const response = await this.transport.request("action", request, signal);
949
+ // Sign the action
950
+ const signature = await signL1Action({
951
+ wallet: this.wallet,
952
+ action,
953
+ nonce,
954
+ isTestnet: this.isTestnet,
955
+ });
956
+ // Send a request
957
+ const request = { action, signature, nonce };
958
+ const response = await this.transport.request("exchange", request, signal);
959
+ // Validate a response
629
960
  this._validateResponse(response);
630
961
  return response;
631
962
  }
@@ -654,33 +985,134 @@ export class WalletClient {
654
985
  * ```
655
986
  */
656
987
  async spotSend(args, signal) {
988
+ // Construct an action
657
989
  const action = {
658
990
  ...args,
659
991
  type: "spotSend",
660
992
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
661
- signatureChainId: args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1"),
993
+ signatureChainId: this.signatureChainId,
662
994
  time: args.time ?? Date.now(),
663
995
  };
664
- const signature = await signUserSignedAction(this.wallet, action, {
665
- "HyperliquidTransaction:SpotSend": [
666
- { name: "hyperliquidChain", type: "string" },
667
- { name: "destination", type: "string" },
668
- { name: "token", type: "string" },
669
- { name: "amount", type: "string" },
670
- { name: "time", type: "uint64" },
671
- ],
672
- }, parseInt(action.signatureChainId, 16));
673
- const request = {
996
+ // Sign the action
997
+ const signature = await signUserSignedAction({
998
+ wallet: this.wallet,
999
+ action,
1000
+ types: {
1001
+ "HyperliquidTransaction:SpotSend": [
1002
+ { name: "hyperliquidChain", type: "string" },
1003
+ { name: "destination", type: "string" },
1004
+ { name: "token", type: "string" },
1005
+ { name: "amount", type: "string" },
1006
+ { name: "time", type: "uint64" },
1007
+ ],
1008
+ },
1009
+ chainId: parseInt(action.signatureChainId, 16),
1010
+ });
1011
+ // Send a request
1012
+ const request = { action, signature, nonce: action.time };
1013
+ const response = await this.transport.request("exchange", request, signal);
1014
+ // Validate a response
1015
+ this._validateResponse(response);
1016
+ return response;
1017
+ }
1018
+ /**
1019
+ * Opt Out of Spot Dusting.
1020
+ * @param args - The parameters for the request.
1021
+ * @param signal - An optional abort signal.
1022
+ * @returns Successful response without specific data.
1023
+ * @throws {ApiRequestError} When the API returns an error response.
1024
+ *
1025
+ * @see null - no documentation
1026
+ * @example
1027
+ * ```ts
1028
+ * import * as hl from "@nktkas/hyperliquid";
1029
+ * import { privateKeyToAccount } from "viem/accounts";
1030
+ *
1031
+ * const wallet = privateKeyToAccount("0x...");
1032
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
1033
+ * const client = new hl.WalletClient({ wallet, transport });
1034
+ *
1035
+ * const result = await client.spotUser({
1036
+ * toggleSpotDusting: { optOut: false },
1037
+ * });
1038
+ * ```
1039
+ */
1040
+ async spotUser(args, signal) {
1041
+ // Destructure the parameters
1042
+ const { nonce = Date.now(), ...actionArgs } = args;
1043
+ // Construct an action
1044
+ const action = {
1045
+ type: "spotUser",
1046
+ toggleSpotDusting: {
1047
+ optOut: actionArgs.toggleSpotDusting.optOut,
1048
+ },
1049
+ };
1050
+ // Sign the action
1051
+ const signature = await signL1Action({
1052
+ wallet: this.wallet,
674
1053
  action,
675
- signature,
676
- nonce: action.time,
1054
+ nonce,
1055
+ isTestnet: this.isTestnet,
1056
+ });
1057
+ // Send a request
1058
+ const request = { action, signature, nonce };
1059
+ const response = await this.transport.request("exchange", request, signal);
1060
+ // Validate a response
1061
+ this._validateResponse(response);
1062
+ return response;
1063
+ }
1064
+ /**
1065
+ * Transfer between sub-accounts (spot).
1066
+ * @param args - The parameters for the request.
1067
+ * @param signal - An optional abort signal.
1068
+ * @returns Successful response without specific data.
1069
+ * @throws {ApiRequestError} When the API returns an error response.
1070
+ *
1071
+ * @see null - no documentation
1072
+ * @example
1073
+ * ```ts
1074
+ * import * as hl from "@nktkas/hyperliquid";
1075
+ * import { privateKeyToAccount } from "viem/accounts";
1076
+ *
1077
+ * const wallet = privateKeyToAccount("0x...");
1078
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
1079
+ * const client = new hl.WalletClient({ wallet, transport });
1080
+ *
1081
+ * const result = await client.subAccountSpotTransfer({
1082
+ * subAccountUser: "0x...",
1083
+ * isDeposit: true,
1084
+ * token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
1085
+ * amount: "1",
1086
+ * });
1087
+ * ```
1088
+ */
1089
+ async subAccountSpotTransfer(args, signal) {
1090
+ // Destructure the parameters
1091
+ const { nonce = Date.now(), ...actionArgs } = args;
1092
+ // Construct an action
1093
+ const action = {
1094
+ type: "subAccountSpotTransfer",
1095
+ subAccountUser: actionArgs.subAccountUser,
1096
+ isDeposit: actionArgs.isDeposit,
1097
+ token: actionArgs.token,
1098
+ amount: actionArgs.amount,
677
1099
  };
678
- const response = await this.transport.request("action", request, signal);
1100
+ // Sign the action
1101
+ const signature = await signL1Action({
1102
+ wallet: this.wallet,
1103
+ action,
1104
+ nonce,
1105
+ isTestnet: this.isTestnet,
1106
+ });
1107
+ // Send a request
1108
+ const request = { action, signature, nonce };
1109
+ const response = await this.transport.request("exchange", request, signal);
1110
+ // Validate a response
679
1111
  this._validateResponse(response);
680
1112
  return response;
681
1113
  }
682
1114
  /**
683
- * Transfer between sub-accounts.
1115
+ * Transfer between sub-accounts (perpetual).
684
1116
  * @param args - The parameters for the request.
685
1117
  * @param signal - An optional abort signal.
686
1118
  * @returns Successful response without specific data.
@@ -699,20 +1131,31 @@ export class WalletClient {
699
1131
  * const result = await client.subAccountTransfer({
700
1132
  * subAccountUser: "0x...",
701
1133
  * isDeposit: true,
702
- * usd: 1000000, // 1 USD in raw units (float amount * 1e6)
1134
+ * usd: 1 * 1e6,
703
1135
  * });
704
1136
  * ```
705
1137
  */
706
1138
  async subAccountTransfer(args, signal) {
1139
+ // Destructure the parameters
707
1140
  const { nonce = Date.now(), ...actionArgs } = args;
708
- const sortedAction = sorters.subAccountTransfer({ type: "subAccountTransfer", ...actionArgs });
709
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce);
710
- const request = {
711
- action: sortedAction,
712
- signature,
713
- nonce,
1141
+ // Construct an action
1142
+ const action = {
1143
+ type: "subAccountTransfer",
1144
+ subAccountUser: actionArgs.subAccountUser,
1145
+ isDeposit: actionArgs.isDeposit,
1146
+ usd: actionArgs.usd,
714
1147
  };
715
- const response = await this.transport.request("action", request, signal);
1148
+ // Sign the action
1149
+ const signature = await signL1Action({
1150
+ wallet: this.wallet,
1151
+ action,
1152
+ nonce,
1153
+ isTestnet: this.isTestnet,
1154
+ });
1155
+ // Send a request
1156
+ const request = { action, signature, nonce };
1157
+ const response = await this.transport.request("exchange", request, signal);
1158
+ // Validate a response
716
1159
  this._validateResponse(response);
717
1160
  return response;
718
1161
  }
@@ -736,33 +1179,38 @@ export class WalletClient {
736
1179
  * const result = await client.tokenDelegate({
737
1180
  * validator: "0x...",
738
1181
  * isUndelegate: true,
739
- * wei: 100000000,
1182
+ * wei: 1 * 1e8,
740
1183
  * });
741
1184
  * ```
742
1185
  */
743
1186
  async tokenDelegate(args, signal) {
1187
+ // Construct an action
744
1188
  const action = {
745
1189
  ...args,
746
1190
  type: "tokenDelegate",
747
1191
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
748
- signatureChainId: args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1"),
1192
+ signatureChainId: this.signatureChainId,
749
1193
  nonce: args.nonce ?? Date.now(),
750
1194
  };
751
- const signature = await signUserSignedAction(this.wallet, action, {
752
- "HyperliquidTransaction:TokenDelegate": [
753
- { name: "hyperliquidChain", type: "string" },
754
- { name: "validator", type: "address" },
755
- { name: "wei", type: "uint64" },
756
- { name: "isUndelegate", type: "bool" },
757
- { name: "nonce", type: "uint64" },
758
- ],
759
- }, parseInt(action.signatureChainId, 16));
760
- const request = {
1195
+ // Sign the action
1196
+ const signature = await signUserSignedAction({
1197
+ wallet: this.wallet,
761
1198
  action,
762
- signature,
763
- nonce: action.nonce,
764
- };
765
- const response = await this.transport.request("action", request, signal);
1199
+ types: {
1200
+ "HyperliquidTransaction:TokenDelegate": [
1201
+ { name: "hyperliquidChain", type: "string" },
1202
+ { name: "validator", type: "address" },
1203
+ { name: "wei", type: "uint64" },
1204
+ { name: "isUndelegate", type: "bool" },
1205
+ { name: "nonce", type: "uint64" },
1206
+ ],
1207
+ },
1208
+ chainId: parseInt(action.signatureChainId, 16),
1209
+ });
1210
+ // Send a request
1211
+ const request = { action, signature, nonce: action.nonce };
1212
+ const response = await this.transport.request("exchange", request, signal);
1213
+ // Validate a response
766
1214
  this._validateResponse(response);
767
1215
  return response;
768
1216
  }
@@ -790,16 +1238,26 @@ export class WalletClient {
790
1238
  * ```
791
1239
  */
792
1240
  async twapCancel(args, signal) {
1241
+ // Destructure the parameters
793
1242
  const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
794
- const sortedAction = sorters.twapCancel({ type: "twapCancel", ...actionArgs });
795
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
796
- const request = {
797
- action: sortedAction,
798
- signature,
1243
+ // Construct an action
1244
+ const action = {
1245
+ type: "twapCancel",
1246
+ a: actionArgs.a,
1247
+ t: actionArgs.t,
1248
+ };
1249
+ // Sign the action
1250
+ const signature = await signL1Action({
1251
+ wallet: this.wallet,
1252
+ action,
799
1253
  nonce,
1254
+ isTestnet: this.isTestnet,
800
1255
  vaultAddress,
801
- };
802
- const response = await this.transport.request("action", request, signal);
1256
+ });
1257
+ // Send a request
1258
+ const request = { action, signature, nonce, vaultAddress };
1259
+ const response = await this.transport.request("exchange", request, signal);
1260
+ // Validate a response
803
1261
  this._validateResponse(response);
804
1262
  return response;
805
1263
  }
@@ -831,16 +1289,32 @@ export class WalletClient {
831
1289
  * ```
832
1290
  */
833
1291
  async twapOrder(args, signal) {
1292
+ // Destructure the parameters
834
1293
  const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
835
- const sortedAction = sorters.twapOrder({ type: "twapOrder", twap: actionArgs });
836
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
837
- const request = {
838
- action: sortedAction,
839
- signature,
1294
+ // Construct an action
1295
+ const action = {
1296
+ type: "twapOrder",
1297
+ twap: {
1298
+ a: actionArgs.a,
1299
+ b: actionArgs.b,
1300
+ s: actionArgs.s,
1301
+ r: actionArgs.r,
1302
+ m: actionArgs.m,
1303
+ t: actionArgs.t,
1304
+ },
1305
+ };
1306
+ // Sign the action
1307
+ const signature = await signL1Action({
1308
+ wallet: this.wallet,
1309
+ action,
840
1310
  nonce,
1311
+ isTestnet: this.isTestnet,
841
1312
  vaultAddress,
842
- };
843
- const response = await this.transport.request("action", request, signal);
1313
+ });
1314
+ // Send a request
1315
+ const request = { action, signature, nonce, vaultAddress };
1316
+ const response = await this.transport.request("exchange", request, signal);
1317
+ // Validate a response
844
1318
  this._validateResponse(response);
845
1319
  return response;
846
1320
  }
@@ -864,21 +1338,32 @@ export class WalletClient {
864
1338
  * const result = await client.updateIsolatedMargin({
865
1339
  * asset: 0,
866
1340
  * isBuy: true, // Add to long position
867
- * ntli: 1000, // Add 1000 USD margin (integer only)
1341
+ * ntli: 1, // Add 1 USD margin (integer only)
868
1342
  * });
869
1343
  * ```
870
1344
  */
871
1345
  async updateIsolatedMargin(args, signal) {
1346
+ // Destructure the parameters
872
1347
  const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
873
- const sortedAction = sorters.updateIsolatedMargin({ type: "updateIsolatedMargin", ...actionArgs });
874
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
875
- const request = {
876
- action: sortedAction,
877
- signature,
1348
+ // Construct an action
1349
+ const action = {
1350
+ type: "updateIsolatedMargin",
1351
+ asset: actionArgs.asset,
1352
+ isBuy: actionArgs.isBuy,
1353
+ ntli: actionArgs.ntli,
1354
+ };
1355
+ // Sign the action
1356
+ const signature = await signL1Action({
1357
+ wallet: this.wallet,
1358
+ action,
878
1359
  nonce,
1360
+ isTestnet: this.isTestnet,
879
1361
  vaultAddress,
880
- };
881
- const response = await this.transport.request("action", request, signal);
1362
+ });
1363
+ // Send a request
1364
+ const request = { action, signature, nonce, vaultAddress };
1365
+ const response = await this.transport.request("exchange", request, signal);
1366
+ // Validate a response
882
1367
  this._validateResponse(response);
883
1368
  return response;
884
1369
  }
@@ -907,16 +1392,27 @@ export class WalletClient {
907
1392
  * ```
908
1393
  */
909
1394
  async updateLeverage(args, signal) {
1395
+ // Destructure the parameters
910
1396
  const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
911
- const sortedAction = sorters.updateLeverage({ type: "updateLeverage", ...actionArgs });
912
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
913
- const request = {
914
- action: sortedAction,
915
- signature,
1397
+ // Construct an action
1398
+ const action = {
1399
+ type: "updateLeverage",
1400
+ asset: actionArgs.asset,
1401
+ isCross: actionArgs.isCross,
1402
+ leverage: actionArgs.leverage,
1403
+ };
1404
+ // Sign the action
1405
+ const signature = await signL1Action({
1406
+ wallet: this.wallet,
1407
+ action,
916
1408
  nonce,
1409
+ isTestnet: this.isTestnet,
917
1410
  vaultAddress,
918
- };
919
- const response = await this.transport.request("action", request, signal);
1411
+ });
1412
+ // Send a request
1413
+ const request = { action, signature, nonce, vaultAddress };
1414
+ const response = await this.transport.request("exchange", request, signal);
1415
+ // Validate a response
920
1416
  this._validateResponse(response);
921
1417
  return response;
922
1418
  }
@@ -938,33 +1434,38 @@ export class WalletClient {
938
1434
  * const client = new hl.WalletClient({ wallet, transport });
939
1435
  *
940
1436
  * const result = await client.usdClassTransfer({
941
- * amount: "1000",
1437
+ * amount: "1",
942
1438
  * toPerp: true, // Transfer from Spot to Perp
943
1439
  * });
944
1440
  * ```
945
1441
  */
946
1442
  async usdClassTransfer(args, signal) {
1443
+ // Construct an action
947
1444
  const action = {
948
1445
  ...args,
949
1446
  type: "usdClassTransfer",
950
1447
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
951
- signatureChainId: args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1"),
1448
+ signatureChainId: this.signatureChainId,
952
1449
  nonce: args.nonce ?? Date.now(),
953
1450
  };
954
- const signature = await signUserSignedAction(this.wallet, action, {
955
- "HyperliquidTransaction:UsdClassTransfer": [
956
- { name: "hyperliquidChain", type: "string" },
957
- { name: "amount", type: "string" },
958
- { name: "toPerp", type: "bool" },
959
- { name: "nonce", type: "uint64" },
960
- ],
961
- }, parseInt(action.signatureChainId, 16));
962
- const request = {
1451
+ // Sign the action
1452
+ const signature = await signUserSignedAction({
1453
+ wallet: this.wallet,
963
1454
  action,
964
- signature,
965
- nonce: action.nonce,
966
- };
967
- const response = await this.transport.request("action", request, signal);
1455
+ types: {
1456
+ "HyperliquidTransaction:UsdClassTransfer": [
1457
+ { name: "hyperliquidChain", type: "string" },
1458
+ { name: "amount", type: "string" },
1459
+ { name: "toPerp", type: "bool" },
1460
+ { name: "nonce", type: "uint64" },
1461
+ ],
1462
+ },
1463
+ chainId: parseInt(action.signatureChainId, 16),
1464
+ });
1465
+ // Send a request
1466
+ const request = { action, signature, nonce: action.nonce };
1467
+ const response = await this.transport.request("exchange", request, signal);
1468
+ // Validate a response
968
1469
  this._validateResponse(response);
969
1470
  return response;
970
1471
  }
@@ -987,32 +1488,131 @@ export class WalletClient {
987
1488
  *
988
1489
  * const result = await client.usdSend({
989
1490
  * destination: "0x...",
990
- * amount: "1000",
1491
+ * amount: "1",
991
1492
  * });
992
1493
  * ```
993
1494
  */
994
1495
  async usdSend(args, signal) {
1496
+ // Construct an action
995
1497
  const action = {
996
1498
  ...args,
997
1499
  type: "usdSend",
998
1500
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
999
- signatureChainId: args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1"),
1501
+ signatureChainId: this.signatureChainId,
1000
1502
  time: args.time ?? Date.now(),
1001
1503
  };
1002
- const signature = await signUserSignedAction(this.wallet, action, {
1003
- "HyperliquidTransaction:UsdSend": [
1004
- { name: "hyperliquidChain", type: "string" },
1005
- { name: "destination", type: "string" },
1006
- { name: "amount", type: "string" },
1007
- { name: "time", type: "uint64" },
1008
- ],
1009
- }, parseInt(action.signatureChainId, 16));
1010
- const request = {
1504
+ // Sign the action
1505
+ const signature = await signUserSignedAction({
1506
+ wallet: this.wallet,
1011
1507
  action,
1012
- signature,
1013
- nonce: action.time,
1508
+ types: {
1509
+ "HyperliquidTransaction:UsdSend": [
1510
+ { name: "hyperliquidChain", type: "string" },
1511
+ { name: "destination", type: "string" },
1512
+ { name: "amount", type: "string" },
1513
+ { name: "time", type: "uint64" },
1514
+ ],
1515
+ },
1516
+ chainId: parseInt(action.signatureChainId, 16),
1517
+ });
1518
+ // Send a request
1519
+ const request = { action, signature, nonce: action.time };
1520
+ const response = await this.transport.request("exchange", request, signal);
1521
+ // Validate a response
1522
+ this._validateResponse(response);
1523
+ return response;
1524
+ }
1525
+ /**
1526
+ * Distribute funds from a vault between followers.
1527
+ * @param args - The parameters for the request.
1528
+ * @param signal - An optional abort signal.
1529
+ * @returns Successful response without specific data.
1530
+ * @throws {ApiRequestError} When the API returns an error response.
1531
+ *
1532
+ * @see null - no documentation
1533
+ * @example
1534
+ * ```ts
1535
+ * import * as hl from "@nktkas/hyperliquid";
1536
+ * import { privateKeyToAccount } from "viem/accounts";
1537
+ *
1538
+ * const wallet = privateKeyToAccount("0x...");
1539
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
1540
+ * const client = new hl.WalletClient({ wallet, transport });
1541
+ *
1542
+ * const result = await client.vaultDistribute({
1543
+ * vaultAddress: "0x...",
1544
+ * usd: 10 * 1e6,
1545
+ * });
1546
+ * ```
1547
+ */
1548
+ async vaultDistribute(args, signal) {
1549
+ // Destructure the parameters
1550
+ const { nonce = Date.now(), ...actionArgs } = args;
1551
+ // Construct an action
1552
+ const action = {
1553
+ type: "vaultDistribute",
1554
+ vaultAddress: actionArgs.vaultAddress,
1555
+ usd: actionArgs.usd,
1014
1556
  };
1015
- const response = await this.transport.request("action", request, signal);
1557
+ // Sign the action
1558
+ const signature = await signL1Action({
1559
+ wallet: this.wallet,
1560
+ action,
1561
+ nonce,
1562
+ isTestnet: this.isTestnet,
1563
+ });
1564
+ // Send a request
1565
+ const request = { action, signature, nonce };
1566
+ const response = await this.transport.request("exchange", request, signal);
1567
+ // Validate a response
1568
+ this._validateResponse(response);
1569
+ return response;
1570
+ }
1571
+ /**
1572
+ * Modify a vault's configuration.
1573
+ * @param args - The parameters for the request.
1574
+ * @param signal - An optional abort signal.
1575
+ * @returns Successful response without specific data.
1576
+ * @throws {ApiRequestError} When the API returns an error response.
1577
+ *
1578
+ * @see null - no documentation
1579
+ * @example
1580
+ * ```ts
1581
+ * import * as hl from "@nktkas/hyperliquid";
1582
+ * import { privateKeyToAccount } from "viem/accounts";
1583
+ *
1584
+ * const wallet = privateKeyToAccount("0x...");
1585
+ * const transport = new hl.HttpTransport(); // or WebSocketTransport
1586
+ * const client = new hl.WalletClient({ wallet, transport });
1587
+ *
1588
+ * const result = await client.vaultModify({
1589
+ * vaultAddress: "0x...",
1590
+ * allowDeposits: true,
1591
+ * alwaysCloseOnWithdraw: false,
1592
+ * });
1593
+ * ```
1594
+ */
1595
+ async vaultModify(args, signal) {
1596
+ // Destructure the parameters
1597
+ const { nonce = Date.now(), ...actionArgs } = args;
1598
+ // Construct an action
1599
+ const action = {
1600
+ type: "vaultModify",
1601
+ vaultAddress: actionArgs.vaultAddress,
1602
+ allowDeposits: actionArgs.allowDeposits,
1603
+ alwaysCloseOnWithdraw: actionArgs.alwaysCloseOnWithdraw,
1604
+ };
1605
+ // Sign the action
1606
+ const signature = await signL1Action({
1607
+ wallet: this.wallet,
1608
+ action,
1609
+ nonce,
1610
+ isTestnet: this.isTestnet,
1611
+ });
1612
+ // Send a request
1613
+ const request = { action, signature, nonce };
1614
+ const response = await this.transport.request("exchange", request, signal);
1615
+ // Validate a response
1016
1616
  this._validateResponse(response);
1017
1617
  return response;
1018
1618
  }
@@ -1036,20 +1636,31 @@ export class WalletClient {
1036
1636
  * const result = await client.vaultTransfer({
1037
1637
  * vaultAddress: "0x...",
1038
1638
  * isDeposit: true,
1039
- * usd: 1000000, // 1 USD in raw units (float amount * 1e6)
1639
+ * usd: 10 * 1e6,
1040
1640
  * });
1041
1641
  * ```
1042
1642
  */
1043
1643
  async vaultTransfer(args, signal) {
1644
+ // Destructure the parameters
1044
1645
  const { nonce = Date.now(), ...actionArgs } = args;
1045
- const sortedAction = sorters.vaultTransfer({ type: "vaultTransfer", ...actionArgs });
1046
- const signature = await signL1Action(this.wallet, this.isTestnet, sortedAction, nonce);
1047
- const request = {
1048
- action: sortedAction,
1049
- signature,
1050
- nonce,
1646
+ // Construct an action
1647
+ const action = {
1648
+ type: "vaultTransfer",
1649
+ vaultAddress: actionArgs.vaultAddress,
1650
+ isDeposit: actionArgs.isDeposit,
1651
+ usd: actionArgs.usd,
1051
1652
  };
1052
- const response = await this.transport.request("action", request, signal);
1653
+ // Sign the action
1654
+ const signature = await signL1Action({
1655
+ wallet: this.wallet,
1656
+ action,
1657
+ nonce,
1658
+ isTestnet: this.isTestnet,
1659
+ });
1660
+ // Send a request
1661
+ const request = { action, signature, nonce };
1662
+ const response = await this.transport.request("exchange", request, signal);
1663
+ // Validate a response
1053
1664
  this._validateResponse(response);
1054
1665
  return response;
1055
1666
  }
@@ -1072,32 +1683,37 @@ export class WalletClient {
1072
1683
  *
1073
1684
  * const result = await client.withdraw3({
1074
1685
  * destination: "0x...",
1075
- * amount: "1000",
1686
+ * amount: "1",
1076
1687
  * });
1077
1688
  * ```
1078
1689
  */
1079
1690
  async withdraw3(args, signal) {
1691
+ // Construct an action
1080
1692
  const action = {
1081
1693
  ...args,
1082
1694
  type: "withdraw3",
1083
1695
  hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
1084
- signatureChainId: args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1"),
1696
+ signatureChainId: this.signatureChainId,
1085
1697
  time: args.time ?? Date.now(),
1086
1698
  };
1087
- const signature = await signUserSignedAction(this.wallet, action, {
1088
- "HyperliquidTransaction:Withdraw": [
1089
- { name: "hyperliquidChain", type: "string" },
1090
- { name: "destination", type: "string" },
1091
- { name: "amount", type: "string" },
1092
- { name: "time", type: "uint64" },
1093
- ],
1094
- }, parseInt(action.signatureChainId, 16));
1095
- const request = {
1699
+ // Sign the action
1700
+ const signature = await signUserSignedAction({
1701
+ wallet: this.wallet,
1096
1702
  action,
1097
- signature,
1098
- nonce: action.time,
1099
- };
1100
- const response = await this.transport.request("action", request, signal);
1703
+ types: {
1704
+ "HyperliquidTransaction:Withdraw": [
1705
+ { name: "hyperliquidChain", type: "string" },
1706
+ { name: "destination", type: "string" },
1707
+ { name: "amount", type: "string" },
1708
+ { name: "time", type: "uint64" },
1709
+ ],
1710
+ },
1711
+ chainId: parseInt(action.signatureChainId, 16),
1712
+ });
1713
+ // Send a request
1714
+ const request = { action, signature, nonce: action.time };
1715
+ const response = await this.transport.request("exchange", request, signal);
1716
+ // Validate a response
1101
1717
  this._validateResponse(response);
1102
1718
  return response;
1103
1719
  }