@lifi/perps-sdk 0.1.1-alpha.8 → 0.2.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (748) hide show
  1. package/README.md +38 -15
  2. package/dist/cjs/agent/AgentManager.d.ts +5 -5
  3. package/dist/cjs/agent/AgentManager.d.ts.map +1 -1
  4. package/dist/cjs/agent/AgentManager.js +16 -14
  5. package/dist/cjs/agent/AgentManager.js.map +1 -1
  6. package/dist/cjs/client/PerpsClient.d.ts +75 -21
  7. package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
  8. package/dist/cjs/client/PerpsClient.js +642 -173
  9. package/dist/cjs/client/PerpsClient.js.map +1 -1
  10. package/dist/cjs/client/createPerpsClient.d.ts +15 -2
  11. package/dist/cjs/client/createPerpsClient.d.ts.map +1 -1
  12. package/dist/cjs/client/createPerpsClient.js +6 -3
  13. package/dist/cjs/client/createPerpsClient.js.map +1 -1
  14. package/dist/cjs/client/projectAccountConfigSettings.d.ts +3 -0
  15. package/dist/cjs/client/projectAccountConfigSettings.d.ts.map +1 -0
  16. package/dist/cjs/client/projectAccountConfigSettings.js +17 -0
  17. package/dist/cjs/client/projectAccountConfigSettings.js.map +1 -0
  18. package/dist/cjs/client/types.d.ts +49 -26
  19. package/dist/cjs/client/types.d.ts.map +1 -1
  20. package/dist/cjs/client/types.js +6 -0
  21. package/dist/cjs/client/types.js.map +1 -1
  22. package/dist/cjs/errors/PerpsError.d.ts +2 -3
  23. package/dist/cjs/errors/PerpsError.d.ts.map +1 -1
  24. package/dist/cjs/errors/PerpsError.js +3 -15
  25. package/dist/cjs/errors/PerpsError.js.map +1 -1
  26. package/dist/cjs/errors/constants.d.ts +0 -10
  27. package/dist/cjs/errors/constants.d.ts.map +1 -1
  28. package/dist/cjs/errors/constants.js +1 -12
  29. package/dist/cjs/errors/constants.js.map +1 -1
  30. package/dist/cjs/index.d.ts +37 -31
  31. package/dist/cjs/index.d.ts.map +1 -1
  32. package/dist/cjs/index.js +87 -42
  33. package/dist/cjs/index.js.map +1 -1
  34. package/dist/cjs/providers/hyperliquid/accountConfig.d.ts +3 -0
  35. package/dist/cjs/providers/hyperliquid/accountConfig.d.ts.map +1 -0
  36. package/dist/cjs/providers/hyperliquid/accountConfig.js +41 -0
  37. package/dist/cjs/providers/hyperliquid/accountConfig.js.map +1 -0
  38. package/dist/cjs/providers/lighter/accountConfig.d.ts +3 -0
  39. package/dist/cjs/providers/lighter/accountConfig.d.ts.map +1 -0
  40. package/dist/cjs/providers/lighter/accountConfig.js +45 -0
  41. package/dist/cjs/providers/lighter/accountConfig.js.map +1 -0
  42. package/dist/cjs/realtime/PerpsWsClient.d.ts +7 -1
  43. package/dist/cjs/realtime/PerpsWsClient.d.ts.map +1 -1
  44. package/dist/cjs/realtime/PerpsWsClient.js +36 -23
  45. package/dist/cjs/realtime/PerpsWsClient.js.map +1 -1
  46. package/dist/cjs/realtime/hyperliquid/HyperliquidWsProvider.d.ts +9 -5
  47. package/dist/cjs/realtime/hyperliquid/HyperliquidWsProvider.d.ts.map +1 -1
  48. package/dist/cjs/realtime/hyperliquid/HyperliquidWsProvider.js +158 -52
  49. package/dist/cjs/realtime/hyperliquid/HyperliquidWsProvider.js.map +1 -1
  50. package/dist/cjs/realtime/hyperliquid/types.d.ts +11 -9
  51. package/dist/cjs/realtime/hyperliquid/types.d.ts.map +1 -1
  52. package/dist/cjs/realtime/lighter/LighterWsProvider.d.ts +48 -0
  53. package/dist/cjs/realtime/lighter/LighterWsProvider.d.ts.map +1 -0
  54. package/dist/cjs/realtime/lighter/LighterWsProvider.js +424 -0
  55. package/dist/cjs/realtime/lighter/LighterWsProvider.js.map +1 -0
  56. package/dist/cjs/realtime/lighter/types.d.ts +84 -0
  57. package/dist/cjs/realtime/lighter/types.d.ts.map +1 -0
  58. package/dist/cjs/{dex → realtime/lighter}/types.js.map +1 -1
  59. package/dist/cjs/services/createAction.d.ts +11 -0
  60. package/dist/cjs/services/createAction.d.ts.map +1 -0
  61. package/dist/cjs/services/{submitAuthorization.js → createAction.js} +7 -6
  62. package/dist/cjs/services/createAction.js.map +1 -0
  63. package/dist/cjs/services/executeAction.d.ts +11 -0
  64. package/dist/cjs/services/executeAction.d.ts.map +1 -0
  65. package/dist/cjs/services/{submitOrder.js → executeAction.js} +6 -5
  66. package/dist/cjs/services/executeAction.js.map +1 -0
  67. package/dist/cjs/services/getAccount.d.ts +1 -1
  68. package/dist/cjs/services/getAccount.d.ts.map +1 -1
  69. package/dist/cjs/services/getAccount.js +1 -1
  70. package/dist/cjs/services/getAccount.js.map +1 -1
  71. package/dist/cjs/services/getActivity.d.ts +13 -0
  72. package/dist/cjs/services/getActivity.d.ts.map +1 -0
  73. package/dist/cjs/services/getActivity.js +21 -0
  74. package/dist/cjs/services/getActivity.js.map +1 -0
  75. package/dist/cjs/services/getAsset.d.ts +8 -0
  76. package/dist/cjs/services/getAsset.d.ts.map +1 -0
  77. package/dist/cjs/services/{getMarkets.js → getAsset.js} +6 -4
  78. package/dist/cjs/services/getAsset.js.map +1 -0
  79. package/dist/cjs/services/getAssets.d.ts +7 -0
  80. package/dist/cjs/services/getAssets.d.ts.map +1 -0
  81. package/dist/cjs/services/{getMarket.js → getAssets.js} +5 -5
  82. package/dist/cjs/services/getAssets.js.map +1 -0
  83. package/dist/cjs/services/getFills.d.ts +12 -0
  84. package/dist/cjs/services/getFills.d.ts.map +1 -0
  85. package/dist/cjs/services/{getHistory.js → getFills.js} +7 -5
  86. package/dist/cjs/services/getFills.js.map +1 -0
  87. package/dist/cjs/services/getOhlcv.d.ts +1 -1
  88. package/dist/cjs/services/getOhlcv.d.ts.map +1 -1
  89. package/dist/cjs/services/getOhlcv.js +2 -2
  90. package/dist/cjs/services/getOhlcv.js.map +1 -1
  91. package/dist/cjs/services/getOrder.d.ts +1 -1
  92. package/dist/cjs/services/getOrder.d.ts.map +1 -1
  93. package/dist/cjs/services/getOrder.js +2 -2
  94. package/dist/cjs/services/getOrder.js.map +1 -1
  95. package/dist/cjs/services/getOrderbook.d.ts +1 -1
  96. package/dist/cjs/services/getOrderbook.d.ts.map +1 -1
  97. package/dist/cjs/services/getOrderbook.js +2 -2
  98. package/dist/cjs/services/getOrderbook.js.map +1 -1
  99. package/dist/cjs/services/getOrders.d.ts +11 -0
  100. package/dist/cjs/services/getOrders.d.ts.map +1 -0
  101. package/dist/cjs/services/getOrders.js +15 -0
  102. package/dist/cjs/services/getOrders.js.map +1 -0
  103. package/dist/cjs/services/getPositions.d.ts +11 -0
  104. package/dist/cjs/services/getPositions.d.ts.map +1 -0
  105. package/dist/cjs/services/getPositions.js +15 -0
  106. package/dist/cjs/services/getPositions.js.map +1 -0
  107. package/dist/cjs/services/getPrices.d.ts +1 -1
  108. package/dist/cjs/services/getPrices.d.ts.map +1 -1
  109. package/dist/cjs/services/getPrices.js +1 -1
  110. package/dist/cjs/services/getPrices.js.map +1 -1
  111. package/dist/cjs/services/getProviders.d.ts +4 -0
  112. package/dist/cjs/services/getProviders.d.ts.map +1 -0
  113. package/dist/cjs/services/{getDexes.js → getProviders.js} +4 -4
  114. package/dist/cjs/services/getProviders.js.map +1 -0
  115. package/dist/cjs/signers/lighter/LighterKeyStore.d.ts +20 -0
  116. package/dist/cjs/signers/lighter/LighterKeyStore.d.ts.map +1 -0
  117. package/dist/cjs/signers/lighter/LighterKeyStore.js +42 -0
  118. package/dist/cjs/signers/lighter/LighterKeyStore.js.map +1 -0
  119. package/dist/cjs/signers/lighter/LighterReadOnlyTokenManager.d.ts +66 -0
  120. package/dist/cjs/signers/lighter/LighterReadOnlyTokenManager.d.ts.map +1 -0
  121. package/dist/cjs/signers/lighter/LighterReadOnlyTokenManager.js +141 -0
  122. package/dist/cjs/signers/lighter/LighterReadOnlyTokenManager.js.map +1 -0
  123. package/dist/cjs/signers/lighter/LighterSigner.d.ts +41 -0
  124. package/dist/cjs/signers/lighter/LighterSigner.d.ts.map +1 -0
  125. package/dist/cjs/signers/lighter/LighterSigner.js +176 -0
  126. package/dist/cjs/signers/lighter/LighterSigner.js.map +1 -0
  127. package/dist/cjs/signers/lighter/index.d.ts +9 -0
  128. package/dist/cjs/signers/lighter/index.d.ts.map +1 -0
  129. package/dist/cjs/signers/lighter/index.js +20 -0
  130. package/dist/cjs/signers/lighter/index.js.map +1 -0
  131. package/dist/cjs/signers/lighter/wasmLoader.d.ts +42 -0
  132. package/dist/cjs/signers/lighter/wasmLoader.d.ts.map +1 -0
  133. package/dist/cjs/signers/lighter/wasmLoader.js +166 -0
  134. package/dist/cjs/signers/lighter/wasmLoader.js.map +1 -0
  135. package/dist/cjs/utils/accountSummary.d.ts +9 -0
  136. package/dist/cjs/utils/accountSummary.d.ts.map +1 -0
  137. package/dist/cjs/utils/accountSummary.js +83 -0
  138. package/dist/cjs/utils/accountSummary.js.map +1 -0
  139. package/dist/cjs/utils/assertNever.d.ts +2 -0
  140. package/dist/cjs/utils/assertNever.d.ts.map +1 -0
  141. package/dist/cjs/utils/assertNever.js +7 -0
  142. package/dist/cjs/utils/assertNever.js.map +1 -0
  143. package/dist/cjs/utils/calculations.d.ts +16 -0
  144. package/dist/cjs/utils/calculations.d.ts.map +1 -0
  145. package/dist/cjs/utils/calculations.js +71 -0
  146. package/dist/cjs/utils/calculations.js.map +1 -0
  147. package/dist/cjs/utils/hyperliquid/index.d.ts +3 -0
  148. package/dist/cjs/utils/hyperliquid/index.d.ts.map +1 -0
  149. package/dist/cjs/utils/hyperliquid/index.js +11 -0
  150. package/dist/cjs/utils/hyperliquid/index.js.map +1 -0
  151. package/dist/cjs/utils/hyperliquid/liquidation.d.ts +3 -0
  152. package/dist/cjs/utils/hyperliquid/liquidation.d.ts.map +1 -0
  153. package/dist/cjs/utils/hyperliquid/liquidation.js +24 -0
  154. package/dist/cjs/utils/hyperliquid/liquidation.js.map +1 -0
  155. package/dist/cjs/utils/hyperliquid/orderFormatting.d.ts +4 -0
  156. package/dist/cjs/utils/hyperliquid/orderFormatting.d.ts.map +1 -0
  157. package/dist/cjs/utils/hyperliquid/orderFormatting.js +33 -0
  158. package/dist/cjs/utils/hyperliquid/orderFormatting.js.map +1 -0
  159. package/dist/cjs/utils/orderClassification.d.ts +8 -0
  160. package/dist/cjs/utils/orderClassification.d.ts.map +1 -0
  161. package/dist/cjs/utils/orderClassification.js +39 -0
  162. package/dist/cjs/utils/orderClassification.js.map +1 -0
  163. package/dist/cjs/utils/orderMath.d.ts +6 -0
  164. package/dist/cjs/utils/orderMath.d.ts.map +1 -0
  165. package/dist/cjs/utils/orderMath.js +71 -0
  166. package/dist/cjs/utils/orderMath.js.map +1 -0
  167. package/dist/cjs/utils/parse.d.ts +2 -0
  168. package/dist/cjs/utils/parse.d.ts.map +1 -0
  169. package/dist/cjs/utils/parse.js +14 -0
  170. package/dist/cjs/utils/parse.js.map +1 -0
  171. package/dist/cjs/utils/positionMath.d.ts +26 -0
  172. package/dist/cjs/utils/positionMath.d.ts.map +1 -0
  173. package/dist/cjs/utils/positionMath.js +38 -0
  174. package/dist/cjs/utils/positionMath.js.map +1 -0
  175. package/dist/cjs/utils/request.d.ts.map +1 -1
  176. package/dist/cjs/utils/request.js +19 -4
  177. package/dist/cjs/utils/request.js.map +1 -1
  178. package/dist/cjs/utils/signTypedData.d.ts +2 -0
  179. package/dist/cjs/utils/signTypedData.d.ts.map +1 -1
  180. package/dist/cjs/utils/signTypedData.js +10 -3
  181. package/dist/cjs/utils/signTypedData.js.map +1 -1
  182. package/dist/cjs/utils/units.d.ts +3 -0
  183. package/dist/cjs/utils/units.d.ts.map +1 -0
  184. package/dist/cjs/utils/units.js +18 -0
  185. package/dist/cjs/utils/units.js.map +1 -0
  186. package/dist/cjs/utils/validation.d.ts +2 -0
  187. package/dist/cjs/utils/validation.d.ts.map +1 -0
  188. package/dist/cjs/utils/validation.js +16 -0
  189. package/dist/cjs/utils/validation.js.map +1 -0
  190. package/dist/cjs/version.d.ts +1 -1
  191. package/dist/cjs/version.js +1 -1
  192. package/dist/cjs/wasm/lighter-signer.wasm +0 -0
  193. package/dist/cjs/wasm/wasm_exec.js +575 -0
  194. package/dist/esm/agent/AgentManager.d.ts +9 -9
  195. package/dist/esm/agent/AgentManager.d.ts.map +1 -1
  196. package/dist/esm/agent/AgentManager.js +20 -18
  197. package/dist/esm/agent/AgentManager.js.map +1 -1
  198. package/dist/esm/agent/storage.d.ts +1 -1
  199. package/dist/esm/agent/storage.js +1 -1
  200. package/dist/esm/client/PerpsClient.d.ts +226 -144
  201. package/dist/esm/client/PerpsClient.d.ts.map +1 -1
  202. package/dist/esm/client/PerpsClient.js +869 -320
  203. package/dist/esm/client/PerpsClient.js.map +1 -1
  204. package/dist/esm/client/createPerpsClient.d.ts +30 -51
  205. package/dist/esm/client/createPerpsClient.d.ts.map +1 -1
  206. package/dist/esm/client/createPerpsClient.js +6 -21
  207. package/dist/esm/client/createPerpsClient.js.map +1 -1
  208. package/dist/esm/client/projectAccountConfigSettings.d.ts +18 -0
  209. package/dist/esm/client/projectAccountConfigSettings.d.ts.map +1 -0
  210. package/dist/esm/client/projectAccountConfigSettings.js +29 -0
  211. package/dist/esm/client/projectAccountConfigSettings.js.map +1 -0
  212. package/dist/esm/client/types.d.ts +115 -49
  213. package/dist/esm/client/types.d.ts.map +1 -1
  214. package/dist/esm/client/types.js +11 -1
  215. package/dist/esm/client/types.js.map +1 -1
  216. package/dist/esm/errors/PerpsError.d.ts +2 -3
  217. package/dist/esm/errors/PerpsError.d.ts.map +1 -1
  218. package/dist/esm/errors/PerpsError.js +3 -15
  219. package/dist/esm/errors/PerpsError.js.map +1 -1
  220. package/dist/esm/errors/constants.d.ts +0 -10
  221. package/dist/esm/errors/constants.d.ts.map +1 -1
  222. package/dist/esm/errors/constants.js +0 -11
  223. package/dist/esm/errors/constants.js.map +1 -1
  224. package/dist/esm/index.d.ts +37 -31
  225. package/dist/esm/index.d.ts.map +1 -1
  226. package/dist/esm/index.js +27 -22
  227. package/dist/esm/index.js.map +1 -1
  228. package/dist/esm/providers/hyperliquid/accountConfig.d.ts +13 -0
  229. package/dist/esm/providers/hyperliquid/accountConfig.d.ts.map +1 -0
  230. package/dist/esm/providers/hyperliquid/accountConfig.js +69 -0
  231. package/dist/esm/providers/hyperliquid/accountConfig.js.map +1 -0
  232. package/dist/esm/providers/lighter/accountConfig.d.ts +13 -0
  233. package/dist/esm/providers/lighter/accountConfig.d.ts.map +1 -0
  234. package/dist/esm/providers/lighter/accountConfig.js +79 -0
  235. package/dist/esm/providers/lighter/accountConfig.js.map +1 -0
  236. package/dist/esm/realtime/PerpsWsClient.d.ts +13 -1
  237. package/dist/esm/realtime/PerpsWsClient.d.ts.map +1 -1
  238. package/dist/esm/realtime/PerpsWsClient.js +36 -23
  239. package/dist/esm/realtime/PerpsWsClient.js.map +1 -1
  240. package/dist/esm/realtime/hyperliquid/HyperliquidWsProvider.d.ts +11 -5
  241. package/dist/esm/realtime/hyperliquid/HyperliquidWsProvider.d.ts.map +1 -1
  242. package/dist/esm/realtime/hyperliquid/HyperliquidWsProvider.js +170 -53
  243. package/dist/esm/realtime/hyperliquid/HyperliquidWsProvider.js.map +1 -1
  244. package/dist/esm/realtime/hyperliquid/types.d.ts +11 -9
  245. package/dist/esm/realtime/hyperliquid/types.d.ts.map +1 -1
  246. package/dist/esm/realtime/lighter/LighterWsProvider.d.ts +68 -0
  247. package/dist/esm/realtime/lighter/LighterWsProvider.d.ts.map +1 -0
  248. package/dist/esm/realtime/lighter/LighterWsProvider.js +474 -0
  249. package/dist/esm/realtime/lighter/LighterWsProvider.js.map +1 -0
  250. package/dist/esm/realtime/lighter/types.d.ts +108 -0
  251. package/dist/esm/realtime/lighter/types.d.ts.map +1 -0
  252. package/dist/esm/realtime/lighter/types.js +14 -0
  253. package/dist/esm/realtime/lighter/types.js.map +1 -0
  254. package/dist/esm/services/createAction.d.ts +11 -0
  255. package/dist/esm/services/createAction.d.ts.map +1 -0
  256. package/dist/esm/services/createAction.js +14 -0
  257. package/dist/esm/services/createAction.js.map +1 -0
  258. package/dist/esm/services/executeAction.d.ts +11 -0
  259. package/dist/esm/services/executeAction.d.ts.map +1 -0
  260. package/dist/esm/services/executeAction.js +14 -0
  261. package/dist/esm/services/executeAction.js.map +1 -0
  262. package/dist/esm/services/getAccount.d.ts +7 -7
  263. package/dist/esm/services/getAccount.d.ts.map +1 -1
  264. package/dist/esm/services/getAccount.js +6 -6
  265. package/dist/esm/services/getAccount.js.map +1 -1
  266. package/dist/esm/services/getActivity.d.ts +49 -0
  267. package/dist/esm/services/getActivity.d.ts.map +1 -0
  268. package/dist/esm/services/getActivity.js +47 -0
  269. package/dist/esm/services/getActivity.js.map +1 -0
  270. package/dist/esm/services/getAsset.d.ts +20 -0
  271. package/dist/esm/services/getAsset.d.ts.map +1 -0
  272. package/dist/esm/services/getAsset.js +18 -0
  273. package/dist/esm/services/getAsset.js.map +1 -0
  274. package/dist/esm/services/getAssets.d.ts +18 -0
  275. package/dist/esm/services/getAssets.d.ts.map +1 -0
  276. package/dist/esm/services/getAssets.js +18 -0
  277. package/dist/esm/services/getAssets.js.map +1 -0
  278. package/dist/{types/services/getHistory.d.ts → esm/services/getFills.d.ts} +17 -13
  279. package/dist/esm/services/getFills.d.ts.map +1 -0
  280. package/dist/esm/services/{getHistory.js → getFills.js} +13 -11
  281. package/dist/esm/services/getFills.js.map +1 -0
  282. package/dist/esm/services/getOhlcv.d.ts +4 -4
  283. package/dist/esm/services/getOhlcv.d.ts.map +1 -1
  284. package/dist/esm/services/getOhlcv.js +4 -4
  285. package/dist/esm/services/getOhlcv.js.map +1 -1
  286. package/dist/esm/services/getOrder.d.ts +4 -4
  287. package/dist/esm/services/getOrder.d.ts.map +1 -1
  288. package/dist/esm/services/getOrder.js +4 -4
  289. package/dist/esm/services/getOrder.js.map +1 -1
  290. package/dist/esm/services/getOrderbook.d.ts +4 -4
  291. package/dist/esm/services/getOrderbook.d.ts.map +1 -1
  292. package/dist/esm/services/getOrderbook.js +4 -4
  293. package/dist/esm/services/getOrderbook.js.map +1 -1
  294. package/dist/esm/services/getOrders.d.ts +27 -0
  295. package/dist/esm/services/getOrders.d.ts.map +1 -0
  296. package/dist/esm/services/getOrders.js +23 -0
  297. package/dist/esm/services/getOrders.js.map +1 -0
  298. package/dist/esm/services/getPositions.d.ts +27 -0
  299. package/dist/esm/services/getPositions.d.ts.map +1 -0
  300. package/dist/esm/services/getPositions.js +23 -0
  301. package/dist/esm/services/getPositions.js.map +1 -0
  302. package/dist/esm/services/getPrices.d.ts +5 -5
  303. package/dist/esm/services/getPrices.d.ts.map +1 -1
  304. package/dist/esm/services/getPrices.js +4 -4
  305. package/dist/esm/services/getPrices.js.map +1 -1
  306. package/dist/esm/services/getProviders.d.ts +20 -0
  307. package/dist/esm/services/getProviders.d.ts.map +1 -0
  308. package/dist/esm/services/getProviders.js +21 -0
  309. package/dist/esm/services/getProviders.js.map +1 -0
  310. package/dist/esm/signers/lighter/LighterKeyStore.d.ts +29 -0
  311. package/dist/esm/signers/lighter/LighterKeyStore.d.ts.map +1 -0
  312. package/dist/esm/signers/lighter/LighterKeyStore.js +53 -0
  313. package/dist/esm/signers/lighter/LighterKeyStore.js.map +1 -0
  314. package/dist/esm/signers/lighter/LighterReadOnlyTokenManager.d.ts +174 -0
  315. package/dist/esm/signers/lighter/LighterReadOnlyTokenManager.d.ts.map +1 -0
  316. package/dist/esm/signers/lighter/LighterReadOnlyTokenManager.js +214 -0
  317. package/dist/esm/signers/lighter/LighterReadOnlyTokenManager.js.map +1 -0
  318. package/dist/esm/signers/lighter/LighterSigner.d.ts +88 -0
  319. package/dist/esm/signers/lighter/LighterSigner.d.ts.map +1 -0
  320. package/dist/esm/signers/lighter/LighterSigner.js +226 -0
  321. package/dist/esm/signers/lighter/LighterSigner.js.map +1 -0
  322. package/dist/esm/signers/lighter/index.d.ts +9 -0
  323. package/dist/esm/signers/lighter/index.d.ts.map +1 -0
  324. package/dist/esm/signers/lighter/index.js +5 -0
  325. package/dist/esm/signers/lighter/index.js.map +1 -0
  326. package/dist/esm/signers/lighter/wasmLoader.d.ts +71 -0
  327. package/dist/esm/signers/lighter/wasmLoader.d.ts.map +1 -0
  328. package/dist/esm/signers/lighter/wasmLoader.js +181 -0
  329. package/dist/esm/signers/lighter/wasmLoader.js.map +1 -0
  330. package/dist/esm/utils/accountSummary.d.ts +13 -0
  331. package/dist/esm/utils/accountSummary.d.ts.map +1 -0
  332. package/dist/esm/utils/accountSummary.js +97 -0
  333. package/dist/esm/utils/accountSummary.js.map +1 -0
  334. package/dist/esm/utils/assertNever.d.ts +19 -0
  335. package/dist/esm/utils/assertNever.d.ts.map +1 -0
  336. package/dist/esm/utils/assertNever.js +21 -0
  337. package/dist/esm/utils/assertNever.js.map +1 -0
  338. package/dist/esm/utils/calculations.d.ts +109 -0
  339. package/dist/esm/utils/calculations.d.ts.map +1 -0
  340. package/dist/esm/utils/calculations.js +154 -0
  341. package/dist/esm/utils/calculations.js.map +1 -0
  342. package/dist/esm/utils/hyperliquid/index.d.ts +3 -0
  343. package/dist/esm/utils/hyperliquid/index.d.ts.map +1 -0
  344. package/dist/esm/utils/hyperliquid/index.js +3 -0
  345. package/dist/esm/utils/hyperliquid/index.js.map +1 -0
  346. package/dist/esm/utils/hyperliquid/liquidation.d.ts +46 -0
  347. package/dist/esm/utils/hyperliquid/liquidation.d.ts.map +1 -0
  348. package/dist/esm/utils/hyperliquid/liquidation.js +63 -0
  349. package/dist/esm/utils/hyperliquid/liquidation.js.map +1 -0
  350. package/dist/esm/utils/hyperliquid/orderFormatting.d.ts +44 -0
  351. package/dist/esm/utils/hyperliquid/orderFormatting.d.ts.map +1 -0
  352. package/dist/esm/utils/hyperliquid/orderFormatting.js +79 -0
  353. package/dist/esm/utils/hyperliquid/orderFormatting.js.map +1 -0
  354. package/dist/esm/utils/orderClassification.d.ts +29 -0
  355. package/dist/esm/utils/orderClassification.d.ts.map +1 -0
  356. package/dist/esm/utils/orderClassification.js +53 -0
  357. package/dist/esm/utils/orderClassification.js.map +1 -0
  358. package/dist/esm/utils/orderMath.d.ts +40 -0
  359. package/dist/esm/utils/orderMath.d.ts.map +1 -0
  360. package/dist/esm/utils/orderMath.js +99 -0
  361. package/dist/esm/utils/orderMath.js.map +1 -0
  362. package/dist/esm/utils/parse.d.ts +18 -0
  363. package/dist/esm/utils/parse.d.ts.map +1 -0
  364. package/dist/esm/utils/parse.js +28 -0
  365. package/dist/esm/utils/parse.js.map +1 -0
  366. package/dist/esm/utils/positionMath.d.ts +78 -0
  367. package/dist/esm/utils/positionMath.d.ts.map +1 -0
  368. package/dist/esm/utils/positionMath.js +83 -0
  369. package/dist/esm/utils/positionMath.js.map +1 -0
  370. package/dist/esm/utils/request.d.ts +1 -2
  371. package/dist/esm/utils/request.d.ts.map +1 -1
  372. package/dist/esm/utils/request.js +23 -7
  373. package/dist/esm/utils/request.js.map +1 -1
  374. package/dist/esm/utils/signTypedData.d.ts +8 -10
  375. package/dist/esm/utils/signTypedData.d.ts.map +1 -1
  376. package/dist/esm/utils/signTypedData.js +15 -14
  377. package/dist/esm/utils/signTypedData.js.map +1 -1
  378. package/dist/esm/utils/units.d.ts +20 -0
  379. package/dist/esm/utils/units.d.ts.map +1 -0
  380. package/dist/esm/utils/units.js +31 -0
  381. package/dist/esm/utils/units.js.map +1 -0
  382. package/dist/esm/utils/validation.d.ts +15 -0
  383. package/dist/esm/utils/validation.d.ts.map +1 -0
  384. package/dist/esm/utils/validation.js +26 -0
  385. package/dist/esm/utils/validation.js.map +1 -0
  386. package/dist/esm/version.d.ts +1 -1
  387. package/dist/esm/version.js +1 -1
  388. package/dist/esm/wasm/lighter-signer.wasm +0 -0
  389. package/dist/esm/wasm/wasm_exec.js +575 -0
  390. package/dist/types/agent/AgentManager.d.ts +9 -9
  391. package/dist/types/agent/AgentManager.d.ts.map +1 -1
  392. package/dist/types/agent/storage.d.ts +1 -1
  393. package/dist/types/client/PerpsClient.d.ts +226 -144
  394. package/dist/types/client/PerpsClient.d.ts.map +1 -1
  395. package/dist/types/client/createPerpsClient.d.ts +30 -51
  396. package/dist/types/client/createPerpsClient.d.ts.map +1 -1
  397. package/dist/types/client/projectAccountConfigSettings.d.ts +18 -0
  398. package/dist/types/client/projectAccountConfigSettings.d.ts.map +1 -0
  399. package/dist/types/client/types.d.ts +115 -49
  400. package/dist/types/client/types.d.ts.map +1 -1
  401. package/dist/types/errors/PerpsError.d.ts +2 -3
  402. package/dist/types/errors/PerpsError.d.ts.map +1 -1
  403. package/dist/types/errors/constants.d.ts +0 -10
  404. package/dist/types/errors/constants.d.ts.map +1 -1
  405. package/dist/types/index.d.ts +37 -31
  406. package/dist/types/index.d.ts.map +1 -1
  407. package/dist/types/providers/hyperliquid/accountConfig.d.ts +13 -0
  408. package/dist/types/providers/hyperliquid/accountConfig.d.ts.map +1 -0
  409. package/dist/types/providers/lighter/accountConfig.d.ts +13 -0
  410. package/dist/types/providers/lighter/accountConfig.d.ts.map +1 -0
  411. package/dist/types/realtime/PerpsWsClient.d.ts +13 -1
  412. package/dist/types/realtime/PerpsWsClient.d.ts.map +1 -1
  413. package/dist/types/realtime/hyperliquid/HyperliquidWsProvider.d.ts +11 -5
  414. package/dist/types/realtime/hyperliquid/HyperliquidWsProvider.d.ts.map +1 -1
  415. package/dist/types/realtime/hyperliquid/types.d.ts +11 -9
  416. package/dist/types/realtime/hyperliquid/types.d.ts.map +1 -1
  417. package/dist/types/realtime/lighter/LighterWsProvider.d.ts +68 -0
  418. package/dist/types/realtime/lighter/LighterWsProvider.d.ts.map +1 -0
  419. package/dist/types/realtime/lighter/types.d.ts +108 -0
  420. package/dist/types/realtime/lighter/types.d.ts.map +1 -0
  421. package/dist/types/services/createAction.d.ts +11 -0
  422. package/dist/types/services/createAction.d.ts.map +1 -0
  423. package/dist/types/services/executeAction.d.ts +11 -0
  424. package/dist/types/services/executeAction.d.ts.map +1 -0
  425. package/dist/types/services/getAccount.d.ts +7 -7
  426. package/dist/types/services/getAccount.d.ts.map +1 -1
  427. package/dist/types/services/getActivity.d.ts +49 -0
  428. package/dist/types/services/getActivity.d.ts.map +1 -0
  429. package/dist/types/services/getAsset.d.ts +20 -0
  430. package/dist/types/services/getAsset.d.ts.map +1 -0
  431. package/dist/types/services/getAssets.d.ts +18 -0
  432. package/dist/types/services/getAssets.d.ts.map +1 -0
  433. package/dist/{esm/services/getHistory.d.ts → types/services/getFills.d.ts} +17 -13
  434. package/dist/types/services/getFills.d.ts.map +1 -0
  435. package/dist/types/services/getOhlcv.d.ts +4 -4
  436. package/dist/types/services/getOhlcv.d.ts.map +1 -1
  437. package/dist/types/services/getOrder.d.ts +4 -4
  438. package/dist/types/services/getOrder.d.ts.map +1 -1
  439. package/dist/types/services/getOrderbook.d.ts +4 -4
  440. package/dist/types/services/getOrderbook.d.ts.map +1 -1
  441. package/dist/types/services/getOrders.d.ts +27 -0
  442. package/dist/types/services/getOrders.d.ts.map +1 -0
  443. package/dist/types/services/getPositions.d.ts +27 -0
  444. package/dist/types/services/getPositions.d.ts.map +1 -0
  445. package/dist/types/services/getPrices.d.ts +5 -5
  446. package/dist/types/services/getPrices.d.ts.map +1 -1
  447. package/dist/types/services/getProviders.d.ts +20 -0
  448. package/dist/types/services/getProviders.d.ts.map +1 -0
  449. package/dist/types/signers/lighter/LighterKeyStore.d.ts +29 -0
  450. package/dist/types/signers/lighter/LighterKeyStore.d.ts.map +1 -0
  451. package/dist/types/signers/lighter/LighterReadOnlyTokenManager.d.ts +174 -0
  452. package/dist/types/signers/lighter/LighterReadOnlyTokenManager.d.ts.map +1 -0
  453. package/dist/types/signers/lighter/LighterSigner.d.ts +88 -0
  454. package/dist/types/signers/lighter/LighterSigner.d.ts.map +1 -0
  455. package/dist/types/signers/lighter/index.d.ts +9 -0
  456. package/dist/types/signers/lighter/index.d.ts.map +1 -0
  457. package/dist/types/signers/lighter/wasmLoader.d.ts +71 -0
  458. package/dist/types/signers/lighter/wasmLoader.d.ts.map +1 -0
  459. package/dist/types/utils/accountSummary.d.ts +13 -0
  460. package/dist/types/utils/accountSummary.d.ts.map +1 -0
  461. package/dist/types/utils/assertNever.d.ts +19 -0
  462. package/dist/types/utils/assertNever.d.ts.map +1 -0
  463. package/dist/types/utils/calculations.d.ts +109 -0
  464. package/dist/types/utils/calculations.d.ts.map +1 -0
  465. package/dist/types/utils/hyperliquid/index.d.ts +3 -0
  466. package/dist/types/utils/hyperliquid/index.d.ts.map +1 -0
  467. package/dist/types/utils/hyperliquid/liquidation.d.ts +46 -0
  468. package/dist/types/utils/hyperliquid/liquidation.d.ts.map +1 -0
  469. package/dist/types/utils/hyperliquid/orderFormatting.d.ts +44 -0
  470. package/dist/types/utils/hyperliquid/orderFormatting.d.ts.map +1 -0
  471. package/dist/types/utils/orderClassification.d.ts +29 -0
  472. package/dist/types/utils/orderClassification.d.ts.map +1 -0
  473. package/dist/types/utils/orderMath.d.ts +40 -0
  474. package/dist/types/utils/orderMath.d.ts.map +1 -0
  475. package/dist/types/utils/parse.d.ts +18 -0
  476. package/dist/types/utils/parse.d.ts.map +1 -0
  477. package/dist/types/utils/positionMath.d.ts +78 -0
  478. package/dist/types/utils/positionMath.d.ts.map +1 -0
  479. package/dist/types/utils/request.d.ts +1 -2
  480. package/dist/types/utils/request.d.ts.map +1 -1
  481. package/dist/types/utils/signTypedData.d.ts +8 -10
  482. package/dist/types/utils/signTypedData.d.ts.map +1 -1
  483. package/dist/types/utils/units.d.ts +20 -0
  484. package/dist/types/utils/units.d.ts.map +1 -0
  485. package/dist/types/utils/validation.d.ts +15 -0
  486. package/dist/types/utils/validation.d.ts.map +1 -0
  487. package/dist/types/version.d.ts +1 -1
  488. package/package.json +16 -8
  489. package/src/agent/AgentManager.ts +21 -19
  490. package/src/agent/storage.ts +1 -1
  491. package/src/client/PerpsClient.ts +1221 -396
  492. package/src/client/createPerpsClient.ts +39 -54
  493. package/src/client/projectAccountConfigSettings.ts +39 -0
  494. package/src/client/types.ts +130 -52
  495. package/src/errors/PerpsError.ts +3 -22
  496. package/src/errors/constants.ts +0 -11
  497. package/src/index.ts +115 -47
  498. package/src/providers/hyperliquid/accountConfig.ts +92 -0
  499. package/src/providers/lighter/accountConfig.ts +103 -0
  500. package/src/realtime/PerpsWsClient.ts +67 -32
  501. package/src/realtime/hyperliquid/HyperliquidWsProvider.ts +199 -64
  502. package/src/realtime/hyperliquid/types.ts +8 -10
  503. package/src/realtime/lighter/LighterWsProvider.ts +682 -0
  504. package/src/realtime/lighter/types.ts +121 -0
  505. package/src/services/createAction.ts +41 -0
  506. package/src/services/executeAction.ts +41 -0
  507. package/src/services/getAccount.ts +8 -8
  508. package/src/services/getActivity.ts +77 -0
  509. package/src/services/getAsset.ts +37 -0
  510. package/src/services/getAssets.ts +32 -0
  511. package/src/services/{getHistory.ts → getFills.ts} +23 -17
  512. package/src/services/getOhlcv.ts +14 -11
  513. package/src/services/getOrder.ts +11 -8
  514. package/src/services/getOrderbook.ts +11 -8
  515. package/src/services/getOrders.ts +45 -0
  516. package/src/services/getPositions.ts +45 -0
  517. package/src/services/getPrices.ts +6 -6
  518. package/src/services/{getDexes.ts → getProviders.ts} +10 -10
  519. package/src/signers/lighter/LighterKeyStore.ts +74 -0
  520. package/src/signers/lighter/LighterReadOnlyTokenManager.ts +358 -0
  521. package/src/signers/lighter/LighterSigner.ts +396 -0
  522. package/src/signers/lighter/index.ts +36 -0
  523. package/src/signers/lighter/wasmLoader.ts +291 -0
  524. package/src/utils/accountSummary.ts +130 -0
  525. package/src/utils/assertNever.ts +22 -0
  526. package/src/utils/calculations.ts +209 -0
  527. package/src/utils/hyperliquid/index.ts +9 -0
  528. package/src/utils/hyperliquid/liquidation.ts +71 -0
  529. package/src/utils/hyperliquid/orderFormatting.ts +96 -0
  530. package/src/utils/orderClassification.ts +64 -0
  531. package/src/utils/orderMath.ts +130 -0
  532. package/src/utils/parse.ts +28 -0
  533. package/src/utils/positionMath.ts +107 -0
  534. package/src/utils/request.ts +26 -7
  535. package/src/utils/signTypedData.ts +19 -15
  536. package/src/utils/units.ts +32 -0
  537. package/src/utils/validation.ts +35 -0
  538. package/src/version.ts +1 -1
  539. package/wasm/lighter-signer.wasm +0 -0
  540. package/wasm/wasm_exec.js +575 -0
  541. package/dist/cjs/dex/hyperliquid.d.ts +0 -3
  542. package/dist/cjs/dex/hyperliquid.d.ts.map +0 -1
  543. package/dist/cjs/dex/hyperliquid.js +0 -21
  544. package/dist/cjs/dex/hyperliquid.js.map +0 -1
  545. package/dist/cjs/dex/registry.d.ts +0 -3
  546. package/dist/cjs/dex/registry.d.ts.map +0 -1
  547. package/dist/cjs/dex/registry.js +0 -16
  548. package/dist/cjs/dex/registry.js.map +0 -1
  549. package/dist/cjs/dex/types.d.ts +0 -13
  550. package/dist/cjs/dex/types.d.ts.map +0 -1
  551. package/dist/cjs/errors/AgentError.d.ts +0 -10
  552. package/dist/cjs/errors/AgentError.d.ts.map +0 -1
  553. package/dist/cjs/errors/AgentError.js +0 -23
  554. package/dist/cjs/errors/AgentError.js.map +0 -1
  555. package/dist/cjs/errors/HTTPError.d.ts +0 -11
  556. package/dist/cjs/errors/HTTPError.d.ts.map +0 -1
  557. package/dist/cjs/errors/HTTPError.js +0 -62
  558. package/dist/cjs/errors/HTTPError.js.map +0 -1
  559. package/dist/cjs/errors/PerpsSDKError.d.ts +0 -9
  560. package/dist/cjs/errors/PerpsSDKError.d.ts.map +0 -1
  561. package/dist/cjs/errors/PerpsSDKError.js +0 -36
  562. package/dist/cjs/errors/PerpsSDKError.js.map +0 -1
  563. package/dist/cjs/errors/ServerError.d.ts +0 -10
  564. package/dist/cjs/errors/ServerError.d.ts.map +0 -1
  565. package/dist/cjs/errors/ServerError.js +0 -24
  566. package/dist/cjs/errors/ServerError.js.map +0 -1
  567. package/dist/cjs/errors/ValidationError.d.ts +0 -9
  568. package/dist/cjs/errors/ValidationError.d.ts.map +0 -1
  569. package/dist/cjs/errors/ValidationError.js +0 -23
  570. package/dist/cjs/errors/ValidationError.js.map +0 -1
  571. package/dist/cjs/errors/utils/rootCause.d.ts +0 -6
  572. package/dist/cjs/errors/utils/rootCause.d.ts.map +0 -1
  573. package/dist/cjs/errors/utils/rootCause.js +0 -41
  574. package/dist/cjs/errors/utils/rootCause.js.map +0 -1
  575. package/dist/cjs/services/cancelOrder.d.ts +0 -10
  576. package/dist/cjs/services/cancelOrder.d.ts.map +0 -1
  577. package/dist/cjs/services/cancelOrder.js +0 -16
  578. package/dist/cjs/services/cancelOrder.js.map +0 -1
  579. package/dist/cjs/services/createAuthorization.d.ts +0 -10
  580. package/dist/cjs/services/createAuthorization.d.ts.map +0 -1
  581. package/dist/cjs/services/createAuthorization.js +0 -16
  582. package/dist/cjs/services/createAuthorization.js.map +0 -1
  583. package/dist/cjs/services/createOrder.d.ts +0 -21
  584. package/dist/cjs/services/createOrder.d.ts.map +0 -1
  585. package/dist/cjs/services/createOrder.js +0 -27
  586. package/dist/cjs/services/createOrder.js.map +0 -1
  587. package/dist/cjs/services/createWithdrawal.d.ts +0 -9
  588. package/dist/cjs/services/createWithdrawal.d.ts.map +0 -1
  589. package/dist/cjs/services/createWithdrawal.js +0 -15
  590. package/dist/cjs/services/createWithdrawal.js.map +0 -1
  591. package/dist/cjs/services/getDexes.d.ts +0 -4
  592. package/dist/cjs/services/getDexes.d.ts.map +0 -1
  593. package/dist/cjs/services/getDexes.js.map +0 -1
  594. package/dist/cjs/services/getHistory.d.ts +0 -10
  595. package/dist/cjs/services/getHistory.d.ts.map +0 -1
  596. package/dist/cjs/services/getHistory.js.map +0 -1
  597. package/dist/cjs/services/getMarket.d.ts +0 -8
  598. package/dist/cjs/services/getMarket.d.ts.map +0 -1
  599. package/dist/cjs/services/getMarket.js.map +0 -1
  600. package/dist/cjs/services/getMarkets.d.ts +0 -7
  601. package/dist/cjs/services/getMarkets.d.ts.map +0 -1
  602. package/dist/cjs/services/getMarkets.js.map +0 -1
  603. package/dist/cjs/services/submitAuthorization.d.ts +0 -10
  604. package/dist/cjs/services/submitAuthorization.d.ts.map +0 -1
  605. package/dist/cjs/services/submitAuthorization.js.map +0 -1
  606. package/dist/cjs/services/submitOrder.d.ts +0 -10
  607. package/dist/cjs/services/submitOrder.d.ts.map +0 -1
  608. package/dist/cjs/services/submitOrder.js.map +0 -1
  609. package/dist/cjs/services/submitWithdrawal.d.ts +0 -9
  610. package/dist/cjs/services/submitWithdrawal.d.ts.map +0 -1
  611. package/dist/cjs/services/submitWithdrawal.js +0 -15
  612. package/dist/cjs/services/submitWithdrawal.js.map +0 -1
  613. package/dist/esm/dex/hyperliquid.d.ts +0 -3
  614. package/dist/esm/dex/hyperliquid.d.ts.map +0 -1
  615. package/dist/esm/dex/hyperliquid.js +0 -19
  616. package/dist/esm/dex/hyperliquid.js.map +0 -1
  617. package/dist/esm/dex/registry.d.ts +0 -3
  618. package/dist/esm/dex/registry.d.ts.map +0 -1
  619. package/dist/esm/dex/registry.js +0 -13
  620. package/dist/esm/dex/registry.js.map +0 -1
  621. package/dist/esm/dex/types.d.ts +0 -15
  622. package/dist/esm/dex/types.d.ts.map +0 -1
  623. package/dist/esm/dex/types.js +0 -2
  624. package/dist/esm/dex/types.js.map +0 -1
  625. package/dist/esm/errors/AgentError.d.ts +0 -25
  626. package/dist/esm/errors/AgentError.d.ts.map +0 -1
  627. package/dist/esm/errors/AgentError.js +0 -35
  628. package/dist/esm/errors/AgentError.js.map +0 -1
  629. package/dist/esm/errors/HTTPError.d.ts +0 -11
  630. package/dist/esm/errors/HTTPError.d.ts.map +0 -1
  631. package/dist/esm/errors/HTTPError.js +0 -61
  632. package/dist/esm/errors/HTTPError.js.map +0 -1
  633. package/dist/esm/errors/PerpsSDKError.d.ts +0 -40
  634. package/dist/esm/errors/PerpsSDKError.d.ts.map +0 -1
  635. package/dist/esm/errors/PerpsSDKError.js +0 -67
  636. package/dist/esm/errors/PerpsSDKError.js.map +0 -1
  637. package/dist/esm/errors/ServerError.d.ts +0 -23
  638. package/dist/esm/errors/ServerError.d.ts.map +0 -1
  639. package/dist/esm/errors/ServerError.js +0 -34
  640. package/dist/esm/errors/ServerError.js.map +0 -1
  641. package/dist/esm/errors/ValidationError.d.ts +0 -23
  642. package/dist/esm/errors/ValidationError.d.ts.map +0 -1
  643. package/dist/esm/errors/ValidationError.js +0 -34
  644. package/dist/esm/errors/ValidationError.js.map +0 -1
  645. package/dist/esm/errors/utils/rootCause.d.ts +0 -71
  646. package/dist/esm/errors/utils/rootCause.d.ts.map +0 -1
  647. package/dist/esm/errors/utils/rootCause.js +0 -99
  648. package/dist/esm/errors/utils/rootCause.js.map +0 -1
  649. package/dist/esm/services/cancelOrder.d.ts +0 -51
  650. package/dist/esm/services/cancelOrder.d.ts.map +0 -1
  651. package/dist/esm/services/cancelOrder.js +0 -50
  652. package/dist/esm/services/cancelOrder.js.map +0 -1
  653. package/dist/esm/services/createAuthorization.d.ts +0 -51
  654. package/dist/esm/services/createAuthorization.d.ts.map +0 -1
  655. package/dist/esm/services/createAuthorization.js +0 -50
  656. package/dist/esm/services/createAuthorization.js.map +0 -1
  657. package/dist/esm/services/createOrder.d.ts +0 -74
  658. package/dist/esm/services/createOrder.d.ts.map +0 -1
  659. package/dist/esm/services/createOrder.js +0 -62
  660. package/dist/esm/services/createOrder.js.map +0 -1
  661. package/dist/esm/services/createWithdrawal.d.ts +0 -49
  662. package/dist/esm/services/createWithdrawal.d.ts.map +0 -1
  663. package/dist/esm/services/createWithdrawal.js +0 -49
  664. package/dist/esm/services/createWithdrawal.js.map +0 -1
  665. package/dist/esm/services/getDexes.d.ts +0 -20
  666. package/dist/esm/services/getDexes.d.ts.map +0 -1
  667. package/dist/esm/services/getDexes.js +0 -21
  668. package/dist/esm/services/getDexes.js.map +0 -1
  669. package/dist/esm/services/getHistory.d.ts.map +0 -1
  670. package/dist/esm/services/getHistory.js.map +0 -1
  671. package/dist/esm/services/getMarket.d.ts +0 -27
  672. package/dist/esm/services/getMarket.d.ts.map +0 -1
  673. package/dist/esm/services/getMarket.js +0 -25
  674. package/dist/esm/services/getMarket.js.map +0 -1
  675. package/dist/esm/services/getMarkets.d.ts +0 -25
  676. package/dist/esm/services/getMarkets.d.ts.map +0 -1
  677. package/dist/esm/services/getMarkets.js +0 -23
  678. package/dist/esm/services/getMarkets.js.map +0 -1
  679. package/dist/esm/services/submitAuthorization.d.ts +0 -42
  680. package/dist/esm/services/submitAuthorization.d.ts.map +0 -1
  681. package/dist/esm/services/submitAuthorization.js +0 -41
  682. package/dist/esm/services/submitAuthorization.js.map +0 -1
  683. package/dist/esm/services/submitOrder.d.ts +0 -44
  684. package/dist/esm/services/submitOrder.d.ts.map +0 -1
  685. package/dist/esm/services/submitOrder.js +0 -43
  686. package/dist/esm/services/submitOrder.js.map +0 -1
  687. package/dist/esm/services/submitWithdrawal.d.ts +0 -40
  688. package/dist/esm/services/submitWithdrawal.d.ts.map +0 -1
  689. package/dist/esm/services/submitWithdrawal.js +0 -40
  690. package/dist/esm/services/submitWithdrawal.js.map +0 -1
  691. package/dist/types/dex/hyperliquid.d.ts +0 -3
  692. package/dist/types/dex/hyperliquid.d.ts.map +0 -1
  693. package/dist/types/dex/registry.d.ts +0 -3
  694. package/dist/types/dex/registry.d.ts.map +0 -1
  695. package/dist/types/dex/types.d.ts +0 -15
  696. package/dist/types/dex/types.d.ts.map +0 -1
  697. package/dist/types/errors/AgentError.d.ts +0 -25
  698. package/dist/types/errors/AgentError.d.ts.map +0 -1
  699. package/dist/types/errors/HTTPError.d.ts +0 -11
  700. package/dist/types/errors/HTTPError.d.ts.map +0 -1
  701. package/dist/types/errors/PerpsSDKError.d.ts +0 -40
  702. package/dist/types/errors/PerpsSDKError.d.ts.map +0 -1
  703. package/dist/types/errors/ServerError.d.ts +0 -23
  704. package/dist/types/errors/ServerError.d.ts.map +0 -1
  705. package/dist/types/errors/ValidationError.d.ts +0 -23
  706. package/dist/types/errors/ValidationError.d.ts.map +0 -1
  707. package/dist/types/errors/utils/rootCause.d.ts +0 -71
  708. package/dist/types/errors/utils/rootCause.d.ts.map +0 -1
  709. package/dist/types/services/cancelOrder.d.ts +0 -51
  710. package/dist/types/services/cancelOrder.d.ts.map +0 -1
  711. package/dist/types/services/createAuthorization.d.ts +0 -51
  712. package/dist/types/services/createAuthorization.d.ts.map +0 -1
  713. package/dist/types/services/createOrder.d.ts +0 -74
  714. package/dist/types/services/createOrder.d.ts.map +0 -1
  715. package/dist/types/services/createWithdrawal.d.ts +0 -49
  716. package/dist/types/services/createWithdrawal.d.ts.map +0 -1
  717. package/dist/types/services/getDexes.d.ts +0 -20
  718. package/dist/types/services/getDexes.d.ts.map +0 -1
  719. package/dist/types/services/getHistory.d.ts.map +0 -1
  720. package/dist/types/services/getMarket.d.ts +0 -27
  721. package/dist/types/services/getMarket.d.ts.map +0 -1
  722. package/dist/types/services/getMarkets.d.ts +0 -25
  723. package/dist/types/services/getMarkets.d.ts.map +0 -1
  724. package/dist/types/services/submitAuthorization.d.ts +0 -42
  725. package/dist/types/services/submitAuthorization.d.ts.map +0 -1
  726. package/dist/types/services/submitOrder.d.ts +0 -44
  727. package/dist/types/services/submitOrder.d.ts.map +0 -1
  728. package/dist/types/services/submitWithdrawal.d.ts +0 -40
  729. package/dist/types/services/submitWithdrawal.d.ts.map +0 -1
  730. package/src/dex/hyperliquid.ts +0 -20
  731. package/src/dex/registry.ts +0 -15
  732. package/src/dex/types.ts +0 -16
  733. package/src/errors/AgentError.ts +0 -43
  734. package/src/errors/HTTPError.ts +0 -72
  735. package/src/errors/PerpsSDKError.ts +0 -79
  736. package/src/errors/ServerError.ts +0 -41
  737. package/src/errors/ValidationError.ts +0 -38
  738. package/src/errors/utils/rootCause.ts +0 -112
  739. package/src/services/cancelOrder.ts +0 -75
  740. package/src/services/createAuthorization.ts +0 -79
  741. package/src/services/createOrder.ts +0 -116
  742. package/src/services/createWithdrawal.ts +0 -76
  743. package/src/services/getMarket.ts +0 -41
  744. package/src/services/getMarkets.ts +0 -37
  745. package/src/services/submitAuthorization.ts +0 -70
  746. package/src/services/submitOrder.ts +0 -72
  747. package/src/services/submitWithdrawal.ts +0 -67
  748. /package/dist/cjs/{dex → realtime/lighter}/types.js +0 -0
