@reefclaw/connect 0.1.12 → 0.1.14

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 (391) hide show
  1. package/assets/plugin/audit/mode-transition-audit.d.ts +11 -0
  2. package/assets/plugin/audit/mode-transition-audit.js +29 -0
  3. package/assets/plugin/balance-utils.d.ts +36 -0
  4. package/assets/plugin/balance-utils.js +98 -0
  5. package/assets/plugin/ccxt/binance-ban-gate.d.ts +47 -0
  6. package/assets/plugin/ccxt/binance-ban-gate.js +420 -0
  7. package/assets/plugin/ccxt/binance-private.d.ts +346 -0
  8. package/assets/plugin/ccxt/binance-private.js +1525 -0
  9. package/assets/plugin/ccxt/binance-public.d.ts +34 -0
  10. package/assets/plugin/ccxt/binance-public.js +180 -0
  11. package/assets/plugin/ccxt/intel-public.d.ts +25 -0
  12. package/assets/plugin/ccxt/intel-public.js +80 -0
  13. package/assets/plugin/ccxt/public-market-data-api.d.ts +26 -0
  14. package/assets/plugin/ccxt/public-market-data-api.js +23 -0
  15. package/assets/plugin/config/agent-config-client.d.ts +77 -0
  16. package/assets/plugin/config/agent-config-client.js +188 -0
  17. package/assets/plugin/config/agent-config-poller.d.ts +32 -0
  18. package/assets/plugin/config/agent-config-poller.js +101 -0
  19. package/assets/plugin/config/brackets-config.d.ts +22 -0
  20. package/assets/plugin/config/brackets-config.js +58 -0
  21. package/assets/plugin/config/entitlement-gate.d.ts +51 -0
  22. package/assets/plugin/config/entitlement-gate.js +137 -0
  23. package/assets/plugin/config/gate-store.d.ts +18 -0
  24. package/assets/plugin/config/gate-store.js +61 -0
  25. package/assets/plugin/config/plugin-config-io.d.ts +222 -0
  26. package/assets/plugin/config/plugin-config-io.js +126 -0
  27. package/assets/plugin/config/position-review-config.d.ts +35 -0
  28. package/assets/plugin/config/position-review-config.js +105 -0
  29. package/assets/plugin/config/tool-gate.d.ts +53 -0
  30. package/assets/plugin/config/tool-gate.js +128 -0
  31. package/assets/plugin/config/user-data-stream-config.d.ts +89 -0
  32. package/assets/plugin/config/user-data-stream-config.js +239 -0
  33. package/assets/plugin/connector-supervisor.d.ts +36 -0
  34. package/assets/plugin/connector-supervisor.js +149 -0
  35. package/assets/plugin/exchange-adapter.d.ts +65 -0
  36. package/assets/plugin/exchange-adapter.js +4 -0
  37. package/assets/plugin/index.d.ts +30 -0
  38. package/assets/plugin/index.js +2763 -0
  39. package/assets/plugin/ingest/pending-entry-metadata.d.ts +74 -0
  40. package/assets/plugin/ingest/pending-entry-metadata.js +236 -0
  41. package/assets/plugin/ingest/position-auto-capture.d.ts +171 -0
  42. package/assets/plugin/ingest/position-auto-capture.js +709 -0
  43. package/assets/plugin/ingest/position-decisions-client.d.ts +327 -0
  44. package/assets/plugin/ingest/position-decisions-client.js +306 -0
  45. package/assets/plugin/ingest/readiness-reporter.d.ts +42 -0
  46. package/assets/plugin/ingest/readiness-reporter.js +163 -0
  47. package/assets/plugin/ingest/reconcile-db-vs-exchange.d.ts +51 -0
  48. package/assets/plugin/ingest/reconcile-db-vs-exchange.js +170 -0
  49. package/assets/plugin/ingest/reconciler-cleanup.d.ts +37 -0
  50. package/assets/plugin/ingest/reconciler-cleanup.js +147 -0
  51. package/assets/plugin/ingest/rest-gap-filler.d.ts +191 -0
  52. package/assets/plugin/ingest/rest-gap-filler.js +565 -0
  53. package/assets/plugin/ingest/touched-symbols-store.d.ts +25 -0
  54. package/assets/plugin/ingest/touched-symbols-store.js +96 -0
  55. package/assets/plugin/ingest/trade-store-client.d.ts +40 -0
  56. package/assets/plugin/ingest/trade-store-client.js +125 -0
  57. package/assets/plugin/ingest/ws-ingest.d.ts +43 -0
  58. package/assets/plugin/ingest/ws-ingest.js +126 -0
  59. package/assets/plugin/learning/setup-family.d.ts +21 -0
  60. package/assets/plugin/learning/setup-family.js +103 -0
  61. package/assets/plugin/lifecycle/install-signal-handlers.d.ts +33 -0
  62. package/assets/plugin/lifecycle/install-signal-handlers.js +112 -0
  63. package/assets/plugin/lifecycle/shutdown-coordinator.d.ts +43 -0
  64. package/assets/plugin/lifecycle/shutdown-coordinator.js +131 -0
  65. package/assets/plugin/lifecycle/trading-operation-lock.d.ts +17 -0
  66. package/assets/plugin/lifecycle/trading-operation-lock.js +14 -0
  67. package/assets/plugin/live/bracket-id.d.ts +26 -0
  68. package/assets/plugin/live/bracket-id.js +112 -0
  69. package/assets/plugin/live/bracket-ledger.d.ts +54 -0
  70. package/assets/plugin/live/bracket-ledger.js +267 -0
  71. package/assets/plugin/live/bracket-manager.d.ts +82 -0
  72. package/assets/plugin/live/bracket-manager.js +478 -0
  73. package/assets/plugin/live/bracket-params.d.ts +22 -0
  74. package/assets/plugin/live/bracket-params.js +124 -0
  75. package/assets/plugin/live/bracket-reconciler.d.ts +95 -0
  76. package/assets/plugin/live/bracket-reconciler.js +573 -0
  77. package/assets/plugin/live/bracket-types.d.ts +102 -0
  78. package/assets/plugin/live/bracket-types.js +8 -0
  79. package/assets/plugin/live/deposit-tracker.d.ts +62 -0
  80. package/assets/plugin/live/deposit-tracker.js +97 -0
  81. package/assets/plugin/live/emergency-controls.d.ts +32 -0
  82. package/assets/plugin/live/emergency-controls.js +226 -0
  83. package/assets/plugin/live/exchange-errors.d.ts +12 -0
  84. package/assets/plugin/live/exchange-errors.js +130 -0
  85. package/assets/plugin/live/exchange-info-cache.d.ts +37 -0
  86. package/assets/plugin/live/exchange-info-cache.js +134 -0
  87. package/assets/plugin/live/fact-subscriber.d.ts +78 -0
  88. package/assets/plugin/live/fact-subscriber.js +182 -0
  89. package/assets/plugin/live/fill-price.d.ts +13 -0
  90. package/assets/plugin/live/fill-price.js +37 -0
  91. package/assets/plugin/live/intent-journal.d.ts +42 -0
  92. package/assets/plugin/live/intent-journal.js +122 -0
  93. package/assets/plugin/live/listen-key-manager.d.ts +70 -0
  94. package/assets/plugin/live/listen-key-manager.js +169 -0
  95. package/assets/plugin/live/live-adapter.d.ts +319 -0
  96. package/assets/plugin/live/live-adapter.js +1906 -0
  97. package/assets/plugin/live/live-balance-enricher.d.ts +32 -0
  98. package/assets/plugin/live/live-balance-enricher.js +104 -0
  99. package/assets/plugin/live/live-bracket-api.d.ts +13 -0
  100. package/assets/plugin/live/live-bracket-api.js +20 -0
  101. package/assets/plugin/live/live-state-store.d.ts +194 -0
  102. package/assets/plugin/live/live-state-store.js +450 -0
  103. package/assets/plugin/live/local-signal-service.d.ts +57 -0
  104. package/assets/plugin/live/local-signal-service.js +151 -0
  105. package/assets/plugin/live/local-strategy-evaluator.d.ts +62 -0
  106. package/assets/plugin/live/local-strategy-evaluator.js +131 -0
  107. package/assets/plugin/live/microstructure-assembler.d.ts +54 -0
  108. package/assets/plugin/live/microstructure-assembler.js +148 -0
  109. package/assets/plugin/live/order-poller.d.ts +29 -0
  110. package/assets/plugin/live/order-poller.js +125 -0
  111. package/assets/plugin/live/position-state-store.d.ts +87 -0
  112. package/assets/plugin/live/position-state-store.js +237 -0
  113. package/assets/plugin/live/proposal-decision-listener.d.ts +70 -0
  114. package/assets/plugin/live/proposal-decision-listener.js +292 -0
  115. package/assets/plugin/live/proposal-manager.d.ts +76 -0
  116. package/assets/plugin/live/proposal-manager.js +140 -0
  117. package/assets/plugin/live/rate-limiter.d.ts +47 -0
  118. package/assets/plugin/live/rate-limiter.js +159 -0
  119. package/assets/plugin/live/reconciler.d.ts +39 -0
  120. package/assets/plugin/live/reconciler.js +175 -0
  121. package/assets/plugin/live/setup-buckets.d.ts +7 -0
  122. package/assets/plugin/live/setup-buckets.js +33 -0
  123. package/assets/plugin/live/slippage-tracker.d.ts +45 -0
  124. package/assets/plugin/live/slippage-tracker.js +78 -0
  125. package/assets/plugin/live/stop-watcher.d.ts +67 -0
  126. package/assets/plugin/live/stop-watcher.js +218 -0
  127. package/assets/plugin/live/user-data-active-probe.d.ts +54 -0
  128. package/assets/plugin/live/user-data-active-probe.js +180 -0
  129. package/assets/plugin/live/user-data-stream-controller.d.ts +200 -0
  130. package/assets/plugin/live/user-data-stream-controller.js +579 -0
  131. package/assets/plugin/live/user-data-stream-ws.d.ts +22 -0
  132. package/assets/plugin/live/user-data-stream-ws.js +63 -0
  133. package/assets/plugin/live/user-data-stream.d.ts +243 -0
  134. package/assets/plugin/live/user-data-stream.js +704 -0
  135. package/assets/plugin/logger.d.ts +2 -0
  136. package/assets/plugin/logger.js +2 -0
  137. package/assets/plugin/mfe.d.ts +21 -0
  138. package/assets/plugin/mfe.js +68 -0
  139. package/assets/plugin/onboarding/mode-ladder.d.ts +1 -0
  140. package/assets/plugin/onboarding/mode-ladder.js +3 -0
  141. package/assets/plugin/onboarding/runtime.d.ts +102 -0
  142. package/assets/plugin/onboarding/runtime.js +215 -0
  143. package/assets/plugin/openclaw.plugin.json +92 -0
  144. package/assets/plugin/paper-adapter.d.ts +24 -0
  145. package/assets/plugin/paper-adapter.js +91 -0
  146. package/assets/plugin/persistence/state-manager.d.ts +66 -0
  147. package/assets/plugin/persistence/state-manager.js +222 -0
  148. package/assets/plugin/pinned-plan.d.ts +9 -0
  149. package/assets/plugin/pinned-plan.js +23 -0
  150. package/assets/plugin/portfolio/reentry-tracker.d.ts +36 -0
  151. package/assets/plugin/portfolio/reentry-tracker.js +127 -0
  152. package/assets/plugin/portfolio/wave9-admission.d.ts +67 -0
  153. package/assets/plugin/portfolio/wave9-admission.js +262 -0
  154. package/assets/plugin/portfolio/wave9-policy.d.ts +36 -0
  155. package/assets/plugin/portfolio/wave9-policy.js +183 -0
  156. package/assets/plugin/risk/pre-trade-check.d.ts +38 -0
  157. package/assets/plugin/risk/pre-trade-check.js +345 -0
  158. package/assets/plugin/risk/pre-trade-types.d.ts +60 -0
  159. package/assets/plugin/risk/pre-trade-types.js +3 -0
  160. package/assets/plugin/shadow/shadow-tracker.d.ts +36 -0
  161. package/assets/plugin/shadow/shadow-tracker.js +151 -0
  162. package/assets/plugin/shadow/types.d.ts +42 -0
  163. package/assets/plugin/shadow/types.js +20 -0
  164. package/assets/plugin/shared/indicators-extended.d.ts +52 -0
  165. package/assets/plugin/shared/indicators-extended.js +291 -0
  166. package/assets/plugin/shared/indicators.d.ts +15 -0
  167. package/assets/plugin/shared/indicators.js +114 -0
  168. package/assets/plugin/signals/conditions/registry.d.ts +16 -0
  169. package/assets/plugin/signals/conditions/registry.js +1333 -0
  170. package/assets/plugin/signals/conditions/types.d.ts +1 -0
  171. package/assets/plugin/signals/conditions/types.js +4 -0
  172. package/assets/plugin/signals/direction-rules.d.ts +3 -0
  173. package/assets/plugin/signals/direction-rules.js +24 -0
  174. package/assets/plugin/signals/entry-rules.d.ts +6 -0
  175. package/assets/plugin/signals/entry-rules.js +33 -0
  176. package/assets/plugin/signals/serialize-context.d.ts +4 -0
  177. package/assets/plugin/signals/serialize-context.js +39 -0
  178. package/assets/plugin/signals/stop-rules.d.ts +3 -0
  179. package/assets/plugin/signals/stop-rules.js +48 -0
  180. package/assets/plugin/signals/strategy-adapter.d.ts +47 -0
  181. package/assets/plugin/signals/strategy-adapter.js +209 -0
  182. package/assets/plugin/signals/types.d.ts +1 -0
  183. package/assets/plugin/signals/types.js +8 -0
  184. package/assets/plugin/simulator/exchange-simulator.d.ts +105 -0
  185. package/assets/plugin/simulator/exchange-simulator.js +759 -0
  186. package/assets/plugin/simulator/fill-engine.d.ts +53 -0
  187. package/assets/plugin/simulator/fill-engine.js +280 -0
  188. package/assets/plugin/simulator/paper-market-feed.d.ts +26 -0
  189. package/assets/plugin/simulator/paper-market-feed.js +104 -0
  190. package/assets/plugin/simulator/realistic-fills.d.ts +59 -0
  191. package/assets/plugin/simulator/realistic-fills.js +175 -0
  192. package/assets/plugin/simulator/types.d.ts +228 -0
  193. package/assets/plugin/simulator/types.js +43 -0
  194. package/assets/plugin/strategy/builtin-strategies.d.ts +2 -0
  195. package/assets/plugin/strategy/builtin-strategies.js +113 -0
  196. package/assets/plugin/strategy/condition-registry.d.ts +3 -0
  197. package/assets/plugin/strategy/condition-registry.js +153 -0
  198. package/assets/plugin/strategy/evaluator.d.ts +70 -0
  199. package/assets/plugin/strategy/evaluator.js +98 -0
  200. package/assets/plugin/tools/assessment-validation.d.ts +141 -0
  201. package/assets/plugin/tools/assessment-validation.js +473 -0
  202. package/assets/plugin/tools/attach-brackets.d.ts +39 -0
  203. package/assets/plugin/tools/attach-brackets.js +564 -0
  204. package/assets/plugin/tools/audit-bracket-protection.d.ts +49 -0
  205. package/assets/plugin/tools/audit-bracket-protection.js +683 -0
  206. package/assets/plugin/tools/bracket-control.d.ts +12 -0
  207. package/assets/plugin/tools/bracket-control.js +35 -0
  208. package/assets/plugin/tools/cancel-all-orders.d.ts +9 -0
  209. package/assets/plugin/tools/cancel-all-orders.js +8 -0
  210. package/assets/plugin/tools/cancel-order.d.ts +14 -0
  211. package/assets/plugin/tools/cancel-order.js +60 -0
  212. package/assets/plugin/tools/check-position-health.d.ts +46 -0
  213. package/assets/plugin/tools/check-position-health.js +194 -0
  214. package/assets/plugin/tools/clear-exchange-credentials.d.ts +24 -0
  215. package/assets/plugin/tools/clear-exchange-credentials.js +70 -0
  216. package/assets/plugin/tools/close-position.d.ts +45 -0
  217. package/assets/plugin/tools/close-position.js +722 -0
  218. package/assets/plugin/tools/create-order.d.ts +89 -0
  219. package/assets/plugin/tools/create-order.js +1555 -0
  220. package/assets/plugin/tools/exit-gate.d.ts +58 -0
  221. package/assets/plugin/tools/exit-gate.js +162 -0
  222. package/assets/plugin/tools/fetch-balance.d.ts +5 -0
  223. package/assets/plugin/tools/fetch-balance.js +4 -0
  224. package/assets/plugin/tools/fetch-ohlcv.d.ts +11 -0
  225. package/assets/plugin/tools/fetch-ohlcv.js +8 -0
  226. package/assets/plugin/tools/fetch-open-orders.d.ts +7 -0
  227. package/assets/plugin/tools/fetch-open-orders.js +4 -0
  228. package/assets/plugin/tools/fetch-positions.d.ts +7 -0
  229. package/assets/plugin/tools/fetch-positions.js +4 -0
  230. package/assets/plugin/tools/fetch-ticker.d.ts +11 -0
  231. package/assets/plugin/tools/fetch-ticker.js +5 -0
  232. package/assets/plugin/tools/get-agent-profile.d.ts +4 -0
  233. package/assets/plugin/tools/get-agent-profile.js +6 -0
  234. package/assets/plugin/tools/get-analytics.d.ts +6 -0
  235. package/assets/plugin/tools/get-analytics.js +7 -0
  236. package/assets/plugin/tools/get-backtest.d.ts +12 -0
  237. package/assets/plugin/tools/get-backtest.js +91 -0
  238. package/assets/plugin/tools/get-basis.d.ts +7 -0
  239. package/assets/plugin/tools/get-basis.js +7 -0
  240. package/assets/plugin/tools/get-bracket-config.d.ts +11 -0
  241. package/assets/plugin/tools/get-bracket-config.js +24 -0
  242. package/assets/plugin/tools/get-cascade-risk.d.ts +7 -0
  243. package/assets/plugin/tools/get-cascade-risk.js +8 -0
  244. package/assets/plugin/tools/get-crypto-metrics.d.ts +18 -0
  245. package/assets/plugin/tools/get-crypto-metrics.js +62 -0
  246. package/assets/plugin/tools/get-cvd.d.ts +6 -0
  247. package/assets/plugin/tools/get-cvd.js +6 -0
  248. package/assets/plugin/tools/get-divergences.d.ts +6 -0
  249. package/assets/plugin/tools/get-divergences.js +6 -0
  250. package/assets/plugin/tools/get-funding-context.d.ts +6 -0
  251. package/assets/plugin/tools/get-funding-context.js +16 -0
  252. package/assets/plugin/tools/get-liquidation-levels.d.ts +7 -0
  253. package/assets/plugin/tools/get-liquidation-levels.js +7 -0
  254. package/assets/plugin/tools/get-liquidation-pulse.d.ts +9 -0
  255. package/assets/plugin/tools/get-liquidation-pulse.js +22 -0
  256. package/assets/plugin/tools/get-market-breadth.d.ts +6 -0
  257. package/assets/plugin/tools/get-market-breadth.js +8 -0
  258. package/assets/plugin/tools/get-market-intel.d.ts +19 -0
  259. package/assets/plugin/tools/get-market-intel.js +116 -0
  260. package/assets/plugin/tools/get-market-structure.d.ts +47 -0
  261. package/assets/plugin/tools/get-market-structure.js +198 -0
  262. package/assets/plugin/tools/get-my-mined-patterns.d.ts +20 -0
  263. package/assets/plugin/tools/get-my-mined-patterns.js +61 -0
  264. package/assets/plugin/tools/get-my-proposed-learnings.d.ts +20 -0
  265. package/assets/plugin/tools/get-my-proposed-learnings.js +55 -0
  266. package/assets/plugin/tools/get-my-recent-reviews.d.ts +22 -0
  267. package/assets/plugin/tools/get-my-recent-reviews.js +66 -0
  268. package/assets/plugin/tools/get-orderbook.d.ts +21 -0
  269. package/assets/plugin/tools/get-orderbook.js +32 -0
  270. package/assets/plugin/tools/get-pattern-scan.d.ts +7 -0
  271. package/assets/plugin/tools/get-pattern-scan.js +8 -0
  272. package/assets/plugin/tools/get-regime.d.ts +6 -0
  273. package/assets/plugin/tools/get-regime.js +7 -0
  274. package/assets/plugin/tools/get-relevant-learnings.d.ts +21 -0
  275. package/assets/plugin/tools/get-relevant-learnings.js +65 -0
  276. package/assets/plugin/tools/get-resting-liquidity.d.ts +6 -0
  277. package/assets/plugin/tools/get-resting-liquidity.js +11 -0
  278. package/assets/plugin/tools/get-risk-scenario.d.ts +29 -0
  279. package/assets/plugin/tools/get-risk-scenario.js +47 -0
  280. package/assets/plugin/tools/get-risk-summary.d.ts +51 -0
  281. package/assets/plugin/tools/get-risk-summary.js +118 -0
  282. package/assets/plugin/tools/get-sentiment.d.ts +4 -0
  283. package/assets/plugin/tools/get-sentiment.js +6 -0
  284. package/assets/plugin/tools/get-session-review.d.ts +7 -0
  285. package/assets/plugin/tools/get-session-review.js +8 -0
  286. package/assets/plugin/tools/get-setup-detail.d.ts +7 -0
  287. package/assets/plugin/tools/get-setup-detail.js +322 -0
  288. package/assets/plugin/tools/get-signals.d.ts +15 -0
  289. package/assets/plugin/tools/get-signals.js +54 -0
  290. package/assets/plugin/tools/get-sizing.d.ts +6 -0
  291. package/assets/plugin/tools/get-sizing.js +6 -0
  292. package/assets/plugin/tools/get-trade-feedback.d.ts +7 -0
  293. package/assets/plugin/tools/get-trade-feedback.js +8 -0
  294. package/assets/plugin/tools/get-trade-flow.d.ts +7 -0
  295. package/assets/plugin/tools/get-trade-flow.js +7 -0
  296. package/assets/plugin/tools/get-volume-analysis.d.ts +21 -0
  297. package/assets/plugin/tools/get-volume-analysis.js +74 -0
  298. package/assets/plugin/tools/get-volume-profile.d.ts +7 -0
  299. package/assets/plugin/tools/get-volume-profile.js +7 -0
  300. package/assets/plugin/tools/get-wave9-status.d.ts +127 -0
  301. package/assets/plugin/tools/get-wave9-status.js +796 -0
  302. package/assets/plugin/tools/helpers.d.ts +26 -0
  303. package/assets/plugin/tools/helpers.js +39 -0
  304. package/assets/plugin/tools/intel-api.d.ts +34 -0
  305. package/assets/plugin/tools/intel-api.js +119 -0
  306. package/assets/plugin/tools/intel-cache.d.ts +25 -0
  307. package/assets/plugin/tools/intel-cache.js +148 -0
  308. package/assets/plugin/tools/list-strategies.d.ts +17 -0
  309. package/assets/plugin/tools/list-strategies.js +23 -0
  310. package/assets/plugin/tools/modify-stop.d.ts +21 -0
  311. package/assets/plugin/tools/modify-stop.js +120 -0
  312. package/assets/plugin/tools/modify-target.d.ts +21 -0
  313. package/assets/plugin/tools/modify-target.js +110 -0
  314. package/assets/plugin/tools/propose-learning.d.ts +22 -0
  315. package/assets/plugin/tools/propose-learning.js +65 -0
  316. package/assets/plugin/tools/query-review-outcomes.d.ts +30 -0
  317. package/assets/plugin/tools/query-review-outcomes.js +64 -0
  318. package/assets/plugin/tools/query-trades.d.ts +21 -0
  319. package/assets/plugin/tools/query-trades.js +37 -0
  320. package/assets/plugin/tools/record-position-reviews.d.ts +38 -0
  321. package/assets/plugin/tools/record-position-reviews.js +147 -0
  322. package/assets/plugin/tools/save-strategy.d.ts +16 -0
  323. package/assets/plugin/tools/save-strategy.js +46 -0
  324. package/assets/plugin/tools/scan-pairs.d.ts +22 -0
  325. package/assets/plugin/tools/scan-pairs.js +234 -0
  326. package/assets/plugin/tools/score-setup.d.ts +31 -0
  327. package/assets/plugin/tools/score-setup.js +268 -0
  328. package/assets/plugin/tools/set-bracket-requirement.d.ts +18 -0
  329. package/assets/plugin/tools/set-bracket-requirement.js +81 -0
  330. package/assets/plugin/tools/set-exchange-credentials.d.ts +25 -0
  331. package/assets/plugin/tools/set-exchange-credentials.js +80 -0
  332. package/assets/plugin/tools/set-trading-mode.d.ts +26 -0
  333. package/assets/plugin/tools/set-trading-mode.js +152 -0
  334. package/assets/plugin/tools/test-exchange-credentials.d.ts +16 -0
  335. package/assets/plugin/tools/test-exchange-credentials.js +100 -0
  336. package/assets/plugin/tools/toggle-strategy.d.ts +8 -0
  337. package/assets/plugin/tools/toggle-strategy.js +15 -0
  338. package/assets/plugin/trading-params-cache.d.ts +26 -0
  339. package/assets/plugin/trading-params-cache.js +52 -0
  340. package/assets/plugin/types.d.ts +134 -0
  341. package/assets/plugin/types.js +7 -0
  342. package/assets/plugin/util/plugin-paths.d.ts +3 -0
  343. package/assets/plugin/util/plugin-paths.js +15 -0
  344. package/assets/plugin/venues/hyperliquid/hl-balance.d.ts +116 -0
  345. package/assets/plugin/venues/hyperliquid/hl-balance.js +145 -0
  346. package/assets/plugin/venues/hyperliquid/hl-bracket-coordinator.d.ts +123 -0
  347. package/assets/plugin/venues/hyperliquid/hl-bracket-coordinator.js +533 -0
  348. package/assets/plugin/venues/hyperliquid/hl-brackets.d.ts +102 -0
  349. package/assets/plugin/venues/hyperliquid/hl-brackets.js +172 -0
  350. package/assets/plugin/venues/hyperliquid/hl-cloid.d.ts +22 -0
  351. package/assets/plugin/venues/hyperliquid/hl-cloid.js +82 -0
  352. package/assets/plugin/venues/hyperliquid/hl-info-cache.d.ts +46 -0
  353. package/assets/plugin/venues/hyperliquid/hl-info-cache.js +125 -0
  354. package/assets/plugin/venues/hyperliquid/hl-live-adapter.d.ts +146 -0
  355. package/assets/plugin/venues/hyperliquid/hl-live-adapter.js +728 -0
  356. package/assets/plugin/venues/hyperliquid/hl-precision.d.ts +61 -0
  357. package/assets/plugin/venues/hyperliquid/hl-precision.js +176 -0
  358. package/assets/plugin/venues/hyperliquid/hl-private.d.ts +88 -0
  359. package/assets/plugin/venues/hyperliquid/hl-private.js +357 -0
  360. package/assets/plugin/venues/hyperliquid/hl-public.d.ts +79 -0
  361. package/assets/plugin/venues/hyperliquid/hl-public.js +436 -0
  362. package/assets/plugin/venues/hyperliquid/hl-rate-gate.d.ts +57 -0
  363. package/assets/plugin/venues/hyperliquid/hl-rate-gate.js +220 -0
  364. package/assets/plugin/venues/hyperliquid/hl-user-stream.d.ts +90 -0
  365. package/assets/plugin/venues/hyperliquid/hl-user-stream.js +220 -0
  366. package/assets/plugin/venues/registry.d.ts +38 -0
  367. package/assets/plugin/venues/registry.js +46 -0
  368. package/assets/plugin/venues/symbols.d.ts +43 -0
  369. package/assets/plugin/venues/symbols.js +107 -0
  370. package/assets/plugin/wave9/live-account-capture.d.ts +67 -0
  371. package/assets/plugin/wave9/live-account-capture.js +435 -0
  372. package/assets/plugin/wave9/live-autonomous-protection.d.ts +39 -0
  373. package/assets/plugin/wave9/live-autonomous-protection.js +112 -0
  374. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.d.ts +33 -0
  375. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.js +115 -0
  376. package/assets/plugin/wave9/live-execution-ledger.d.ts +107 -0
  377. package/assets/plugin/wave9/live-execution-ledger.js +498 -0
  378. package/assets/plugin/wave9/live-position-confirmation.d.ts +18 -0
  379. package/assets/plugin/wave9/live-position-confirmation.js +111 -0
  380. package/assets/plugin/wave9/live-residual-protection.d.ts +18 -0
  381. package/assets/plugin/wave9/live-residual-protection.js +250 -0
  382. package/assets/plugin/wave9/live-startup-reconciliation.d.ts +38 -0
  383. package/assets/plugin/wave9/live-startup-reconciliation.js +454 -0
  384. package/assets/plugin/wave9/live-symbol-ownership.d.ts +20 -0
  385. package/assets/plugin/wave9/live-symbol-ownership.js +132 -0
  386. package/assets/plugin/wave9/paper-admission-guard.d.ts +199 -0
  387. package/assets/plugin/wave9/paper-admission-guard.js +650 -0
  388. package/assets/plugin/wave9/usdm-evidence-provider.d.ts +42 -0
  389. package/assets/plugin/wave9/usdm-evidence-provider.js +133 -0
  390. package/dist/plugin.js +24 -15
  391. package/package.json +1 -1
