@reefclaw/openclaw-plugin 0.1.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 (371) hide show
  1. package/.gitignore +8 -0
  2. package/audit/mode-transition-audit.d.ts +11 -0
  3. package/audit/mode-transition-audit.js +29 -0
  4. package/balance-utils.d.ts +36 -0
  5. package/balance-utils.js +98 -0
  6. package/bridge/bridge.d.ts +109 -0
  7. package/bridge/bridge.js +1036 -0
  8. package/bridge/config.d.ts +43 -0
  9. package/bridge/config.js +176 -0
  10. package/bridge/connector.d.ts +52 -0
  11. package/bridge/connector.js +293 -0
  12. package/bridge/event-replay-buffer.d.ts +43 -0
  13. package/bridge/event-replay-buffer.js +109 -0
  14. package/bridge/gateway/event-parser.d.ts +209 -0
  15. package/bridge/gateway/event-parser.js +793 -0
  16. package/bridge/gateway/gateway-config.d.ts +39 -0
  17. package/bridge/gateway/gateway-config.js +86 -0
  18. package/bridge/gateway/gateway-http-client.d.ts +50 -0
  19. package/bridge/gateway/gateway-http-client.js +165 -0
  20. package/bridge/gateway/gateway-ws-client.d.ts +116 -0
  21. package/bridge/gateway/gateway-ws-client.js +417 -0
  22. package/bridge/gateway/poller.d.ts +146 -0
  23. package/bridge/gateway/poller.js +505 -0
  24. package/bridge/gateway/tool-discovery.d.ts +25 -0
  25. package/bridge/gateway/tool-discovery.js +198 -0
  26. package/bridge/index.d.ts +2 -0
  27. package/bridge/index.js +253 -0
  28. package/bridge/logger.d.ts +2 -0
  29. package/bridge/logger.js +2 -0
  30. package/bridge/provider.d.ts +156 -0
  31. package/bridge/provider.js +2 -0
  32. package/bridge/providers/emergency-commands.d.ts +54 -0
  33. package/bridge/providers/emergency-commands.js +235 -0
  34. package/bridge/providers/gateway.d.ts +322 -0
  35. package/bridge/providers/gateway.js +2302 -0
  36. package/bridge/providers/mock.d.ts +37 -0
  37. package/bridge/providers/mock.js +385 -0
  38. package/bridge/providers/onboarding-commands.d.ts +83 -0
  39. package/bridge/providers/onboarding-commands.js +213 -0
  40. package/bridge/providers/risk-calculator.d.ts +96 -0
  41. package/bridge/providers/risk-calculator.js +369 -0
  42. package/bridge/setup.d.ts +32 -0
  43. package/bridge/setup.js +226 -0
  44. package/bridge/types.d.ts +584 -0
  45. package/bridge/types.js +50 -0
  46. package/bridge/utils/reconnect.d.ts +6 -0
  47. package/bridge/utils/reconnect.js +6 -0
  48. package/bridge/utils/skill-signing.d.ts +51 -0
  49. package/bridge/utils/skill-signing.js +138 -0
  50. package/bridge/utils/skill-version.d.ts +17 -0
  51. package/bridge/utils/skill-version.js +74 -0
  52. package/ccxt/binance-ban-gate.d.ts +47 -0
  53. package/ccxt/binance-ban-gate.js +409 -0
  54. package/ccxt/binance-private.d.ts +325 -0
  55. package/ccxt/binance-private.js +1415 -0
  56. package/ccxt/binance-public.d.ts +18 -0
  57. package/ccxt/binance-public.js +147 -0
  58. package/config/agent-config-client.d.ts +55 -0
  59. package/config/agent-config-client.js +145 -0
  60. package/config/agent-config-poller.d.ts +25 -0
  61. package/config/agent-config-poller.js +100 -0
  62. package/config/brackets-config.d.ts +22 -0
  63. package/config/brackets-config.js +58 -0
  64. package/config/gate-store.d.ts +18 -0
  65. package/config/gate-store.js +61 -0
  66. package/config/plugin-config-io.d.ts +181 -0
  67. package/config/plugin-config-io.js +84 -0
  68. package/config/position-review-config.d.ts +35 -0
  69. package/config/position-review-config.js +105 -0
  70. package/config/tool-gate.d.ts +53 -0
  71. package/config/tool-gate.js +125 -0
  72. package/config/user-data-stream-config.d.ts +85 -0
  73. package/config/user-data-stream-config.js +224 -0
  74. package/connector-supervisor.d.ts +36 -0
  75. package/connector-supervisor.js +149 -0
  76. package/exchange-adapter.d.ts +49 -0
  77. package/exchange-adapter.js +4 -0
  78. package/index.d.ts +30 -0
  79. package/index.js +2030 -0
  80. package/ingest/pending-entry-metadata.d.ts +52 -0
  81. package/ingest/pending-entry-metadata.js +182 -0
  82. package/ingest/position-auto-capture.d.ts +98 -0
  83. package/ingest/position-auto-capture.js +394 -0
  84. package/ingest/position-decisions-client.d.ts +318 -0
  85. package/ingest/position-decisions-client.js +296 -0
  86. package/ingest/reconcile-db-vs-exchange.d.ts +13 -0
  87. package/ingest/reconcile-db-vs-exchange.js +114 -0
  88. package/ingest/reconciler-cleanup.d.ts +37 -0
  89. package/ingest/reconciler-cleanup.js +147 -0
  90. package/ingest/rest-gap-filler.d.ts +191 -0
  91. package/ingest/rest-gap-filler.js +565 -0
  92. package/ingest/touched-symbols-store.d.ts +25 -0
  93. package/ingest/touched-symbols-store.js +96 -0
  94. package/ingest/trade-store-client.d.ts +40 -0
  95. package/ingest/trade-store-client.js +125 -0
  96. package/ingest/ws-ingest.d.ts +43 -0
  97. package/ingest/ws-ingest.js +126 -0
  98. package/learning/setup-family.d.ts +21 -0
  99. package/learning/setup-family.js +103 -0
  100. package/lifecycle/install-signal-handlers.d.ts +33 -0
  101. package/lifecycle/install-signal-handlers.js +112 -0
  102. package/lifecycle/shutdown-coordinator.d.ts +43 -0
  103. package/lifecycle/shutdown-coordinator.js +131 -0
  104. package/live/bracket-id.d.ts +18 -0
  105. package/live/bracket-id.js +81 -0
  106. package/live/bracket-ledger.d.ts +54 -0
  107. package/live/bracket-ledger.js +267 -0
  108. package/live/bracket-manager.d.ts +82 -0
  109. package/live/bracket-manager.js +478 -0
  110. package/live/bracket-params.d.ts +22 -0
  111. package/live/bracket-params.js +124 -0
  112. package/live/bracket-reconciler.d.ts +95 -0
  113. package/live/bracket-reconciler.js +573 -0
  114. package/live/bracket-types.d.ts +102 -0
  115. package/live/bracket-types.js +8 -0
  116. package/live/deposit-tracker.d.ts +62 -0
  117. package/live/deposit-tracker.js +97 -0
  118. package/live/emergency-controls.d.ts +32 -0
  119. package/live/emergency-controls.js +226 -0
  120. package/live/exchange-errors.d.ts +12 -0
  121. package/live/exchange-errors.js +130 -0
  122. package/live/exchange-info-cache.d.ts +35 -0
  123. package/live/exchange-info-cache.js +119 -0
  124. package/live/fact-subscriber.d.ts +78 -0
  125. package/live/fact-subscriber.js +182 -0
  126. package/live/intent-journal.d.ts +42 -0
  127. package/live/intent-journal.js +122 -0
  128. package/live/listen-key-manager.d.ts +70 -0
  129. package/live/listen-key-manager.js +169 -0
  130. package/live/live-adapter.d.ts +264 -0
  131. package/live/live-adapter.js +1665 -0
  132. package/live/live-balance-enricher.d.ts +32 -0
  133. package/live/live-balance-enricher.js +104 -0
  134. package/live/live-bracket-api.d.ts +13 -0
  135. package/live/live-bracket-api.js +20 -0
  136. package/live/live-state-store.d.ts +194 -0
  137. package/live/live-state-store.js +450 -0
  138. package/live/local-signal-service.d.ts +57 -0
  139. package/live/local-signal-service.js +146 -0
  140. package/live/local-strategy-evaluator.d.ts +62 -0
  141. package/live/local-strategy-evaluator.js +127 -0
  142. package/live/microstructure-assembler.d.ts +54 -0
  143. package/live/microstructure-assembler.js +148 -0
  144. package/live/order-poller.d.ts +29 -0
  145. package/live/order-poller.js +125 -0
  146. package/live/position-state-store.d.ts +83 -0
  147. package/live/position-state-store.js +237 -0
  148. package/live/proposal-decision-listener.d.ts +64 -0
  149. package/live/proposal-decision-listener.js +288 -0
  150. package/live/proposal-manager.d.ts +76 -0
  151. package/live/proposal-manager.js +140 -0
  152. package/live/rate-limiter.d.ts +47 -0
  153. package/live/rate-limiter.js +159 -0
  154. package/live/reconciler.d.ts +39 -0
  155. package/live/reconciler.js +175 -0
  156. package/live/setup-buckets.d.ts +7 -0
  157. package/live/setup-buckets.js +33 -0
  158. package/live/slippage-tracker.d.ts +45 -0
  159. package/live/slippage-tracker.js +78 -0
  160. package/live/stop-watcher.d.ts +34 -0
  161. package/live/stop-watcher.js +158 -0
  162. package/live/user-data-active-probe.d.ts +54 -0
  163. package/live/user-data-active-probe.js +180 -0
  164. package/live/user-data-stream-controller.d.ts +200 -0
  165. package/live/user-data-stream-controller.js +579 -0
  166. package/live/user-data-stream-ws.d.ts +22 -0
  167. package/live/user-data-stream-ws.js +63 -0
  168. package/live/user-data-stream.d.ts +243 -0
  169. package/live/user-data-stream.js +704 -0
  170. package/logger.d.ts +2 -0
  171. package/logger.js +2 -0
  172. package/mfe.d.ts +21 -0
  173. package/mfe.js +68 -0
  174. package/onboarding/mode-ladder.d.ts +1 -0
  175. package/onboarding/mode-ladder.js +3 -0
  176. package/onboarding/runtime.d.ts +71 -0
  177. package/onboarding/runtime.js +153 -0
  178. package/openclaw.plugin.json +94 -0
  179. package/package.json +27 -0
  180. package/paper-adapter.d.ts +24 -0
  181. package/paper-adapter.js +91 -0
  182. package/persistence/state-manager.d.ts +42 -0
  183. package/persistence/state-manager.js +164 -0
  184. package/pinned-plan.d.ts +9 -0
  185. package/pinned-plan.js +23 -0
  186. package/risk/pre-trade-check.d.ts +38 -0
  187. package/risk/pre-trade-check.js +345 -0
  188. package/risk/pre-trade-types.d.ts +60 -0
  189. package/risk/pre-trade-types.js +3 -0
  190. package/scripts/assemble.mjs +114 -0
  191. package/shadow/shadow-tracker.d.ts +36 -0
  192. package/shadow/shadow-tracker.js +151 -0
  193. package/shadow/types.d.ts +42 -0
  194. package/shadow/types.js +20 -0
  195. package/shared/indicators-extended.d.ts +52 -0
  196. package/shared/indicators-extended.js +291 -0
  197. package/shared/indicators.d.ts +15 -0
  198. package/shared/indicators.js +114 -0
  199. package/signals/conditions/registry.d.ts +16 -0
  200. package/signals/conditions/registry.js +1274 -0
  201. package/signals/conditions/types.d.ts +1 -0
  202. package/signals/conditions/types.js +4 -0
  203. package/signals/direction-rules.d.ts +3 -0
  204. package/signals/direction-rules.js +24 -0
  205. package/signals/entry-rules.d.ts +6 -0
  206. package/signals/entry-rules.js +33 -0
  207. package/signals/serialize-context.d.ts +4 -0
  208. package/signals/serialize-context.js +39 -0
  209. package/signals/stop-rules.d.ts +3 -0
  210. package/signals/stop-rules.js +48 -0
  211. package/signals/strategy-adapter.d.ts +14 -0
  212. package/signals/strategy-adapter.js +122 -0
  213. package/signals/types.d.ts +1 -0
  214. package/signals/types.js +8 -0
  215. package/simulator/exchange-simulator.d.ts +93 -0
  216. package/simulator/exchange-simulator.js +684 -0
  217. package/simulator/fill-engine.d.ts +53 -0
  218. package/simulator/fill-engine.js +276 -0
  219. package/simulator/paper-market-feed.d.ts +26 -0
  220. package/simulator/paper-market-feed.js +104 -0
  221. package/simulator/realistic-fills.d.ts +59 -0
  222. package/simulator/realistic-fills.js +175 -0
  223. package/simulator/types.d.ts +219 -0
  224. package/simulator/types.js +43 -0
  225. package/skills/reefclaw/SKILL.md +97 -0
  226. package/strategy/builtin-strategies.d.ts +2 -0
  227. package/strategy/builtin-strategies.js +109 -0
  228. package/strategy/condition-registry.d.ts +3 -0
  229. package/strategy/condition-registry.js +153 -0
  230. package/strategy/evaluator.d.ts +67 -0
  231. package/strategy/evaluator.js +93 -0
  232. package/tools/assessment-validation.d.ts +118 -0
  233. package/tools/assessment-validation.js +415 -0
  234. package/tools/attach-brackets.d.ts +34 -0
  235. package/tools/attach-brackets.js +363 -0
  236. package/tools/audit-bracket-protection.d.ts +49 -0
  237. package/tools/audit-bracket-protection.js +527 -0
  238. package/tools/cancel-all-orders.d.ts +7 -0
  239. package/tools/cancel-all-orders.js +5 -0
  240. package/tools/cancel-order.d.ts +10 -0
  241. package/tools/cancel-order.js +14 -0
  242. package/tools/check-position-health.d.ts +46 -0
  243. package/tools/check-position-health.js +194 -0
  244. package/tools/clear-exchange-credentials.d.ts +24 -0
  245. package/tools/clear-exchange-credentials.js +70 -0
  246. package/tools/close-position.d.ts +22 -0
  247. package/tools/close-position.js +449 -0
  248. package/tools/create-order.d.ts +54 -0
  249. package/tools/create-order.js +338 -0
  250. package/tools/exit-gate.d.ts +58 -0
  251. package/tools/exit-gate.js +162 -0
  252. package/tools/fetch-balance.d.ts +5 -0
  253. package/tools/fetch-balance.js +4 -0
  254. package/tools/fetch-ohlcv.d.ts +11 -0
  255. package/tools/fetch-ohlcv.js +8 -0
  256. package/tools/fetch-open-orders.d.ts +7 -0
  257. package/tools/fetch-open-orders.js +4 -0
  258. package/tools/fetch-positions.d.ts +7 -0
  259. package/tools/fetch-positions.js +4 -0
  260. package/tools/fetch-ticker.d.ts +11 -0
  261. package/tools/fetch-ticker.js +5 -0
  262. package/tools/get-agent-profile.d.ts +4 -0
  263. package/tools/get-agent-profile.js +6 -0
  264. package/tools/get-analytics.d.ts +6 -0
  265. package/tools/get-analytics.js +7 -0
  266. package/tools/get-backtest.d.ts +12 -0
  267. package/tools/get-backtest.js +91 -0
  268. package/tools/get-basis.d.ts +7 -0
  269. package/tools/get-basis.js +7 -0
  270. package/tools/get-bracket-config.d.ts +11 -0
  271. package/tools/get-bracket-config.js +24 -0
  272. package/tools/get-cascade-risk.d.ts +7 -0
  273. package/tools/get-cascade-risk.js +8 -0
  274. package/tools/get-crypto-metrics.d.ts +18 -0
  275. package/tools/get-crypto-metrics.js +45 -0
  276. package/tools/get-cvd.d.ts +6 -0
  277. package/tools/get-cvd.js +6 -0
  278. package/tools/get-divergences.d.ts +6 -0
  279. package/tools/get-divergences.js +6 -0
  280. package/tools/get-funding-context.d.ts +6 -0
  281. package/tools/get-funding-context.js +16 -0
  282. package/tools/get-liquidation-levels.d.ts +7 -0
  283. package/tools/get-liquidation-levels.js +7 -0
  284. package/tools/get-liquidation-pulse.d.ts +9 -0
  285. package/tools/get-liquidation-pulse.js +22 -0
  286. package/tools/get-market-breadth.d.ts +6 -0
  287. package/tools/get-market-breadth.js +8 -0
  288. package/tools/get-market-intel.d.ts +19 -0
  289. package/tools/get-market-intel.js +116 -0
  290. package/tools/get-market-structure.d.ts +47 -0
  291. package/tools/get-market-structure.js +198 -0
  292. package/tools/get-my-mined-patterns.d.ts +20 -0
  293. package/tools/get-my-mined-patterns.js +61 -0
  294. package/tools/get-my-proposed-learnings.d.ts +20 -0
  295. package/tools/get-my-proposed-learnings.js +55 -0
  296. package/tools/get-my-recent-reviews.d.ts +22 -0
  297. package/tools/get-my-recent-reviews.js +66 -0
  298. package/tools/get-orderbook.d.ts +21 -0
  299. package/tools/get-orderbook.js +32 -0
  300. package/tools/get-pattern-scan.d.ts +7 -0
  301. package/tools/get-pattern-scan.js +8 -0
  302. package/tools/get-regime.d.ts +6 -0
  303. package/tools/get-regime.js +7 -0
  304. package/tools/get-relevant-learnings.d.ts +21 -0
  305. package/tools/get-relevant-learnings.js +65 -0
  306. package/tools/get-resting-liquidity.d.ts +6 -0
  307. package/tools/get-resting-liquidity.js +11 -0
  308. package/tools/get-risk-scenario.d.ts +29 -0
  309. package/tools/get-risk-scenario.js +47 -0
  310. package/tools/get-risk-summary.d.ts +51 -0
  311. package/tools/get-risk-summary.js +118 -0
  312. package/tools/get-sentiment.d.ts +4 -0
  313. package/tools/get-sentiment.js +6 -0
  314. package/tools/get-session-review.d.ts +7 -0
  315. package/tools/get-session-review.js +8 -0
  316. package/tools/get-setup-detail.d.ts +7 -0
  317. package/tools/get-setup-detail.js +303 -0
  318. package/tools/get-signals.d.ts +15 -0
  319. package/tools/get-signals.js +54 -0
  320. package/tools/get-sizing.d.ts +6 -0
  321. package/tools/get-sizing.js +6 -0
  322. package/tools/get-trade-feedback.d.ts +7 -0
  323. package/tools/get-trade-feedback.js +8 -0
  324. package/tools/get-trade-flow.d.ts +7 -0
  325. package/tools/get-trade-flow.js +7 -0
  326. package/tools/get-volume-analysis.d.ts +21 -0
  327. package/tools/get-volume-analysis.js +74 -0
  328. package/tools/get-volume-profile.d.ts +7 -0
  329. package/tools/get-volume-profile.js +7 -0
  330. package/tools/helpers.d.ts +25 -0
  331. package/tools/helpers.js +38 -0
  332. package/tools/intel-api.d.ts +14 -0
  333. package/tools/intel-api.js +52 -0
  334. package/tools/intel-cache.d.ts +25 -0
  335. package/tools/intel-cache.js +133 -0
  336. package/tools/list-strategies.d.ts +7 -0
  337. package/tools/list-strategies.js +6 -0
  338. package/tools/modify-stop.d.ts +17 -0
  339. package/tools/modify-stop.js +81 -0
  340. package/tools/modify-target.d.ts +17 -0
  341. package/tools/modify-target.js +71 -0
  342. package/tools/propose-learning.d.ts +22 -0
  343. package/tools/propose-learning.js +65 -0
  344. package/tools/query-review-outcomes.d.ts +30 -0
  345. package/tools/query-review-outcomes.js +64 -0
  346. package/tools/query-trades.d.ts +21 -0
  347. package/tools/query-trades.js +37 -0
  348. package/tools/record-position-reviews.d.ts +38 -0
  349. package/tools/record-position-reviews.js +147 -0
  350. package/tools/save-strategy.d.ts +16 -0
  351. package/tools/save-strategy.js +46 -0
  352. package/tools/scan-pairs.d.ts +18 -0
  353. package/tools/scan-pairs.js +220 -0
  354. package/tools/score-setup.d.ts +31 -0
  355. package/tools/score-setup.js +268 -0
  356. package/tools/set-bracket-requirement.d.ts +18 -0
  357. package/tools/set-bracket-requirement.js +81 -0
  358. package/tools/set-exchange-credentials.d.ts +25 -0
  359. package/tools/set-exchange-credentials.js +80 -0
  360. package/tools/set-trading-mode.d.ts +26 -0
  361. package/tools/set-trading-mode.js +135 -0
  362. package/tools/test-exchange-credentials.d.ts +16 -0
  363. package/tools/test-exchange-credentials.js +100 -0
  364. package/tools/toggle-strategy.d.ts +8 -0
  365. package/tools/toggle-strategy.js +8 -0
  366. package/trading-params-cache.d.ts +26 -0
  367. package/trading-params-cache.js +52 -0
  368. package/types.d.ts +110 -0
  369. package/types.js +7 -0
  370. package/util/plugin-paths.d.ts +3 -0
  371. package/util/plugin-paths.js +15 -0