@@ -1,572 +1,1397 @@
1
1
  import type {
2
+ ActionDescriptor,
3
+ ActionParamsMap,
4
+ ActionStep,
2
5
  Address,
3
- AuthorizationsResponse,
4
- CancelOrderPayloadResponse,
5
- CreateAuthorizationResponse,
6
- CreateOrderResponse,
7
- CreateWithdrawalResponse,
8
- OrderActionType,
9
- SignedAuthorization,
10
- SignedOrderAction,
11
- SubmitOrderResponse,
12
- SubmitWithdrawalResponse,
6
+ ApproveReadOnlyTokenParams,
7
+ AssetIdentity,
8
+ CreateActionResponse,
9
+ Eip712ActionStep,
10
+ Eip712SignedActionStep,
11
+ EvmTxActionStep,
12
+ EvmTxSignedActionStep,
13
+ ExecuteActionResponse,
14
+ Provider,
15
+ SignedActionStep,
16
+ WasmBlobActionStep,
17
+ WasmBlobSignedActionStep,
13
18
  } from '@lifi/perps-types'
14
- import { PerpsErrorCode } from '@lifi/perps-types'
15
- import { getDexAuthProvider } from '../dex/registry.js'
16
- import { PerpsErrorMessage } from '../errors/constants.js'
19
+ import {
20
+ ActionType,
21
+ PerpsErrorCode,
22
+ PerpsSigner,
23
+ SigningMethod,
24
+ } from '@lifi/perps-types'
25
+ import { parseAbi } from 'viem'
26
+ import { localStorageAdapter } from '../agent/storage.js'
27
+ import type { StorageAdapter } from '../agent/types.js'
17
28
  import { PerpsError } from '../errors/PerpsError.js'