@@ -0,0 +1,220 @@
1
+ // Hyperliquid rate gate — the HL analog of `ccxt/binance-ban-gate.ts` (plan §5.6).
2
+ //
3
+ // SAME SHAPE as the Binance gate (process-wide singleton; `assertNotLimited(ctx)`
4
+ // first line in the try, `noteError(err)` in the catch, `noteSuccess()` after a
5
+ // clean call; order/cancel paths are NEVER pre-gated but DO arm the gate).
6
+ // DIFFERENT MODEL inside — read twice before tuning:
7
+ //
8
+ // Binance: per-IP weight window; abuse ⇒ a 418 BAN that EXTENDS on every further
9
+ // request. The danger is a poller hammering through a ban.
10
+ // HL: TWO independent budgets.
11
+ // (1) IP weight: 1200/min (no response header to reconcile against —
12
+ // the local estimate IS the authority; calibrate in shadow).
13
+ // (2) ★ ADDRESS action budget: 10,000 initial + 1 per 1 USDC of
14
+ // cumulative traded volume. Exhausted ⇒ 1 request / 10 s. A
15
+ // low-volume, chatty heartbeat agent STARVES ITSELF — the exact
16
+ // opposite failure mode from Binance, and the one Binance-tuned
17
+ // intuition will miss.
18
+ //
19
+ // Batches count as **1** for the IP window but **n** for the address budget, so
20
+ // every `note*` call takes both numbers — brackets (2 legs, one batch) are counted
21
+ // honestly.
22
+ import { logger } from '../../logger.js';
23
+ const TAG = 'hl-rate-gate';
24
+ /** Documented IP limit is 1200 weight/min; we pace against a soft ceiling so a
25
+ * burst never reaches the real one. Env override for calibration. */
26
+ const DEFAULT_WEIGHT_CEILING = 900;
27
+ /** Below this many remaining address actions we start shedding SHED_FIRST reads
28
+ * and warn loudly (the remedy is operator-level: trade volume accrues budget, or
29
+ * `reserveRequestWeight` purchases more — never automatic). */
30
+ const DEFAULT_ADDRESS_FLOOR = 2000;
31
+ const WINDOW_MS = 60_000;
32
+ /** 429 backoff ladder (mirrors the Binance gate's shape; HL has no
33
+ * 418-with-timestamp analog, so there is no stated window to parse). */
34
+ const BACKOFF_LADDER_MS = [5_000, 15_000, 45_000, 90_000, 120_000];
35
+ /** Info-request weights, from the docs (§3.3). Anything unlisted defaults to 20 —
36
+ * the conservative side. `/exchange` actions are `1 + floor(batch/40)`. */
37
+ export const HL_INFO_WEIGHTS = {
38
+ l2Book: 2,
39
+ allMids: 2,
40
+ clearinghouseState: 2,
41
+ orderStatus: 2,
42
+ exchangeStatus: 2,
43
+ spotClearinghouseState: 2,
44
+ userRole: 60,
45
+ // everything else (meta, metaAndAssetCtxs, userFills, frontendOpenOrders,
46
+ // userFunding, userNonFundingLedgerUpdates, candleSnapshot, userRateLimit …)
47
+ default: 20,
48
+ };
49
+ /** Read contexts that are safe to SHED when the address budget runs low — they are
50
+ * refreshable/derivable, unlike the safety-floor reads (positions, open orders,
51
+ * order status) which must always pass. */
52
+ const SHED_FIRST = new Set([
53
+ 'candleSnapshot',
54
+ 'metaAndAssetCtxs',
55
+ 'allMids',
56
+ 'l2Book',
57
+ 'userFunding',
58
+ 'userFees',
59
+ 'portfolio',
60
+ ]);
61
+ export class HyperliquidRateLimitedError extends Error {
62
+ constructor(message) {
63
+ super(message);
64
+ this.name = 'HyperliquidRateLimitedError';
65
+ }
66
+ }
67
+ /** Thrown by the proactive pacer BEFORE a call goes out. Subclass so every
68
+ * existing `catch (HyperliquidRateLimitedError)` absorbs it — the same
69
+ * relationship `BinanceWeightPacedError` has to `BinanceBannedError`. */
70
+ export class HyperliquidPacedError extends HyperliquidRateLimitedError {
71
+ constructor(message) {
72
+ super(message);
73
+ this.name = 'HyperliquidPacedError';
74
+ }
75
+ }
76
+ const state = {
77
+ samples: [],
78
+ limitedUntil: 0,
79
+ consecutive429: 0,
80
+ windowIpWeight: 0,
81
+ windowAddressActions: 0,
82
+ windowStart: Date.now(),
83
+ };
84
+ function weightCeiling() {
85
+ const raw = Number(process.env.RC_HL_WEIGHT_CEILING);
86
+ return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_WEIGHT_CEILING;
87
+ }
88
+ function addressFloor() {
89
+ const raw = Number(process.env.RC_HL_ADDRESS_BUDGET_FLOOR);
90
+ return Number.isFinite(raw) && raw >= 0 ? raw : DEFAULT_ADDRESS_FLOOR;
91
+ }
92
+ function pruneWindow(now) {
93
+ const cutoff = now - WINDOW_MS;
94
+ while (state.samples.length > 0 && state.samples[0].at < cutoff) {
95
+ state.samples.shift();
96
+ }
97
+ }
98
+ /** Current 60s IP-weight estimate. */
99
+ export function currentIpWeight(now = Date.now()) {
100
+ pruneWindow(now);
101
+ return state.samples.reduce((sum, s) => sum + s.weight, 0);
102
+ }
103
+ /** Weight for an info context (defaults to the conservative 20). */
104
+ export function infoWeight(ctx) {
105
+ return HL_INFO_WEIGHTS[ctx] ?? HL_INFO_WEIGHTS.default;
106
+ }
107
+ /** `/exchange` IP weight for a batch of n actions: 1 + floor(n/40). */
108
+ export function exchangeIpWeight(batchLen) {
109
+ return 1 + Math.floor(Math.max(batchLen, 1) / 40);
110
+ }
111
+ /** FIRST LINE of every gated read's try-block.
112
+ *
113
+ * Throws when:
114
+ * - a 429 backoff is active (hard stop — like an active Binance ban), or
115
+ * - the IP weight window is over its soft ceiling (proactive pacing), or
116
+ * - the address budget is below the floor AND this context is shed-able.
117
+ *
118
+ * Order/cancel/close paths must NOT call this — they arm the gate via
119
+ * `noteError` only, so a limit can never block an exit. */
120
+ export function assertNotLimited(ctx) {
121
+ const now = Date.now();
122
+ if (state.limitedUntil > now) {
123
+ const secs = Math.ceil((state.limitedUntil - now) / 1000);
124
+ throw new HyperliquidRateLimitedError(`Hyperliquid rate limit active (${secs}s remaining) — ${ctx} shed`);
125
+ }
126
+ const weight = infoWeight(ctx);
127
+ const used = currentIpWeight(now);
128
+ if (used + weight > weightCeiling()) {
129
+ throw new HyperliquidPacedError(`Hyperliquid IP weight pacer: ${used}+${weight} > ${weightCeiling()}/min ceiling — ${ctx} shed`);
130
+ }
131
+ const remaining = state.addressRemaining;
132
+ if (remaining !== undefined && remaining < addressFloor() && SHED_FIRST.has(ctx)) {
133
+ throw new HyperliquidPacedError(`Hyperliquid address action budget low (${remaining} left, floor ${addressFloor()}) — ` +
134
+ `shedding ${ctx}. Budget accrues with traded volume; reserveRequestWeight can purchase more.`);
135
+ }
136
+ }
137
+ /** Record a successful call's cost. `addressActions` is 0 for pure info reads
138
+ * (they cost IP weight only) and n for an `/exchange` batch of n actions. */
139
+ export function noteSuccess(ctx, cost) {
140
+ const now = Date.now();
141
+ const ipWeight = cost?.ipWeight ?? infoWeight(ctx);
142
+ const addressActions = cost?.addressActions ?? 0;
143
+ state.samples.push({ at: now, weight: ipWeight });
144
+ pruneWindow(now);
145
+ state.consecutive429 = 0;
146
+ state.limitedUntil = 0;
147
+ state.windowIpWeight += ipWeight;
148
+ state.windowAddressActions += addressActions;
149
+ if (addressActions > 0 && state.addressRemaining !== undefined) {
150
+ state.addressRemaining = Math.max(0, state.addressRemaining - addressActions);
151
+ }
152
+ maybeLogWindow(now);
153
+ }
154
+ /** Arm the gate from a caught error. Called in EVERY catch — including on the
155
+ * order/cancel paths that are never pre-gated (so a burst of rejects still
156
+ * backs the gate off). */
157
+ export function noteError(err, ctx = 'unknown') {
158
+ if (!isRateLimitError(err))
159
+ return;
160
+ state.consecutive429 += 1;
161
+ const idx = Math.min(state.consecutive429 - 1, BACKOFF_LADDER_MS.length - 1);
162
+ const backoff = BACKOFF_LADDER_MS[idx];
163
+ state.limitedUntil = Date.now() + backoff;
164
+ logger.warn(TAG, `Hyperliquid rate limit hit on ${ctx} (#${state.consecutive429}) — backing off ${backoff / 1000}s`);
165
+ }
166
+ /** HL surfaces rate limiting as HTTP 429 and/or a text body; match on shape, not
167
+ * on a venue flag, so the skill-side breaker can reuse this predicate. */
168
+ export function isRateLimitError(err) {
169
+ if (err instanceof HyperliquidRateLimitedError)
170
+ return true;
171
+ const msg = err instanceof Error ? err.message : String(err ?? '');
172
+ return /429|rate limit|too many requests/i.test(msg);
173
+ }
174
+ /** Feed the address budget from info `userRateLimit` (`nRequestsCap −
175
+ * nRequestsUsed`). Poll it every ~5 min — it costs weight 20. */
176
+ export function updateAddressBudget(args) {
177
+ const remaining = Math.max(0, args.nRequestsCap - args.nRequestsUsed);
178
+ const prev = state.addressRemaining;
179
+ state.addressRemaining = remaining;
180
+ state.addressUpdatedAt = Date.now();
181
+ if (remaining < addressFloor() && (prev === undefined || prev >= addressFloor())) {
182
+ logger.warn(TAG, `★ Hyperliquid ADDRESS action budget low: ${remaining} remaining (cap ${args.nRequestsCap}). ` +
183
+ 'Exhaustion throttles the account to 1 request/10s. Budget accrues at 1 action per 1 USDC ' +
184
+ 'of traded volume; an operator can purchase more via reserveRequestWeight.');
185
+ }
186
+ }
187
+ /** Snapshot for tests + the readiness/diagnostic surfaces. */
188
+ export function getGateState() {
189
+ const now = Date.now();
190
+ return {
191
+ ipWeight60s: currentIpWeight(now),
192
+ weightCeiling: weightCeiling(),
193
+ addressRemaining: state.addressRemaining,
194
+ limited: state.limitedUntil > now,
195
+ limitedForMs: Math.max(0, state.limitedUntil - now),
196
+ };
197
+ }
198
+ /** Permanent instrumentation — the `weight window summary` analog. Attribute load
199
+ * from THESE lines, never from a guess. */
200
+ function maybeLogWindow(now) {
201
+ if (now - state.windowStart < WINDOW_MS)
202
+ return;
203
+ logger.info(TAG, `hl window summary: ipWeight=${state.windowIpWeight}/${weightCeiling()} ` +
204
+ `addressActions=${state.windowAddressActions} ` +
205
+ `addressRemaining=${state.addressRemaining ?? 'unknown'}`);
206
+ state.windowIpWeight = 0;
207
+ state.windowAddressActions = 0;
208
+ state.windowStart = now;
209
+ }
210
+ /** Test-only reset. */
211
+ export function __resetGateForTests() {
212
+ state.samples = [];
213
+ state.limitedUntil = 0;
214
+ state.consecutive429 = 0;
215
+ state.addressRemaining = undefined;
216
+ state.addressUpdatedAt = undefined;
217
+ state.windowIpWeight = 0;
218
+ state.windowAddressActions = 0;
219
+ state.windowStart = Date.now();
220
+ }
@@ -0,0 +1,90 @@
1
+ export interface HlFillEvent {
2
+ coin: string;
3
+ px: string;
4
+ sz: string;
5
+ side: 'A' | 'B';
6
+ time: number;
7
+ dir: string;
8
+ closedPnl: string;
9
+ fee: string;
10
+ feeToken?: string;
11
+ builderFee?: string;
12
+ crossed: boolean;
13
+ oid: number;
14
+ tid: number;
15
+ cloid?: string;
16
+ startPosition?: string;
17
+ /** Present ONLY on a liquidation fill — an authoritative close-bypass signal. */
18
+ liquidation?: {
19
+ liquidatedUser?: string;
20
+ markPx?: string;
21
+ method?: string;
22
+ };
23
+ }
24
+ export interface HlOrderUpdateEvent {
25
+ order: {
26
+ coin: string;
27
+ side: 'A' | 'B';
28
+ limitPx: string;
29
+ sz: string;
30
+ oid: number;
31
+ timestamp: number;
32
+ origSz: string;
33
+ cloid?: string;
34
+ isTrigger?: boolean;
35
+ triggerPx?: string;
36
+ isPositionTpsl?: boolean;
37
+ reduceOnly?: boolean;
38
+ orderType?: string;
39
+ };
40
+ status: string;
41
+ statusTimestamp: number;
42
+ }
43
+ export interface HlUserStreamCallbacks {
44
+ onFill: (fill: HlFillEvent) => void;
45
+ onOrderUpdate: (update: HlOrderUpdateEvent) => void;
46
+ /** userEvents: liquidation / funding / non-user-cancel — the close-bypass feed. */
47
+ onUserEvent: (event: Record<string, unknown>) => void;
48
+ /**
49
+ * ★ MANDATORY. Fired after every (re)connect, carrying the window during which
50
+ * we were blind. T-5 proved the WS does NOT backfill it, so the caller MUST
51
+ * reconcile via REST (positions, open orders, fills since `sinceMs`) before
52
+ * trusting local state again. A caller that ignores this WILL miss fills.
53
+ */
54
+ onResyncNeeded: (window: {
55
+ sinceMs: number;
56
+ wasDisconnectedMs: number;
57
+ }) => void;
58
+ }
59
+ export declare class HyperliquidUserStream {
60
+ private readonly opts;
61
+ private ws;
62
+ private pingTimer;
63
+ private staleTimer;
64
+ private reconnectTimer;
65
+ private reconnectAttempts;
66
+ private stopped;
67
+ private lastFrameAt;
68
+ /** Last event we actually processed — the low-water mark for the REST gap-fill. */
69
+ private lastEventAt;
70
+ private disconnectedAt;
71
+ constructor(opts: {
72
+ /** MASTER address — subscriptions are keyed by the account, never the agent. */
73
+ walletAddress: string;
74
+ testnet?: boolean;
75
+ callbacks: HlUserStreamCallbacks;
76
+ });
77
+ get isConnected(): boolean;
78
+ /** Epoch-ms of the last processed event (0 = none yet). */
79
+ get lastEventTimestamp(): number;
80
+ start(): void;
81
+ stop(): void;
82
+ private url;
83
+ private connect;
84
+ private subscribeAll;
85
+ private handle;
86
+ private send;
87
+ private armTimers;
88
+ private clearTimers;
89
+ private onDisconnected;
90
+ }
@@ -0,0 +1,220 @@
1
+ // Hyperliquid user data stream (plan §5.4/§5.9) — the HL analog of
2
+ // `live/user-data-stream.ts`.
3
+ //
4
+ // ★ THE MEASURED FACT THAT SHAPES THIS FILE (T-5, testnet 2026-07-12):
5
+ // **HL's WS replays NOTHING on reconnect.** We killed the socket, placed an
6
+ // order inside the gap, re-subscribed — and received ZERO events for it, while
7
+ // REST showed it plainly. There is no `isSnapshot` backfill for the gap.
8
+ //
9
+ // ⇒ WS is a FAST PATH, never the ledger. Every reconnect MUST be followed by a
10
+ // REST truth-check (positions + open orders + fills since the disconnect), and
11
+ // the caller is REQUIRED to wire `onResyncNeeded`. This class refuses to
12
+ // pretend otherwise: it tracks `lastEventAt`/`disconnectedAt` and hands them
13
+ // to the resync callback so the gap window is explicit.
14
+ //
15
+ // Other HL-specific rules honoured here:
16
+ // - No listenKey. Auth is by SUBSCRIBING with the MASTER address (agent wallets
17
+ // sign; queries always name the master).
18
+ // - Server closes an idle socket after 60s of silence ⇒ app-level ping every 30s
19
+ // (same cadence the intel HL client uses).
20
+ // - Subscriptions are NOT auto-restored by the server: they must be re-sent on
21
+ // every (re)connect.
22
+ // - `orderUpdates` carries trigger orders natively (statuses incl. `triggered`,
23
+ // `siblingFilledCanceled`, `liquidatedCanceled`, `delistedCanceled`,
24
+ // `marginCanceled`) — simpler than Binance, where brackets needed a separate
25
+ // ALGO_UPDATE channel.
26
+ import WebSocket from 'ws';
27
+ import { logger } from '../../logger.js';
28
+ const TAG = 'hl-user-stream';
29
+ const PING_INTERVAL_MS = 30_000; // server cuts idle sockets at 60s
30
+ const STALE_AFTER_MS = 90_000; // no frame at all for 90s ⇒ terminate + reconnect
31
+ const RECONNECT_BASE_MS = 1_000;
32
+ const RECONNECT_MAX_MS = 60_000;
33
+ export class HyperliquidUserStream {
34
+ opts;
35
+ ws = null;
36
+ pingTimer = null;
37
+ staleTimer = null;
38
+ reconnectTimer = null;
39
+ reconnectAttempts = 0;
40
+ stopped = false;
41
+ lastFrameAt = 0;
42
+ /** Last event we actually processed — the low-water mark for the REST gap-fill. */
43
+ lastEventAt = 0;
44
+ disconnectedAt = 0;
45
+ constructor(opts) {
46
+ this.opts = opts;
47
+ }
48
+ get isConnected() {
49
+ return this.ws?.readyState === WebSocket.OPEN;
50
+ }
51
+ /** Epoch-ms of the last processed event (0 = none yet). */
52
+ get lastEventTimestamp() {
53
+ return this.lastEventAt;
54
+ }
55
+ start() {
56
+ this.stopped = false;
57
+ this.connect();
58
+ }
59
+ stop() {
60
+ this.stopped = true;
61
+ this.clearTimers();
62
+ if (this.reconnectTimer)
63
+ clearTimeout(this.reconnectTimer);
64
+ this.reconnectTimer = null;
65
+ try {
66
+ this.ws?.close();
67
+ }
68
+ catch {
69
+ /* best-effort */
70
+ }
71
+ this.ws = null;
72
+ }
73
+ url() {
74
+ return this.opts.testnet
75
+ ? 'wss://api.hyperliquid-testnet.xyz/ws'
76
+ : 'wss://api.hyperliquid.xyz/ws';
77
+ }
78
+ connect() {
79
+ if (this.stopped)
80
+ return;
81
+ const url = this.url();
82
+ logger.info(TAG, `connecting ${url}`);
83
+ const ws = new WebSocket(url);
84
+ this.ws = ws;
85
+ ws.on('open', () => {
86
+ this.reconnectAttempts = 0;
87
+ this.lastFrameAt = Date.now();
88
+ this.subscribeAll();
89
+ this.armTimers();
90
+ // ★ T-5: the server sends NO backfill for the gap. Tell the caller exactly
91
+ // how blind we were so it can REST-reconcile that window. `lastEventAt || 0`
92
+ // makes the first connect a full-snapshot request too.
93
+ const wasDisconnectedMs = this.disconnectedAt ? Date.now() - this.disconnectedAt : 0;
94
+ const sinceMs = this.lastEventAt || Date.now() - 60_000;
95
+ logger.info(TAG, `connected — REST resync required (blind ${Math.round(wasDisconnectedMs / 1000)}s; ` +
96
+ 'HL WS does not replay missed events — verified testnet 2026-07-12)');
97
+ this.opts.callbacks.onResyncNeeded({ sinceMs, wasDisconnectedMs });
98
+ this.disconnectedAt = 0;
99
+ });
100
+ ws.on('message', (raw) => {
101
+ this.lastFrameAt = Date.now();
102
+ let msg;
103
+ try {
104
+ msg = JSON.parse(raw.toString());
105
+ }
106
+ catch {
107
+ return;
108
+ }
109
+ this.handle(msg);
110
+ });
111
+ ws.on('close', (code, reason) => {
112
+ logger.warn(TAG, `closed code=${code} reason=${reason?.toString().slice(0, 80)}`);
113
+ this.onDisconnected();
114
+ });
115
+ ws.on('error', (err) => {
116
+ logger.warn(TAG, `socket error: ${err.message}`);
117
+ // 'close' follows — reconnect is handled there.
118
+ });
119
+ }
120
+ subscribeAll() {
121
+ const user = this.opts.walletAddress;
122
+ // Subscriptions are NOT restored by the server after a reconnect — always re-send.
123
+ const subs = [
124
+ { type: 'orderUpdates', user },
125
+ { type: 'userFills', user },
126
+ { type: 'userEvents', user },
127
+ { type: 'userFundings', user },
128
+ ];
129
+ for (const subscription of subs) {
130
+ this.send({ method: 'subscribe', subscription });
131
+ }
132
+ }
133
+ handle(msg) {
134
+ const { channel, data } = msg;
135
+ if (!channel || channel === 'subscriptionResponse' || channel === 'pong')
136
+ return;
137
+ switch (channel) {
138
+ case 'userFills': {
139
+ const payload = data;
140
+ for (const fill of payload?.fills ?? []) {
141
+ this.lastEventAt = Math.max(this.lastEventAt, fill.time ?? Date.now());
142
+ this.opts.callbacks.onFill(fill);
143
+ }
144
+ break;
145
+ }
146
+ case 'orderUpdates': {
147
+ const updates = (Array.isArray(data) ? data : []);
148
+ for (const u of updates) {
149
+ this.lastEventAt = Math.max(this.lastEventAt, u.statusTimestamp ?? Date.now());
150
+ this.opts.callbacks.onOrderUpdate(u);
151
+ }
152
+ break;
153
+ }
154
+ case 'userEvents': {
155
+ this.lastEventAt = Date.now();
156
+ this.opts.callbacks.onUserEvent((data ?? {}));
157
+ break;
158
+ }
159
+ case 'userFundings': {
160
+ this.lastEventAt = Date.now();
161
+ this.opts.callbacks.onUserEvent({ fundings: data });
162
+ break;
163
+ }
164
+ default:
165
+ break;
166
+ }
167
+ }
168
+ send(payload) {
169
+ if (this.ws?.readyState !== WebSocket.OPEN)
170
+ return;
171
+ try {
172
+ this.ws.send(JSON.stringify(payload));
173
+ }
174
+ catch (err) {
175
+ logger.warn(TAG, `send failed: ${err instanceof Error ? err.message : String(err)}`);
176
+ }
177
+ }
178
+ armTimers() {
179
+ this.clearTimers();
180
+ // App-level ping — the server cuts an idle socket at 60s.
181
+ this.pingTimer = setInterval(() => this.send({ method: 'ping' }), PING_INTERVAL_MS);
182
+ // Frame-staleness watchdog — a silent socket is worse than a closed one
183
+ // (we would believe stale positions). Terminate ⇒ reconnect ⇒ REST resync.
184
+ this.staleTimer = setInterval(() => {
185
+ if (!this.lastFrameAt)
186
+ return;
187
+ const silentMs = Date.now() - this.lastFrameAt;
188
+ if (silentMs > STALE_AFTER_MS) {
189
+ logger.warn(TAG, `no frames for ${Math.round(silentMs / 1000)}s — terminating socket`);
190
+ try {
191
+ this.ws?.terminate();
192
+ }
193
+ catch {
194
+ /* the close handler drives the reconnect */
195
+ }
196
+ }
197
+ }, 15_000);
198
+ }
199
+ clearTimers() {
200
+ if (this.pingTimer)
201
+ clearInterval(this.pingTimer);
202
+ if (this.staleTimer)
203
+ clearInterval(this.staleTimer);
204
+ this.pingTimer = null;
205
+ this.staleTimer = null;
206
+ }
207
+ onDisconnected() {
208
+ this.clearTimers();
209
+ this.ws = null;
210
+ if (this.stopped)
211
+ return;
212
+ if (!this.disconnectedAt)
213
+ this.disconnectedAt = Date.now();
214
+ const delay = Math.min(RECONNECT_BASE_MS * 2 ** this.reconnectAttempts, RECONNECT_MAX_MS);
215
+ const jittered = delay * (0.8 + Math.random() * 0.4);
216
+ this.reconnectAttempts += 1;
217
+ logger.info(TAG, `reconnecting in ${Math.round(jittered / 1000)}s (attempt ${this.reconnectAttempts})`);
218
+ this.reconnectTimer = setTimeout(() => this.connect(), jittered);
219
+ }
220
+ }
@@ -0,0 +1,38 @@
1
+ import { LiveAdapter } from '../live/live-adapter.js';
2
+ import { HyperliquidLiveAdapter, type HlLiveAdapterOptions } from './hyperliquid/hl-live-adapter.js';
3
+ import { fillExchangeId, parseVenue, type VenueId } from './symbols.js';
4
+ export type { VenueId };
5
+ export { fillExchangeId, parseVenue };
6
+ /** Venues this build can construct a LIVE adapter for. PAPER mode is
7
+ * venue-flavored only by its market-data source (PaperMarketFeed / chart) and
8
+ * is not gated here. */
9
+ export declare const SUPPORTED_LIVE_VENUES: ReadonlySet<VenueId>;
10
+ export declare function isLiveVenueSupported(venue: VenueId): boolean;
11
+ /** Paper-wallet settlement/quote currency for a venue. Hyperliquid margins
12
+ * USDC linear perps; Binance USDⓈ-M paper keeps the historical USDT.
13
+ * Issue #174: the paper wallet MUST follow the venue — a USDT wallet on the
14
+ * USDC venue reads as $0 equity and every order fails "Insufficient USDC". */
15
+ export declare function venueQuoteCurrency(venue: VenueId): 'USDT' | 'USDC';
16
+ type BinanceLiveAdapterArgs = ConstructorParameters<typeof LiveAdapter>;
17
+ /** Every live adapter this build can construct. Both are EventEmitters exposing
18
+ * the same lifecycle events (`drift_detected`) and both implement
19
+ * IExchangeAdapter — the boot path treats them identically. */
20
+ export type AnyLiveAdapter = LiveAdapter | HyperliquidLiveAdapter;
21
+ /** Venue-typed construction spec. A discriminated union so the compiler — not a
22
+ * runtime branch in the boot path — guarantees each venue gets ITS OWN args
23
+ * (Binance takes API key/secret; Hyperliquid takes a master address + agent key,
24
+ * a completely different credential shape). */
25
+ export type LiveAdapterSpec = {
26
+ venue: 'binance';
27
+ args: BinanceLiveAdapterArgs;
28
+ } | {
29
+ venue: 'hyperliquid';
30
+ args: HlLiveAdapterOptions;
31
+ };
32
+ /** Construct the live adapter for a venue — the ONLY place either class is newed.
33
+ *
34
+ * Binance: a pure pass-through to `new LiveAdapter(...)` — byte-identical to the
35
+ * inline construction this factory replaced (the args tuple is derived from the
36
+ * constructor so the two can never drift).
37
+ * Hyperliquid: `new HyperliquidLiveAdapter(...)` (Phase 3). */
38
+ export declare function createLiveAdapter(spec: LiveAdapterSpec): AnyLiveAdapter;
@@ -0,0 +1,46 @@
1
+ // Venue registry — the single seam where a trading venue's LIVE adapter is
2
+ // constructed (Phase 0 of docs/HYPERLIQUID_INTEGRATION_PLAN.md §5.1/§7.1).
3
+ //
4
+ // Phase 0 scope: Binance is the ONLY venue this build can trade live;
5
+ // 'hyperliquid' is a recognised-but-unsupported config value that boot handles
6
+ // by falling back to PAPER (never by crashing register() — OpenClaw treats a
7
+ // throwing register as "ignored" and the agent silently loses every tool).
8
+ // Phase 3 adds the HyperliquidLiveAdapter arm HERE and nowhere else, so the
9
+ // boot path never grows a second venue branch.
10
+ //
11
+ // Venue is LOCAL mechanism (TOOL_DISTRIBUTION_ARCHITECTURE.md §2 decision
12
+ // rule: it holds keys + is part of the safety floor) — it is read from
13
+ // ~/.reefclaw/plugin-config.json `exchange.venue` and MUST never be settable
14
+ // from the central config channel.
15
+ import { LiveAdapter } from '../live/live-adapter.js';
16
+ import { HyperliquidLiveAdapter } from './hyperliquid/hl-live-adapter.js';
17
+ import { fillExchangeId, parseVenue } from './symbols.js';
18
+ export { fillExchangeId, parseVenue };
19
+ /** Venues this build can construct a LIVE adapter for. PAPER mode is
20
+ * venue-flavored only by its market-data source (PaperMarketFeed / chart) and
21
+ * is not gated here. */
22
+ export const SUPPORTED_LIVE_VENUES = new Set(['binance', 'hyperliquid']);
23
+ export function isLiveVenueSupported(venue) {
24
+ return SUPPORTED_LIVE_VENUES.has(venue);
25
+ }
26
+ /** Paper-wallet settlement/quote currency for a venue. Hyperliquid margins
27
+ * USDC linear perps; Binance USDⓈ-M paper keeps the historical USDT.
28
+ * Issue #174: the paper wallet MUST follow the venue — a USDT wallet on the
29
+ * USDC venue reads as $0 equity and every order fails "Insufficient USDC". */
30
+ export function venueQuoteCurrency(venue) {
31
+ return venue === 'hyperliquid' ? 'USDC' : 'USDT';
32
+ }
33
+ /** Construct the live adapter for a venue — the ONLY place either class is newed.
34
+ *
35
+ * Binance: a pure pass-through to `new LiveAdapter(...)` — byte-identical to the
36
+ * inline construction this factory replaced (the args tuple is derived from the
37
+ * constructor so the two can never drift).
38
+ * Hyperliquid: `new HyperliquidLiveAdapter(...)` (Phase 3). */
39
+ export function createLiveAdapter(spec) {
40
+ switch (spec.venue) {
41
+ case 'binance':
42
+ return new LiveAdapter(...spec.args);
43
+ case 'hyperliquid':
44
+ return new HyperliquidLiveAdapter(spec.args);
45
+ }
46
+ }
@@ -0,0 +1,43 @@
1
+ export type VenueId = 'binance' | 'hyperliquid';
2
+ export declare const VENUE_IDS: readonly VenueId[];
3
+ export declare function isVenueId(value: unknown): value is VenueId;
4
+ /** Parse a raw config value into a venue.
5
+ * Absent/empty → 'binance' (every pre-venue config file keeps today's
6
+ * behavior byte-identically). An unrecognized string is surfaced to the
7
+ * caller instead of being silently coerced — mis-spelling a venue must be
8
+ * loud, never quietly become "trade on Binance". */
9
+ export declare function parseVenue(raw: unknown): {
10
+ venue: VenueId;
11
+ unrecognized?: string;
12
+ };
13
+ /** `FillEvent.exchange` / webapp `trades.exchange` value — half of the
14
+ * audit-trail idempotency key `(exchange, exchange_trade_id)` (migration
15
+ * 0042). 'binance_futures' is the historical literal on every existing row;
16
+ * NEVER change these strings once a venue has written rows. */
17
+ export declare const FILL_EXCHANGE_ID: Record<VenueId, string>;
18
+ export declare function fillExchangeId(venue: VenueId): string;
19
+ /** Quote/settle asset of the venue's linear perps. */
20
+ export declare const VENUE_QUOTE_ASSET: Record<VenueId, string>;
21
+ /** Prefix that namespaces Hyperliquid rows inside the intel symbol column. */
22
+ export declare const HL_INTEL_PREFIX = "HL_";
23
+ /** Canonical symbol → the venue's CCXT unified symbol.
24
+ * 'BTC/USDT' (binance) → 'BTC/USDT:USDT'; 'BTC/USDC' (hyperliquid) →
25
+ * 'BTC/USDC:USDC'. Accepts an already-suffixed input (idempotent). */
26
+ export declare function toCcxtSymbol(venue: VenueId, canonical: string): string;
27
+ /** Canonical symbol → intel DB symbol.
28
+ * binance: 'BTC/USDT' → 'BTCUSDT' (the historical concatenated form intel has
29
+ * always stored); hyperliquid: 'BTC/USDC' → 'HL_BTC' (namespaced coin, case
30
+ * preserved). */
31
+ export declare function toIntelSymbol(venue: VenueId, canonical: string): string;
32
+ /** Inverse of toIntelSymbol. 'HL_'-prefixed → hyperliquid; everything else is
33
+ * the historical Binance namespace. Binance symbols that are not
34
+ * USDT-concatenated (none exist in INTEL_SYMBOLS today) come back verbatim as
35
+ * canonical — honest passthrough, not a guess. */
36
+ export declare function fromIntelSymbol(intelSymbol: string): {
37
+ venue: VenueId;
38
+ canonical: string;
39
+ };
40
+ /** The Hyperliquid venue-native coin name for a canonical symbol
41
+ * ('BTC/USDC' → 'BTC'). Orders address assets by integer index resolved from
42
+ * `meta.universe` at runtime — the coin name is the stable half. */
43
+ export declare function toHyperliquidCoin(canonical: string): string;