@reefclaw/connect 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 (415) hide show
  1. package/assets/bridge/bridge.d.ts +96 -0
  2. package/assets/bridge/bridge.js +969 -0
  3. package/assets/bridge/config.d.ts +43 -0
  4. package/assets/bridge/config.js +176 -0
  5. package/assets/bridge/connector.d.ts +52 -0
  6. package/assets/bridge/connector.js +293 -0
  7. package/assets/bridge/event-replay-buffer.d.ts +43 -0
  8. package/assets/bridge/event-replay-buffer.js +109 -0
  9. package/assets/bridge/gateway/event-parser.d.ts +209 -0
  10. package/assets/bridge/gateway/event-parser.js +793 -0
  11. package/assets/bridge/gateway/gateway-config.d.ts +39 -0
  12. package/assets/bridge/gateway/gateway-config.js +86 -0
  13. package/assets/bridge/gateway/gateway-http-client.d.ts +50 -0
  14. package/assets/bridge/gateway/gateway-http-client.js +165 -0
  15. package/assets/bridge/gateway/gateway-ws-client.d.ts +116 -0
  16. package/assets/bridge/gateway/gateway-ws-client.js +417 -0
  17. package/assets/bridge/gateway/poller.d.ts +146 -0
  18. package/assets/bridge/gateway/poller.js +505 -0
  19. package/assets/bridge/gateway/tool-discovery.d.ts +25 -0
  20. package/assets/bridge/gateway/tool-discovery.js +198 -0
  21. package/assets/bridge/index.d.ts +2 -0
  22. package/assets/bridge/index.js +253 -0
  23. package/assets/bridge/logger.d.ts +2 -0
  24. package/assets/bridge/logger.js +2 -0
  25. package/assets/bridge/provider.d.ts +156 -0
  26. package/assets/bridge/provider.js +2 -0
  27. package/assets/bridge/providers/emergency-commands.d.ts +54 -0
  28. package/assets/bridge/providers/emergency-commands.js +235 -0
  29. package/assets/bridge/providers/gateway.d.ts +322 -0
  30. package/assets/bridge/providers/gateway.js +2302 -0
  31. package/assets/bridge/providers/mock.d.ts +37 -0
  32. package/assets/bridge/providers/mock.js +385 -0
  33. package/assets/bridge/providers/onboarding-commands.d.ts +83 -0
  34. package/assets/bridge/providers/onboarding-commands.js +213 -0
  35. package/assets/bridge/providers/risk-calculator.d.ts +96 -0
  36. package/assets/bridge/providers/risk-calculator.js +369 -0
  37. package/assets/bridge/setup.d.ts +32 -0
  38. package/assets/bridge/setup.js +226 -0
  39. package/assets/bridge/types.d.ts +584 -0
  40. package/assets/bridge/types.js +50 -0
  41. package/assets/bridge/utils/reconnect.d.ts +6 -0
  42. package/assets/bridge/utils/reconnect.js +6 -0
  43. package/assets/bridge/utils/skill-signing.d.ts +51 -0
  44. package/assets/bridge/utils/skill-signing.js +138 -0
  45. package/assets/bridge/utils/skill-version.d.ts +17 -0
  46. package/assets/bridge/utils/skill-version.js +71 -0
  47. package/assets/plugin/audit/mode-transition-audit.d.ts +11 -0
  48. package/assets/plugin/audit/mode-transition-audit.js +29 -0
  49. package/assets/plugin/balance-utils.d.ts +36 -0
  50. package/assets/plugin/balance-utils.js +98 -0
  51. package/assets/plugin/ccxt/binance-ban-gate.d.ts +47 -0
  52. package/assets/plugin/ccxt/binance-ban-gate.js +409 -0
  53. package/assets/plugin/ccxt/binance-private.d.ts +325 -0
  54. package/assets/plugin/ccxt/binance-private.js +1415 -0
  55. package/assets/plugin/ccxt/binance-public.d.ts +18 -0
  56. package/assets/plugin/ccxt/binance-public.js +147 -0
  57. package/assets/plugin/config/agent-config-client.d.ts +55 -0
  58. package/assets/plugin/config/agent-config-client.js +145 -0
  59. package/assets/plugin/config/agent-config-poller.d.ts +25 -0
  60. package/assets/plugin/config/agent-config-poller.js +100 -0
  61. package/assets/plugin/config/brackets-config.d.ts +22 -0
  62. package/assets/plugin/config/brackets-config.js +58 -0
  63. package/assets/plugin/config/gate-store.d.ts +18 -0
  64. package/assets/plugin/config/gate-store.js +61 -0
  65. package/assets/plugin/config/plugin-config-io.d.ts +175 -0
  66. package/assets/plugin/config/plugin-config-io.js +84 -0
  67. package/assets/plugin/config/position-review-config.d.ts +35 -0
  68. package/assets/plugin/config/position-review-config.js +105 -0
  69. package/assets/plugin/config/tool-gate.d.ts +53 -0
  70. package/assets/plugin/config/tool-gate.js +125 -0
  71. package/assets/plugin/config/user-data-stream-config.d.ts +85 -0
  72. package/assets/plugin/config/user-data-stream-config.js +224 -0
  73. package/assets/plugin/exchange-adapter.d.ts +49 -0
  74. package/assets/plugin/exchange-adapter.js +4 -0
  75. package/assets/plugin/index.d.ts +30 -0
  76. package/assets/plugin/index.js +1989 -0
  77. package/assets/plugin/ingest/pending-entry-metadata.d.ts +52 -0
  78. package/assets/plugin/ingest/pending-entry-metadata.js +182 -0
  79. package/assets/plugin/ingest/position-auto-capture.d.ts +98 -0
  80. package/assets/plugin/ingest/position-auto-capture.js +394 -0
  81. package/assets/plugin/ingest/position-decisions-client.d.ts +318 -0
  82. package/assets/plugin/ingest/position-decisions-client.js +296 -0
  83. package/assets/plugin/ingest/reconcile-db-vs-exchange.d.ts +13 -0
  84. package/assets/plugin/ingest/reconcile-db-vs-exchange.js +114 -0
  85. package/assets/plugin/ingest/reconciler-cleanup.d.ts +37 -0
  86. package/assets/plugin/ingest/reconciler-cleanup.js +147 -0
  87. package/assets/plugin/ingest/rest-gap-filler.d.ts +191 -0
  88. package/assets/plugin/ingest/rest-gap-filler.js +565 -0
  89. package/assets/plugin/ingest/touched-symbols-store.d.ts +25 -0
  90. package/assets/plugin/ingest/touched-symbols-store.js +96 -0
  91. package/assets/plugin/ingest/trade-store-client.d.ts +40 -0
  92. package/assets/plugin/ingest/trade-store-client.js +125 -0
  93. package/assets/plugin/ingest/ws-ingest.d.ts +43 -0
  94. package/assets/plugin/ingest/ws-ingest.js +126 -0
  95. package/assets/plugin/learning/setup-family.d.ts +21 -0
  96. package/assets/plugin/learning/setup-family.js +103 -0
  97. package/assets/plugin/lifecycle/install-signal-handlers.d.ts +33 -0
  98. package/assets/plugin/lifecycle/install-signal-handlers.js +112 -0
  99. package/assets/plugin/lifecycle/shutdown-coordinator.d.ts +43 -0
  100. package/assets/plugin/lifecycle/shutdown-coordinator.js +131 -0
  101. package/assets/plugin/live/bracket-id.d.ts +18 -0
  102. package/assets/plugin/live/bracket-id.js +81 -0
  103. package/assets/plugin/live/bracket-ledger.d.ts +54 -0
  104. package/assets/plugin/live/bracket-ledger.js +267 -0
  105. package/assets/plugin/live/bracket-manager.d.ts +82 -0
  106. package/assets/plugin/live/bracket-manager.js +478 -0
  107. package/assets/plugin/live/bracket-params.d.ts +22 -0
  108. package/assets/plugin/live/bracket-params.js +124 -0
  109. package/assets/plugin/live/bracket-reconciler.d.ts +95 -0
  110. package/assets/plugin/live/bracket-reconciler.js +573 -0
  111. package/assets/plugin/live/bracket-types.d.ts +102 -0
  112. package/assets/plugin/live/bracket-types.js +8 -0
  113. package/assets/plugin/live/deposit-tracker.d.ts +62 -0
  114. package/assets/plugin/live/deposit-tracker.js +97 -0
  115. package/assets/plugin/live/emergency-controls.d.ts +32 -0
  116. package/assets/plugin/live/emergency-controls.js +226 -0
  117. package/assets/plugin/live/exchange-errors.d.ts +12 -0
  118. package/assets/plugin/live/exchange-errors.js +130 -0
  119. package/assets/plugin/live/exchange-info-cache.d.ts +35 -0
  120. package/assets/plugin/live/exchange-info-cache.js +119 -0
  121. package/assets/plugin/live/fact-subscriber.d.ts +78 -0
  122. package/assets/plugin/live/fact-subscriber.js +182 -0
  123. package/assets/plugin/live/intent-journal.d.ts +42 -0
  124. package/assets/plugin/live/intent-journal.js +122 -0
  125. package/assets/plugin/live/listen-key-manager.d.ts +70 -0
  126. package/assets/plugin/live/listen-key-manager.js +169 -0
  127. package/assets/plugin/live/live-adapter.d.ts +264 -0
  128. package/assets/plugin/live/live-adapter.js +1665 -0
  129. package/assets/plugin/live/live-balance-enricher.d.ts +32 -0
  130. package/assets/plugin/live/live-balance-enricher.js +104 -0
  131. package/assets/plugin/live/live-bracket-api.d.ts +13 -0
  132. package/assets/plugin/live/live-bracket-api.js +20 -0
  133. package/assets/plugin/live/live-state-store.d.ts +194 -0
  134. package/assets/plugin/live/live-state-store.js +450 -0
  135. package/assets/plugin/live/local-signal-service.d.ts +57 -0
  136. package/assets/plugin/live/local-signal-service.js +146 -0
  137. package/assets/plugin/live/local-strategy-evaluator.d.ts +62 -0
  138. package/assets/plugin/live/local-strategy-evaluator.js +127 -0
  139. package/assets/plugin/live/microstructure-assembler.d.ts +54 -0
  140. package/assets/plugin/live/microstructure-assembler.js +148 -0
  141. package/assets/plugin/live/order-poller.d.ts +29 -0
  142. package/assets/plugin/live/order-poller.js +125 -0
  143. package/assets/plugin/live/position-state-store.d.ts +83 -0
  144. package/assets/plugin/live/position-state-store.js +237 -0
  145. package/assets/plugin/live/proposal-decision-listener.d.ts +64 -0
  146. package/assets/plugin/live/proposal-decision-listener.js +288 -0
  147. package/assets/plugin/live/proposal-manager.d.ts +76 -0
  148. package/assets/plugin/live/proposal-manager.js +140 -0
  149. package/assets/plugin/live/rate-limiter.d.ts +47 -0
  150. package/assets/plugin/live/rate-limiter.js +159 -0
  151. package/assets/plugin/live/reconciler.d.ts +39 -0
  152. package/assets/plugin/live/reconciler.js +175 -0
  153. package/assets/plugin/live/setup-buckets.d.ts +7 -0
  154. package/assets/plugin/live/setup-buckets.js +33 -0
  155. package/assets/plugin/live/slippage-tracker.d.ts +45 -0
  156. package/assets/plugin/live/slippage-tracker.js +78 -0
  157. package/assets/plugin/live/stop-watcher.d.ts +34 -0
  158. package/assets/plugin/live/stop-watcher.js +158 -0
  159. package/assets/plugin/live/user-data-active-probe.d.ts +54 -0
  160. package/assets/plugin/live/user-data-active-probe.js +180 -0
  161. package/assets/plugin/live/user-data-stream-controller.d.ts +200 -0
  162. package/assets/plugin/live/user-data-stream-controller.js +579 -0
  163. package/assets/plugin/live/user-data-stream-ws.d.ts +22 -0
  164. package/assets/plugin/live/user-data-stream-ws.js +63 -0
  165. package/assets/plugin/live/user-data-stream.d.ts +243 -0
  166. package/assets/plugin/live/user-data-stream.js +704 -0
  167. package/assets/plugin/logger.d.ts +2 -0
  168. package/assets/plugin/logger.js +2 -0
  169. package/assets/plugin/mfe.d.ts +21 -0
  170. package/assets/plugin/mfe.js +68 -0
  171. package/assets/plugin/onboarding/mode-ladder.d.ts +1 -0
  172. package/assets/plugin/onboarding/mode-ladder.js +3 -0
  173. package/assets/plugin/onboarding/runtime.d.ts +71 -0
  174. package/assets/plugin/onboarding/runtime.js +153 -0
  175. package/assets/plugin/openclaw.plugin.json +91 -0
  176. package/assets/plugin/paper-adapter.d.ts +24 -0
  177. package/assets/plugin/paper-adapter.js +91 -0
  178. package/assets/plugin/persistence/state-manager.d.ts +42 -0
  179. package/assets/plugin/persistence/state-manager.js +164 -0
  180. package/assets/plugin/pinned-plan.d.ts +9 -0
  181. package/assets/plugin/pinned-plan.js +23 -0
  182. package/assets/plugin/risk/pre-trade-check.d.ts +38 -0
  183. package/assets/plugin/risk/pre-trade-check.js +345 -0
  184. package/assets/plugin/risk/pre-trade-types.d.ts +60 -0
  185. package/assets/plugin/risk/pre-trade-types.js +3 -0
  186. package/assets/plugin/shadow/shadow-tracker.d.ts +36 -0
  187. package/assets/plugin/shadow/shadow-tracker.js +151 -0
  188. package/assets/plugin/shadow/types.d.ts +42 -0
  189. package/assets/plugin/shadow/types.js +20 -0
  190. package/assets/plugin/shared/indicators-extended.d.ts +52 -0
  191. package/assets/plugin/shared/indicators-extended.js +291 -0
  192. package/assets/plugin/shared/indicators.d.ts +15 -0
  193. package/assets/plugin/shared/indicators.js +114 -0
  194. package/assets/plugin/signals/conditions/registry.d.ts +16 -0
  195. package/assets/plugin/signals/conditions/registry.js +1274 -0
  196. package/assets/plugin/signals/conditions/types.d.ts +1 -0
  197. package/assets/plugin/signals/conditions/types.js +4 -0
  198. package/assets/plugin/signals/direction-rules.d.ts +3 -0
  199. package/assets/plugin/signals/direction-rules.js +24 -0
  200. package/assets/plugin/signals/entry-rules.d.ts +6 -0
  201. package/assets/plugin/signals/entry-rules.js +33 -0
  202. package/assets/plugin/signals/serialize-context.d.ts +4 -0
  203. package/assets/plugin/signals/serialize-context.js +39 -0
  204. package/assets/plugin/signals/stop-rules.d.ts +3 -0
  205. package/assets/plugin/signals/stop-rules.js +48 -0
  206. package/assets/plugin/signals/strategy-adapter.d.ts +14 -0
  207. package/assets/plugin/signals/strategy-adapter.js +122 -0
  208. package/assets/plugin/signals/types.d.ts +1 -0
  209. package/assets/plugin/signals/types.js +8 -0
  210. package/assets/plugin/simulator/exchange-simulator.d.ts +93 -0
  211. package/assets/plugin/simulator/exchange-simulator.js +684 -0
  212. package/assets/plugin/simulator/fill-engine.d.ts +53 -0
  213. package/assets/plugin/simulator/fill-engine.js +276 -0
  214. package/assets/plugin/simulator/paper-market-feed.d.ts +26 -0
  215. package/assets/plugin/simulator/paper-market-feed.js +104 -0
  216. package/assets/plugin/simulator/realistic-fills.d.ts +59 -0
  217. package/assets/plugin/simulator/realistic-fills.js +175 -0
  218. package/assets/plugin/simulator/types.d.ts +219 -0
  219. package/assets/plugin/simulator/types.js +43 -0
  220. package/assets/plugin/strategy/builtin-strategies.d.ts +2 -0
  221. package/assets/plugin/strategy/builtin-strategies.js +109 -0
  222. package/assets/plugin/strategy/condition-registry.d.ts +3 -0
  223. package/assets/plugin/strategy/condition-registry.js +153 -0
  224. package/assets/plugin/strategy/evaluator.d.ts +67 -0
  225. package/assets/plugin/strategy/evaluator.js +93 -0
  226. package/assets/plugin/tools/assessment-validation.d.ts +118 -0
  227. package/assets/plugin/tools/assessment-validation.js +415 -0
  228. package/assets/plugin/tools/attach-brackets.d.ts +34 -0
  229. package/assets/plugin/tools/attach-brackets.js +363 -0
  230. package/assets/plugin/tools/audit-bracket-protection.d.ts +49 -0
  231. package/assets/plugin/tools/audit-bracket-protection.js +527 -0
  232. package/assets/plugin/tools/cancel-all-orders.d.ts +7 -0
  233. package/assets/plugin/tools/cancel-all-orders.js +5 -0
  234. package/assets/plugin/tools/cancel-order.d.ts +10 -0
  235. package/assets/plugin/tools/cancel-order.js +14 -0
  236. package/assets/plugin/tools/check-position-health.d.ts +46 -0
  237. package/assets/plugin/tools/check-position-health.js +194 -0
  238. package/assets/plugin/tools/clear-exchange-credentials.d.ts +24 -0
  239. package/assets/plugin/tools/clear-exchange-credentials.js +70 -0
  240. package/assets/plugin/tools/close-position.d.ts +22 -0
  241. package/assets/plugin/tools/close-position.js +449 -0
  242. package/assets/plugin/tools/create-order.d.ts +54 -0
  243. package/assets/plugin/tools/create-order.js +338 -0
  244. package/assets/plugin/tools/exit-gate.d.ts +58 -0
  245. package/assets/plugin/tools/exit-gate.js +162 -0
  246. package/assets/plugin/tools/fetch-balance.d.ts +5 -0
  247. package/assets/plugin/tools/fetch-balance.js +4 -0
  248. package/assets/plugin/tools/fetch-ohlcv.d.ts +11 -0
  249. package/assets/plugin/tools/fetch-ohlcv.js +8 -0
  250. package/assets/plugin/tools/fetch-open-orders.d.ts +7 -0
  251. package/assets/plugin/tools/fetch-open-orders.js +4 -0
  252. package/assets/plugin/tools/fetch-positions.d.ts +7 -0
  253. package/assets/plugin/tools/fetch-positions.js +4 -0
  254. package/assets/plugin/tools/fetch-ticker.d.ts +11 -0
  255. package/assets/plugin/tools/fetch-ticker.js +5 -0
  256. package/assets/plugin/tools/get-agent-profile.d.ts +4 -0
  257. package/assets/plugin/tools/get-agent-profile.js +6 -0
  258. package/assets/plugin/tools/get-analytics.d.ts +6 -0
  259. package/assets/plugin/tools/get-analytics.js +7 -0
  260. package/assets/plugin/tools/get-backtest.d.ts +12 -0
  261. package/assets/plugin/tools/get-backtest.js +91 -0
  262. package/assets/plugin/tools/get-basis.d.ts +7 -0
  263. package/assets/plugin/tools/get-basis.js +7 -0
  264. package/assets/plugin/tools/get-bracket-config.d.ts +11 -0
  265. package/assets/plugin/tools/get-bracket-config.js +24 -0
  266. package/assets/plugin/tools/get-cascade-risk.d.ts +7 -0
  267. package/assets/plugin/tools/get-cascade-risk.js +8 -0
  268. package/assets/plugin/tools/get-crypto-metrics.d.ts +18 -0
  269. package/assets/plugin/tools/get-crypto-metrics.js +45 -0
  270. package/assets/plugin/tools/get-cvd.d.ts +6 -0
  271. package/assets/plugin/tools/get-cvd.js +6 -0
  272. package/assets/plugin/tools/get-divergences.d.ts +6 -0
  273. package/assets/plugin/tools/get-divergences.js +6 -0
  274. package/assets/plugin/tools/get-funding-context.d.ts +6 -0
  275. package/assets/plugin/tools/get-funding-context.js +16 -0
  276. package/assets/plugin/tools/get-liquidation-levels.d.ts +7 -0
  277. package/assets/plugin/tools/get-liquidation-levels.js +7 -0
  278. package/assets/plugin/tools/get-liquidation-pulse.d.ts +9 -0
  279. package/assets/plugin/tools/get-liquidation-pulse.js +22 -0
  280. package/assets/plugin/tools/get-market-breadth.d.ts +6 -0
  281. package/assets/plugin/tools/get-market-breadth.js +8 -0
  282. package/assets/plugin/tools/get-market-intel.d.ts +19 -0
  283. package/assets/plugin/tools/get-market-intel.js +116 -0
  284. package/assets/plugin/tools/get-market-structure.d.ts +47 -0
  285. package/assets/plugin/tools/get-market-structure.js +198 -0
  286. package/assets/plugin/tools/get-my-mined-patterns.d.ts +20 -0
  287. package/assets/plugin/tools/get-my-mined-patterns.js +61 -0
  288. package/assets/plugin/tools/get-my-proposed-learnings.d.ts +20 -0
  289. package/assets/plugin/tools/get-my-proposed-learnings.js +55 -0
  290. package/assets/plugin/tools/get-my-recent-reviews.d.ts +22 -0
  291. package/assets/plugin/tools/get-my-recent-reviews.js +66 -0
  292. package/assets/plugin/tools/get-orderbook.d.ts +21 -0
  293. package/assets/plugin/tools/get-orderbook.js +32 -0
  294. package/assets/plugin/tools/get-pattern-scan.d.ts +7 -0
  295. package/assets/plugin/tools/get-pattern-scan.js +8 -0
  296. package/assets/plugin/tools/get-regime.d.ts +6 -0
  297. package/assets/plugin/tools/get-regime.js +7 -0
  298. package/assets/plugin/tools/get-relevant-learnings.d.ts +21 -0
  299. package/assets/plugin/tools/get-relevant-learnings.js +65 -0
  300. package/assets/plugin/tools/get-resting-liquidity.d.ts +6 -0
  301. package/assets/plugin/tools/get-resting-liquidity.js +11 -0
  302. package/assets/plugin/tools/get-risk-scenario.d.ts +29 -0
  303. package/assets/plugin/tools/get-risk-scenario.js +47 -0
  304. package/assets/plugin/tools/get-risk-summary.d.ts +51 -0
  305. package/assets/plugin/tools/get-risk-summary.js +118 -0
  306. package/assets/plugin/tools/get-sentiment.d.ts +4 -0
  307. package/assets/plugin/tools/get-sentiment.js +6 -0
  308. package/assets/plugin/tools/get-session-review.d.ts +7 -0
  309. package/assets/plugin/tools/get-session-review.js +8 -0
  310. package/assets/plugin/tools/get-setup-detail.d.ts +7 -0
  311. package/assets/plugin/tools/get-setup-detail.js +303 -0
  312. package/assets/plugin/tools/get-signals.d.ts +15 -0
  313. package/assets/plugin/tools/get-signals.js +54 -0
  314. package/assets/plugin/tools/get-sizing.d.ts +6 -0
  315. package/assets/plugin/tools/get-sizing.js +6 -0
  316. package/assets/plugin/tools/get-trade-feedback.d.ts +7 -0
  317. package/assets/plugin/tools/get-trade-feedback.js +8 -0
  318. package/assets/plugin/tools/get-trade-flow.d.ts +7 -0
  319. package/assets/plugin/tools/get-trade-flow.js +7 -0
  320. package/assets/plugin/tools/get-volume-analysis.d.ts +21 -0
  321. package/assets/plugin/tools/get-volume-analysis.js +74 -0
  322. package/assets/plugin/tools/get-volume-profile.d.ts +7 -0
  323. package/assets/plugin/tools/get-volume-profile.js +7 -0
  324. package/assets/plugin/tools/helpers.d.ts +25 -0
  325. package/assets/plugin/tools/helpers.js +38 -0
  326. package/assets/plugin/tools/intel-api.d.ts +14 -0
  327. package/assets/plugin/tools/intel-api.js +52 -0
  328. package/assets/plugin/tools/intel-cache.d.ts +25 -0
  329. package/assets/plugin/tools/intel-cache.js +133 -0
  330. package/assets/plugin/tools/list-strategies.d.ts +7 -0
  331. package/assets/plugin/tools/list-strategies.js +6 -0
  332. package/assets/plugin/tools/modify-stop.d.ts +17 -0
  333. package/assets/plugin/tools/modify-stop.js +81 -0
  334. package/assets/plugin/tools/modify-target.d.ts +17 -0
  335. package/assets/plugin/tools/modify-target.js +71 -0
  336. package/assets/plugin/tools/propose-learning.d.ts +22 -0
  337. package/assets/plugin/tools/propose-learning.js +65 -0
  338. package/assets/plugin/tools/query-review-outcomes.d.ts +30 -0
  339. package/assets/plugin/tools/query-review-outcomes.js +64 -0
  340. package/assets/plugin/tools/query-trades.d.ts +21 -0
  341. package/assets/plugin/tools/query-trades.js +37 -0
  342. package/assets/plugin/tools/record-position-reviews.d.ts +38 -0
  343. package/assets/plugin/tools/record-position-reviews.js +147 -0
  344. package/assets/plugin/tools/save-strategy.d.ts +16 -0
  345. package/assets/plugin/tools/save-strategy.js +46 -0
  346. package/assets/plugin/tools/scan-pairs.d.ts +18 -0
  347. package/assets/plugin/tools/scan-pairs.js +220 -0
  348. package/assets/plugin/tools/score-setup.d.ts +31 -0
  349. package/assets/plugin/tools/score-setup.js +268 -0
  350. package/assets/plugin/tools/set-bracket-requirement.d.ts +18 -0
  351. package/assets/plugin/tools/set-bracket-requirement.js +81 -0
  352. package/assets/plugin/tools/set-exchange-credentials.d.ts +25 -0
  353. package/assets/plugin/tools/set-exchange-credentials.js +80 -0
  354. package/assets/plugin/tools/set-trading-mode.d.ts +26 -0
  355. package/assets/plugin/tools/set-trading-mode.js +135 -0
  356. package/assets/plugin/tools/test-exchange-credentials.d.ts +16 -0
  357. package/assets/plugin/tools/test-exchange-credentials.js +100 -0
  358. package/assets/plugin/tools/toggle-strategy.d.ts +8 -0
  359. package/assets/plugin/tools/toggle-strategy.js +8 -0
  360. package/assets/plugin/trading-params-cache.d.ts +26 -0
  361. package/assets/plugin/trading-params-cache.js +52 -0
  362. package/assets/plugin/types.d.ts +110 -0
  363. package/assets/plugin/types.js +7 -0
  364. package/assets/plugin/util/plugin-paths.d.ts +3 -0
  365. package/assets/plugin/util/plugin-paths.js +15 -0
  366. package/assets/shared/fills.d.ts +36 -0
  367. package/assets/shared/fills.js +20 -0
  368. package/assets/shared/index.d.ts +10 -0
  369. package/assets/shared/index.js +5 -0
  370. package/assets/shared/logger.d.ts +10 -0
  371. package/assets/shared/logger.js +34 -0
  372. package/assets/shared/protocol.d.ts +29 -0
  373. package/assets/shared/protocol.js +14 -0
  374. package/assets/shared/redact.d.ts +6 -0
  375. package/assets/shared/redact.js +31 -0
  376. package/assets/shared/shared/indicators-extended.d.ts +52 -0
  377. package/assets/shared/shared/indicators-extended.js +284 -0
  378. package/assets/shared/shared/indicators.d.ts +15 -0
  379. package/assets/shared/shared/indicators.js +107 -0
  380. package/assets/shared/signals/conditions/registry.d.ts +16 -0
  381. package/assets/shared/signals/conditions/registry.js +1267 -0
  382. package/assets/shared/signals/conditions/types.d.ts +65 -0
  383. package/assets/shared/signals/conditions/types.js +8 -0
  384. package/assets/shared/signals/direction-rules.d.ts +3 -0
  385. package/assets/shared/signals/direction-rules.js +18 -0
  386. package/assets/shared/signals/entry-rules.d.ts +6 -0
  387. package/assets/shared/signals/entry-rules.js +26 -0
  388. package/assets/shared/signals/indicators-extended.d.ts +52 -0
  389. package/assets/shared/signals/indicators-extended.js +284 -0
  390. package/assets/shared/signals/indicators.d.ts +15 -0
  391. package/assets/shared/signals/indicators.js +107 -0
  392. package/assets/shared/signals/serialize-context.d.ts +4 -0
  393. package/assets/shared/signals/serialize-context.js +41 -0
  394. package/assets/shared/signals/stop-rules.d.ts +3 -0
  395. package/assets/shared/signals/stop-rules.js +41 -0
  396. package/assets/shared/signals/strategy-adapter.d.ts +14 -0
  397. package/assets/shared/signals/strategy-adapter.js +117 -0
  398. package/assets/shared/signals/types.d.ts +187 -0
  399. package/assets/shared/signals/types.js +9 -0
  400. package/assets/shared/trading-mode.d.ts +16 -0
  401. package/assets/shared/trading-mode.js +49 -0
  402. package/assets/skill/SKILL.md +1357 -0
  403. package/dist/bridge.js +25 -0
  404. package/dist/bundle.js +33 -0
  405. package/dist/cli.js +120 -0
  406. package/dist/daemon.js +104 -0
  407. package/dist/deps.js +41 -0
  408. package/dist/exec.js +28 -0
  409. package/dist/openclaw.js +153 -0
  410. package/dist/paths.js +23 -0
  411. package/dist/plugin.js +48 -0
  412. package/dist/skill.js +35 -0
  413. package/dist/ui.js +29 -0
  414. package/dist/validate.js +28 -0
  415. package/package.json +32 -0
