hypervibes 0.0.0-stage → 0.4.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 (362) hide show
  1. package/.build/client/assets/_authenticated-C87LKvH0.js +1 -0
  2. package/.build/client/assets/_authenticated.account-D-nTh_fC.js +1 -0
  3. package/.build/client/assets/_authenticated.agents-HwcveLyB.js +1 -0
  4. package/.build/client/assets/_authenticated.agents._agentId-DuE8Lv62.js +1 -0
  5. package/.build/client/assets/_authenticated.agents._agentId.chart-Bb_XkvQx.js +4 -0
  6. package/.build/client/assets/_authenticated.agents._agentId.chat-ClMMKw_N.js +1 -0
  7. package/.build/client/assets/_authenticated.agents._agentId.index-DNJwBwn9.js +1 -0
  8. package/.build/client/assets/_authenticated.agents._agentId.indicators-BmVjLtRI.js +1 -0
  9. package/.build/client/assets/_authenticated.agents._agentId.indicators_._indicatorId-CMqaaFQf.js +2 -0
  10. package/.build/client/assets/_authenticated.agents._agentId.indicators_._indicatorId-DtgkoNV5.js +6 -0
  11. package/.build/client/assets/_authenticated.agents._agentId.memories-O-4f6a4G.js +1 -0
  12. package/.build/client/assets/_authenticated.agents._agentId.memories_._memoryRef-BUPtUcj3.js +1 -0
  13. package/.build/client/assets/_authenticated.agents._agentId.notifications-2lyhXCSk.js +1 -0
  14. package/.build/client/assets/_authenticated.agents._agentId.notifications_._notificationId-Da3ZVT4v.js +1 -0
  15. package/.build/client/assets/_authenticated.agents._agentId.settings-C5cWHoYw.js +1 -0
  16. package/.build/client/assets/_authenticated.agents._agentId.sub-agents-HwcveLyB.js +1 -0
  17. package/.build/client/assets/_authenticated.agents._agentId.sub-agents._subagentId-CZ4MeRy4.js +1 -0
  18. package/.build/client/assets/_authenticated.agents._agentId.sub-agents._subagentId_.runs._runId-dVbo5kMU.js +3 -0
  19. package/.build/client/assets/_authenticated.agents._agentId.sub-agents.index-DeWTOYJD.js +1 -0
  20. package/.build/client/assets/_authenticated.agents._agentId.sub-agents.new-D02TflCE.js +37 -0
  21. package/.build/client/assets/_authenticated.agents._agentId.transactions-D3a8Glgj.js +1 -0
  22. package/.build/client/assets/_authenticated.agents.index-CEqeDEgP.js +1 -0
  23. package/.build/client/assets/_authenticated.agents.new-DLRWK5Uk.js +1 -0
  24. package/.build/client/assets/_authenticated.providers-D0iPLXra.js +1 -0
  25. package/.build/client/assets/agent-chat-page-C5eYFgxw.js +1 -0
  26. package/.build/client/assets/agent-enablement-control-CUzOp9ce.js +1 -0
  27. package/.build/client/assets/agent-events-DC8eDZf3.js +1 -0
  28. package/.build/client/assets/agent-input-aolvZ47U.js +1 -0
  29. package/.build/client/assets/agent-notifications-page-B0mr-Zz8.js +1 -0
  30. package/.build/client/assets/agent-queries-CNMBImun.js +1 -0
  31. package/.build/client/assets/app-DjmsvbUC.css +2 -0
  32. package/.build/client/assets/artifact-content-COO4VTSZ.js +1 -0
  33. package/.build/client/assets/auth-client-K13li9H1.js +3 -0
  34. package/.build/client/assets/call-DxlGie4_.js +31 -0
  35. package/.build/client/assets/ccip-BgPlVPYP.js +1 -0
  36. package/.build/client/assets/chart-contracts-Cr5SFCbE.js +1 -0
  37. package/.build/client/assets/chart-queries-Bpvrgd0-.js +1 -0
  38. package/.build/client/assets/chat-bubble-CAJkT-vL.js +1 -0
  39. package/.build/client/assets/config-dialog-C9x9gKW9.js +1 -0
  40. package/.build/client/assets/contracts-HhAL7Tt7.js +1 -0
  41. package/.build/client/assets/createServerFn-DfZIp2Fu.js +3 -0
  42. package/.build/client/assets/custom-BeqXuIIS.js +5 -0
  43. package/.build/client/assets/decimal-B0DEG-1V.js +1 -0
  44. package/.build/client/assets/esm-BTb2nBdW.js +1 -0
  45. package/.build/client/assets/identicon-Lb9pS4O1.js +1 -0
  46. package/.build/client/assets/index-B4hvjMmI.js +10 -0
  47. package/.build/client/assets/indicator-input-fields-CtmrfVfS.js +1 -0
  48. package/.build/client/assets/indicator-queries-CzZ6u1Mh.js +1 -0
  49. package/.build/client/assets/indicator-renderer-CfccsIt2.js +1 -0
  50. package/.build/client/assets/instrument-label-BZYlWXR5.js +1 -0
  51. package/.build/client/assets/instrument-picker-DLPpryOm.js +1 -0
  52. package/.build/client/assets/journal-decimal-DBvd_Ibi.js +1 -0
  53. package/.build/client/assets/jsx-runtime-CIazjfqY.js +1 -0
  54. package/.build/client/assets/lazyRouteComponent-CJgUa7_r.js +1 -0
  55. package/.build/client/assets/lightweight-charts.production-BiBiFZSH.js +1 -0
  56. package/.build/client/assets/login-MNgYxCOY.js +3 -0
  57. package/.build/client/assets/memory-badge-BbN-DJQi.js +1 -0
  58. package/.build/client/assets/memory-contracts-Doi_Q1XJ.js +1 -0
  59. package/.build/client/assets/memory-queries-BttL580R.js +1 -0
  60. package/.build/client/assets/model-picker-YCQNNmyw.js +1 -0
  61. package/.build/client/assets/notification-queries-B12DG3aS.js +1 -0
  62. package/.build/client/assets/preload-helper-Czpn1I53.js +1 -0
  63. package/.build/client/assets/provider-logo-Ddb77aBD.js +1 -0
  64. package/.build/client/assets/provider-queries-DxPwhDOU.js +1 -0
  65. package/.build/client/assets/query-nvK_95Jo.js +1 -0
  66. package/.build/client/assets/random-uuid-DJR3ygJS.js +1 -0
  67. package/.build/client/assets/react-dom-C6bOPxes.js +1 -0
  68. package/.build/client/assets/risk-queries-D_6PHwus.js +1 -0
  69. package/.build/client/assets/run-subagent-dialog-B4yQe9T9.js +1 -0
  70. package/.build/client/assets/secp256k1-BbZnIgDP.js +1 -0
  71. package/.build/client/assets/setup-checklist-CUW-K484.js +1 -0
  72. package/.build/client/assets/sha2-hT-Q4pur.js +1 -0
  73. package/.build/client/assets/subagent-enabled-toggle-Bk5wfScg.js +1 -0
  74. package/.build/client/assets/subagent-input-TQke90I1.js +1 -0
  75. package/.build/client/assets/subagent-mutations-DfsDbmFu.js +1 -0
  76. package/.build/client/assets/subagent-queries-DVv5JCfs.js +1 -0
  77. package/.build/client/assets/subagent-run-history-D55Uh5VK.js +1 -0
  78. package/.build/client/assets/toggle-timestamp-B50FTPmA.js +1 -0
  79. package/.build/client/assets/useBaseQuery-Bxruo_mV.js +1 -0
  80. package/.build/client/assets/useMutation-DrF53EQG.js +1 -0
  81. package/.build/client/assets/useQuery-BMSU16jY.js +1 -0
  82. package/.build/client/assets/useRouter-c0I1aURm.js +1 -0
  83. package/.build/client/assets/useSelector-ERD9RroG.js +2 -0
  84. package/.build/client/assets/useSuspenseQuery-vODFwDb8.js +1 -0
  85. package/.build/client/assets/utils-Bpv4vmSW.js +1 -0
  86. package/.build/client/assets/worker-triggers-DtXyn40O.js +1 -0
  87. package/.build/server/assets/_authenticated-Bch0_2QH.js +264 -0
  88. package/.build/server/assets/_authenticated-DGV5cZYE.js +22 -0
  89. package/.build/server/assets/_authenticated.account-6qu6oQ1y.js +685 -0
  90. package/.build/server/assets/_authenticated.agents-DYDnQxli.js +5 -0
  91. package/.build/server/assets/_authenticated.agents._agentId-4HvB3mhd.js +17 -0
  92. package/.build/server/assets/_authenticated.agents._agentId-Cl608F1T.js +260 -0
  93. package/.build/server/assets/_authenticated.agents._agentId-G2jAHjma.js +15 -0
  94. package/.build/server/assets/_authenticated.agents._agentId.chart-BIA8wy73.js +2644 -0
  95. package/.build/server/assets/_authenticated.agents._agentId.chart-D4aj8Qy9.js +22 -0
  96. package/.build/server/assets/_authenticated.agents._agentId.chat-ClsVle4g.js +13 -0
  97. package/.build/server/assets/_authenticated.agents._agentId.chat-JV3FDsTp.js +18 -0
  98. package/.build/server/assets/_authenticated.agents._agentId.index-Ct4kbu2f.js +1044 -0
  99. package/.build/server/assets/_authenticated.agents._agentId.index-DJgrupvW.js +18 -0
  100. package/.build/server/assets/_authenticated.agents._agentId.indicators-DrKd0aP5.js +184 -0
  101. package/.build/server/assets/_authenticated.agents._agentId.indicators-wiVaY8fW.js +18 -0
  102. package/.build/server/assets/_authenticated.agents._agentId.indicators_._indicatorId-C4Ox2R-a.js +25 -0
  103. package/.build/server/assets/_authenticated.agents._agentId.indicators_._indicatorId-D8Q0hCW0.js +489 -0
  104. package/.build/server/assets/_authenticated.agents._agentId.memories-BUTyVLYy.js +42 -0
  105. package/.build/server/assets/_authenticated.agents._agentId.memories-E8-nSEMT.js +362 -0
  106. package/.build/server/assets/_authenticated.agents._agentId.memories_._memoryRef-C-SC6wzq.js +14 -0
  107. package/.build/server/assets/_authenticated.agents._agentId.memories_._memoryRef-ZCrdrc8C.js +490 -0
  108. package/.build/server/assets/_authenticated.agents._agentId.notifications-DQeQqTzh.js +14 -0
  109. package/.build/server/assets/_authenticated.agents._agentId.notifications-DlFyYyHh.js +16 -0
  110. package/.build/server/assets/_authenticated.agents._agentId.notifications_._notificationId-B0RosY_R.js +15 -0
  111. package/.build/server/assets/_authenticated.agents._agentId.notifications_._notificationId-C1NikQ9e.js +13 -0
  112. package/.build/server/assets/_authenticated.agents._agentId.settings-DDwjT3Ui.js +42 -0
  113. package/.build/server/assets/_authenticated.agents._agentId.settings-PEzEvOfo.js +751 -0
  114. package/.build/server/assets/_authenticated.agents._agentId.sub-agents-z34-J3Tu.js +5 -0
  115. package/.build/server/assets/_authenticated.agents._agentId.sub-agents._subagentId-D-6TOi1U.js +1371 -0
  116. package/.build/server/assets/_authenticated.agents._agentId.sub-agents._subagentId-DipzVdnr.js +13 -0
  117. package/.build/server/assets/_authenticated.agents._agentId.sub-agents._subagentId_.runs._runId-BZR3VLV7.js +610 -0
  118. package/.build/server/assets/_authenticated.agents._agentId.sub-agents._subagentId_.runs._runId-DsYJKfGm.js +12 -0
  119. package/.build/server/assets/_authenticated.agents._agentId.sub-agents.index-BF8Cuzcr.js +231 -0
  120. package/.build/server/assets/_authenticated.agents._agentId.sub-agents.index-D2x0qCnt.js +12 -0
  121. package/.build/server/assets/_authenticated.agents._agentId.sub-agents.new-CYm_vuDD.js +13 -0
  122. package/.build/server/assets/_authenticated.agents._agentId.sub-agents.new-CiVShIka.js +497 -0
  123. package/.build/server/assets/_authenticated.agents._agentId.transactions-BC_XfGqw.js +95 -0
  124. package/.build/server/assets/_authenticated.agents._agentId.transactions-WtBW3xmh.js +495 -0
  125. package/.build/server/assets/_authenticated.agents.index-C8zmu8T8.js +78 -0
  126. package/.build/server/assets/_authenticated.agents.new-Bt-tBR47.js +302 -0
  127. package/.build/server/assets/_authenticated.providers-C0pb-ujV.js +672 -0
  128. package/.build/server/assets/_tanstack-start-manifest_v-Baw5u9sk.js +354 -0
  129. package/.build/server/assets/account-XvMwzRXh.js +66 -0
  130. package/.build/server/assets/account-queries-AJJVkLAV.js +32 -0
  131. package/.build/server/assets/agent-chat-page-DChiz8KQ.js +686 -0
  132. package/.build/server/assets/agent-enablement-control-C90f0uIb.js +143 -0
  133. package/.build/server/assets/agent-events-DK9Yz5__.js +217 -0
  134. package/.build/server/assets/agent-notifications-page-BdyKAyds.js +276 -0
  135. package/.build/server/assets/agent-queries-Cmx8RiUx.js +51 -0
  136. package/.build/server/assets/agents-CZq-0mna.js +106 -0
  137. package/.build/server/assets/agents-CfjmtW7A.js +278 -0
  138. package/.build/server/assets/artifact-content-B6uHmPz7.js +35 -0
  139. package/.build/server/assets/artifacts-HtLwHs8q.js +42 -0
  140. package/.build/server/assets/auth-DTikZAVz.js +12 -0
  141. package/.build/server/assets/auth-client-Vb3O0v7P.js +1897 -0
  142. package/.build/server/assets/auth-user-DkLo8ojH.js +108 -0
  143. package/.build/server/assets/chart-queries-Bc3AfsEb.js +109 -0
  144. package/.build/server/assets/charts-C4dKuwTJ.js +130 -0
  145. package/.build/server/assets/chat-bubble-ik3itVbx.js +109 -0
  146. package/.build/server/assets/config-dialog-9gSAjwwT.js +55 -0
  147. package/.build/server/assets/contracts-CG-nZuYJ.js +155 -0
  148. package/.build/server/assets/createServerRpc-DNqhdU4z.js +12 -0
  149. package/.build/server/assets/decimal-BthtZ77w.js +97 -0
  150. package/.build/server/assets/empty-plugin-adapters-MOWBbCMw.js +5 -0
  151. package/.build/server/assets/errors-DaZqUftX.js +151 -0
  152. package/.build/server/assets/gateway-CHkruO_a.js +193 -0
  153. package/.build/server/assets/identicon-CyawcVnx.js +41 -0
  154. package/.build/server/assets/indicator-input-fields-bzuhIh6t.js +75 -0
  155. package/.build/server/assets/indicator-queries-4dY1-LXx.js +171 -0
  156. package/.build/server/assets/indicator-renderer-B2muPS-8.js +395 -0
  157. package/.build/server/assets/indicators-ENxAHN42.js +192 -0
  158. package/.build/server/assets/insight-contracts-B5rmUDfO.js +14 -0
  159. package/.build/server/assets/instrument-label-C-tTGGsD.js +40 -0
  160. package/.build/server/assets/instrument-picker-CRroLwVq.js +381 -0
  161. package/.build/server/assets/journal-9aE-um9f.js +107 -0
  162. package/.build/server/assets/journal-decimal-Bh9EL029.js +66 -0
  163. package/.build/server/assets/login-BsEFUvTX.js +125 -0
  164. package/.build/server/assets/memories-2WF2fW1G.js +100 -0
  165. package/.build/server/assets/memory-badge-DVYLTtRR.js +53 -0
  166. package/.build/server/assets/memory-contracts-DQGN2IKV.js +22 -0
  167. package/.build/server/assets/memory-queries--4RbPRrk.js +92 -0
  168. package/.build/server/assets/model-picker-CA1uYb--.js +225 -0
  169. package/.build/server/assets/notification-queries-0CJUkBt9.js +52 -0
  170. package/.build/server/assets/notifications-Cn7BiCyw.js +72 -0
  171. package/.build/server/assets/provider-logo-BRdbOr9I.js +32 -0
  172. package/.build/server/assets/provider-queries-BaZWLw8J.js +78 -0
  173. package/.build/server/assets/providers-CyoN_jgW.js +89 -0
  174. package/.build/server/assets/risk-Bqrb6hKQ.js +34 -0
  175. package/.build/server/assets/risk-queries-JQpByHT2.js +18 -0
  176. package/.build/server/assets/router-Hkr5TH_I.js +419 -0
  177. package/.build/server/assets/run-subagent-dialog-C7iUOZa-.js +59 -0
  178. package/.build/server/assets/setup-DqMlwgNr.js +30 -0
  179. package/.build/server/assets/setup-checklist-BICTmBo2.js +60 -0
  180. package/.build/server/assets/start-C-GPoWRt.js +4 -0
  181. package/.build/server/assets/subagent-enabled-toggle-Djte00oo.js +22 -0
  182. package/.build/server/assets/subagent-input-BHQKs2cW.js +57 -0
  183. package/.build/server/assets/subagent-mutations-dUo3B_SG.js +32 -0
  184. package/.build/server/assets/subagent-queries-sAwBjFxC.js +146 -0
  185. package/.build/server/assets/subagent-run-history-C_xmucO-.js +186 -0
  186. package/.build/server/assets/subagents-CIoilC66.js +180 -0
  187. package/.build/server/assets/toggle-timestamp-CToUVn67.js +28 -0
  188. package/.build/server/assets/trading-contracts-zWq1Hxnb.js +26 -0
  189. package/.build/server/assets/validation-BX-krL0i.js +33 -0
  190. package/.build/server/assets/worker-triggers-CJF5HWzR.js +51 -0
  191. package/.build/server/server.js +7501 -0
  192. package/LICENSE +661 -0
  193. package/README.md +145 -2
  194. package/bin/hypervibes.js +24 -0
  195. package/dist/agents/agent-enablement.js +10 -0
  196. package/dist/agents/agent-input.js +38 -0
  197. package/dist/agents/agent-service.js +1004 -0
  198. package/dist/agents/cancel-task-scope.js +52 -0
  199. package/dist/agents/candle-intervals.js +1 -0
  200. package/dist/agents/default-subagents.js +36 -0
  201. package/dist/agents/execution-context-contracts.js +1 -0
  202. package/dist/agents/execution-context.js +206 -0
  203. package/dist/agents/execution-warnings.js +33 -0
  204. package/dist/agents/orchestrator-insights.js +14 -0
  205. package/dist/agents/run-inspection.js +99 -0
  206. package/dist/agents/subagent-dashboard.js +1 -0
  207. package/dist/agents/subagent-extension.js +156 -0
  208. package/dist/agents/subagent-history.js +5 -0
  209. package/dist/agents/subagent-input.js +73 -0
  210. package/dist/agents/subagent-service.js +1177 -0
  211. package/dist/agents/subagent-templates.js +20 -0
  212. package/dist/agents/template-manifest.js +34 -0
  213. package/dist/agents/templates/basic-analysis.json +40 -0
  214. package/dist/agents/templates/basic-review.json +48 -0
  215. package/dist/agents/templates/basic-trading.json +45 -0
  216. package/dist/agents/templates/indicator-developer.json +16 -0
  217. package/dist/agents/time-guidance.js +29 -0
  218. package/dist/agents/worker-events.js +18 -0
  219. package/dist/agents/worker-inbox.js +28 -0
  220. package/dist/agents/worker-triggers.js +23 -0
  221. package/dist/auth-options.js +98 -0
  222. package/dist/auth-user.js +15 -0
  223. package/dist/auth.js +28 -0
  224. package/dist/cache/svg-logo-cache.js +155 -0
  225. package/dist/canonical.js +13 -0
  226. package/dist/charts/chart-service.js +236 -0
  227. package/dist/charts/contracts.js +118 -0
  228. package/dist/charts/durable-extension.js +27 -0
  229. package/dist/charts/trading-contracts.js +14 -0
  230. package/dist/config.js +85 -0
  231. package/dist/db/agent-schema.js +26 -0
  232. package/dist/db/auth-schema.js +122 -0
  233. package/dist/db/database.js +31 -0
  234. package/dist/db/exchange-schema.js +23 -0
  235. package/dist/db/gateway-schema.js +24 -0
  236. package/dist/db/indicator-schema.js +19 -0
  237. package/dist/db/migrations/20261015221717_auth/migration.sql +62 -0
  238. package/dist/db/migrations/20261015231224_agents/migration.sql +35 -0
  239. package/dist/db/migrations/20261016040641_provider_connections/migration.sql +19 -0
  240. package/dist/db/migrations/20261016061831_trade_journal/migration.sql +48 -0
  241. package/dist/db/migrations/20261016080320_order_execution/migration.sql +62 -0
  242. package/dist/db/migrations/20261016181110_subagents/migration.sql +51 -0
  243. package/dist/db/migrations/20261017222959_research_artifacts/migration.sql +37 -0
  244. package/dist/db/migrations/20261018061531_memories_and_insights/migration.sql +162 -0
  245. package/dist/db/migrations/20261020091156_worker_event_inbox/migration.sql +54 -0
  246. package/dist/db/migrations/20261021051229_chart_workspace/migration.sql +33 -0
  247. package/dist/db/migrations/20261021222116_gateways/migration.sql +15 -0
  248. package/dist/db/migrations/20261022015813_pine_indicators/migration.sql +43 -0
  249. package/dist/db/migrations/20261022101559_notifications/migration.sql +51 -0
  250. package/dist/db/migrations.js +12 -0
  251. package/dist/db/order-provenance-schema.js +17 -0
  252. package/dist/db/order-schema.js +32 -0
  253. package/dist/db/profile-lock.js +12 -0
  254. package/dist/db/provider-schema.js +16 -0
  255. package/dist/db/shared-database.js +128 -0
  256. package/dist/db/subagent-schema.js +79 -0
  257. package/dist/gateway/bridge-service.js +223 -0
  258. package/dist/gateway/gateway-store.js +77 -0
  259. package/dist/gateway/handlers.js +122 -0
  260. package/dist/gateway/telegram/connector.js +115 -0
  261. package/dist/gateway/telegram/transport.js +96 -0
  262. package/dist/hyperliquid/account-info.js +117 -0
  263. package/dist/hyperliquid/account-status.js +64 -0
  264. package/dist/hyperliquid/agent-dashboard.js +56 -0
  265. package/dist/hyperliquid/chart-contracts.js +9 -0
  266. package/dist/hyperliquid/constants.js +25 -0
  267. package/dist/hyperliquid/crypto.js +29 -0
  268. package/dist/hyperliquid/currency-logo.js +7 -0
  269. package/dist/hyperliquid/decimal.js +98 -0
  270. package/dist/hyperliquid/durable-extension.js +39 -0
  271. package/dist/hyperliquid/errors.js +8 -0
  272. package/dist/hyperliquid/exchange.js +118 -0
  273. package/dist/hyperliquid/journal-decimal.js +48 -0
  274. package/dist/hyperliquid/journal-model.js +167 -0
  275. package/dist/hyperliquid/journal-service.js +648 -0
  276. package/dist/hyperliquid/live-dashboard.js +245 -0
  277. package/dist/hyperliquid/logo-cache.js +27 -0
  278. package/dist/hyperliquid/market-charts.js +242 -0
  279. package/dist/hyperliquid/market-snapshot.js +45 -0
  280. package/dist/hyperliquid/orders/order-contracts.js +42 -0
  281. package/dist/hyperliquid/orders/order-math.js +89 -0
  282. package/dist/hyperliquid/orders/order-outcomes.js +74 -0
  283. package/dist/hyperliquid/orders/order-prepare.js +109 -0
  284. package/dist/hyperliquid/orders/order-service.js +432 -0
  285. package/dist/hyperliquid/orders/order-store.js +134 -0
  286. package/dist/hyperliquid/orders/order-tools.js +40 -0
  287. package/dist/hyperliquid/orders/protection.js +35 -0
  288. package/dist/hyperliquid/orders/risk-settings.js +44 -0
  289. package/dist/hyperliquid/orders/trade-admission.js +117 -0
  290. package/dist/hyperliquid/orders/trade-planning.js +60 -0
  291. package/dist/hyperliquid/service.js +529 -0
  292. package/dist/hyperliquid/shared-feeds.js +40 -0
  293. package/dist/hyperliquid/signing.js +89 -0
  294. package/dist/indicators/builtin-catalog.js +59 -0
  295. package/dist/indicators/builtins/adx.pine +22 -0
  296. package/dist/indicators/builtins/atr.pine +11 -0
  297. package/dist/indicators/builtins/bollinger.pine +10 -0
  298. package/dist/indicators/builtins/ema.pine +5 -0
  299. package/dist/indicators/builtins/macd.pine +18 -0
  300. package/dist/indicators/builtins/rsi.pine +18 -0
  301. package/dist/indicators/builtins/sma.pine +5 -0
  302. package/dist/indicators/candle-window.js +36 -0
  303. package/dist/indicators/chart-contracts.js +64 -0
  304. package/dist/indicators/contracts.js +14 -0
  305. package/dist/indicators/durable-extension.js +32 -0
  306. package/dist/indicators/indicator-service.js +300 -0
  307. package/dist/indicators/indicator-store.js +137 -0
  308. package/dist/indicators/normalize.js +149 -0
  309. package/dist/indicators/result-schema.js +79 -0
  310. package/dist/indicators/runtime-wrapper.js +52 -0
  311. package/dist/indicators/runtime.js +201 -0
  312. package/dist/indicators/validation.js +124 -0
  313. package/dist/indicators/worker-queue.js +48 -0
  314. package/dist/initialize-config.js +160 -0
  315. package/dist/main.js +59 -0
  316. package/dist/memory/decision-audit.js +47 -0
  317. package/dist/memory/durable-extension.js +40 -0
  318. package/dist/memory/execution-audit.js +83 -0
  319. package/dist/memory/insight-contracts.js +33 -0
  320. package/dist/memory/insight-service.js +117 -0
  321. package/dist/memory/memory-contracts.js +113 -0
  322. package/dist/memory/memory-service.js +179 -0
  323. package/dist/memory/operations.js +46 -0
  324. package/dist/memory/tool-schemas.js +44 -0
  325. package/dist/memory/validation.js +42 -0
  326. package/dist/notifications/contracts.js +1 -0
  327. package/dist/notifications/delivery.js +11 -0
  328. package/dist/notifications/durable-extension.js +20 -0
  329. package/dist/notifications/notification-service.js +324 -0
  330. package/dist/providers/credential-store.js +86 -0
  331. package/dist/providers/ollama-cloud.js +148 -0
  332. package/dist/providers/provider-logo-url.js +18 -0
  333. package/dist/providers/provider-logo.js +31 -0
  334. package/dist/providers/provider-service.js +295 -0
  335. package/dist/research/artifacts.js +151 -0
  336. package/dist/research/call-queue.js +43 -0
  337. package/dist/research/contracts.js +37 -0
  338. package/dist/research/evidence.js +43 -0
  339. package/dist/research/journal.js +30 -0
  340. package/dist/research/research-service.js +191 -0
  341. package/dist/research/tool-activity.js +49 -0
  342. package/dist/research/tool-response.js +25 -0
  343. package/dist/runtime.js +145 -0
  344. package/dist/web/agent-events.js +418 -0
  345. package/dist/web/app.js +206 -0
  346. package/dist/web/artifact-downloads.js +23 -0
  347. package/dist/web/middleware.js +25 -0
  348. package/dist/web/random-uuid.js +14 -0
  349. package/dist/web/start.js +56 -0
  350. package/package.json +93 -3
  351. package/scripts/check-node.mjs +24 -0
  352. package/static/android-chrome-192x192.png +0 -0
  353. package/static/android-chrome-512x512.png +0 -0
  354. package/static/apple-touch-icon.png +0 -0
  355. package/static/favicon-16x16.png +0 -0
  356. package/static/favicon-32x32.png +0 -0
  357. package/static/favicon.ico +0 -0
  358. package/static/github.svg +3 -0
  359. package/static/hypervibes.png +0 -0
  360. package/static/logo.png +0 -0
  361. package/static/site.webmanifest +1 -0
  362. package/static/telegram.svg +1 -0