18
- import { cancelOrder } from '../services/cancelOrder.js'
19
- import { createAuthorization } from '../services/createAuthorization.js'
20
- import { createOrder } from '../services/createOrder.js'
21
- import { createWithdrawal } from '../services/createWithdrawal.js'
22
- import type { SubmitAuthorizationParams } from '../services/submitAuthorization.js'
23
- import { submitAuthorization } from '../services/submitAuthorization.js'
24
- import type { SubmitOrderParams } from '../services/submitOrder.js'
25
- import { submitOrder } from '../services/submitOrder.js'
26
- import type { SubmitWithdrawalParams } from '../services/submitWithdrawal.js'
27
- import { submitWithdrawal } from '../services/submitWithdrawal.js'
28
- import { signTypedData } from '../utils/signTypedData.js'
29
+ import { createAction } from '../services/createAction.js'
30
+ import { executeAction } from '../services/executeAction.js'
31
+ import { getAccount } from '../services/getAccount.js'
32
+ import { getProviders } from '../services/getProviders.js'
33
+ import {
34
+ type ApproveReadOnlyTokenResult,
35
+ DEFAULT_API_KEY_INDEX,
36
+ type LighterApiKey,
37
+ LighterKeyStore,
38
+ LighterReadOnlyTokenManager,
39
+ type LighterReadOnlyTokenManagerOptions,
40
+ LighterSigner,
41
+ type LighterSignerConfig,
42
+ walletClientSigner,
43
+ } from '../signers/lighter/index.js'
44
+ import {
45
+ signTypedData,
46
+ signTypedDataWithSigner,
47
+ } from '../utils/signTypedData.js'
29
48
  import { createPerpsClient, type PerpsSDKClient } from './createPerpsClient.js'
