@antseed/ants 0.1.5 → 0.1.7

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 (251) hide show
  1. package/dist/ants-web/assets/Arc-VDBY7LNS-BChRXCXW.js +1 -0
  2. package/dist/ants-web/assets/Brave-BRAKJXDS-mq-Xo37j.js +1 -0
  3. package/dist/ants-web/assets/Browser-76IHF3Y2-BMhRaC5Z.js +1 -0
  4. package/dist/ants-web/assets/Chrome-65Q5P54Y-DR9MQEVr.js +1 -0
  5. package/dist/ants-web/assets/Edge-XSPUTORV-DEoZslQE.js +1 -0
  6. package/dist/ants-web/assets/Firefox-AAHGJQIP-Bp_Hm04m.js +1 -0
  7. package/dist/ants-web/assets/Linux-OO4TNCLJ-B0aw93n9.js +1 -0
  8. package/dist/ants-web/assets/Macos-MW4AE7LN-Vvm8Drw3.js +1 -0
  9. package/dist/ants-web/assets/Opera-KQZLSACL-Cwv5MDFy.js +1 -0
  10. package/dist/ants-web/assets/Safari-ZPL37GXR-C4Ggg6rz.js +1 -0
  11. package/dist/ants-web/assets/Windows-PPTHQER6-BlyV2p7Y.js +1 -0
  12. package/dist/ants-web/assets/add-1qQ_SVL6.js +15 -0
  13. package/dist/ants-web/assets/all-wallets-D0QF065k.js +6 -0
  14. package/dist/ants-web/assets/apechain-SX5YFU6N-q5qBv-mp.js +1 -0
  15. package/dist/ants-web/assets/app-store-j-2thKGl.js +17 -0
  16. package/dist/ants-web/assets/apple-CCcInWVX.js +18 -0
  17. package/dist/ants-web/assets/ar_AR-44JUQ6EW-BMX-am0v.js +1487 -0
  18. package/dist/ants-web/assets/arbitrum-WURIBY6W-CqVkHBr5.js +1 -0
  19. package/dist/ants-web/assets/arrow-bottom-DVZa97G2.js +8 -0
  20. package/dist/ants-web/assets/arrow-bottom-circle-tt2k5BWG.js +11 -0
  21. package/dist/ants-web/assets/arrow-left-DnjqXMe0.js +8 -0
  22. package/dist/ants-web/assets/arrow-right-De8QMymS.js +8 -0
  23. package/dist/ants-web/assets/arrow-top-BS2oLt_x.js +8 -0
  24. package/dist/ants-web/assets/assets-Q6ZU7ZJ5-P8HioiAD.js +1 -0
  25. package/dist/ants-web/assets/avalanche-KOMJD3XY-Dsn_JPR4.js +1 -0
  26. package/dist/ants-web/assets/bank-DIxCskFM.js +14 -0
  27. package/dist/ants-web/assets/base-OAXLRA4F-CoYTVIiL.js +1 -0
  28. package/dist/ants-web/assets/baseAccount-44UITRK7-CsjdbWCf.js +1 -0
  29. package/dist/ants-web/assets/basic-D0Dg7j2v.js +2128 -0
  30. package/dist/ants-web/assets/berachain-NJECWIVC-DumxnFvf.js +1 -0
  31. package/dist/ants-web/assets/blast-V555OVXZ-BbhJh1tj.js +1 -0
  32. package/dist/ants-web/assets/browser-n9VVPree.js +14 -0
  33. package/dist/ants-web/assets/bsc-N647EYR2-B2nLKXWV.js +1 -0
  34. package/dist/ants-web/assets/card-Bl7AHEuE.js +14 -0
  35. package/dist/ants-web/assets/ccip-C_ifxkiT.js +1 -0
  36. package/dist/ants-web/assets/celo-GEP4TUHG-CenIBYLU.js +1 -0
  37. package/dist/ants-web/assets/checkmark-DXB1SsFx.js +11 -0
  38. package/dist/ants-web/assets/checkmark-bold-CIMnw7st.js +8 -0
  39. package/dist/ants-web/assets/chevron-bottom-DGkVb8CY.js +8 -0
  40. package/dist/ants-web/assets/chevron-left-D8vC6sW_.js +8 -0
  41. package/dist/ants-web/assets/chevron-right-CP8tyhU4.js +8 -0
  42. package/dist/ants-web/assets/chevron-top-DUqp6O8b.js +8 -0
  43. package/dist/ants-web/assets/chrome-store-CDk6Jfiv.js +61 -0
  44. package/dist/ants-web/assets/clock-t0Dwo5ck.js +8 -0
  45. package/dist/ants-web/assets/close-BiTlv6FX.js +8 -0
  46. package/dist/ants-web/assets/coinPlaceholder-PJZCh_De.js +8 -0
  47. package/dist/ants-web/assets/compass-CctP2ZVM.js +8 -0
  48. package/dist/ants-web/assets/connect-UA7M4XW6-IY3X6Bmr.js +1 -0
  49. package/dist/ants-web/assets/copy-b1i5dSZT.js +15 -0
  50. package/dist/ants-web/assets/core-4w9H32as.js +908 -0
  51. package/dist/ants-web/assets/create-FASO7PVG-D_rvSpre.js +1 -0
  52. package/dist/ants-web/assets/cronos-HJPAQTAE-BEOvlOC4.js +1 -0
  53. package/dist/ants-web/assets/cursor-kLCZuRWK.js +3 -0
  54. package/dist/ants-web/assets/cursor-transparent-C1IxvCBs.js +12 -0
  55. package/dist/ants-web/assets/de_DE-PYAO5YD6-BWlqPWgO.js +1487 -0
  56. package/dist/ants-web/assets/degen-FQQ4XGHB-CeHTs88l.js +1 -0
  57. package/dist/ants-web/assets/desktop-Qa_41eha.js +9 -0
  58. package/dist/ants-web/assets/disconnect-7QBZVVG8.js +8 -0
  59. package/dist/ants-web/assets/discord-DuRr0OMy.js +17 -0
  60. package/dist/ants-web/assets/es_419-HRGOJ6VT-D-qzxUM-.js +1487 -0
  61. package/dist/ants-web/assets/ethereum-RGGVA4PY-SWGOlkuk.js +1 -0
  62. package/dist/ants-web/assets/etherscan-BOImzSgC.js +6 -0
  63. package/dist/ants-web/assets/events-DQ172AOg.js +1 -0
  64. package/dist/ants-web/assets/exclamation-triangle-evZ54TSt.js +4 -0
  65. package/dist/ants-web/assets/extension-YSvzNEgu.js +8 -0
  66. package/dist/ants-web/assets/external-link-BukU3aK3.js +8 -0
  67. package/dist/ants-web/assets/facebook-WJZQGI9M.js +26 -0
  68. package/dist/ants-web/assets/farcaster-Dt0XRvlP.js +12 -0
  69. package/dist/ants-web/assets/filters-CFC5g--u.js +8 -0
  70. package/dist/ants-web/assets/flow-5FQJFCTK-CUie2reO.js +1 -0
  71. package/dist/ants-web/assets/fr_FR-IGGVC6RM-D8LpUM75.js +1487 -0
  72. package/dist/ants-web/assets/github-Bhz0AnGj.js +18 -0
  73. package/dist/ants-web/assets/gnosis-37ZC4RBL-B137OtHZ.js +1 -0
  74. package/dist/ants-web/assets/google-CGzSUXjP.js +18 -0
  75. package/dist/ants-web/assets/gravity-J5YQHTYH-Bj6B0uod.js +1 -0
  76. package/dist/ants-web/assets/hardhat-TX56IT5N-CV1FY-wE.js +1 -0
  77. package/dist/ants-web/assets/help-circle-BoGPtVJY.js +12 -0
  78. package/dist/ants-web/assets/hi_IN-XSKAA3MF-C3QUpWyP.js +1487 -0
  79. package/dist/ants-web/assets/hyperevm-VKPAA4SA-CHwraEsx.js +1 -0
  80. package/dist/ants-web/assets/id-ir8rS0J_.js +12 -0
  81. package/dist/ants-web/assets/id_ID-KUOB4UAL-K9y-nRWm.js +1487 -0
  82. package/dist/ants-web/assets/image-DXBUHwz_.js +4 -0
  83. package/dist/ants-web/assets/index-9ALlRD6p.css +1 -0
  84. package/dist/ants-web/assets/index-B7p3jPAJ.js +1 -0
  85. package/dist/ants-web/assets/index-BqWNkBzB.js +395 -0
  86. package/dist/ants-web/assets/index-C-I4ROfT.js +16 -0
  87. package/dist/ants-web/assets/index-Chq8yV_g.js +47 -0
  88. package/dist/ants-web/assets/index-Ci5bF__2.js +1729 -0
  89. package/dist/ants-web/assets/index-kzlEvkEN.js +1 -0
  90. package/dist/ants-web/assets/index.es-D1GdDJUC.js +39 -0
  91. package/dist/ants-web/assets/info-DzGq_QPQ.js +3 -0
  92. package/dist/ants-web/assets/info-circle-z91TqQxH.js +12 -0
  93. package/dist/ants-web/assets/ink-FZMYZWHG-62p-5IK5.js +1 -0
  94. package/dist/ants-web/assets/ja_JP-4WRQ63RX-Ct5pF4ug.js +1487 -0
  95. package/dist/ants-web/assets/kaia-65D2U3PU-JmuLQ4gC.js +1 -0
  96. package/dist/ants-web/assets/ko_KR-I2K7AIEP-B5gw8Mwb.js +1487 -0
  97. package/dist/ants-web/assets/lightbulb-CgYwiQYs.js +3 -0
  98. package/dist/ants-web/assets/linea-QRMVQ5DY-DuI3vv0d.js +1 -0
  99. package/dist/ants-web/assets/login-UP3DZBGS-Db_wM5oQ.js +1 -0
  100. package/dist/ants-web/assets/mail-FLPFIbqi.js +8 -0
  101. package/dist/ants-web/assets/manta-SI27YFEJ-CpVOKa06.js +1 -0
  102. package/dist/ants-web/assets/mantle-CKIUT334-DR2WgqzU.js +1 -0
  103. package/dist/ants-web/assets/metaMaskWallet-SITXT2FV-BlemcphV.js +1 -0
  104. package/dist/ants-web/assets/metamask-sdk-QG4PtQco.js +542 -0
  105. package/dist/ants-web/assets/mobile--kHpa5NK.js +9 -0
  106. package/dist/ants-web/assets/monad-4KWC6TSS-DVXSkpiz.js +1 -0
  107. package/dist/ants-web/assets/more-CJbReLy0.js +11 -0
  108. package/dist/ants-web/assets/ms_MY-6VZW6Q3Z-BtFD07hR.js +1487 -0
  109. package/dist/ants-web/assets/network-placeholder-BfSizFBN.js +14 -0
  110. package/dist/ants-web/assets/nftPlaceholder-BTfly2G8.js +8 -0
  111. package/dist/ants-web/assets/off-DCMXa6Y2.js +8 -0
  112. package/dist/ants-web/assets/optimism-HAF2GUT7-ec6Nqxs9.js +1 -0
  113. package/dist/ants-web/assets/play-store-CbbevixE.js +32 -0
  114. package/dist/ants-web/assets/plus-BxINT2r_.js +13 -0
  115. package/dist/ants-web/assets/polygon-WW6ZI7PM-DXlmm4L1.js +1 -0
  116. package/dist/ants-web/assets/pt_BR-N3XOZ4SV-CvVpfsHb.js +1487 -0
  117. package/dist/ants-web/assets/qr-code-CMEsvGrE.js +6 -0
  118. package/dist/ants-web/assets/rainbowWallet-O26YNBMX-DUhYus-9.js +1 -0
  119. package/dist/ants-web/assets/recycle-horizontal-BldRTXPT.js +9 -0
  120. package/dist/ants-web/assets/refresh-82vLCcdB.js +8 -0
  121. package/dist/ants-web/assets/refresh-S4T5V5GX-CwqIaaxK.js +1 -0
  122. package/dist/ants-web/assets/reown-logo-BPGalyzg.js +12 -0
  123. package/dist/ants-web/assets/ronin-EMCPYXZT-N-QBHZdV.js +1 -0
  124. package/dist/ants-web/assets/ru_RU-IITAPRET-DOj6Jzj7.js +1487 -0
  125. package/dist/ants-web/assets/safeWallet-5MNKTR5Z-D-5imDLD.js +1 -0
  126. package/dist/ants-web/assets/sanko-RHQYXGM5-OX010CbN.js +1 -0
  127. package/dist/ants-web/assets/scan-4UYSQ56Q-CjMz6-XC.js +1 -0
  128. package/dist/ants-web/assets/scroll-5OBGQVOV-DJFECiai.js +1 -0
  129. package/dist/ants-web/assets/search-CADsyV1c.js +8 -0
  130. package/dist/ants-web/assets/secp256k1-B5byVYSZ.js +1 -0
  131. package/dist/ants-web/assets/secp256k1-Cb4vPU9D.js +1 -0
  132. package/dist/ants-web/assets/send-DyAisqGO.js +15 -0
  133. package/dist/ants-web/assets/sign-A7IJEUT5-CGsRnPrd.js +1 -0
  134. package/dist/ants-web/assets/superposition-HG6MMR2Y-bRkgatRO.js +1 -0
  135. package/dist/ants-web/assets/swapHorizontal-BfHwXZPT.js +8 -0
  136. package/dist/ants-web/assets/swapHorizontalBold-FIoCjqnp.js +8 -0
  137. package/dist/ants-web/assets/swapHorizontalMedium-CzDDCY_G.js +16 -0
  138. package/dist/ants-web/assets/swapHorizontalRoundedBold-CvMRJeWj.js +8 -0
  139. package/dist/ants-web/assets/swapVertical-BgSezaow.js +8 -0
  140. package/dist/ants-web/assets/telegram-CsMNhXCs.js +16 -0
  141. package/dist/ants-web/assets/th_TH-3ZQCKCQE-BcHUN2Q4.js +1487 -0
  142. package/dist/ants-web/assets/three-dots-DYf4gmVW.js +5 -0
  143. package/dist/ants-web/assets/tr_TR-QUPUGMUF-CwpF6ZFn.js +1487 -0
  144. package/dist/ants-web/assets/twitch-BtBr-NTg.js +18 -0
  145. package/dist/ants-web/assets/twitterIcon-BmRf6M77.js +6 -0
  146. package/dist/ants-web/assets/uk_UA-SSN6SV5E-IlYYyRC6.js +1487 -0
  147. package/dist/ants-web/assets/unichain-C5BWO2ZY-BfguYsnu.js +1 -0
  148. package/dist/ants-web/assets/verify-cxA8gdP6.js +8 -0
  149. package/dist/ants-web/assets/verify-filled-DHnnW8EE.js +8 -0
  150. package/dist/ants-web/assets/vi_VN-7BUVRNYY-CZ9S75qZ.js +1487 -0
  151. package/dist/ants-web/assets/w3m-modal-D1ucMOAa.js +642 -0
  152. package/dist/ants-web/assets/wallet-BT4Fue1R.js +8 -0
  153. package/dist/ants-web/assets/wallet-placeholder-C2J5s6Yp.js +14 -0
  154. package/dist/ants-web/assets/walletConnectWallet-YHWKVTDY-D3lyiczV.js +1 -0
  155. package/dist/ants-web/assets/walletconnect-B5k8iJl-.js +30 -0
  156. package/dist/ants-web/assets/warning-circle-9rNSUSsX.js +12 -0
  157. package/dist/ants-web/assets/x-CpRc85jR.js +12 -0
  158. package/dist/ants-web/assets/xdc-KJ3TDBYO-DNV6zchh.js +1 -0
  159. package/dist/ants-web/assets/zetachain-TLDS5IPW-Udhyw16T.js +1 -0
  160. package/dist/ants-web/assets/zh_CN-HJBN674C-Baf0GEeT.js +1487 -0
  161. package/dist/ants-web/assets/zh_HK-JW3WLRKE-VztJKXL5.js +1487 -0
  162. package/dist/ants-web/assets/zh_TW-VNNRNXY7-aWfg7Qp4.js +1487 -0
  163. package/dist/ants-web/assets/zksync-DH7HK5U4-Dt4usFw6.js +1 -0
  164. package/dist/ants-web/assets/zora-FYL5H3IO-iB4wygST.js +1 -0
  165. package/dist/ants-web/index.html +2 -2
  166. package/dist/api-types.d.ts +168 -6
  167. package/dist/browser-signer.d.ts +30 -0
  168. package/dist/browser-signer.js +189 -0
  169. package/dist/browser-signer.js.map +1 -0
  170. package/dist/jobs.d.ts +10 -3
  171. package/dist/jobs.js +97 -20
  172. package/dist/jobs.js.map +1 -1
  173. package/dist/position-actions.d.ts +13 -0
  174. package/dist/position-actions.js +25 -0
  175. package/dist/position-actions.js.map +1 -0
  176. package/dist/routes.d.ts +7 -0
  177. package/dist/routes.js +63 -5
  178. package/dist/routes.js.map +1 -1
  179. package/dist/server.d.ts +8 -0
  180. package/dist/server.js +157 -12
  181. package/dist/server.js.map +1 -1
  182. package/dist/service/context.d.ts +25 -3
  183. package/dist/service/context.js +56 -5
  184. package/dist/service/context.js.map +1 -1
  185. package/dist/service/display-snapshot.d.ts +28 -0
  186. package/dist/service/display-snapshot.js +144 -0
  187. package/dist/service/display-snapshot.js.map +1 -0
  188. package/dist/service/emissions.js +11 -19
  189. package/dist/service/emissions.js.map +1 -1
  190. package/dist/service/explorer.js +2 -1
  191. package/dist/service/explorer.js.map +1 -1
  192. package/dist/service/format.d.ts +1 -1
  193. package/dist/service/format.js +2 -0
  194. package/dist/service/format.js.map +1 -1
  195. package/dist/service/indexed-wallet.d.ts +7 -0
  196. package/dist/service/indexed-wallet.js +58 -0
  197. package/dist/service/indexed-wallet.js.map +1 -0
  198. package/dist/service/indexer.d.ts +32 -3
  199. package/dist/service/indexer.js +64 -8
  200. package/dist/service/indexer.js.map +1 -1
  201. package/dist/service/legacy-payout.d.ts +3 -0
  202. package/dist/service/legacy-payout.js +32 -0
  203. package/dist/service/legacy-payout.js.map +1 -0
  204. package/dist/service/network.d.ts +5 -0
  205. package/dist/service/network.js +185 -0
  206. package/dist/service/network.js.map +1 -0
  207. package/dist/service/overview-reads.d.ts +30 -0
  208. package/dist/service/overview-reads.js +69 -0
  209. package/dist/service/overview-reads.js.map +1 -0
  210. package/dist/service/overview.js +14 -36
  211. package/dist/service/overview.js.map +1 -1
  212. package/dist/service/pool-merge.d.ts +2 -1
  213. package/dist/service/pool-merge.js +11 -4
  214. package/dist/service/pool-merge.js.map +1 -1
  215. package/dist/service/pools.d.ts +22 -1
  216. package/dist/service/pools.js +257 -98
  217. package/dist/service/pools.js.map +1 -1
  218. package/dist/service/position-feed.d.ts +73 -0
  219. package/dist/service/position-feed.js +173 -0
  220. package/dist/service/position-feed.js.map +1 -0
  221. package/dist/service/positions.d.ts +3 -5
  222. package/dist/service/positions.js +155 -93
  223. package/dist/service/positions.js.map +1 -1
  224. package/dist/service/rewards.d.ts +1 -0
  225. package/dist/service/rewards.js +117 -56
  226. package/dist/service/rewards.js.map +1 -1
  227. package/dist/service/rpc-provider.d.ts +4 -0
  228. package/dist/service/rpc-provider.js +44 -3
  229. package/dist/service/rpc-provider.js.map +1 -1
  230. package/dist/service/seller-models.d.ts +2 -0
  231. package/dist/service/seller-models.js +94 -0
  232. package/dist/service/seller-models.js.map +1 -0
  233. package/dist/service/seller.js +33 -30
  234. package/dist/service/seller.js.map +1 -1
  235. package/dist/service/stake-eligibility.d.ts +6 -0
  236. package/dist/service/stake-eligibility.js +68 -0
  237. package/dist/service/stake-eligibility.js.map +1 -0
  238. package/dist/service/usage.js +5 -13
  239. package/dist/service/usage.js.map +1 -1
  240. package/dist/service/yield.d.ts +3 -0
  241. package/dist/service/yield.js +12 -0
  242. package/dist/service/yield.js.map +1 -0
  243. package/dist/view-cache.d.ts +5 -10
  244. package/dist/view-cache.js +12 -14
  245. package/dist/view-cache.js.map +1 -1
  246. package/dist/wallet-errors.d.ts +9 -0
  247. package/dist/wallet-errors.js +32 -0
  248. package/dist/wallet-errors.js.map +1 -0
  249. package/package.json +8 -3
  250. package/dist/ants-web/assets/index-BunPfgXh.css +0 -1
  251. package/dist/ants-web/assets/index-zCPoF694.js +0 -40