@@ -0,0 +1,138 @@
1
+ // Ed25519 signature verification for OTA SKILL.md updates.
2
+ //
3
+ // Security finding C1 (docs/PRE_LAUNCH_SECURITY_HARDENING.md §2.5 + Appendix B):
4
+ // the relay is treated as a DUMB TRANSPORT. A pushed/pulled SKILL.md is applied
5
+ // only if it carries a valid signature from the operator's offline private key,
6
+ // whose PUBLIC key is pinned here in the build. A leaked ADMIN_SECRET, a
7
+ // compromised relay process, or a tampered Durable-Object value therefore
8
+ // CANNOT rewrite an agent's trading instructions — they all fail verification.
9
+ //
10
+ // Key provisioning (one-time, operator, OFFLINE):
11
+ // 1. python scripts/gen-skill-signing-key.py
12
+ // 2. paste the printed PUBLIC key (base64) into TRUSTED_SKILL_SIGNING_KEYS below
13
+ // 3. put the printed PRIVATE key into .env.deploy as SKILL_SIGNING_PRIVATE_KEY
14
+ // (gitignored — keep it offline; NEVER on the relay or any server)
15
+ // 4. rebuild + redeploy the skill (deploy-skillmd-ota.py is already wired to sign)
16
+ //
17
+ // Until a key is pinned, OTA is FAIL-CLOSED (every push rejected) while
18
+ // SKILL_OTA_REQUIRE_SIGNATURE is on (the default). Normal trading is unaffected
19
+ // — only the OTA-update path gates on this.
20
+ import { createHash, createPublicKey, verify as cryptoVerify } from 'node:crypto';
21
+ import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
22
+ import { join } from 'node:path';
23
+ import { homedir } from 'node:os';
24
+ import { parseSkillVersion } from './skill-version.js';
25
+ /**
26
+ * Pinned Ed25519 PUBLIC keys (base64 of the raw 32-byte key) trusted to sign OTA
27
+ * SKILL.md updates. Multiple entries enable key rotation (accept current + next,
28
+ * retire the old after every client has updated). EMPTY until the operator pins
29
+ * one — see the header for provisioning.
30
+ */
31
+ export const TRUSTED_SKILL_SIGNING_KEYS = [
32
+ // 'Base64OfRaw32BytePublicKey=' ← paste from scripts/gen-skill-signing-key.py
33
+ ];
34
+ const OTA_STATE_PATH = join(homedir(), '.openclaw', 'workspace', '.skill-ota-state.json');
35
+ /** Lowercase hex SHA-256 of the UTF-8 content. MUST match the Python signer. */
36
+ export function sha256Hex(content) {
37
+ return createHash('sha256').update(content, 'utf8').digest('hex');
38
+ }
39
+ /** Canonical signed message — MUST match deploy-skillmd-ota.py byte-for-byte. */
40
+ export function signedMessage(version, contentSha256, signedAt) {
41
+ return `${version}\n${contentSha256}\n${signedAt}`;
42
+ }
43
+ /**
44
+ * Is OTA signature verification enforced?
45
+ *
46
+ * Default **OFF** while C1 (signed OTA) is ON HOLD — see
47
+ * docs/PRE_LAUNCH_SECURITY_HARDENING.md §2.5. Keeping it off by default makes
48
+ * this whole module DORMANT, so deploying skill/relay for UNRELATED reasons can
49
+ * never break the existing (unsigned) OTA flow — no env flag to remember.
50
+ *
51
+ * To ENABLE signed-OTA (when the agent-update mechanism is finalized): pin a
52
+ * public key in TRUSTED_SKILL_SIGNING_KEYS **and** set
53
+ * SKILL_OTA_REQUIRE_SIGNATURE=on. Both are required — a pinned key alone does
54
+ * nothing without the flag, and the flag alone fails closed (no key → reject).
55
+ */
56
+ export function signatureRequired() {
57
+ return (process.env.SKILL_OTA_REQUIRE_SIGNATURE ?? 'off').toLowerCase() === 'on';
58
+ }
59
+ function publicKeyFromRawB64(b64) {
60
+ try {
61
+ const raw = Buffer.from(b64, 'base64');
62
+ if (raw.length !== 32)
63
+ return null; // raw Ed25519 public key is exactly 32 bytes
64
+ return createPublicKey({
65
+ format: 'jwk',
66
+ key: { kty: 'OKP', crv: 'Ed25519', x: raw.toString('base64url') },
67
+ });
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ }
73
+ /**
74
+ * Verify a signed OTA envelope against the pinned (or supplied) trusted keys.
75
+ * Checks: required fields present, content hash matches (no tampering), the
76
+ * frontmatter version matches the signed version (no number-bump replay), and
77
+ * the Ed25519 signature verifies under some trusted key. Pure — does NOT touch
78
+ * disk or the replay clock; the caller enforces monotonic signedAt.
79
+ */
80
+ export function verifySkillSignature(env, opts) {
81
+ const keys = opts?.trustedKeys ?? TRUSTED_SKILL_SIGNING_KEYS;
82
+ if (keys.length === 0) {
83
+ return { ok: false, reason: 'no trusted signing keys configured — pin a public key in skill-signing.ts (see scripts/gen-skill-signing-key.py)' };
84
+ }
85
+ if (!env.signature || !env.signedAt || !env.contentSha256) {
86
+ return { ok: false, reason: 'missing signature/signedAt/contentSha256 (unsigned push)' };
87
+ }
88
+ if (sha256Hex(env.content) !== env.contentSha256) {
89
+ return { ok: false, reason: 'content hash mismatch (tampered content)' };
90
+ }
91
+ const frontmatterVersion = parseSkillVersion(env.content);
92
+ if (frontmatterVersion !== env.version) {
93
+ return { ok: false, reason: `version mismatch (envelope ${env.version} vs frontmatter ${frontmatterVersion ?? 'none'})` };
94
+ }
95
+ const msg = Buffer.from(signedMessage(env.version, env.contentSha256, env.signedAt), 'utf8');
96
+ let sig;
97
+ try {
98
+ sig = Buffer.from(env.signature, 'base64');
99
+ }
100
+ catch {
101
+ return { ok: false, reason: 'signature is not valid base64' };
102
+ }
103
+ for (const keyB64 of keys) {
104
+ const pub = publicKeyFromRawB64(keyB64);
105
+ if (!pub)
106
+ continue;
107
+ try {
108
+ if (cryptoVerify(null, msg, pub, sig))
109
+ return { ok: true };
110
+ }
111
+ catch {
112
+ /* malformed key/sig for this candidate — try the next */
113
+ }
114
+ }
115
+ return { ok: false, reason: 'signature does not verify under any trusted key' };
116
+ }
117
+ /** Last applied signedAt as epoch ms, 0 if none/unreadable (replay clock). */
118
+ export function readLastAppliedSignedAtMs() {
119
+ try {
120
+ const raw = readFileSync(OTA_STATE_PATH, 'utf-8');
121
+ const t = JSON.parse(raw).lastAppliedSignedAt;
122
+ const ms = t ? new Date(t).getTime() : 0;
123
+ return Number.isFinite(ms) ? ms : 0;
124
+ }
125
+ catch {
126
+ return 0;
127
+ }
128
+ }
129
+ /** Persist the signedAt of the just-applied update (monotonic replay clock). */
130
+ export function recordAppliedSignedAt(signedAt) {
131
+ try {
132
+ mkdirSync(join(homedir(), '.openclaw', 'workspace'), { recursive: true });
133
+ writeFileSync(OTA_STATE_PATH, JSON.stringify({ lastAppliedSignedAt: signedAt }), 'utf-8');
134
+ }
135
+ catch {
136
+ /* best-effort — if this fails the replay window is bounded to one process life */
137
+ }
138
+ }
@@ -0,0 +1,17 @@
1
+ /** Extract version from SKILL.md frontmatter */
2
+ export declare function parseSkillVersion(content: string): string | null;
3
+ /** Read current SKILL.md version from disk */
4
+ export declare function readLocalSkillVersion(): string | null;
5
+ /**
6
+ * Compare two semver strings.
7
+ * Returns 1 if a > b, -1 if a < b, 0 if equal.
8
+ * Non-semver inputs (or null) are treated as -Infinity so a valid semver always
9
+ * wins, which is the safe direction for "should I accept this OTA push?".
10
+ */
11
+ export declare function compareSemver(a: string | null, b: string | null): number;
12
+ /** Validate SKILL.md content is well-formed */
13
+ export declare function validateSkillContent(content: string): {
14
+ valid: boolean;
15
+ version: string | null;
16
+ error?: string;
17
+ };
@@ -0,0 +1,71 @@
1
+ // SKILL.md version parsing utility for OTA updates
2
+ import { readFileSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { homedir } from 'os';
5
+ const SKILL_MD_PATH = join(homedir(), '.openclaw', 'workspace', 'SKILL.md');
6
+ /** Extract version from SKILL.md frontmatter */
7
+ export function parseSkillVersion(content) {
8
+ const match = content.match(/^---[\s\S]*?version:\s*(\S+)[\s\S]*?---/);
9
+ return match ? match[1] : null;
10
+ }
11
+ /** Read current SKILL.md version from disk */
12
+ export function readLocalSkillVersion() {
13
+ try {
14
+ const content = readFileSync(SKILL_MD_PATH, 'utf-8');
15
+ return parseSkillVersion(content);
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ const MAX_SKILL_CONTENT_SIZE = 100_000; // 100KB
22
+ const SEMVER_REGEX = /^\d+\.\d+\.\d+$/;
23
+ /**
24
+ * Compare two semver strings.
25
+ * Returns 1 if a > b, -1 if a < b, 0 if equal.
26
+ * Non-semver inputs (or null) are treated as -Infinity so a valid semver always
27
+ * wins, which is the safe direction for "should I accept this OTA push?".
28
+ */
29
+ export function compareSemver(a, b) {
30
+ const parse = (v) => {
31
+ if (!v || !SEMVER_REGEX.test(v))
32
+ return null;
33
+ const [maj, min, pat] = v.split('.').map(Number);
34
+ return [maj, min, pat];
35
+ };
36
+ const pa = parse(a);
37
+ const pb = parse(b);
38
+ if (!pa && !pb)
39
+ return 0;
40
+ if (!pa)
41
+ return -1;
42
+ if (!pb)
43
+ return 1;
44
+ for (let i = 0; i < 3; i++) {
45
+ if (pa[i] > pb[i])
46
+ return 1;
47
+ if (pa[i] < pb[i])
48
+ return -1;
49
+ }
50
+ return 0;
51
+ }
52
+ /** Validate SKILL.md content is well-formed */
53
+ export function validateSkillContent(content) {
54
+ if (content.length > MAX_SKILL_CONTENT_SIZE) {
55
+ return { valid: false, version: null, error: `Content too large (${content.length} bytes, max ${MAX_SKILL_CONTENT_SIZE})` };
56
+ }
57
+ if (!content.startsWith('---')) {
58
+ return { valid: false, version: null, error: 'Missing frontmatter delimiter' };
59
+ }
60
+ const version = parseSkillVersion(content);
61
+ if (!version) {
62
+ return { valid: false, version: null, error: 'No version in frontmatter' };
63
+ }
64
+ if (!SEMVER_REGEX.test(version)) {
65
+ return { valid: false, version, error: `Invalid version format: ${version} (expected semver x.y.z)` };
66
+ }
67
+ if (content.length < 100) {
68
+ return { valid: false, version, error: 'Content suspiciously short' };
69
+ }
70
+ return { valid: true, version };
71
+ }
@@ -0,0 +1,11 @@
1
+ import type { TradingMode } from '../types.js';
2
+ export interface ModeTransitionAuditEntry {
3
+ ts: string;
4
+ previousMode: TradingMode;
5
+ targetMode: TradingMode;
6
+ acknowledged: boolean;
7
+ ok: boolean;
8
+ reason?: string;
9
+ testnet?: boolean;
10
+ }
11
+ export declare function recordModeTransition(entry: Omit<ModeTransitionAuditEntry, 'ts'>, pluginId?: string): void;
@@ -0,0 +1,29 @@
1
+ // Mode-transition audit — append-only JSONL record of every set_trading_mode call.
2
+ //
3
+ // Written BEFORE the adapter swap (so even a crashed transition leaves a trail)
4
+ // and updated with the outcome. Intended for post-incident review and regulatory
5
+ // defence ("the operator acknowledged the LIVE transition at 2026-04-20T14:32:11Z").
6
+ //
7
+ // Path: ~/.openclaw/plugins/<pluginId>/mode-transitions.jsonl
8
+ // Append-only; never truncated. One JSON object per line.
9
+ import { appendFileSync, existsSync, mkdirSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { logger, formatError } from '../logger.js';
12
+ import { resolvePluginsBaseDir } from '../util/plugin-paths.js';
13
+ const TAG = 'mode-audit';
14
+ function resolvePath(pluginId) {
15
+ const dir = join(resolvePluginsBaseDir(), pluginId ?? 'reefclaw-paper-trading');
16
+ if (!existsSync(dir))
17
+ mkdirSync(dir, { recursive: true });
18
+ return join(dir, 'mode-transitions.jsonl');
19
+ }
20
+ export function recordModeTransition(entry, pluginId) {
21
+ const full = { ts: new Date().toISOString(), ...entry };
22
+ try {
23
+ appendFileSync(resolvePath(pluginId), JSON.stringify(full) + '\n', 'utf8');
24
+ logger.info(TAG, `${full.previousMode} → ${full.targetMode} ok=${full.ok} ack=${full.acknowledged}`);
25
+ }
26
+ catch (err) {
27
+ logger.error(TAG, `Failed to write audit entry: ${formatError(err)}`);
28
+ }
29
+ }
@@ -0,0 +1,36 @@
1
+ import type { CcxtBalance } from './types.js';
2
+ /**
3
+ * Read the total quote-currency balance from a CCXT balance map.
4
+ *
5
+ * Uses the PRIMARY funded currency only — whichever of USDT/USDC has
6
+ * the larger balance. Summing both was incorrect because Binance
7
+ * cross-margin accounting reports position margin/value as a phantom
8
+ * balance in the settlement currency (e.g., opening an ATOM/USDT
9
+ * position with a USDC-funded account creates a USDT "balance" entry
10
+ * equal to the position's notional, inflating getQuoteBalance by the
11
+ * position value and causing the KPI to double-count).
12
+ *
13
+ * For wallet/equity/NAV reads on Binance Futures, prefer
14
+ * `getQuoteWalletBalance(balance)` — it handles BNFCR.
15
+ */
16
+ export declare function getQuoteBalance(balanceMap: Record<string, number> | undefined): number;
17
+ /**
18
+ * Read the effective wallet-equivalent quote balance from a Binance Futures
19
+ * fetchBalance response, including the BNFCR realized-PnL accumulator.
20
+ *
21
+ * Why this exists: Binance multi-asset accounts settle realized PnL into
22
+ * BNFCR (negative when net-loss, positive when net-gain). CCXT's `total`
23
+ * map carries `marginBalance` (= walletBalance + uPnl), so the BNFCR line
24
+ * mixes uPnl into the total, which double-counts when the caller adds
25
+ * position uPnl on top. This helper reads `info.assets[i].walletBalance`
26
+ * directly, which excludes uPnl by construction.
27
+ *
28
+ * Returns max(USDT_wallet, USDC_wallet) + BNFCR_wallet. BNFCR is added
29
+ * (not max'd) because it is independent of the funded stablecoin — a
30
+ * USDC-funded account with cumulative losses shows USDC unchanged plus
31
+ * BNFCR negative; the user's true wallet is the sum.
32
+ *
33
+ * Falls back to `getQuoteBalance(balance.total)` when `info.assets` is
34
+ * absent (mock balances in unit tests, non-Binance exchanges).
35
+ */
36
+ export declare function getQuoteWalletBalance(balance: CcxtBalance | null | undefined): number;
@@ -0,0 +1,98 @@
1
+ // Utility for reading quote-currency balance from CCXT balance objects.
2
+ // Binance USDⓈ-M Futures settles in USDT or USDC — accounts may hold either or both.
3
+ // On multi-asset accounts a third asset, BNFCR, accumulates realized PnL as a
4
+ // signed wallet line (negative = cumulative loss, positive = cumulative gain).
5
+ /**
6
+ * Read the total quote-currency balance from a CCXT balance map.
7
+ *
8
+ * Uses the PRIMARY funded currency only — whichever of USDT/USDC has
9
+ * the larger balance. Summing both was incorrect because Binance
10
+ * cross-margin accounting reports position margin/value as a phantom
11
+ * balance in the settlement currency (e.g., opening an ATOM/USDT
12
+ * position with a USDC-funded account creates a USDT "balance" entry
13
+ * equal to the position's notional, inflating getQuoteBalance by the
14
+ * position value and causing the KPI to double-count).
15
+ *
16
+ * For wallet/equity/NAV reads on Binance Futures, prefer
17
+ * `getQuoteWalletBalance(balance)` — it handles BNFCR.
18
+ */
19
+ export function getQuoteBalance(balanceMap) {
20
+ if (!balanceMap)
21
+ return 0;
22
+ const usdt = balanceMap.USDT ?? 0;
23
+ const usdc = balanceMap.USDC ?? 0;
24
+ // Use whichever currency has the larger wallet balance (the funded one).
25
+ // If both are zero, return 0. If both are funded, use the larger.
26
+ return Math.max(usdt, usdc);
27
+ }
28
+ /**
29
+ * Read the effective wallet-equivalent quote balance from a Binance Futures
30
+ * fetchBalance response, including the BNFCR realized-PnL accumulator.
31
+ *
32
+ * Why this exists: Binance multi-asset accounts settle realized PnL into
33
+ * BNFCR (negative when net-loss, positive when net-gain). CCXT's `total`
34
+ * map carries `marginBalance` (= walletBalance + uPnl), so the BNFCR line
35
+ * mixes uPnl into the total, which double-counts when the caller adds
36
+ * position uPnl on top. This helper reads `info.assets[i].walletBalance`
37
+ * directly, which excludes uPnl by construction.
38
+ *
39
+ * Returns max(USDT_wallet, USDC_wallet) + BNFCR_wallet. BNFCR is added
40
+ * (not max'd) because it is independent of the funded stablecoin — a
41
+ * USDC-funded account with cumulative losses shows USDC unchanged plus
42
+ * BNFCR negative; the user's true wallet is the sum.
43
+ *
44
+ * Falls back to `getQuoteBalance(balance.total)` when `info.assets` is
45
+ * absent (mock balances in unit tests, non-Binance exchanges).
46
+ */
47
+ export function getQuoteWalletBalance(balance) {
48
+ if (!balance)
49
+ return 0;
50
+ // Prefer Binance's own account-level wallet aggregate when present.
51
+ // `/fapi/v3/account` (CCXT passes it through verbatim at `info`) returns
52
+ // `totalWalletBalance` — in Multi-Assets Mode this is the USD-denominated
53
+ // sum across all margin assets, with each non-USD collateral valued at
54
+ // Binance's live index price (verified against developers.binance.com →
55
+ // Account Information V3, 2026-05-16). It also excludes uPnL by
56
+ // construction (marginBalance = walletBalance + uPnL), matching this
57
+ // function's "wallet, uPnL added by caller" contract.
58
+ //
59
+ // Why this beats the per-asset reconstruction below: summing
60
+ // `max(USDT,USDC) + BNFCR` values USDC at FACE 1.0000, but Binance values
61
+ // USDC collateral at the live USDC/USD index (~0.9998). That made the
62
+ // dashboard wallet permanently ~$0.2 high vs the Binance app on this
63
+ // account (always-on, same-sign, slowly varying with the USDC peg —
64
+ // 2026-05-16 "figures slightly off always"). totalWalletBalance is the
65
+ // exact number the app's Futures "Wallet Balance" shows. The read path is
66
+ // already REST (`LiveAdapter.getBalance` → `fetchBalance()` every poll),
67
+ // so this is zero freshness regression — same cadence, correct value.
68
+ const info = balance?.info;
69
+ if (info && info.totalWalletBalance != null) {
70
+ const twb = parseFloat(String(info.totalWalletBalance));
71
+ if (Number.isFinite(twb))
72
+ return twb;
73
+ }
74
+ // Fallback (no Binance aggregate — non-Binance exchange, mock balances in
75
+ // unit tests, or a WS-store-derived balance object): the legacy
76
+ // face-value per-asset reconstruction. Carries the documented ~USDC-index
77
+ // drift but is the best available when the aggregate is absent.
78
+ const assets = balance?.info?.assets;
79
+ if (!Array.isArray(assets))
80
+ return getQuoteBalance(balance.total);
81
+ let usdt = 0;
82
+ let usdc = 0;
83
+ let bnfcr = 0;
84
+ for (const a of assets) {
85
+ if (!a || typeof a.asset !== 'string')
86
+ continue;
87
+ const wb = parseFloat(String(a.walletBalance ?? 0));
88
+ if (!Number.isFinite(wb))
89
+ continue;
90
+ if (a.asset === 'USDT')
91
+ usdt = wb;
92
+ else if (a.asset === 'USDC')
93
+ usdc = wb;
94
+ else if (a.asset === 'BNFCR')
95
+ bnfcr = wb;
96
+ }
97
+ return Math.max(usdt, usdc) + bnfcr;
98
+ }
@@ -0,0 +1,47 @@
1
+ /** Thrown by `assertNotBanned` while the gate is closed. Carries the
2
+ * remaining cooldown so callers/telemetry can reason about it. Methods
3
+ * catch this in their existing catch block — it is NOT meant to escape
4
+ * the API layer with special handling; it degrades to the method's normal
5
+ * failure contract. */
6
+ export declare class BinanceBannedError extends Error {
7
+ readonly retryAfterMs: number;
8
+ constructor(retryAfterMs: number, context: string);
9
+ }
10
+ /** Thrown by the proactive weight pacer. Subclass of BinanceBannedError so
11
+ * every `instanceof BinanceBannedError` check and every method's existing
12
+ * catch keep working unchanged — it degrades to the same null/[]/throw
13
+ * contract (treated exactly like a transient fetch failure). The distinct
14
+ * name lets journal/telemetry tell prevention apart from a real IP ban. */
15
+ export declare class BinanceWeightPacedError extends BinanceBannedError {
16
+ constructor(retryAfterMs: number, context: string);
17
+ }
18
+ /** Fast pre-flight check. Call as the first line inside a Binance call's
19
+ * try-block. Throws `BinanceBannedError` (no network) while the gate is
20
+ * open. */
21
+ export declare function assertNotBanned(context: string): void;
22
+ /** Inspect a failed call's error and arm/extend the gate on a Binance
23
+ * rate-limit signal. Non-rate-limit errors are ignored (normal transient
24
+ * handling stays in the caller). Safe to call with any error shape. */
25
+ export declare function noteBinanceError(err: unknown): void;
26
+ /** Relax the soft-429 ladder after a clean call. (A hard 418 window is NOT
27
+ * shortened by this — only Binance's stated expiry clears it.) */
28
+ export declare function noteSuccess(): void;
29
+ /** Reconcile the local weight estimate against Binance truth from a response
30
+ * header (`x-mbx-used-weight-1m`). Best-effort: callers pass whatever header
31
+ * bag they have; absent/garbage values are ignored. The local estimate
32
+ * leads (counts in-flight calls Binance hasn't tallied yet), so we take the
33
+ * MAX within the window — never let a lagging header lower our guard. A
34
+ * header far BELOW the estimate means Binance's minute rolled; re-anchor the
35
+ * window to Binance's clock so we don't shed for a stale local total. */
36
+ export declare function noteResponseWeight(headers: Record<string, string> | undefined | null): void;
37
+ /** Test/diagnostic helper — current gate state. */
38
+ export declare function getBanGateState(): {
39
+ banUntilMs: number;
40
+ remainingMs: number;
41
+ rateLimitStep: number;
42
+ weightUsed: number;
43
+ weightCeiling: number;
44
+ cosmeticCeiling: number;
45
+ };
46
+ /** Test-only reset. Not used in production code paths. */
47
+ export declare function __resetBanGateForTests(): void;