@@ -0,0 +1,200 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { BinancePrivateApi } from '../ccxt/binance-private.js';
3
+ import { UserDataStream } from './user-data-stream.js';
4
+ import type { ParsedAlgoUpdate } from './user-data-stream.js';
5
+ import { LiveStateStore } from './live-state-store.js';
6
+ import type { RestSnapshot, StateDrift } from './live-state-store.js';
7
+ import type { UserDataStreamMode, UserDataStreamTunables } from '../config/user-data-stream-config.js';
8
+ import type { CcxtBalance } from '../types.js';
9
+ import type { TradeStoreClient } from '../ingest/trade-store-client.js';
10
+ import type { TouchedSymbolsStore } from '../ingest/touched-symbols-store.js';
11
+ import type { AutoCaptureContext } from '../ingest/position-auto-capture.js';
12
+ /**
13
+ * Rewrite `balance.total[asset]` from CCXT's marginBalance-equivalent (wallet
14
+ * + unrealizedProfit for Binance Futures) to raw walletBalance only, so the
15
+ * REST snapshot aligns with what the WS ACCOUNT_UPDATE frames deliver. The
16
+ * raw walletBalance field lives under `balance.info.assets[i].walletBalance`
17
+ * — an array of per-asset records Binance Futures always returns alongside
18
+ * the top-level totals. Exported for unit testing.
19
+ *
20
+ * Falls back to the unmodified balance if `info.assets` is missing or
21
+ * malformed (e.g. mock responses in unit tests without the info envelope).
22
+ * Only `total` is rewritten; `free` and `used` are left untouched because
23
+ * the WS store computes them separately from position-lock state.
24
+ */
25
+ export declare function normalizeBinanceFuturesBalance(balance: CcxtBalance): CcxtBalance;
26
+ /**
27
+ * Thrown by `buildSnapshot` when ANY of the three REST fetches returned
28
+ * `null` — i.e. the fetch FAILED (Binance 429 / weight-paced / transient
29
+ * network), state is UNKNOWN. It does NOT mean "the account is flat / has no
30
+ * orders". `LiveStateStore.applySnapshot` replaces positions + orders +
31
+ * balances WHOLESALE, so applying a snapshot built from a failed fetch would
32
+ * wipe still-live positions and bracket SL/TP from the store — which is the
33
+ * AUTHORITATIVE read path in observe/enforce mode — blinding the agent into
34
+ * the documented phantom-naked spiral.
35
+ *
36
+ * Subclass of `Error` so the existing `.catch()` sites absorb it unchanged;
37
+ * callers detect the type to skip the apply, leave the store intact, and let
38
+ * WS deltas + the next reconnect/resync repair state. Same null≠empty rule as
39
+ * `getOpenOrders` / `getPositions` / `closePosition` / the bracket reconciler.
40
+ */
41
+ export declare class UntrustedSnapshotError extends Error {
42
+ constructor(message: string);
43
+ }
44
+ export interface ControllerTimerDeps {
45
+ setInterval: (fn: () => void, ms: number) => ReturnType<typeof setInterval>;
46
+ clearInterval: (handle: ReturnType<typeof setInterval>) => void;
47
+ now: () => number;
48
+ }
49
+ export interface UserDataStreamControllerOptions {
50
+ mode: UserDataStreamMode;
51
+ testnet: boolean;
52
+ tunables: UserDataStreamTunables;
53
+ /** If absent, a real WS stream is built from `defaultWebSocketFactory`.
54
+ * Tests inject a prebuilt stream to avoid touching the network. */
55
+ stream?: UserDataStream;
56
+ /** If absent, a fresh LiveStateStore is constructed. */
57
+ store?: LiveStateStore;
58
+ /** 60_000 by default. Shorter values allowed for post-drift tightening. */
59
+ truthCheckIntervalMs?: number;
60
+ /** Timer injection for unit tests. */
61
+ timers?: Partial<ControllerTimerDeps>;
62
+ /** Audit-trail ingest path (TRADE_AUDIT_TRAIL_PLAN Phase 1). When present
63
+ * AND mode≠'off', the controller starts a WsIngest alongside the stream
64
+ * that POSTs every TRADE event to the webapp's /api/internal/trades.
65
+ * Caller decides whether to pass this in based on userDataStream.dbWrite. */
66
+ tradeIngest?: {
67
+ client: TradeStoreClient;
68
+ userId: string;
69
+ exchange?: string;
70
+ /** Optional override for the gap-filler's persistent touched-symbols
71
+ * store. Pass `null` to disable cross-restart persistence (tests).
72
+ * Production callers leave this undefined to get the file-backed
73
+ * default under ~/.reefclaw/touched-symbols-<userId>.json. */
74
+ touchedSymbolsStore?: TouchedSymbolsStore | null;
75
+ };
76
+ /** Position-decision auto-capture context. When provided alongside
77
+ * tradeIngest, the controller passes it to WsIngest so every TRADE event
78
+ * is also routed through `onWsFillObserved` (limit-order entries +
79
+ * scale-ins). When omitted, ws-ingest only records to the audit trail
80
+ * (the legacy PR1 behaviour). */
81
+ autoCapture?: AutoCaptureContext;
82
+ }
83
+ export type ControllerEvents = {
84
+ /** Emitted after every REST snapshot has been applied. */
85
+ snapshotApplied: (snap: RestSnapshot) => void;
86
+ /** Emitted when the 60s drift check finds anything (minor or major). */
87
+ drift: (drift: StateDrift) => void;
88
+ /** Emitted when a major drift triggered a forced resync. */
89
+ forcedResync: (cause: string) => void;
90
+ /** Emitted when the stream reports a reconnect — observability. */
91
+ reconnecting: (attempt: number, delayMs: number) => void;
92
+ /** Pass-through of advisory events from the stream. */
93
+ marginCall: (ev: unknown) => void;
94
+ /** Pass-through of ALGO_UPDATE (conditional/bracket order lifecycle).
95
+ * LiveAdapter consumes this as the AUTHORITATIVE bracket-state signal —
96
+ * Binance pushes EXPIRED when it auto-cancels a sibling on position
97
+ * close, CANCELED only on an explicit cancel, TRIGGERED/FINISHED on
98
+ * fire. Replaces REST-audit guessing. */
99
+ algoUpdate: (ev: ParsedAlgoUpdate) => void;
100
+ };
101
+ export declare class UserDataStreamController extends EventEmitter {
102
+ readonly mode: UserDataStreamMode;
103
+ private readonly api;
104
+ private readonly stream;
105
+ private readonly store;
106
+ private readonly truthCheckIntervalMs;
107
+ private readonly staleStoreThresholdMs;
108
+ private readonly timers;
109
+ private truthCheckTimer;
110
+ private algoRefreshTimer;
111
+ private reconnectRateTimer;
112
+ private readonly algoRefreshMs;
113
+ private readonly wsIngest;
114
+ private readonly restGapFiller;
115
+ private readonly activeProbe;
116
+ /** Count of stale-forced + other reconnects in the current hourly window.
117
+ * Checked every hour; a spike above RECONNECT_RATE_ALERT_THRESHOLD logs
118
+ * a WARN so operator can spot Binance-side trouble or network flaps. */
119
+ private reconnectCountThisHour;
120
+ private running;
121
+ private snapshotInFlight;
122
+ /** Serialises snapshot applies so WS events don't race with a snapshot
123
+ * we're in the middle of fetching. WS events that arrive during a
124
+ * snapshot are buffered here and drained after apply. */
125
+ private bufferedDuringSnapshot;
126
+ private consecutiveMajorDrifts;
127
+ constructor(api: BinancePrivateApi, options: UserDataStreamControllerOptions);
128
+ getStore(): LiveStateStore;
129
+ getStream(): UserDataStream;
130
+ /** True when the in-memory store is safe to serve as the authoritative
131
+ * source for positions/orders reads. Two independent conditions, BOTH
132
+ * required — each guards a distinct failure in the null≠empty class
133
+ * (same class as the getOpenOrders / getPositions / closePosition /
134
+ * bracket-reconciler / UntrustedSnapshotError rules):
135
+ *
136
+ * (1) **Seeded.** A trusted REST snapshot has run at least once
137
+ * (`lastSnapshotAt !== null`). False during startup before the
138
+ * `connected` handler's initial snapshot lands and the gap after
139
+ * `reset()`. An unseeded `[]` is indistinguishable from "no
140
+ * positions/orders" and would trip naked-bracket / orphan-cancel
141
+ * paths against real exchange state.
142
+ *
143
+ * (2) **Fresh.** We've received SOME incoming frame within
144
+ * `staleStoreThresholdMs` — the SAME calibrated threshold
145
+ * (`staleEventWatchdogMs`, default 6 min) and the SAME signal
146
+ * (`lastFrameAt`, any frame incl. Binance's 3-min server pings) the
147
+ * dead-socket watchdog itself uses to declare the socket dead.
148
+ * Beyond it the watchdog is already forcing a reconnect; serving a
149
+ * seeded-but-stale store as authoritative there would present stale
150
+ * state as truth on a destructive-action-gating read — the residual
151
+ * a reviewer flagged. Deliberately NOT a bare `isConnected()` check:
152
+ * a brief reconnect (listenKey rotation ~25 min, 1 s→60 s backoff)
153
+ * keeps `lastFrameAt` recent, so the common case is NOT pushed onto
154
+ * the weight-heavy / rate-limit-poisoned REST path — that would just
155
+ * trade one failure in this class for another. When the reconnect +
156
+ * resync completes, `lastFrameAt` refreshes and the store is trusted
157
+ * again. `lastFrameAt === null` (seeded but never a frame — an odd
158
+ * state) is conservatively treated as untrusted. */
159
+ isStoreTrusted(): boolean;
160
+ /** Start the stream + run the initial REST snapshot + seed the store.
161
+ * No-op if mode is 'off'. Throws if already running. */
162
+ start(): Promise<void>;
163
+ /** Graceful shutdown. */
164
+ stop(): Promise<void>;
165
+ /** Force a full snapshot + re-seed. Used by operator tools for manual resync. */
166
+ forceResync(cause: string): Promise<void>;
167
+ private buildStreamOptions;
168
+ private attachStreamHandlers;
169
+ /** Fetch REST positions/balance/orders and normalise symbols so the store
170
+ * keys match WS events regardless of which write path landed first.
171
+ * CCXT returns `BTC/USDT:USDT`; our WS parser produces `BTC/USDT`. */
172
+ private buildSnapshot;
173
+ private takeAndApplySnapshot;
174
+ private startTruthCheckLoop;
175
+ private stopTruthCheckLoop;
176
+ /** Start the algo-order refresh loop — REST-polls open orders and replaces
177
+ * the algo (bracket SL/TP) subset in the store. Fills the gap left by
178
+ * Binance's WS not emitting ORDER_TRADE_UPDATE for algo orders until they
179
+ * trigger. Disabled when algoRefreshMs === 0. */
180
+ private startAlgoRefreshLoop;
181
+ private stopAlgoRefreshLoop;
182
+ /** Alert threshold — hourly reconnect count that logs a WARN. Set at
183
+ * 10/hour because the natural baseline on a quiet account (listenKey
184
+ * rotation every 25 min + occasional stale-watchdog firing) is
185
+ * 3-4/hour; anything consistently above that is unexpected. Does NOT
186
+ * auto-pause or take action — operator investigates when they see
187
+ * the log line land. */
188
+ private static readonly RECONNECT_RATE_ALERT_THRESHOLD;
189
+ private static readonly RECONNECT_RATE_WINDOW_MS;
190
+ /** Start the reconnect-rate monitor. Runs hourly; resets the counter
191
+ * after each check whether or not it alerted. */
192
+ private startReconnectRateMonitor;
193
+ private stopReconnectRateMonitor;
194
+ /** One pass of algo-order refresh: fetch open orders (merges regular + algo
195
+ * via BinancePrivateApi), filter to algo-bracket cids, and hand them to the
196
+ * store's replaceAlgoOrders. No mutation if WS isn't connected (we'd be
197
+ * polluting state the reconnect snapshot is about to replace anyway). */
198
+ private runAlgoRefresh;
199
+ private runTruthCheck;
200
+ }