package/dist/jobs.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- const JOB_RETENTION_MS = 30 * 60 * 1000;
2
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ const JOB_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
3
5
  /**
4
- * In-memory job runner for multi-transaction actions. The dashboard starts a
6
+ * Job runner with optional activity persistence for multi-transaction actions. The dashboard starts a
5
7
  * job, then polls it for step-by-step progress (transaction hashes included)
6
8
  * instead of holding one HTTP request open across several confirmations.
7
9
  */
@@ -9,44 +11,119 @@ export class JobRunner {
9
11
  options;
10
12
  jobs = new Map();
11
13
  active = null;
14
+ acceptingWrites = true;
12
15
  /** `onFinish` runs after every job, successful or not, before its final status is visible. */
13
16
  constructor(options = {}) {
14
17
  this.options = options;
18
+ if (!options.journalPath)
19
+ return;
20
+ let records;
21
+ try {
22
+ records = JSON.parse(readFileSync(options.journalPath, 'utf8'));
23
+ }
24
+ catch (error) {
25
+ if (error.code === 'ENOENT')
26
+ return;
27
+ throw new Error('Could not read saved activity. Preserve the activity file and resolve the error before starting the dashboard.', { cause: error });
28
+ }
29
+ if (!Array.isArray(records))
30
+ throw new Error('Invalid saved activity file.');
31
+ for (const record of records) {
32
+ if (!record || typeof record.id !== 'string' || typeof record.kind !== 'string' || !['running', 'done', 'failed'].includes(record.status) || !Number.isFinite(record.startedAt) || (record.owner !== undefined && typeof record.owner !== 'string') || !Array.isArray(record.steps) || !record.steps.every((step) => step && typeof step.label === 'string' && Number.isFinite(step.at) && (step.hash === undefined || typeof step.hash === 'string'))) {
33
+ throw new Error('Invalid saved activity record.');
34
+ }
35
+ const job = record;
36
+ if (job.status === 'running') {
37
+ job.status = 'failed';
38
+ job.finishedAt = Date.now();
39
+ job.error = 'The server stopped before completion was recorded. Transactions may have succeeded. Check the wallet and transaction links before retrying; this action was not automatically resubmitted.';
40
+ }
41
+ this.jobs.set(job.id, job);
42
+ }
43
+ this.prune();
44
+ this.persist();
45
+ }
46
+ persist() {
47
+ if (!this.options.journalPath)
48
+ return;
49
+ mkdirSync(dirname(this.options.journalPath), { recursive: true, mode: 0o700 });
50
+ const temporary = `${this.options.journalPath}.${randomUUID()}.tmp`;
51
+ writeFileSync(temporary, JSON.stringify([...this.jobs.values()]), { mode: 0o600 });
52
+ renameSync(temporary, this.options.journalPath);
15
53
  }
16
- list() {
54
+ /** All jobs, or only those started for `owner` (case-insensitive address match). */
55
+ list(owner) {
17
56
  this.prune();
18
- return [...this.jobs.values()].sort((a, b) => b.startedAt - a.startedAt);
57
+ const all = [...this.jobs.values()].sort((a, b) => b.startedAt - a.startedAt);
58
+ if (!owner)
59
+ return all;
60
+ return all.filter((job) => job.owner?.toLowerCase() === owner.toLowerCase());
19
61
  }
20
62
  get(id) {
21
63
  this.prune();
22
64
  return this.jobs.get(id);
23
65
  }
66
+ get busy() {
67
+ return this.active !== null;
68
+ }
69
+ /** Atomically stop new jobs before replacing a wallet or network. */
70
+ pauseWrites() {
71
+ if (this.busy)
72
+ throw new Error('A staking action is still running. Wait for it to finish before changing wallets or networks.');
73
+ this.acceptingWrites = false;
74
+ }
24
75
  /** Run `work` as a job. Only one signing job runs at a time so nonces stay ordered. */
25
- start(kind, work) {
76
+ start(kind, work, owner) {
77
+ if (!this.acceptingWrites)
78
+ throw new Error('This staking session has ended. Reopen Staking to continue.');
26
79
  if (this.active && this.jobs.get(this.active)?.status === 'running') {
27
80
  throw new Error(`Another action (${this.jobs.get(this.active)?.kind}) is still running. Wait for it to finish.`);
28
81
  }
29
- const job = { id: randomUUID(), kind, status: 'running', steps: [], startedAt: Date.now() };
82
+ const job = { id: randomUUID(), kind, status: 'running', steps: [], startedAt: Date.now(), ...(owner ? { owner } : {}) };
30
83
  this.jobs.set(job.id, job);
84
+ try {
85
+ this.prune();
86
+ this.persist();
87
+ }
88
+ catch (error) {
89
+ this.jobs.delete(job.id);
90
+ throw new Error('Could not save activity. No action was started.', { cause: error });
91
+ }
31
92
  this.active = job.id;
32
93
  const report = (label, hash) => {
33
94
  const step = { at: Date.now(), label, ...(hash ? { hash } : {}) };
34
95
  job.steps.push(step);
96
+ this.persist();
35
97
  };
36
- void work(report).then((result) => {
37
- this.options.onFinish?.();
38
- job.status = 'done';
39
- job.result = result;
40
- job.finishedAt = Date.now();
41
- }, (error) => {
42
- this.options.onFinish?.();
43
- job.status = 'failed';
44
- job.error = describeError(error);
45
- job.finishedAt = Date.now();
46
- }).finally(() => {
47
- if (this.active === job.id)
48
- this.active = null;
49
- });
98
+ void (async () => {
99
+ try {
100
+ job.result = await work(report);
101
+ job.status = 'done';
102
+ }
103
+ catch (error) {
104
+ job.status = 'failed';
105
+ job.error = describeError(error);
106
+ }
107
+ finally {
108
+ try {
109
+ this.options.onFinish?.();
110
+ }
111
+ catch (error) {
112
+ job.status = 'failed';
113
+ job.error = `${job.error ?? 'The action finished.'} Refresh failed: ${describeError(error)}. Check transaction status before retrying.`;
114
+ }
115
+ job.finishedAt = Date.now();
116
+ if (this.active === job.id)
117
+ this.active = null;
118
+ try {
119
+ this.persist();
120
+ }
121
+ catch {
122
+ job.status = 'failed';
123
+ job.error = `${job.error ?? 'The action finished.'} Activity could not be saved. Check transaction status before retrying.`;
124
+ }
125
+ }
126
+ })();
50
127
  return job;
51
128
  }
52
129
  prune() {
package/dist/jobs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../src/jobs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../src/jobs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export type PositionAction = 'split' | 'move' | 'merge' | 'extend' | 'enable-max-lock' | 'disable-max-lock';
2
+ interface ActionPosition {
3
+ stakeStartEpoch: number;
4
+ stakeEndEpoch: number;
5
+ closedAtEpoch: number;
6
+ withdrawn: boolean;
7
+ maxLocked: boolean;
8
+ maxLockedNext?: boolean;
9
+ }
10
+ export declare function scheduledMaxLock(position: Pick<ActionPosition, 'maxLocked' | 'maxLockedNext'>): boolean;
11
+ export declare function positionActionEpoch(action: PositionAction, currentEpoch: number, positions: Pick<ActionPosition, 'stakeStartEpoch'>[]): number;
12
+ export declare function positionActionProblem(position: ActionPosition, action: PositionAction, effectiveEpoch: number | null): string | null;
13
+ export {};
@@ -0,0 +1,25 @@
1
+ export function scheduledMaxLock(position) {
2
+ return position.maxLockedNext ?? position.maxLocked;
3
+ }
4
+ export function positionActionEpoch(action, currentEpoch, positions) {
5
+ if (action === 'enable-max-lock' || action === 'disable-max-lock')
6
+ return currentEpoch + 1;
7
+ return Math.max(currentEpoch + 1, ...positions.map(position => position.stakeStartEpoch));
8
+ }
9
+ export function positionActionProblem(position, action, effectiveEpoch) {
10
+ if (position.withdrawn || position.closedAtEpoch !== 0)
11
+ return 'This position is already closed or withdrawn.';
12
+ if (effectiveEpoch === null)
13
+ return 'Waiting for current epoch information.';
14
+ const locked = scheduledMaxLock(position);
15
+ if (action === 'disable-max-lock')
16
+ return locked ? null : 'This position is not scheduled for max lock.';
17
+ if (locked)
18
+ return action === 'enable-max-lock' ? 'This position is already scheduled for max lock.' : 'Disable maximum lock before this action.';
19
+ if (action === 'enable-max-lock' && effectiveEpoch < position.stakeStartEpoch)
20
+ return `Max lock can be enabled when the next epoch reaches activation epoch ${position.stakeStartEpoch}.`;
21
+ if (position.stakeEndEpoch === 0 || effectiveEpoch >= position.stakeEndEpoch)
22
+ return 'The position must have a remaining lock when this action takes effect.';
23
+ return null;
24
+ }
25
+ //# sourceMappingURL=position-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position-actions.js","sourceRoot":"","sources":["../src/position-actions.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,gBAAgB,CAAC,QAA6D;IAC5F,OAAO,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC,SAAS,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAsB,EAAE,YAAoB,EAAE,SAAoD;IACpI,IAAI,MAAM,KAAK,iBAAiB,IAAI,MAAM,KAAK,kBAAkB;QAAE,OAAO,YAAY,GAAG,CAAC,CAAC;IAC3F,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAwB,EAAE,MAAsB,EAAE,cAA6B;IACnH,IAAI,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,aAAa,KAAK,CAAC;QAAE,OAAO,+CAA+C,CAAC;IAC/G,IAAI,cAAc,KAAK,IAAI;QAAE,OAAO,wCAAwC,CAAC;IAC7E,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,MAAM,KAAK,kBAAkB;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,8CAA8C,CAAC;IACzG,IAAI,MAAM;QAAE,OAAO,MAAM,KAAK,iBAAiB,CAAC,CAAC,CAAC,kDAAkD,CAAC,CAAC,CAAC,0CAA0C,CAAC;IAClJ,IAAI,MAAM,KAAK,iBAAiB,IAAI,cAAc,GAAG,QAAQ,CAAC,eAAe;QAAE,OAAO,wEAAwE,QAAQ,CAAC,eAAe,GAAG,CAAC;IAC1L,IAAI,QAAQ,CAAC,aAAa,KAAK,CAAC,IAAI,cAAc,IAAI,QAAQ,CAAC,aAAa;QAAE,OAAO,wEAAwE,CAAC;IAC9J,OAAO,IAAI,CAAC;AACd,CAAC"}
package/dist/routes.d.ts CHANGED
@@ -8,5 +8,12 @@ export interface RouteContext {
8
8
  views: ViewCache;
9
9
  readOnly: boolean;
10
10
  dataDir: string | null;
11
+ selectedAddress?: string;
12
+ /** The buyer account this session started for; the local authorization flow only applies to it. */
13
+ originBuyer: string;
14
+ browserSigning?: import('./browser-signer.js').BrowserSigning;
15
+ onAuthorize?: () => Promise<void>;
16
+ rememberTransaction?: (hash: string) => Promise<void>;
11
17
  }
18
+ export declare function assertSelectedWallet(ctx: AntsContext, selected: string, wallet: string, scope: 'connection' | 'wallet' | 'buyer'): Promise<void>;
12
19
  export declare function registerRoutes(app: FastifyInstance, context: RouteContext): void;
package/dist/routes.js CHANGED
@@ -1,5 +1,20 @@
1
+ import { ZeroAddress } from 'ethers';
2
+ import { networkSnapshot, networkLegacy } from './service/network.js';
1
3
  import { describeError } from './jobs.js';
4
+ import { sellerModels } from './service/seller-models.js';
2
5
  import { overview, positions, stake, move, split, merge, extend, maxLock, previewWithdraw, withdraw, rewards, claim, restake, stakeUsageRewards, compound, poolsView, singlePool, usage, emissions, verification, proofStatus, submitProof, seller, registerBinding, claimStarter, } from './service/index.js';
6
+ export async function assertSelectedWallet(ctx, selected, wallet, scope) {
7
+ if (scope !== 'buyer' && wallet.toLowerCase() === selected.toLowerCase())
8
+ return;
9
+ if (scope === 'wallet')
10
+ throw new Error(`Connect the selected account wallet ${selected} for seller and staking actions.`);
11
+ const operator = await ctx.deposits()?.getOperator(selected);
12
+ if (operator && operator !== ZeroAddress && wallet.toLowerCase() === operator.toLowerCase())
13
+ return;
14
+ throw new Error(scope === 'buyer'
15
+ ? `Connect the authorized wallet for buyer ${selected}. Current operator: ${operator && operator !== ZeroAddress ? operator : 'not configured; authorize a wallet first'}.`
16
+ : `Wallet mismatch. Connect ${selected} for seller/staking actions${operator && operator !== ZeroAddress ? ` or authorized operator ${operator} for buyer actions` : '; no buyer operator is configured'}.`);
17
+ }
3
18
  async function respond(reply, read) {
4
19
  try {
5
20
  reply.send({ ok: true, data: await read() });
@@ -13,20 +28,32 @@ export function registerRoutes(app, context) {
13
28
  const cached = (key, load) => views.read(key, load);
14
29
  app.get('/api/config', async () => ({
15
30
  ok: true,
16
- data: { address: ctx.address, chainId: ctx.chain.chainId, evmChainId: ctx.chain.evmChainId, readOnly: context.readOnly, dataDir: context.dataDir },
31
+ data: { address: ctx.address, selectedAddress: context.selectedAddress, walletAddress: context.selectedAddress ? await ctx.signer?.getAddress() ?? null : ctx.address, chainId: ctx.chain.chainId, evmChainId: ctx.chain.evmChainId, walletRpcUrl: ctx.chain.evmChainId === 31337 && /^http:\/\/(127\.0\.0\.1|localhost):[0-9]+\/?$/.test(ctx.chain.rpcUrl) ? ctx.chain.rpcUrl : undefined, readOnly: !ctx.signer, browserWallet: !!context.browserSigning, buyerAddress: ctx.buyerAddress, canAuthorize: !!context.onAuthorize && ctx.buyerAddress.toLowerCase() === context.originBuyer.toLowerCase(), dataDir: context.dataDir },
32
+ }));
33
+ app.post('/api/wallet/authorize', (_request, reply) => respond(reply, async () => {
34
+ if (!context.onAuthorize)
35
+ throw new Error('Open the VPR wallet authorization setup to authorize a wallet.');
36
+ if (ctx.buyerAddress.toLowerCase() !== context.originBuyer.toLowerCase())
37
+ throw new Error('The connected wallet is its own buyer account; the local authorization flow only applies to the originating buyer.');
38
+ await context.onAuthorize();
39
+ return {};
17
40
  }));
18
41
  app.get('/api/overview', (_request, reply) => respond(reply, () => cached('overview', () => overview(ctx))));
19
42
  app.get('/api/positions', (_request, reply) => respond(reply, () => cached('positions', () => positions(ctx))));
20
43
  app.get('/api/rewards', (_request, reply) => respond(reply, () => cached('rewards', () => rewards(ctx))));
21
- app.get('/api/pools', (_request, reply) => respond(reply, () => cached('pools', () => poolsView(ctx))));
44
+ app.get('/api/pools', (_request, reply) => respond(reply, () => views.read('pools', () => poolsView(ctx), 60_000)));
45
+ app.get('/api/sellers/:address/models', (request, reply) => respond(reply, () => views.read(`seller-models:${request.params.address.toLowerCase()}`, () => sellerModels(ctx.chain.explorerApiUrl, request.params.address), 60_000)));
22
46
  app.get('/api/pools/:agentId', (request, reply) => respond(reply, () => cached(`pool:${request.params.agentId}`, () => singlePool(ctx, Number(request.params.agentId)))));
23
47
  app.get('/api/usage', (request, reply) => respond(reply, () => cached(`usage:${request.query.epochs ?? ''}`, () => usage(ctx, { epochs: request.query.epochs ? Number(request.query.epochs) : undefined }))));
24
48
  app.get('/api/emissions', (_request, reply) => respond(reply, () => cached('emissions', () => emissions(ctx))));
49
+ app.get('/api/network', (_request, reply) => respond(reply, () => networkSnapshot(ctx)));
50
+ app.get('/api/network/legacy', (_request, reply) => respond(reply, () => views.read('network:legacy', () => networkLegacy(ctx), 300_000)));
25
51
  app.get('/api/verification', (request, reply) => respond(reply, () => cached(`verification:${(request.query.seller ?? '').toLowerCase()}`, () => verification(ctx, request.query.seller || undefined))));
26
52
  app.get('/api/verification/proofs/:proofId', (request, reply) => respond(reply, () => proofStatus(ctx, request.params.proofId)));
27
53
  app.get('/api/seller', (_request, reply) => respond(reply, () => cached('seller', () => seller(ctx))));
28
54
  app.post('/api/positions/withdraw/preview', (request, reply) => respond(reply, () => previewWithdraw(ctx, request.body?.positionIds ?? [])));
29
- app.get('/api/jobs', async () => ({ ok: true, data: jobs.list() }));
55
+ // Browser sessions share one journal across wallets; show each wallet only its own actions.
56
+ app.get('/api/jobs', async () => ({ ok: true, data: jobs.list(context.browserSigning ? ctx.address : undefined) }));
30
57
  app.get('/api/jobs/:id', async (request, reply) => {
31
58
  const job = jobs.get(request.params.id);
32
59
  if (!job)
@@ -35,10 +62,41 @@ export function registerRoutes(app, context) {
35
62
  });
36
63
  const action = (path, kind, run) => {
37
64
  app.post(path, async (request, reply) => {
38
- if (context.readOnly)
65
+ if (!ctx.signer)
39
66
  return reply.status(403).send({ ok: false, error: 'The dashboard is running in read-only mode (no wallet available).' });
40
67
  try {
41
- const job = jobs.start(kind, (report) => run((request.body ?? {}), report));
68
+ const job = jobs.start(kind, async (report) => {
69
+ ctx.invalidate();
70
+ try {
71
+ if (context.selectedAddress) {
72
+ const body = (request.body ?? {});
73
+ const buyerOnly = (kind === 'claim' && body.scope === 'buyer') || (kind === 'stake-usage' && body.side === 'buyer');
74
+ const wallet = await ctx.requireSigner().getAddress();
75
+ await assertSelectedWallet(ctx, context.selectedAddress, wallet, buyerOnly ? 'buyer' : 'wallet');
76
+ if (kind === 'claim' && body.scope !== 'wallet' && body.buckets?.includes('buyer')) {
77
+ await assertSelectedWallet(ctx, context.selectedAddress, wallet, 'buyer');
78
+ }
79
+ }
80
+ return await run((request.body ?? {}), async (label, hash) => {
81
+ if (hash)
82
+ ctx.invalidate();
83
+ await report(label, hash);
84
+ // Local position history is best-effort bookkeeping: an RPC hiccup or a
85
+ // full disk must not abort a multi-transaction action whose step already confirmed.
86
+ if (hash) {
87
+ try {
88
+ await context.rememberTransaction?.(hash);
89
+ }
90
+ catch (error) {
91
+ console.warn(`[ants] could not record transaction ${hash}: ${describeError(error)}`);
92
+ }
93
+ }
94
+ });
95
+ }
96
+ finally {
97
+ ctx.invalidate();
98
+ }
99
+ }, ctx.address);
42
100
  return { ok: true, data: job };
43
101
  }
44
102
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -3,6 +3,9 @@ import type { AbstractSigner } from 'ethers';
3
3
  import { AntsContext, type AntsChainConfig } from './service/context.js';
4
4
  export interface AntsServerOptions {
5
5
  port: number;
6
+ /** Browser wallet signing (default). Set false only for explicit local service test harnesses. */
7
+ browserWallet?: boolean;
8
+ onAuthorize?: () => Promise<void>;
6
9
  host?: string;
7
10
  /** Node data directory holding the identity wallet (default ~/.antseed). */
8
11
  dataDir?: string;
@@ -13,14 +16,19 @@ export interface AntsServerOptions {
13
16
  /** Explicit signer/address; skips loading the identity from disk. */
14
17
  signer?: AbstractSigner;
15
18
  address?: string;
19
+ selectedAddress?: string;
16
20
  /** Serve a read-only dashboard for `address` without a signer. */
17
21
  readOnly?: boolean;
22
+ /** Notify the host after an action finishes, including failed actions. */
23
+ onActionFinished?: () => void;
18
24
  }
19
25
  export interface AntsServer {
20
26
  app: FastifyInstance;
21
27
  token: string;
22
28
  url: string;
23
29
  context: AntsContext;
30
+ readonly busy: boolean;
31
+ pauseWrites(): void;
24
32
  listen(): Promise<string>;
25
33
  close(): Promise<void>;
26
34
  }
package/dist/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { randomBytes } from 'node:crypto';
2
2
  import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- import { readFile } from 'node:fs/promises';
4
+ import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
5
5
  import { homedir } from 'node:os';
6
6
  import Fastify from 'fastify';
7
7
  import fastifyCors from '@fastify/cors';
@@ -9,7 +9,9 @@ import fastifyStatic from '@fastify/static';
9
9
  import { loadOrCreateIdentity, resolveChainConfig } from '@antseed/node';
10
10
  import { AntsContext } from './service/context.js';
11
11
  import { JobRunner } from './jobs.js';
12
- import { registerRoutes } from './routes.js';
12
+ import { assertSelectedWallet, registerRoutes } from './routes.js';
13
+ import { BrowserSigning } from './browser-signer.js';
14
+ import { getAddress, ZeroAddress, id as eventId } from 'ethers';
13
15
  import { ViewCache } from './view-cache.js';
14
16
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
17
  async function readCryptoOverrides(configPath) {
@@ -30,12 +32,18 @@ export async function resolveAntsChain(configPath, env = process.env) {
30
32
  }
31
33
  export async function createAntsServer(options) {
32
34
  const host = options.host ?? '127.0.0.1';
35
+ const browserWallet = options.browserWallet !== false;
36
+ const selectedAddress = options.selectedAddress ? getAddress(options.selectedAddress) : undefined;
37
+ if (selectedAddress === ZeroAddress)
38
+ throw new Error('Select a non-zero account address.');
39
+ if (selectedAddress && !browserWallet)
40
+ throw new Error('Account selection requires browser wallet signing.');
33
41
  const dataDir = options.dataDir ?? path.join(homedir(), '.antseed');
34
42
  const configPath = options.configPath ?? path.join(dataDir, 'config.json');
35
43
  const chain = options.chain ?? await resolveAntsChain(configPath);
36
- let signer = options.signer;
37
- let address = options.address;
38
- if (!signer && !options.readOnly) {
44
+ let signer = browserWallet ? undefined : options.signer;
45
+ let address = selectedAddress ?? options.address;
46
+ if (!signer && !options.readOnly && !browserWallet) {
39
47
  const identity = await loadOrCreateIdentity(dataDir);
40
48
  signer = identity.wallet;
41
49
  address = identity.wallet.address;
@@ -43,12 +51,34 @@ export async function createAntsServer(options) {
43
51
  if (!address)
44
52
  throw new Error('An address is required for a read-only dashboard.');
45
53
  const readOnly = !signer;
54
+ const browserSigning = browserWallet ? new BrowserSigning(chain.evmChainId) : undefined;
46
55
  const context = new AntsContext({ chain, address, ...(signer ? { signer } : {}) });
56
+ if (browserSigning && !selectedAddress)
57
+ context.address = ZeroAddress;
58
+ const originBuyer = context.buyerAddress;
59
+ /** The buyer account a connected wallet manages: the originating buyer when the wallet is that buyer or its authorized operator, otherwise the wallet itself. */
60
+ const buyerAccountFor = async (wallet) => {
61
+ if (!wallet || wallet.toLowerCase() === originBuyer.toLowerCase())
62
+ return originBuyer;
63
+ try {
64
+ const operator = await context.deposits()?.getOperator(originBuyer);
65
+ if (operator && operator.toLowerCase() === wallet.toLowerCase())
66
+ return originBuyer;
67
+ }
68
+ catch {
69
+ return originBuyer;
70
+ }
71
+ return wallet;
72
+ };
47
73
  await context.selectRpc();
48
74
  const app = Fastify({ logger: false, bodyLimit: 32 * 1024 * 1024 });
75
+ app.addHook('onSend', async (_request, reply, payload) => {
76
+ reply.header('Content-Security-Policy', "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self' https: wss: http://127.0.0.1:* http://localhost:*; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'");
77
+ return payload;
78
+ });
49
79
  const token = randomBytes(24).toString('hex');
50
- const origin = `http://${host}:${options.port}`;
51
- await app.register(fastifyCors, { origin });
80
+ let origin = `http://${host}:${options.port}`;
81
+ await app.register(fastifyCors, { origin: (requestOrigin, callback) => callback(null, requestOrigin === origin) });
52
82
  // Every API call carries the per-session token the CLI put in the URL fragment;
53
83
  // a page on another origin cannot read it, and a stray tab cannot sign.
54
84
  app.addHook('onRequest', async (request, reply) => {
@@ -71,18 +101,133 @@ export async function createAntsServer(options) {
71
101
  // No web bundle (dev mode); the API is still available for the Vite dev server.
72
102
  }
73
103
  const views = new ViewCache();
74
- registerRoutes(app, { ctx: context, jobs: new JobRunner({ onFinish: () => views.invalidate() }), views, readOnly, dataDir });
75
- const url = `${origin}/#token=${token}`;
104
+ const historyPath = path.join(dataDir, 'ants-activity', `${chain.evmChainId}-positions.json`);
105
+ try {
106
+ const saved = JSON.parse(await readFile(historyPath, 'utf8'));
107
+ for (const [positionId, owner] of saved)
108
+ if (Number.isSafeInteger(positionId) && positionId > 0 && /^0x[0-9a-fA-F]{40}$/.test(owner))
109
+ context.localPositionIds.set(positionId, owner);
110
+ }
111
+ catch (error) {
112
+ if (error.code !== 'ENOENT')
113
+ throw new Error('Could not read local position history. Preserve the file and resolve the error before continuing.', { cause: error });
114
+ }
115
+ const rememberTransaction = async (hash) => {
116
+ const receipt = await context.provider().getTransactionReceipt(hash);
117
+ if (!receipt || receipt.status !== 1)
118
+ return;
119
+ const wallet = receipt.from.toLowerCase();
120
+ const previous = context.positionReadBarriers.get(wallet);
121
+ context.positionReadBarriers.set(wallet, { block: Math.max(previous?.block ?? 0, receipt.blockNumber), at: Math.max(previous?.at ?? 0, Math.floor(Date.now() / 1000)) });
122
+ const ids = receipt.logs.filter(log => log.address.toLowerCase() === chain.sellerPoolsAddress?.toLowerCase() && log.topics.length === 4 && log.topics[0] === eventId('Transfer(address,address,uint256)')).map(log => Number(BigInt(log.topics[3])));
123
+ if (!ids.length)
124
+ return;
125
+ const positions = await context.requirePools().positionsBatch([...new Set(ids)]);
126
+ for (const position of positions)
127
+ if (position.owner.toLowerCase() === context.address.toLowerCase())
128
+ context.localPositionIds.set(position.id, position.owner);
129
+ await mkdir(path.dirname(historyPath), { recursive: true, mode: 0o700 });
130
+ const temporary = `${historyPath}.${randomBytes(8).toString('hex')}.tmp`;
131
+ await writeFile(temporary, JSON.stringify([...context.localPositionIds]), { mode: 0o600 });
132
+ await rename(temporary, historyPath);
133
+ };
134
+ // Browser sessions have no wallet at startup; one journal per chain, with jobs tagged by owner.
135
+ const journalPath = path.join(dataDir, 'ants-activity', browserSigning ? `${chain.evmChainId}-browser.json` : `${chain.evmChainId}-${context.address.toLowerCase()}.json`);
136
+ const jobs = new JobRunner({
137
+ onFinish: () => {
138
+ views.invalidate();
139
+ // A host refresh failure must not turn a successful transaction into a failed job.
140
+ try {
141
+ options.onActionFinished?.();
142
+ }
143
+ catch { /* The host can refresh on focus. */ }
144
+ },
145
+ ...(!readOnly || browserSigning ? { journalPath } : {}),
146
+ });
147
+ registerRoutes(app, { ctx: context, jobs, views, readOnly, dataDir, selectedAddress, originBuyer, browserSigning, onAuthorize: options.onAuthorize, rememberTransaction });
148
+ if (browserSigning) {
149
+ app.post('/api/wallet', async (request, reply) => {
150
+ const body = request.body ?? {};
151
+ try {
152
+ const next = body.address ? getAddress(body.address) : null;
153
+ if (next === ZeroAddress)
154
+ throw new Error('Connect a non-zero wallet address.');
155
+ if (next && body.chainId !== chain.evmChainId)
156
+ throw new Error('Switch your wallet to the dashboard network.');
157
+ const current = await context.signer?.getAddress() ?? null;
158
+ if (next && selectedAddress && !jobs.busy)
159
+ await assertSelectedWallet(context, selectedAddress, next, 'connection');
160
+ // A tab without a wallet (still reconnecting, or a second tab opened from VPR) must not
161
+ // downgrade the connected session; only an explicit disconnect clears the signer.
162
+ if (next === current || (next === null && !body.disconnect)) {
163
+ // A no-op initial sync must not discard reads already loading. An explicit
164
+ // focus refresh still rechecks permissions after the authorization flow.
165
+ if (body.refresh) {
166
+ context.invalidate({ walletOnly: true });
167
+ views.invalidate();
168
+ }
169
+ return { ok: true, data: { changed: false } };
170
+ }
171
+ // Check before cancelling: a refused switch must not poison the running job's signer.
172
+ if (jobs.busy && !(next === null && body.disconnect))
173
+ return reply.code(409).send({ ok: false, error: 'Waiting for the previous wallet action to finish. Submitted transactions are still tracked.' });
174
+ browserSigning.cancel();
175
+ context.address = selectedAddress ?? next ?? context.address;
176
+ if (!selectedAddress)
177
+ context.buyerAddress = await buyerAccountFor(next);
178
+ context.signer = next ? browserSigning.signer(next, context.provider()) : undefined;
179
+ context.invalidate({ walletOnly: true });
180
+ views.invalidate();
181
+ return { ok: true, data: { changed: true } };
182
+ }
183
+ catch (error) {
184
+ if (selectedAddress && !jobs.busy) {
185
+ browserSigning.cancel();
186
+ context.signer = undefined;
187
+ context.invalidate({ walletOnly: true });
188
+ views.invalidate();
189
+ }
190
+ return reply.code(400).send({ ok: false, error: error instanceof Error ? error.message : String(error) });
191
+ }
192
+ });
193
+ app.post('/api/wallet/begin', async (request, reply) => {
194
+ try {
195
+ browserSigning.begin(request.body.id);
196
+ return { ok: true, data: {} };
197
+ }
198
+ catch (error) {
199
+ return reply.code(409).send({ ok: false, error: error instanceof Error ? error.message : String(error) });
200
+ }
201
+ });
202
+ app.get('/api/wallet/request', async () => {
203
+ const transaction = browserSigning.request;
204
+ const job = transaction ? jobs.list(selectedAddress ?? transaction.from).find(job => job.status === 'running') : undefined;
205
+ return { ok: true, data: transaction ? { ...transaction, ...(job ? { jobId: job.id } : {}) } : null };
206
+ });
207
+ app.post('/api/wallet/result', async (request, reply) => {
208
+ try {
209
+ await browserSigning.complete(request.body.id, request.body.hash, request.body.error);
210
+ return { ok: true, data: {} };
211
+ }
212
+ catch (error) {
213
+ return reply.code(400).send({ ok: false, error: error instanceof Error ? error.message : String(error) });
214
+ }
215
+ });
216
+ }
217
+ const sessionUrl = () => `${origin}/#token=${token}`;
76
218
  return {
77
219
  app,
78
220
  token,
79
- url,
221
+ get url() { return sessionUrl(); },
80
222
  context,
223
+ get busy() { return jobs.busy; },
224
+ pauseWrites: () => jobs.pauseWrites(),
81
225
  async listen() {
82
- await app.listen({ port: options.port, host });
83
- return url;
226
+ origin = await app.listen({ port: options.port, host });
227
+ return sessionUrl();
84
228
  },
85
229
  async close() {
230
+ browserSigning?.cancel('Dashboard session ended.');
86
231
  await app.close();
87
232
  },
88
233
  };