@lifi/perps-sdk-provider-lighter 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 (405) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +176 -0
  3. package/dist/cjs/LighterProvider.d.ts +20 -0
  4. package/dist/cjs/LighterProvider.d.ts.map +1 -0
  5. package/dist/cjs/LighterProvider.js +592 -0
  6. package/dist/cjs/LighterProvider.js.map +1 -0
  7. package/dist/cjs/accountConfig.d.ts +3 -0
  8. package/dist/cjs/accountConfig.d.ts.map +1 -0
  9. package/dist/cjs/accountConfig.js +69 -0
  10. package/dist/cjs/accountConfig.js.map +1 -0
  11. package/dist/cjs/accountSummary.d.ts +3 -0
  12. package/dist/cjs/accountSummary.d.ts.map +1 -0
  13. package/dist/cjs/accountSummary.js +8 -0
  14. package/dist/cjs/accountSummary.js.map +1 -0
  15. package/dist/cjs/constants.d.ts +14 -0
  16. package/dist/cjs/constants.d.ts.map +1 -0
  17. package/dist/cjs/constants.js +18 -0
  18. package/dist/cjs/constants.js.map +1 -0
  19. package/dist/cjs/index.d.ts +11 -0
  20. package/dist/cjs/index.d.ts.map +1 -0
  21. package/dist/cjs/index.js +35 -0
  22. package/dist/cjs/index.js.map +1 -0
  23. package/dist/cjs/package.json +1 -0
  24. package/dist/cjs/signers/LighterKeyStore.d.ts +18 -0
  25. package/dist/cjs/signers/LighterKeyStore.d.ts.map +1 -0
  26. package/dist/cjs/signers/LighterKeyStore.js +54 -0
  27. package/dist/cjs/signers/LighterKeyStore.js.map +1 -0
  28. package/dist/cjs/signers/LighterReadOnlyTokenManager.d.ts +56 -0
  29. package/dist/cjs/signers/LighterReadOnlyTokenManager.d.ts.map +1 -0
  30. package/dist/cjs/signers/LighterReadOnlyTokenManager.js +127 -0
  31. package/dist/cjs/signers/LighterReadOnlyTokenManager.js.map +1 -0
  32. package/dist/cjs/signers/LighterSigner.d.ts +41 -0
  33. package/dist/cjs/signers/LighterSigner.d.ts.map +1 -0
  34. package/dist/cjs/signers/LighterSigner.js +175 -0
  35. package/dist/cjs/signers/LighterSigner.js.map +1 -0
  36. package/dist/cjs/signers/createAuthToken.d.ts +12 -0
  37. package/dist/cjs/signers/createAuthToken.d.ts.map +1 -0
  38. package/dist/cjs/signers/createAuthToken.js +28 -0
  39. package/dist/cjs/signers/createAuthToken.js.map +1 -0
  40. package/dist/cjs/signers/index.d.ts +11 -0
  41. package/dist/cjs/signers/index.d.ts.map +1 -0
  42. package/dist/cjs/signers/index.js +19 -0
  43. package/dist/cjs/signers/index.js.map +1 -0
  44. package/dist/cjs/signers/signActions.d.ts +15 -0
  45. package/dist/cjs/signers/signActions.d.ts.map +1 -0
  46. package/dist/cjs/signers/signActions.js +142 -0
  47. package/dist/cjs/signers/signActions.js.map +1 -0
  48. package/dist/cjs/signers/wasmLoader.d.ts +42 -0
  49. package/dist/cjs/signers/wasmLoader.d.ts.map +1 -0
  50. package/dist/cjs/signers/wasmLoader.js +166 -0
  51. package/dist/cjs/signers/wasmLoader.js.map +1 -0
  52. package/dist/cjs/types/account.d.ts +97 -0
  53. package/dist/cjs/types/account.d.ts.map +1 -0
  54. package/dist/cjs/types/account.js +3 -0
  55. package/dist/cjs/types/account.js.map +1 -0
  56. package/dist/cjs/types/action.d.ts +72 -0
  57. package/dist/cjs/types/action.d.ts.map +1 -0
  58. package/dist/cjs/types/action.js +23 -0
  59. package/dist/cjs/types/action.js.map +1 -0
  60. package/dist/cjs/types/activity.d.ts +73 -0
  61. package/dist/cjs/types/activity.d.ts.map +1 -0
  62. package/dist/cjs/types/activity.js +3 -0
  63. package/dist/cjs/types/activity.js.map +1 -0
  64. package/dist/cjs/types/asset.d.ts +122 -0
  65. package/dist/cjs/types/asset.d.ts.map +1 -0
  66. package/dist/cjs/types/asset.js +3 -0
  67. package/dist/cjs/types/asset.js.map +1 -0
  68. package/dist/cjs/types/fill.d.ts +29 -0
  69. package/dist/cjs/types/fill.d.ts.map +1 -0
  70. package/dist/cjs/types/fill.js +3 -0
  71. package/dist/cjs/types/fill.js.map +1 -0
  72. package/dist/cjs/types/index.d.ts +9 -0
  73. package/dist/cjs/types/index.d.ts.map +1 -0
  74. package/dist/cjs/types/index.js +25 -0
  75. package/dist/cjs/types/index.js.map +1 -0
  76. package/dist/cjs/types/order.d.ts +57 -0
  77. package/dist/cjs/types/order.d.ts.map +1 -0
  78. package/dist/cjs/types/order.js +3 -0
  79. package/dist/cjs/types/order.js.map +1 -0
  80. package/dist/cjs/types/submit.d.ts +39 -0
  81. package/dist/cjs/types/submit.d.ts.map +1 -0
  82. package/dist/cjs/types/submit.js +3 -0
  83. package/dist/cjs/types/submit.js.map +1 -0
  84. package/dist/cjs/types/ws.d.ts +84 -0
  85. package/dist/cjs/types/ws.d.ts.map +1 -0
  86. package/dist/cjs/types/ws.js +3 -0
  87. package/dist/cjs/types/ws.js.map +1 -0
  88. package/dist/cjs/utils/activityCursor.d.ts +12 -0
  89. package/dist/cjs/utils/activityCursor.d.ts.map +1 -0
  90. package/dist/cjs/utils/activityCursor.js +85 -0
  91. package/dist/cjs/utils/activityCursor.js.map +1 -0
  92. package/dist/cjs/utils/apiClient.d.ts +26 -0
  93. package/dist/cjs/utils/apiClient.d.ts.map +1 -0
  94. package/dist/cjs/utils/apiClient.js +94 -0
  95. package/dist/cjs/utils/apiClient.js.map +1 -0
  96. package/dist/cjs/utils/fetchDetailedAccount.d.ts +5 -0
  97. package/dist/cjs/utils/fetchDetailedAccount.d.ts.map +1 -0
  98. package/dist/cjs/utils/fetchDetailedAccount.js +22 -0
  99. package/dist/cjs/utils/fetchDetailedAccount.js.map +1 -0
  100. package/dist/cjs/utils/index.d.ts +16 -0
  101. package/dist/cjs/utils/index.d.ts.map +1 -0
  102. package/dist/cjs/utils/index.js +45 -0
  103. package/dist/cjs/utils/index.js.map +1 -0
  104. package/dist/cjs/utils/lighterAsset.d.ts +3 -0
  105. package/dist/cjs/utils/lighterAsset.d.ts.map +1 -0
  106. package/dist/cjs/utils/lighterAsset.js +12 -0
  107. package/dist/cjs/utils/lighterAsset.js.map +1 -0
  108. package/dist/cjs/utils/liquidation.d.ts +4 -0
  109. package/dist/cjs/utils/liquidation.d.ts.map +1 -0
  110. package/dist/cjs/utils/liquidation.js +16 -0
  111. package/dist/cjs/utils/liquidation.js.map +1 -0
  112. package/dist/cjs/utils/mapFill.d.ts +4 -0
  113. package/dist/cjs/utils/mapFill.d.ts.map +1 -0
  114. package/dist/cjs/utils/mapFill.js +61 -0
  115. package/dist/cjs/utils/mapFill.js.map +1 -0
  116. package/dist/cjs/utils/mapOpenPositions.d.ts +4 -0
  117. package/dist/cjs/utils/mapOpenPositions.d.ts.map +1 -0
  118. package/dist/cjs/utils/mapOpenPositions.js +9 -0
  119. package/dist/cjs/utils/mapOpenPositions.js.map +1 -0
  120. package/dist/cjs/utils/mapOrder.d.ts +15 -0
  121. package/dist/cjs/utils/mapOrder.d.ts.map +1 -0
  122. package/dist/cjs/utils/mapOrder.js +164 -0
  123. package/dist/cjs/utils/mapOrder.js.map +1 -0
  124. package/dist/cjs/utils/mapPosition.d.ts +4 -0
  125. package/dist/cjs/utils/mapPosition.d.ts.map +1 -0
  126. package/dist/cjs/utils/mapPosition.js +30 -0
  127. package/dist/cjs/utils/mapPosition.js.map +1 -0
  128. package/dist/cjs/utils/ohlcvInterval.d.ts +2 -0
  129. package/dist/cjs/utils/ohlcvInterval.d.ts.map +1 -0
  130. package/dist/cjs/utils/ohlcvInterval.js +26 -0
  131. package/dist/cjs/utils/ohlcvInterval.js.map +1 -0
  132. package/dist/cjs/utils/orderFormatting.d.ts +4 -0
  133. package/dist/cjs/utils/orderFormatting.d.ts.map +1 -0
  134. package/dist/cjs/utils/orderFormatting.js +23 -0
  135. package/dist/cjs/utils/orderFormatting.js.map +1 -0
  136. package/dist/cjs/utils/time.d.ts +3 -0
  137. package/dist/cjs/utils/time.d.ts.map +1 -0
  138. package/dist/cjs/utils/time.js +8 -0
  139. package/dist/cjs/utils/time.js.map +1 -0
  140. package/dist/cjs/utils/wireEncoding.d.ts +9 -0
  141. package/dist/cjs/utils/wireEncoding.d.ts.map +1 -0
  142. package/dist/cjs/utils/wireEncoding.js +87 -0
  143. package/dist/cjs/utils/wireEncoding.js.map +1 -0
  144. package/dist/cjs/websocket/LighterWsProvider.d.ts +45 -0
  145. package/dist/cjs/websocket/LighterWsProvider.d.ts.map +1 -0
  146. package/dist/cjs/websocket/LighterWsProvider.js +396 -0
  147. package/dist/cjs/websocket/LighterWsProvider.js.map +1 -0
  148. package/dist/esm/LighterProvider.d.ts +105 -0
  149. package/dist/esm/LighterProvider.d.ts.map +1 -0
  150. package/dist/esm/LighterProvider.js +684 -0
  151. package/dist/esm/LighterProvider.js.map +1 -0
  152. package/dist/esm/accountConfig.d.ts +14 -0
  153. package/dist/esm/accountConfig.d.ts.map +1 -0
  154. package/dist/esm/accountConfig.js +135 -0
  155. package/dist/esm/accountConfig.js.map +1 -0
  156. package/dist/esm/accountSummary.d.ts +12 -0
  157. package/dist/esm/accountSummary.d.ts.map +1 -0
  158. package/dist/esm/accountSummary.js +14 -0
  159. package/dist/esm/accountSummary.js.map +1 -0
  160. package/dist/esm/constants.d.ts +74 -0
  161. package/dist/esm/constants.d.ts.map +1 -0
  162. package/dist/esm/constants.js +73 -0
  163. package/dist/esm/constants.js.map +1 -0
  164. package/dist/esm/index.d.ts +22 -0
  165. package/dist/esm/index.d.ts.map +1 -0
  166. package/dist/esm/index.js +22 -0
  167. package/dist/esm/index.js.map +1 -0
  168. package/dist/esm/package.json +1 -0
  169. package/dist/esm/signers/LighterKeyStore.d.ts +24 -0
  170. package/dist/esm/signers/LighterKeyStore.d.ts.map +1 -0
  171. package/dist/esm/signers/LighterKeyStore.js +55 -0
  172. package/dist/esm/signers/LighterKeyStore.js.map +1 -0
  173. package/dist/esm/signers/LighterReadOnlyTokenManager.d.ts +157 -0
  174. package/dist/esm/signers/LighterReadOnlyTokenManager.d.ts.map +1 -0
  175. package/dist/esm/signers/LighterReadOnlyTokenManager.js +194 -0
  176. package/dist/esm/signers/LighterReadOnlyTokenManager.js.map +1 -0
  177. package/dist/esm/signers/LighterSigner.d.ts +94 -0
  178. package/dist/esm/signers/LighterSigner.d.ts.map +1 -0
  179. package/dist/esm/signers/LighterSigner.js +228 -0
  180. package/dist/esm/signers/LighterSigner.js.map +1 -0
  181. package/dist/esm/signers/createAuthToken.d.ts +36 -0
  182. package/dist/esm/signers/createAuthToken.d.ts.map +1 -0
  183. package/dist/esm/signers/createAuthToken.js +42 -0
  184. package/dist/esm/signers/createAuthToken.js.map +1 -0
  185. package/dist/esm/signers/index.d.ts +11 -0
  186. package/dist/esm/signers/index.d.ts.map +1 -0
  187. package/dist/esm/signers/index.js +7 -0
  188. package/dist/esm/signers/index.js.map +1 -0
  189. package/dist/esm/signers/signActions.d.ts +54 -0
  190. package/dist/esm/signers/signActions.d.ts.map +1 -0
  191. package/dist/esm/signers/signActions.js +193 -0
  192. package/dist/esm/signers/signActions.js.map +1 -0
  193. package/dist/esm/signers/wasmLoader.d.ts +79 -0
  194. package/dist/esm/signers/wasmLoader.d.ts.map +1 -0
  195. package/dist/esm/signers/wasmLoader.js +180 -0
  196. package/dist/esm/signers/wasmLoader.js.map +1 -0
  197. package/dist/esm/types/account.d.ts +113 -0
  198. package/dist/esm/types/account.d.ts.map +1 -0
  199. package/dist/esm/types/account.js +4 -0
  200. package/dist/esm/types/account.js.map +1 -0
  201. package/dist/esm/types/action.d.ts +146 -0
  202. package/dist/esm/types/action.d.ts.map +1 -0
  203. package/dist/esm/types/action.js +50 -0
  204. package/dist/esm/types/action.js.map +1 -0
  205. package/dist/esm/types/activity.d.ts +83 -0
  206. package/dist/esm/types/activity.d.ts.map +1 -0
  207. package/dist/esm/types/activity.js +4 -0
  208. package/dist/esm/types/activity.js.map +1 -0
  209. package/dist/esm/types/asset.d.ts +134 -0
  210. package/dist/esm/types/asset.d.ts.map +1 -0
  211. package/dist/esm/types/asset.js +3 -0
  212. package/dist/esm/types/asset.js.map +1 -0
  213. package/dist/esm/types/fill.d.ts +31 -0
  214. package/dist/esm/types/fill.d.ts.map +1 -0
  215. package/dist/esm/types/fill.js +3 -0
  216. package/dist/esm/types/fill.js.map +1 -0
  217. package/dist/esm/types/index.d.ts +9 -0
  218. package/dist/esm/types/index.d.ts.map +1 -0
  219. package/dist/esm/types/index.js +12 -0
  220. package/dist/esm/types/index.js.map +1 -0
  221. package/dist/esm/types/order.d.ts +61 -0
  222. package/dist/esm/types/order.d.ts.map +1 -0
  223. package/dist/esm/types/order.js +3 -0
  224. package/dist/esm/types/order.js.map +1 -0
  225. package/dist/esm/types/submit.d.ts +76 -0
  226. package/dist/esm/types/submit.d.ts.map +1 -0
  227. package/dist/esm/types/submit.js +3 -0
  228. package/dist/esm/types/submit.js.map +1 -0
  229. package/dist/esm/types/ws.d.ts +124 -0
  230. package/dist/esm/types/ws.d.ts.map +1 -0
  231. package/dist/esm/types/ws.js +11 -0
  232. package/dist/esm/types/ws.js.map +1 -0
  233. package/dist/esm/utils/activityCursor.d.ts +51 -0
  234. package/dist/esm/utils/activityCursor.d.ts.map +1 -0
  235. package/dist/esm/utils/activityCursor.js +99 -0
  236. package/dist/esm/utils/activityCursor.js.map +1 -0
  237. package/dist/esm/utils/apiClient.d.ts +65 -0
  238. package/dist/esm/utils/apiClient.d.ts.map +1 -0
  239. package/dist/esm/utils/apiClient.js +131 -0
  240. package/dist/esm/utils/apiClient.js.map +1 -0
  241. package/dist/esm/utils/fetchDetailedAccount.d.ts +11 -0
  242. package/dist/esm/utils/fetchDetailedAccount.d.ts.map +1 -0
  243. package/dist/esm/utils/fetchDetailedAccount.js +24 -0
  244. package/dist/esm/utils/fetchDetailedAccount.js.map +1 -0
  245. package/dist/esm/utils/index.d.ts +16 -0
  246. package/dist/esm/utils/index.d.ts.map +1 -0
  247. package/dist/esm/utils/index.js +17 -0
  248. package/dist/esm/utils/index.js.map +1 -0
  249. package/dist/esm/utils/lighterAsset.d.ts +4 -0
  250. package/dist/esm/utils/lighterAsset.d.ts.map +1 -0
  251. package/dist/esm/utils/lighterAsset.js +9 -0
  252. package/dist/esm/utils/lighterAsset.js.map +1 -0
  253. package/dist/esm/utils/liquidation.d.ts +22 -0
  254. package/dist/esm/utils/liquidation.d.ts.map +1 -0
  255. package/dist/esm/utils/liquidation.js +31 -0
  256. package/dist/esm/utils/liquidation.js.map +1 -0
  257. package/dist/esm/utils/mapFill.d.ts +10 -0
  258. package/dist/esm/utils/mapFill.d.ts.map +1 -0
  259. package/dist/esm/utils/mapFill.js +72 -0
  260. package/dist/esm/utils/mapFill.js.map +1 -0
  261. package/dist/esm/utils/mapOpenPositions.d.ts +11 -0
  262. package/dist/esm/utils/mapOpenPositions.d.ts.map +1 -0
  263. package/dist/esm/utils/mapOpenPositions.js +12 -0
  264. package/dist/esm/utils/mapOpenPositions.js.map +1 -0
  265. package/dist/esm/utils/mapOrder.d.ts +72 -0
  266. package/dist/esm/utils/mapOrder.d.ts.map +1 -0
  267. package/dist/esm/utils/mapOrder.js +219 -0
  268. package/dist/esm/utils/mapOrder.js.map +1 -0
  269. package/dist/esm/utils/mapPosition.d.ts +9 -0
  270. package/dist/esm/utils/mapPosition.d.ts.map +1 -0
  271. package/dist/esm/utils/mapPosition.js +34 -0
  272. package/dist/esm/utils/mapPosition.js.map +1 -0
  273. package/dist/esm/utils/ohlcvInterval.d.ts +3 -0
  274. package/dist/esm/utils/ohlcvInterval.d.ts.map +1 -0
  275. package/dist/esm/utils/ohlcvInterval.js +30 -0
  276. package/dist/esm/utils/ohlcvInterval.js.map +1 -0
  277. package/dist/esm/utils/orderFormatting.d.ts +29 -0
  278. package/dist/esm/utils/orderFormatting.d.ts.map +1 -0
  279. package/dist/esm/utils/orderFormatting.js +41 -0
  280. package/dist/esm/utils/orderFormatting.js.map +1 -0
  281. package/dist/esm/utils/time.d.ts +5 -0
  282. package/dist/esm/utils/time.d.ts.map +1 -0
  283. package/dist/esm/utils/time.js +5 -0
  284. package/dist/esm/utils/time.js.map +1 -0
  285. package/dist/esm/utils/wireEncoding.d.ts +72 -0
  286. package/dist/esm/utils/wireEncoding.d.ts.map +1 -0
  287. package/dist/esm/utils/wireEncoding.js +129 -0
  288. package/dist/esm/utils/wireEncoding.js.map +1 -0
  289. package/dist/esm/websocket/LighterWsProvider.d.ts +97 -0
  290. package/dist/esm/websocket/LighterWsProvider.d.ts.map +1 -0
  291. package/dist/esm/websocket/LighterWsProvider.js +489 -0
  292. package/dist/esm/websocket/LighterWsProvider.js.map +1 -0
  293. package/dist/types/LighterProvider.d.ts +105 -0
  294. package/dist/types/LighterProvider.d.ts.map +1 -0
  295. package/dist/types/accountConfig.d.ts +14 -0
  296. package/dist/types/accountConfig.d.ts.map +1 -0
  297. package/dist/types/accountSummary.d.ts +12 -0
  298. package/dist/types/accountSummary.d.ts.map +1 -0
  299. package/dist/types/constants.d.ts +74 -0
  300. package/dist/types/constants.d.ts.map +1 -0
  301. package/dist/types/index.d.ts +22 -0
  302. package/dist/types/index.d.ts.map +1 -0
  303. package/dist/types/signers/LighterKeyStore.d.ts +24 -0
  304. package/dist/types/signers/LighterKeyStore.d.ts.map +1 -0
  305. package/dist/types/signers/LighterReadOnlyTokenManager.d.ts +157 -0
  306. package/dist/types/signers/LighterReadOnlyTokenManager.d.ts.map +1 -0
  307. package/dist/types/signers/LighterSigner.d.ts +94 -0
  308. package/dist/types/signers/LighterSigner.d.ts.map +1 -0
  309. package/dist/types/signers/createAuthToken.d.ts +36 -0
  310. package/dist/types/signers/createAuthToken.d.ts.map +1 -0
  311. package/dist/types/signers/index.d.ts +11 -0
  312. package/dist/types/signers/index.d.ts.map +1 -0
  313. package/dist/types/signers/signActions.d.ts +54 -0
  314. package/dist/types/signers/signActions.d.ts.map +1 -0
  315. package/dist/types/signers/wasmLoader.d.ts +79 -0
  316. package/dist/types/signers/wasmLoader.d.ts.map +1 -0
  317. package/dist/types/types/account.d.ts +113 -0
  318. package/dist/types/types/account.d.ts.map +1 -0
  319. package/dist/types/types/action.d.ts +146 -0
  320. package/dist/types/types/action.d.ts.map +1 -0
  321. package/dist/types/types/activity.d.ts +83 -0
  322. package/dist/types/types/activity.d.ts.map +1 -0
  323. package/dist/types/types/asset.d.ts +134 -0
  324. package/dist/types/types/asset.d.ts.map +1 -0
  325. package/dist/types/types/fill.d.ts +31 -0
  326. package/dist/types/types/fill.d.ts.map +1 -0
  327. package/dist/types/types/index.d.ts +9 -0
  328. package/dist/types/types/index.d.ts.map +1 -0
  329. package/dist/types/types/order.d.ts +61 -0
  330. package/dist/types/types/order.d.ts.map +1 -0
  331. package/dist/types/types/submit.d.ts +76 -0
  332. package/dist/types/types/submit.d.ts.map +1 -0
  333. package/dist/types/types/ws.d.ts +124 -0
  334. package/dist/types/types/ws.d.ts.map +1 -0
  335. package/dist/types/utils/activityCursor.d.ts +51 -0
  336. package/dist/types/utils/activityCursor.d.ts.map +1 -0
  337. package/dist/types/utils/apiClient.d.ts +65 -0
  338. package/dist/types/utils/apiClient.d.ts.map +1 -0
  339. package/dist/types/utils/fetchDetailedAccount.d.ts +11 -0
  340. package/dist/types/utils/fetchDetailedAccount.d.ts.map +1 -0
  341. package/dist/types/utils/index.d.ts +16 -0
  342. package/dist/types/utils/index.d.ts.map +1 -0
  343. package/dist/types/utils/lighterAsset.d.ts +4 -0
  344. package/dist/types/utils/lighterAsset.d.ts.map +1 -0
  345. package/dist/types/utils/liquidation.d.ts +22 -0
  346. package/dist/types/utils/liquidation.d.ts.map +1 -0
  347. package/dist/types/utils/mapFill.d.ts +10 -0
  348. package/dist/types/utils/mapFill.d.ts.map +1 -0
  349. package/dist/types/utils/mapOpenPositions.d.ts +11 -0
  350. package/dist/types/utils/mapOpenPositions.d.ts.map +1 -0
  351. package/dist/types/utils/mapOrder.d.ts +72 -0
  352. package/dist/types/utils/mapOrder.d.ts.map +1 -0
  353. package/dist/types/utils/mapPosition.d.ts +9 -0
  354. package/dist/types/utils/mapPosition.d.ts.map +1 -0
  355. package/dist/types/utils/ohlcvInterval.d.ts +3 -0
  356. package/dist/types/utils/ohlcvInterval.d.ts.map +1 -0
  357. package/dist/types/utils/orderFormatting.d.ts +29 -0
  358. package/dist/types/utils/orderFormatting.d.ts.map +1 -0
  359. package/dist/types/utils/time.d.ts +5 -0
  360. package/dist/types/utils/time.d.ts.map +1 -0
  361. package/dist/types/utils/wireEncoding.d.ts +72 -0
  362. package/dist/types/utils/wireEncoding.d.ts.map +1 -0
  363. package/dist/types/websocket/LighterWsProvider.d.ts +97 -0
  364. package/dist/types/websocket/LighterWsProvider.d.ts.map +1 -0
  365. package/dist/wasm/lighter-signer.wasm +0 -0
  366. package/dist/wasm/wasm_exec.js +575 -0
  367. package/package.json +67 -0
  368. package/src/LighterProvider.ts +1167 -0
  369. package/src/accountConfig.ts +162 -0
  370. package/src/accountSummary.ts +22 -0
  371. package/src/constants.ts +89 -0
  372. package/src/index.ts +37 -0
  373. package/src/signers/LighterKeyStore.ts +79 -0
  374. package/src/signers/LighterReadOnlyTokenManager.ts +340 -0
  375. package/src/signers/LighterSigner.ts +400 -0
  376. package/src/signers/createAuthToken.ts +69 -0
  377. package/src/signers/index.ts +36 -0
  378. package/src/signers/signActions.ts +311 -0
  379. package/src/signers/wasmLoader.ts +293 -0
  380. package/src/types/account.ts +123 -0
  381. package/src/types/action.ts +163 -0
  382. package/src/types/activity.ts +94 -0
  383. package/src/types/asset.ts +146 -0
  384. package/src/types/fill.ts +42 -0
  385. package/src/types/index.ts +12 -0
  386. package/src/types/order.ts +65 -0
  387. package/src/types/submit.ts +83 -0
  388. package/src/types/ws.ts +136 -0
  389. package/src/utils/activityCursor.ts +150 -0
  390. package/src/utils/apiClient.ts +185 -0
  391. package/src/utils/fetchDetailedAccount.ts +46 -0
  392. package/src/utils/index.ts +38 -0
  393. package/src/utils/lighterAsset.ts +10 -0
  394. package/src/utils/liquidation.ts +39 -0
  395. package/src/utils/mapFill.ts +108 -0
  396. package/src/utils/mapOpenPositions.ts +18 -0
  397. package/src/utils/mapOrder.ts +258 -0
  398. package/src/utils/mapPosition.ts +42 -0
  399. package/src/utils/ohlcvInterval.ts +34 -0
  400. package/src/utils/orderFormatting.ts +46 -0
  401. package/src/utils/time.ts +6 -0
  402. package/src/utils/wireEncoding.ts +179 -0
  403. package/src/websocket/LighterWsProvider.ts +725 -0
  404. package/wasm/lighter-signer.wasm +0 -0
  405. package/wasm/wasm_exec.js +575 -0