@@ -0,0 +1,96 @@
1
+ import { Bot, GrammyError } from "grammy";
2
+ import { NotificationDeliveryError } from "../../notifications/delivery.js";
3
+ import { chunkText } from "../handlers.js";
4
+ /** Telegram caps one message at 4096 characters. */
5
+ export const TELEGRAM_MESSAGE_MAX_CHARS = 4096;
6
+ /** Validates a bot token with Telegram and returns the bot's own username. */
7
+ export async function fetchBotUsername(token) {
8
+ const bot = new Bot(token);
9
+ await bot.init();
10
+ return bot.botInfo.username;
11
+ }
12
+ /** Uses the existing bot's HTTP API without starting another polling endpoint. */
13
+ export async function sendTelegramNotification(token, chatId, text, signal) {
14
+ try {
15
+ const bot = new Bot(token, { client: { timeoutSeconds: 15 } });
16
+ // grammY's Node declarations use abort-controller's older signal type;
17
+ // its HTTP client accepts the native signal's standard abort interface.
18
+ const cancellation = signal;
19
+ return (await bot.api.sendMessage(chatId, text, { link_preview_options: { is_disabled: true } }, cancellation)).message_id;
20
+ }
21
+ catch (error) {
22
+ if (error instanceof GrammyError) {
23
+ if (error.error_code === 429)
24
+ throw new NotificationDeliveryError("Telegram rate limit; retrying", false, (error.parameters.retry_after ?? 1) * 1000);
25
+ throw new NotificationDeliveryError(`Telegram rejected delivery (${error.error_code})`, error.error_code >= 400 && error.error_code < 500);
26
+ }
27
+ throw new NotificationDeliveryError("Telegram is unreachable; retrying");
28
+ }
29
+ }
30
+ /** One grammY long-polling bot: routes messages and sends on behalf of the bridge. */
31
+ export function grammyEndpoint(token, onMessage, logger) {
32
+ // Leave room for grammY's default 30-second long poll, but bound its
33
+ // final, unsignalled offset acknowledgement during stop.
34
+ const bot = new Bot(token, { client: { timeoutSeconds: 45 } });
35
+ const lifetime = new AbortController();
36
+ let polling;
37
+ let stopping;
38
+ const cancellation = (signal) => {
39
+ const combined = signal ? AbortSignal.any([lifetime.signal, signal]) : lifetime.signal;
40
+ combined.throwIfAborted();
41
+ // grammY uses abort-controller's older declarations, but accepts native signals.
42
+ return combined;
43
+ };
44
+ bot.on("message", (ctx) => {
45
+ const text = ctx.msg.text?.trim();
46
+ const chatId = ctx.chat?.id;
47
+ if (text && chatId !== undefined)
48
+ onMessage({ chatId, text, ...(ctx.from?.username ? { fromUsername: ctx.from.username } : {}) });
49
+ });
50
+ // One failing update must not stop polling for the whole bot.
51
+ bot.catch((error) => logger?.warn("Telegram update handling failed", error.error));
52
+ return {
53
+ start(onStarted) {
54
+ if (lifetime.signal.aborted)
55
+ return Promise.resolve();
56
+ polling ??= (async () => {
57
+ try {
58
+ // bot.start creates its polling controller only after starting init.
59
+ // Initialize explicitly so stop can cancel that first request and retries.
60
+ await bot.init(cancellation());
61
+ if (lifetime.signal.aborted)
62
+ return;
63
+ await bot.start({ allowed_updates: ["message"], ...(onStarted ? { onStart: onStarted } : {}) });
64
+ }
65
+ catch (error) {
66
+ if (!lifetime.signal.aborted)
67
+ throw error;
68
+ }
69
+ })();
70
+ return polling;
71
+ },
72
+ stop() {
73
+ stopping ??= (async () => {
74
+ lifetime.abort();
75
+ try {
76
+ // Keep grammY's final offset acknowledgement: skipping it can replay
77
+ // the last delivered update when the next endpoint starts.
78
+ await bot.stop();
79
+ }
80
+ finally {
81
+ // stop does not join start, including its middleware and retry delay.
82
+ // grammY's polling-error sleep is not cancellable; this join can wait
83
+ // for retry_after even though its HTTP requests have been cancelled.
84
+ await polling?.catch(() => undefined);
85
+ }
86
+ })();
87
+ return stopping;
88
+ },
89
+ async sendText(chatId, text, signal) {
90
+ for (const chunk of chunkText(text, TELEGRAM_MESSAGE_MAX_CHARS)) {
91
+ await bot.api.sendMessage(chatId, chunk, {}, cancellation(signal));
92
+ }
93
+ },
94
+ async sendTyping(chatId, signal) { await bot.api.sendChatAction(chatId, "typing", {}, cancellation(signal)); },
95
+ };
96
+ }
@@ -0,0 +1,117 @@
1
+ import { HttpTransport, InfoClient } from "@nktkas/hyperliquid";
2
+ import { compareDecimals, parseDecimal } from "./decimal.js";
3
+ export function accountModeMessage(mode) {
4
+ switch (mode) {
5
+ case "unified": return "";
6
+ case "unregistered":
7
+ return "This wallet is not registered with Hyperliquid yet. Register it before setting up a trading signer, approving a builder fee, transferring funds, or creating agents.";
8
+ case "unsupported":
9
+ return "HyperVibes currently supports Unified Accounts only. Enable Unified Account in Hyperliquid before transferring or creating agents.";
10
+ case "unavailable":
11
+ return "Hyperliquid account mode could not be verified. Transfers are temporarily unavailable.";
12
+ }
13
+ }
14
+ export function accountModeError(mode) {
15
+ return mode === "unified" ? null : accountModeMessage(mode);
16
+ }
17
+ function usdcBalance(balances) {
18
+ const balance = balances.find((entry) => entry.coin.toLowerCase() === "usdc");
19
+ // A registered account simply not holding USDC is zero, not unavailable.
20
+ if (!balance)
21
+ return "0";
22
+ if (typeof balance.total !== "string")
23
+ return null;
24
+ const value = parseDecimal(balance.total);
25
+ if (!value || value.negative)
26
+ return null;
27
+ return balance.total;
28
+ }
29
+ /** Sub-account capacity follows Hyperliquid's volume-based schedule, capped at 50. */
30
+ function subaccountCapacity(cumulativeVolume, existing) {
31
+ const comparison = compareDecimals(cumulativeVolume, "100000");
32
+ if (comparison === null)
33
+ return null;
34
+ if (comparison < 0)
35
+ return "0 remaining of 0 total";
36
+ // One additional account per $100M of volume above the first $100k.
37
+ const additional = wholeQuotientMinus(cumulativeVolume);
38
+ const limit = Math.min(10 + additional, 50);
39
+ const remaining = Math.max(limit - existing, 0);
40
+ return `${remaining} remaining of ${limit} total`;
41
+ }
42
+ function wholeQuotientMinus(volume) {
43
+ const separator = volume.indexOf(".");
44
+ const whole = separator === -1 ? volume : volume.slice(0, separator);
45
+ const base = BigInt(whole) - 100000n;
46
+ if (base < 0n)
47
+ return 0;
48
+ return Number(base / 100000000n);
49
+ }
50
+ /**
51
+ * Loads the wallet's main account and owned sub-accounts with their spot USDC
52
+ * balances, mirroring the legacy application's unified-account checks.
53
+ */
54
+ export async function loadOwnedTradingAccounts(transport, walletAddress, options = {}) {
55
+ const mainAddress = walletAddress.toLowerCase();
56
+ const info = new InfoClient({ transport });
57
+ const checkMode = options.checkMode ?? true;
58
+ const [spotState, subaccountsResult, userRole, abstraction] = await Promise.all([
59
+ info.spotClearinghouseState({ user: mainAddress }).then((state) => ({ ok: true, state }), (error) => ({ ok: false, error })),
60
+ info.subAccounts({ user: mainAddress }).then((accounts) => ({ ok: true, accounts }), (error) => ({ ok: false, error })),
61
+ checkMode
62
+ ? info.userRole({ user: mainAddress }).then((role) => ({ ok: true, role }), (error) => ({ ok: false, error }))
63
+ : Promise.resolve({ ok: true, role: { role: "user" } }),
64
+ checkMode
65
+ ? info.userAbstraction({ user: mainAddress }).then((mode) => ({ ok: true, mode }), (error) => ({ ok: false, error }))
66
+ : Promise.resolve({ ok: true, mode: "unifiedAccount" }),
67
+ ]);
68
+ const mainBalance = spotState.ok ? usdcBalance(spotState.state.balances) : null;
69
+ const accountMode = userRole.ok && userRole.role.role === "missing"
70
+ ? "unregistered"
71
+ : abstraction.ok && abstraction.mode === "unifiedAccount"
72
+ ? "unified"
73
+ : abstraction.ok
74
+ ? "unsupported"
75
+ : "unavailable";
76
+ let subaccounts = [];
77
+ let subaccountLookupError = null;
78
+ if (subaccountsResult.ok) {
79
+ subaccounts = (subaccountsResult.accounts ?? [])
80
+ .filter((account) => account.master.toLowerCase() === mainAddress)
81
+ .map((account) => ({
82
+ name: account.name || null,
83
+ address: account.subAccountUser.toLowerCase(),
84
+ // Hyperliquid omits spotState entirely for never-funded sub-accounts.
85
+ balance: usdcBalance(account.spotState?.balances ?? []),
86
+ }));
87
+ }
88
+ else {
89
+ subaccountLookupError = "Hyperliquid sub-account data is temporarily unavailable.";
90
+ }
91
+ const lookupError = accountMode === "unregistered"
92
+ ? null
93
+ : spotState.ok || mainBalance !== null
94
+ ? subaccountLookupError
95
+ : "Hyperliquid account data is temporarily unavailable.";
96
+ let subaccountCapacityText = null;
97
+ if (options.includeCapacity && accountMode === "unified") {
98
+ try {
99
+ const rateLimit = await info.userRateLimit({ user: mainAddress });
100
+ subaccountCapacityText = subaccountCapacity(rateLimit.cumVlm, subaccounts.length);
101
+ }
102
+ catch { /* Capacity is advisory; the page still renders without it. */ }
103
+ }
104
+ return {
105
+ mainAddress,
106
+ mainBalance,
107
+ subaccounts,
108
+ subaccountCapacity: subaccountCapacityText,
109
+ lookupError,
110
+ accountMode,
111
+ };
112
+ }
113
+ /** Looks up the current builder-fee maximum for a user, in tenths of a bp. */
114
+ export async function maxBuilderFee(transport, user, builder, signal) {
115
+ const info = new InfoClient({ transport });
116
+ return info.maxBuilderFee({ user: user, builder: builder }, signal);
117
+ }
@@ -0,0 +1,64 @@
1
+ import { InfoClient } from "@nktkas/hyperliquid";
2
+ import { dashboardOrders, dashboardPerps, dashboardSpot } from "./agent-dashboard.js";
3
+ function perpetualOrder(coin) { return !coin.startsWith("@") && !coin.includes("/"); }
4
+ /** A bounded-age read of the shared feed, repaired without modifying its state. */
5
+ export async function loadAccountStatus(transport, address, cached, cancellation) {
6
+ const now = Date.now();
7
+ const result = {
8
+ address, scope: "main-dex-perpetuals-and-spot-usdc", observedAt: now, accountAbstraction: null,
9
+ perpEquity: cached?.perpEquity ?? null, positions: cached?.positions ?? null,
10
+ spotUsdc: cached?.spotUsdc ?? null, spotUsdcHold: cached?.spotUsdcHold ?? null,
11
+ orders: cached?.orders?.filter((order) => perpetualOrder(order.coin)) ?? null,
12
+ sections: {
13
+ perps: { updatedAt: null, fresh: false, source: "unavailable" },
14
+ spot: { updatedAt: null, fresh: false, source: "unavailable" },
15
+ orders: { updatedAt: null, fresh: false, source: "unavailable" },
16
+ mode: { updatedAt: null, fresh: false, source: "unavailable" },
17
+ }, errors: [],
18
+ };
19
+ if (!address) {
20
+ result.errors.push("No trading account is assigned to this Agent.");
21
+ return result;
22
+ }
23
+ for (const section of ["perps", "spot", "orders"]) {
24
+ const state = cached?.live?.sections[section];
25
+ if (state?.updatedAt !== null && state?.updatedAt !== undefined) {
26
+ const complete = section === "perps" ? result.perpEquity !== null && result.positions !== null
27
+ : section === "spot" ? result.spotUsdc !== null && result.spotUsdcHold !== null : result.orders !== null;
28
+ result.sections[section] = { updatedAt: state.updatedAt, fresh: complete && state.fresh && cached?.live?.status === "connected" && now - state.updatedAt <= 30_000, source: "live" };
29
+ }
30
+ }
31
+ const client = new InfoClient({ transport });
32
+ const user = address;
33
+ const signal = AbortSignal.any([AbortSignal.timeout(8_000), ...(cancellation ? [cancellation] : [])]);
34
+ const errors = {
35
+ perps: "Perpetual balances and positions are unavailable; any retained values are stale.",
36
+ spot: "Spot USDC balance and holds are unavailable; any retained values are stale.",
37
+ orders: "Open perpetual orders are unavailable; any retained values are stale.",
38
+ mode: "Account mode is unavailable. Do not infer collateral availability from balances or the raw perp summary.",
39
+ };
40
+ await Promise.all(["perps", "spot", "orders", "mode"].map(async (section) => {
41
+ if (result.sections[section].fresh)
42
+ return;
43
+ try {
44
+ if (section === "perps")
45
+ Object.assign(result, dashboardPerps(await client.clearinghouseState({ user, dex: "" }, signal)));
46
+ else if (section === "spot")
47
+ Object.assign(result, dashboardSpot(await client.spotClearinghouseState({ user }, signal)));
48
+ else if (section === "mode")
49
+ result.accountAbstraction = await client.userAbstraction({ user }, signal);
50
+ else {
51
+ const orders = await client.frontendOpenOrders({ user, dex: "" }, signal);
52
+ result.orders = dashboardOrders(orders.filter((order) => perpetualOrder(order.coin))).orders;
53
+ }
54
+ result.sections[section] = { updatedAt: Date.now(), fresh: true, source: "http" };
55
+ }
56
+ catch {
57
+ if (cancellation?.aborted)
58
+ throw new Error("Account status request aborted");
59
+ result.errors.push(errors[section]);
60
+ }
61
+ }));
62
+ result.observedAt = Date.now();
63
+ return result;
64
+ }
@@ -0,0 +1,56 @@
1
+ import { InfoClient } from "@nktkas/hyperliquid";
2
+ import { compareDecimals } from "./decimal.js";
3
+ export function dashboardPerps(state) {
4
+ return {
5
+ perpEquity: state.marginSummary.accountValue,
6
+ positions: state.assetPositions.filter(({ position }) => {
7
+ const size = compareDecimals(position.szi, "0");
8
+ return size !== null && size !== 0;
9
+ }).map(({ position: p }) => ({ coin: p.coin, size: p.szi, entryPrice: p.entryPx, unrealizedPnl: p.unrealizedPnl, liquidationPrice: p.liquidationPx, leverage: p.leverage.value })),
10
+ };
11
+ }
12
+ export function dashboardSpot(state) {
13
+ const usdc = state.balances.find((balance) => balance.coin === "USDC");
14
+ return { spotUsdc: usdc?.total ?? "0", spotUsdcHold: usdc ? usdc.hold ?? null : "0" };
15
+ }
16
+ export function dashboardOrders(orders) {
17
+ const convert = (order) => ({ id: order.oid, coin: order.coin, side: order.side === "B" ? "Buy" : "Sell", size: order.sz, price: order.limitPx, type: order.orderType,
18
+ ...(Number.isFinite(order.timestamp) ? { timestamp: order.timestamp } : {}),
19
+ ...(order.isTrigger ? { triggerPrice: order.triggerPx } : {}), ...(order.isPositionTpsl ? { positionTpsl: true } : {}),
20
+ ...(order.children?.length ? { children: order.children.map(convert) } : {}), });
21
+ return { orders: orders.map(convert) };
22
+ }
23
+ /** Read-only main-DEX snapshots. No signer, persistence, or trading authority. */
24
+ export async function loadAgentDashboard(transport, address, cancellation) {
25
+ const result = { address, accountAbstraction: null, fetchedAt: Date.now(), perpEquity: null, spotUsdc: null, positions: null, orders: null, errors: [] };
26
+ if (!address)
27
+ return result;
28
+ const client = new InfoClient({ transport });
29
+ const user = address;
30
+ const signal = AbortSignal.any([AbortSignal.timeout(8_000), ...(cancellation ? [cancellation] : [])]);
31
+ const [perps, spot, orders, mode] = await Promise.allSettled([
32
+ client.clearinghouseState({ user }, signal),
33
+ client.spotClearinghouseState({ user }, signal),
34
+ client.frontendOpenOrders({ user }, signal),
35
+ client.userAbstraction({ user }, signal),
36
+ ]);
37
+ if (perps.status === "fulfilled") {
38
+ Object.assign(result, dashboardPerps(perps.value));
39
+ }
40
+ else
41
+ result.errors.push("Perpetual balances and positions are temporarily unavailable.");
42
+ if (spot.status === "fulfilled")
43
+ Object.assign(result, dashboardSpot(spot.value));
44
+ else
45
+ result.errors.push("Spot USDC balance is temporarily unavailable.");
46
+ if (orders.status === "fulfilled")
47
+ Object.assign(result, dashboardOrders(orders.value));
48
+ else
49
+ result.errors.push("Open orders are temporarily unavailable.");
50
+ if (mode.status === "fulfilled")
51
+ result.accountAbstraction = mode.value;
52
+ else
53
+ result.errors.push("Account mode is temporarily unavailable; total equity cannot be determined.");
54
+ result.fetchedAt = Date.now();
55
+ return result;
56
+ }
@@ -0,0 +1,9 @@
1
+ export const chartIntervals = ["1m", "5m", "15m", "1h", "4h", "1d"];
2
+ export const intervalMillis = { "1m": 60_000, "5m": 300_000, "15m": 900_000, "1h": 3_600_000, "4h": 14_400_000, "1d": 86_400_000 };
3
+ export function isChartInterval(value) { return chartIntervals.some((interval) => interval === value); }
4
+ export function mergeChartCandles(previous, incoming) {
5
+ const values = new Map(previous.map((candle) => [candle.time, candle]));
6
+ for (const candle of incoming)
7
+ values.set(candle.time, candle);
8
+ return [...values.values()].sort((a, b) => a.time - b.time);
9
+ }
@@ -0,0 +1,25 @@
1
+ /** Mainnet-only Hyperliquid constants shared by server code and templates. */
2
+ /** The only builder fee recipient the server accepts and submits. */
3
+ export const BUILDER_RECIPIENT = "0x2ebba955c61116e1c249efb1e39d25cb4a79ea05";
4
+ /** Builder fee limits in whole basis points, stored as tenths of a basis point. */
5
+ export const MIN_BUILDER_FEE_BPS = 1;
6
+ export const MAX_BUILDER_FEE_BPS = 10;
7
+ export const DEFAULT_BUILDER_FEE_BPS = 5;
8
+ export const BUILDER_FEE_BPS_TO_TENTHS = 10;
9
+ /** The maximum builder fee Hyperliquid allows this builder, in tenths of a bp. */
10
+ export const MAX_BUILDER_FEE_TENTHS_OF_BP = MAX_BUILDER_FEE_BPS * BUILDER_FEE_BPS_TO_TENTHS;
11
+ /** The maxFeeRate string that revokes the builder fee approval. */
12
+ export const REVOKED_BUILDER_FEE_RATE = "0.00%";
13
+ /** Name recorded with Hyperliquid for every HyperVibes trading signer. */
14
+ export const USER_API_WALLET_NAME = "HyperVibes";
15
+ /** Arbitrum One: the chain every Hyperliquid action signature must target. */
16
+ export const SIGNATURE_CHAIN_ID = 42_161;
17
+ export const SIGNATURE_CHAIN_HEX = "0xa4b1";
18
+ /** Hyperliquid mainnet API endpoints. */
19
+ export const HYPERLIQUID_API_URL = "https://api.hyperliquid.xyz";
20
+ /** Approvals of trading signers expire on Hyperliquid after 180 days. */
21
+ export const API_WALLET_APPROVAL_MS = 180 * 24 * 60 * 60 * 1000;
22
+ /** `vt-` prefix plus at most 13 characters keeps subaccount names within Hyperliquid's limit. */
23
+ export function agentSubaccountName(displayName) {
24
+ return `vt-${displayName.trim().slice(0, 13).trimEnd()}`;
25
+ }
@@ -0,0 +1,29 @@
1
+ import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
2
+ const NONCE_LENGTH = 12;
3
+ const TAG_LENGTH = 16;
4
+ const KEY_LENGTH = 32;
5
+ /** Generates a fresh secp256k1 private key in Hyperliquid's `0x…` hex form. */
6
+ export function generateWalletPrivateKey() {
7
+ return `0x${randomBytes(KEY_LENGTH).toString("hex")}`;
8
+ }
9
+ /** Encrypts a secret with AES-256-GCM: `nonce ‖ ciphertext ‖ tag`. */
10
+ export function encryptSecret(key, plaintext) {
11
+ const nonce = randomBytes(NONCE_LENGTH);
12
+ const cipher = createCipheriv("aes-256-gcm", key.bytes, nonce);
13
+ const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
14
+ return new Uint8Array(Buffer.concat([nonce, ciphertext, cipher.getAuthTag()]));
15
+ }
16
+ /**
17
+ * Decrypts an AES-256-GCM secret. Throws on truncation, tampering or a
18
+ * mismatched key so callers never silently accept corrupted credentials.
19
+ */
20
+ export function decryptSecret(key, sealed) {
21
+ if (sealed.length < NONCE_LENGTH + TAG_LENGTH)
22
+ throw new Error("Encrypted secret is truncated");
23
+ const decipher = createDecipheriv("aes-256-gcm", key.bytes, sealed.subarray(0, NONCE_LENGTH));
24
+ decipher.setAuthTag(sealed.subarray(sealed.length - TAG_LENGTH));
25
+ return Buffer.concat([
26
+ decipher.update(sealed.subarray(NONCE_LENGTH, sealed.length - TAG_LENGTH)),
27
+ decipher.final(),
28
+ ]).toString("utf8");
29
+ }
@@ -0,0 +1,7 @@
1
+ /** Spot identifiers are intentionally not resolved by the perpetual logo feature. */
2
+ export function isPerpetualLogoSymbol(symbol) {
3
+ return symbol.length <= 64 && /^(?:[A-Za-z0-9_-]+:)?[A-Za-z0-9_-]+$/.test(symbol);
4
+ }
5
+ export function currencyLogoUrl(symbol) {
6
+ return isPerpetualLogoSymbol(symbol) ? `/currency/${encodeURIComponent(symbol)}.svg` : null;
7
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Minimal string-decimal helpers for display-only exchange amounts. Values
3
+ * arriving from Hyperliquid are kept as strings and combined with integer
4
+ * arithmetic; these are never used for signed amounts or order placement.
5
+ */
6
+ /** Splits a plain decimal string like `-12.3400`; returns null when malformed. */
7
+ export function parseDecimal(value) {
8
+ if (!/^-?\d+(?:\.\d+)?$/.test(value) || value.includes("e") || value.includes("E"))
9
+ return null;
10
+ const negative = value.startsWith("-");
11
+ const unsigned = negative ? value.slice(1) : value;
12
+ const separator = unsigned.indexOf(".");
13
+ const whole = separator === -1 ? unsigned : unsigned.slice(0, separator);
14
+ const fraction = separator === -1 ? "" : unsigned.slice(separator + 1);
15
+ return { negative, whole: BigInt(whole), fraction };
16
+ }
17
+ /** Scales two parsed decimals to a common denominator and returns the parts. */
18
+ function commonScale(left, right) {
19
+ const scale = Math.max(left.fraction.length, right.fraction.length);
20
+ const scaleUp = (part) => BigInt(part.negative ? -1 : 1) * (part.whole * 10n ** BigInt(scale) + BigInt(part.fraction.padEnd(scale, "0") || "0"));
21
+ return { leftScaled: scaleUp(left), rightScaled: scaleUp(right), scale };
22
+ }
23
+ /** Adds two plain decimal strings; returns null when either is malformed. */
24
+ export function addDecimals(left, right) {
25
+ const parsedLeft = parseDecimal(left);
26
+ const parsedRight = parseDecimal(right);
27
+ if (!parsedLeft || !parsedRight)
28
+ return null;
29
+ const { leftScaled, rightScaled, scale } = commonScale(parsedLeft, parsedRight);
30
+ const total = leftScaled + rightScaled;
31
+ return formatScaled(total, scale);
32
+ }
33
+ function formatScaled(scaled, scale) {
34
+ const negative = scaled < 0n;
35
+ const absolute = negative ? -scaled : scaled;
36
+ const denominator = 10n ** BigInt(scale);
37
+ const whole = absolute / denominator;
38
+ const fraction = (absolute % denominator).toString().padStart(scale, "0");
39
+ const canonical = fraction.replace(/0+$/, "");
40
+ const body = canonical ? `${whole}.${canonical}` : `${whole}`;
41
+ return negative && absolute !== 0n ? `-${body}` : body;
42
+ }
43
+ /** Compares two plain decimal strings; null when either is malformed. */
44
+ export function compareDecimals(left, right) {
45
+ const parsedLeft = parseDecimal(left);
46
+ const parsedRight = parseDecimal(right);
47
+ if (!parsedLeft || !parsedRight)
48
+ return null;
49
+ const { leftScaled, rightScaled } = commonScale(parsedLeft, parsedRight);
50
+ return leftScaled === rightScaled ? 0 : leftScaled < rightScaled ? -1 : 1;
51
+ }
52
+ /**
53
+ * Formats a plain decimal string with fixed precision (4 places by default),
54
+ * half-up rounding, thousands separators and negatives in parentheses.
55
+ */
56
+ export function formatMoneyText(value, decimalPlaces = 4) {
57
+ if (!value)
58
+ return "-";
59
+ const parsed = parseDecimal(value);
60
+ if (!parsed)
61
+ return "-";
62
+ // Keep one guard digit for exact half-up rounding at the requested precision.
63
+ const guard = BigInt(decimalPlaces + 1);
64
+ const scale = 10n ** guard;
65
+ const scaled = parsed.whole * scale
66
+ + BigInt(parsed.fraction.padEnd(Number(guard), "0").slice(0, Number(guard)) || "0");
67
+ const rounded = (scaled + 5n) / 10n;
68
+ const denominator = 10n ** BigInt(decimalPlaces);
69
+ const whole = rounded / denominator;
70
+ const fraction = (rounded % denominator).toString().padStart(decimalPlaces, "0");
71
+ const grouped = whole.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
72
+ const formatted = `${grouped}.${fraction}`;
73
+ return parsed.negative && rounded !== 0n ? `(${formatted})` : formatted;
74
+ }
75
+ /** Formats an exchange amount for display: exact fraction preserved (padded to
76
+ * at least 2 decimals), thousands separators on the whole part, and negatives in
77
+ * parentheses. Never rounds; prices and sizes are exchange-exact. */
78
+ export function formatAmountText(value) {
79
+ if (!value)
80
+ return "-";
81
+ const parsed = parseDecimal(value);
82
+ if (!parsed)
83
+ return "-";
84
+ const fraction = parsed.fraction.length < 2 ? parsed.fraction.padEnd(2, "0") : parsed.fraction;
85
+ const grouped = parsed.whole.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
86
+ const body = `${grouped}.${fraction}`;
87
+ return parsed.negative ? `(${body})` : body;
88
+ }
89
+ /** Splits formatted money into the whole part and optional decimals. */
90
+ export function moneyParts(value) {
91
+ if (!value)
92
+ return { whole: "-", decimals: null };
93
+ const separator = value.indexOf(".");
94
+ return {
95
+ whole: separator === -1 ? value : value.slice(0, separator),
96
+ decimals: separator === -1 ? null : value.slice(separator + 1),
97
+ };
98
+ }
@@ -0,0 +1,39 @@
1
+ import { Type } from "@earendil-works/pi-ai";
2
+ import { createOrderTools, toolResult } from "./orders/order-tools.js";
3
+ import { MarketSnapshotSchema } from "./market-snapshot.js";
4
+ import { defineExtension, defineTool, section } from "@earendil-works/pi-durable";
5
+ const nullable = Type.Union([Type.String(), Type.Null()]);
6
+ const freshness = Type.Object({ updatedAt: Type.Union([Type.Number(), Type.Null()]), fresh: Type.Boolean(), source: Type.Union([Type.Literal("live"), Type.Literal("http"), Type.Literal("unavailable")]) });
7
+ const AccountStatusSchema = Type.Object({
8
+ address: nullable, scope: Type.Literal("main-dex-perpetuals-and-spot-usdc"), observedAt: Type.Number(),
9
+ accountAbstraction: Type.Union([Type.Literal("unifiedAccount"), Type.Literal("portfolioMargin"), Type.Literal("disabled"), Type.Literal("default"), Type.Null()]),
10
+ perpEquity: nullable, spotUsdc: nullable, spotUsdcHold: nullable,
11
+ positions: Type.Union([Type.Array(Type.Object({ coin: Type.String(), size: Type.String(), entryPrice: Type.String(), unrealizedPnl: Type.String(), liquidationPrice: nullable, leverage: Type.Number() })), Type.Null()]),
12
+ orders: Type.Union([Type.Array(Type.Object({ id: Type.Number(), coin: Type.String(), side: Type.String(), size: Type.String(), price: Type.String(), type: Type.String() })), Type.Null()]),
13
+ sections: Type.Object({ perps: freshness, spot: freshness, orders: freshness, mode: freshness }), errors: Type.Array(Type.String()),
14
+ });
15
+ /** Trusted host binding: the model cannot choose an account or supply credentials. */
16
+ export function createHyperliquidExtension(service, userId, agentId, orders) {
17
+ return defineExtension({
18
+ name: "hyperliquid",
19
+ sections: [section("hyperliquid", () => "When get_market_snapshot is selected, fetch fresh data before answering current price/market questions. Report its source and observation time, distinguish mid/mark/oracle from executable quotes, and distinguish this snapshot from older stored research. Missing data is unknown, not zero. Use analyst workers for deeper candle/indicator research, not basic price lookups. Use get_account to read this Agent's assigned Hyperliquid account: main-DEX perpetual positions/orders, spot USDC total and holds, and accountAbstraction (queried for this exact account). Decimal strings preserve exchange precision. Check each section's freshness, timestamps, and errors; null/stale data is not zero or an empty account. In unifiedAccount mode, spot USDC is the single shared balance collateralizing USDC-settled cross-margin perps and used for spot trading; individual perp-DEX balance summaries are not meaningful account equity. In portfolioMargin mode, eligible spot assets and perps share portfolio collateral, but this tool only includes spot USDC, not the whole portfolio. Never conclude the account has zero collateral from perpEquity=0 in either mode. In standard/manual mode, spot and perp balances are separate; do not assume spot USDC automatically collateralizes perps. Do not infer the mode from the application's supported/default mode, or guess if mode lookup failed. Spot total is not available buying power: holds, existing positions, margin requirements, and exposure on other DEXs may constrain it. Do not add spotUsdc and perpEquity into a total in unified/portfolio mode or double-count shared collateral. Report spot USDC explicitly when summarizing the account. Other spot tokens, spot orders, and other DEX positions/orders are outside this view. Order tools place/cancel real orders autonomously on this Agent's assigned account only. Use exact decimal strings and stable unique request_id values. Size is base-asset quantity, not a USDC amount. Main-DEX perps require a minimum order notional of $10 (size × price), in addition to exchange size/tick precision. Check intended notional before submitting; never silently increase the user's intended exposure to satisfy the minimum. Exchange validation is authoritative, including any reduce-only/closing exceptions; do not assume an exception or retry a rejected order unchanged. Reuse the same ID and identical arguments after an interruption; never use a new ID to retry an unknown outcome. Query get_order_request/get_order to reconcile. Unknown/not-found is not rejection or cancellation. Inspect every leg: accepted is not filled; a rejected TP/SL can leave exposure unprotected. Market entries are 0.5%-guarded IOC and can partially fill. Native attached TP/SL activates only on full parent fill (or certain venue margin-cancel paths); manually canceling a partially filled parent also cancels its protection. Triggers use mark prices; market triggers use a 10% guard and may not fully fill. Standalone triggers are fixed-size reduce-only. Cancel-all can remove protective stops and does not close positions. No transfers, leverage changes, or trading on other accounts/DEXs are exposed. Reference: https://hyperliquid.gitbook.io/hyperliquid-docs/trading/account-abstraction-modes")],
20
+ tools: [defineTool({
21
+ name: "get_account",
22
+ description: "Read this Agent's own Hyperliquid account mode, spot USDC total/holds, main-DEX perpetual positions/orders, and raw perp equity summary with per-section freshness. Unified/portfolio accounts use spot collateral; raw perp equity is not account equity. Reuses the live feed with HTTP repair.",
23
+ parameters: Type.Object({}, { additionalProperties: false }),
24
+ replay: "safe",
25
+ structuredOutputSchema: AccountStatusSchema,
26
+ execute: async (_args, _api, context) => {
27
+ const status = await service.agentAccountStatus(userId, agentId, context.abortSignal);
28
+ return toolResult(status);
29
+ },
30
+ }), defineTool({
31
+ name: "get_market_snapshot",
32
+ description: "Read a fresh public Hyperliquid main-DEX perpetual snapshot for one instrument (exact venue symbol, e.g. BTC): mid/mark/oracle prices, mark-based 24h change, volumes, hourly funding and open interest. Read-only; independent of trading permissions. Includes host observation time, not a venue timestamp. Not an executable quote, last trade, or technical-analysis report.",
33
+ parameters: Type.Object({ instrument: Type.String({ minLength: 1, maxLength: 32 }) }, { additionalProperties: false }),
34
+ replay: "safe",
35
+ structuredOutputSchema: MarketSnapshotSchema,
36
+ execute: async (args, _api, context) => toolResult(await service.marketSnapshot(args.instrument, context.abortSignal)),
37
+ }), ...createOrderTools(orders, userId, agentId)],
38
+ });
39
+ }
@@ -0,0 +1,8 @@
1
+ /** Public exchange errors surfaced to users with their HTTP status. Browser-safe. */
2
+ export class HyperliquidError extends Error {
3
+ status;
4
+ constructor(message, status = 400) {
5
+ super(message);
6
+ this.status = status;
7
+ }
8
+ }