@nktkas/hyperliquid 0.24.3 → 0.25.0-beta.2

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 (358) hide show
  1. package/README.md +141 -32
  2. package/esm/mod.d.ts +11 -11
  3. package/esm/mod.d.ts.map +1 -1
  4. package/esm/mod.js +2 -1
  5. package/esm/mod.js.map +1 -0
  6. package/esm/src/clients/exchange.d.ts +29 -25
  7. package/esm/src/clients/exchange.d.ts.map +1 -1
  8. package/esm/src/clients/exchange.js +54 -53
  9. package/esm/src/clients/exchange.js.map +1 -0
  10. package/esm/src/clients/info.d.ts +80 -20
  11. package/esm/src/clients/info.d.ts.map +1 -1
  12. package/esm/src/clients/info.js +312 -73
  13. package/esm/src/clients/info.js.map +1 -0
  14. package/esm/src/clients/multiSign.d.ts +11 -7
  15. package/esm/src/clients/multiSign.d.ts.map +1 -1
  16. package/esm/src/clients/multiSign.js +2 -1
  17. package/esm/src/clients/multiSign.js.map +1 -0
  18. package/esm/src/clients/subscription.d.ts +9 -9
  19. package/esm/src/clients/subscription.d.ts.map +1 -1
  20. package/esm/src/clients/subscription.js +29 -27
  21. package/esm/src/clients/subscription.js.map +1 -0
  22. package/esm/src/{base.d.ts → errors.d.ts} +1 -1
  23. package/esm/src/errors.d.ts.map +1 -0
  24. package/esm/src/{base.js → errors.js} +1 -0
  25. package/esm/src/errors.js.map +1 -0
  26. package/esm/src/schemas/_base.d.ts +14 -0
  27. package/esm/src/schemas/_base.d.ts.map +1 -0
  28. package/esm/src/schemas/_base.js +15 -0
  29. package/esm/src/schemas/_base.js.map +1 -0
  30. package/esm/src/schemas/exchange/requests.d.ts +8953 -0
  31. package/esm/src/schemas/exchange/requests.d.ts.map +1 -0
  32. package/esm/src/schemas/exchange/requests.js +1414 -0
  33. package/esm/src/schemas/exchange/requests.js.map +1 -0
  34. package/esm/src/schemas/exchange/responses.d.ts +567 -0
  35. package/esm/src/schemas/exchange/responses.d.ts.map +1 -0
  36. package/esm/src/schemas/exchange/responses.js +244 -0
  37. package/esm/src/schemas/exchange/responses.js.map +1 -0
  38. package/esm/src/schemas/explorer/requests.d.ts +44 -0
  39. package/esm/src/schemas/explorer/requests.d.ts.map +1 -0
  40. package/esm/src/schemas/explorer/requests.js +33 -0
  41. package/esm/src/schemas/explorer/requests.js.map +1 -0
  42. package/esm/src/schemas/explorer/responses.d.ts +360 -0
  43. package/esm/src/schemas/explorer/responses.d.ts.map +1 -0
  44. package/esm/src/schemas/explorer/responses.js +57 -0
  45. package/esm/src/schemas/explorer/responses.js.map +1 -0
  46. package/esm/src/schemas/info/accounts.d.ts +2159 -0
  47. package/esm/src/schemas/info/accounts.d.ts.map +1 -0
  48. package/esm/src/schemas/info/accounts.js +623 -0
  49. package/esm/src/schemas/info/accounts.js.map +1 -0
  50. package/esm/src/schemas/info/assets.d.ts +974 -0
  51. package/esm/src/schemas/info/assets.d.ts.map +1 -0
  52. package/esm/src/schemas/info/assets.js +285 -0
  53. package/esm/src/schemas/info/assets.js.map +1 -0
  54. package/esm/src/schemas/info/markets.d.ts +155 -0
  55. package/esm/src/schemas/info/markets.d.ts.map +1 -0
  56. package/esm/src/schemas/info/markets.js +70 -0
  57. package/esm/src/schemas/info/markets.js.map +1 -0
  58. package/esm/src/schemas/info/orders.d.ts +957 -0
  59. package/esm/src/schemas/info/orders.d.ts.map +1 -0
  60. package/esm/src/schemas/info/orders.js +298 -0
  61. package/esm/src/schemas/info/orders.js.map +1 -0
  62. package/esm/src/schemas/info/requests.d.ts +924 -0
  63. package/esm/src/schemas/info/requests.d.ts.map +1 -0
  64. package/esm/src/schemas/info/requests.js +687 -0
  65. package/esm/src/schemas/info/requests.js.map +1 -0
  66. package/esm/src/schemas/info/validators.d.ts +326 -0
  67. package/esm/src/schemas/info/validators.d.ts.map +1 -0
  68. package/esm/src/schemas/info/validators.js +126 -0
  69. package/esm/src/schemas/info/validators.js.map +1 -0
  70. package/esm/src/schemas/info/vaults.d.ts +447 -0
  71. package/esm/src/schemas/info/vaults.d.ts.map +1 -0
  72. package/esm/src/schemas/info/vaults.js +111 -0
  73. package/esm/src/schemas/info/vaults.js.map +1 -0
  74. package/esm/src/schemas/mod.d.ts +101 -0
  75. package/esm/src/schemas/mod.d.ts.map +1 -0
  76. package/esm/src/schemas/mod.js +115 -0
  77. package/esm/src/schemas/mod.js.map +1 -0
  78. package/esm/src/schemas/subscriptions/requests.d.ts +332 -0
  79. package/esm/src/schemas/subscriptions/requests.d.ts.map +1 -0
  80. package/esm/src/schemas/subscriptions/requests.js +259 -0
  81. package/esm/src/schemas/subscriptions/requests.js.map +1 -0
  82. package/esm/src/schemas/subscriptions/responses.d.ts +3643 -0
  83. package/esm/src/schemas/subscriptions/responses.d.ts.map +1 -0
  84. package/esm/src/schemas/subscriptions/responses.js +234 -0
  85. package/esm/src/schemas/subscriptions/responses.js.map +1 -0
  86. package/esm/src/signing/_signTypedData/ethers.js +1 -0
  87. package/esm/src/signing/_signTypedData/ethers.js.map +1 -0
  88. package/esm/src/signing/_signTypedData/mod.js +1 -0
  89. package/esm/src/signing/_signTypedData/mod.js.map +1 -0
  90. package/esm/src/signing/_signTypedData/private_key.js +1 -0
  91. package/esm/src/signing/_signTypedData/private_key.js.map +1 -0
  92. package/esm/src/signing/_signTypedData/viem.js +1 -0
  93. package/esm/src/signing/_signTypedData/viem.js.map +1 -0
  94. package/esm/src/signing/mod.d.ts +109 -29
  95. package/esm/src/signing/mod.d.ts.map +1 -1
  96. package/esm/src/signing/mod.js +136 -29
  97. package/esm/src/signing/mod.js.map +1 -0
  98. package/esm/src/transports/base.d.ts +4 -4
  99. package/esm/src/transports/base.d.ts.map +1 -1
  100. package/esm/src/transports/base.js +3 -2
  101. package/esm/src/transports/base.js.map +1 -0
  102. package/esm/src/transports/http/http_transport.d.ts +3 -2
  103. package/esm/src/transports/http/http_transport.d.ts.map +1 -1
  104. package/esm/src/transports/http/http_transport.js +1 -0
  105. package/esm/src/transports/http/http_transport.js.map +1 -0
  106. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +1 -1
  107. package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  108. package/esm/src/transports/websocket/_hyperliquid_event_target.js +1 -0
  109. package/esm/src/transports/websocket/_hyperliquid_event_target.js.map +1 -0
  110. package/esm/src/transports/websocket/_reconnecting_websocket.js +1 -0
  111. package/esm/src/transports/websocket/_reconnecting_websocket.js.map +1 -0
  112. package/esm/src/transports/websocket/_websocket_async_request.js +1 -0
  113. package/esm/src/transports/websocket/_websocket_async_request.js.map +1 -0
  114. package/esm/src/transports/websocket/websocket_transport.d.ts +9 -1
  115. package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  116. package/esm/src/transports/websocket/websocket_transport.js +4 -0
  117. package/esm/src/transports/websocket/websocket_transport.js.map +1 -0
  118. package/package.json +6 -5
  119. package/script/mod.d.ts +11 -11
  120. package/script/mod.d.ts.map +1 -1
  121. package/script/mod.js +2 -1
  122. package/script/mod.js.map +1 -0
  123. package/script/src/clients/exchange.d.ts +29 -25
  124. package/script/src/clients/exchange.d.ts.map +1 -1
  125. package/script/src/clients/exchange.js +60 -59
  126. package/script/src/clients/exchange.js.map +1 -0
  127. package/script/src/clients/info.d.ts +80 -20
  128. package/script/src/clients/info.d.ts.map +1 -1
  129. package/script/src/clients/info.js +312 -73
  130. package/script/src/clients/info.js.map +1 -0
  131. package/script/src/clients/multiSign.d.ts +11 -7
  132. package/script/src/clients/multiSign.d.ts.map +1 -1
  133. package/script/src/clients/multiSign.js +2 -1
  134. package/script/src/clients/multiSign.js.map +1 -0
  135. package/script/src/clients/subscription.d.ts +9 -9
  136. package/script/src/clients/subscription.d.ts.map +1 -1
  137. package/script/src/clients/subscription.js +29 -27
  138. package/script/src/clients/subscription.js.map +1 -0
  139. package/script/src/{base.d.ts → errors.d.ts} +1 -1
  140. package/script/src/errors.d.ts.map +1 -0
  141. package/script/src/{base.js → errors.js} +1 -0
  142. package/script/src/errors.js.map +1 -0
  143. package/script/src/schemas/_base.d.ts +14 -0
  144. package/script/src/schemas/_base.d.ts.map +1 -0
  145. package/script/src/schemas/_base.js +51 -0
  146. package/script/src/schemas/_base.js.map +1 -0
  147. package/script/src/schemas/exchange/requests.d.ts +8953 -0
  148. package/script/src/schemas/exchange/requests.d.ts.map +1 -0
  149. package/script/src/schemas/exchange/requests.js +1450 -0
  150. package/script/src/schemas/exchange/requests.js.map +1 -0
  151. package/script/src/schemas/exchange/responses.d.ts +567 -0
  152. package/script/src/schemas/exchange/responses.d.ts.map +1 -0
  153. package/script/src/schemas/exchange/responses.js +280 -0
  154. package/script/src/schemas/exchange/responses.js.map +1 -0
  155. package/script/src/schemas/explorer/requests.d.ts +44 -0
  156. package/script/src/schemas/explorer/requests.d.ts.map +1 -0
  157. package/script/src/schemas/explorer/requests.js +69 -0
  158. package/script/src/schemas/explorer/requests.js.map +1 -0
  159. package/script/src/schemas/explorer/responses.d.ts +360 -0
  160. package/script/src/schemas/explorer/responses.d.ts.map +1 -0
  161. package/script/src/schemas/explorer/responses.js +93 -0
  162. package/script/src/schemas/explorer/responses.js.map +1 -0
  163. package/script/src/schemas/info/accounts.d.ts +2159 -0
  164. package/script/src/schemas/info/accounts.d.ts.map +1 -0
  165. package/script/src/schemas/info/accounts.js +659 -0
  166. package/script/src/schemas/info/accounts.js.map +1 -0
  167. package/script/src/schemas/info/assets.d.ts +974 -0
  168. package/script/src/schemas/info/assets.d.ts.map +1 -0
  169. package/script/src/schemas/info/assets.js +321 -0
  170. package/script/src/schemas/info/assets.js.map +1 -0
  171. package/script/src/schemas/info/markets.d.ts +155 -0
  172. package/script/src/schemas/info/markets.d.ts.map +1 -0
  173. package/script/src/schemas/info/markets.js +106 -0
  174. package/script/src/schemas/info/markets.js.map +1 -0
  175. package/script/src/schemas/info/orders.d.ts +957 -0
  176. package/script/src/schemas/info/orders.d.ts.map +1 -0
  177. package/script/src/schemas/info/orders.js +334 -0
  178. package/script/src/schemas/info/orders.js.map +1 -0
  179. package/script/src/schemas/info/requests.d.ts +924 -0
  180. package/script/src/schemas/info/requests.d.ts.map +1 -0
  181. package/script/src/schemas/info/requests.js +724 -0
  182. package/script/src/schemas/info/requests.js.map +1 -0
  183. package/script/src/schemas/info/validators.d.ts +326 -0
  184. package/script/src/schemas/info/validators.d.ts.map +1 -0
  185. package/script/src/schemas/info/validators.js +162 -0
  186. package/script/src/schemas/info/validators.js.map +1 -0
  187. package/script/src/schemas/info/vaults.d.ts +447 -0
  188. package/script/src/schemas/info/vaults.d.ts.map +1 -0
  189. package/script/src/schemas/info/vaults.js +147 -0
  190. package/script/src/schemas/info/vaults.js.map +1 -0
  191. package/script/src/schemas/mod.d.ts +101 -0
  192. package/script/src/schemas/mod.d.ts.map +1 -0
  193. package/script/src/schemas/mod.js +157 -0
  194. package/script/src/schemas/mod.js.map +1 -0
  195. package/script/src/schemas/subscriptions/requests.d.ts +332 -0
  196. package/script/src/schemas/subscriptions/requests.d.ts.map +1 -0
  197. package/script/src/schemas/subscriptions/requests.js +295 -0
  198. package/script/src/schemas/subscriptions/requests.js.map +1 -0
  199. package/script/src/schemas/subscriptions/responses.d.ts +3643 -0
  200. package/script/src/schemas/subscriptions/responses.d.ts.map +1 -0
  201. package/script/src/schemas/subscriptions/responses.js +270 -0
  202. package/script/src/schemas/subscriptions/responses.js.map +1 -0
  203. package/script/src/signing/_signTypedData/ethers.js +1 -0
  204. package/script/src/signing/_signTypedData/ethers.js.map +1 -0
  205. package/script/src/signing/_signTypedData/mod.js +1 -0
  206. package/script/src/signing/_signTypedData/mod.js.map +1 -0
  207. package/script/src/signing/_signTypedData/private_key.js +1 -0
  208. package/script/src/signing/_signTypedData/private_key.js.map +1 -0
  209. package/script/src/signing/_signTypedData/viem.js +1 -0
  210. package/script/src/signing/_signTypedData/viem.js.map +1 -0
  211. package/script/src/signing/mod.d.ts +109 -29
  212. package/script/src/signing/mod.d.ts.map +1 -1
  213. package/script/src/signing/mod.js +138 -33
  214. package/script/src/signing/mod.js.map +1 -0
  215. package/script/src/transports/base.d.ts +4 -4
  216. package/script/src/transports/base.d.ts.map +1 -1
  217. package/script/src/transports/base.js +4 -3
  218. package/script/src/transports/base.js.map +1 -0
  219. package/script/src/transports/http/http_transport.d.ts +3 -2
  220. package/script/src/transports/http/http_transport.d.ts.map +1 -1
  221. package/script/src/transports/http/http_transport.js +1 -0
  222. package/script/src/transports/http/http_transport.js.map +1 -0
  223. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +1 -1
  224. package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -1
  225. package/script/src/transports/websocket/_hyperliquid_event_target.js +1 -0
  226. package/script/src/transports/websocket/_hyperliquid_event_target.js.map +1 -0
  227. package/script/src/transports/websocket/_reconnecting_websocket.js +1 -0
  228. package/script/src/transports/websocket/_reconnecting_websocket.js.map +1 -0
  229. package/script/src/transports/websocket/_websocket_async_request.js +1 -0
  230. package/script/src/transports/websocket/_websocket_async_request.js.map +1 -0
  231. package/script/src/transports/websocket/websocket_transport.d.ts +9 -1
  232. package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
  233. package/script/src/transports/websocket/websocket_transport.js +4 -0
  234. package/script/src/transports/websocket/websocket_transport.js.map +1 -0
  235. package/src/mod.ts +28 -0
  236. package/src/src/clients/exchange.ts +2246 -0
  237. package/src/src/clients/info.ts +2076 -0
  238. package/src/src/clients/multiSign.ts +183 -0
  239. package/src/src/clients/subscription.ts +841 -0
  240. package/src/src/errors.ts +7 -0
  241. package/src/src/schemas/_base.ts +43 -0
  242. package/src/src/schemas/exchange/requests.ts +3057 -0
  243. package/src/src/schemas/exchange/responses.ts +540 -0
  244. package/src/src/schemas/explorer/requests.ts +65 -0
  245. package/src/src/schemas/explorer/responses.ts +138 -0
  246. package/src/src/schemas/info/accounts.ts +1490 -0
  247. package/src/src/schemas/info/assets.ts +693 -0
  248. package/src/src/schemas/info/markets.ts +171 -0
  249. package/src/src/schemas/info/orders.ts +597 -0
  250. package/src/src/schemas/info/requests.ts +1369 -0
  251. package/src/src/schemas/info/validators.ts +299 -0
  252. package/src/src/schemas/info/vaults.ts +262 -0
  253. package/src/src/schemas/mod.ts +121 -0
  254. package/src/src/schemas/subscriptions/requests.ts +504 -0
  255. package/src/src/schemas/subscriptions/responses.ts +576 -0
  256. package/src/src/signing/_signTypedData/ethers.ts +59 -0
  257. package/src/src/signing/_signTypedData/mod.ts +121 -0
  258. package/src/src/signing/_signTypedData/private_key.ts +229 -0
  259. package/src/src/signing/_signTypedData/viem.ts +55 -0
  260. package/src/src/signing/mod.ts +572 -0
  261. package/src/src/transports/base.ts +54 -0
  262. package/src/src/transports/http/http_transport.ts +208 -0
  263. package/src/src/transports/websocket/_hyperliquid_event_target.ts +118 -0
  264. package/src/src/transports/websocket/_reconnecting_websocket.ts +404 -0
  265. package/src/src/transports/websocket/_websocket_async_request.ts +229 -0
  266. package/src/src/transports/websocket/websocket_transport.ts +394 -0
  267. package/esm/src/base.d.ts.map +0 -1
  268. package/esm/src/signing/_sorter.d.ts +0 -127
  269. package/esm/src/signing/_sorter.d.ts.map +0 -1
  270. package/esm/src/signing/_sorter.js +0 -693
  271. package/esm/src/types/exchange/requests.d.ts +0 -1345
  272. package/esm/src/types/exchange/requests.d.ts.map +0 -1
  273. package/esm/src/types/exchange/requests.js +0 -1
  274. package/esm/src/types/exchange/responses.d.ts +0 -233
  275. package/esm/src/types/exchange/responses.d.ts.map +0 -1
  276. package/esm/src/types/exchange/responses.js +0 -1
  277. package/esm/src/types/explorer/requests.d.ts +0 -32
  278. package/esm/src/types/explorer/requests.d.ts.map +0 -1
  279. package/esm/src/types/explorer/requests.js +0 -1
  280. package/esm/src/types/explorer/responses.d.ts +0 -58
  281. package/esm/src/types/explorer/responses.d.ts.map +0 -1
  282. package/esm/src/types/explorer/responses.js +0 -1
  283. package/esm/src/types/info/accounts.d.ts +0 -864
  284. package/esm/src/types/info/accounts.d.ts.map +0 -1
  285. package/esm/src/types/info/accounts.js +0 -1
  286. package/esm/src/types/info/assets.d.ts +0 -354
  287. package/esm/src/types/info/assets.d.ts.map +0 -1
  288. package/esm/src/types/info/assets.js +0 -1
  289. package/esm/src/types/info/markets.d.ts +0 -79
  290. package/esm/src/types/info/markets.d.ts.map +0 -1
  291. package/esm/src/types/info/markets.js +0 -1
  292. package/esm/src/types/info/orders.d.ts +0 -266
  293. package/esm/src/types/info/orders.d.ts.map +0 -1
  294. package/esm/src/types/info/orders.js +0 -1
  295. package/esm/src/types/info/requests.d.ts +0 -640
  296. package/esm/src/types/info/requests.d.ts.map +0 -1
  297. package/esm/src/types/info/requests.js +0 -1
  298. package/esm/src/types/info/validators.d.ts +0 -147
  299. package/esm/src/types/info/validators.d.ts.map +0 -1
  300. package/esm/src/types/info/validators.js +0 -1
  301. package/esm/src/types/info/vaults.d.ts +0 -119
  302. package/esm/src/types/info/vaults.d.ts.map +0 -1
  303. package/esm/src/types/info/vaults.js +0 -1
  304. package/esm/src/types/mod.d.ts +0 -38
  305. package/esm/src/types/mod.d.ts.map +0 -1
  306. package/esm/src/types/mod.js +0 -24
  307. package/esm/src/types/subscriptions/requests.d.ts +0 -154
  308. package/esm/src/types/subscriptions/requests.d.ts.map +0 -1
  309. package/esm/src/types/subscriptions/requests.js +0 -1
  310. package/esm/src/types/subscriptions/responses.d.ts +0 -238
  311. package/esm/src/types/subscriptions/responses.d.ts.map +0 -1
  312. package/esm/src/types/subscriptions/responses.js +0 -1
  313. package/script/src/base.d.ts.map +0 -1
  314. package/script/src/signing/_sorter.d.ts +0 -127
  315. package/script/src/signing/_sorter.d.ts.map +0 -1
  316. package/script/src/signing/_sorter.js +0 -696
  317. package/script/src/types/exchange/requests.d.ts +0 -1345
  318. package/script/src/types/exchange/requests.d.ts.map +0 -1
  319. package/script/src/types/exchange/requests.js +0 -2
  320. package/script/src/types/exchange/responses.d.ts +0 -233
  321. package/script/src/types/exchange/responses.d.ts.map +0 -1
  322. package/script/src/types/exchange/responses.js +0 -2
  323. package/script/src/types/explorer/requests.d.ts +0 -32
  324. package/script/src/types/explorer/requests.d.ts.map +0 -1
  325. package/script/src/types/explorer/requests.js +0 -2
  326. package/script/src/types/explorer/responses.d.ts +0 -58
  327. package/script/src/types/explorer/responses.d.ts.map +0 -1
  328. package/script/src/types/explorer/responses.js +0 -2
  329. package/script/src/types/info/accounts.d.ts +0 -864
  330. package/script/src/types/info/accounts.d.ts.map +0 -1
  331. package/script/src/types/info/accounts.js +0 -2
  332. package/script/src/types/info/assets.d.ts +0 -354
  333. package/script/src/types/info/assets.d.ts.map +0 -1
  334. package/script/src/types/info/assets.js +0 -2
  335. package/script/src/types/info/markets.d.ts +0 -79
  336. package/script/src/types/info/markets.d.ts.map +0 -1
  337. package/script/src/types/info/markets.js +0 -2
  338. package/script/src/types/info/orders.d.ts +0 -266
  339. package/script/src/types/info/orders.d.ts.map +0 -1
  340. package/script/src/types/info/orders.js +0 -2
  341. package/script/src/types/info/requests.d.ts +0 -640
  342. package/script/src/types/info/requests.d.ts.map +0 -1
  343. package/script/src/types/info/requests.js +0 -2
  344. package/script/src/types/info/validators.d.ts +0 -147
  345. package/script/src/types/info/validators.d.ts.map +0 -1
  346. package/script/src/types/info/validators.js +0 -2
  347. package/script/src/types/info/vaults.d.ts +0 -119
  348. package/script/src/types/info/vaults.d.ts.map +0 -1
  349. package/script/src/types/info/vaults.js +0 -2
  350. package/script/src/types/mod.d.ts +0 -38
  351. package/script/src/types/mod.d.ts.map +0 -1
  352. package/script/src/types/mod.js +0 -25
  353. package/script/src/types/subscriptions/requests.d.ts +0 -154
  354. package/script/src/types/subscriptions/requests.d.ts.map +0 -1
  355. package/script/src/types/subscriptions/requests.js +0 -2
  356. package/script/src/types/subscriptions/responses.d.ts +0 -238
  357. package/script/src/types/subscriptions/responses.d.ts.map +0 -1
  358. package/script/src/types/subscriptions/responses.js +0 -2