30
- import type {
31
- BuildAuthorizationParams,
32
- BuildWithdrawalParams,
33
- CancelOrdersParams,
34
- ExecuteAuthorizationsParams,
35
- ExecuteAuthorizationsResult,
36
- GetRequiredAuthorizationsParams,
37
- PerpsClientOptions,
38
- PlaceOrderParams,
39
- RequiredAuthorizationsResult,
49
+ import { projectAccountConfigSettings } from './projectAccountConfigSettings.js'
50
+ import {
51
+ type CancelOrdersParams,
52
+ type CheckPrerequisitesParams,
53
+ type GetAccountResult,
54
+ type GetSetupParams,
55
+ type ModifyOrdersParams,
56
+ type PerpsClientOptions,
57
+ type PlaceOrderParams,
58
+ type PlaceTriggerOrderParams,
59
+ type SatisfySetupParams,
60
+ type SatisfySetupResult,
61
+ type SetupResult,
40
62
  SigningMode,
63
+ type WithdrawParams,
41
64
  } from './types.js'
42
65
 
66
+ const MAX_NONCE_RETRIES = 3
67
+
43
68
  /**
44
- * Stateful client for managing signing modes and trading operations.
45
- *
46
- * The PerpsClient provides two signing modes:
47
- * - `USER`: User wallet signs each action (wallet popup per action)
48
- * - `USER_AGENT`: SDK-generated agent signs actions (no popups after setup)
49
- *
50
- * In `USER_AGENT` mode, the client:
51
- * - Generates an agent keypair stored in localStorage (or custom storage)
52
- * - Auto-injects agent address into authorization requests
53
- * - Auto-signs trading actions with the agent key
54
- *
55
- * @remarks
56
- * The example below uses Hyperliquid. Authorization keys and parameters are DEX-specific.
57
- *
58
- * @example
59
- * ```ts
60
- * const perps = new PerpsClient({ integrator: 'my-app' })
61
- *
62
- * // Set up agent signing for a user + DEX pair
63
- * await perps.setSigningMode(userAddress, 'hyperliquid', 'USER_AGENT')
64
- *
65
- * // Check and execute required authorizations
66
- * const required = await perps.getRequiredAuthorizations({
67
- * dex: 'hyperliquid',
68
- * address: userAddress,
69
- * })
70
- *
71
- * // ... sign actions with user wallet ...
72
- *
73
- * // Place orders (agent signs automatically)
74
- * const result = await perps.placeOrder({
75
- * address: userAddress,
76
- * dex: 'hyperliquid',
77
- * symbol: 'BTC',
78
- * side: 'BUY',
79
- * type: 'MARKET',
80
- * size: '0.1',
81
- * price: '95000.00'
82
- * })
83
- * ```
69
+ * Look up an action's descriptor in the provider's metadata. Throws if the
70
+ * action isn't declared — defensive: better to fail loudly than to mis-sign.
84
71
  */
72
+ function findActionDescriptor(
73
+ metadata: Provider,
74
+ action: ActionType
75
+ ): ActionDescriptor {
76
+ const descriptor = [
77
+ ...metadata.setup,
78
+ ...metadata.options,
79
+ ...metadata.actions,
80
+ ].find((d) => d.type === action)
81
+ if (!descriptor) {
82
+ throw new PerpsError(
83
+ PerpsErrorCode.SDKError,
84
+ `Provider '${metadata.key}' does not declare action '${action}'.`
85
+ )
86
+ }
87
+ return descriptor
88
+ }
89
+
85
90
  export class PerpsClient {
86
91
  private sdkClient: PerpsSDKClient
92
+ private storage: StorageAdapter
87
93
  private signingModes: Map<string, SigningMode> = new Map()
94
+ private providerMetadataCache: Map<string, Provider> = new Map()
95
+ private _signer: PerpsSDKClient['signer'] | undefined
96
+ private readonly lighterConfig: LighterSignerConfig | undefined
97
+ private readonly lighterReadOnlyTokenOptions:
98
+ | LighterReadOnlyTokenManagerOptions
99
+ | undefined
100
+ private _lighterSigner: LighterSigner | undefined
101
+ private _lighterKeyStore: LighterKeyStore | undefined
102
+ private _lighterReadOnlyTokenManager: LighterReadOnlyTokenManager | undefined
88
103
 
89
104
  constructor(options: PerpsClientOptions) {
105
+ this.storage = options.storage ?? localStorageAdapter
106
+ this.lighterConfig = options.lighter
107
+ this.lighterReadOnlyTokenOptions = options.lighterReadOnlyToken
90
108
  this.sdkClient = createPerpsClient({
91
109
  integrator: options.integrator,
92
110
  apiKey: options.apiKey,
93
111
  apiUrl: options.apiUrl,
94
- storage: options.storage,
112
+ storage: this.storage,
113
+ providers: options.providers,
95
114
  })
96
115
  }
97
116
 
117
+ private getLighterSigner(): LighterSigner {
118
+ if (!this._lighterSigner) {
119
+ this._lighterSigner = new LighterSigner(this.lighterConfig)
120
+ }
121
+ return this._lighterSigner
122
+ }
123
+
124
+ private getLighterKeyStore(): LighterKeyStore {
125
+ if (!this._lighterKeyStore) {
126
+ this._lighterKeyStore = new LighterKeyStore(this.storage)
127
+ }
128
+ return this._lighterKeyStore
129
+ }
130
+
131
+ private getLighterReadOnlyTokenManager(): LighterReadOnlyTokenManager {
132
+ if (!this._lighterReadOnlyTokenManager) {
133
+ this._lighterReadOnlyTokenManager = new LighterReadOnlyTokenManager({
134
+ storage: this.storage,
135
+ ...this.lighterReadOnlyTokenOptions,
136
+ })
137
+ }
138
+ return this._lighterReadOnlyTokenManager
139
+ }
140
+
98
141
  /**
99
- * Get the underlying SDK client for use with service functions.
142
+ * Set or update the wallet signer. Used whenever an action's descriptor
143
+ * names the user wallet in its `signers` list. Pass undefined to clear.
100
144
  */
145
+ setSigner(signer: PerpsSDKClient['signer']): void {
146
+ this._signer = signer
147
+ // Override the signer on the sdkClient
148
+ Object.defineProperty(this.sdkClient, 'signer', {
149
+ get: () => this._signer,
150
+ configurable: true,
151
+ })
152
+ }
153
+
101
154
  get client(): PerpsSDKClient {
102
155
  return this.sdkClient
103
156
  }
104
157
 
105
- /**
106
- * Get the storage key for a user + DEX pair.
107
- */
108
- private modeKey(address: Address, dex: string): string {
109
- return `${address.toLowerCase()}:${dex.toLowerCase()}`
158
+ private modeKey(address: Address, provider: string): string {
159
+ return `${address.toLowerCase()}:${provider.toLowerCase()}`
160
+ }
161
+
162
+ private signingModeStorageKey(address: Address, provider: string): string {
163
+ return `lifi-perps-mode:${address.toLowerCase()}:${provider.toLowerCase()}`
164
+ }
165
+
166
+ private async getProviderMetadata(provider: string): Promise<Provider> {
167
+ const cached = this.providerMetadataCache.get(provider)
168
+ if (cached) {
169
+ return cached
170
+ }
171
+
172
+ const { providers } = await getProviders(this.sdkClient)
173
+ for (const d of providers) {
174
+ this.providerMetadataCache.set(d.key, d)
175
+ }
176
+
177
+ const metadata = this.providerMetadataCache.get(provider)
178
+ if (!metadata) {
179
+ const error = new PerpsError(
180
+ PerpsErrorCode.SDKError,
181
+ `Unsupported provider: ${provider}`
182
+ )
183
+ error.tool = '@lifi/perps-sdk'
184
+ throw error
185
+ }
186
+ return metadata
110
187
  }
111
188
 
112
189
  /**
113
- * Set the signing mode for a user + DEX pair.
114
- *
115
- * In `USER_AGENT` mode, generates an agent keypair if one doesn't exist.
116
- *
117
- * @param address - User wallet address
118
- * @param dex - DEX identifier
119
- * @param mode - Signing mode to set
190
+ * Action types that require explicit user input (a chosen mode or tier)
191
+ * and therefore cannot be bulk-staged through `buildPrerequisites` with
192
+ * empty params. Callers must dispatch these via `execute(...)` once a
193
+ * value is picked. The post-`APPROVE_AGENT` auto-upgrade path also
194
+ * dispatches `ACCOUNT_MODE` directly with `mode: 'unifiedAccount'`.
120
195
  */
121
- async setSigningMode(
196
+ private static readonly EXPLICIT_INPUT_PREREQUISITES: ReadonlySet<ActionType> =
197
+ new Set([ActionType.ACCOUNT_MODE, ActionType.ACCOUNT_TYPE])
198
+
199
+ private buildPrerequisiteInputs(
200
+ prerequisites: ActionDescriptor[],
201
+ mode: SigningMode,
202
+ agentAddress?: Address
203
+ ): Array<{ key: string; params?: Record<string, unknown> }> {
204
+ return prerequisites
205
+ .filter((p) => {
206
+ // ACCOUNT_MODE / ACCOUNT_TYPE require explicit params; they're
207
+ // dispatched separately via `execute(...)` (or the post-APPROVE_AGENT
208
+ // auto-upgrade chain) rather than bulk-staged.
209
+ if (PerpsClient.EXPLICIT_INPUT_PREREQUISITES.has(p.type)) {
210
+ return false
211
+ }
212
+ if (mode === SigningMode.USER) {
213
+ // USER mode: only items the user can sign, and never APPROVE_AGENT
214
+ // (no agent is created in this mode).
215
+ if (!p.signers.includes(PerpsSigner.USER)) {
216
+ return false
217
+ }
218
+ if (p.type === ActionType.APPROVE_AGENT) {
219
+ return false
220
+ }
221
+ return true
222
+ }
223
+ // USER_AGENT mode: include every remaining declared prerequisite.
224
+ return true
225
+ })
226
+ .map((p) => {
227
+ const params: Record<string, unknown> = {}
228
+ if (p.type === ActionType.APPROVE_AGENT && agentAddress) {
229
+ params.agentAddress = agentAddress
230
+ }
231
+ return {
232
+ key: p.type,
233
+ ...(Object.keys(params).length > 0 ? { params } : {}),
234
+ }
235
+ })
236
+ }
237
+
238
+ private async resolveSignerForAction(
239
+ action: ActionType,
122
240
  address: Address,
123
- dex: string,
124
- mode: SigningMode
125
- ): Promise<void> {
126
- const key = this.modeKey(address, dex)
127
- this.signingModes.set(key, mode)
241
+ provider: string
242
+ ): Promise<Address | undefined> {
243
+ const mode = await this.loadSigningMode(address, provider)
244
+ if (mode !== SigningMode.USER_AGENT) {
245
+ return undefined
246
+ }
128
247
 
129
- if (mode === 'USER_AGENT') {
130
- // Generate agent keypair if not exists
131
- await this.sdkClient.agentManager.getOrCreateAgent(address, dex)
248
+ // Only AGENT-signed actions surface a distinct signerAddress on the wire.
249
+ // API_KEY signers (e.g. Lighter's LighterKeyStore) are managed per-provider
250
+ // and don't have an EVM address — the backend identifies the action by the
251
+ // L1 `address` instead.
252
+ const metadata = await this.getProviderMetadata(provider)
253
+ const allActions = [
254
+ ...metadata.setup,
255
+ ...metadata.options,
256
+ ...metadata.actions,
257
+ ]
258
+ const descriptor = allActions.find((d) => d.type === action)
259
+ if (!descriptor?.signers.includes(PerpsSigner.AGENT)) {
260
+ return undefined
132
261
  }
262
+
263
+ const agent = await this.sdkClient.agentManager.getAgent(address, provider)
264
+ return agent.address
133
265
  }
134
266
 
135
267
  /**
136
- * Get the current signing mode for a user + DEX pair.
137
- * Defaults to `USER` if not set.
268
+ * True if any descriptor for the provider lists `PerpsSigner.AGENT`.
269
+ * Providers like Lighter sign with their own keystore and never need an
270
+ * AgentManager-managed agent.
138
271
  */
139
- getSigningMode(address: Address, dex: string): SigningMode {
140
- return this.signingModes.get(this.modeKey(address, dex)) ?? 'USER'
272
+ private async providerUsesAgent(provider: string): Promise<boolean> {
273
+ const metadata = await this.getProviderMetadata(provider)
274
+ const all = [...metadata.setup, ...metadata.options, ...metadata.actions]
275
+ return all.some((d) => d.signers.includes(PerpsSigner.AGENT))
141
276
  }
142
277
 
143
- /**
144
- * Get the agent address for a user + DEX pair.
145
- *
146
- * @throws {PerpsError} If in USER mode or agent not found
147
- */
148
- async getAgentAddress(address: Address, dex: string): Promise<Address> {
149
- const agent = await this.sdkClient.agentManager.getAgent(address, dex)
150
- return agent.address
278
+ private async autoSignAndExecute(
279
+ provider: string,
280
+ address: Address,
281
+ action: ActionType,
282
+ actions: ActionStep[],
283
+ descriptor: ActionDescriptor
284
+ ): Promise<ExecuteActionResponse> {
285
+ switch (descriptor.signingMethod) {
286
+ case SigningMethod.EIP712: {
287
+ const eip712Actions = actions as Eip712ActionStep[]
288
+
289
+ if (descriptor.signers.includes(PerpsSigner.AGENT)) {
290
+ const agent = await this.sdkClient.agentManager.getAgent(
291
+ address,
292
+ provider
293
+ )
294
+ const signedActions: SignedActionStep[] = await Promise.all(
295
+ eip712Actions.map(
296
+ async (a) =>
297
+ ({
298
+ action: a.action,
299
+ typedData: a.typedData,
300
+ signature: await signTypedData(agent.privateKey, a.typedData),
301
+ }) satisfies Eip712SignedActionStep
302
+ )
303
+ )
304
+ return executeAction(this.sdkClient, {
305
+ provider,
306
+ address,
307
+ signerAddress: agent.address,
308
+ action,
309
+ actions: signedActions,
310
+ })
311
+ }
312
+
313
+ if (descriptor.signers.includes(PerpsSigner.USER)) {
314
+ const signer = this.sdkClient.signer
315
+ if (!signer) {
316
+ throw new PerpsError(
317
+ PerpsErrorCode.SDKError,
318
+ `Action '${action}' requires a user-wallet signature, but no signer was configured. Pass a WalletClient to createPerpsClient({ signer }).`
319
+ )
320
+ }
321
+ const signedActions: SignedActionStep[] = await Promise.all(
322
+ eip712Actions.map(
323
+ async (a) =>
324
+ ({
325
+ action: a.action,
326
+ typedData: a.typedData,
327
+ signature: await signTypedDataWithSigner(signer, a.typedData),
328
+ }) satisfies Eip712SignedActionStep
329
+ )
330
+ )
331
+ return executeAction(this.sdkClient, {
332
+ provider,
333
+ address,
334
+ signerAddress: address,
335
+ action,
336
+ actions: signedActions,
337
+ })
338
+ }
339
+
340
+ throw new PerpsError(
341
+ PerpsErrorCode.SDKError,
342
+ `Action '${action}' descriptor names no supported signer (signers=[${descriptor.signers.join(', ')}]).`
343
+ )
344
+ }
345
+
346
+ case SigningMethod.WASM_BLOB: {
347
+ const wasmActions = actions as WasmBlobActionStep[]
348
+ const signedActions = await this.signWasmBlobActions(
349
+ provider,
350
+ address,
351
+ wasmActions
352
+ )
353
+ return executeAction(this.sdkClient, {
354
+ provider,
355
+ address,
356
+ signerAddress: address,
357
+ action,
358
+ actions: signedActions,
359
+ })
360
+ }
361
+
362
+ case SigningMethod.EVM_TX: {
363
+ const evmActions = actions as EvmTxActionStep[]
364
+ const signedActions = await this.signEvmTxActions(evmActions)
365
+ return executeAction(this.sdkClient, {
366
+ provider,
367
+ address,
368
+ signerAddress: address,
369
+ action,
370
+ actions: signedActions,
371
+ })
372
+ }
373
+
374
+ default:
375
+ throw new Error(`Unknown signingMethod: ${descriptor.signingMethod}`)
376
+ }
151
377
  }
152
378
 
153
379
  /**
154
- * Check if an agent exists for a user + DEX pair.
380
+ * Sign a single prerequisite step using whichever signing path matches the
381
+ * step's shape — EIP-712 typed data, WASM blob (with the hybrid EIP-191 +
382
+ * WASM flow for REGISTER_API_KEY), or EVM transaction. Lets consumers
383
+ * collect signed prereqs without embedding per-method signing logic.
155
384
  */
156
- async hasAgent(address: Address, dex: string): Promise<boolean> {
157
- return this.sdkClient.agentManager.hasAgent(address, dex)
385
+ async signPrerequisite(
386
+ provider: string,
387
+ address: Address,
388
+ step: ActionStep
389
+ ): Promise<SignedActionStep> {
390
+ if ('typedData' in step) {
391
+ if (!this.sdkClient.signer) {
392
+ throw new PerpsError(
393
+ PerpsErrorCode.SDKError,
394
+ 'EIP-712 prerequisite signing requires a wallet signer. Pass ' +
395
+ '`signer` to createPerpsClient or call setSigner(walletClient).'
396
+ )
397
+ }
398
+ return {
399
+ action: step.action,
400
+ typedData: step.typedData,
401
+ signature: await signTypedDataWithSigner(
402
+ this.sdkClient.signer,
403
+ step.typedData
404
+ ),
405
+ } satisfies Eip712SignedActionStep
406
+ }
407
+ if ('wasmSignParams' in step) {
408
+ const [signed] = await this.signWasmBlobActions(provider, address, [step])
409
+ return signed
410
+ }
411
+ if ('txParams' in step) {
412
+ const [signed] = await this.signEvmTxActions([step])
413
+ return signed
414
+ }
415
+ throw new PerpsError(
416
+ PerpsErrorCode.SDKError,
417
+ 'Unknown ActionStep shape — expected typedData, wasmSignParams, or txParams.'
418
+ )
158
419
  }
159
420
 
160
421
  /**
161
- * Remove the agent for a user + DEX pair.
162
- * Also resets signing mode to USER.
422
+ * Sign and broadcast a sequence of EVM transactions via the user's wallet
423
+ * client. Steps are submitted serially so a later step (e.g. deposit) can
424
+ * rely on an earlier step (e.g. approve) having mined. Each step's
425
+ * `txParams` carries chainId, target, function name, args, and a
426
+ * human-readable abi from the backend.
163
427
  */
164
- async removeAgent(address: Address, dex: string): Promise<void> {
165
- await this.sdkClient.agentManager.removeAgent(address, dex)
166
- this.signingModes.delete(this.modeKey(address, dex))
428
+ private async signEvmTxActions(
429
+ actions: EvmTxActionStep[]
430
+ ): Promise<EvmTxSignedActionStep[]> {
431
+ if (!this.sdkClient.signer) {
432
+ throw new PerpsError(
433
+ PerpsErrorCode.SDKError,
434
+ 'EVM_TX signing requires a wallet signer. Pass `signer` to ' +
435
+ 'createPerpsClient or call setSigner(walletClient).'
436
+ )
437
+ }
438
+ const { signer } = this.sdkClient
439
+ const signed: EvmTxSignedActionStep[] = []
440
+
441
+ for (const step of actions) {
442
+ const params = step.txParams as {
443
+ chainId: number
444
+ to: Address
445
+ functionName: string
446
+ args: readonly unknown[]
447
+ abi: readonly string[]
448
+ }
449
+
450
+ const txHash = await signer.writeContract({
451
+ address: params.to,
452
+ abi: parseAbi(params.abi),
453
+ functionName: params.functionName,
454
+ args: params.args,
455
+ chain: signer.chain,
456
+ account: signer.account,
457
+ })
458
+
459
+ signed.push({
460
+ action: step.action,
461
+ txParams: step.txParams,
462
+ txHash,
463
+ })
464
+ }
465
+
466
+ return signed
167
467
  }
168
468
 
169
469
  /**
170
- * Build authorization payloads for signing.
470
+ * Sign a batch of WASM_BLOB action steps (Lighter). Ensures the user's
471
+ * Lighter API keypair is registered first — generating one and running the
472
+ * REGISTER_API_KEY hybrid flow via the L1 signer if not — then feeds each
473
+ * subsequent step through the WASM signer and returns signed blobs.
171
474
  *
172
- * In `USER` mode, `signerAddress` is omitted (backend defaults to `address`).
173
- * In `USER_AGENT` mode, auto-injects the agent address as `signerAddress`.
174
- *
175
- * @param params - Authorization parameters
176
- * @returns Authorization actions with typed data for signing
475
+ * `ACCOUNT_TYPE` (Lighter `/api/v1/changeAccountTier`) is dispatched as a
476
+ * WASM_BLOB envelope by the backend but is NOT a wasm-signed transaction —
477
+ * Lighter authenticates the endpoint with an auth token and enforces
478
+ * anti-replay server-side (24h cooldown, no open positions). The signer
479
+ * mints a Lighter auth token via the same WASM `CreateAuthToken` the read
480
+ * endpoints use and parks it in `signedTx.txInfo`; the backend's
481
+ * `executeChangeAccountTier` consumes that field as the `auth` form
482
+ * parameter. `txType`/`txHash` are unused for this action — they carry
483
+ * placeholder values to satisfy the `WasmBlobSignedActionStep` shape.
177
484
  */
178
- async buildAuthorization(
179
- params: BuildAuthorizationParams
180
- ): Promise<CreateAuthorizationResponse> {
181
- const mode = this.getSigningMode(params.address, params.dex)
182
- let { signerAddress } = params
485
+ private async signWasmBlobActions(
486
+ provider: string,
487
+ address: Address,
488
+ actions: WasmBlobActionStep[]
489
+ ): Promise<WasmBlobSignedActionStep[]> {
490
+ const signed: WasmBlobSignedActionStep[] = []
491
+ for (const step of actions) {
492
+ if (step.action === ActionType.REGISTER_API_KEY) {
493
+ signed.push(await this.signRegisterApiKey(provider, address, step))
494
+ } else if (step.action === ActionType.ACCOUNT_TYPE) {
495
+ signed.push(await this.signAccountTierChange(address, step))
496
+ } else {
497
+ signed.push(await this.signStandardWasmAction(provider, address, step))
498
+ }
499
+ }
500
+ return signed
501
+ }
183
502
 
184
- if (mode === 'USER_AGENT') {
185
- const agent = await this.sdkClient.agentManager.getAgent(
186
- params.address,
187
- params.dex
503
+ private async signStandardWasmAction(
504
+ provider: string,
505
+ address: Address,
506
+ step: WasmBlobActionStep
507
+ ): Promise<WasmBlobSignedActionStep> {
508
+ const apiKey = await this.getLighterKeyStore().get(address)
509
+ if (!apiKey) {
510
+ throw new PerpsError(
511
+ PerpsErrorCode.SDKError,
512
+ `No Lighter API key registered for ${address}. ` +
513
+ 'Run prepareAccount / REGISTER_API_KEY first.'
188
514
  )
189
- signerAddress = signerAddress ?? agent.address
190
515
  }
191
-
192
- return createAuthorization(this.sdkClient, {
193
- ...params,
194
- signerAddress,
516
+ const signer = this.getLighterSigner()
517
+ const signedTx = await signer.sign(step.action, step.wasmSignParams, {
518
+ apiKeyPrivateKey: apiKey.apiKeyPrivateKey,
519
+ apiKeyIndex: apiKey.apiKeyIndex,
520
+ accountIndex: apiKey.accountIndex,
195
521
  })
522
+ void provider
523
+ return {
524
+ action: step.action,
525
+ wasmSignParams: step.wasmSignParams,
526
+ signedTx,
527
+ }
196
528
  }
197
529
 
198
530
  /**
199
- * Submit signed authorizations.
531
+ * REGISTER_API_KEY flow:
532
+ * 1. Look up the user's Lighter accountIndex from getAccount()
533
+ * 2. Generate a fresh Lighter API keypair via the WASM signer
534
+ * 3. Call SignChangePubKey to produce the WASM blob + EIP-191 message
535
+ * 4. Have the user's L1 Ethereum wallet sign the message
536
+ * 5. Inject the L1 signature into the ChangePubKey txInfo JSON
537
+ * 6. Persist the keypair and return the signed blob
200
538
  *
201
- * In `USER` mode, `signerAddress` is omitted (backend defaults to `address`).
202
- * In `USER_AGENT` mode, auto-injects the agent address as `signerAddress`.
203
- *
204
- * @param params - Signed authorization parameters
539
+ * Requires a USER wallet signer to be set via `setSigner` or passed at
540
+ * construction the L1 signature is the user's consent to rotate keys.
205
541
  */
206
- async submitAuthorizations(
207
- params: SubmitAuthorizationParams
208
- ): Promise<AuthorizationsResponse> {
209
- const mode = this.getSigningMode(params.address, params.dex)
210
- let { signerAddress } = params
542
+ private async signRegisterApiKey(
543
+ provider: string,
544
+ address: Address,
545
+ step: WasmBlobActionStep
546
+ ): Promise<WasmBlobSignedActionStep> {
547
+ if (!this.sdkClient.signer) {
548
+ throw new PerpsError(
549
+ PerpsErrorCode.SDKError,
550
+ 'REGISTER_API_KEY requires a wallet signer — pass `signer` to ' +
551
+ 'createPerpsClient or call setSigner(walletClient).'
552
+ )
553
+ }
211
554
 
212
- if (mode === 'USER_AGENT') {
213
- const agent = await this.sdkClient.agentManager.getAgent(
214
- params.address,
215
- params.dex
555
+ const params = step.wasmSignParams as {
556
+ api_key_index?: number
557
+ nonce?: number
558
+ }
559
+ const apiKeyIndex = params.api_key_index ?? DEFAULT_API_KEY_INDEX
560
+ const nonce = params.nonce
561
+ if (typeof nonce !== 'number') {
562
+ throw new PerpsError(
563
+ PerpsErrorCode.SDKError,
564
+ 'REGISTER_API_KEY wasmSignParams is missing `nonce`.'
565
+ )
566
+ }
567
+
568
+ const account = await getAccount(this.sdkClient, { provider, address })
569
+ if (account.config.provider !== 'lighter') {
570
+ throw new PerpsError(
571
+ PerpsErrorCode.SDKError,
572
+ `REGISTER_API_KEY requires a Lighter account, but getAccount ` +
573
+ `returned config for provider '${account.config.provider}'.`
216
574
  )
217
- signerAddress = signerAddress ?? agent.address
218
575
  }
576
+ const accountIndex = account.config.accountIndex
577
+
578
+ const signer = this.getLighterSigner()
579
+ const keypair = await signer.generateAPIKey()
580
+ const changePubKey = await signer.signChangePubKey(
581
+ keypair.publicKey,
582
+ keypair.privateKey,
583
+ nonce,
584
+ apiKeyIndex,
585
+ accountIndex
586
+ )
587
+
588
+ const l1Signature = await this.sdkClient.signer.signMessage({
589
+ account: this.sdkClient.signer.account,
590
+ message: changePubKey.messageToSign,
591
+ })
592
+
593
+ const txInfoWithL1Sig = signer.embedL1Signature(
594
+ changePubKey.txInfo,
595
+ l1Signature
596
+ )
597
+
598
+ const apiKey: LighterApiKey = {
599
+ accountIndex,
600
+ apiKeyIndex,
601
+ apiKeyPrivateKey: keypair.privateKey,
602
+ apiKeyPublicKey: keypair.publicKey,
603
+ }
604
+ await this.getLighterKeyStore().set(address, apiKey)
219
605
 
220
- return submitAuthorization(this.sdkClient, { ...params, signerAddress })
606
+ return {
607
+ action: step.action,
608
+ wasmSignParams: {
609
+ ...step.wasmSignParams,
610
+ new_public_key: keypair.publicKey,
611
+ },
612
+ signedTx: {
613
+ txType: changePubKey.txType,
614
+ txInfo: txInfoWithL1Sig,
615
+ txHash: changePubKey.txHash,
616
+ },
617
+ }
221
618
  }
222
619
 
223
620
  /**
224
- * Build order payloads for signing.
621
+ * Sign an `ACCOUNT_TYPE` step (Lighter `changeAccountTier`).
225
622
  *
226
- * In `USER` mode, `signerAddress` is omitted (backend defaults to `address`).
227
- * In `USER_AGENT` mode, auto-injects the agent address as `signerAddress`.
623
+ * Lighter's `/api/v1/changeAccountTier` is an HTTP-only mutation
624
+ * Lighter does NOT consume a wasm-signed transaction here; it
625
+ * authenticates the request with the same auth token its read endpoints
626
+ * use, and enforces anti-replay business rules server-side. The backend
627
+ * therefore declares the step as a `WasmBlobActionStep` with
628
+ * `wasmSignParams.kind = 'changeAccountTier'` and expects the SDK to
629
+ * mint an auth token in lieu of a transaction signature. That contract
630
+ * is documented in `lifi-perps-backend/src/providers/lighter/actions/
631
+ * lighter.actions.accountType.ts` and consumed by `executeChangeAccountTier`.
228
632
  *
229
- * @param params - Order parameters
230
- * @returns Order actions with typed data for signing
633
+ * The auth-token deadline mirrors {@link createLighterAuthToken}'s 1h
634
+ * default Lighter caps tokens at 8h hard, and the backend's executor
635
+ * runs `verifyPendingAction` then a single `/changeAccountTier` POST,
636
+ * which completes well inside an hour.
231
637
  */
232
- async buildOrder(params: PlaceOrderParams): Promise<CreateOrderResponse> {
233
- const mode = this.getSigningMode(params.address, params.dex)
234
- let signerAddress: Address | undefined
235
-
236
- if (mode === 'USER_AGENT') {
237
- const agent = await this.sdkClient.agentManager.getAgent(
238
- params.address,
239
- params.dex
638
+ private async signAccountTierChange(
639
+ address: Address,
640
+ step: WasmBlobActionStep
641
+ ): Promise<WasmBlobSignedActionStep> {
642
+ const apiKey = await this.getLighterKeyStore().get(address)
643
+ if (!apiKey) {
644
+ throw new PerpsError(
645
+ PerpsErrorCode.SDKError,
646
+ `No Lighter API key registered for ${address}. ` +
647
+ 'Run prepareAccount / REGISTER_API_KEY first.'
240
648
  )
241
- signerAddress = agent.address
242
649
  }
243
-
244
- return createOrder(this.sdkClient, {
245
- dex: params.dex,
246
- address: params.address,
247
- signerAddress,
248
- clientOrderId: params.clientOrderId,
249
- symbol: params.symbol,
250
- side: params.side,
251
- type: params.type,
252
- size: params.size,
253
- price: params.price,
254
- leverage: params.leverage,
255
- reduceOnly: params.reduceOnly,
256
- timeInForce: params.timeInForce,
257
- expiresAt: params.expiresAt,
258
- takeProfit: params.takeProfit,
259
- stopLoss: params.stopLoss,
650
+ const signer = this.getLighterSigner()
651
+ const deadline = Math.floor(Date.now() / 1000) + 60 * 60
652
+ const authToken = await signer.createAuthToken(deadline, {
653
+ apiKeyPrivateKey: apiKey.apiKeyPrivateKey,
654
+ apiKeyIndex: apiKey.apiKeyIndex,
655
+ accountIndex: apiKey.accountIndex,
260
656
  })
657
+ return {
658
+ action: step.action,
659
+ wasmSignParams: step.wasmSignParams,
660
+ signedTx: {
661
+ // `/changeAccountTier` reads only `txInfo` (the auth token); `txType`
662
+ // and `txHash` are placeholders to satisfy the envelope shape.
663
+ txType: 0,
664
+ txInfo: authToken,
665
+ txHash: '',
666
+ },
667
+ }
261
668
  }
262
669
 
263
670
  /**
264
- * Build cancel order payloads for signing.
671
+ * Return a bearer token that authenticates Lighter's read endpoints
672
+ * (getOrders, getOrder, getActivity, getFills).
265
673
  *
266
- * In `USER` mode, `signerAddress` is omitted (backend defaults to `address`).
267
- * In `USER_AGENT` mode, auto-injects the agent address as `signerAddress`.
674
+ * Resolution order:
675
+ * 1. The long-lived read-only token persisted by `approveReadOnlyToken`,
676
+ * when one is stored for this `(address, accountIndex)` AND has not
677
+ * passed its recorded `expiry`. The SDK never returns an expired
678
+ * stored token.
679
+ * 2. A freshly minted 8h Lighter auth token, signed off the user's
680
+ * Lighter API key. Requires `REGISTER_API_KEY` to have completed.
681
+ * 3. `undefined` — caller falls back to public reads.
268
682
  *
269
- * @param params - Cancel parameters
270
- * @returns Cancel actions with typed data for signing
683
+ * `accountIndex` lets callers in pure read-only mode (no API key
684
+ * registered) target the RO token. When omitted, the SDK derives it from
685
+ * the user's registered API key.
686
+ *
687
+ * `deadlineSeconds` only affects the standard-token fallback (Lighter caps
688
+ * those tokens at 8h). Read-only tokens carry their own mint-time expiry
689
+ * recorded by {@link approveReadOnlyToken}.
271
690
  */
272
- async buildCancelOrder(
273
- params: CancelOrdersParams
274
- ): Promise<CancelOrderPayloadResponse> {
275
- const mode = this.getSigningMode(params.address, params.dex)
276
- let signerAddress: Address | undefined
277
-
278
- if (mode === 'USER_AGENT') {
279
- const agent = await this.sdkClient.agentManager.getAgent(
280
- params.address,
281
- params.dex
691
+ async createLighterAuthToken(
692
+ address: Address,
693
+ deadlineSeconds?: number,
694
+ accountIndex?: number
695
+ ): Promise<string | undefined> {
696
+ const apiKey = await this.getLighterKeyStore().get(address)
697
+ const resolvedAccountIndex = accountIndex ?? apiKey?.accountIndex
698
+ if (resolvedAccountIndex !== undefined) {
699
+ const stored = await this.getLighterReadOnlyTokenManager().get(
700
+ address,
701
+ resolvedAccountIndex
282
702
  )
283
- signerAddress = agent.address
703
+ if (stored) {
704
+ return stored.token
705
+ }
284
706
  }
285
-
286
- return cancelOrder(this.sdkClient, {
287
- dex: params.dex,
288
- address: params.address,
289
- signerAddress,
290
- ids: params.ids,
707
+ if (!apiKey) {
708
+ return undefined
709
+ }
710
+ const deadline = deadlineSeconds ?? Math.floor(Date.now() / 1000) + 60 * 60
711
+ const signer = this.getLighterSigner()
712
+ return signer.createAuthToken(deadline, {
713
+ apiKeyPrivateKey: apiKey.apiKeyPrivateKey,
714
+ apiKeyIndex: apiKey.apiKeyIndex,
715
+ accountIndex: apiKey.accountIndex,
291
716
  })
292
717
  }
293
718
 
294
719
  /**
295
- * Place an order with automatic agent signing.
720
+ * Mint a long-lived Lighter read-only token via Lighter's
721
+ * `tokens/create` endpoint and persist it through the configured
722
+ * `StorageAdapter`, keyed by `(L1 address, accountIndex)`.
723
+ *
724
+ * The user's connected wallet signs an EIP-191 message describing the
725
+ * mint request; the resulting `Authorization` header authenticates the
726
+ * Lighter HTTP call. The bearer string Lighter returns is persisted
727
+ * alongside its `expiry` and `scope`; subsequent calls to
728
+ * {@link createLighterAuthToken} prefer it over the 8h standard token.
296
729
  *
297
- * **Requires USER_AGENT mode.** For USER mode, use `buildOrder()` + `submitSignedOrder()`.
730
+ * `expirySeconds` is the absolute unix-seconds expiry recorded on
731
+ * Lighter's row. Lighter enforces 1 day ≤ lifetime ≤ 10 years
732
+ * server-side; the SDK does NOT pre-validate and surfaces Lighter's 400
733
+ * verbatim. `scope` defaults to `'all'`; the `'single'` variant is wired
734
+ * through but only useful when the caller has a specific reason to scope
735
+ * the token to one account.
298
736
  *
299
- * @param params - Order parameters
300
- * @returns Order submission results
301
- * @throws {PerpsError} If not in USER_AGENT mode
737
+ * Requires a USER wallet signer to be set via {@link setSigner} or
738
+ * passed at construction — the L1 signature is the user's consent.
302
739
  */
303
- async placeOrder(params: PlaceOrderParams): Promise<SubmitOrderResponse> {
304
- const mode = this.getSigningMode(params.address, params.dex)
305
-
306
- if (mode !== 'USER_AGENT') {
740
+ async approveReadOnlyToken(
741
+ address: Address,
742
+ params: ApproveReadOnlyTokenParams
743
+ ): Promise<ApproveReadOnlyTokenResult> {
744
+ if (!this.sdkClient.signer) {
307
745
  throw new PerpsError(
308
- PerpsErrorCode.ValidationError,
309
- `${PerpsErrorMessage.InvalidSigningMode} placeOrder() requires USER_AGENT mode. Use createOrder() + submitOrder() for USER mode.`
746
+ PerpsErrorCode.SDKError,
747
+ 'approveReadOnlyToken requires a wallet signer pass `signer` to ' +
748
+ 'createPerpsClient or call setSigner(walletClient).'
310
749
  )
311
750
  }
751
+ const signer = walletClientSigner(this.sdkClient.signer)
752
+ return this.getLighterReadOnlyTokenManager().approve(signer, {
753
+ address,
754
+ ...params,
755
+ })
756
+ }
312
757
 
313
- const agent = await this.sdkClient.agentManager.getAgent(
314
- params.address,
315
- params.dex
758
+ /**
759
+ * Whether the stored Lighter read-only token for `(address, accountIndex)`
760
+ * falls within `thresholdDays` of its `expiry`. Returns `false` when no
761
+ * token is stored, when the stored token has already expired, or when
762
+ * more than `thresholdDays` of life remain. Intended for widget renewal
763
+ * banners (default threshold: 30 days).
764
+ */
765
+ async isLighterReadOnlyTokenExpiringSoon(
766
+ address: Address,
767
+ accountIndex: number,
768
+ thresholdDays?: number
769
+ ): Promise<boolean> {
770
+ return this.getLighterReadOnlyTokenManager().isReadOnlyTokenExpiringSoon(
771
+ address,
772
+ accountIndex,
773
+ thresholdDays
316
774
  )
775
+ }
317
776
 
318
- // 1. Create order payloads
319
- const { actions } = await createOrder(this.sdkClient, {
320
- dex: params.dex,
321
- address: params.address,
322
- signerAddress: agent.address,
323
- clientOrderId: params.clientOrderId,
324
- symbol: params.symbol,
325
- side: params.side,
326
- type: params.type,
327
- size: params.size,
328
- price: params.price,
329
- leverage: params.leverage,
330
- reduceOnly: params.reduceOnly,
331
- timeInForce: params.timeInForce,
332
- expiresAt: params.expiresAt,
333
- takeProfit: params.takeProfit,
334
- stopLoss: params.stopLoss,
335
- })
777
+ // ---------------------------------------------------------------------------
778
+ // Generic action helpers
779
+ // ---------------------------------------------------------------------------
336
780
 
337
- // 2. Sign each action with agent key
338
- const signedActions: SignedOrderAction[] = await Promise.all(
339
- actions.map(async (a) => ({
340
- action: a.action,
341
- typedData: a.typedData,
342
- signature: await signTypedData(agent.privateKey, a.typedData),
343
- }))
781
+ async buildAction<T extends ActionType>(
782
+ action: T,
783
+ params: { provider: string; address: Address; params: ActionParamsMap[T] }
784
+ ): Promise<CreateActionResponse> {
785
+ const signerAddress = await this.resolveSignerForAction(
786
+ action,
787
+ params.address,
788
+ params.provider
344
789
  )
345
-
346
- // 3. Submit
347
- return submitOrder(this.sdkClient, {
348
- dex: params.dex,
790
+ return createAction(this.sdkClient, {
791
+ provider: params.provider,
349
792
  address: params.address,
350
- signerAddress: agent.address,
351
- actions: signedActions,
793
+ signerAddress,
794
+ action,
795
+ params: params.params,
352
796
  })
353
797
  }
354
798
 
355
- /**
356
- * Cancel orders with automatic agent signing.
357
- *
358
- * **Requires USER_AGENT mode.** For USER mode, use `buildCancelOrder()` + `submitSignedOrder()`.
359
- *
360
- * @param params - Cancel parameters
361
- * @returns Cancel submission results
362
- * @throws {PerpsError} If not in USER_AGENT mode
363
- */
364
- async cancelOrders(params: CancelOrdersParams): Promise<SubmitOrderResponse> {
365
- const mode = this.getSigningMode(params.address, params.dex)
799
+ // ---------------------------------------------------------------------------
800
+ // Signing mode management
801
+ // ---------------------------------------------------------------------------
366
802
 
367
- if (mode !== 'USER_AGENT') {
368
- throw new PerpsError(
369
- PerpsErrorCode.ValidationError,
370
- `${PerpsErrorMessage.InvalidSigningMode} cancelOrders() requires USER_AGENT mode. Use cancelOrder() + submitOrder() for USER mode.`
371
- )
803
+ async setSigningMode(
804
+ address: Address,
805
+ provider: string,
806
+ mode: SigningMode
807
+ ): Promise<void> {
808
+ const key = this.modeKey(address, provider)
809
+ this.signingModes.set(key, mode)
810
+ await this.storage.set(this.signingModeStorageKey(address, provider), mode)
811
+ if (
812
+ mode === SigningMode.USER_AGENT &&
813
+ (await this.providerUsesAgent(provider))
814
+ ) {
815
+ await this.sdkClient.agentManager.getOrCreateAgent(address, provider)
372
816
  }
817
+ }
373
818
 
374
- const agent = await this.sdkClient.agentManager.getAgent(
375
- params.address,
376
- params.dex
819
+ getSigningMode(address: Address, provider: string): SigningMode {
820
+ return (
821
+ this.signingModes.get(this.modeKey(address, provider)) ??
822
+ SigningMode.USER_AGENT
377
823
  )
824
+ }
378
825
 
379
- // 1. Create cancel payloads
380
- const { actions } = await cancelOrder(this.sdkClient, {
381
- dex: params.dex,
382
- address: params.address,
383
- signerAddress: agent.address,
384
- ids: params.ids,
385
- })
826
+ async loadSigningMode(
827
+ address: Address,
828
+ provider: string
829
+ ): Promise<SigningMode> {
830
+ const key = this.modeKey(address, provider)
831
+ if (this.signingModes.has(key)) {
832
+ return this.signingModes.get(key)!
833
+ }
386
834
 
387
- // 2. Sign each action with agent key
388
- const signedActions: SignedOrderAction[] = await Promise.all(
389
- actions.map(async (a) => ({
390
- action: a.action as OrderActionType,
391
- typedData: a.typedData,
392
- signature: await signTypedData(agent.privateKey, a.typedData),
393
- }))
835
+ const stored = await this.storage.get(
836
+ this.signingModeStorageKey(address, provider)
394
837
  )
838
+ const mode: SigningMode =
839
+ stored === SigningMode.USER_AGENT || stored === SigningMode.USER
840
+ ? stored
841
+ : SigningMode.USER_AGENT
842
+ this.signingModes.set(key, mode)
843
+ return mode
844
+ }
395
845
 
396
- // 3. Submit
397
- return submitOrder(this.sdkClient, {
398
- dex: params.dex,
399
- address: params.address,
400
- signerAddress: agent.address,
401
- actions: signedActions,
402
- })
846
+ async loadAgentMode(address: Address, provider: string): Promise<boolean> {
847
+ const mode = await this.loadSigningMode(address, provider)
848
+ return mode === SigningMode.USER_AGENT
403
849
  }
404
850
 
405
- /**
406
- * Submit pre-signed order actions.
407
- *
408
- * Use this for USER mode when you've already signed the actions with the user's wallet.
409
- * Auto-injects `signerAddress` if not provided (defaults to `address`).
410
- *
411
- * @param params - Signed order parameters
412
- */
413
- async submitSignedOrder(
414
- params: SubmitOrderParams
415
- ): Promise<SubmitOrderResponse> {
416
- return submitOrder(this.sdkClient, params)
851
+ async setAgentMode(
852
+ address: Address,
853
+ provider: string,
854
+ useAgent: boolean
855
+ ): Promise<void> {
856
+ await this.setSigningMode(
857
+ address,
858
+ provider,
859
+ useAgent ? SigningMode.USER_AGENT : SigningMode.USER
860
+ )
861
+ }
862
+
863
+ async getAgentAddress(address: Address, provider: string): Promise<Address> {
864
+ const agent = await this.sdkClient.agentManager.getAgent(address, provider)
865
+ return agent.address
866
+ }
867
+
868
+ async hasAgent(address: Address, provider: string): Promise<boolean> {
869
+ return this.sdkClient.agentManager.hasAgent(address, provider)
870
+ }
871
+
872
+ async removeAgent(address: Address, provider: string): Promise<void> {
873
+ await this.sdkClient.agentManager.removeAgent(address, provider)
874
+ this.signingModes.delete(this.modeKey(address, provider))
875
+ await this.storage.remove(this.signingModeStorageKey(address, provider))
417
876
  }
418
877
 
878
+ // ---------------------------------------------------------------------------
879
+ // Account
880
+ // ---------------------------------------------------------------------------
881
+
419
882
  /**
420
- * Build a withdrawal payload for the user to sign.
421
- *
422
- * Withdrawals are user-signed only agents cannot initiate withdrawals.
423
- * No agent injection is performed regardless of signing mode.
424
- *
425
- * @param params - Withdrawal parameters
426
- * @returns Withdrawal action with typed data for signing
883
+ * Fetch the user's account state from the backend and attach the
884
+ * SDK-projected `settings` array — one `AccountConfigSetting` per
885
+ * descriptor on `Provider.setup` + `Provider.options`. Callers read
886
+ * `result.settings` directly without re-deriving values from the typed
887
+ * `AccountConfig`.
427
888
  */
428
- async buildWithdrawal(
429
- params: BuildWithdrawalParams
430
- ): Promise<CreateWithdrawalResponse> {
431
- return createWithdrawal(this.sdkClient, {
432
- dex: params.dex,
433
- address: params.address,
434
- withdrawal: params.withdrawal,
435
- })
889
+ async getAccount(params: {
890
+ provider: string
891
+ address: Address
892
+ }): Promise<GetAccountResult> {
893
+ const [response, metadata] = await Promise.all([
894
+ getAccount(this.sdkClient, params),
895
+ this.getProviderMetadata(params.provider),
896
+ ])
897
+ const settings = projectAccountConfigSettings(
898
+ response.config,
899
+ metadata.setup,
900
+ metadata.options
901
+ )
902
+ return { ...response, settings }
436
903
  }
437
904
 
438
905
  /**
439
- * Submit a signed withdrawal.
440
- *
441
- * Withdrawals are user-signed only agents cannot initiate withdrawals.
442
- *
443
- * @param params - Signed withdrawal parameters
444
- * @returns Withdrawal result
906
+ * Thin existence check for a provider account at `address`. Returns
907
+ * `true` when `getAccount` resolves, `false` when the backend reports
908
+ * `PerpsErrorCode.AccountNotFound`, and re-throws on any other error
909
+ * (transport failures, validation errors, server errors).
445
910
  */
446
- async submitWithdrawal(
447
- params: SubmitWithdrawalParams
448
- ): Promise<SubmitWithdrawalResponse> {
449
- return submitWithdrawal(this.sdkClient, params)
911
+ async accountExists(provider: string, address: Address): Promise<boolean> {
912
+ try {
913
+ await getAccount(this.sdkClient, { provider, address })
914
+ return true
915
+ } catch (err) {
916
+ if (
917
+ err instanceof PerpsError &&
918
+ err.code === PerpsErrorCode.AccountNotFound
919
+ ) {
920
+ return false
921
+ }
922
+ throw err
923
+ }
450
924
  }
451
925
 
926
+ // ---------------------------------------------------------------------------
927
+ // Setup
928
+ // ---------------------------------------------------------------------------
929
+
452
930
  /**
453
- * Determine which authorizations (if any) the user needs to sign before trading.
454
- *
455
- * Uses the dex auth provider to determine what authorizations to request,
456
- * then calls buildAuthorization — the backend filters already-valid auths
457
- * and returns only what's needed.
931
+ * Return the unsatisfied entries on `Provider.setup` for this account,
932
+ * split by signer role. Trading is gated on `isReady === true`.
458
933
  *
459
- * @param params - Parameters including dex, address, and dex-specific config
460
- * @returns Which authorizations are needed and whether the user is ready to trade
934
+ * `Provider.options` descriptors are NEVER returned here options are
935
+ * post-setup tunables and never gate trading. Option state is surfaced
936
+ * separately via `getAccount().settings`.
461
937
  */
462
- async getRequiredAuthorizations(
463
- params: GetRequiredAuthorizationsParams
464
- ): Promise<RequiredAuthorizationsResult> {
465
- const { dex, address } = params
466
- const mode = this.getSigningMode(address, dex)
467
- const provider = getDexAuthProvider(dex)
468
-
469
- // Ensure agent exists in USER_AGENT mode
938
+ async checkSetup(params: GetSetupParams): Promise<SetupResult> {
939
+ const { provider, address } = params
940
+ const mode = await this.loadSigningMode(address, provider)
941
+
942
+ const metadata = await this.getProviderMetadata(provider)
943
+ const usesAgent = [
944
+ ...metadata.setup,
945
+ ...metadata.options,
946
+ ...metadata.actions,
947
+ ].some((d) => d.signers.includes(PerpsSigner.AGENT))
948
+
470
949
  let agentAddress: Address | undefined
471
- if (mode === 'USER_AGENT') {
950
+ if (mode === SigningMode.USER_AGENT && usesAgent) {
472
951
  const agent = await this.sdkClient.agentManager.getOrCreateAgent(
473
952
  address,
474
- dex
953
+ provider
475
954
  )
476
955
  agentAddress = agent.address
477
956
  }
478
957
 
479
- // Provider declares auth inputs categorized as user/agent
480
- const authInputs = provider.getAuthorizationInputs({
481
- signingMode: mode,
482
- agentAddress,
483
- })
958
+ const allInputs = this.buildPrerequisiteInputs(
959
+ metadata.setup,
960
+ mode,
961
+ agentAddress
962
+ )
484
963
 
485
- const allInputs = [...authInputs.user, ...authInputs.agent]
486
964
  if (allInputs.length === 0) {
487
- return { userAuthorizations: [], agentAuthorizations: [], isReady: true }
965
+ return { userPrerequisites: [], agentPrerequisites: [], isReady: true }
488
966
  }
489
967
 
490
- // Send ALL to backend it filters already-satisfied ones and returns typed data
491
- const { actions } = await this.buildAuthorization({
492
- dex,
968
+ // Build a signer lookup from setup descriptors.
969
+ const signersByAction = new Map<string, PerpsSigner[]>()
970
+ for (const desc of metadata.setup) {
971
+ signersByAction.set(desc.type, desc.signers)
972
+ }
973
+
974
+ // Send all to backend via createAction for the first prerequisite type
975
+ // The backend filters already-satisfied ones and returns typed data
976
+ const { actions } = await this.buildPrerequisites({
977
+ provider,
493
978
  address,
494
- authorizations: allInputs,
979
+ signerAddress: agentAddress,
495
980
  })
496
981
 
497
982
  if (actions.length === 0) {
498
- return { userAuthorizations: [], agentAuthorizations: [], isReady: true }
983
+ return { userPrerequisites: [], agentPrerequisites: [], isReady: true }
499
984
  }
500
985
 
501
- // Categorize backend results using provider's original key sets
502
- const agentKeys = new Set(authInputs.agent.map((a) => a.key))
503
- const userAuthorizations = actions.filter((a) => !agentKeys.has(a.action))
504
- const agentAuthorizations = actions.filter((a) => agentKeys.has(a.action))
986
+ const userPrerequisites = actions.filter((a) => {
987
+ const signers = signersByAction.get(a.action) ?? []
988
+ return signers.includes(PerpsSigner.USER)
989
+ })
990
+ const agentPrerequisites = actions.filter((a) => {
991
+ const signers = signersByAction.get(a.action) ?? []
992
+ return signers.includes(PerpsSigner.AGENT)
993
+ })
505
994
 
506
995
  return {
507
- userAuthorizations,
508
- agentAuthorizations,
996
+ userPrerequisites,
997
+ agentPrerequisites,
509
998
  isReady: false,
510
999
  }
511
1000
  }
512
1001
 
1002
+ async buildPrerequisites(
1003
+ params: CheckPrerequisitesParams
1004
+ ): Promise<CreateActionResponse> {
1005
+ const mode = await this.loadSigningMode(params.address, params.provider)
1006
+ let { signerAddress } = params
1007
+
1008
+ if (mode === SigningMode.USER_AGENT && !signerAddress) {
1009
+ const agent = await this.sdkClient.agentManager.getAgent(
1010
+ params.address,
1011
+ params.provider
1012
+ )
1013
+ signerAddress = agent.address
1014
+ }
1015
+
1016
+ const metadata = await this.getProviderMetadata(params.provider)
1017
+ const allInputs = this.buildPrerequisiteInputs(
1018
+ metadata.setup,
1019
+ mode,
1020
+ signerAddress
1021
+ )
1022
+
1023
+ // Use the first prerequisite type as the action type for the batch
1024
+ // The backend handles all prerequisites in a single createPrerequisite call
1025
+ const allActions: ActionStep[] = []
1026
+ for (const input of allInputs) {
1027
+ const { actions } = await createAction(this.sdkClient, {
1028
+ provider: params.provider,
1029
+ address: params.address,
1030
+ signerAddress,
1031
+ action: input.key as ActionType,
1032
+ params: (input.params ?? {}) as Record<string, never>,
1033
+ })
1034
+ allActions.push(...actions)
1035
+ }
1036
+
1037
+ return { actions: allActions }
1038
+ }
1039
+
1040
+ /**
1041
+ * Default mode the SDK auto-applies after `APPROVE_AGENT` on a provider
1042
+ * whose `options` array exposes a writable `ACCOUNT_MODE` (today
1043
+ * Hyperliquid). Callers can override this through a subsequent
1044
+ * `ACCOUNT_MODE` dispatch.
1045
+ */
1046
+ private static readonly DEFAULT_ACCOUNT_MODE = 'unifiedAccount'
1047
+
513
1048
  /**
514
- * Execute authorizations: submit user-signed actions, then auto-sign and submit
515
- * any agent authorizations.
1049
+ * Prepare an `ACCOUNT_MODE` change by proactively reading the account's
1050
+ * current `config.abstractionMode` and routing to the correct signer:
516
1051
  *
517
- * @param params - User-signed actions and the required authorizations result
518
- * @returns Combined results from user and agent submissions
1052
+ * - `abstractionMode == null` (never set, e.g. a fresh HL account):
1053
+ * the change MAY be performed by the agent signer. Build, sign with
1054
+ * the agent key, and dispatch. Returns `{ results }`.
1055
+ * - `abstractionMode === mode`: idempotent no-op. Returns an empty
1056
+ * results envelope without contacting `/createAction` or `/executeAction`.
1057
+ * - `abstractionMode` set to any other value: HL requires a user-wallet
1058
+ * signature to change the abstraction once it has been set. Build the
1059
+ * action unsigned and return it as `{ fallback }` so the caller can
1060
+ * surface a wallet prompt via `fallbackUserPrerequisites`.
1061
+ *
1062
+ * Network errors from `/account` propagate — we never guess the signer.
1063
+ * `account.config.provider !== 'hyperliquid'` also throws: this helper
1064
+ * is HL-specific and the dispatcher should never reach it for another
1065
+ * provider (gated by `hasWritableAccountMode`).
519
1066
  */
520
- async executeAuthorizations(
521
- params: ExecuteAuthorizationsParams
522
- ): Promise<ExecuteAuthorizationsResult> {
523
- const { dex, address, required, userSignedActions } = params
524
- const mode = this.getSigningMode(address, dex)
525
-
526
- // 1. Submit user-signed actions (if any)
527
- let userResults: AuthorizationsResponse = { results: [] }
1067
+ private async prepareAccountModeChange(
1068
+ provider: string,
1069
+ address: Address,
1070
+ mode: string
1071
+ ): Promise<{
1072
+ results?: ExecuteActionResponse
1073
+ fallback?: ActionStep[]
1074
+ }> {
1075
+ const account = await getAccount(this.sdkClient, { provider, address })
1076
+ if (account.config.provider !== 'hyperliquid') {
1077
+ throw new PerpsError(
1078
+ PerpsErrorCode.SDKError,
1079
+ `prepareAccountModeChange is Hyperliquid-specific, but ` +
1080
+ `getAccount returned config for provider ` +
1081
+ `'${account.config.provider}'.`
1082
+ )
1083
+ }
1084
+ const currentStatus = account.config.abstractionMode
1085
+
1086
+ // Idempotent short-circuit: already in the requested mode.
1087
+ if (currentStatus === mode) {
1088
+ return {}
1089
+ }
1090
+
1091
+ // Never set → the agent is authorised to perform the change.
1092
+ if (currentStatus == null) {
1093
+ const agent = await this.sdkClient.agentManager.getAgent(
1094
+ address,
1095
+ provider
1096
+ )
1097
+
1098
+ const { actions } = await createAction(this.sdkClient, {
1099
+ provider,
1100
+ address,
1101
+ signerAddress: agent.address,
1102
+ action: ActionType.ACCOUNT_MODE,
1103
+ params: { mode } satisfies ActionParamsMap[ActionType.ACCOUNT_MODE],
1104
+ })
1105
+
1106
+ if (actions.length === 0) {
1107
+ // Backend's per-mode early-exit (defensive — shouldn't fire given
1108
+ // the short-circuit above, but covers a race between our /account
1109
+ // read and the backend's view of the current status).
1110
+ return { results: { results: [] } }
1111
+ }
1112
+
1113
+ const signedActions: SignedActionStep[] = await Promise.all(
1114
+ (actions as Eip712ActionStep[]).map(
1115
+ async (a): Promise<Eip712SignedActionStep> => ({
1116
+ action: a.action,
1117
+ typedData: a.typedData,
1118
+ signature: await signTypedData(agent.privateKey, a.typedData),
1119
+ })
1120
+ )
1121
+ )
1122
+
1123
+ const results = await executeAction(this.sdkClient, {
1124
+ provider,
1125
+ address,
1126
+ signerAddress: agent.address,
1127
+ action: ActionType.ACCOUNT_MODE,
1128
+ actions: signedActions,
1129
+ })
1130
+
1131
+ return { results }
1132
+ }
1133
+
1134
+ // Already set to a different mode → HL requires a user-wallet signature.
1135
+ // Build the action unsigned and surface it as a fallback to the caller.
1136
+ const { actions: fallbackActions } = await createAction(this.sdkClient, {
1137
+ provider,
1138
+ address,
1139
+ action: ActionType.ACCOUNT_MODE,
1140
+ params: { mode } satisfies ActionParamsMap[ActionType.ACCOUNT_MODE],
1141
+ })
1142
+
1143
+ return {
1144
+ fallback: fallbackActions.length > 0 ? fallbackActions : undefined,
1145
+ }
1146
+ }
1147
+
1148
+ /**
1149
+ * True when the provider exposes an `ACCOUNT_MODE` descriptor (in `setup`
1150
+ * or `options`) whose `mode` Param has a writable enumeration of values.
1151
+ * Providers that omit `ACCOUNT_MODE` or expose it as read-only / free-form
1152
+ * input return false.
1153
+ */
1154
+ private static hasWritableAccountMode(metadata: Provider): boolean {
1155
+ const item = [...metadata.setup, ...metadata.options].find(
1156
+ (i) => i.type === ActionType.ACCOUNT_MODE
1157
+ )
1158
+ if (!item) {
1159
+ return false
1160
+ }
1161
+ const modeParam = item.params.find((p) => p.name === 'mode')
1162
+ if (!modeParam) {
1163
+ return false
1164
+ }
1165
+ // Writable multi-option: `values` enumerates choices and `readOnly`
1166
+ // is not set (treat absence as writable, matching the descriptor
1167
+ // contract in `Param`).
1168
+ if (!modeParam.values || modeParam.values.length === 0) {
1169
+ return false
1170
+ }
1171
+ return !modeParam.readOnly
1172
+ }
1173
+
1174
+ /**
1175
+ * Submit the signed setup steps returned by `checkSetup` (and seeded
1176
+ * with user-wallet signatures by the caller). Internally splits into:
1177
+ *
1178
+ * 1. Submit user-signed setup actions.
1179
+ * 2. After a successful `APPROVE_AGENT`, auto-upgrade `ACCOUNT_MODE`
1180
+ * to the SDK's default when the provider exposes a writable
1181
+ * `ACCOUNT_MODE` Param (Hyperliquid today). The SDK reads
1182
+ * `account.config.abstractionMode` to choose the signer: `null` →
1183
+ * agent dispatch; non-null → wallet fallback returned in
1184
+ * `fallbackUserPrerequisites`.
1185
+ * 3. Sign and submit any pre-staged agent-side setup actions the
1186
+ * backend returned alongside the user-signed ones.
1187
+ */
1188
+ async satisfySetup(params: SatisfySetupParams): Promise<SatisfySetupResult> {
1189
+ const { provider, address, required, userSignedActions } = params
1190
+ const mode = await this.loadSigningMode(address, provider)
1191
+
1192
+ // 1. Submit user-signed prerequisites
1193
+ let userResults: ExecuteActionResponse = { results: [] }
528
1194
  if (userSignedActions.length > 0) {
529
1195
  const signerAddress =
530
- mode === 'USER_AGENT'
531
- ? (await this.sdkClient.agentManager.getAgent(address, dex)).address
1196
+ mode === SigningMode.USER_AGENT
1197
+ ? (await this.sdkClient.agentManager.getAgent(address, provider))
1198
+ .address
532
1199
  : address
533
- userResults = await submitAuthorization(this.sdkClient, {
534
- dex,
1200
+
1201
+ // Submit all user-signed actions — use first action's type for routing
1202
+ const firstAction = required.userPrerequisites[0]?.action as string
1203
+ userResults = await executeAction(this.sdkClient, {
1204
+ provider,
535
1205
  address,
536
1206
  signerAddress,
1207
+ action: (firstAction ?? ActionType.APPROVE_AGENT) as ActionType,
537
1208
  actions: userSignedActions,
538
1209
  })
539
1210
 
540
- // Check for failures - return early if any user auth failed
541
- const failed = userResults.results.find((r) => !r.success)
542
- if (failed) {
1211
+ const mandatoryFailure = userResults.results.find((r) => !r.success)
1212
+ if (mandatoryFailure) {
543
1213
  return { userResults }
544
1214
  }
545
1215
  }
546
1216
 
547
- // 2. Auto-sign and submit agent authorizations (if any)
548
- // Typed data already built by getRequiredAuthorizations — just sign and submit
549
- if (required.agentAuthorizations.length > 0 && mode === 'USER_AGENT') {
550
- const agent = await this.sdkClient.agentManager.getAgent(address, dex)
1217
+ // 2. Auto-upgrade ACCOUNT_MODE after APPROVE_AGENT.
1218
+ //
1219
+ // When the user-signed setup included a successful APPROVE_AGENT, the
1220
+ // freshly approved agent is now authorised to sign account-level
1221
+ // actions for accounts whose abstraction has never been set. If the
1222
+ // provider exposes a writable `ACCOUNT_MODE` descriptor (Hyperliquid
1223
+ // today), the SDK reads `account.config.abstractionMode` to decide
1224
+ // the signer: `null` → agent-dispatch silently to the SDK's preferred
1225
+ // default; non-null → return a wallet-signing fallback step. Either
1226
+ // way the chain does NOT abort onboarding — `ACCOUNT_MODE` lives on
1227
+ // `Provider.options`, not `Provider.setup`, and so does not gate
1228
+ // trading.
1229
+ let agentResults: ExecuteActionResponse | undefined
1230
+ let fallbackUserPrerequisites: ActionStep[] | undefined
1231
+ if (mode === SigningMode.USER_AGENT) {
1232
+ const justApprovedAgent = userResults.results.some(
1233
+ (r) => r.success && r.action === ActionType.APPROVE_AGENT
1234
+ )
1235
+ if (justApprovedAgent) {
1236
+ const metadata = await this.getProviderMetadata(provider)
1237
+ if (PerpsClient.hasWritableAccountMode(metadata)) {
1238
+ const upgrade = await this.prepareAccountModeChange(
1239
+ provider,
1240
+ address,
1241
+ PerpsClient.DEFAULT_ACCOUNT_MODE
1242
+ )
1243
+ agentResults = upgrade.results
1244
+ fallbackUserPrerequisites = upgrade.fallback
1245
+ }
1246
+ }
1247
+ }
1248
+
1249
+ // 3. Sign and submit any pre-staged agent prerequisites returned by the
1250
+ // backend's `buildPrerequisites` call. ACCOUNT_MODE is filtered out of
1251
+ // bulk staging (it requires explicit `mode` params), so this block
1252
+ // today only runs for future agent-signed steps the backend chooses
1253
+ // to stage.
1254
+ if (
1255
+ required.agentPrerequisites.length > 0 &&
1256
+ mode === SigningMode.USER_AGENT
1257
+ ) {
1258
+ const agent = await this.sdkClient.agentManager.getAgent(
1259
+ address,
1260
+ provider
1261
+ )
551
1262
 
552
- const signedAgentActions: SignedAuthorization[] = await Promise.all(
553
- required.agentAuthorizations.map(async (action) => ({
554
- action: action.action,
555
- typedData: action.typedData,
556
- signature: await signTypedData(agent.privateKey, action.typedData),
557
- }))
1263
+ const signedAgentActions: SignedActionStep[] = await Promise.all(
1264
+ (required.agentPrerequisites as Eip712ActionStep[]).map(
1265
+ async (action) =>
1266
+ ({
1267
+ action: action.action,
1268
+ typedData: action.typedData,
1269
+ signature: await signTypedData(
1270
+ agent.privateKey,
1271
+ action.typedData
1272
+ ),
1273
+ }) satisfies Eip712SignedActionStep
1274
+ )
558
1275
  )
559
1276
 
560
- const agentResults = await submitAuthorization(this.sdkClient, {
561
- dex,
1277
+ const firstAction = required.agentPrerequisites[0]?.action as string
1278
+ const stagedResults = await executeAction(this.sdkClient, {
1279
+ provider,
562
1280
  address,
563
1281
  signerAddress: agent.address,
1282
+ action: (firstAction ?? ActionType.ACCOUNT_MODE) as ActionType,
564
1283
  actions: signedAgentActions,
565
1284
  })
566
1285
 
567
- return { userResults, agentResults }
1286
+ // Merge staged-prereq results with any auto-upgrade results from step 2.
1287
+ agentResults = {
1288
+ results: [...(agentResults?.results ?? []), ...stagedResults.results],
1289
+ }
1290
+ }
1291
+
1292
+ return {
1293
+ userResults,
1294
+ ...(agentResults ? { agentResults } : {}),
1295
+ ...(fallbackUserPrerequisites ? { fallbackUserPrerequisites } : {}),
568
1296
  }
1297
+ }
1298
+
1299
+ // ---------------------------------------------------------------------------
1300
+ // Typed action helpers
1301
+ // ---------------------------------------------------------------------------
1302
+
1303
+ async placeOrder(params: PlaceOrderParams): Promise<ExecuteActionResponse> {
1304
+ return this.execute({ ...params, action: ActionType.PLACE_ORDER, params })
1305
+ }
1306
+
1307
+ async placeTriggerOrder(
1308
+ params: PlaceTriggerOrderParams
1309
+ ): Promise<ExecuteActionResponse> {
1310
+ return this.execute({
1311
+ ...params,
1312
+ action: ActionType.PLACE_TRIGGER_ORDER,
1313
+ params,
1314
+ })
1315
+ }
569
1316
 
570
- return { userResults }
1317
+ async cancelOrders(
1318
+ params: CancelOrdersParams
1319
+ ): Promise<ExecuteActionResponse> {
1320
+ return this.execute({ ...params, action: ActionType.CANCEL_ORDER, params })
1321
+ }
1322
+
1323
+ async modifyOrders(
1324
+ params: ModifyOrdersParams
1325
+ ): Promise<ExecuteActionResponse> {
1326
+ return this.execute({ ...params, action: ActionType.MODIFY_ORDER, params })
1327
+ }
1328
+
1329
+ async updatePositionMargin(params: {
1330
+ provider: string
1331
+ address: Address
1332
+ asset: AssetIdentity
1333
+ action: 'add' | 'remove'
1334
+ amount: string
1335
+ }): Promise<ExecuteActionResponse> {
1336
+ return this.execute({
1337
+ ...params,
1338
+ action: ActionType.UPDATE_POSITION_MARGIN,
1339
+ params,
1340
+ })
1341
+ }
1342
+
1343
+ async withdraw(params: WithdrawParams): Promise<ExecuteActionResponse> {
1344
+ return this.execute({
1345
+ provider: params.provider,
1346
+ address: params.address,
1347
+ action: ActionType.WITHDRAWAL,
1348
+ params: params.withdrawal,
1349
+ })
1350
+ }
1351
+
1352
+ /**
1353
+ * Execute any action through the SDK's signing pipeline. Signing is routed
1354
+ * by the action's descriptor in provider metadata — the agent keypair, the
1355
+ * configured WalletClient signer, the Lighter API key, or an EVM tx — as
1356
+ * the descriptor's `signers` and `signingMethod` dictate.
1357
+ */
1358
+ async execute<T extends ActionType>(params: {
1359
+ provider: string
1360
+ address: Address
1361
+ signerAddress?: Address
1362
+ action: T
1363
+ params: ActionParamsMap[T]
1364
+ }): Promise<ExecuteActionResponse> {
1365
+ await this.loadSigningMode(params.address, params.provider)
1366
+ const metadata = await this.getProviderMetadata(params.provider)
1367
+ const descriptor = findActionDescriptor(metadata, params.action)
1368
+
1369
+ let lastError: unknown
1370
+ for (let attempt = 0; attempt < MAX_NONCE_RETRIES; attempt++) {
1371
+ const { actions } = await this.buildAction(params.action, {
1372
+ provider: params.provider,
1373
+ address: params.address,
1374
+ params: params.params,
1375
+ })
1376
+ try {
1377
+ return await this.autoSignAndExecute(
1378
+ params.provider,
1379
+ params.address,
1380
+ params.action,
1381
+ actions,
1382
+ descriptor
1383
+ )
1384
+ } catch (err) {
1385
+ if (
1386
+ err instanceof PerpsError &&
1387
+ err.code === PerpsErrorCode.InvalidNonce
1388
+ ) {
1389
+ lastError = err
1390
+ continue
1391
+ }
1392
+ throw err
1393
+ }
1394
+ }
1395
+ throw lastError
571
1396
  }
572
1397
  }