@@ -0,0 +1,311 @@
1
+ import { PerpsError, type SignActionsContext } from '@lifi/perps-sdk'
2
+ import type {
3
+ ActionStep,
4
+ EvmTxActionStep,
5
+ EvmTxSignedActionStep,
6
+ SignedActionStep,
7
+ WasmBlobActionStep,
8
+ WasmBlobSignedActionStep,
9
+ } from '@lifi/perps-types'
10
+ import { ActionType, PerpsErrorCode, SigningMethod } from '@lifi/perps-types'
11
+ import type { Address } from 'viem'
12
+ import { parseAbi } from 'viem'
13
+ import { DEFAULT_API_KEY_INDEX } from '../constants.js'
14
+ import type { LighterApiKey, LighterKeyStore } from './LighterKeyStore.js'
15
+ import type { LighterSigner } from './LighterSigner.js'
16
+
17
+ /**
18
+ * Per-batch dependencies the Lighter `signActions` implementation needs:
19
+ * a WASM signer (`LighterSigner`), the API-key store keyed on L1 address,
20
+ * and a reference to the host SDK client for descriptor/account fetches
21
+ * within the REGISTER_API_KEY hybrid flow.
22
+ * @internal
23
+ */
24
+ export interface LighterSignActionsDeps {
25
+ signer: LighterSigner
26
+ keyStore: LighterKeyStore
27
+ /**
28
+ * Resolve the user's Lighter `accountIndex` for an L1 address. Required
29
+ * by REGISTER_API_KEY so the ChangePubKey blob carries the right
30
+ * account. Implementations typically call Lighter's `/api/v1/account`
31
+ * with `by=l1_address`.
32
+ */
33
+ resolveAccountIndex(address: Address): Promise<number>
34
+ }
35
+
36
+ /**
37
+ * Sign a `WASM_BLOB` batch (Lighter). Ensures the user's API keypair is
38
+ * registered first — generating one and running the REGISTER_API_KEY
39
+ * hybrid flow via the L1 signer if not — then feeds each subsequent step
40
+ * through the WASM signer.
41
+ *
42
+ * `ACCOUNT_TYPE` (Lighter `/changeAccountTier`) is a WASM_BLOB envelope
43
+ * authenticated with an auth token rather than a wasm tx signature —
44
+ * created via `LighterSigner.createAuthToken` and parked in `signedTx.txInfo`.
45
+ * @internal
46
+ */
47
+ export async function signWasmBlobActions(
48
+ deps: LighterSignActionsDeps,
49
+ address: Address,
50
+ steps: WasmBlobActionStep[],
51
+ ctx: SignActionsContext | undefined
52
+ ): Promise<WasmBlobSignedActionStep[]> {
53
+ const signed: WasmBlobSignedActionStep[] = []
54
+ for (const step of steps) {
55
+ if (step.action === ActionType.REGISTER_API_KEY) {
56
+ signed.push(await signRegisterApiKey(deps, address, step, ctx))
57
+ } else if (step.action === ActionType.ACCOUNT_TYPE) {
58
+ signed.push(await signAccountTierChange(deps, address, step))
59
+ } else {
60
+ signed.push(await signStandardWasmAction(deps, address, step))
61
+ }
62
+ }
63
+ return signed
64
+ }
65
+
66
+ async function signStandardWasmAction(
67
+ deps: LighterSignActionsDeps,
68
+ address: Address,
69
+ step: WasmBlobActionStep
70
+ ): Promise<WasmBlobSignedActionStep> {
71
+ const apiKey = await requireApiKey(deps, address)
72
+ const signedTx = await deps.signer.sign(step.action, step.wasmSignParams, {
73
+ apiKeyPrivateKey: apiKey.apiKeyPrivateKey,
74
+ apiKeyIndex: apiKey.apiKeyIndex,
75
+ accountIndex: apiKey.accountIndex,
76
+ })
77
+ return {
78
+ action: step.action,
79
+ wasmSignParams: step.wasmSignParams,
80
+ signedTx,
81
+ }
82
+ }
83
+
84
+ /**
85
+ * REGISTER_API_KEY flow:
86
+ * 1. Look up the user's Lighter accountIndex (Lighter REST).
87
+ * 2. Generate a fresh Lighter API keypair via the WASM signer.
88
+ * 3. Call SignChangePubKey to produce the WASM blob + EIP-191 message.
89
+ * 4. Have the user's L1 Ethereum wallet sign the message.
90
+ * 5. Inject the L1 signature into the ChangePubKey txInfo JSON.
91
+ * 6. Persist the keypair and return the signed blob.
92
+ *
93
+ * Requires the end-user's wallet in `ctx.userWallet` — the L1 signature is the
94
+ * user's consent to rotate keys.
95
+ */
96
+ async function signRegisterApiKey(
97
+ deps: LighterSignActionsDeps,
98
+ address: Address,
99
+ step: WasmBlobActionStep,
100
+ ctx: SignActionsContext | undefined
101
+ ): Promise<WasmBlobSignedActionStep> {
102
+ const walletSigner = ctx?.userWallet
103
+ if (!walletSigner) {
104
+ throw new PerpsError(
105
+ PerpsErrorCode.SDKError,
106
+ 'REGISTER_API_KEY requires the end-user wallet — pass `userWallet` to ' +
107
+ 'createPerpsClient or call setUserWallet(walletClient).'
108
+ )
109
+ }
110
+
111
+ const params = step.wasmSignParams as {
112
+ api_key_index?: number
113
+ nonce?: number
114
+ skip_nonce?: 0 | 1
115
+ }
116
+ const apiKeyIndex = params.api_key_index ?? DEFAULT_API_KEY_INDEX
117
+ const nonce = params.nonce
118
+ if (typeof nonce !== 'number') {
119
+ throw new PerpsError(
120
+ PerpsErrorCode.SDKError,
121
+ 'REGISTER_API_KEY wasmSignParams is missing `nonce`.'
122
+ )
123
+ }
124
+ const skipNonce = params.skip_nonce === 1 ? 1 : 0
125
+
126
+ const accountIndex = await deps.resolveAccountIndex(address)
127
+
128
+ const keypair = await deps.signer.generateAPIKey()
129
+ const changePubKey = await deps.signer.signChangePubKey(
130
+ keypair.publicKey,
131
+ keypair.privateKey,
132
+ nonce,
133
+ apiKeyIndex,
134
+ accountIndex,
135
+ skipNonce
136
+ )
137
+
138
+ const l1Signature = await walletSigner.signMessage({
139
+ account: walletSigner.account,
140
+ message: changePubKey.messageToSign,
141
+ })
142
+
143
+ const txInfoWithL1Sig = deps.signer.embedL1Signature(
144
+ changePubKey.txInfo,
145
+ l1Signature
146
+ )
147
+
148
+ const apiKey: LighterApiKey = {
149
+ accountIndex,
150
+ apiKeyIndex,
151
+ apiKeyPrivateKey: keypair.privateKey,
152
+ apiKeyPublicKey: keypair.publicKey,
153
+ }
154
+ await deps.keyStore.set(address, apiKey)
155
+
156
+ return {
157
+ action: step.action,
158
+ wasmSignParams: {
159
+ ...step.wasmSignParams,
160
+ new_public_key: keypair.publicKey,
161
+ },
162
+ signedTx: {
163
+ txType: changePubKey.txType,
164
+ txInfo: txInfoWithL1Sig,
165
+ txHash: changePubKey.txHash,
166
+ },
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Sign an `ACCOUNT_TYPE` step (Lighter `changeAccountTier`).
172
+ *
173
+ * Lighter's `/api/v1/changeAccountTier` is an HTTP-only mutation —
174
+ * Lighter does NOT consume a wasm-signed transaction here; it
175
+ * authenticates the request with the same auth token its read endpoints
176
+ * use, and enforces anti-replay business rules server-side. The backend
177
+ * declares the step as a `WasmBlobActionStep` with
178
+ * `wasmSignParams.kind = 'changeAccountTier'` and expects the SDK to create
179
+ * an auth token in lieu of a transaction signature; the executor reads
180
+ * `signedTx.txInfo` as the `auth` form parameter.
181
+ *
182
+ * The 1h deadline mirrors the previous behaviour — Lighter caps tokens at
183
+ * 8h hard, and the backend's executor runs `verifyPendingAction` then a
184
+ * single POST, which completes well inside an hour.
185
+ */
186
+ async function signAccountTierChange(
187
+ deps: LighterSignActionsDeps,
188
+ address: Address,
189
+ step: WasmBlobActionStep
190
+ ): Promise<WasmBlobSignedActionStep> {
191
+ const apiKey = await requireApiKey(deps, address)
192
+ const deadline = Math.floor(Date.now() / 1000) + 60 * 60
193
+ const authToken = await deps.signer.createAuthToken(deadline, {
194
+ apiKeyPrivateKey: apiKey.apiKeyPrivateKey,
195
+ apiKeyIndex: apiKey.apiKeyIndex,
196
+ accountIndex: apiKey.accountIndex,
197
+ })
198
+ return {
199
+ action: step.action,
200
+ wasmSignParams: step.wasmSignParams,
201
+ signedTx: {
202
+ // `/changeAccountTier` reads only `txInfo` (the auth token); `txType`
203
+ // and `txHash` are placeholders to satisfy the envelope shape.
204
+ txType: 0,
205
+ txInfo: authToken,
206
+ txHash: '',
207
+ },
208
+ }
209
+ }
210
+
211
+ async function requireApiKey(
212
+ deps: LighterSignActionsDeps,
213
+ address: Address
214
+ ): Promise<LighterApiKey> {
215
+ const apiKey = await deps.keyStore.get(address)
216
+ if (!apiKey) {
217
+ throw new PerpsError(
218
+ PerpsErrorCode.SDKError,
219
+ `No Lighter API key registered for ${address}. ` +
220
+ 'Run prepareAccount / REGISTER_API_KEY first.'
221
+ )
222
+ }
223
+ return apiKey
224
+ }
225
+
226
+ /**
227
+ * Sign and broadcast a sequence of `EVM_TX` actions via the user's wallet
228
+ * client. Steps are submitted serially so a later step (e.g. deposit) can
229
+ * rely on an earlier step (e.g. approve) having mined. Each step's
230
+ * `txParams` carries chainId, target, function name, args, and a
231
+ * human-readable abi from the backend.
232
+ * @internal
233
+ */
234
+ export async function signEvmTxActions(
235
+ steps: EvmTxActionStep[],
236
+ ctx: SignActionsContext | undefined
237
+ ): Promise<EvmTxSignedActionStep[]> {
238
+ const walletSigner = ctx?.userWallet
239
+ if (!walletSigner) {
240
+ throw new PerpsError(
241
+ PerpsErrorCode.SDKError,
242
+ 'EVM_TX signing requires the end-user wallet. Pass `userWallet` to ' +
243
+ 'createPerpsClient or call setUserWallet(walletClient).'
244
+ )
245
+ }
246
+
247
+ const signed: EvmTxSignedActionStep[] = []
248
+ for (const step of steps) {
249
+ const params = step.txParams as {
250
+ chainId: number
251
+ to: Address
252
+ functionName: string
253
+ args: readonly unknown[]
254
+ abi: readonly string[]
255
+ }
256
+
257
+ const txHash = await walletSigner.writeContract({
258
+ address: params.to,
259
+ abi: parseAbi(params.abi),
260
+ functionName: params.functionName,
261
+ args: params.args,
262
+ chain: walletSigner.chain,
263
+ account: walletSigner.account,
264
+ })
265
+
266
+ signed.push({
267
+ action: step.action,
268
+ txParams: step.txParams,
269
+ txHash,
270
+ })
271
+ }
272
+
273
+ return signed
274
+ }
275
+
276
+ /**
277
+ * Top-level dispatch: pick the per-method signer based on the descriptor's
278
+ * `signingMethod` and forward. `EIP712` is rejected — Lighter declares no
279
+ * EIP712 actions (its user-consent step uses an EIP-191 `signMessage` inside
280
+ * the `WASM_BLOB` REGISTER_API_KEY flow).
281
+ * @internal
282
+ */
283
+ export async function lighterSignActions(
284
+ deps: LighterSignActionsDeps,
285
+ method: SigningMethod,
286
+ steps: ActionStep[],
287
+ address: Address,
288
+ ctx?: SignActionsContext
289
+ ): Promise<SignedActionStep[]> {
290
+ switch (method) {
291
+ case SigningMethod.WASM_BLOB:
292
+ return signWasmBlobActions(
293
+ deps,
294
+ address,
295
+ steps as WasmBlobActionStep[],
296
+ ctx
297
+ )
298
+ case SigningMethod.EVM_TX:
299
+ return signEvmTxActions(steps as EvmTxActionStep[], ctx)
300
+ case SigningMethod.EIP712:
301
+ throw new PerpsError(
302
+ PerpsErrorCode.SDKError,
303
+ 'LighterProvider.signActions: Lighter declares no EIP712 actions.'
304
+ )
305
+ default:
306
+ throw new PerpsError(
307
+ PerpsErrorCode.SDKError,
308
+ `LighterProvider.signActions: unknown SigningMethod '${method as string}'.`
309
+ )
310
+ }
311
+ }
@@ -0,0 +1,293 @@
1
+ // The Go runtime installs functions (SignCreateOrder, SignCancelOrder, etc.)
2
+ // onto `globalThis` when `go.run(instance)` starts the main goroutine.
3
+ //
4
+ // The default asset URLs resolve relative to this module's emitted JS file:
5
+ // src/signers/../../wasm/lighter-signer.wasm → package-root wasm/
6
+ // dist/{esm,cjs}/signers/../../wasm/… → dist/wasm/ (shared)
7
+ // The build script copies the wasm assets into both dist subtrees so the same
8
+ // relative path resolves at runtime regardless of which bundle is loaded.
9
+ //
10
+ // To resolve the module's own URL in both ESM (where `__filename` is absent)
11
+ // and CJS (where `import.meta.url` is a syntax error), we parse a stack trace
12
+ // — `currentModuleUrl` always appears as the first frame, and V8 includes the
13
+ // emitting file path regardless of module system. Callers can override both
14
+ // asset URLs via {@link LoadLighterWasmOptions} to bypass this heuristic.
15
+
16
+ function currentModuleUrl(): string {
17
+ const cjsFilename = (globalThis as { __filename?: string }).__filename
18
+ if (typeof cjsFilename === 'string' && cjsFilename.length > 0) {
19
+ return `file://${cjsFilename}`
20
+ }
21
+ const stack = new Error().stack ?? ''
22
+ // Stack frames look like one of:
23
+ // " at currentModuleUrl (file:///abs/path/wasmLoader.js:29:10)"
24
+ // " at currentModuleUrl (/abs/path/wasmLoader.js:29:10)"
25
+ // " at currentModuleUrl (file:///abs/path/wasmLoader.ts:29:10)" (vitest)
26
+ // " at currentModuleUrl (http://localhost:5173/.../wasmLoader.ts?v=…:29:10)" (vite dev)
27
+ const match = stack.match(/\(([^)]+wasmLoader\.[tj]s[^)]*)\)/)
28
+ const frame = match?.[1] ?? ''
29
+ const withoutPos = frame.replace(/:\d+:\d+$/, '')
30
+ if (
31
+ withoutPos.startsWith('file://') ||
32
+ withoutPos.startsWith('http://') ||
33
+ withoutPos.startsWith('https://')
34
+ ) {
35
+ return withoutPos
36
+ }
37
+ if (withoutPos.length > 0) {
38
+ // Bare absolute path (Node CJS without `file://` prefix in some runners).
39
+ return `file://${withoutPos}`
40
+ }
41
+ throw new Error(
42
+ 'Could not resolve the Lighter WASM loader module URL. Pass an explicit ' +
43
+ '`wasmBinaryUrl` and `wasmExecJsUrl` to loadLighterWasm().'
44
+ )
45
+ }
46
+
47
+ function defaultAssetUrl(filename: string): URL {
48
+ return new URL(`../../wasm/${filename}`, currentModuleUrl())
49
+ }
50
+
51
+ /** @public */
52
+ export interface LoadLighterWasmOptions {
53
+ /** Override URL for the `.wasm` binary (browser: fetch; Node: fs). */
54
+ wasmBinaryUrl?: string | URL
55
+ /** Override URL for Go's `wasm_exec.js` runtime. */
56
+ wasmExecJsUrl?: string | URL
57
+ /**
58
+ * Pre-fetched source of Go's `wasm_exec.js`. Preferred over
59
+ * `wasmExecJsUrl` for bundlers (Vite/webpack) that may transform a `.js`
60
+ * URL on serve, breaking the IIFE that installs `globalThis.Go`. Pass via
61
+ * a `?raw` import (Vite) or equivalent so the original source survives
62
+ * intact.
63
+ */
64
+ wasmExecJsSource?: string
65
+ }
66
+
67
+ /** @public */
68
+ export interface LighterWasmExports {
69
+ GenerateAPIKey: (seed?: string) => {
70
+ publicKey?: string
71
+ privateKey?: string
72
+ error?: string
73
+ }
74
+ CreateClient: (
75
+ url: string,
76
+ privateKey: string,
77
+ chainId: number,
78
+ apiKeyIndex: number,
79
+ accountIndex: number
80
+ ) => { error?: string }
81
+ CheckClient: (apiKeyIndex: number, accountIndex: number) => { error?: string }
82
+ /**
83
+ * Returns `{authToken}` on success — note the field name is `authToken`,
84
+ * NOT `token`. Reading the wrong field silently fails (Go sets nothing
85
+ * else on the result), which is why early code paths returned undefined
86
+ * tokens with no error.
87
+ */
88
+ CreateAuthToken: (
89
+ deadline: number,
90
+ apiKeyIndex: number,
91
+ accountIndex: number
92
+ ) => { authToken?: string; error?: string }
93
+ /**
94
+ * Signature mirrors lighter-python's `signer.SignChangePubKey(...)` call —
95
+ * 5 positional args including `skipNonce` (use 0 to embed our supplied
96
+ * nonce; 1 to leave it out for server-fill scenarios). Earlier versions
97
+ * here had only 4 args, which silently shifted all arguments by one and
98
+ * produced txInfo with garbage AccountIndex / ApiKeyIndex fields →
99
+ * Lighter rejected with code 20001 "invalid param".
100
+ */
101
+ SignChangePubKey: (
102
+ pubKeyHex: string,
103
+ skipNonce: number,
104
+ nonce: number,
105
+ apiKeyIndex: number,
106
+ accountIndex: number
107
+ ) => SignResult & { messageToSign?: string }
108
+ SignCreateOrder: (...args: unknown[]) => SignResult
109
+ SignCancelOrder: (...args: unknown[]) => SignResult
110
+ SignCancelAllOrders: (...args: unknown[]) => SignResult
111
+ SignTransfer: (...args: unknown[]) => SignResult
112
+ SignWithdraw: (...args: unknown[]) => SignResult
113
+ SignUpdateLeverage: (...args: unknown[]) => SignResult
114
+ SignModifyOrder: (...args: unknown[]) => SignResult
115
+ SignUpdateMargin: (...args: unknown[]) => SignResult
116
+ }
117
+
118
+ /** @internal */
119
+ export interface SignResult {
120
+ txType?: number
121
+ txInfo?: string
122
+ txHash?: string
123
+ error?: string
124
+ }
125
+
126
+ const WASM_FUNCTION_NAMES = [
127
+ 'GenerateAPIKey',
128
+ 'CreateClient',
129
+ 'CheckClient',
130
+ 'CreateAuthToken',
131
+ 'SignChangePubKey',
132
+ 'SignCreateOrder',
133
+ 'SignCancelOrder',
134
+ 'SignCancelAllOrders',
135
+ 'SignTransfer',
136
+ 'SignWithdraw',
137
+ 'SignUpdateLeverage',
138
+ 'SignModifyOrder',
139
+ 'SignUpdateMargin',
140
+ ] as const
141
+
142
+ type GoClass = new () => {
143
+ importObject: WebAssembly.Imports
144
+ run(instance: WebAssembly.Instance): Promise<void>
145
+ }
146
+
147
+ let cachedExports: Promise<LighterWasmExports> | undefined
148
+
149
+ // `node:fs/promises` and `node:url` are Node-only. Static imports force browser
150
+ // bundlers (Vite/Rollup/esbuild) to resolve them up-front, which fails. Dynamic
151
+ // `import('node:...')` lets bundlers leave the branch unreachable in browsers
152
+ // while Node still resolves it at runtime when asked for a `file://` URL.
153
+ async function readNodeFile(url: URL): Promise<Uint8Array> {
154
+ const [{ readFile }, { fileURLToPath }] = await Promise.all([
155
+ import(/* @vite-ignore */ 'node:fs/promises'),
156
+ import(/* @vite-ignore */ 'node:url'),
157
+ ])
158
+ return readFile(fileURLToPath(url))
159
+ }
160
+
161
+ /**
162
+ * Resolve a possibly-relative URL string against the current document/page
163
+ * origin. Bundlers like Vite hand out absolute paths (e.g. `/node_modules/…`)
164
+ * for `?url` imports, which `new URL(string)` rejects without a base.
165
+ */
166
+ function toResolvedUrl(url: string | URL): URL {
167
+ if (url instanceof URL) {
168
+ return url
169
+ }
170
+ const base =
171
+ typeof globalThis !== 'undefined' &&
172
+ (globalThis as { location?: { href?: string } }).location?.href
173
+ ? (globalThis as { location: { href: string } }).location.href
174
+ : undefined
175
+ return new URL(url, base)
176
+ }
177
+
178
+ async function readUrlBytes(url: string | URL): Promise<ArrayBuffer> {
179
+ const u = toResolvedUrl(url)
180
+ if (u.protocol === 'file:') {
181
+ const buf = await readNodeFile(u)
182
+ // Copy the view into a fresh ArrayBuffer — `Buffer.buffer` is a shared
183
+ // ArrayBuffer in Node and the wasm instantiator expects a plain one.
184
+ return buf.slice().buffer as ArrayBuffer
185
+ }
186
+ const response = await fetch(u)
187
+ if (!response.ok) {
188
+ throw new Error(
189
+ `Failed to fetch ${u.href}: ${response.status} ${response.statusText}`
190
+ )
191
+ }
192
+ return response.arrayBuffer()
193
+ }
194
+
195
+ async function readUrlText(url: string | URL): Promise<string> {
196
+ const u = toResolvedUrl(url)
197
+ if (u.protocol === 'file:') {
198
+ const buf = await readNodeFile(u)
199
+ return new TextDecoder('utf-8').decode(buf)
200
+ }
201
+ const response = await fetch(u)
202
+ if (!response.ok) {
203
+ throw new Error(
204
+ `Failed to fetch ${u.href}: ${response.status} ${response.statusText}`
205
+ )
206
+ }
207
+ return response.text()
208
+ }
209
+
210
+ /**
211
+ * Load the Lighter WASM signer. Memoized per-process: subsequent calls return
212
+ * the cached exports. The Go runtime keeps a long-running goroutine to service
213
+ * JS calls — we start it once and never stop it.
214
+ * @public
215
+ */
216
+ export async function loadLighterWasm(
217
+ options?: LoadLighterWasmOptions
218
+ ): Promise<LighterWasmExports> {
219
+ if (!cachedExports) {
220
+ cachedExports = loadWasmUncached(options)
221
+ }
222
+ return cachedExports
223
+ }
224
+
225
+ async function loadWasmUncached(
226
+ options?: LoadLighterWasmOptions
227
+ ): Promise<LighterWasmExports> {
228
+ const wasmBinaryUrl =
229
+ options?.wasmBinaryUrl ?? defaultAssetUrl('lighter-signer.wasm')
230
+
231
+ // Prefer a pre-fetched source string (bundler `?raw` imports) over a URL —
232
+ // bundlers may transform a `.js` URL on serve, breaking the IIFE that sets
233
+ // `globalThis.Go`.
234
+ const wasmExecSourcePromise: Promise<string> =
235
+ options?.wasmExecJsSource !== undefined
236
+ ? Promise.resolve(options.wasmExecJsSource)
237
+ : readUrlText(options?.wasmExecJsUrl ?? defaultAssetUrl('wasm_exec.js'))
238
+
239
+ const [wasmExecSource, wasmBytes] = await Promise.all([
240
+ wasmExecSourcePromise,
241
+ readUrlBytes(wasmBinaryUrl),
242
+ ])
243
+
244
+ // wasm_exec.js is an IIFE that installs `globalThis.Go = class { ... }` plus
245
+ // fs/process/crypto polyfills. Evaluate it in a Function scope so the class
246
+ // attaches to globalThis and we read it back from there.
247
+ const installGo = new Function(`${wasmExecSource}; return globalThis.Go`)
248
+ const Go = installGo() as GoClass
249
+
250
+ const go = new Go()
251
+ const { instance } = await WebAssembly.instantiate(wasmBytes, go.importObject)
252
+ // Start the Go goroutine — this never resolves until the Go main() returns,
253
+ // which our signer never does. Intentionally not awaited.
254
+ void go.run(instance)
255
+
256
+ // Wait microtasks to let Go's init() register JS-bound functions.
257
+ await yieldToGoRuntime()
258
+
259
+ const exports: Partial<LighterWasmExports> = {}
260
+ for (const name of WASM_FUNCTION_NAMES) {
261
+ const fn = (globalThis as Record<string, unknown>)[name]
262
+ if (typeof fn !== 'function') {
263
+ throw new Error(
264
+ `Lighter WASM did not export expected function: ${name}. ` +
265
+ 'The .wasm binary may be stale or incompatible.'
266
+ )
267
+ }
268
+ ;(exports as Record<string, unknown>)[name] = fn
269
+ }
270
+
271
+ return exports as LighterWasmExports
272
+ }
273
+
274
+ async function yieldToGoRuntime(): Promise<void> {
275
+ for (let i = 0; i < 2; i++) {
276
+ await new Promise<void>((resolve) => {
277
+ if (typeof setImmediate === 'function') {
278
+ setImmediate(resolve)
279
+ } else {
280
+ setTimeout(resolve, 0)
281
+ }
282
+ })
283
+ }
284
+ }
285
+
286
+ /**
287
+ * Testing helper — drop the cached WASM instance so the next load reinitializes.
288
+ *
289
+ * @public
290
+ */
291
+ export function resetLighterWasmCache(): void {
292
+ cachedExports = undefined
293
+ }