@@ -0,0 +1,2246 @@
1
+ import { HyperliquidError } from "../errors.js";
2
+ import type { IRequestTransport } from "../transports/base.js";
3
+ import {
4
+ ApproveAgentRequest,
5
+ ApproveBuilderFeeRequest,
6
+ BatchModifyRequest,
7
+ CancelByCloidRequest,
8
+ CancelRequest,
9
+ type CancelResponse,
10
+ type CancelSuccessResponse,
11
+ CDepositRequest,
12
+ ClaimRewardsRequest,
13
+ ConvertToMultiSigUserRequest,
14
+ type ConvertToMultiSigUserRequestSigners,
15
+ CreateSubAccountRequest,
16
+ type CreateSubAccountResponse,
17
+ CreateVaultRequest,
18
+ type CreateVaultResponse,
19
+ CSignerActionRequest,
20
+ CValidatorActionRequest,
21
+ CWithdrawRequest,
22
+ type ErrorResponse,
23
+ EvmUserModifyRequest,
24
+ ModifyRequest,
25
+ MultiSigRequest,
26
+ NoopRequest,
27
+ OrderRequest,
28
+ type OrderResponse,
29
+ type OrderSuccessResponse,
30
+ parser,
31
+ PerpDeployRequest,
32
+ RegisterReferrerRequest,
33
+ ReserveRequestWeightRequest,
34
+ ScheduleCancelRequest,
35
+ SendAssetRequest,
36
+ SetDisplayNameRequest,
37
+ SetReferrerRequest,
38
+ SpotDeployRequest,
39
+ SpotSendRequest,
40
+ SpotUserRequest,
41
+ SubAccountModifyRequest,
42
+ SubAccountSpotTransferRequest,
43
+ SubAccountTransferRequest,
44
+ type SuccessResponse,
45
+ TokenDelegateRequest,
46
+ TwapCancelRequest,
47
+ type TwapCancelResponse,
48
+ type TwapCancelSuccessResponse,
49
+ TwapOrderRequest,
50
+ type TwapOrderResponse,
51
+ type TwapOrderSuccessResponse,
52
+ UpdateIsolatedMarginRequest,
53
+ UpdateLeverageRequest,
54
+ UsdClassTransferRequest,
55
+ UsdSendRequest,
56
+ VaultDistributeRequest,
57
+ VaultModifyRequest,
58
+ VaultTransferRequest,
59
+ Withdraw3Request,
60
+ } from "../schemas/mod.js";
61
+ import {
62
+ type AbstractWallet,
63
+ getWalletChainId,
64
+ signL1Action,
65
+ signMultiSigAction,
66
+ signUserSignedAction,
67
+ userSignedActionEip712Types,
68
+ } from "../signing/mod.js";
69
+
70
+ type MaybePromise<T> = T | Promise<T>;
71
+
72
+ /** @see https://github.com/microsoft/TypeScript/issues/13923#issuecomment-2191862501 */
73
+ type DeepImmutable<T> = {
74
+ readonly [K in keyof T]: DeepImmutable<T[K]>;
75
+ };
76
+
77
+ /** Parameters for the {@linkcode ExchangeClient} constructor. */
78
+ export interface ExchangeClientParameters<
79
+ T extends IRequestTransport = IRequestTransport,
80
+ W extends AbstractWallet = AbstractWallet,
81
+ > {
82
+ /** The transport used to connect to the Hyperliquid API. */
83
+ transport: T;
84
+ /** The viem or ethers.js wallet used for signing transactions. */
85
+ wallet: W;
86
+ /** Sets a default vaultAddress to be used if no vaultAddress is explicitly passed to a method. */
87
+ defaultVaultAddress?: `0x${string}`;
88
+ /** Sets a default expiresAfter to be used if no expiresAfter is explicitly passed to a method. */
89
+ defaultExpiresAfter?: number | (() => MaybePromise<number>);
90
+ /**
91
+ * The network that will be used to sign transactions.
92
+ * Must match the network of the {@link wallet}.
93
+ *
94
+ * Defaults to get chain id from wallet otherwise `0x1`.
95
+ */
96
+ signatureChainId?: `0x${string}` | (() => MaybePromise<`0x${string}`>);
97
+ /**
98
+ * Function to get the next nonce for signing transactions.
99
+ *
100
+ * Defaults to a function that returns the current timestamp or, if duplicated, increments the last nonce.
101
+ */
102
+ nonceManager?: () => MaybePromise<number>;
103
+ }
104
+
105
+ // deno-lint-ignore no-explicit-any
106
+ type DistributiveOmit<T, K extends keyof any> = T extends unknown ? Omit<T, K> : never;
107
+ type ExtractRequestAction<T extends { action: Record<string, unknown> }> = T["action"] extends
108
+ { signatureChainId: unknown }
109
+ ? DistributiveOmit<T["action"], "type" | "signatureChainId" | "hyperliquidChain" | "nonce" | "time"> // user-signed actions
110
+ : DistributiveOmit<T["action"], "type">; // L1 actions
111
+ /** Action parameters for the {@linkcode ExchangeClient.approveAgent} method. */
112
+ export type ApproveAgentParameters = ExtractRequestAction<ApproveAgentRequest>;
113
+ /** Action parameters for the {@linkcode ExchangeClient.approveBuilderFee} method. */
114
+ export type ApproveBuilderFeeParameters = ExtractRequestAction<ApproveBuilderFeeRequest>;
115
+ /** Action parameters for the {@linkcode ExchangeClient.batchModify} method. */
116
+ export type BatchModifyParameters = ExtractRequestAction<BatchModifyRequest>;
117
+ /** Action parameters for the {@linkcode ExchangeClient.cancel} method. */
118
+ export type CancelParameters = ExtractRequestAction<CancelRequest>;
119
+ /** Action parameters for the {@linkcode ExchangeClient.cancelByCloid} method. */
120
+ export type CancelByCloidParameters = ExtractRequestAction<CancelByCloidRequest>;
121
+ /** Action parameters for the {@linkcode ExchangeClient.cDeposit} method. */
122
+ export type CDepositParameters = ExtractRequestAction<CDepositRequest>;
123
+ /** Action parameters for the {@linkcode ExchangeClient.convertToMultiSigUser} method. */
124
+ export type ConvertToMultiSigUserParameters =
125
+ & Omit<ExtractRequestAction<ConvertToMultiSigUserRequest>, "signers">
126
+ & {
127
+ /** Signers configuration. */
128
+ signers: ConvertToMultiSigUserRequestSigners;
129
+ };
130
+ /** Action parameters for the {@linkcode ExchangeClient.createSubAccount} method. */
131
+ export type CreateSubAccountParameters = ExtractRequestAction<CreateSubAccountRequest>;
132
+ /** Action parameters for the {@linkcode ExchangeClient.createVault} method. */
133
+ export type CreateVaultParameters = ExtractRequestAction<CreateVaultRequest>;
134
+ /** Action parameters for the {@linkcode ExchangeClient.cSignerAction} method. */
135
+ export type CSignerActionParameters = ExtractRequestAction<CSignerActionRequest>;
136
+ /** Action parameters for the {@linkcode ExchangeClient.cValidatorAction} method. */
137
+ export type CValidatorActionParameters = ExtractRequestAction<CValidatorActionRequest>;
138
+ /** Action parameters for the {@linkcode ExchangeClient.cWithdraw} method. */
139
+ export type CWithdrawParameters = ExtractRequestAction<CWithdrawRequest>;
140
+ /** Action parameters for the {@linkcode ExchangeClient.evmUserModify} method. */
141
+ export type EvmUserModifyParameters = ExtractRequestAction<EvmUserModifyRequest>;
142
+ /** Action parameters for the {@linkcode ExchangeClient.modify} method. */
143
+ export type ModifyParameters = ExtractRequestAction<ModifyRequest>;
144
+ /** Action parameters for the {@linkcode ExchangeClient.multiSig} method. */
145
+ export type MultiSigParameters = ExtractRequestAction<MultiSigRequest> & Pick<MultiSigRequest, "nonce">;
146
+ /** Action parameters for the {@linkcode ExchangeClient.order} method. */
147
+ export type OrderParameters = ExtractRequestAction<OrderRequest>;
148
+ /** Action parameters for the {@linkcode ExchangeClient.perpDeploy} method. */
149
+ export type PerpDeployParameters = ExtractRequestAction<PerpDeployRequest>;
150
+ /** Action parameters for the {@linkcode ExchangeClient.registerReferrer} method. */
151
+ export type RegisterReferrerParameters = ExtractRequestAction<RegisterReferrerRequest>;
152
+ /** Action parameters for the {@linkcode ExchangeClient.reserveRequestWeight} method. */
153
+ export type ReserveRequestWeightParameters = ExtractRequestAction<ReserveRequestWeightRequest>;
154
+ /** Action parameters for the {@linkcode ExchangeClient.scheduleCancel} method. */
155
+ export type ScheduleCancelParameters = ExtractRequestAction<ScheduleCancelRequest>;
156
+ /** Action parameters for the {@linkcode ExchangeClient.sendAsset} method. */
157
+ export type SendAssetParameters = ExtractRequestAction<SendAssetRequest>;
158
+ /** Action parameters for the {@linkcode ExchangeClient.setDisplayName} method. */
159
+ export type SetDisplayNameParameters = ExtractRequestAction<SetDisplayNameRequest>;
160
+ /** Action parameters for the {@linkcode ExchangeClient.setReferrer} method. */
161
+ export type SetReferrerParameters = ExtractRequestAction<SetReferrerRequest>;
162
+ /** Action parameters for the {@linkcode ExchangeClient.spotDeploy} method. */
163
+ export type SpotDeployParameters = ExtractRequestAction<SpotDeployRequest>;
164
+ /** Action parameters for the {@linkcode ExchangeClient.spotSend} method. */
165
+ export type SpotSendParameters = ExtractRequestAction<SpotSendRequest>;
166
+ /** Action parameters for the {@linkcode ExchangeClient.spotUser} method. */
167
+ export type SpotUserParameters = ExtractRequestAction<SpotUserRequest>;
168
+ /** Action parameters for the {@linkcode ExchangeClient.subAccountModify} method. */
169
+ export type SubAccountModifyParameters = ExtractRequestAction<SubAccountModifyRequest>;
170
+ /** Action parameters for the {@linkcode ExchangeClient.subAccountSpotTransfer} method. */
171
+ export type SubAccountSpotTransferParameters = ExtractRequestAction<SubAccountSpotTransferRequest>;
172
+ /** Action parameters for the {@linkcode ExchangeClient.subAccountTransfer} method. */
173
+ export type SubAccountTransferParameters = ExtractRequestAction<SubAccountTransferRequest>;
174
+ /** Action parameters for the {@linkcode ExchangeClient.tokenDelegate} method. */
175
+ export type TokenDelegateParameters = ExtractRequestAction<TokenDelegateRequest>;
176
+ /** Action parameters for the {@linkcode ExchangeClient.twapCancel} method. */
177
+ export type TwapCancelParameters = ExtractRequestAction<TwapCancelRequest>;
178
+ /** Action parameters for the {@linkcode ExchangeClient.twapOrder} method. */
179
+ export type TwapOrderParameters = ExtractRequestAction<TwapOrderRequest>;
180
+ /** Action parameters for the {@linkcode ExchangeClient.updateIsolatedMargin} method. */
181
+ export type UpdateIsolatedMarginParameters = ExtractRequestAction<UpdateIsolatedMarginRequest>;
182
+ /** Action parameters for the {@linkcode ExchangeClient.updateLeverage} method. */
183
+ export type UpdateLeverageParameters = ExtractRequestAction<UpdateLeverageRequest>;
184
+ /** Action parameters for the {@linkcode ExchangeClient.usdClassTransfer} method. */
185
+ export type UsdClassTransferParameters = ExtractRequestAction<UsdClassTransferRequest>;
186
+ /** Action parameters for the {@linkcode ExchangeClient.usdSend} method. */
187
+ export type UsdSendParameters = ExtractRequestAction<UsdSendRequest>;
188
+ /** Action parameters for the {@linkcode ExchangeClient.vaultDistribute} method. */
189
+ export type VaultDistributeParameters = ExtractRequestAction<VaultDistributeRequest>;
190
+ /** Action parameters for the {@linkcode ExchangeClient.vaultModify} method. */
191
+ export type VaultModifyParameters = ExtractRequestAction<VaultModifyRequest>;
192
+ /** Action parameters for the {@linkcode ExchangeClient.vaultTransfer} method. */
193
+ export type VaultTransferParameters = ExtractRequestAction<VaultTransferRequest>;
194
+ /** Action parameters for the {@linkcode ExchangeClient.withdraw3} method. */
195
+ export type Withdraw3Parameters = ExtractRequestAction<Withdraw3Request>;
196
+
197
+ interface BaseRequestOptions {
198
+ /**
199
+ * An {@linkcode https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal | AbortSignal}
200
+ * If this option is set, the request can be canceled by calling {@linkcode https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort | abort()}
201
+ * on the corresponding {@linkcode https://developer.mozilla.org/en-US/docs/Web/API/AbortController | AbortController}.
202
+ */
203
+ signal?: AbortSignal;
204
+ }
205
+ type ExtractRequestOptions<T extends { action: Record<string, unknown> }> =
206
+ & BaseRequestOptions
207
+ & Omit<T, "action" | "nonce" | "signature">;
208
+ /** Request options for the {@linkcode ExchangeClient.approveAgent} method. */
209
+ export type ApproveAgentOptions = ExtractRequestOptions<ApproveAgentRequest>;
210
+ /** Request options for the {@linkcode ExchangeClient.approveBuilderFee} method. */
211
+ export type ApproveBuilderFeeOptions = ExtractRequestOptions<ApproveBuilderFeeRequest>;
212
+ /** Request options for the {@linkcode ExchangeClient.batchModify} method. */
213
+ export type BatchModifyOptions = ExtractRequestOptions<BatchModifyRequest>;
214
+ /** Request options for the {@linkcode ExchangeClient.cancel} method. */
215
+ export type CancelOptions = ExtractRequestOptions<CancelRequest>;
216
+ /** Request options for the {@linkcode ExchangeClient.cancelByCloid} method. */
217
+ export type CancelByCloidOptions = ExtractRequestOptions<CancelByCloidRequest>;
218
+ /** Request options for the {@linkcode ExchangeClient.cDeposit} method. */
219
+ export type CDepositOptions = ExtractRequestOptions<CDepositRequest>;
220
+ /** Request options for the {@linkcode ExchangeClient.claimRewards} method. */
221
+ export type ClaimRewardsOptions = ExtractRequestOptions<ClaimRewardsRequest>;
222
+ /** Request options for the {@linkcode ExchangeClient.convertToMultiSigUser} method. */
223
+ export type ConvertToMultiSigUserOptions = ExtractRequestOptions<ConvertToMultiSigUserRequest>;
224
+ /** Request options for the {@linkcode ExchangeClient.createSubAccount} method. */
225
+ export type CreateSubAccountOptions = ExtractRequestOptions<CreateSubAccountRequest>;
226
+ /** Request options for the {@linkcode ExchangeClient.createVault} method. */
227
+ export type CreateVaultOptions = ExtractRequestOptions<CreateVaultRequest>;
228
+ /** Request options for the {@linkcode ExchangeClient.cSignerAction} method. */
229
+ export type CSignerActionOptions = ExtractRequestOptions<CSignerActionRequest>;
230
+ /** Request options for the {@linkcode ExchangeClient.cValidatorAction} method. */
231
+ export type CValidatorActionOptions = ExtractRequestOptions<CValidatorActionRequest>;
232
+ /** Request options for the {@linkcode ExchangeClient.cWithdraw} method. */
233
+ export type CWithdrawOptions = ExtractRequestOptions<CWithdrawRequest>;
234
+ /** Request options for the {@linkcode ExchangeClient.evmUserModify} method. */
235
+ export type EvmUserModifyOptions = ExtractRequestOptions<EvmUserModifyRequest>;
236
+ /** Request options for the {@linkcode ExchangeClient.modify} method. */
237
+ export type ModifyOptions = ExtractRequestOptions<ModifyRequest>;
238
+ /** Request options for the {@linkcode ExchangeClient.multiSig} method. */
239
+ export type MultiSigOptions = ExtractRequestOptions<MultiSigRequest>;
240
+ /** Request options for the {@linkcode ExchangeClient.noop} method. */
241
+ export type NoopOptions = ExtractRequestOptions<NoopRequest>;
242
+ /** Request options for the {@linkcode ExchangeClient.order} method. */
243
+ export type OrderOptions = ExtractRequestOptions<OrderRequest>;
244
+ /** Request options for the {@linkcode ExchangeClient.perpDeploy} method. */
245
+ export type PerpDeployOptions = ExtractRequestOptions<PerpDeployRequest>;
246
+ /** Request options for the {@linkcode ExchangeClient.registerReferrer} method. */
247
+ export type RegisterReferrerOptions = ExtractRequestOptions<RegisterReferrerRequest>;
248
+ /** Request options for the {@linkcode ExchangeClient.reserveRequestWeight} method. */
249
+ export type ReserveRequestWeightOptions = ExtractRequestOptions<ReserveRequestWeightRequest>;
250
+ /** Request options for the {@linkcode ExchangeClient.scheduleCancel} method. */
251
+ export type ScheduleCancelOptions = ExtractRequestOptions<ScheduleCancelRequest>;
252
+ /** Request options for the {@linkcode ExchangeClient.sendAsset} method. */
253
+ export type SendAssetOptions = ExtractRequestOptions<SendAssetRequest>;
254
+ /** Request options for the {@linkcode ExchangeClient.setDisplayName} method. */
255
+ export type SetDisplayNameOptions = ExtractRequestOptions<SetDisplayNameRequest>;
256
+ /** Request options for the {@linkcode ExchangeClient.setReferrer} method. */
257
+ export type SetReferrerOptions = ExtractRequestOptions<SetReferrerRequest>;
258
+ /** Request options for the {@linkcode ExchangeClient.spotDeploy} method. */
259
+ export type SpotDeployOptions = ExtractRequestOptions<SpotDeployRequest>;
260
+ /** Request options for the {@linkcode ExchangeClient.spotSend} method. */
261
+ export type SpotSendOptions = ExtractRequestOptions<SpotSendRequest>;
262
+ /** Request options for the {@linkcode ExchangeClient.spotUser} method. */
263
+ export type SpotUserOptions = ExtractRequestOptions<SpotUserRequest>;
264
+ /** Request options for the {@linkcode ExchangeClient.subAccountModify} method. */
265
+ export type SubAccountModifyOptions = ExtractRequestOptions<SubAccountModifyRequest>;
266
+ /** Request options for the {@linkcode ExchangeClient.subAccountSpotTransfer} method. */
267
+ export type SubAccountSpotTransferOptions = ExtractRequestOptions<SubAccountSpotTransferRequest>;
268
+ /** Request options for the {@linkcode ExchangeClient.subAccountTransfer} method. */
269
+ export type SubAccountTransferOptions = ExtractRequestOptions<SubAccountTransferRequest>;
270
+ /** Request options for the {@linkcode ExchangeClient.tokenDelegate} method. */
271
+ export type TokenDelegateOptions = ExtractRequestOptions<TokenDelegateRequest>;
272
+ /** Request options for the {@linkcode ExchangeClient.twapCancel} method. */
273
+ export type TwapCancelOptions = ExtractRequestOptions<TwapCancelRequest>;
274
+ /** Request options for the {@linkcode ExchangeClient.twapOrder} method. */
275
+ export type TwapOrderOptions = ExtractRequestOptions<TwapOrderRequest>;
276
+ /** Request options for the {@linkcode ExchangeClient.updateIsolatedMargin} method. */
277
+ export type UpdateIsolatedMarginOptions = ExtractRequestOptions<UpdateIsolatedMarginRequest>;
278
+ /** Request options for the {@linkcode ExchangeClient.updateLeverage} method. */
279
+ export type UpdateLeverageOptions = ExtractRequestOptions<UpdateLeverageRequest>;
280
+ /** Request options for the {@linkcode ExchangeClient.usdClassTransfer} method. */
281
+ export type UsdClassTransferOptions = ExtractRequestOptions<UsdClassTransferRequest>;
282
+ /** Request options for the {@linkcode ExchangeClient.usdSend} method. */
283
+ export type UsdSendOptions = ExtractRequestOptions<UsdSendRequest>;
284
+ /** Request options for the {@linkcode ExchangeClient.vaultDistribute} method. */
285
+ export type VaultDistributeOptions = ExtractRequestOptions<VaultDistributeRequest>;
286
+ /** Request options for the {@linkcode ExchangeClient.vaultModify} method. */
287
+ export type VaultModifyOptions = ExtractRequestOptions<VaultModifyRequest>;
288
+ /** Request options for the {@linkcode ExchangeClient.vaultTransfer} method. */
289
+ export type VaultTransferOptions = ExtractRequestOptions<VaultTransferRequest>;
290
+ /** Request options for the {@linkcode ExchangeClient.withdraw3} method. */
291
+ export type Withdraw3Options = ExtractRequestOptions<Withdraw3Request>;
292
+
293
+ /** Thrown when an API request fails. */
294
+ export class ApiRequestError extends HyperliquidError {
295
+ constructor(
296
+ public response:
297
+ | ErrorResponse
298
+ | OrderResponse
299
+ | CancelResponse
300
+ | TwapOrderResponse
301
+ | TwapCancelResponse,
302
+ ) {
303
+ let message;
304
+ if (response.status === "err") {
305
+ // ErrorResponse
306
+ message = response.response;
307
+ } else {
308
+ if ("statuses" in response.response.data) {
309
+ // OrderResponse | CancelResponse
310
+ const errors = response.response.data.statuses.reduce<string[]>((acc, status, index) => {
311
+ if (typeof status === "object" && "error" in status) {
312
+ acc.push(`Order ${index}: ${status.error}`);
313
+ }
314
+ return acc;
315
+ }, []);
316
+ if (errors.length > 0) {
317
+ message = errors.join(", ");
318
+ }
319
+ } else {
320
+ // TwapOrderResponse | TwapCancelResponse
321
+ if (typeof response.response.data.status === "object" && "error" in response.response.data.status) {
322
+ message = response.response.data.status.error;
323
+ }
324
+ }
325
+ }
326
+
327
+ super(message || "An unknown error occurred while processing an API request. See `response` for more details.");
328
+ this.name = "ApiRequestError";
329
+ }
330
+ }
331
+
332
+ /** Nonce manager for generating unique nonces for signing transactions. */
333
+ class NonceManager {
334
+ /** The last nonce used for signing transactions. */
335
+ private lastNonce = 0;
336
+
337
+ /**
338
+ * Gets the next nonce for signing transactions.
339
+ * @returns The next nonce.
340
+ */
341
+ getNonce(): number {
342
+ let nonce = Date.now();
343
+ if (nonce <= this.lastNonce) {
344
+ nonce = ++this.lastNonce;
345
+ } else {
346
+ this.lastNonce = nonce;
347
+ }
348
+ return nonce;
349
+ }
350
+ }
351
+
352
+ /**
353
+ * Exchange client for interacting with the Hyperliquid API.
354
+ * @typeParam T The transport used to connect to the Hyperliquid API.
355
+ * @typeParam W The wallet used for signing transactions.
356
+ */
357
+ export class ExchangeClient<
358
+ T extends IRequestTransport = IRequestTransport,
359
+ W extends AbstractWallet = AbstractWallet,
360
+ > implements ExchangeClientParameters<T, W>, AsyncDisposable {
361
+ transport: T;
362
+ wallet: W;
363
+ defaultVaultAddress?: `0x${string}`;
364
+ defaultExpiresAfter?: number | (() => MaybePromise<number>);
365
+ signatureChainId: `0x${string}` | (() => MaybePromise<`0x${string}`>);
366
+ nonceManager: () => MaybePromise<number>;
367
+
368
+ /**
369
+ * Initialises a new instance.
370
+ * @param args - The parameters for the client.
371
+ *
372
+ * @example Private key directly
373
+ * ```ts
374
+ * import * as hl from "@nktkas/hyperliquid";
375
+ *
376
+ * const privateKey = "0x...";
377
+ *
378
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
379
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
380
+ * ```
381
+ *
382
+ * @example [Viem](https://viem.sh/docs/clients/wallet#local-accounts-private-key-mnemonic-etc)
383
+ * ```ts
384
+ * import * as hl from "@nktkas/hyperliquid";
385
+ * import { privateKeyToAccount } from "npm:viem/accounts";
386
+ *
387
+ * const account = privateKeyToAccount("0x...");
388
+ *
389
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
390
+ * const exchClient = new hl.ExchangeClient({ wallet: account, transport });
391
+ * ```
392
+ *
393
+ * @example [ethers.js](https://docs.ethers.org/v6/api/wallet/#Wallet) or [ethers.js v5](https://docs.ethers.org/v5/api/signer/#Wallet)
394
+ * ```ts
395
+ * import * as hl from "@nktkas/hyperliquid";
396
+ * import { ethers } from "npm:ethers";
397
+ *
398
+ * const wallet = new ethers.Wallet("0x...");
399
+ *
400
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
401
+ * const exchClient = new hl.ExchangeClient({ wallet, transport });
402
+ * ```
403
+ *
404
+ * @example External wallet (e.g. MetaMask) via [viem](https://viem.sh/docs/clients/wallet)
405
+ * ```ts
406
+ * import * as hl from "@nktkas/hyperliquid";
407
+ * import { createWalletClient, custom } from "npm:viem";
408
+ *
409
+ * const ethereum = (window as any).ethereum;
410
+ * const [account] = await ethereum.request({ method: "eth_requestAccounts" }) as `0x${string}`[];
411
+ * const wallet = createWalletClient({ account, transport: custom(ethereum) });
412
+ *
413
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
414
+ * const exchClient = new hl.ExchangeClient({ wallet, transport });
415
+ * ```
416
+ */
417
+ constructor(args: ExchangeClientParameters<T, W>) {
418
+ this.transport = args.transport;
419
+ this.wallet = args.wallet;
420
+ this.defaultVaultAddress = args.defaultVaultAddress;
421
+ this.defaultExpiresAfter = args.defaultExpiresAfter;
422
+ this.signatureChainId = args.signatureChainId ?? (() => getWalletChainId(this.wallet));
423
+ this.nonceManager = args.nonceManager ?? new NonceManager().getNonce;
424
+ }
425
+
426
+ /**
427
+ * Approve an agent to sign on behalf of the master account.
428
+ * @param params - Action-specific parameters.
429
+ * @param opts - Request execution options.
430
+ * @returns Successful response without specific data.
431
+ *
432
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
433
+ * @throws {TransportError} When the transport layer throws an error.
434
+ *
435
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-an-api-wallet
436
+ * @example
437
+ * ```ts
438
+ * import * as hl from "@nktkas/hyperliquid";
439
+ *
440
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
441
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
442
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
443
+ *
444
+ * await exchClient.approveAgent({ agentAddress: "0x...", agentName: "..." });
445
+ * ```
446
+ */
447
+ async approveAgent(
448
+ params: DeepImmutable<ApproveAgentParameters>,
449
+ opts?: ApproveAgentOptions,
450
+ ): Promise<SuccessResponse> {
451
+ const action = parser(ApproveAgentRequest.entries.action)({
452
+ type: "approveAgent",
453
+ hyperliquidChain: this._getHyperliquidChain(),
454
+ signatureChainId: await this._getSignatureChainId(),
455
+ nonce: await this.nonceManager(),
456
+ ...params,
457
+ });
458
+ return await this._executeUserSignedAction({ action }, opts?.signal);
459
+ }
460
+
461
+ /**
462
+ * Approve a maximum fee rate for a builder.
463
+ * @param params - Action-specific parameters.
464
+ * @param opts - Request execution options.
465
+ * @returns Successful response without specific data.
466
+ *
467
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
468
+ * @throws {TransportError} When the transport layer throws an error.
469
+ *
470
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-a-builder-fee
471
+ * @example
472
+ * ```ts
473
+ * import * as hl from "@nktkas/hyperliquid";
474
+ *
475
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
476
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
477
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
478
+ *
479
+ * await exchClient.approveBuilderFee({ maxFeeRate: "0.01%", builder: "0x..." });
480
+ * ```
481
+ */
482
+ async approveBuilderFee(
483
+ params: DeepImmutable<ApproveBuilderFeeParameters>,
484
+ opts?: ApproveBuilderFeeOptions,
485
+ ): Promise<SuccessResponse> {
486
+ const action = parser(ApproveBuilderFeeRequest.entries.action)({
487
+ type: "approveBuilderFee",
488
+ hyperliquidChain: this._getHyperliquidChain(),
489
+ signatureChainId: await this._getSignatureChainId(),
490
+ nonce: await this.nonceManager(),
491
+ ...params,
492
+ });
493
+ return await this._executeUserSignedAction({ action }, opts?.signal);
494
+ }
495
+
496
+ /**
497
+ * Modify multiple orders.
498
+ * @param params - Action-specific parameters.
499
+ * @param opts - Request execution options.
500
+ * @returns Successful variant of {@link OrderResponse} without error statuses.
501
+ *
502
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
503
+ * @throws {TransportError} When the transport layer throws an error.
504
+ *
505
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-multiple-orders
506
+ * @example
507
+ * ```ts
508
+ * import * as hl from "@nktkas/hyperliquid";
509
+ *
510
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
511
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
512
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
513
+ *
514
+ * const data = await exchClient.batchModify({
515
+ * modifies: [
516
+ * {
517
+ * oid: 123,
518
+ * order: {
519
+ * a: 0,
520
+ * b: true,
521
+ * p: "31000",
522
+ * s: "0.2",
523
+ * r: false,
524
+ * t: { limit: { tif: "Gtc" } },
525
+ * },
526
+ * },
527
+ * ],
528
+ * });
529
+ * ```
530
+ */
531
+ async batchModify(
532
+ params: DeepImmutable<BatchModifyParameters>,
533
+ opts?: BatchModifyOptions,
534
+ ): Promise<OrderSuccessResponse> {
535
+ const action = parser(BatchModifyRequest.entries.action)({
536
+ type: "batchModify",
537
+ ...params,
538
+ });
539
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
540
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
541
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
542
+ }
543
+
544
+ /**
545
+ * Cancel order(s).
546
+ * @param params - Action-specific parameters.
547
+ * @param opts - Request execution options.
548
+ * @returns Successful variant of {@link CancelResponse} without error statuses.
549
+ *
550
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
551
+ * @throws {TransportError} When the transport layer throws an error.
552
+ *
553
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s
554
+ * @example
555
+ * ```ts
556
+ * import * as hl from "@nktkas/hyperliquid";
557
+ *
558
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
559
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
560
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
561
+ *
562
+ * const data = await exchClient.cancel({
563
+ * cancels: [
564
+ * { a: 0, o: 123 },
565
+ * ],
566
+ * });
567
+ * ```
568
+ */
569
+ async cancel(
570
+ params: DeepImmutable<CancelParameters>,
571
+ opts?: CancelOptions,
572
+ ): Promise<CancelSuccessResponse> {
573
+ const action = parser(CancelRequest.entries.action)({
574
+ type: "cancel",
575
+ ...params,
576
+ });
577
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
578
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
579
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
580
+ }
581
+
582
+ /**
583
+ * Cancel order(s) by cloid.
584
+ * @param params - Action-specific parameters.
585
+ * @param opts - Request execution options.
586
+ * @returns Successful variant of {@link CancelResponse} without error statuses.
587
+ *
588
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
589
+ * @throws {TransportError} When the transport layer throws an error.
590
+ *
591
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
592
+ * @example
593
+ * ```ts
594
+ * import * as hl from "@nktkas/hyperliquid";
595
+ *
596
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
597
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
598
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
599
+ *
600
+ * const data = await exchClient.cancelByCloid({
601
+ * cancels: [
602
+ * { asset: 0, cloid: "0x..." },
603
+ * ],
604
+ * });
605
+ * ```
606
+ */
607
+ async cancelByCloid(
608
+ params: DeepImmutable<CancelByCloidParameters>,
609
+ opts?: CancelByCloidOptions,
610
+ ): Promise<CancelSuccessResponse> {
611
+ const action = parser(CancelByCloidRequest.entries.action)({
612
+ type: "cancelByCloid",
613
+ ...params,
614
+ });
615
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
616
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
617
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
618
+ }
619
+
620
+ /**
621
+ * Transfer native token from the user's spot account into staking for delegating to validators.
622
+ * @param params - Action-specific parameters.
623
+ * @param opts - Request execution options.
624
+ * @returns Successful response without specific data.
625
+ *
626
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
627
+ * @throws {TransportError} When the transport layer throws an error.
628
+ *
629
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-into-staking
630
+ * @example
631
+ * ```ts
632
+ * import * as hl from "@nktkas/hyperliquid";
633
+ *
634
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
635
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
636
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
637
+ *
638
+ * await exchClient.cDeposit({ wei: 1 * 1e8 });
639
+ * ```
640
+ */
641
+ async cDeposit(
642
+ params: DeepImmutable<CDepositParameters>,
643
+ opts?: CDepositOptions,
644
+ ): Promise<SuccessResponse> {
645
+ const action = parser(CDepositRequest.entries.action)({
646
+ type: "cDeposit",
647
+ hyperliquidChain: this._getHyperliquidChain(),
648
+ signatureChainId: await this._getSignatureChainId(),
649
+ nonce: await this.nonceManager(),
650
+ ...params,
651
+ });
652
+ return await this._executeUserSignedAction({ action }, opts?.signal);
653
+ }
654
+
655
+ /**
656
+ * Claim rewards from referral program.
657
+ * @param opts - Request execution options.
658
+ * @returns Successful response without specific data.
659
+ *
660
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
661
+ * @throws {TransportError} When the transport layer throws an error.
662
+ *
663
+ * @see null
664
+ * @example
665
+ * ```ts
666
+ * import * as hl from "@nktkas/hyperliquid";
667
+ *
668
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
669
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
670
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
671
+ *
672
+ * await exchClient.claimRewards();
673
+ * ```
674
+ */
675
+ async claimRewards(
676
+ opts?: ClaimRewardsOptions,
677
+ ): Promise<SuccessResponse> {
678
+ const action = parser(ClaimRewardsRequest.entries.action)({
679
+ type: "claimRewards",
680
+ });
681
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
682
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
683
+ }
684
+
685
+ /**
686
+ * Convert a single-signature account to a multi-signature account or vice versa.
687
+ * @param params - Action-specific parameters.
688
+ * @param opts - Request execution options.
689
+ * @returns Successful response without specific data.
690
+ *
691
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
692
+ * @throws {TransportError} When the transport layer throws an error.
693
+ *
694
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig
695
+ * @example
696
+ * ```ts
697
+ * import * as hl from "@nktkas/hyperliquid";
698
+ *
699
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
700
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
701
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
702
+ *
703
+ * // Convert to multi-sig user
704
+ * await exchClient.convertToMultiSigUser({
705
+ * signers: {
706
+ * authorizedUsers: ["0x...", "0x...", "0x..."],
707
+ * threshold: 2,
708
+ * },
709
+ * });
710
+ *
711
+ * // Convert to single-sig user
712
+ * await exchClient.convertToMultiSigUser({ signers: null });
713
+ * ```
714
+ */
715
+ async convertToMultiSigUser(
716
+ params: DeepImmutable<ConvertToMultiSigUserParameters>,
717
+ opts?: ConvertToMultiSigUserOptions,
718
+ ): Promise<SuccessResponse> {
719
+ const action = parser(ConvertToMultiSigUserRequest.entries.action)({
720
+ type: "convertToMultiSigUser",
721
+ hyperliquidChain: this._getHyperliquidChain(),
722
+ signatureChainId: await this._getSignatureChainId(),
723
+ nonce: await this.nonceManager(),
724
+ ...params,
725
+ });
726
+ return await this._executeUserSignedAction({ action }, opts?.signal);
727
+ }
728
+
729
+ /**
730
+ * Create a sub-account.
731
+ * @param params - Action-specific parameters.
732
+ * @param opts - Request execution options.
733
+ * @returns Response for creating a sub-account.
734
+ *
735
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
736
+ * @throws {TransportError} When the transport layer throws an error.
737
+ *
738
+ * @see null
739
+ * @example
740
+ * ```ts
741
+ * import * as hl from "@nktkas/hyperliquid";
742
+ *
743
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
744
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
745
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
746
+ *
747
+ * const data = await exchClient.createSubAccount({ name: "..." });
748
+ * ```
749
+ */
750
+ async createSubAccount(
751
+ params: DeepImmutable<CreateSubAccountParameters>,
752
+ opts?: CreateSubAccountOptions,
753
+ ): Promise<CreateSubAccountResponse> {
754
+ const action = parser(CreateSubAccountRequest.entries.action)({
755
+ type: "createSubAccount",
756
+ ...params,
757
+ });
758
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
759
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
760
+ }
761
+
762
+ /**
763
+ * Create a vault.
764
+ * @param params - Action-specific parameters.
765
+ * @param opts - Request execution options.
766
+ * @returns Response for creating a vault.
767
+ *
768
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
769
+ * @throws {TransportError} When the transport layer throws an error.
770
+ *
771
+ * @see null
772
+ * @example
773
+ * ```ts
774
+ * import * as hl from "@nktkas/hyperliquid";
775
+ *
776
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
777
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
778
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
779
+ *
780
+ * const data = await exchClient.createVault({
781
+ * name: "...",
782
+ * description: "...",
783
+ * initialUsd: 100 * 1e6,
784
+ * nonce: Date.now(),
785
+ * });
786
+ * ```
787
+ */
788
+ async createVault(
789
+ params: DeepImmutable<CreateVaultParameters>,
790
+ opts?: CreateVaultOptions,
791
+ ): Promise<CreateVaultResponse> {
792
+ const action = parser(CreateVaultRequest.entries.action)({
793
+ type: "createVault",
794
+ ...params,
795
+ });
796
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
797
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
798
+ }
799
+
800
+ /**
801
+ * Jail or unjail self as a validator signer.
802
+ * @param params - Action-specific parameters.
803
+ * @param opts - Request execution options.
804
+ * @returns Successful response without specific data.
805
+ *
806
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
807
+ * @throws {TransportError} When the transport layer throws an error.
808
+ *
809
+ * @see null
810
+ * @example
811
+ * ```ts
812
+ * import * as hl from "@nktkas/hyperliquid";
813
+ *
814
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
815
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
816
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
817
+ *
818
+ * // Jail self
819
+ * await exchClient.cSignerAction({ jailSelf: null });
820
+ *
821
+ * // Unjail self
822
+ * await exchClient.cSignerAction({ unjailSelf: null });
823
+ * ```
824
+ */
825
+ async cSignerAction(
826
+ params: DeepImmutable<CSignerActionParameters>,
827
+ opts?: CSignerActionOptions,
828
+ ): Promise<SuccessResponse> {
829
+ const action = parser(CSignerActionRequest.entries.action)({
830
+ type: "CSignerAction",
831
+ ...params,
832
+ });
833
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
834
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
835
+ }
836
+
837
+ /**
838
+ * Action related to validator management.
839
+ * @param params - Action-specific parameters.
840
+ * @param opts - Request execution options.
841
+ * @returns Successful response without specific data.
842
+ *
843
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
844
+ * @throws {TransportError} When the transport layer throws an error.
845
+ *
846
+ * @see null
847
+ * @example
848
+ * ```ts
849
+ * import * as hl from "@nktkas/hyperliquid";
850
+ *
851
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
852
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
853
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
854
+ *
855
+ * // Change validator profile
856
+ * await exchClient.cValidatorAction({
857
+ * changeProfile: {
858
+ * node_ip: { Ip: "1.2.3.4" },
859
+ * name: "...",
860
+ * description: "...",
861
+ * unjailed: true,
862
+ * disable_delegations: false,
863
+ * commission_bps: null,
864
+ * signer: null,
865
+ * },
866
+ * });
867
+ *
868
+ * // Register a new validator
869
+ * await exchClient.cValidatorAction({
870
+ * register: {
871
+ * profile: {
872
+ * node_ip: { Ip: "1.2.3.4" },
873
+ * name: "...",
874
+ * description: "...",
875
+ * delegations_disabled: true,
876
+ * commission_bps: 1,
877
+ * signer: "0x...",
878
+ * },
879
+ * unjailed: false,
880
+ * initial_wei: 1,
881
+ * },
882
+ * });
883
+ *
884
+ * // Unregister a validator
885
+ * await exchClient.cValidatorAction({ unregister: null });
886
+ * ```
887
+ */
888
+ async cValidatorAction(
889
+ params: DeepImmutable<CValidatorActionParameters>,
890
+ opts?: CValidatorActionOptions,
891
+ ): Promise<SuccessResponse> {
892
+ const action = parser(CValidatorActionRequest.entries.action)({
893
+ type: "CValidatorAction",
894
+ ...params,
895
+ });
896
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
897
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
898
+ }
899
+
900
+ /**
901
+ * Transfer native token from staking into the user's spot account.
902
+ * @param params - Action-specific parameters.
903
+ * @param opts - Request execution options.
904
+ * @returns Successful response without specific data.
905
+ *
906
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
907
+ * @throws {TransportError} When the transport layer throws an error.
908
+ *
909
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#withdraw-from-staking
910
+ * @example
911
+ * ```ts
912
+ * import * as hl from "@nktkas/hyperliquid";
913
+ *
914
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
915
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
916
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
917
+ *
918
+ * await exchClient.cWithdraw({ wei: 1 * 1e8 });
919
+ * ```
920
+ */
921
+ async cWithdraw(
922
+ params: DeepImmutable<CWithdrawParameters>,
923
+ opts?: CWithdrawOptions,
924
+ ): Promise<SuccessResponse> {
925
+ const action = parser(CWithdrawRequest.entries.action)({
926
+ type: "cWithdraw",
927
+ hyperliquidChain: this._getHyperliquidChain(),
928
+ signatureChainId: await this._getSignatureChainId(),
929
+ nonce: await this.nonceManager(),
930
+ ...params,
931
+ });
932
+ return await this._executeUserSignedAction({ action }, opts?.signal);
933
+ }
934
+
935
+ /**
936
+ * Configure block type for EVM transactions.
937
+ * @param params - Action-specific parameters.
938
+ * @param opts - Request execution options.
939
+ * @returns Response for creating a sub-account.
940
+ *
941
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
942
+ * @throws {TransportError} When the transport layer throws an error.
943
+ *
944
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/dual-block-architecture
945
+ * @example
946
+ * ```ts
947
+ * import * as hl from "@nktkas/hyperliquid";
948
+ *
949
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
950
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
951
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
952
+ *
953
+ * const data = await exchClient.evmUserModify({ usingBigBlocks: true });
954
+ * ```
955
+ */
956
+ async evmUserModify(
957
+ params: DeepImmutable<EvmUserModifyParameters>,
958
+ opts?: EvmUserModifyOptions,
959
+ ): Promise<SuccessResponse> {
960
+ const action = parser(EvmUserModifyRequest.entries.action)({
961
+ type: "evmUserModify",
962
+ ...params,
963
+ });
964
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
965
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
966
+ }
967
+
968
+ /**
969
+ * Modify an order.
970
+ * @param params - Action-specific parameters.
971
+ * @param opts - Request execution options.
972
+ * @returns Successful response without specific data.
973
+ *
974
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
975
+ * @throws {TransportError} When the transport layer throws an error.
976
+ *
977
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-an-order
978
+ * @example
979
+ * ```ts
980
+ * import * as hl from "@nktkas/hyperliquid";
981
+ *
982
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
983
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
984
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
985
+ *
986
+ * await exchClient.modify({
987
+ * oid: 123,
988
+ * order: {
989
+ * a: 0,
990
+ * b: true,
991
+ * p: "31000",
992
+ * s: "0.2",
993
+ * r: false,
994
+ * t: { limit: { tif: "Gtc" } },
995
+ * c: "0x...",
996
+ * },
997
+ * });
998
+ * ```
999
+ */
1000
+ async modify(
1001
+ params: DeepImmutable<ModifyParameters>,
1002
+ opts?: ModifyOptions,
1003
+ ): Promise<SuccessResponse> {
1004
+ const action = parser(ModifyRequest.entries.action)({
1005
+ type: "modify",
1006
+ ...params,
1007
+ });
1008
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
1009
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1010
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
1011
+ }
1012
+
1013
+ /**
1014
+ * A multi-signature request.
1015
+ * @param params - Action-specific parameters.
1016
+ * @param opts - Request execution options.
1017
+ * @returns Any successful response.
1018
+ *
1019
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1020
+ * @throws {TransportError} When the transport layer throws an error.
1021
+ *
1022
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig
1023
+ * @example
1024
+ * ```ts
1025
+ * import * as hl from "@nktkas/hyperliquid";
1026
+ * import { signL1Action } from "@nktkas/hyperliquid/signing";
1027
+ * import { parser, ScheduleCancelRequest } from "@nktkas/hyperliquid/schemas";
1028
+ * import { privateKeyToAccount } from "npm:viem/accounts";
1029
+ *
1030
+ * const wallet = privateKeyToAccount("0x..."); // or any other wallet libraries
1031
+ * const multiSigUser = "0x...";
1032
+ *
1033
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1034
+ * const exchClient = new hl.ExchangeClient({ wallet, transport });
1035
+ *
1036
+ * const nonce = Date.now();
1037
+ * const action = parser(ScheduleCancelRequest.entries.action)({ // for correct signature generation
1038
+ * type: "scheduleCancel",
1039
+ * time: Date.now() + 10000,
1040
+ * });
1041
+ *
1042
+ * // Create the required number of signatures
1043
+ * const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
1044
+ * return await signL1Action({
1045
+ * wallet: signerPrivKey as `0x${string}`,
1046
+ * action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), action],
1047
+ * nonce,
1048
+ * });
1049
+ * }));
1050
+ *
1051
+ * // // or user-signed action
1052
+ * // const signatures = await Promise.all(["0x...", "0x..."].map(async (signerPrivKey) => {
1053
+ * // return await signUserSignedAction({
1054
+ * // wallet: signerPrivKey as `0x${string}`,
1055
+ * // action: {
1056
+ * // ...action,
1057
+ * // payloadMultiSigUser: multiSigUser,
1058
+ * // outerSigner: wallet.address,
1059
+ * // },
1060
+ * // types: userSignedActionEip712Types[action.type],
1061
+ * // });
1062
+ * // }));
1063
+ *
1064
+ * // Then use signatures in the `multiSig` action
1065
+ * const data = await exchClient.multiSig({
1066
+ * signatures,
1067
+ * payload: {
1068
+ * multiSigUser,
1069
+ * outerSigner: wallet.address,
1070
+ * action,
1071
+ * },
1072
+ * nonce,
1073
+ * });
1074
+ * ```
1075
+ */
1076
+ async multiSig<
1077
+ T extends
1078
+ | SuccessResponse
1079
+ | CancelSuccessResponse
1080
+ | CreateSubAccountResponse
1081
+ | CreateVaultResponse
1082
+ | OrderSuccessResponse
1083
+ | TwapOrderSuccessResponse
1084
+ | TwapCancelSuccessResponse,
1085
+ >(
1086
+ params_and_nonce: DeepImmutable<MultiSigParameters>,
1087
+ opts?: MultiSigOptions,
1088
+ ): Promise<T> {
1089
+ const { nonce, ...params } = params_and_nonce;
1090
+
1091
+ const action = parser(MultiSigRequest.entries.action)({
1092
+ type: "multiSig",
1093
+ signatureChainId: await this._getSignatureChainId(),
1094
+ ...params,
1095
+ });
1096
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
1097
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1098
+ return await this._executeMultiSigAction({ action, vaultAddress, expiresAfter, nonce }, opts?.signal);
1099
+ }
1100
+
1101
+ /**
1102
+ * Place an order(s).
1103
+ * @param params - Action-specific parameters.
1104
+ * @param opts - Request execution options.
1105
+ * @returns Successful variant of {@link OrderResponse} without error statuses.
1106
+ *
1107
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1108
+ * @throws {TransportError} When the transport layer throws an error.
1109
+ *
1110
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order
1111
+ * @example
1112
+ * ```ts
1113
+ * import * as hl from "@nktkas/hyperliquid";
1114
+ *
1115
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1116
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1117
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1118
+ *
1119
+ * const data = await exchClient.order({
1120
+ * orders: [
1121
+ * {
1122
+ * a: 0,
1123
+ * b: true,
1124
+ * p: "30000",
1125
+ * s: "0.1",
1126
+ * r: false,
1127
+ * t: { limit: { tif: "Gtc" } },
1128
+ * c: "0x...",
1129
+ * },
1130
+ * ],
1131
+ * grouping: "na",
1132
+ * });
1133
+ * ```
1134
+ */
1135
+ async order(
1136
+ params: DeepImmutable<OrderParameters>,
1137
+ opts?: OrderOptions,
1138
+ ): Promise<OrderSuccessResponse> {
1139
+ const action = parser(OrderRequest.entries.action)({
1140
+ type: "order",
1141
+ ...params,
1142
+ });
1143
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
1144
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1145
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
1146
+ }
1147
+
1148
+ /**
1149
+ * This action does not do anything (no operation), but causes the nonce to be marked as used.
1150
+ * @param opts - Request execution options.
1151
+ * @returns Successful response without specific data.
1152
+ *
1153
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1154
+ * @throws {TransportError} When the transport layer throws an error.
1155
+ *
1156
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order
1157
+ * @example
1158
+ * ```ts
1159
+ * import * as hl from "@nktkas/hyperliquid";
1160
+ *
1161
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1162
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1163
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1164
+ *
1165
+ * await exchClient.noop();
1166
+ * ```
1167
+ */
1168
+ async noop(
1169
+ opts?: NoopOptions,
1170
+ ): Promise<SuccessResponse> {
1171
+ const action = parser(NoopRequest.entries.action)({
1172
+ type: "noop",
1173
+ });
1174
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1175
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1176
+ }
1177
+
1178
+ /**
1179
+ * Deploying HIP-3 assets.
1180
+ * @param params - Action-specific parameters.
1181
+ * @param opts - Request execution options.
1182
+ * @returns Successful response without specific data.
1183
+ *
1184
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1185
+ * @throws {TransportError} When the transport layer throws an error.
1186
+ *
1187
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/deploying-hip-3-assets
1188
+ * @example
1189
+ * ```ts
1190
+ * import * as hl from "@nktkas/hyperliquid";
1191
+ *
1192
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1193
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1194
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1195
+ *
1196
+ * await exchClient.perpDeploy({
1197
+ * registerAsset: {
1198
+ * maxGas: 1000000,
1199
+ * assetRequest: {
1200
+ * coin: "USDC",
1201
+ * szDecimals: 8,
1202
+ * oraclePx: "1",
1203
+ * marginTableId: 1,
1204
+ * onlyIsolated: false,
1205
+ * },
1206
+ * dex: "test",
1207
+ * schema: null,
1208
+ * },
1209
+ * });
1210
+ * ```
1211
+ */
1212
+ async perpDeploy(
1213
+ params: DeepImmutable<PerpDeployParameters>,
1214
+ opts?: PerpDeployOptions,
1215
+ ): Promise<SuccessResponse> {
1216
+ const action = parser(PerpDeployRequest.entries.action)({
1217
+ type: "perpDeploy",
1218
+ ...params,
1219
+ });
1220
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1221
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1222
+ }
1223
+
1224
+ /**
1225
+ * Create a referral code.
1226
+ * @param params - Action-specific parameters.
1227
+ * @param opts - Request execution options.
1228
+ * @returns Successful response without specific data.
1229
+ *
1230
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1231
+ * @throws {TransportError} When the transport layer throws an error.
1232
+ *
1233
+ * @see null
1234
+ * @example
1235
+ * ```ts
1236
+ * import * as hl from "@nktkas/hyperliquid";
1237
+ *
1238
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1239
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1240
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1241
+ *
1242
+ * await exchClient.registerReferrer({ code: "..." });
1243
+ * ```
1244
+ */
1245
+ async registerReferrer(
1246
+ params: DeepImmutable<RegisterReferrerParameters>,
1247
+ opts?: RegisterReferrerOptions,
1248
+ ): Promise<SuccessResponse> {
1249
+ const action = parser(RegisterReferrerRequest.entries.action)({
1250
+ type: "registerReferrer",
1251
+ ...params,
1252
+ });
1253
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1254
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1255
+ }
1256
+
1257
+ /**
1258
+ * Reserve additional rate-limited actions for a fee.
1259
+ * @param params - Action-specific parameters.
1260
+ * @param opts - Request execution options.
1261
+ * @returns Successful response without specific data.
1262
+ *
1263
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1264
+ * @throws {TransportError} When the transport layer throws an error.
1265
+ *
1266
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#reserve-additional-actions
1267
+ * @example
1268
+ * ```ts
1269
+ * import * as hl from "@nktkas/hyperliquid";
1270
+ *
1271
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1272
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1273
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1274
+ *
1275
+ * await exchClient.reserveRequestWeight({ weight: 10 });
1276
+ * ```
1277
+ */
1278
+ async reserveRequestWeight(
1279
+ params: DeepImmutable<ReserveRequestWeightParameters>,
1280
+ opts?: ReserveRequestWeightOptions,
1281
+ ): Promise<SuccessResponse> {
1282
+ const action = parser(ReserveRequestWeightRequest.entries.action)({
1283
+ type: "reserveRequestWeight",
1284
+ ...params,
1285
+ });
1286
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1287
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1288
+ }
1289
+
1290
+ /**
1291
+ * Schedule a cancel-all operation at a future time.
1292
+ * @param params - An optional action-specific parameters.
1293
+ * @param opts - Request execution options.
1294
+ * @returns Successful response without specific data.
1295
+ *
1296
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1297
+ * @throws {TransportError} When the transport layer throws an error.
1298
+ *
1299
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#schedule-cancel-dead-mans-switch
1300
+ * @example
1301
+ * ```ts
1302
+ * import * as hl from "@nktkas/hyperliquid";
1303
+ *
1304
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1305
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1306
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1307
+ *
1308
+ * await exchClient.scheduleCancel({ time: Date.now() + 10_000 });
1309
+ * ```
1310
+ */
1311
+ async scheduleCancel(
1312
+ params?: DeepImmutable<ScheduleCancelParameters>,
1313
+ opts?: ScheduleCancelOptions,
1314
+ ): Promise<SuccessResponse>;
1315
+ async scheduleCancel(opts?: ScheduleCancelOptions): Promise<SuccessResponse>;
1316
+ async scheduleCancel(
1317
+ params_or_opts?:
1318
+ | DeepImmutable<ScheduleCancelParameters>
1319
+ | ScheduleCancelOptions,
1320
+ maybeOpts?: ScheduleCancelOptions,
1321
+ ): Promise<SuccessResponse> {
1322
+ const isFirstArgParams = params_or_opts && "time" in params_or_opts;
1323
+ const params = isFirstArgParams ? params_or_opts : {};
1324
+ const opts = isFirstArgParams ? maybeOpts : params_or_opts as ScheduleCancelOptions;
1325
+
1326
+ const action = parser(ScheduleCancelRequest.entries.action)({
1327
+ type: "scheduleCancel",
1328
+ ...params,
1329
+ });
1330
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
1331
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1332
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
1333
+ }
1334
+
1335
+ /**
1336
+ * Transfer tokens between different perp DEXs, spot balance, users, and/or sub-accounts.
1337
+ * @param params - Action-specific parameters.
1338
+ * @param opts - Request execution options.
1339
+ * @returns Successful response without specific data.
1340
+ *
1341
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1342
+ * @throws {TransportError} When the transport layer throws an error.
1343
+ *
1344
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#send-asset-testnet-only
1345
+ * @example
1346
+ * ```ts
1347
+ * import * as hl from "@nktkas/hyperliquid";
1348
+ *
1349
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1350
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1351
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1352
+ *
1353
+ * await exchClient.sendAsset({
1354
+ * destination: "0x0000000000000000000000000000000000000001",
1355
+ * sourceDex: "",
1356
+ * destinationDex: "test",
1357
+ * token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
1358
+ * amount: "1",
1359
+ * fromSubAccount: "",
1360
+ * });
1361
+ * ```
1362
+ */
1363
+ async sendAsset(
1364
+ params: DeepImmutable<SendAssetParameters>,
1365
+ opts?: SendAssetOptions,
1366
+ ): Promise<SuccessResponse> {
1367
+ const action = parser(SendAssetRequest.entries.action)({
1368
+ type: "sendAsset",
1369
+ hyperliquidChain: this._getHyperliquidChain(),
1370
+ signatureChainId: await this._getSignatureChainId(),
1371
+ nonce: await this.nonceManager(),
1372
+ ...params,
1373
+ });
1374
+ return await this._executeUserSignedAction({ action }, opts?.signal);
1375
+ }
1376
+
1377
+ /**
1378
+ * Set the display name in the leaderboard.
1379
+ * @param params - Action-specific parameters.
1380
+ * @param opts - Request execution options.
1381
+ * @returns Successful response without specific data.
1382
+ *
1383
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1384
+ * @throws {TransportError} When the transport layer throws an error.
1385
+ *
1386
+ * @see null
1387
+ * @example
1388
+ * ```ts
1389
+ * import * as hl from "@nktkas/hyperliquid";
1390
+ *
1391
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1392
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1393
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1394
+ *
1395
+ * await exchClient.setDisplayName({ displayName: "..." });
1396
+ * ```
1397
+ */
1398
+ async setDisplayName(
1399
+ params: DeepImmutable<SetDisplayNameParameters>,
1400
+ opts?: SetDisplayNameOptions,
1401
+ ): Promise<SuccessResponse> {
1402
+ const action = parser(SetDisplayNameRequest.entries.action)({
1403
+ type: "setDisplayName",
1404
+ ...params,
1405
+ });
1406
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1407
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1408
+ }
1409
+
1410
+ /**
1411
+ * Set a referral code.
1412
+ * @param params - Action-specific parameters.
1413
+ * @param opts - Request execution options.
1414
+ * @returns Successful response without specific data.
1415
+ *
1416
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1417
+ * @throws {TransportError} When the transport layer throws an error.
1418
+ *
1419
+ * @see null
1420
+ * @example
1421
+ * ```ts
1422
+ * import * as hl from "@nktkas/hyperliquid";
1423
+ *
1424
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1425
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1426
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1427
+ *
1428
+ * await exchClient.setReferrer({ code: "..." });
1429
+ * ```
1430
+ */
1431
+ async setReferrer(
1432
+ params: DeepImmutable<SetReferrerParameters>,
1433
+ opts?: SetReferrerOptions,
1434
+ ): Promise<SuccessResponse> {
1435
+ const action = parser(SetReferrerRequest.entries.action)({
1436
+ type: "setReferrer",
1437
+ ...params,
1438
+ });
1439
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1440
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1441
+ }
1442
+
1443
+ /**
1444
+ * Deploying HIP-1 and HIP-2 assets.
1445
+ * @param params - Action-specific parameters.
1446
+ * @param opts - Request execution options.
1447
+ * @returns Successful response without specific data.
1448
+ *
1449
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1450
+ * @throws {TransportError} When the transport layer throws an error.
1451
+ *
1452
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/deploying-hip-1-and-hip-2-assets
1453
+ * @example
1454
+ * ```ts
1455
+ * import * as hl from "@nktkas/hyperliquid";
1456
+ *
1457
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1458
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1459
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1460
+ *
1461
+ * await exchClient.spotDeploy({
1462
+ * registerToken2: {
1463
+ * spec: {
1464
+ * name: "USDC",
1465
+ * szDecimals: 8,
1466
+ * weiDecimals: 8,
1467
+ * },
1468
+ * maxGas: 1000000,
1469
+ * fullName: "USD Coin",
1470
+ * },
1471
+ * });
1472
+ * ```
1473
+ */
1474
+ async spotDeploy(
1475
+ params: DeepImmutable<SpotDeployParameters>,
1476
+ opts?: SpotDeployOptions,
1477
+ ): Promise<SuccessResponse> {
1478
+ const action = parser(SpotDeployRequest.entries.action)({
1479
+ type: "spotDeploy",
1480
+ ...params,
1481
+ });
1482
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1483
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1484
+ }
1485
+
1486
+ /**
1487
+ * Send spot assets to another address.
1488
+ * @param params - Action-specific parameters.
1489
+ * @param opts - Request execution options.
1490
+ * @returns Successful response without specific data.
1491
+ *
1492
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1493
+ * @throws {TransportError} When the transport layer throws an error.
1494
+ *
1495
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#core-spot-transfer
1496
+ * @example
1497
+ * ```ts
1498
+ * import * as hl from "@nktkas/hyperliquid";
1499
+ *
1500
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1501
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1502
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1503
+ *
1504
+ * await exchClient.spotSend({
1505
+ * destination: "0x...",
1506
+ * token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
1507
+ * amount: "1",
1508
+ * });
1509
+ * ```
1510
+ */
1511
+ async spotSend(
1512
+ params: DeepImmutable<SpotSendParameters>,
1513
+ opts?: SpotSendOptions,
1514
+ ): Promise<SuccessResponse> {
1515
+ const action = parser(SpotSendRequest.entries.action)({
1516
+ type: "spotSend",
1517
+ hyperliquidChain: this._getHyperliquidChain(),
1518
+ signatureChainId: await this._getSignatureChainId(),
1519
+ time: await this.nonceManager(),
1520
+ ...params,
1521
+ });
1522
+ return await this._executeUserSignedAction({ action }, opts?.signal);
1523
+ }
1524
+
1525
+ /**
1526
+ * Opt Out of Spot Dusting.
1527
+ * @param params - Action-specific parameters.
1528
+ * @param opts - Request execution options.
1529
+ * @returns Successful response without specific data.
1530
+ *
1531
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1532
+ * @throws {TransportError} When the transport layer throws an error.
1533
+ *
1534
+ * @see null
1535
+ * @example
1536
+ * ```ts
1537
+ * import * as hl from "@nktkas/hyperliquid";
1538
+ *
1539
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1540
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1541
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1542
+ *
1543
+ * await exchClient.spotUser({ toggleSpotDusting: { optOut: false } });
1544
+ * ```
1545
+ */
1546
+ async spotUser(
1547
+ params: DeepImmutable<SpotUserParameters>,
1548
+ opts?: SpotUserOptions,
1549
+ ): Promise<SuccessResponse> {
1550
+ const action = parser(SpotUserRequest.entries.action)({
1551
+ type: "spotUser",
1552
+ ...params,
1553
+ });
1554
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1555
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1556
+ }
1557
+
1558
+ /**
1559
+ * Modify a sub-account's.
1560
+ * @param params - Action-specific parameters.
1561
+ * @param opts - Request execution options.
1562
+ * @returns Successful response without specific data.
1563
+ *
1564
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1565
+ * @throws {TransportError} When the transport layer throws an error.
1566
+ *
1567
+ * @see null
1568
+ * @example
1569
+ * ```ts
1570
+ * import * as hl from "@nktkas/hyperliquid";
1571
+ *
1572
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1573
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1574
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1575
+ *
1576
+ * await exchClient.subAccountModify({ subAccountUser: "0x...", name: "..." });
1577
+ * ```
1578
+ */
1579
+ async subAccountModify(
1580
+ params: DeepImmutable<SubAccountModifyParameters>,
1581
+ opts?: SubAccountModifyOptions,
1582
+ ): Promise<SuccessResponse> {
1583
+ const action = parser(SubAccountModifyRequest.entries.action)({
1584
+ type: "subAccountModify",
1585
+ ...params,
1586
+ });
1587
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1588
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1589
+ }
1590
+
1591
+ /**
1592
+ * Transfer between sub-accounts (spot).
1593
+ * @param params - Action-specific parameters.
1594
+ * @param opts - Request execution options.
1595
+ * @returns Successful response without specific data.
1596
+ *
1597
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1598
+ * @throws {TransportError} When the transport layer throws an error.
1599
+ *
1600
+ * @see null
1601
+ * @example
1602
+ * ```ts
1603
+ * import * as hl from "@nktkas/hyperliquid";
1604
+ *
1605
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1606
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1607
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1608
+ *
1609
+ * await exchClient.subAccountSpotTransfer({
1610
+ * subAccountUser: "0x...",
1611
+ * isDeposit: true,
1612
+ * token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
1613
+ * amount: "1",
1614
+ * });
1615
+ * ```
1616
+ */
1617
+ async subAccountSpotTransfer(
1618
+ params: DeepImmutable<SubAccountSpotTransferParameters>,
1619
+ opts?: SubAccountSpotTransferOptions,
1620
+ ): Promise<SuccessResponse> {
1621
+ const action = parser(SubAccountSpotTransferRequest.entries.action)({
1622
+ type: "subAccountSpotTransfer",
1623
+ ...params,
1624
+ });
1625
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1626
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1627
+ }
1628
+
1629
+ /**
1630
+ * Transfer between sub-accounts (perpetual).
1631
+ * @param params - Action-specific parameters.
1632
+ * @param opts - Request execution options.
1633
+ * @returns Successful response without specific data.
1634
+ *
1635
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1636
+ * @throws {TransportError} When the transport layer throws an error.
1637
+ *
1638
+ * @see null
1639
+ * @example
1640
+ * ```ts
1641
+ * import * as hl from "@nktkas/hyperliquid";
1642
+ *
1643
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1644
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1645
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1646
+ *
1647
+ * await exchClient.subAccountTransfer({ subAccountUser: "0x...", isDeposit: true, usd: 1 * 1e6 });
1648
+ * ```
1649
+ */
1650
+ async subAccountTransfer(
1651
+ params: DeepImmutable<SubAccountTransferParameters>,
1652
+ opts?: SubAccountTransferOptions,
1653
+ ): Promise<SuccessResponse> {
1654
+ const action = parser(SubAccountTransferRequest.entries.action)({
1655
+ type: "subAccountTransfer",
1656
+ ...params,
1657
+ });
1658
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1659
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1660
+ }
1661
+
1662
+ /**
1663
+ * Delegate or undelegate native tokens to or from a validator.
1664
+ * @param params - Action-specific parameters.
1665
+ * @param opts - Request execution options.
1666
+ * @returns Successful response without specific data.
1667
+ *
1668
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1669
+ * @throws {TransportError} When the transport layer throws an error.
1670
+ *
1671
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#delegate-or-undelegate-stake-from-validator
1672
+ * @example
1673
+ * ```ts
1674
+ * import * as hl from "@nktkas/hyperliquid";
1675
+ *
1676
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1677
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1678
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1679
+ *
1680
+ * await exchClient.tokenDelegate({ validator: "0x...", isUndelegate: true, wei: 1 * 1e8 });
1681
+ * ```
1682
+ */
1683
+ async tokenDelegate(
1684
+ params: DeepImmutable<TokenDelegateParameters>,
1685
+ opts?: TokenDelegateOptions,
1686
+ ): Promise<SuccessResponse> {
1687
+ const action = parser(TokenDelegateRequest.entries.action)({
1688
+ type: "tokenDelegate",
1689
+ hyperliquidChain: this._getHyperliquidChain(),
1690
+ signatureChainId: await this._getSignatureChainId(),
1691
+ nonce: await this.nonceManager(),
1692
+ ...params,
1693
+ });
1694
+ return await this._executeUserSignedAction({ action }, opts?.signal);
1695
+ }
1696
+
1697
+ /**
1698
+ * Cancel a TWAP order.
1699
+ * @param params - Action-specific parameters.
1700
+ * @param opts - Request execution options.
1701
+ * @returns Successful variant of {@link TwapCancelResponse} without error status.
1702
+ *
1703
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1704
+ * @throws {TransportError} When the transport layer throws an error.
1705
+ *
1706
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-a-twap-order
1707
+ * @example
1708
+ * ```ts
1709
+ * import * as hl from "@nktkas/hyperliquid";
1710
+ *
1711
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1712
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1713
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1714
+ *
1715
+ * const data = await exchClient.twapCancel({ a: 0, t: 1 });
1716
+ * ```
1717
+ */
1718
+ async twapCancel(
1719
+ params: DeepImmutable<TwapCancelParameters>,
1720
+ opts?: TwapCancelOptions,
1721
+ ): Promise<TwapCancelSuccessResponse> {
1722
+ const action = parser(TwapCancelRequest.entries.action)({
1723
+ type: "twapCancel",
1724
+ ...params,
1725
+ });
1726
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
1727
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1728
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
1729
+ }
1730
+
1731
+ /**
1732
+ * Place a TWAP order.
1733
+ * @param params - Action-specific parameters.
1734
+ * @param opts - Request execution options.
1735
+ * @returns Successful variant of {@link TwapOrderResponse} without error status.
1736
+ *
1737
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1738
+ * @throws {TransportError} When the transport layer throws an error.
1739
+ *
1740
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-a-twap-order
1741
+ * @example
1742
+ * ```ts
1743
+ * import * as hl from "@nktkas/hyperliquid";
1744
+ *
1745
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1746
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1747
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1748
+ *
1749
+ * const data = await exchClient.twapOrder({
1750
+ * twap: {
1751
+ * a: 0,
1752
+ * b: true,
1753
+ * s: "1",
1754
+ * r: false,
1755
+ * m: 10,
1756
+ * t: true,
1757
+ * },
1758
+ * });
1759
+ * ```
1760
+ */
1761
+ async twapOrder(
1762
+ params: DeepImmutable<TwapOrderParameters>,
1763
+ opts?: TwapOrderOptions,
1764
+ ): Promise<TwapOrderSuccessResponse> {
1765
+ const action = parser(TwapOrderRequest.entries.action)({
1766
+ type: "twapOrder",
1767
+ ...params,
1768
+ });
1769
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
1770
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1771
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
1772
+ }
1773
+
1774
+ /**
1775
+ * Add or remove margin from isolated position.
1776
+ * @param params - Action-specific parameters.
1777
+ * @param opts - Request execution options.
1778
+ * @returns Successful response without specific data.
1779
+ *
1780
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1781
+ * @throws {TransportError} When the transport layer throws an error.
1782
+ *
1783
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
1784
+ * @example
1785
+ * ```ts
1786
+ * import * as hl from "@nktkas/hyperliquid";
1787
+ *
1788
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1789
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1790
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1791
+ *
1792
+ * await exchClient.updateIsolatedMargin({ asset: 0, isBuy: true, ntli: 1 * 1e6 });
1793
+ * ```
1794
+ */
1795
+ async updateIsolatedMargin(
1796
+ params: DeepImmutable<UpdateIsolatedMarginParameters>,
1797
+ opts?: UpdateIsolatedMarginOptions,
1798
+ ): Promise<SuccessResponse> {
1799
+ const action = parser(UpdateIsolatedMarginRequest.entries.action)({
1800
+ type: "updateIsolatedMargin",
1801
+ ...params,
1802
+ });
1803
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
1804
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1805
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
1806
+ }
1807
+
1808
+ /**
1809
+ * Update cross or isolated leverage on a coin.
1810
+ * @param params - Action-specific parameters.
1811
+ * @param opts - Request execution options.
1812
+ * @returns Successful response without specific data.
1813
+ *
1814
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1815
+ * @throws {TransportError} When the transport layer throws an error.
1816
+ *
1817
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-leverage
1818
+ * @example
1819
+ * ```ts
1820
+ * import * as hl from "@nktkas/hyperliquid";
1821
+ *
1822
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1823
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1824
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1825
+ *
1826
+ * await exchClient.updateLeverage({ asset: 0, isCross: true, leverage: 5 });
1827
+ * ```
1828
+ */
1829
+ async updateLeverage(
1830
+ params: DeepImmutable<UpdateLeverageParameters>,
1831
+ opts?: UpdateLeverageOptions,
1832
+ ): Promise<SuccessResponse> {
1833
+ const action = parser(UpdateLeverageRequest.entries.action)({
1834
+ type: "updateLeverage",
1835
+ ...params,
1836
+ });
1837
+ const vaultAddress = opts?.vaultAddress ?? this.defaultVaultAddress;
1838
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1839
+ return await this._executeL1Action({ action, vaultAddress, expiresAfter }, opts?.signal);
1840
+ }
1841
+
1842
+ /**
1843
+ * Transfer funds between Spot account and Perp account.
1844
+ * @param params - Action-specific parameters.
1845
+ * @param opts - Request execution options.
1846
+ * @returns Successful response without specific data.
1847
+ *
1848
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1849
+ * @throws {TransportError} When the transport layer throws an error.
1850
+ *
1851
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#transfer-from-spot-account-to-perp-account-and-vice-versa
1852
+ * @example
1853
+ * ```ts
1854
+ * import * as hl from "@nktkas/hyperliquid";
1855
+ *
1856
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1857
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1858
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1859
+ *
1860
+ * await exchClient.usdClassTransfer({ amount: "1", toPerp: true });
1861
+ * ```
1862
+ */
1863
+ async usdClassTransfer(
1864
+ params: DeepImmutable<UsdClassTransferParameters>,
1865
+ opts?: UsdClassTransferOptions,
1866
+ ): Promise<SuccessResponse> {
1867
+ const action = parser(UsdClassTransferRequest.entries.action)({
1868
+ type: "usdClassTransfer",
1869
+ hyperliquidChain: this._getHyperliquidChain(),
1870
+ signatureChainId: await this._getSignatureChainId(),
1871
+ nonce: await this.nonceManager(),
1872
+ ...params,
1873
+ });
1874
+ return await this._executeUserSignedAction({ action }, opts?.signal);
1875
+ }
1876
+
1877
+ /**
1878
+ * Send usd to another address.
1879
+ * @param params - Action-specific parameters.
1880
+ * @param opts - Request execution options.
1881
+ * @returns Successful response without specific data.
1882
+ *
1883
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1884
+ * @throws {TransportError} When the transport layer throws an error.
1885
+ *
1886
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#core-usdc-transfer
1887
+ * @example
1888
+ * ```ts
1889
+ * import * as hl from "@nktkas/hyperliquid";
1890
+ *
1891
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1892
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1893
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1894
+ *
1895
+ * await exchClient.usdSend({ destination: "0x...", amount: "1" });
1896
+ * ```
1897
+ */
1898
+ async usdSend(
1899
+ params: DeepImmutable<UsdSendParameters>,
1900
+ opts?: UsdSendOptions,
1901
+ ): Promise<SuccessResponse> {
1902
+ const action = parser(UsdSendRequest.entries.action)({
1903
+ type: "usdSend",
1904
+ hyperliquidChain: this._getHyperliquidChain(),
1905
+ signatureChainId: await this._getSignatureChainId(),
1906
+ time: await this.nonceManager(),
1907
+ ...params,
1908
+ });
1909
+ return await this._executeUserSignedAction({ action }, opts?.signal);
1910
+ }
1911
+
1912
+ /**
1913
+ * Distribute funds from a vault between followers.
1914
+ * @param params - Action-specific parameters.
1915
+ * @param opts - Request execution options.
1916
+ * @returns Successful response without specific data.
1917
+ *
1918
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1919
+ * @throws {TransportError} When the transport layer throws an error.
1920
+ *
1921
+ * @see null
1922
+ * @example
1923
+ * ```ts
1924
+ * import * as hl from "@nktkas/hyperliquid";
1925
+ *
1926
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1927
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1928
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1929
+ *
1930
+ * await exchClient.vaultDistribute({ vaultAddress: "0x...", usd: 10 * 1e6 });
1931
+ * ```
1932
+ */
1933
+ async vaultDistribute(
1934
+ params: DeepImmutable<VaultDistributeParameters>,
1935
+ opts?: VaultDistributeOptions,
1936
+ ): Promise<SuccessResponse> {
1937
+ const action = parser(VaultDistributeRequest.entries.action)({
1938
+ type: "vaultDistribute",
1939
+ ...params,
1940
+ });
1941
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1942
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1943
+ }
1944
+
1945
+ /**
1946
+ * Modify a vault's configuration.
1947
+ * @param params - Action-specific parameters.
1948
+ * @param opts - Request execution options.
1949
+ * @returns Successful response without specific data.
1950
+ *
1951
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1952
+ * @throws {TransportError} When the transport layer throws an error.
1953
+ *
1954
+ * @see null
1955
+ * @example
1956
+ * ```ts
1957
+ * import * as hl from "@nktkas/hyperliquid";
1958
+ *
1959
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1960
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1961
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1962
+ *
1963
+ * await exchClient.vaultModify({
1964
+ * vaultAddress: "0x...",
1965
+ * allowDeposits: true,
1966
+ * alwaysCloseOnWithdraw: false,
1967
+ * });
1968
+ * ```
1969
+ */
1970
+ async vaultModify(
1971
+ params: DeepImmutable<VaultModifyParameters>,
1972
+ opts?: VaultModifyOptions,
1973
+ ): Promise<SuccessResponse> {
1974
+ const action = parser(VaultModifyRequest.entries.action)({
1975
+ type: "vaultModify",
1976
+ ...params,
1977
+ });
1978
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
1979
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
1980
+ }
1981
+
1982
+ /**
1983
+ * Deposit or withdraw from a vault.
1984
+ * @param params - Action-specific parameters.
1985
+ * @param opts - Request execution options.
1986
+ * @returns Successful response without specific data.
1987
+ *
1988
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
1989
+ * @throws {TransportError} When the transport layer throws an error.
1990
+ *
1991
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-or-withdraw-from-a-vault
1992
+ * @example
1993
+ * ```ts
1994
+ * import * as hl from "@nktkas/hyperliquid";
1995
+ *
1996
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
1997
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1998
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
1999
+ *
2000
+ * await exchClient.vaultTransfer({ vaultAddress: "0x...", isDeposit: true, usd: 10 * 1e6 });
2001
+ * ```
2002
+ */
2003
+ async vaultTransfer(
2004
+ params: DeepImmutable<VaultTransferParameters>,
2005
+ opts?: VaultTransferOptions,
2006
+ ): Promise<SuccessResponse> {
2007
+ const action = parser(VaultTransferRequest.entries.action)({
2008
+ type: "vaultTransfer",
2009
+ ...params,
2010
+ });
2011
+ const expiresAfter = opts?.expiresAfter ?? await this._getDefaultExpiresAfter();
2012
+ return await this._executeL1Action({ action, expiresAfter }, opts?.signal);
2013
+ }
2014
+
2015
+ /**
2016
+ * Initiate a withdrawal request.
2017
+ * @param params - Action-specific parameters.
2018
+ * @param opts - Request execution options.
2019
+ * @returns Successful response without specific data.
2020
+ *
2021
+ * @throws {ApiRequestError} When the API returns an unsuccessful response.
2022
+ * @throws {TransportError} When the transport layer throws an error.
2023
+ *
2024
+ * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#initiate-a-withdrawal-request
2025
+ * @example
2026
+ * ```ts
2027
+ * import * as hl from "@nktkas/hyperliquid";
2028
+ *
2029
+ * const privateKey = "0x..."; // `viem`, `ethers`, or private key directly
2030
+ * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2031
+ * const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
2032
+ *
2033
+ * await exchClient.withdraw3({ destination: "0x...", amount: "1" });
2034
+ * ```
2035
+ */
2036
+ async withdraw3(
2037
+ params: DeepImmutable<Withdraw3Parameters>,
2038
+ opts?: Withdraw3Options,
2039
+ ): Promise<SuccessResponse> {
2040
+ const action = parser(Withdraw3Request.entries.action)({
2041
+ type: "withdraw3",
2042
+ hyperliquidChain: this._getHyperliquidChain(),
2043
+ signatureChainId: await this._getSignatureChainId(),
2044
+ time: await this.nonceManager(),
2045
+ ...params,
2046
+ });
2047
+ return await this._executeUserSignedAction({ action }, opts?.signal);
2048
+ }
2049
+
2050
+ protected async _executeL1Action<
2051
+ T extends
2052
+ | SuccessResponse
2053
+ | CancelSuccessResponse
2054
+ | CreateSubAccountResponse
2055
+ | CreateVaultResponse
2056
+ | OrderSuccessResponse
2057
+ | TwapOrderSuccessResponse
2058
+ | TwapCancelSuccessResponse,
2059
+ >(
2060
+ request: {
2061
+ action: Record<string, unknown>;
2062
+ vaultAddress?: `0x${string}`;
2063
+ expiresAfter: number | undefined;
2064
+ },
2065
+ signal?: AbortSignal,
2066
+ ): Promise<T> {
2067
+ const { action, vaultAddress, expiresAfter } = request;
2068
+
2069
+ // Sign an L1 action
2070
+ const nonce = await this.nonceManager();
2071
+ const signature = await signL1Action({
2072
+ wallet: this.wallet,
2073
+ action,
2074
+ nonce,
2075
+ isTestnet: this.transport.isTestnet,
2076
+ vaultAddress,
2077
+ expiresAfter,
2078
+ });
2079
+
2080
+ // Send a request
2081
+ const response = await this.transport.request(
2082
+ "exchange",
2083
+ { action, signature, nonce, vaultAddress, expiresAfter },
2084
+ signal,
2085
+ ) as
2086
+ | SuccessResponse
2087
+ | ErrorResponse
2088
+ | CancelResponse
2089
+ | CreateSubAccountResponse
2090
+ | CreateVaultResponse
2091
+ | OrderResponse
2092
+ | TwapOrderResponse
2093
+ | TwapCancelResponse;
2094
+ this._validateResponse<T>(response);
2095
+ return response;
2096
+ }
2097
+
2098
+ protected async _executeUserSignedAction<
2099
+ T extends
2100
+ | SuccessResponse
2101
+ | CancelSuccessResponse
2102
+ | CreateSubAccountResponse
2103
+ | CreateVaultResponse
2104
+ | OrderSuccessResponse
2105
+ | TwapOrderSuccessResponse
2106
+ | TwapCancelSuccessResponse,
2107
+ >(
2108
+ request: {
2109
+ action: {
2110
+ type: keyof typeof userSignedActionEip712Types;
2111
+ signatureChainId: `0x${string}`;
2112
+ [key: string]: unknown;
2113
+ };
2114
+ },
2115
+ signal?: AbortSignal,
2116
+ ): Promise<T> {
2117
+ const { action } = request;
2118
+
2119
+ // Sign a user-signed action
2120
+ const nonce = "nonce" in action ? action.nonce : action.time;
2121
+ const signature = await signUserSignedAction({
2122
+ wallet: this.wallet,
2123
+ action,
2124
+ types: userSignedActionEip712Types[action.type],
2125
+ });
2126
+
2127
+ // Send a request
2128
+ const response = await this.transport.request(
2129
+ "exchange",
2130
+ { action, signature, nonce },
2131
+ signal,
2132
+ ) as
2133
+ | SuccessResponse
2134
+ | ErrorResponse
2135
+ | CancelResponse
2136
+ | CreateSubAccountResponse
2137
+ | CreateVaultResponse
2138
+ | OrderResponse
2139
+ | TwapOrderResponse
2140
+ | TwapCancelResponse;
2141
+ this._validateResponse<T>(response);
2142
+ return response;
2143
+ }
2144
+
2145
+ protected async _executeMultiSigAction<
2146
+ T extends
2147
+ | SuccessResponse
2148
+ | CancelSuccessResponse
2149
+ | CreateSubAccountResponse
2150
+ | CreateVaultResponse
2151
+ | OrderSuccessResponse
2152
+ | TwapOrderSuccessResponse
2153
+ | TwapCancelSuccessResponse,
2154
+ >(
2155
+ request: {
2156
+ action: {
2157
+ signatureChainId: `0x${string}`;
2158
+ [key: string]: unknown;
2159
+ };
2160
+ nonce: number;
2161
+ vaultAddress?: `0x${string}`;
2162
+ expiresAfter?: number;
2163
+ },
2164
+ signal?: AbortSignal,
2165
+ ): Promise<T> {
2166
+ const { action, nonce, vaultAddress, expiresAfter } = request;
2167
+
2168
+ // Sign a multi-signature action
2169
+ const signature = await signMultiSigAction({
2170
+ wallet: this.wallet,
2171
+ action,
2172
+ nonce,
2173
+ isTestnet: this.transport.isTestnet,
2174
+ vaultAddress,
2175
+ expiresAfter,
2176
+ });
2177
+
2178
+ // Send a request
2179
+ const response = await this.transport.request(
2180
+ "exchange",
2181
+ { action, signature, nonce, vaultAddress, expiresAfter },
2182
+ signal,
2183
+ ) as
2184
+ | SuccessResponse
2185
+ | ErrorResponse
2186
+ | CancelResponse
2187
+ | CreateSubAccountResponse
2188
+ | CreateVaultResponse
2189
+ | OrderResponse
2190
+ | TwapOrderResponse
2191
+ | TwapCancelResponse;
2192
+ this._validateResponse<T>(response);
2193
+ return response;
2194
+ }
2195
+
2196
+ protected async _getDefaultExpiresAfter(): Promise<number | undefined> {
2197
+ return typeof this.defaultExpiresAfter === "number"
2198
+ ? this.defaultExpiresAfter
2199
+ : await this.defaultExpiresAfter?.();
2200
+ }
2201
+
2202
+ protected async _getSignatureChainId(): Promise<`0x${string}`> {
2203
+ return typeof this.signatureChainId === "string" ? this.signatureChainId : await this.signatureChainId();
2204
+ }
2205
+
2206
+ protected _getHyperliquidChain(): "Mainnet" | "Testnet" {
2207
+ return this.transport.isTestnet ? "Testnet" : "Mainnet";
2208
+ }
2209
+
2210
+ protected _validateResponse<
2211
+ T extends
2212
+ | SuccessResponse
2213
+ | CancelSuccessResponse
2214
+ | CreateSubAccountResponse
2215
+ | CreateVaultResponse
2216
+ | OrderSuccessResponse
2217
+ | TwapOrderSuccessResponse
2218
+ | TwapCancelSuccessResponse,
2219
+ >(
2220
+ response:
2221
+ | SuccessResponse
2222
+ | ErrorResponse
2223
+ | CancelResponse
2224
+ | CreateSubAccountResponse
2225
+ | CreateVaultResponse
2226
+ | OrderResponse
2227
+ | TwapOrderResponse
2228
+ | TwapCancelResponse,
2229
+ ): asserts response is T {
2230
+ if (response.status === "err") {
2231
+ throw new ApiRequestError(response as ErrorResponse);
2232
+ } else if (response.response.type === "order" || response.response.type === "cancel") {
2233
+ if (response.response.data.statuses.some((status) => typeof status === "object" && "error" in status)) {
2234
+ throw new ApiRequestError(response as OrderResponse | CancelResponse);
2235
+ }
2236
+ } else if (response.response.type === "twapOrder" || response.response.type === "twapCancel") {
2237
+ if (typeof response.response.data.status === "object" && "error" in response.response.data.status) {
2238
+ throw new ApiRequestError(response as TwapOrderResponse | TwapCancelResponse);
2239
+ }
2240
+ }
2241
+ }
2242
+
2243
+ async [Symbol.asyncDispose](): Promise<void> {
2244
+ await this.transport[Symbol.asyncDispose]?.();
2245
+ }
2246
+ }