@nktkas/hyperliquid 0.22.1 → 0.23.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 (230) hide show
  1. package/README.md +125 -70
  2. package/esm/mod.d.ts +1 -1
  3. package/esm/mod.d.ts.map +1 -1
  4. package/esm/src/base.d.ts +4 -1
  5. package/esm/src/base.d.ts.map +1 -1
  6. package/esm/src/base.js +2 -2
  7. package/esm/src/clients/exchange.d.ts +420 -368
  8. package/esm/src/clients/exchange.d.ts.map +1 -1
  9. package/esm/src/clients/exchange.js +721 -551
  10. package/esm/src/clients/info.d.ts +137 -41
  11. package/esm/src/clients/info.d.ts.map +1 -1
  12. package/esm/src/clients/info.js +124 -28
  13. package/esm/src/clients/multiSign.d.ts +406 -484
  14. package/esm/src/clients/multiSign.d.ts.map +1 -1
  15. package/esm/src/clients/multiSign.js +639 -734
  16. package/esm/src/clients/subscription.d.ts +38 -3
  17. package/esm/src/clients/subscription.d.ts.map +1 -1
  18. package/esm/src/clients/subscription.js +36 -3
  19. package/esm/src/signing/_signTypedData/ethers.d.ts +33 -0
  20. package/esm/src/signing/_signTypedData/ethers.d.ts.map +1 -0
  21. package/esm/src/signing/_signTypedData/ethers.js +12 -0
  22. package/esm/src/signing/_signTypedData/mod.d.ts +35 -0
  23. package/esm/src/signing/_signTypedData/mod.d.ts.map +1 -0
  24. package/esm/src/signing/_signTypedData/mod.js +59 -0
  25. package/esm/src/signing/_signTypedData/private_key.d.ts +26 -0
  26. package/esm/src/signing/_signTypedData/private_key.d.ts.map +1 -0
  27. package/esm/src/signing/_signTypedData/private_key.js +144 -0
  28. package/esm/src/signing/_signTypedData/viem.d.ts +23 -0
  29. package/esm/src/signing/_signTypedData/viem.d.ts.map +1 -0
  30. package/esm/src/signing/_signTypedData/viem.js +6 -0
  31. package/esm/src/signing/_signTypedData/window.d.ts +29 -0
  32. package/esm/src/signing/_signTypedData/window.d.ts.map +1 -0
  33. package/esm/src/signing/_signTypedData/window.js +30 -0
  34. package/esm/src/signing/_sorter.d.ts +128 -0
  35. package/esm/src/signing/_sorter.d.ts.map +1 -0
  36. package/esm/src/{signing.js → signing/_sorter.js} +36 -449
  37. package/esm/src/signing/mod.d.ts +272 -0
  38. package/esm/src/signing/mod.d.ts.map +1 -0
  39. package/esm/src/signing/mod.js +306 -0
  40. package/esm/src/transports/base.d.ts +1 -1
  41. package/esm/src/transports/base.d.ts.map +1 -1
  42. package/esm/src/transports/base.js +2 -2
  43. package/esm/src/transports/http/http_transport.d.ts +9 -15
  44. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  45. package/esm/src/transports/http/http_transport.js +64 -59
  46. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +1 -1
  47. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  48. package/esm/src/transports/websocket/_hyperliquid_event_target.js +1 -1
  49. package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  50. package/esm/src/transports/websocket/_reconnecting_websocket.js +17 -4
  51. package/esm/src/transports/websocket/_websocket_async_request.d.ts +0 -9
  52. package/esm/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  53. package/esm/src/transports/websocket/_websocket_async_request.js +14 -20
  54. package/esm/src/transports/websocket/websocket_transport.d.ts +8 -4
  55. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  56. package/esm/src/transports/websocket/websocket_transport.js +83 -54
  57. package/esm/src/types/exchange/requests.d.ts +27 -51
  58. package/esm/src/types/exchange/requests.d.ts.map +1 -1
  59. package/esm/src/types/explorer/requests.d.ts +5 -8
  60. package/esm/src/types/explorer/requests.d.ts.map +1 -1
  61. package/esm/src/types/info/accounts.d.ts +5 -5
  62. package/esm/src/types/info/accounts.d.ts.map +1 -1
  63. package/esm/src/types/info/delegations.d.ts +1 -1
  64. package/esm/src/types/info/delegations.d.ts.map +1 -1
  65. package/esm/src/types/info/orders.d.ts +1 -1
  66. package/esm/src/types/info/orders.d.ts.map +1 -1
  67. package/esm/src/types/info/requests.d.ts +49 -96
  68. package/esm/src/types/info/requests.d.ts.map +1 -1
  69. package/esm/src/types/subscriptions/requests.d.ts +72 -18
  70. package/esm/src/types/subscriptions/requests.d.ts.map +1 -1
  71. package/esm/src/types/subscriptions/responses.d.ts +2 -0
  72. package/esm/src/types/subscriptions/responses.d.ts.map +1 -1
  73. package/package.json +12 -8
  74. package/script/mod.d.ts +1 -1
  75. package/script/mod.d.ts.map +1 -1
  76. package/script/mod.js +13 -23
  77. package/script/src/base.d.ts +4 -1
  78. package/script/src/base.d.ts.map +1 -1
  79. package/script/src/base.js +10 -20
  80. package/script/src/clients/exchange.d.ts +420 -368
  81. package/script/src/clients/exchange.d.ts.map +1 -1
  82. package/script/src/clients/exchange.js +2000 -1840
  83. package/script/src/clients/info.d.ts +137 -41
  84. package/script/src/clients/info.d.ts.map +1 -1
  85. package/script/src/clients/info.js +1296 -1210
  86. package/script/src/clients/multiSign.d.ts +406 -484
  87. package/script/src/clients/multiSign.d.ts.map +1 -1
  88. package/script/src/clients/multiSign.js +2043 -2148
  89. package/script/src/clients/subscription.d.ts +38 -3
  90. package/script/src/clients/subscription.d.ts.map +1 -1
  91. package/script/src/clients/subscription.js +568 -545
  92. package/script/src/signing/_signTypedData/ethers.d.ts +33 -0
  93. package/script/src/signing/_signTypedData/ethers.d.ts.map +1 -0
  94. package/script/src/signing/_signTypedData/ethers.js +16 -0
  95. package/script/src/signing/_signTypedData/mod.d.ts +35 -0
  96. package/script/src/signing/_signTypedData/mod.d.ts.map +1 -0
  97. package/script/src/signing/_signTypedData/mod.js +67 -0
  98. package/script/src/signing/_signTypedData/private_key.d.ts +26 -0
  99. package/script/src/signing/_signTypedData/private_key.d.ts.map +1 -0
  100. package/script/src/signing/_signTypedData/private_key.js +148 -0
  101. package/script/src/signing/_signTypedData/viem.d.ts +23 -0
  102. package/script/src/signing/_signTypedData/viem.d.ts.map +1 -0
  103. package/script/src/signing/_signTypedData/viem.js +9 -0
  104. package/script/src/signing/_signTypedData/window.d.ts +29 -0
  105. package/script/src/signing/_signTypedData/window.d.ts.map +1 -0
  106. package/script/src/signing/_signTypedData/window.js +34 -0
  107. package/script/src/signing/_sorter.d.ts +128 -0
  108. package/script/src/signing/_sorter.d.ts.map +1 -0
  109. package/script/src/signing/_sorter.js +698 -0
  110. package/script/src/signing/mod.d.ts +272 -0
  111. package/script/src/signing/mod.d.ts.map +1 -0
  112. package/script/src/signing/mod.js +331 -0
  113. package/script/src/transports/base.d.ts +1 -1
  114. package/script/src/transports/base.d.ts.map +1 -1
  115. package/script/src/transports/base.js +11 -21
  116. package/script/src/transports/http/http_transport.d.ts +9 -15
  117. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  118. package/script/src/transports/http/http_transport.js +97 -102
  119. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +1 -1
  120. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  121. package/script/src/transports/websocket/_hyperliquid_event_target.js +51 -61
  122. package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -1
  123. package/script/src/transports/websocket/_reconnecting_websocket.js +271 -268
  124. package/script/src/transports/websocket/_websocket_async_request.d.ts +0 -9
  125. package/script/src/transports/websocket/_websocket_async_request.d.ts.map +1 -1
  126. package/script/src/transports/websocket/_websocket_async_request.js +157 -174
  127. package/script/src/transports/websocket/websocket_transport.d.ts +8 -4
  128. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  129. package/script/src/transports/websocket/websocket_transport.js +209 -189
  130. package/script/src/types/exchange/requests.d.ts +27 -51
  131. package/script/src/types/exchange/requests.d.ts.map +1 -1
  132. package/script/src/types/exchange/requests.js +2 -12
  133. package/script/src/types/exchange/responses.js +2 -12
  134. package/script/src/types/explorer/requests.d.ts +5 -8
  135. package/script/src/types/explorer/requests.d.ts.map +1 -1
  136. package/script/src/types/explorer/requests.js +2 -12
  137. package/script/src/types/explorer/responses.js +2 -12
  138. package/script/src/types/info/accounts.d.ts +5 -5
  139. package/script/src/types/info/accounts.d.ts.map +1 -1
  140. package/script/src/types/info/accounts.js +2 -12
  141. package/script/src/types/info/assets.js +2 -12
  142. package/script/src/types/info/delegations.d.ts +1 -1
  143. package/script/src/types/info/delegations.d.ts.map +1 -1
  144. package/script/src/types/info/delegations.js +2 -12
  145. package/script/src/types/info/markets.js +2 -12
  146. package/script/src/types/info/orders.d.ts +1 -1
  147. package/script/src/types/info/orders.d.ts.map +1 -1
  148. package/script/src/types/info/orders.js +2 -12
  149. package/script/src/types/info/requests.d.ts +49 -96
  150. package/script/src/types/info/requests.d.ts.map +1 -1
  151. package/script/src/types/info/requests.js +2 -12
  152. package/script/src/types/info/vaults.js +2 -12
  153. package/script/src/types/mod.js +2 -12
  154. package/script/src/types/subscriptions/requests.d.ts +72 -18
  155. package/script/src/types/subscriptions/requests.d.ts.map +1 -1
  156. package/script/src/types/subscriptions/requests.js +2 -12
  157. package/script/src/types/subscriptions/responses.d.ts +2 -0
  158. package/script/src/types/subscriptions/responses.d.ts.map +1 -1
  159. package/script/src/types/subscriptions/responses.js +2 -12
  160. package/esm/deps/jsr.io/@derzade/typescript-event-target/1.1.1/mod.d.ts +0 -2
  161. package/esm/deps/jsr.io/@derzade/typescript-event-target/1.1.1/mod.d.ts.map +0 -1
  162. package/esm/deps/jsr.io/@derzade/typescript-event-target/1.1.1/mod.js +0 -1
  163. package/esm/deps/jsr.io/@derzade/typescript-event-target/1.1.1/src/TypedEventTarget.d.ts +0 -95
  164. package/esm/deps/jsr.io/@derzade/typescript-event-target/1.1.1/src/TypedEventTarget.d.ts.map +0 -1
  165. package/esm/deps/jsr.io/@derzade/typescript-event-target/1.1.1/src/TypedEventTarget.js +0 -10
  166. package/esm/deps/jsr.io/@std/async/1.0.13/delay.d.ts +0 -43
  167. package/esm/deps/jsr.io/@std/async/1.0.13/delay.d.ts.map +0 -1
  168. package/esm/deps/jsr.io/@std/async/1.0.13/delay.js +0 -63
  169. package/esm/deps/jsr.io/@std/bytes/1.0.6/_types.d.ts +0 -9
  170. package/esm/deps/jsr.io/@std/bytes/1.0.6/_types.d.ts.map +0 -1
  171. package/esm/deps/jsr.io/@std/bytes/1.0.6/_types.js +0 -2
  172. package/esm/deps/jsr.io/@std/bytes/1.0.6/concat.d.ts +0 -21
  173. package/esm/deps/jsr.io/@std/bytes/1.0.6/concat.d.ts.map +0 -1
  174. package/esm/deps/jsr.io/@std/bytes/1.0.6/concat.js +0 -32
  175. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts +0 -23
  176. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +0 -1
  177. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.js +0 -51
  178. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts +0 -4
  179. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +0 -1
  180. package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.js +0 -13
  181. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts +0 -9
  182. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +0 -1
  183. package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.js +0 -2
  184. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts +0 -39
  185. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +0 -1
  186. package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.js +0 -87
  187. package/esm/deps/jsr.io/@std/msgpack/1.0.3/_types.d.ts +0 -9
  188. package/esm/deps/jsr.io/@std/msgpack/1.0.3/_types.d.ts.map +0 -1
  189. package/esm/deps/jsr.io/@std/msgpack/1.0.3/_types.js +0 -2
  190. package/esm/deps/jsr.io/@std/msgpack/1.0.3/encode.d.ts +0 -39
  191. package/esm/deps/jsr.io/@std/msgpack/1.0.3/encode.d.ts.map +0 -1
  192. package/esm/deps/jsr.io/@std/msgpack/1.0.3/encode.js +0 -237
  193. package/esm/src/signing.d.ts +0 -463
  194. package/esm/src/signing.d.ts.map +0 -1
  195. package/script/deps/jsr.io/@derzade/typescript-event-target/1.1.1/mod.d.ts +0 -2
  196. package/script/deps/jsr.io/@derzade/typescript-event-target/1.1.1/mod.d.ts.map +0 -1
  197. package/script/deps/jsr.io/@derzade/typescript-event-target/1.1.1/mod.js +0 -27
  198. package/script/deps/jsr.io/@derzade/typescript-event-target/1.1.1/src/TypedEventTarget.d.ts +0 -95
  199. package/script/deps/jsr.io/@derzade/typescript-event-target/1.1.1/src/TypedEventTarget.d.ts.map +0 -1
  200. package/script/deps/jsr.io/@derzade/typescript-event-target/1.1.1/src/TypedEventTarget.js +0 -24
  201. package/script/deps/jsr.io/@std/async/1.0.13/delay.d.ts +0 -43
  202. package/script/deps/jsr.io/@std/async/1.0.13/delay.d.ts.map +0 -1
  203. package/script/deps/jsr.io/@std/async/1.0.13/delay.js +0 -76
  204. package/script/deps/jsr.io/@std/bytes/1.0.6/_types.d.ts +0 -9
  205. package/script/deps/jsr.io/@std/bytes/1.0.6/_types.d.ts.map +0 -1
  206. package/script/deps/jsr.io/@std/bytes/1.0.6/_types.js +0 -13
  207. package/script/deps/jsr.io/@std/bytes/1.0.6/concat.d.ts +0 -21
  208. package/script/deps/jsr.io/@std/bytes/1.0.6/concat.d.ts.map +0 -1
  209. package/script/deps/jsr.io/@std/bytes/1.0.6/concat.js +0 -45
  210. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts +0 -23
  211. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +0 -1
  212. package/script/deps/jsr.io/@std/encoding/1.0.10/_common16.js +0 -67
  213. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts +0 -4
  214. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +0 -1
  215. package/script/deps/jsr.io/@std/encoding/1.0.10/_common_detach.js +0 -26
  216. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts +0 -9
  217. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +0 -1
  218. package/script/deps/jsr.io/@std/encoding/1.0.10/_types.js +0 -13
  219. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts +0 -39
  220. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +0 -1
  221. package/script/deps/jsr.io/@std/encoding/1.0.10/hex.js +0 -101
  222. package/script/deps/jsr.io/@std/msgpack/1.0.3/_types.d.ts +0 -9
  223. package/script/deps/jsr.io/@std/msgpack/1.0.3/_types.d.ts.map +0 -1
  224. package/script/deps/jsr.io/@std/msgpack/1.0.3/_types.js +0 -13
  225. package/script/deps/jsr.io/@std/msgpack/1.0.3/encode.d.ts +0 -39
  226. package/script/deps/jsr.io/@std/msgpack/1.0.3/encode.d.ts.map +0 -1
  227. package/script/deps/jsr.io/@std/msgpack/1.0.3/encode.js +0 -250
  228. package/script/src/signing.d.ts +0 -463
  229. package/script/src/signing.d.ts.map +0 -1
  230. package/script/src/signing.js +0 -1129
@@ -1,5 +1,5 @@
1
1
  import { HyperliquidError } from "../base.js";
2
- import { actionSorter, isAbstractEthersSigner, isAbstractEthersV5Signer, isAbstractViemWalletClient, isAbstractWindowEthereum, signL1Action, signMultiSigAction, signUserSignedAction, userSignedActionEip712Types, } from "../signing.js";
2
+ import { actionSorter, isAbstractEthersSigner, isAbstractEthersV5Signer, isAbstractViemWalletClient, isAbstractWindowEthereum, signL1Action, signMultiSigAction, signUserSignedAction, userSignedActionEip712Types, } from "../signing/mod.js";
3
3
  /** Error thrown when the API returns an error response. */
4
4
  export class ApiRequestError extends HyperliquidError {
5
5
  response;
@@ -70,46 +70,58 @@ export class ExchangeClient {
70
70
  * Initialises a new instance.
71
71
  * @param args - The parameters for the client.
72
72
  *
73
- * @example Private key via [viem](https://viem.sh/docs/clients/wallet#local-accounts-private-key-mnemonic-etc)
73
+ * @example Private key directly
74
+ * ```ts
75
+ * import * as hl from "@nktkas/hyperliquid";
76
+ *
77
+ * const privateKey = "0x...";
78
+ *
79
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
80
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
81
+ * ```
82
+ *
83
+ * @example [Viem](https://viem.sh/docs/clients/wallet#local-accounts-private-key-mnemonic-etc)
74
84
  * ```ts
75
85
  * import * as hl from "@nktkas/hyperliquid";
76
86
  * import { privateKeyToAccount } from "viem/accounts";
77
87
  *
78
- * const wallet = privateKeyToAccount("0x...");
88
+ * const account = privateKeyToAccount("0x...");
79
89
  *
80
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
81
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
90
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
91
+ * const exchClient = new hl.ExchangeClient({ wallet: account, transport });
82
92
  * ```
83
93
  *
84
- * @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)
94
+ * @example [ethers.js](https://docs.ethers.org/v6/api/wallet/#Wallet) or [ethers.js v5](https://docs.ethers.org/v5/api/signer/#Wallet)
85
95
  * ```ts
86
96
  * import * as hl from "@nktkas/hyperliquid";
87
97
  * import { ethers } from "ethers";
88
98
  *
89
99
  * const wallet = new ethers.Wallet("0x...");
90
100
  *
91
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
101
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
92
102
  * const exchClient = new hl.ExchangeClient({ wallet, transport });
93
103
  * ```
94
104
  *
95
- * @example External wallet (e.g. MetaMask) via [viem](https://viem.sh/docs/clients/wallet#optional-hoist-the-account)
105
+ * @example External wallet (e.g. MetaMask) via [viem](https://viem.sh/docs/clients/wallet)
96
106
  * ```ts
97
107
  * import * as hl from "@nktkas/hyperliquid";
98
108
  * import { createWalletClient, custom } from "viem";
99
109
  *
100
- * const [account] = await window.ethereum.request({ method: "eth_requestAccounts" });
101
- * const wallet = createWalletClient({ account, transport: custom(window.ethereum) });
110
+ * const ethereum = (window as any).ethereum;
111
+ * const [account] = await ethereum.request({ method: "eth_requestAccounts" });
112
+ * const wallet = createWalletClient({ account, transport: custom(ethereum) });
102
113
  *
103
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
114
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
104
115
  * const exchClient = new hl.ExchangeClient({ wallet, transport });
105
116
  * ```
106
117
  *
107
- * @example External wallet (e.g. MetaMask) via `window.ethereum` directly
118
+ * @example External wallet (e.g. MetaMask) via [`window.ethereum`](https://eips.ethereum.org/EIPS/eip-1193)
108
119
  * ```ts
109
120
  * import * as hl from "@nktkas/hyperliquid";
110
121
  *
111
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
112
- * const exchClient = new hl.ExchangeClient({ wallet: window.ethereum, transport });
122
+ * const ethereum = (window as any).ethereum;
123
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
124
+ * const exchClient = new hl.ExchangeClient({ wallet: ethereum, transport });
113
125
  * ```
114
126
  */
115
127
  constructor(args) {
@@ -126,19 +138,20 @@ export class ExchangeClient {
126
138
  * @param args - The parameters for the request.
127
139
  * @param signal - An optional abort signal
128
140
  * @returns Successful response without specific data.
129
- * @throws {ApiRequestError} When the API returns an error response.
141
+ *
142
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
143
+ * @throws {TransportError} When the transport layer throws an error.
130
144
  *
131
145
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-an-api-wallet
132
146
  * @example
133
147
  * ```ts
134
148
  * import * as hl from "@nktkas/hyperliquid";
135
- * import { privateKeyToAccount } from "viem/accounts";
136
149
  *
137
- * const wallet = privateKeyToAccount("0x...");
138
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
139
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
150
+ * const privateKey = "0x..."; // or `viem`, `ethers`
151
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
152
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
140
153
  *
141
- * const data = await exchClient.approveAgent({ agentAddress: "0x...", agentName: "agentName" });
154
+ * await exchClient.approveAgent({ agentAddress: "0x...", agentName: "..." });
142
155
  * ```
143
156
  */
144
157
  async approveAgent(args, signal) {
@@ -146,44 +159,45 @@ export class ExchangeClient {
146
159
  const { ...actionArgs } = args;
147
160
  // Construct an action
148
161
  const nonce = await this.nonceManager();
149
- const action = {
150
- ...actionArgs,
151
- agentName: args.agentName ?? "",
162
+ const action = actionSorter.approveAgent({
152
163
  type: "approveAgent",
153
164
  hyperliquidChain: this._getHyperliquidChain(),
154
165
  signatureChainId: await this._getSignatureChainId(),
155
166
  nonce,
156
- };
167
+ ...actionArgs,
168
+ });
157
169
  // Sign the action
158
170
  const signature = await signUserSignedAction({
159
171
  wallet: this.wallet,
160
172
  action,
161
173
  types: userSignedActionEip712Types[action.type],
162
- chainId: parseInt(action.signatureChainId, 16),
163
174
  });
164
175
  if (action.agentName === "")
165
176
  action.agentName = null;
166
177
  // Send a request
167
- return await this._request({ action, signature, nonce }, signal);
178
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
179
+ this._validateResponse(response);
180
+ return response;
168
181
  }
169
182
  /**
170
183
  * Approve a maximum fee rate for a builder.
171
184
  * @param args - The parameters for the request.
172
185
  * @param signal - An optional abort signal.
173
186
  * @returns Successful response without specific data.
174
- * @throws {ApiRequestError} When the API returns an error response.
187
+ *
188
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
189
+ * @throws {TransportError} When the transport layer throws an error.
175
190
  *
176
191
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-a-builder-fee
177
192
  * @example
178
193
  * ```ts
179
194
  * import * as hl from "@nktkas/hyperliquid";
180
- * import { privateKeyToAccount } from "viem/accounts";
181
195
  *
182
- * const wallet = privateKeyToAccount("0x...");
183
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
184
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
196
+ * const privateKey = "0x..."; // or `viem`, `ethers`
197
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
198
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
185
199
  *
186
- * const data = await exchClient.approveBuilderFee({ maxFeeRate: "0.01%", builder: "0x..." });
200
+ * await exchClient.approveBuilderFee({ maxFeeRate: "0.01%", builder: "0x..." });
187
201
  * ```
188
202
  */
189
203
  async approveBuilderFee(args, signal) {
@@ -191,57 +205,56 @@ export class ExchangeClient {
191
205
  const { ...actionArgs } = args;
192
206
  // Construct an action
193
207
  const nonce = await this.nonceManager();
194
- const action = {
195
- ...actionArgs,
208
+ const action = actionSorter.approveBuilderFee({
196
209
  type: "approveBuilderFee",
197
210
  hyperliquidChain: this._getHyperliquidChain(),
198
211
  signatureChainId: await this._getSignatureChainId(),
199
212
  nonce,
200
- };
213
+ ...actionArgs,
214
+ });
201
215
  // Sign the action
202
216
  const signature = await signUserSignedAction({
203
217
  wallet: this.wallet,
204
218
  action,
205
219
  types: userSignedActionEip712Types[action.type],
206
- chainId: parseInt(action.signatureChainId, 16),
207
220
  });
208
221
  // Send a request
209
- return await this._request({ action, signature, nonce }, signal);
222
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
223
+ this._validateResponse(response);
224
+ return response;
210
225
  }
211
226
  /**
212
227
  * Modify multiple orders.
213
228
  * @param args - The parameters for the request.
214
229
  * @param signal - An optional abort signal.
215
230
  * @returns Successful variant of {@link OrderResponse} without error statuses.
216
- * @throws {ApiRequestError} When the API returns an error response.
231
+ *
232
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
233
+ * @throws {TransportError} When the transport layer throws an error.
217
234
  *
218
235
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-multiple-orders
219
236
  * @example
220
237
  * ```ts
221
238
  * import * as hl from "@nktkas/hyperliquid";
222
- * import { privateKeyToAccount } from "viem/accounts";
223
239
  *
224
- * const wallet = privateKeyToAccount("0x...");
225
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
226
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
240
+ * const privateKey = "0x..."; // or `viem`, `ethers`
241
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
242
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
227
243
  *
228
244
  * const data = await exchClient.batchModify({
229
- * modifies: [{
230
- * oid: 123,
231
- * order: {
232
- * a: 0, // Asset index
233
- * b: true, // Buy order
234
- * p: "31000", // New price
235
- * s: "0.2", // New size
236
- * r: false, // Not reduce-only
237
- * t: {
238
- * limit: {
239
- * tif: "Gtc", // Good-til-cancelled
240
- * },
245
+ * modifies: [
246
+ * {
247
+ * oid: 123,
248
+ * order: {
249
+ * a: 0,
250
+ * b: true,
251
+ * p: "31000",
252
+ * s: "0.2",
253
+ * r: false,
254
+ * t: { limit: { tif: "Gtc" } },
241
255
  * },
242
- * c: "0x...", // Client Order ID (optional)
243
256
  * },
244
- * }],
257
+ * ],
245
258
  * });
246
259
  * ```
247
260
  */
@@ -250,44 +263,43 @@ export class ExchangeClient {
250
263
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
251
264
  // Construct an action
252
265
  const nonce = await this.nonceManager();
253
- const action = {
254
- type: "batchModify",
255
- ...actionArgs,
256
- };
266
+ const action = actionSorter.batchModify({ type: "batchModify", ...actionArgs });
257
267
  // Sign the action
258
268
  const signature = await signL1Action({
259
269
  wallet: this.wallet,
260
- action: actionSorter[action.type](action),
270
+ action,
261
271
  nonce,
262
272
  isTestnet: this.isTestnet,
263
273
  vaultAddress,
264
274
  expiresAfter,
265
275
  });
266
276
  // Send a request
267
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
277
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
278
+ this._validateResponse(response);
279
+ return response;
268
280
  }
269
281
  /**
270
282
  * Cancel order(s).
271
283
  * @param args - The parameters for the request.
272
284
  * @param signal - An optional abort signal.
273
285
  * @returns Successful variant of {@link CancelResponse} without error statuses.
274
- * @throws {ApiRequestError} When the API returns an error response.
286
+ *
287
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
288
+ * @throws {TransportError} When the transport layer throws an error.
275
289
  *
276
290
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s
277
291
  * @example
278
292
  * ```ts
279
293
  * import * as hl from "@nktkas/hyperliquid";
280
- * import { privateKeyToAccount } from "viem/accounts";
281
294
  *
282
- * const wallet = privateKeyToAccount("0x...");
283
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
284
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
295
+ * const privateKey = "0x..."; // or `viem`, `ethers`
296
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
297
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
285
298
  *
286
299
  * const data = await exchClient.cancel({
287
- * cancels: [{
288
- * a: 0, // Asset index
289
- * o: 123, // Order ID
290
- * }],
300
+ * cancels: [
301
+ * { a: 0, o: 123 },
302
+ * ],
291
303
  * });
292
304
  * ```
293
305
  */
@@ -296,38 +308,38 @@ export class ExchangeClient {
296
308
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
297
309
  // Construct an action
298
310
  const nonce = await this.nonceManager();
299
- const action = {
300
- type: "cancel",
301
- ...actionArgs,
302
- };
311
+ const action = actionSorter.cancel({ type: "cancel", ...actionArgs });
303
312
  // Sign the action
304
313
  const signature = await signL1Action({
305
314
  wallet: this.wallet,
306
- action: actionSorter[action.type](action),
315
+ action,
307
316
  nonce,
308
317
  isTestnet: this.isTestnet,
309
318
  vaultAddress,
310
319
  expiresAfter,
311
320
  });
312
321
  // Send a request
313
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
322
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
323
+ this._validateResponse(response);
324
+ return response;
314
325
  }
315
326
  /**
316
327
  * Cancel order(s) by cloid.
317
328
  * @param args - The parameters for the request.
318
329
  * @param signal - An optional abort signal.
319
330
  * @returns Successful variant of {@link CancelResponse} without error statuses.
320
- * @throws {ApiRequestError} When the API returns an error response.
331
+ *
332
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
333
+ * @throws {TransportError} When the transport layer throws an error.
321
334
  *
322
335
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
323
336
  * @example
324
337
  * ```ts
325
338
  * import * as hl from "@nktkas/hyperliquid";
326
- * import { privateKeyToAccount } from "viem/accounts";
327
339
  *
328
- * const wallet = privateKeyToAccount("0x...");
329
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
330
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
340
+ * const privateKey = "0x..."; // or `viem`, `ethers`
341
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
342
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
331
343
  *
332
344
  * const data = await exchClient.cancelByCloid({
333
345
  * cancels: [
@@ -341,40 +353,40 @@ export class ExchangeClient {
341
353
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
342
354
  // Construct an action
343
355
  const nonce = await this.nonceManager();
344
- const action = {
345
- type: "cancelByCloid",
346
- ...actionArgs,
347
- };
356
+ const action = actionSorter.cancelByCloid({ type: "cancelByCloid", ...actionArgs });
348
357
  // Sign the action
349
358
  const signature = await signL1Action({
350
359
  wallet: this.wallet,
351
- action: actionSorter[action.type](action),
360
+ action,
352
361
  nonce,
353
362
  isTestnet: this.isTestnet,
354
363
  vaultAddress,
355
364
  expiresAfter,
356
365
  });
357
366
  // Send a request
358
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
367
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
368
+ this._validateResponse(response);
369
+ return response;
359
370
  }
360
371
  /**
361
372
  * Transfer native token from the user's spot account into staking for delegating to validators.
362
373
  * @param args - The parameters for the request.
363
374
  * @param signal - An optional abort signal.
364
375
  * @returns Successful response without specific data.
365
- * @throws {ApiRequestError} When the API returns an error response.
376
+ *
377
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
378
+ * @throws {TransportError} When the transport layer throws an error.
366
379
  *
367
380
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-into-staking
368
381
  * @example
369
382
  * ```ts
370
383
  * import * as hl from "@nktkas/hyperliquid";
371
- * import { privateKeyToAccount } from "viem/accounts";
372
384
  *
373
- * const wallet = privateKeyToAccount("0x...");
374
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
375
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
385
+ * const privateKey = "0x..."; // or `viem`, `ethers`
386
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
387
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
376
388
  *
377
- * const data = await exchClient.cDeposit({ wei: 1 * 1e8 });
389
+ * await exchClient.cDeposit({ wei: 1 * 1e8 });
378
390
  * ```
379
391
  */
380
392
  async cDeposit(args, signal) {
@@ -382,122 +394,131 @@ export class ExchangeClient {
382
394
  const { ...actionArgs } = args;
383
395
  // Construct an action
384
396
  const nonce = await this.nonceManager();
385
- const action = {
386
- ...actionArgs,
397
+ const action = actionSorter.cDeposit({
387
398
  type: "cDeposit",
388
399
  hyperliquidChain: this._getHyperliquidChain(),
389
400
  signatureChainId: await this._getSignatureChainId(),
390
401
  nonce,
391
- };
402
+ ...actionArgs,
403
+ });
392
404
  // Sign the action
393
405
  const signature = await signUserSignedAction({
394
406
  wallet: this.wallet,
395
407
  action,
396
408
  types: userSignedActionEip712Types[action.type],
397
- chainId: parseInt(action.signatureChainId, 16),
398
409
  });
399
410
  // Send a request
400
- return await this._request({ action, signature, nonce }, signal);
411
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
412
+ this._validateResponse(response);
413
+ return response;
401
414
  }
402
415
  /**
403
416
  * Claim rewards from referral program.
404
417
  * @param args - The parameters for the request.
405
418
  * @param signal - An optional abort signal.
406
419
  * @returns Successful response without specific data.
407
- * @throws {ApiRequestError} When the API returns an error response.
408
420
  *
409
- * @see null - no documentation
421
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
422
+ * @throws {TransportError} When the transport layer throws an error.
423
+ *
424
+ * @see null
410
425
  * @example
411
426
  * ```ts
412
427
  * import * as hl from "@nktkas/hyperliquid";
413
- * import { privateKeyToAccount } from "viem/accounts";
414
428
  *
415
- * const wallet = privateKeyToAccount("0x...");
416
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
417
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
429
+ * const privateKey = "0x..."; // or `viem`, `ethers`
430
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
431
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
418
432
  *
419
- * const data = await exchClient.claimRewards();
433
+ * await exchClient.claimRewards();
420
434
  * ```
421
435
  */
422
436
  async claimRewards(signal) {
423
437
  // Construct an action
424
438
  const nonce = await this.nonceManager();
425
- const action = {
426
- type: "claimRewards",
427
- };
439
+ const action = actionSorter.claimRewards({ type: "claimRewards" });
428
440
  // Sign the action
429
441
  const signature = await signL1Action({
430
442
  wallet: this.wallet,
431
- action: actionSorter[action.type](action),
443
+ action,
432
444
  nonce,
433
445
  isTestnet: this.isTestnet,
434
446
  });
435
447
  // Send a request
436
- return await this._request({ action, signature, nonce }, signal);
448
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
449
+ this._validateResponse(response);
450
+ return response;
437
451
  }
438
452
  /**
439
453
  * Convert a single-signature account to a multi-signature account or vice versa.
440
454
  * @param args - The parameters for the request.
441
455
  * @param signal - An optional abort signal.
442
456
  * @returns Successful response without specific data.
443
- * @throws {ApiRequestError} When the API returns an error response.
457
+ *
458
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
459
+ * @throws {TransportError} When the transport layer throws an error.
444
460
  *
445
461
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig
446
462
  * @example
447
463
  * ```ts
448
464
  * import * as hl from "@nktkas/hyperliquid";
449
- * import { privateKeyToAccount } from "viem/accounts";
450
465
  *
451
- * const wallet = privateKeyToAccount("0x...");
452
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
453
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
466
+ * const privateKey = "0x..."; // or `viem`, `ethers`
467
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
468
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
454
469
  *
455
- * const data = await exchClient.convertToMultiSigUser({ // convert to multi-sig user
470
+ * // Convert to multi-sig user
471
+ * await exchClient.convertToMultiSigUser({
456
472
  * authorizedUsers: ["0x...", "0x...", "0x..."],
457
473
  * threshold: 2,
458
474
  * });
475
+ *
476
+ * // Convert to single-sig user
477
+ * await exchClient.convertToMultiSigUser(null);
459
478
  * ```
460
479
  */
461
480
  async convertToMultiSigUser(args, signal) {
462
481
  // Destructure the parameters
463
- const { ...actionArgs } = args;
482
+ const actionArgs = args;
464
483
  // Construct an action
465
484
  const nonce = await this.nonceManager();
466
- const action = {
485
+ const action = actionSorter.convertToMultiSigUser({
467
486
  type: "convertToMultiSigUser",
468
487
  hyperliquidChain: this._getHyperliquidChain(),
469
488
  signatureChainId: await this._getSignatureChainId(),
470
489
  signers: JSON.stringify(actionArgs),
471
490
  nonce,
472
- };
491
+ });
473
492
  // Sign the action
474
493
  const signature = await signUserSignedAction({
475
494
  wallet: this.wallet,
476
495
  action,
477
496
  types: userSignedActionEip712Types[action.type],
478
- chainId: parseInt(action.signatureChainId, 16),
479
497
  });
480
498
  // Send a request
481
- return await this._request({ action, signature, nonce }, signal);
499
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
500
+ this._validateResponse(response);
501
+ return response;
482
502
  }
483
503
  /**
484
504
  * Create a sub-account.
485
505
  * @param args - The parameters for the request.
486
506
  * @param signal - An optional abort signal.
487
507
  * @returns Response for creating a sub-account.
488
- * @throws {ApiRequestError} When the API returns an error response.
489
508
  *
490
- * @see null - no documentation
509
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
510
+ * @throws {TransportError} When the transport layer throws an error.
511
+ *
512
+ * @see null
491
513
  * @example
492
514
  * ```ts
493
515
  * import * as hl from "@nktkas/hyperliquid";
494
- * import { privateKeyToAccount } from "viem/accounts";
495
516
  *
496
- * const wallet = privateKeyToAccount("0x...");
497
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
498
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
517
+ * const privateKey = "0x..."; // or `viem`, `ethers`
518
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
519
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
499
520
  *
500
- * const data = await exchClient.createSubAccount({ name: "subAccountName" });
521
+ * const data = await exchClient.createSubAccount({ name: "..." });
501
522
  * ```
502
523
  */
503
524
  async createSubAccount(args, signal) {
@@ -505,42 +526,38 @@ export class ExchangeClient {
505
526
  const { ...actionArgs } = args;
506
527
  // Construct an action
507
528
  const nonce = await this.nonceManager();
508
- const action = {
509
- type: "createSubAccount",
510
- ...actionArgs,
511
- };
529
+ const action = actionSorter.createSubAccount({ type: "createSubAccount", ...actionArgs });
512
530
  // Sign the action
513
531
  const signature = await signL1Action({
514
532
  wallet: this.wallet,
515
- action: actionSorter[action.type](action),
533
+ action,
516
534
  nonce,
517
535
  isTestnet: this.isTestnet,
518
536
  });
519
537
  // Send a request
520
- return await this._request({ action, signature, nonce }, signal);
538
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
539
+ this._validateResponse(response);
540
+ return response;
521
541
  }
522
542
  /**
523
543
  * Create a vault.
524
544
  * @param args - The parameters for the request.
525
545
  * @param signal - An optional abort signal.
526
546
  * @returns Response for creating a vault.
527
- * @throws {ApiRequestError} When the API returns an error response.
528
547
  *
529
- * @see null - no documentation
548
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
549
+ * @throws {TransportError} When the transport layer throws an error.
550
+ *
551
+ * @see null
530
552
  * @example
531
553
  * ```ts
532
554
  * import * as hl from "@nktkas/hyperliquid";
533
- * import { privateKeyToAccount } from "viem/accounts";
534
555
  *
535
- * const wallet = privateKeyToAccount("0x...");
536
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
537
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
556
+ * const privateKey = "0x..."; // or `viem`, `ethers`
557
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
558
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
538
559
  *
539
- * const data = await exchClient.createVault({
540
- * name: "VaultName",
541
- * description: "Vault description",
542
- * initialUsd: 100 * 1e6,
543
- * });
560
+ * const data = await exchClient.createVault({ name: "...", description: "...", initialUsd: 100 * 1e6 });
544
561
  * ```
545
562
  */
546
563
  async createVault(args, signal) {
@@ -548,79 +565,148 @@ export class ExchangeClient {
548
565
  const { ...actionArgs } = args;
549
566
  // Construct an action
550
567
  const nonce = await this.nonceManager();
551
- const action = {
552
- type: "createVault",
553
- nonce,
554
- ...actionArgs,
555
- };
568
+ const action = actionSorter.createVault({ type: "createVault", nonce, ...actionArgs });
556
569
  // Sign the action
557
570
  const signature = await signL1Action({
558
571
  wallet: this.wallet,
559
- action: actionSorter[action.type](action),
572
+ action,
560
573
  nonce,
561
574
  isTestnet: this.isTestnet,
562
575
  });
563
576
  // Send a request
564
- return await this._request({ action, signature, nonce }, signal);
577
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
578
+ this._validateResponse(response);
579
+ return response;
565
580
  }
581
+ /**
582
+ * Jail or unjail self as a validator signer.
583
+ * @param args - The parameters for the request.
584
+ * @param signal - An optional abort signal.
585
+ * @returns Successful response without specific data.
586
+ *
587
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
588
+ * @throws {TransportError} When the transport layer throws an error.
589
+ *
590
+ * @see null
591
+ * @example
592
+ * ```ts
593
+ * import * as hl from "@nktkas/hyperliquid";
594
+ *
595
+ * const privateKey = "0x..."; // or `viem`, `ethers`
596
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
597
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
598
+ *
599
+ * // Jail self
600
+ * await exchClient.cSignerAction({ jailSelf: null });
601
+ *
602
+ * // Unjail self
603
+ * await exchClient.cSignerAction({ unjailSelf: null });
604
+ * ```
605
+ */
566
606
  async cSignerAction(args, signal) {
567
607
  // Destructure the parameters
568
608
  const { expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
569
609
  // Construct an action
570
610
  const nonce = await this.nonceManager();
571
- const action = {
572
- type: "CSignerAction",
573
- ...actionArgs,
574
- };
611
+ const action = actionSorter.CSignerAction({ type: "CSignerAction", ...actionArgs });
575
612
  // Sign the action
576
613
  const signature = await signL1Action({
577
614
  wallet: this.wallet,
578
- action: actionSorter[action.type](action),
615
+ action,
579
616
  nonce,
580
617
  isTestnet: this.isTestnet,
581
618
  expiresAfter,
582
619
  });
583
620
  // Send a request
584
- return await this._request({ action, signature, nonce, expiresAfter }, signal);
621
+ const response = await this.transport.request("exchange", { action, signature, nonce, expiresAfter }, signal);
622
+ this._validateResponse(response);
623
+ return response;
585
624
  }
625
+ /**
626
+ * Action related to validator management.
627
+ * @param args - The parameters for the request.
628
+ * @param signal - An optional abort signal.
629
+ * @returns Successful response without specific data.
630
+ *
631
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
632
+ * @throws {TransportError} When the transport layer throws an error.
633
+ *
634
+ * @see null
635
+ * @example
636
+ * ```ts
637
+ * import * as hl from "@nktkas/hyperliquid";
638
+ *
639
+ * const privateKey = "0x..."; // or `viem`, `ethers`
640
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
641
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
642
+ *
643
+ * // Change validator profile
644
+ * await exchClient.cValidatorAction({
645
+ * changeProfile: {
646
+ * name: "...",
647
+ * description: "...",
648
+ * unjailed: true,
649
+ * }
650
+ * });
651
+ *
652
+ * // Register a new validator
653
+ * await exchClient.cValidatorAction({
654
+ * register: {
655
+ * profile: {
656
+ * node_ip: { Ip: "1.2.3.4" },
657
+ * name: "...",
658
+ * description: "...",
659
+ * delegations_disabled: true,
660
+ * commission_bps: 1,
661
+ * signer: "0x...",
662
+ * },
663
+ * unjailed: false,
664
+ * initial_wei: 1,
665
+ * },
666
+ * });
667
+ *
668
+ * // Unregister a validator
669
+ * await exchClient.cValidatorAction({ unregister: null });
670
+ * ```
671
+ */
586
672
  async cValidatorAction(args, signal) {
587
673
  // Destructure the parameters
588
674
  const { expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
589
675
  // Construct an action
590
676
  const nonce = await this.nonceManager();
591
- const action = {
592
- type: "CValidatorAction",
593
- ...actionArgs,
594
- };
677
+ const action = actionSorter.CValidatorAction({ type: "CValidatorAction", ...actionArgs });
595
678
  // Sign the action
596
679
  const signature = await signL1Action({
597
680
  wallet: this.wallet,
598
- action: actionSorter[action.type](action),
681
+ action,
599
682
  nonce,
600
683
  isTestnet: this.isTestnet,
601
684
  expiresAfter,
602
685
  });
603
686
  // Send a request
604
- return await this._request({ action, signature, nonce, expiresAfter }, signal);
687
+ const response = await this.transport.request("exchange", { action, signature, nonce, expiresAfter }, signal);
688
+ this._validateResponse(response);
689
+ return response;
605
690
  }
606
691
  /**
607
692
  * Transfer native token from staking into the user's spot account.
608
693
  * @param args - The parameters for the request.
609
694
  * @param signal - An optional abort signal.
610
695
  * @returns Successful response without specific data.
611
- * @throws {ApiRequestError} When the API returns an error response.
696
+ *
697
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
698
+ * @throws {TransportError} When the transport layer throws an error.
612
699
  *
613
700
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#withdraw-from-staking
614
701
  * @example
615
702
  * ```ts
616
703
  * import * as hl from "@nktkas/hyperliquid";
617
- * import { privateKeyToAccount } from "viem/accounts";
618
704
  *
619
- * const wallet = privateKeyToAccount("0x...");
620
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
621
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
705
+ * const privateKey = "0x..."; // or `viem`, `ethers`
706
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
707
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
622
708
  *
623
- * const data = await exchClient.cWithdraw({ wei: 1 * 1e8 });
709
+ * await exchClient.cWithdraw({ wei: 1 * 1e8 });
624
710
  * ```
625
711
  */
626
712
  async cWithdraw(args, signal) {
@@ -628,39 +714,41 @@ export class ExchangeClient {
628
714
  const { ...actionArgs } = args;
629
715
  // Construct an action
630
716
  const nonce = await this.nonceManager();
631
- const action = {
632
- ...actionArgs,
717
+ const action = actionSorter.cWithdraw({
633
718
  type: "cWithdraw",
634
719
  hyperliquidChain: this._getHyperliquidChain(),
635
720
  signatureChainId: await this._getSignatureChainId(),
636
721
  nonce,
637
- };
722
+ ...actionArgs,
723
+ });
638
724
  // Sign the action
639
725
  const signature = await signUserSignedAction({
640
726
  wallet: this.wallet,
641
727
  action,
642
728
  types: userSignedActionEip712Types[action.type],
643
- chainId: parseInt(action.signatureChainId, 16),
644
729
  });
645
730
  // Send a request
646
- return await this._request({ action, signature, nonce }, signal);
731
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
732
+ this._validateResponse(response);
733
+ return response;
647
734
  }
648
735
  /**
649
736
  * Configure block type for EVM transactions.
650
737
  * @param args - The parameters for the request.
651
738
  * @param signal - An optional abort signal.
652
739
  * @returns Response for creating a sub-account.
653
- * @throws {ApiRequestError} When the API returns an error response.
740
+ *
741
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
742
+ * @throws {TransportError} When the transport layer throws an error.
654
743
  *
655
744
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm/dual-block-architecture
656
745
  * @example
657
746
  * ```ts
658
747
  * import * as hl from "@nktkas/hyperliquid";
659
- * import { privateKeyToAccount } from "viem/accounts";
660
748
  *
661
- * const wallet = privateKeyToAccount("0x...");
662
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
663
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
749
+ * const privateKey = "0x..."; // or `viem`, `ethers`
750
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
751
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
664
752
  *
665
753
  * const data = await exchClient.evmUserModify({ usingBigBlocks: true });
666
754
  * ```
@@ -670,51 +758,47 @@ export class ExchangeClient {
670
758
  const { ...actionArgs } = args;
671
759
  // Construct an action
672
760
  const nonce = await this.nonceManager();
673
- const action = {
674
- type: "evmUserModify",
675
- ...actionArgs,
676
- };
761
+ const action = actionSorter.evmUserModify({ type: "evmUserModify", ...actionArgs });
677
762
  // Sign the action
678
763
  const signature = await signL1Action({
679
764
  wallet: this.wallet,
680
- action: actionSorter[action.type](action),
765
+ action,
681
766
  nonce,
682
767
  isTestnet: this.isTestnet,
683
768
  });
684
769
  // Send a request
685
- return await this._request({ action, signature, nonce }, signal);
770
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
771
+ this._validateResponse(response);
772
+ return response;
686
773
  }
687
774
  /**
688
775
  * Modify an order.
689
776
  * @param args - The parameters for the request.
690
777
  * @param signal - An optional abort signal.
691
778
  * @returns Successful response without specific data.
692
- * @throws {ApiRequestError} When the API returns an error response.
779
+ *
780
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
781
+ * @throws {TransportError} When the transport layer throws an error.
693
782
  *
694
783
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-an-order
695
784
  * @example
696
785
  * ```ts
697
786
  * import * as hl from "@nktkas/hyperliquid";
698
- * import { privateKeyToAccount } from "viem/accounts";
699
787
  *
700
- * const wallet = privateKeyToAccount("0x...");
701
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
702
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
788
+ * const privateKey = "0x..."; // or `viem`, `ethers`
789
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
790
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
703
791
  *
704
- * const data = await exchClient.modify({
792
+ * await exchClient.modify({
705
793
  * oid: 123,
706
794
  * order: {
707
- * a: 0, // Asset index
708
- * b: true, // Buy order
709
- * p: "31000", // New price
710
- * s: "0.2", // New size
711
- * r: false, // Not reduce-only
712
- * t: {
713
- * limit: {
714
- * tif: "Gtc", // Good-til-cancelled
715
- * },
716
- * },
717
- * c: "0x...", // Client Order ID (optional)
795
+ * a: 0,
796
+ * b: true,
797
+ * p: "31000",
798
+ * s: "0.2",
799
+ * r: false,
800
+ * t: { limit: { tif: "Gtc" } },
801
+ * c: "0x...",
718
802
  * },
719
803
  * });
720
804
  * ```
@@ -724,49 +808,54 @@ export class ExchangeClient {
724
808
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
725
809
  // Construct an action
726
810
  const nonce = await this.nonceManager();
727
- const action = {
728
- type: "modify",
729
- ...actionArgs,
730
- };
811
+ const action = actionSorter.modify({ type: "modify", ...actionArgs });
731
812
  // Sign the action
732
813
  const signature = await signL1Action({
733
814
  wallet: this.wallet,
734
- action: actionSorter[action.type](action),
815
+ action,
735
816
  nonce,
736
817
  isTestnet: this.isTestnet,
737
818
  vaultAddress,
738
819
  expiresAfter,
739
820
  });
740
821
  // Send a request
741
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
822
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
823
+ this._validateResponse(response);
824
+ return response;
742
825
  }
743
826
  /**
744
827
  * A multi-signature request.
745
828
  * @param args - The parameters for the request.
746
829
  * @param signal - An optional abort signal.
747
- * @returns Successful response without specific data.
748
- * @throws {ApiRequestError} When the API returns an error response.
830
+ * @returns Any successful response.
831
+ *
832
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
833
+ * @throws {TransportError} When the transport layer throws an error.
749
834
  *
750
835
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig
751
836
  * @example
752
837
  * ```ts
753
838
  * import * as hl from "@nktkas/hyperliquid";
839
+ * import { actionSorter, signL1Action } from "@nktkas/hyperliquid/signing";
754
840
  * import { privateKeyToAccount } from "viem/accounts";
755
841
  *
756
- * const wallet = privateKeyToAccount("0x...");
757
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
758
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
842
+ * const wallet = privateKeyToAccount("0x..."); // or any other wallet libraries
843
+ * const multiSigUser = "0x...";
759
844
  *
760
- * const multiSigUser = "0x..."; // Multi-sig user address
845
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
846
+ * const exchClient = new hl.ExchangeClient({ wallet, transport });
761
847
  *
762
848
  * const nonce = Date.now();
763
- * const action = { type: "scheduleCancel", time: Date.now() + 10000 };
849
+ * const action = {
850
+ * type: "scheduleCancel",
851
+ * time: Date.now() + 10000,
852
+ * } as const;
764
853
  *
765
- * const signature = await hl.signL1Action({
854
+ * // Create the required number of signatures
855
+ * const signature = await signL1Action({
766
856
  * wallet,
767
- * action: [multiSigUser.toLowerCase(), signer1.address.toLowerCase(), action],
857
+ * action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), actionSorter[action.type](action)],
768
858
  * nonce,
769
- * isTestnet: true,
770
859
  * });
771
860
  *
772
861
  * const data = await exchClient.multiSig({
@@ -784,58 +873,59 @@ export class ExchangeClient {
784
873
  // Destructure the parameters
785
874
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), nonce, ...actionArgs } = args;
786
875
  // Construct an action
787
- const action = {
876
+ const action = actionSorter.multiSig({
788
877
  type: "multiSig",
789
878
  signatureChainId: await this._getSignatureChainId(),
790
879
  ...actionArgs,
791
- };
880
+ });
792
881
  // Sign the action
793
- const actionForMultiSig = actionSorter[action.type](action);
794
- delete actionForMultiSig.type;
882
+ // deno-lint-ignore no-explicit-any
883
+ const actionWithoutType = structuredClone(action);
884
+ delete actionWithoutType.type;
795
885
  const signature = await signMultiSigAction({
796
886
  wallet: this.wallet,
797
- action: actionForMultiSig,
887
+ action: actionWithoutType,
798
888
  nonce,
889
+ isTestnet: this.isTestnet,
799
890
  vaultAddress,
800
891
  expiresAfter,
801
- hyperliquidChain: this._getHyperliquidChain(),
802
- signatureChainId: action.signatureChainId,
803
892
  });
804
893
  // Send a request
805
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
894
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
895
+ this._validateResponse(response);
896
+ return response;
806
897
  }
807
898
  /**
808
899
  * Place an order(s).
809
900
  * @param args - The parameters for the request.
810
901
  * @param signal - An optional abort signal.
811
902
  * @returns Successful variant of {@link OrderResponse} without error statuses.
812
- * @throws {ApiRequestError} When the API returns an error response.
903
+ *
904
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
905
+ * @throws {TransportError} When the transport layer throws an error.
813
906
  *
814
907
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order
815
908
  * @example
816
909
  * ```ts
817
910
  * import * as hl from "@nktkas/hyperliquid";
818
- * import { privateKeyToAccount } from "viem/accounts";
819
911
  *
820
- * const wallet = privateKeyToAccount("0x...");
821
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
822
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
912
+ * const privateKey = "0x..."; // or `viem`, `ethers`
913
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
914
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
823
915
  *
824
916
  * const data = await exchClient.order({
825
- * orders: [{
826
- * a: 0, // Asset index
827
- * b: true, // Buy order
828
- * p: "30000", // Price
829
- * s: "0.1", // Size
830
- * r: false, // Not reduce-only
831
- * t: {
832
- * limit: {
833
- * tif: "Gtc", // Good-til-cancelled
834
- * },
917
+ * orders: [
918
+ * {
919
+ * a: 0,
920
+ * b: true,
921
+ * p: "30000",
922
+ * s: "0.1",
923
+ * r: false,
924
+ * t: { limit: { tif: "Gtc" } },
925
+ * c: "0x...",
835
926
  * },
836
- * c: "0x...", // Client Order ID (optional)
837
- * }],
838
- * grouping: "na", // No grouping
927
+ * ],
928
+ * grouping: "na",
839
929
  * });
840
930
  * ```
841
931
  */
@@ -844,64 +934,91 @@ export class ExchangeClient {
844
934
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
845
935
  // Construct an action
846
936
  const nonce = await this.nonceManager();
847
- const action = {
848
- type: "order",
849
- ...actionArgs,
850
- };
937
+ const action = actionSorter.order({ type: "order", ...actionArgs });
851
938
  // Sign the action
852
939
  const signature = await signL1Action({
853
940
  wallet: this.wallet,
854
- action: actionSorter[action.type](action),
941
+ action,
855
942
  nonce,
856
943
  isTestnet: this.isTestnet,
857
944
  vaultAddress,
858
945
  expiresAfter,
859
946
  });
860
947
  // Send a request
861
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
948
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
949
+ this._validateResponse(response);
950
+ return response;
862
951
  }
952
+ /**
953
+ * Deploying HIP-3 assets.
954
+ * @param args - The parameters for the request.
955
+ * @param signal - An optional abort signal.
956
+ * @returns Successful response without specific data.
957
+ *
958
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
959
+ * @throws {TransportError} When the transport layer throws an error.
960
+ *
961
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/deploying-hip-3-assets
962
+ * @example
963
+ * ```ts
964
+ * import * as hl from "@nktkas/hyperliquid";
965
+ *
966
+ * const privateKey = "0x..."; // or `viem`, `ethers`
967
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
968
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
969
+ *
970
+ * await exchClient.perpDeploy({
971
+ * registerAsset: {
972
+ * maxGas: 1000000,
973
+ * assetRequest: {
974
+ * coin: "USDC",
975
+ * szDecimals: 8,
976
+ * oraclePx: "1",
977
+ * marginTableId: 1,
978
+ * onlyIsolated: false,
979
+ * },
980
+ * dex: "test",
981
+ * },
982
+ * });
983
+ * ```
984
+ */
863
985
  async perpDeploy(args, signal) {
864
986
  // Destructure the parameters
865
987
  const { ...actionArgs } = args;
866
988
  // Construct an action
867
989
  const nonce = await this.nonceManager();
868
- const action = {
869
- type: "perpDeploy",
870
- ...actionArgs,
871
- };
990
+ const action = actionSorter.perpDeploy({ type: "perpDeploy", ...actionArgs });
872
991
  // Sign the action
873
992
  const signature = await signL1Action({
874
993
  wallet: this.wallet,
875
- action: actionSorter[action.type](action),
994
+ action,
876
995
  nonce,
877
996
  isTestnet: this.isTestnet,
878
997
  });
879
998
  // Send a request
880
- return await this._request({ action, signature, nonce }, signal);
999
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1000
+ this._validateResponse(response);
1001
+ return response;
881
1002
  }
882
1003
  /**
883
1004
  * Transfer funds between Spot account and Perp dex account.
884
1005
  * @param args - The parameters for the request.
885
1006
  * @param signal - An optional abort signal.
886
1007
  * @returns Successful response without specific data.
887
- * @throws {ApiRequestError} When the API returns an error response.
1008
+ *
1009
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1010
+ * @throws {TransportError} When the transport layer throws an error.
888
1011
  *
889
1012
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#transfer-from-spot-account-to-perp-account-and-vice-versa
890
1013
  * @example
891
1014
  * ```ts
892
1015
  * import * as hl from "@nktkas/hyperliquid";
893
- * import { privateKeyToAccount } from "viem/accounts";
894
1016
  *
895
- * const wallet = privateKeyToAccount("0x...");
896
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
897
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1017
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1018
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1019
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
898
1020
  *
899
- * const data = await exchClient.perpDexClassTransfer({
900
- * dex: "test",
901
- * token: "USDC",
902
- * amount: "1",
903
- * toPerp: true,
904
- * });
1021
+ * await exchClient.perpDexClassTransfer({ dex: "test", token: "USDC", amount: "1", toPerp: true });
905
1022
  * ```
906
1023
  */
907
1024
  async perpDexClassTransfer(args, signal) {
@@ -909,41 +1026,87 @@ export class ExchangeClient {
909
1026
  const { ...actionArgs } = args;
910
1027
  // Construct an action
911
1028
  const nonce = await this.nonceManager();
912
- const action = {
913
- ...actionArgs,
1029
+ const action = actionSorter.PerpDexClassTransfer({
914
1030
  type: "PerpDexClassTransfer",
915
1031
  hyperliquidChain: this._getHyperliquidChain(),
916
1032
  signatureChainId: await this._getSignatureChainId(),
917
1033
  nonce,
918
- };
1034
+ ...actionArgs,
1035
+ });
1036
+ // Sign the action
1037
+ const signature = await signUserSignedAction({
1038
+ wallet: this.wallet,
1039
+ action,
1040
+ types: userSignedActionEip712Types[action.type],
1041
+ });
1042
+ // Send a request
1043
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1044
+ this._validateResponse(response);
1045
+ return response;
1046
+ }
1047
+ /**
1048
+ * Transfer collateral tokens between different perp dexes for the same user.
1049
+ * @param args - The parameters for the request.
1050
+ * @param signal - An optional abort signal.
1051
+ * @returns Successful response without specific data.
1052
+ *
1053
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1054
+ * @throws {TransportError} When the transport layer throws an error.
1055
+ *
1056
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#transfer-from-perp-account-to-perp-account-for-builder-deployed-dex
1057
+ * @example
1058
+ * ```ts
1059
+ * import * as hl from "@nktkas/hyperliquid";
1060
+ *
1061
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1062
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1063
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1064
+ *
1065
+ * await exchClient.perpDexTransfer({ sourceDex: "", destinationDex: "test", amount: "1" });
1066
+ * ```
1067
+ */
1068
+ async perpDexTransfer(args, signal) {
1069
+ // Destructure the parameters
1070
+ const { ...actionArgs } = args;
1071
+ // Construct an action
1072
+ const nonce = await this.nonceManager();
1073
+ const action = actionSorter.PerpDexTransfer({
1074
+ type: "PerpDexTransfer",
1075
+ hyperliquidChain: this._getHyperliquidChain(),
1076
+ signatureChainId: await this._getSignatureChainId(),
1077
+ nonce,
1078
+ ...actionArgs,
1079
+ });
919
1080
  // Sign the action
920
1081
  const signature = await signUserSignedAction({
921
1082
  wallet: this.wallet,
922
1083
  action,
923
1084
  types: userSignedActionEip712Types[action.type],
924
- chainId: parseInt(action.signatureChainId, 16),
925
1085
  });
926
1086
  // Send a request
927
- return await this._request({ action, signature, nonce }, signal);
1087
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1088
+ this._validateResponse(response);
1089
+ return response;
928
1090
  }
929
1091
  /**
930
1092
  * Create a referral code.
931
1093
  * @param args - The parameters for the request.
932
1094
  * @param signal - An optional abort signal.
933
1095
  * @returns Successful response without specific data.
934
- * @throws {ApiRequestError} When the API returns an error response.
935
1096
  *
936
- * @see null - no documentation
1097
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1098
+ * @throws {TransportError} When the transport layer throws an error.
1099
+ *
1100
+ * @see null
937
1101
  * @example
938
1102
  * ```ts
939
1103
  * import * as hl from "@nktkas/hyperliquid";
940
- * import { privateKeyToAccount } from "viem/accounts";
941
1104
  *
942
- * const wallet = privateKeyToAccount("0x...");
943
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
944
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1105
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1106
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1107
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
945
1108
  *
946
- * const data = await exchClient.registerReferrer({ code: "TEST" });
1109
+ * await exchClient.registerReferrer({ code: "..." });
947
1110
  * ```
948
1111
  */
949
1112
  async registerReferrer(args, signal) {
@@ -951,38 +1114,38 @@ export class ExchangeClient {
951
1114
  const { ...actionArgs } = args;
952
1115
  // Construct an action
953
1116
  const nonce = await this.nonceManager();
954
- const action = {
955
- type: "registerReferrer",
956
- ...actionArgs,
957
- };
1117
+ const action = actionSorter.registerReferrer({ type: "registerReferrer", ...actionArgs });
958
1118
  // Sign the action
959
1119
  const signature = await signL1Action({
960
1120
  wallet: this.wallet,
961
- action: actionSorter[action.type](action),
1121
+ action,
962
1122
  nonce,
963
1123
  isTestnet: this.isTestnet,
964
1124
  });
965
1125
  // Send a request
966
- return await this._request({ action, signature, nonce }, signal);
1126
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1127
+ this._validateResponse(response);
1128
+ return response;
967
1129
  }
968
1130
  /**
969
1131
  * Reserve additional rate-limited actions for a fee.
970
1132
  * @param args - The parameters for the request.
971
1133
  * @param signal - An optional abort signal.
972
1134
  * @returns Successful response without specific data.
973
- * @throws {ApiRequestError} When the API returns an error response.
1135
+ *
1136
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1137
+ * @throws {TransportError} When the transport layer throws an error.
974
1138
  *
975
1139
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#reserve-additional-actions
976
1140
  * @example
977
1141
  * ```ts
978
1142
  * import * as hl from "@nktkas/hyperliquid";
979
- * import { privateKeyToAccount } from "viem/accounts";
980
1143
  *
981
- * const wallet = privateKeyToAccount("0x...");
982
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
983
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1144
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1145
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1146
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
984
1147
  *
985
- * const data = await exchClient.reserveRequestWeight({ weight: 10 });
1148
+ * await exchClient.reserveRequestWeight({ weight: 10 });
986
1149
  * ```
987
1150
  */
988
1151
  async reserveRequestWeight(args, signal) {
@@ -990,20 +1153,19 @@ export class ExchangeClient {
990
1153
  const { expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
991
1154
  // Construct an action
992
1155
  const nonce = await this.nonceManager();
993
- const action = {
994
- type: "reserveRequestWeight",
995
- ...actionArgs,
996
- };
1156
+ const action = actionSorter.reserveRequestWeight({ type: "reserveRequestWeight", ...actionArgs });
997
1157
  // Sign the action
998
1158
  const signature = await signL1Action({
999
1159
  wallet: this.wallet,
1000
- action: actionSorter[action.type](action),
1160
+ action,
1001
1161
  nonce,
1002
1162
  isTestnet: this.isTestnet,
1003
1163
  expiresAfter,
1004
1164
  });
1005
1165
  // Send a request
1006
- return await this._request({ action, signature, nonce, expiresAfter }, signal);
1166
+ const response = await this.transport.request("exchange", { action, signature, nonce, expiresAfter }, signal);
1167
+ this._validateResponse(response);
1168
+ return response;
1007
1169
  }
1008
1170
  async scheduleCancel(args_or_signal, maybeSignal) {
1009
1171
  const args = args_or_signal instanceof AbortSignal ? {} : args_or_signal ?? {};
@@ -1012,40 +1174,40 @@ export class ExchangeClient {
1012
1174
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
1013
1175
  // Construct an action
1014
1176
  const nonce = await this.nonceManager();
1015
- const action = {
1016
- type: "scheduleCancel",
1017
- ...actionArgs,
1018
- };
1177
+ const action = actionSorter.scheduleCancel({ type: "scheduleCancel", ...actionArgs });
1019
1178
  // Sign the action
1020
1179
  const signature = await signL1Action({
1021
1180
  wallet: this.wallet,
1022
- action: actionSorter[action.type](action),
1181
+ action,
1023
1182
  nonce,
1024
1183
  isTestnet: this.isTestnet,
1025
1184
  vaultAddress,
1026
1185
  expiresAfter,
1027
1186
  });
1028
1187
  // Send a request
1029
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
1188
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
1189
+ this._validateResponse(response);
1190
+ return response;
1030
1191
  }
1031
1192
  /**
1032
1193
  * Set the display name in the leaderboard.
1033
1194
  * @param args - The parameters for the request.
1034
1195
  * @param signal - An optional abort signal.
1035
1196
  * @returns Successful response without specific data.
1036
- * @throws {ApiRequestError} When the API returns an error response.
1037
1197
  *
1038
- * @see null - no documentation
1198
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1199
+ * @throws {TransportError} When the transport layer throws an error.
1200
+ *
1201
+ * @see null
1039
1202
  * @example
1040
1203
  * ```ts
1041
1204
  * import * as hl from "@nktkas/hyperliquid";
1042
- * import { privateKeyToAccount } from "viem/accounts";
1043
1205
  *
1044
- * const wallet = privateKeyToAccount("0x...");
1045
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1046
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1206
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1207
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1208
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1047
1209
  *
1048
- * const data = await exchClient.setDisplayName({ displayName: "My Name" });
1210
+ * await exchClient.setDisplayName({ displayName: "..." });
1049
1211
  * ```
1050
1212
  */
1051
1213
  async setDisplayName(args, signal) {
@@ -1053,38 +1215,38 @@ export class ExchangeClient {
1053
1215
  const { ...actionArgs } = args;
1054
1216
  // Construct an action
1055
1217
  const nonce = await this.nonceManager();
1056
- const action = {
1057
- type: "setDisplayName",
1058
- ...actionArgs,
1059
- };
1218
+ const action = actionSorter.setDisplayName({ type: "setDisplayName", ...actionArgs });
1060
1219
  // Sign the action
1061
1220
  const signature = await signL1Action({
1062
1221
  wallet: this.wallet,
1063
- action: actionSorter[action.type](action),
1222
+ action,
1064
1223
  nonce,
1065
1224
  isTestnet: this.isTestnet,
1066
1225
  });
1067
1226
  // Send a request
1068
- return await this._request({ action, signature, nonce }, signal);
1227
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1228
+ this._validateResponse(response);
1229
+ return response;
1069
1230
  }
1070
1231
  /**
1071
1232
  * Set a referral code.
1072
1233
  * @param args - The parameters for the request.
1073
1234
  * @param signal - An optional abort signal.
1074
1235
  * @returns Successful response without specific data.
1075
- * @throws {ApiRequestError} When the API returns an error response.
1076
1236
  *
1077
- * @see null - no documentation
1237
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1238
+ * @throws {TransportError} When the transport layer throws an error.
1239
+ *
1240
+ * @see null
1078
1241
  * @example
1079
1242
  * ```ts
1080
1243
  * import * as hl from "@nktkas/hyperliquid";
1081
- * import { privateKeyToAccount } from "viem/accounts";
1082
1244
  *
1083
- * const wallet = privateKeyToAccount("0x...");
1084
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1085
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1245
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1246
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1247
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1086
1248
  *
1087
- * const data = await exchClient.setReferrer({ code: "TEST" });
1249
+ * await exchClient.setReferrer({ code: "..." });
1088
1250
  * ```
1089
1251
  */
1090
1252
  async setReferrer(args, signal) {
@@ -1092,57 +1254,87 @@ export class ExchangeClient {
1092
1254
  const { ...actionArgs } = args;
1093
1255
  // Construct an action
1094
1256
  const nonce = await this.nonceManager();
1095
- const action = {
1096
- type: "setReferrer",
1097
- ...actionArgs,
1098
- };
1257
+ const action = actionSorter.setReferrer({ type: "setReferrer", ...actionArgs });
1099
1258
  // Sign the action
1100
1259
  const signature = await signL1Action({
1101
1260
  wallet: this.wallet,
1102
- action: actionSorter[action.type](action),
1261
+ action,
1103
1262
  nonce,
1104
1263
  isTestnet: this.isTestnet,
1105
1264
  });
1106
1265
  // Send a request
1107
- return await this._request({ action, signature, nonce }, signal);
1266
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1267
+ this._validateResponse(response);
1268
+ return response;
1108
1269
  }
1270
+ /**
1271
+ * Deploying HIP-1 and HIP-2 assets.
1272
+ * @param args - The parameters for the request.
1273
+ * @param signal - An optional abort signal.
1274
+ * @returns Successful response without specific data.
1275
+ *
1276
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1277
+ * @throws {TransportError} When the transport layer throws an error.
1278
+ *
1279
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/deploying-hip-1-and-hip-2-assets
1280
+ * @example
1281
+ * ```ts
1282
+ * import * as hl from "@nktkas/hyperliquid";
1283
+ *
1284
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1285
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1286
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1287
+ *
1288
+ * await exchClient.spotDeploy({
1289
+ * registerToken2: {
1290
+ * spec: {
1291
+ * name: "USDC",
1292
+ * szDecimals: 8,
1293
+ * weiDecimals: 8,
1294
+ * },
1295
+ * maxGas: 1000000,
1296
+ * fullName: "USD Coin",
1297
+ * },
1298
+ * });
1299
+ * ```
1300
+ */
1109
1301
  async spotDeploy(args, signal) {
1110
1302
  // Destructure the parameters
1111
1303
  const { ...actionArgs } = args;
1112
1304
  // Construct an action
1113
1305
  const nonce = await this.nonceManager();
1114
- const action = {
1115
- type: "spotDeploy",
1116
- ...actionArgs,
1117
- };
1306
+ const action = actionSorter.spotDeploy({ type: "spotDeploy", ...actionArgs });
1118
1307
  // Sign the action
1119
1308
  const signature = await signL1Action({
1120
1309
  wallet: this.wallet,
1121
- action: actionSorter[action.type](action),
1310
+ action,
1122
1311
  nonce,
1123
1312
  isTestnet: this.isTestnet,
1124
1313
  });
1125
1314
  // Send a request
1126
- return await this._request({ action, signature, nonce }, signal);
1315
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1316
+ this._validateResponse(response);
1317
+ return response;
1127
1318
  }
1128
1319
  /**
1129
1320
  * Send spot assets to another address.
1130
1321
  * @param args - The parameters for the request.
1131
1322
  * @param signal - An optional abort signal.
1132
1323
  * @returns Successful response without specific data.
1133
- * @throws {ApiRequestError} When the API returns an error response.
1324
+ *
1325
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1326
+ * @throws {TransportError} When the transport layer throws an error.
1134
1327
  *
1135
1328
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#core-spot-transfer
1136
1329
  * @example
1137
1330
  * ```ts
1138
1331
  * import * as hl from "@nktkas/hyperliquid";
1139
- * import { privateKeyToAccount } from "viem/accounts";
1140
1332
  *
1141
- * const wallet = privateKeyToAccount("0x...");
1142
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1143
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1333
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1334
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1335
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1144
1336
  *
1145
- * const data = await exchClient.spotSend({
1337
+ * await exchClient.spotSend({
1146
1338
  * destination: "0x...",
1147
1339
  * token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
1148
1340
  * amount: "1",
@@ -1154,41 +1346,43 @@ export class ExchangeClient {
1154
1346
  const { ...actionArgs } = args;
1155
1347
  // Construct an action
1156
1348
  const nonce = await this.nonceManager();
1157
- const action = {
1158
- ...actionArgs,
1349
+ const action = actionSorter.spotSend({
1159
1350
  type: "spotSend",
1160
1351
  hyperliquidChain: this._getHyperliquidChain(),
1161
1352
  signatureChainId: await this._getSignatureChainId(),
1162
1353
  time: nonce,
1163
- };
1354
+ ...actionArgs,
1355
+ });
1164
1356
  // Sign the action
1165
1357
  const signature = await signUserSignedAction({
1166
1358
  wallet: this.wallet,
1167
1359
  action,
1168
1360
  types: userSignedActionEip712Types[action.type],
1169
- chainId: parseInt(action.signatureChainId, 16),
1170
1361
  });
1171
1362
  // Send a request
1172
- return await this._request({ action, signature, nonce }, signal);
1363
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1364
+ this._validateResponse(response);
1365
+ return response;
1173
1366
  }
1174
1367
  /**
1175
1368
  * Opt Out of Spot Dusting.
1176
1369
  * @param args - The parameters for the request.
1177
1370
  * @param signal - An optional abort signal.
1178
1371
  * @returns Successful response without specific data.
1179
- * @throws {ApiRequestError} When the API returns an error response.
1180
1372
  *
1181
- * @see null - no documentation
1373
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1374
+ * @throws {TransportError} When the transport layer throws an error.
1375
+ *
1376
+ * @see null
1182
1377
  * @example
1183
1378
  * ```ts
1184
1379
  * import * as hl from "@nktkas/hyperliquid";
1185
- * import { privateKeyToAccount } from "viem/accounts";
1186
1380
  *
1187
- * const wallet = privateKeyToAccount("0x...");
1188
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1189
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1381
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1382
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1383
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1190
1384
  *
1191
- * const data = await exchClient.spotUser({ toggleSpotDusting: { optOut: false } });
1385
+ * await exchClient.spotUser({ toggleSpotDusting: { optOut: false } });
1192
1386
  * ```
1193
1387
  */
1194
1388
  async spotUser(args, signal) {
@@ -1196,38 +1390,38 @@ export class ExchangeClient {
1196
1390
  const { ...actionArgs } = args;
1197
1391
  // Construct an action
1198
1392
  const nonce = await this.nonceManager();
1199
- const action = {
1200
- type: "spotUser",
1201
- ...actionArgs,
1202
- };
1393
+ const action = actionSorter.spotUser({ type: "spotUser", ...actionArgs });
1203
1394
  // Sign the action
1204
1395
  const signature = await signL1Action({
1205
1396
  wallet: this.wallet,
1206
- action: actionSorter[action.type](action),
1397
+ action,
1207
1398
  nonce,
1208
1399
  isTestnet: this.isTestnet,
1209
1400
  });
1210
1401
  // Send a request
1211
- return await this._request({ action, signature, nonce }, signal);
1402
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1403
+ this._validateResponse(response);
1404
+ return response;
1212
1405
  }
1213
1406
  /**
1214
1407
  * Transfer between sub-accounts (spot).
1215
1408
  * @param args - The parameters for the request.
1216
1409
  * @param signal - An optional abort signal.
1217
1410
  * @returns Successful response without specific data.
1218
- * @throws {ApiRequestError} When the API returns an error response.
1219
1411
  *
1220
- * @see null - no documentation
1412
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1413
+ * @throws {TransportError} When the transport layer throws an error.
1414
+ *
1415
+ * @see null
1221
1416
  * @example
1222
1417
  * ```ts
1223
1418
  * import * as hl from "@nktkas/hyperliquid";
1224
- * import { privateKeyToAccount } from "viem/accounts";
1225
1419
  *
1226
- * const wallet = privateKeyToAccount("0x...");
1227
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1228
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1420
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1421
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1422
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1229
1423
  *
1230
- * const data = await exchClient.subAccountSpotTransfer({
1424
+ * await exchClient.subAccountSpotTransfer({
1231
1425
  * subAccountUser: "0x...",
1232
1426
  * isDeposit: true,
1233
1427
  * token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
@@ -1240,42 +1434,38 @@ export class ExchangeClient {
1240
1434
  const { ...actionArgs } = args;
1241
1435
  // Construct an action
1242
1436
  const nonce = await this.nonceManager();
1243
- const action = {
1244
- type: "subAccountSpotTransfer",
1245
- ...actionArgs,
1246
- };
1437
+ const action = actionSorter.subAccountSpotTransfer({ type: "subAccountSpotTransfer", ...actionArgs });
1247
1438
  // Sign the action
1248
1439
  const signature = await signL1Action({
1249
1440
  wallet: this.wallet,
1250
- action: actionSorter[action.type](action),
1441
+ action,
1251
1442
  nonce,
1252
1443
  isTestnet: this.isTestnet,
1253
1444
  });
1254
1445
  // Send a request
1255
- return await this._request({ action, signature, nonce }, signal);
1446
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1447
+ this._validateResponse(response);
1448
+ return response;
1256
1449
  }
1257
1450
  /**
1258
1451
  * Transfer between sub-accounts (perpetual).
1259
1452
  * @param args - The parameters for the request.
1260
1453
  * @param signal - An optional abort signal.
1261
1454
  * @returns Successful response without specific data.
1262
- * @throws {ApiRequestError} When the API returns an error response.
1263
1455
  *
1264
- * @see null - no documentation
1456
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1457
+ * @throws {TransportError} When the transport layer throws an error.
1458
+ *
1459
+ * @see null
1265
1460
  * @example
1266
1461
  * ```ts
1267
1462
  * import * as hl from "@nktkas/hyperliquid";
1268
- * import { privateKeyToAccount } from "viem/accounts";
1269
1463
  *
1270
- * const wallet = privateKeyToAccount("0x...");
1271
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1272
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1464
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1465
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1466
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1273
1467
  *
1274
- * const data = await exchClient.subAccountTransfer({
1275
- * subAccountUser: "0x...",
1276
- * isDeposit: true,
1277
- * usd: 1 * 1e6,
1278
- * });
1468
+ * await exchClient.subAccountTransfer({ subAccountUser: "0x...", isDeposit: true, usd: 1 * 1e6 });
1279
1469
  * ```
1280
1470
  */
1281
1471
  async subAccountTransfer(args, signal) {
@@ -1283,42 +1473,38 @@ export class ExchangeClient {
1283
1473
  const { ...actionArgs } = args;
1284
1474
  // Construct an action
1285
1475
  const nonce = await this.nonceManager();
1286
- const action = {
1287
- type: "subAccountTransfer",
1288
- ...actionArgs,
1289
- };
1476
+ const action = actionSorter.subAccountTransfer({ type: "subAccountTransfer", ...actionArgs });
1290
1477
  // Sign the action
1291
1478
  const signature = await signL1Action({
1292
1479
  wallet: this.wallet,
1293
- action: actionSorter[action.type](action),
1480
+ action,
1294
1481
  nonce,
1295
1482
  isTestnet: this.isTestnet,
1296
1483
  });
1297
1484
  // Send a request
1298
- return await this._request({ action, signature, nonce }, signal);
1485
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1486
+ this._validateResponse(response);
1487
+ return response;
1299
1488
  }
1300
1489
  /**
1301
1490
  * Delegate or undelegate native tokens to or from a validator.
1302
1491
  * @param args - The parameters for the request.
1303
1492
  * @param signal - An optional abort signal.
1304
1493
  * @returns Successful response without specific data.
1305
- * @throws {ApiRequestError} When the API returns an error response.
1494
+ *
1495
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1496
+ * @throws {TransportError} When the transport layer throws an error.
1306
1497
  *
1307
1498
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#delegate-or-undelegate-stake-from-validator
1308
1499
  * @example
1309
1500
  * ```ts
1310
1501
  * import * as hl from "@nktkas/hyperliquid";
1311
- * import { privateKeyToAccount } from "viem/accounts";
1312
1502
  *
1313
- * const wallet = privateKeyToAccount("0x...");
1314
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1315
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1503
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1504
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1505
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1316
1506
  *
1317
- * const data = await exchClient.tokenDelegate({
1318
- * validator: "0x...",
1319
- * isUndelegate: true,
1320
- * wei: 1 * 1e8,
1321
- * });
1507
+ * await exchClient.tokenDelegate({ validator: "0x...", isUndelegate: true, wei: 1 * 1e8 });
1322
1508
  * ```
1323
1509
  */
1324
1510
  async tokenDelegate(args, signal) {
@@ -1326,44 +1512,43 @@ export class ExchangeClient {
1326
1512
  const { ...actionArgs } = args;
1327
1513
  // Construct an action
1328
1514
  const nonce = await this.nonceManager();
1329
- const action = {
1330
- ...actionArgs,
1515
+ const action = actionSorter.tokenDelegate({
1331
1516
  type: "tokenDelegate",
1332
1517
  hyperliquidChain: this._getHyperliquidChain(),
1333
1518
  signatureChainId: await this._getSignatureChainId(),
1334
1519
  nonce,
1335
- };
1520
+ ...actionArgs,
1521
+ });
1336
1522
  // Sign the action
1337
1523
  const signature = await signUserSignedAction({
1338
1524
  wallet: this.wallet,
1339
1525
  action,
1340
1526
  types: userSignedActionEip712Types[action.type],
1341
- chainId: parseInt(action.signatureChainId, 16),
1342
1527
  });
1343
1528
  // Send a request
1344
- return await this._request({ action, signature, nonce }, signal);
1529
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1530
+ this._validateResponse(response);
1531
+ return response;
1345
1532
  }
1346
1533
  /**
1347
1534
  * Cancel a TWAP order.
1348
1535
  * @param args - The parameters for the request.
1349
1536
  * @param signal - An optional abort signal.
1350
1537
  * @returns Successful variant of {@link TwapCancelResponse} without error status.
1351
- * @throws {ApiRequestError} When the API returns an error response.
1538
+ *
1539
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1540
+ * @throws {TransportError} When the transport layer throws an error.
1352
1541
  *
1353
1542
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-a-twap-order
1354
1543
  * @example
1355
1544
  * ```ts
1356
1545
  * import * as hl from "@nktkas/hyperliquid";
1357
- * import { privateKeyToAccount } from "viem/accounts";
1358
1546
  *
1359
- * const wallet = privateKeyToAccount("0x...");
1360
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1361
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1547
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1548
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1549
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1362
1550
  *
1363
- * const data = await exchClient.twapCancel({
1364
- * a: 0, // Asset index
1365
- * t: 1, // TWAP ID
1366
- * });
1551
+ * const data = await exchClient.twapCancel({ a: 0, t: 1 });
1367
1552
  * ```
1368
1553
  */
1369
1554
  async twapCancel(args, signal) {
@@ -1371,46 +1556,46 @@ export class ExchangeClient {
1371
1556
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
1372
1557
  // Construct an action
1373
1558
  const nonce = await this.nonceManager();
1374
- const action = {
1375
- type: "twapCancel",
1376
- ...actionArgs,
1377
- };
1559
+ const action = actionSorter.twapCancel({ type: "twapCancel", ...actionArgs });
1378
1560
  // Sign the action
1379
1561
  const signature = await signL1Action({
1380
1562
  wallet: this.wallet,
1381
- action: actionSorter[action.type](action),
1563
+ action,
1382
1564
  nonce,
1383
1565
  isTestnet: this.isTestnet,
1384
1566
  vaultAddress,
1385
1567
  expiresAfter,
1386
1568
  });
1387
1569
  // Send a request
1388
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
1570
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
1571
+ this._validateResponse(response);
1572
+ return response;
1389
1573
  }
1390
1574
  /**
1391
1575
  * Place a TWAP order.
1392
1576
  * @param args - The parameters for the request.
1393
1577
  * @param signal - An optional abort signal.
1394
1578
  * @returns Successful variant of {@link TwapOrderResponse} without error status.
1395
- * @throws {ApiRequestError} When the API returns an error response.
1579
+ *
1580
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1581
+ * @throws {TransportError} When the transport layer throws an error.
1396
1582
  *
1397
1583
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-a-twap-order
1398
1584
  * @example
1399
1585
  * ```ts
1400
1586
  * import * as hl from "@nktkas/hyperliquid";
1401
- * import { privateKeyToAccount } from "viem/accounts";
1402
1587
  *
1403
- * const wallet = privateKeyToAccount("0x...");
1404
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1405
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1588
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1589
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1590
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1406
1591
  *
1407
1592
  * const data = await exchClient.twapOrder({
1408
- * a: 0, // Asset index
1409
- * b: true, // Buy order
1410
- * s: "1", // Size
1411
- * r: false, // Not reduce-only
1412
- * m: 10, // Duration in minutes
1413
- * t: true, // Randomize order timing
1593
+ * a: 0,
1594
+ * b: true,
1595
+ * s: "1",
1596
+ * r: false,
1597
+ * m: 10,
1598
+ * t: true,
1414
1599
  * });
1415
1600
  * ```
1416
1601
  */
@@ -1419,46 +1604,40 @@ export class ExchangeClient {
1419
1604
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
1420
1605
  // Construct an action
1421
1606
  const nonce = await this.nonceManager();
1422
- const action = {
1423
- type: "twapOrder",
1424
- twap: {
1425
- ...actionArgs,
1426
- },
1427
- };
1607
+ const action = actionSorter.twapOrder({ type: "twapOrder", twap: { ...actionArgs } });
1428
1608
  // Sign the action
1429
1609
  const signature = await signL1Action({
1430
1610
  wallet: this.wallet,
1431
- action: actionSorter[action.type](action),
1611
+ action,
1432
1612
  nonce,
1433
1613
  isTestnet: this.isTestnet,
1434
1614
  vaultAddress,
1435
1615
  expiresAfter,
1436
1616
  });
1437
1617
  // Send a request
1438
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
1618
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
1619
+ this._validateResponse(response);
1620
+ return response;
1439
1621
  }
1440
1622
  /**
1441
1623
  * Add or remove margin from isolated position.
1442
1624
  * @param args - The parameters for the request.
1443
1625
  * @param signal - An optional abort signal.
1444
1626
  * @returns Successful response without specific data.
1445
- * @throws {ApiRequestError} When the API returns an error response.
1627
+ *
1628
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1629
+ * @throws {TransportError} When the transport layer throws an error.
1446
1630
  *
1447
1631
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
1448
1632
  * @example
1449
1633
  * ```ts
1450
1634
  * import * as hl from "@nktkas/hyperliquid";
1451
- * import { privateKeyToAccount } from "viem/accounts";
1452
1635
  *
1453
- * const wallet = privateKeyToAccount("0x...");
1454
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1455
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1636
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1637
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1638
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1456
1639
  *
1457
- * const data = await exchClient.updateIsolatedMargin({
1458
- * asset: 0,
1459
- * isBuy: true,
1460
- * ntli: 1 * 1e6,
1461
- * });
1640
+ * await exchClient.updateIsolatedMargin({ asset: 0, isBuy: true, ntli: 1 * 1e6 });
1462
1641
  * ```
1463
1642
  */
1464
1643
  async updateIsolatedMargin(args, signal) {
@@ -1466,44 +1645,40 @@ export class ExchangeClient {
1466
1645
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
1467
1646
  // Construct an action
1468
1647
  const nonce = await this.nonceManager();
1469
- const action = {
1470
- type: "updateIsolatedMargin",
1471
- ...actionArgs,
1472
- };
1648
+ const action = actionSorter.updateIsolatedMargin({ type: "updateIsolatedMargin", ...actionArgs });
1473
1649
  // Sign the action
1474
1650
  const signature = await signL1Action({
1475
1651
  wallet: this.wallet,
1476
- action: actionSorter[action.type](action),
1652
+ action,
1477
1653
  nonce,
1478
1654
  isTestnet: this.isTestnet,
1479
1655
  vaultAddress,
1480
1656
  expiresAfter,
1481
1657
  });
1482
1658
  // Send a request
1483
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
1659
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
1660
+ this._validateResponse(response);
1661
+ return response;
1484
1662
  }
1485
1663
  /**
1486
1664
  * Update cross or isolated leverage on a coin.
1487
1665
  * @param args - The parameters for the request.
1488
1666
  * @param signal - An optional abort signal.
1489
1667
  * @returns Successful response without specific data.
1490
- * @throws {ApiRequestError} When the API returns an error response.
1668
+ *
1669
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1670
+ * @throws {TransportError} When the transport layer throws an error.
1491
1671
  *
1492
1672
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-leverage
1493
1673
  * @example
1494
1674
  * ```ts
1495
1675
  * import * as hl from "@nktkas/hyperliquid";
1496
- * import { privateKeyToAccount } from "viem/accounts";
1497
1676
  *
1498
- * const wallet = privateKeyToAccount("0x...");
1499
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1500
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1677
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1678
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1679
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1501
1680
  *
1502
- * const data = await exchClient.updateLeverage({
1503
- * asset: 0,
1504
- * isCross: true,
1505
- * leverage: 5,
1506
- * });
1681
+ * await exchClient.updateLeverage({ asset: 0, isCross: true, leverage: 5 });
1507
1682
  * ```
1508
1683
  */
1509
1684
  async updateLeverage(args, signal) {
@@ -1511,40 +1686,40 @@ export class ExchangeClient {
1511
1686
  const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
1512
1687
  // Construct an action
1513
1688
  const nonce = await this.nonceManager();
1514
- const action = {
1515
- type: "updateLeverage",
1516
- ...actionArgs,
1517
- };
1689
+ const action = actionSorter.updateLeverage({ type: "updateLeverage", ...actionArgs });
1518
1690
  // Sign the action
1519
1691
  const signature = await signL1Action({
1520
1692
  wallet: this.wallet,
1521
- action: actionSorter[action.type](action),
1693
+ action,
1522
1694
  nonce,
1523
1695
  isTestnet: this.isTestnet,
1524
1696
  vaultAddress,
1525
1697
  expiresAfter,
1526
1698
  });
1527
1699
  // Send a request
1528
- return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
1700
+ const response = await this.transport.request("exchange", { action, signature, nonce, vaultAddress, expiresAfter }, signal);
1701
+ this._validateResponse(response);
1702
+ return response;
1529
1703
  }
1530
1704
  /**
1531
1705
  * Transfer funds between Spot account and Perp account.
1532
1706
  * @param args - The parameters for the request.
1533
1707
  * @param signal - An optional abort signal.
1534
1708
  * @returns Successful response without specific data.
1535
- * @throws {ApiRequestError} When the API returns an error response.
1709
+ *
1710
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1711
+ * @throws {TransportError} When the transport layer throws an error.
1536
1712
  *
1537
1713
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#transfer-from-spot-account-to-perp-account-and-vice-versa
1538
1714
  * @example
1539
1715
  * ```ts
1540
1716
  * import * as hl from "@nktkas/hyperliquid";
1541
- * import { privateKeyToAccount } from "viem/accounts";
1542
1717
  *
1543
- * const wallet = privateKeyToAccount("0x...");
1544
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1545
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1718
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1719
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1720
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1546
1721
  *
1547
- * const data = await exchClient.usdClassTransfer({ amount: "1", toPerp: true });
1722
+ * await exchClient.usdClassTransfer({ amount: "1", toPerp: true });
1548
1723
  * ```
1549
1724
  */
1550
1725
  async usdClassTransfer(args, signal) {
@@ -1552,41 +1727,43 @@ export class ExchangeClient {
1552
1727
  const { ...actionArgs } = args;
1553
1728
  // Construct an action
1554
1729
  const nonce = await this.nonceManager();
1555
- const action = {
1556
- ...actionArgs,
1730
+ const action = actionSorter.usdClassTransfer({
1557
1731
  type: "usdClassTransfer",
1558
1732
  hyperliquidChain: this._getHyperliquidChain(),
1559
1733
  signatureChainId: await this._getSignatureChainId(),
1560
1734
  nonce,
1561
- };
1735
+ ...actionArgs,
1736
+ });
1562
1737
  // Sign the action
1563
1738
  const signature = await signUserSignedAction({
1564
1739
  wallet: this.wallet,
1565
1740
  action,
1566
1741
  types: userSignedActionEip712Types[action.type],
1567
- chainId: parseInt(action.signatureChainId, 16),
1568
1742
  });
1569
1743
  // Send a request
1570
- return await this._request({ action, signature, nonce }, signal);
1744
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1745
+ this._validateResponse(response);
1746
+ return response;
1571
1747
  }
1572
1748
  /**
1573
1749
  * Send usd to another address.
1574
1750
  * @param args - The parameters for the request.
1575
1751
  * @param signal - An optional abort signal.
1576
1752
  * @returns Successful response without specific data.
1577
- * @throws {ApiRequestError} When the API returns an error response.
1753
+ *
1754
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1755
+ * @throws {TransportError} When the transport layer throws an error.
1578
1756
  *
1579
1757
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#core-usdc-transfer
1580
1758
  * @example
1581
1759
  * ```ts
1582
1760
  * import * as hl from "@nktkas/hyperliquid";
1583
- * import { privateKeyToAccount } from "viem/accounts";
1584
1761
  *
1585
- * const wallet = privateKeyToAccount("0x...");
1586
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1587
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1762
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1763
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1764
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1588
1765
  *
1589
- * const data = await exchClient.usdSend({ destination: "0x...", amount: "1" });
1766
+ * await exchClient.usdSend({ destination: "0x...", amount: "1" });
1590
1767
  * ```
1591
1768
  */
1592
1769
  async usdSend(args, signal) {
@@ -1594,41 +1771,43 @@ export class ExchangeClient {
1594
1771
  const { ...actionArgs } = args;
1595
1772
  // Construct an action
1596
1773
  const nonce = await this.nonceManager();
1597
- const action = {
1598
- ...actionArgs,
1774
+ const action = actionSorter.usdSend({
1599
1775
  type: "usdSend",
1600
1776
  hyperliquidChain: this._getHyperliquidChain(),
1601
1777
  signatureChainId: await this._getSignatureChainId(),
1602
1778
  time: nonce,
1603
- };
1779
+ ...actionArgs,
1780
+ });
1604
1781
  // Sign the action
1605
1782
  const signature = await signUserSignedAction({
1606
1783
  wallet: this.wallet,
1607
1784
  action,
1608
1785
  types: userSignedActionEip712Types[action.type],
1609
- chainId: parseInt(action.signatureChainId, 16),
1610
1786
  });
1611
1787
  // Send a request
1612
- return await this._request({ action, signature, nonce }, signal);
1788
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1789
+ this._validateResponse(response);
1790
+ return response;
1613
1791
  }
1614
1792
  /**
1615
1793
  * Distribute funds from a vault between followers.
1616
1794
  * @param args - The parameters for the request.
1617
1795
  * @param signal - An optional abort signal.
1618
1796
  * @returns Successful response without specific data.
1619
- * @throws {ApiRequestError} When the API returns an error response.
1620
1797
  *
1621
- * @see null - no documentation
1798
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1799
+ * @throws {TransportError} When the transport layer throws an error.
1800
+ *
1801
+ * @see null
1622
1802
  * @example
1623
1803
  * ```ts
1624
1804
  * import * as hl from "@nktkas/hyperliquid";
1625
- * import { privateKeyToAccount } from "viem/accounts";
1626
1805
  *
1627
- * const wallet = privateKeyToAccount("0x...");
1628
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1629
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1806
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1807
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1808
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1630
1809
  *
1631
- * const data = await exchClient.vaultDistribute({ vaultAddress: "0x...", usd: 10 * 1e6 });
1810
+ * await exchClient.vaultDistribute({ vaultAddress: "0x...", usd: 10 * 1e6 });
1632
1811
  * ```
1633
1812
  */
1634
1813
  async vaultDistribute(args, signal) {
@@ -1636,38 +1815,38 @@ export class ExchangeClient {
1636
1815
  const { ...actionArgs } = args;
1637
1816
  // Construct an action
1638
1817
  const nonce = await this.nonceManager();
1639
- const action = {
1640
- type: "vaultDistribute",
1641
- ...actionArgs,
1642
- };
1818
+ const action = actionSorter.vaultDistribute({ type: "vaultDistribute", ...actionArgs });
1643
1819
  // Sign the action
1644
1820
  const signature = await signL1Action({
1645
1821
  wallet: this.wallet,
1646
- action: actionSorter[action.type](action),
1822
+ action,
1647
1823
  nonce,
1648
1824
  isTestnet: this.isTestnet,
1649
1825
  });
1650
1826
  // Send a request
1651
- return await this._request({ action, signature, nonce }, signal);
1827
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1828
+ this._validateResponse(response);
1829
+ return response;
1652
1830
  }
1653
1831
  /**
1654
1832
  * Modify a vault's configuration.
1655
1833
  * @param args - The parameters for the request.
1656
1834
  * @param signal - An optional abort signal.
1657
1835
  * @returns Successful response without specific data.
1658
- * @throws {ApiRequestError} When the API returns an error response.
1659
1836
  *
1660
- * @see null - no documentation
1837
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1838
+ * @throws {TransportError} When the transport layer throws an error.
1839
+ *
1840
+ * @see null
1661
1841
  * @example
1662
1842
  * ```ts
1663
1843
  * import * as hl from "@nktkas/hyperliquid";
1664
- * import { privateKeyToAccount } from "viem/accounts";
1665
1844
  *
1666
- * const wallet = privateKeyToAccount("0x...");
1667
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1668
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1845
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1846
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1847
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1669
1848
  *
1670
- * const data = await exchClient.vaultModify({
1849
+ * await exchClient.vaultModify({
1671
1850
  * vaultAddress: "0x...",
1672
1851
  * allowDeposits: true,
1673
1852
  * alwaysCloseOnWithdraw: false,
@@ -1679,42 +1858,38 @@ export class ExchangeClient {
1679
1858
  const { ...actionArgs } = args;
1680
1859
  // Construct an action
1681
1860
  const nonce = await this.nonceManager();
1682
- const action = {
1683
- type: "vaultModify",
1684
- ...actionArgs,
1685
- };
1861
+ const action = actionSorter.vaultModify({ type: "vaultModify", ...actionArgs });
1686
1862
  // Sign the action
1687
1863
  const signature = await signL1Action({
1688
1864
  wallet: this.wallet,
1689
- action: actionSorter[action.type](action),
1865
+ action,
1690
1866
  nonce,
1691
1867
  isTestnet: this.isTestnet,
1692
1868
  });
1693
1869
  // Send a request
1694
- return await this._request({ action, signature, nonce }, signal);
1870
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1871
+ this._validateResponse(response);
1872
+ return response;
1695
1873
  }
1696
1874
  /**
1697
1875
  * Deposit or withdraw from a vault.
1698
1876
  * @param args - The parameters for the request.
1699
1877
  * @param signal - An optional abort signal.
1700
1878
  * @returns Successful response without specific data.
1701
- * @throws {ApiRequestError} When the API returns an error response.
1879
+ *
1880
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1881
+ * @throws {TransportError} When the transport layer throws an error.
1702
1882
  *
1703
1883
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-or-withdraw-from-a-vault
1704
1884
  * @example
1705
1885
  * ```ts
1706
1886
  * import * as hl from "@nktkas/hyperliquid";
1707
- * import { privateKeyToAccount } from "viem/accounts";
1708
1887
  *
1709
- * const wallet = privateKeyToAccount("0x...");
1710
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1711
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1888
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1889
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1890
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1712
1891
  *
1713
- * const data = await exchClient.vaultTransfer({
1714
- * vaultAddress: "0x...",
1715
- * isDeposit: true,
1716
- * usd: 10 * 1e6,
1717
- * });
1892
+ * await exchClient.vaultTransfer({ vaultAddress: "0x...", isDeposit: true, usd: 10 * 1e6 });
1718
1893
  * ```
1719
1894
  */
1720
1895
  async vaultTransfer(args, signal) {
@@ -1722,39 +1897,39 @@ export class ExchangeClient {
1722
1897
  const { expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
1723
1898
  // Construct an action
1724
1899
  const nonce = await this.nonceManager();
1725
- const action = {
1726
- type: "vaultTransfer",
1727
- ...actionArgs,
1728
- };
1900
+ const action = actionSorter.vaultTransfer({ type: "vaultTransfer", ...actionArgs });
1729
1901
  // Sign the action
1730
1902
  const signature = await signL1Action({
1731
1903
  wallet: this.wallet,
1732
- action: actionSorter[action.type](action),
1904
+ action,
1733
1905
  nonce,
1734
1906
  isTestnet: this.isTestnet,
1735
1907
  expiresAfter,
1736
1908
  });
1737
1909
  // Send a request
1738
- return await this._request({ action, signature, nonce, expiresAfter }, signal);
1910
+ const response = await this.transport.request("exchange", { action, signature, nonce, expiresAfter }, signal);
1911
+ this._validateResponse(response);
1912
+ return response;
1739
1913
  }
1740
1914
  /**
1741
1915
  * Initiate a withdrawal request.
1742
1916
  * @param args - The parameters for the request.
1743
1917
  * @param signal - An optional abort signal.
1744
1918
  * @returns Successful response without specific data.
1745
- * @throws {ApiRequestError} When the API returns an error response.
1919
+ *
1920
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1921
+ * @throws {TransportError} When the transport layer throws an error.
1746
1922
  *
1747
1923
  * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#initiate-a-withdrawal-request
1748
1924
  * @example
1749
1925
  * ```ts
1750
1926
  * import * as hl from "@nktkas/hyperliquid";
1751
- * import { privateKeyToAccount } from "viem/accounts";
1752
1927
  *
1753
- * const wallet = privateKeyToAccount("0x...");
1754
- * const transport = new hl.HttpTransport(); // or WebSocketTransport
1755
- * const exchClient = new hl.ExchangeClient({ wallet, transport });
1928
+ * const privateKey = "0x..."; // or `viem`, `ethers`
1929
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1930
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1756
1931
  *
1757
- * const data = await exchClient.withdraw3({ destination: "0x...", amount: "1" });
1932
+ * await exchClient.withdraw3({ destination: "0x...", amount: "1" });
1758
1933
  * ```
1759
1934
  */
1760
1935
  async withdraw3(args, signal) {
@@ -1762,26 +1937,21 @@ export class ExchangeClient {
1762
1937
  const { ...actionArgs } = args;
1763
1938
  // Construct an action
1764
1939
  const nonce = await this.nonceManager();
1765
- const action = {
1766
- ...actionArgs,
1940
+ const action = actionSorter.withdraw3({
1767
1941
  type: "withdraw3",
1768
1942
  hyperliquidChain: this._getHyperliquidChain(),
1769
1943
  signatureChainId: await this._getSignatureChainId(),
1770
1944
  time: nonce,
1771
- };
1945
+ ...actionArgs,
1946
+ });
1772
1947
  // Sign the action
1773
1948
  const signature = await signUserSignedAction({
1774
1949
  wallet: this.wallet,
1775
1950
  action,
1776
1951
  types: userSignedActionEip712Types[action.type],
1777
- chainId: parseInt(action.signatureChainId, 16),
1778
1952
  });
1779
1953
  // Send a request
1780
- return await this._request({ action, signature, nonce }, signal);
1781
- }
1782
- /** Send an API request and validate the response. */
1783
- async _request(payload, signal) {
1784
- const response = await this.transport.request("exchange", payload, signal);
1954
+ const response = await this.transport.request("exchange", { action, signature, nonce }, signal);
1785
1955
  this._validateResponse(response);
1786
1956
  return response;
1787
1957
  }