@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.
- package/assets/plugin/audit/mode-transition-audit.d.ts +11 -0
- package/assets/plugin/audit/mode-transition-audit.js +29 -0
- package/assets/plugin/balance-utils.d.ts +36 -0
- package/assets/plugin/balance-utils.js +98 -0
- package/assets/plugin/ccxt/binance-ban-gate.d.ts +47 -0
- package/assets/plugin/ccxt/binance-ban-gate.js +420 -0
- package/assets/plugin/ccxt/binance-private.d.ts +346 -0
- package/assets/plugin/ccxt/binance-private.js +1525 -0
- package/assets/plugin/ccxt/binance-public.d.ts +34 -0
- package/assets/plugin/ccxt/binance-public.js +180 -0
- package/assets/plugin/ccxt/intel-public.d.ts +25 -0
- package/assets/plugin/ccxt/intel-public.js +80 -0
- package/assets/plugin/ccxt/public-market-data-api.d.ts +26 -0
- package/assets/plugin/ccxt/public-market-data-api.js +23 -0
- package/assets/plugin/config/agent-config-client.d.ts +77 -0
- package/assets/plugin/config/agent-config-client.js +188 -0
- package/assets/plugin/config/agent-config-poller.d.ts +32 -0
- package/assets/plugin/config/agent-config-poller.js +101 -0
- package/assets/plugin/config/brackets-config.d.ts +22 -0
- package/assets/plugin/config/brackets-config.js +58 -0
- package/assets/plugin/config/entitlement-gate.d.ts +51 -0
- package/assets/plugin/config/entitlement-gate.js +137 -0
- package/assets/plugin/config/gate-store.d.ts +18 -0
- package/assets/plugin/config/gate-store.js +61 -0
- package/assets/plugin/config/plugin-config-io.d.ts +222 -0
- package/assets/plugin/config/plugin-config-io.js +126 -0
- package/assets/plugin/config/position-review-config.d.ts +35 -0
- package/assets/plugin/config/position-review-config.js +105 -0
- package/assets/plugin/config/tool-gate.d.ts +53 -0
- package/assets/plugin/config/tool-gate.js +128 -0
- package/assets/plugin/config/user-data-stream-config.d.ts +89 -0
- package/assets/plugin/config/user-data-stream-config.js +239 -0
- package/assets/plugin/connector-supervisor.d.ts +36 -0
- package/assets/plugin/connector-supervisor.js +149 -0
- package/assets/plugin/exchange-adapter.d.ts +65 -0
- package/assets/plugin/exchange-adapter.js +4 -0
- package/assets/plugin/index.d.ts +30 -0
- package/assets/plugin/index.js +2763 -0
- package/assets/plugin/ingest/pending-entry-metadata.d.ts +74 -0
- package/assets/plugin/ingest/pending-entry-metadata.js +236 -0
- package/assets/plugin/ingest/position-auto-capture.d.ts +171 -0
- package/assets/plugin/ingest/position-auto-capture.js +709 -0
- package/assets/plugin/ingest/position-decisions-client.d.ts +327 -0
- package/assets/plugin/ingest/position-decisions-client.js +306 -0
- package/assets/plugin/ingest/readiness-reporter.d.ts +42 -0
- package/assets/plugin/ingest/readiness-reporter.js +163 -0
- package/assets/plugin/ingest/reconcile-db-vs-exchange.d.ts +51 -0
- package/assets/plugin/ingest/reconcile-db-vs-exchange.js +170 -0
- package/assets/plugin/ingest/reconciler-cleanup.d.ts +37 -0
- package/assets/plugin/ingest/reconciler-cleanup.js +147 -0
- package/assets/plugin/ingest/rest-gap-filler.d.ts +191 -0
- package/assets/plugin/ingest/rest-gap-filler.js +565 -0
- package/assets/plugin/ingest/touched-symbols-store.d.ts +25 -0
- package/assets/plugin/ingest/touched-symbols-store.js +96 -0
- package/assets/plugin/ingest/trade-store-client.d.ts +40 -0
- package/assets/plugin/ingest/trade-store-client.js +125 -0
- package/assets/plugin/ingest/ws-ingest.d.ts +43 -0
- package/assets/plugin/ingest/ws-ingest.js +126 -0
- package/assets/plugin/learning/setup-family.d.ts +21 -0
- package/assets/plugin/learning/setup-family.js +103 -0
- package/assets/plugin/lifecycle/install-signal-handlers.d.ts +33 -0
- package/assets/plugin/lifecycle/install-signal-handlers.js +112 -0
- package/assets/plugin/lifecycle/shutdown-coordinator.d.ts +43 -0
- package/assets/plugin/lifecycle/shutdown-coordinator.js +131 -0
- package/assets/plugin/lifecycle/trading-operation-lock.d.ts +17 -0
- package/assets/plugin/lifecycle/trading-operation-lock.js +14 -0
- package/assets/plugin/live/bracket-id.d.ts +26 -0
- package/assets/plugin/live/bracket-id.js +112 -0
- package/assets/plugin/live/bracket-ledger.d.ts +54 -0
- package/assets/plugin/live/bracket-ledger.js +267 -0
- package/assets/plugin/live/bracket-manager.d.ts +82 -0
- package/assets/plugin/live/bracket-manager.js +478 -0
- package/assets/plugin/live/bracket-params.d.ts +22 -0
- package/assets/plugin/live/bracket-params.js +124 -0
- package/assets/plugin/live/bracket-reconciler.d.ts +95 -0
- package/assets/plugin/live/bracket-reconciler.js +573 -0
- package/assets/plugin/live/bracket-types.d.ts +102 -0
- package/assets/plugin/live/bracket-types.js +8 -0
- package/assets/plugin/live/deposit-tracker.d.ts +62 -0
- package/assets/plugin/live/deposit-tracker.js +97 -0
- package/assets/plugin/live/emergency-controls.d.ts +32 -0
- package/assets/plugin/live/emergency-controls.js +226 -0
- package/assets/plugin/live/exchange-errors.d.ts +12 -0
- package/assets/plugin/live/exchange-errors.js +130 -0
- package/assets/plugin/live/exchange-info-cache.d.ts +37 -0
- package/assets/plugin/live/exchange-info-cache.js +134 -0
- package/assets/plugin/live/fact-subscriber.d.ts +78 -0
- package/assets/plugin/live/fact-subscriber.js +182 -0
- package/assets/plugin/live/fill-price.d.ts +13 -0
- package/assets/plugin/live/fill-price.js +37 -0
- package/assets/plugin/live/intent-journal.d.ts +42 -0
- package/assets/plugin/live/intent-journal.js +122 -0
- package/assets/plugin/live/listen-key-manager.d.ts +70 -0
- package/assets/plugin/live/listen-key-manager.js +169 -0
- package/assets/plugin/live/live-adapter.d.ts +319 -0
- package/assets/plugin/live/live-adapter.js +1906 -0
- package/assets/plugin/live/live-balance-enricher.d.ts +32 -0
- package/assets/plugin/live/live-balance-enricher.js +104 -0
- package/assets/plugin/live/live-bracket-api.d.ts +13 -0
- package/assets/plugin/live/live-bracket-api.js +20 -0
- package/assets/plugin/live/live-state-store.d.ts +194 -0
- package/assets/plugin/live/live-state-store.js +450 -0
- package/assets/plugin/live/local-signal-service.d.ts +57 -0
- package/assets/plugin/live/local-signal-service.js +151 -0
- package/assets/plugin/live/local-strategy-evaluator.d.ts +62 -0
- package/assets/plugin/live/local-strategy-evaluator.js +131 -0
- package/assets/plugin/live/microstructure-assembler.d.ts +54 -0
- package/assets/plugin/live/microstructure-assembler.js +148 -0
- package/assets/plugin/live/order-poller.d.ts +29 -0
- package/assets/plugin/live/order-poller.js +125 -0
- package/assets/plugin/live/position-state-store.d.ts +87 -0
- package/assets/plugin/live/position-state-store.js +237 -0
- package/assets/plugin/live/proposal-decision-listener.d.ts +70 -0
- package/assets/plugin/live/proposal-decision-listener.js +292 -0
- package/assets/plugin/live/proposal-manager.d.ts +76 -0
- package/assets/plugin/live/proposal-manager.js +140 -0
- package/assets/plugin/live/rate-limiter.d.ts +47 -0
- package/assets/plugin/live/rate-limiter.js +159 -0
- package/assets/plugin/live/reconciler.d.ts +39 -0
- package/assets/plugin/live/reconciler.js +175 -0
- package/assets/plugin/live/setup-buckets.d.ts +7 -0
- package/assets/plugin/live/setup-buckets.js +33 -0
- package/assets/plugin/live/slippage-tracker.d.ts +45 -0
- package/assets/plugin/live/slippage-tracker.js +78 -0
- package/assets/plugin/live/stop-watcher.d.ts +67 -0
- package/assets/plugin/live/stop-watcher.js +218 -0
- package/assets/plugin/live/user-data-active-probe.d.ts +54 -0
- package/assets/plugin/live/user-data-active-probe.js +180 -0
- package/assets/plugin/live/user-data-stream-controller.d.ts +200 -0
- package/assets/plugin/live/user-data-stream-controller.js +579 -0
- package/assets/plugin/live/user-data-stream-ws.d.ts +22 -0
- package/assets/plugin/live/user-data-stream-ws.js +63 -0
- package/assets/plugin/live/user-data-stream.d.ts +243 -0
- package/assets/plugin/live/user-data-stream.js +704 -0
- package/assets/plugin/logger.d.ts +2 -0
- package/assets/plugin/logger.js +2 -0
- package/assets/plugin/mfe.d.ts +21 -0
- package/assets/plugin/mfe.js +68 -0
- package/assets/plugin/onboarding/mode-ladder.d.ts +1 -0
- package/assets/plugin/onboarding/mode-ladder.js +3 -0
- package/assets/plugin/onboarding/runtime.d.ts +102 -0
- package/assets/plugin/onboarding/runtime.js +215 -0
- package/assets/plugin/openclaw.plugin.json +92 -0
- package/assets/plugin/paper-adapter.d.ts +24 -0
- package/assets/plugin/paper-adapter.js +91 -0
- package/assets/plugin/persistence/state-manager.d.ts +66 -0
- package/assets/plugin/persistence/state-manager.js +222 -0
- package/assets/plugin/pinned-plan.d.ts +9 -0
- package/assets/plugin/pinned-plan.js +23 -0
- package/assets/plugin/portfolio/reentry-tracker.d.ts +36 -0
- package/assets/plugin/portfolio/reentry-tracker.js +127 -0
- package/assets/plugin/portfolio/wave9-admission.d.ts +67 -0
- package/assets/plugin/portfolio/wave9-admission.js +262 -0
- package/assets/plugin/portfolio/wave9-policy.d.ts +36 -0
- package/assets/plugin/portfolio/wave9-policy.js +183 -0
- package/assets/plugin/risk/pre-trade-check.d.ts +38 -0
- package/assets/plugin/risk/pre-trade-check.js +345 -0
- package/assets/plugin/risk/pre-trade-types.d.ts +60 -0
- package/assets/plugin/risk/pre-trade-types.js +3 -0
- package/assets/plugin/shadow/shadow-tracker.d.ts +36 -0
- package/assets/plugin/shadow/shadow-tracker.js +151 -0
- package/assets/plugin/shadow/types.d.ts +42 -0
- package/assets/plugin/shadow/types.js +20 -0
- package/assets/plugin/shared/indicators-extended.d.ts +52 -0
- package/assets/plugin/shared/indicators-extended.js +291 -0
- package/assets/plugin/shared/indicators.d.ts +15 -0
- package/assets/plugin/shared/indicators.js +114 -0
- package/assets/plugin/signals/conditions/registry.d.ts +16 -0
- package/assets/plugin/signals/conditions/registry.js +1333 -0
- package/assets/plugin/signals/conditions/types.d.ts +1 -0
- package/assets/plugin/signals/conditions/types.js +4 -0
- package/assets/plugin/signals/direction-rules.d.ts +3 -0
- package/assets/plugin/signals/direction-rules.js +24 -0
- package/assets/plugin/signals/entry-rules.d.ts +6 -0
- package/assets/plugin/signals/entry-rules.js +33 -0
- package/assets/plugin/signals/serialize-context.d.ts +4 -0
- package/assets/plugin/signals/serialize-context.js +39 -0
- package/assets/plugin/signals/stop-rules.d.ts +3 -0
- package/assets/plugin/signals/stop-rules.js +48 -0
- package/assets/plugin/signals/strategy-adapter.d.ts +47 -0
- package/assets/plugin/signals/strategy-adapter.js +209 -0
- package/assets/plugin/signals/types.d.ts +1 -0
- package/assets/plugin/signals/types.js +8 -0
- package/assets/plugin/simulator/exchange-simulator.d.ts +105 -0
- package/assets/plugin/simulator/exchange-simulator.js +759 -0
- package/assets/plugin/simulator/fill-engine.d.ts +53 -0
- package/assets/plugin/simulator/fill-engine.js +280 -0
- package/assets/plugin/simulator/paper-market-feed.d.ts +26 -0
- package/assets/plugin/simulator/paper-market-feed.js +104 -0
- package/assets/plugin/simulator/realistic-fills.d.ts +59 -0
- package/assets/plugin/simulator/realistic-fills.js +175 -0
- package/assets/plugin/simulator/types.d.ts +228 -0
- package/assets/plugin/simulator/types.js +43 -0
- package/assets/plugin/strategy/builtin-strategies.d.ts +2 -0
- package/assets/plugin/strategy/builtin-strategies.js +113 -0
- package/assets/plugin/strategy/condition-registry.d.ts +3 -0
- package/assets/plugin/strategy/condition-registry.js +153 -0
- package/assets/plugin/strategy/evaluator.d.ts +70 -0
- package/assets/plugin/strategy/evaluator.js +98 -0
- package/assets/plugin/tools/assessment-validation.d.ts +141 -0
- package/assets/plugin/tools/assessment-validation.js +473 -0
- package/assets/plugin/tools/attach-brackets.d.ts +39 -0
- package/assets/plugin/tools/attach-brackets.js +564 -0
- package/assets/plugin/tools/audit-bracket-protection.d.ts +49 -0
- package/assets/plugin/tools/audit-bracket-protection.js +683 -0
- package/assets/plugin/tools/bracket-control.d.ts +12 -0
- package/assets/plugin/tools/bracket-control.js +35 -0
- package/assets/plugin/tools/cancel-all-orders.d.ts +9 -0
- package/assets/plugin/tools/cancel-all-orders.js +8 -0
- package/assets/plugin/tools/cancel-order.d.ts +14 -0
- package/assets/plugin/tools/cancel-order.js +60 -0
- package/assets/plugin/tools/check-position-health.d.ts +46 -0
- package/assets/plugin/tools/check-position-health.js +194 -0
- package/assets/plugin/tools/clear-exchange-credentials.d.ts +24 -0
- package/assets/plugin/tools/clear-exchange-credentials.js +70 -0
- package/assets/plugin/tools/close-position.d.ts +45 -0
- package/assets/plugin/tools/close-position.js +722 -0
- package/assets/plugin/tools/create-order.d.ts +89 -0
- package/assets/plugin/tools/create-order.js +1555 -0
- package/assets/plugin/tools/exit-gate.d.ts +58 -0
- package/assets/plugin/tools/exit-gate.js +162 -0
- package/assets/plugin/tools/fetch-balance.d.ts +5 -0
- package/assets/plugin/tools/fetch-balance.js +4 -0
- package/assets/plugin/tools/fetch-ohlcv.d.ts +11 -0
- package/assets/plugin/tools/fetch-ohlcv.js +8 -0
- package/assets/plugin/tools/fetch-open-orders.d.ts +7 -0
- package/assets/plugin/tools/fetch-open-orders.js +4 -0
- package/assets/plugin/tools/fetch-positions.d.ts +7 -0
- package/assets/plugin/tools/fetch-positions.js +4 -0
- package/assets/plugin/tools/fetch-ticker.d.ts +11 -0
- package/assets/plugin/tools/fetch-ticker.js +5 -0
- package/assets/plugin/tools/get-agent-profile.d.ts +4 -0
- package/assets/plugin/tools/get-agent-profile.js +6 -0
- package/assets/plugin/tools/get-analytics.d.ts +6 -0
- package/assets/plugin/tools/get-analytics.js +7 -0
- package/assets/plugin/tools/get-backtest.d.ts +12 -0
- package/assets/plugin/tools/get-backtest.js +91 -0
- package/assets/plugin/tools/get-basis.d.ts +7 -0
- package/assets/plugin/tools/get-basis.js +7 -0
- package/assets/plugin/tools/get-bracket-config.d.ts +11 -0
- package/assets/plugin/tools/get-bracket-config.js +24 -0
- package/assets/plugin/tools/get-cascade-risk.d.ts +7 -0
- package/assets/plugin/tools/get-cascade-risk.js +8 -0
- package/assets/plugin/tools/get-crypto-metrics.d.ts +18 -0
- package/assets/plugin/tools/get-crypto-metrics.js +62 -0
- package/assets/plugin/tools/get-cvd.d.ts +6 -0
- package/assets/plugin/tools/get-cvd.js +6 -0
- package/assets/plugin/tools/get-divergences.d.ts +6 -0
- package/assets/plugin/tools/get-divergences.js +6 -0
- package/assets/plugin/tools/get-funding-context.d.ts +6 -0
- package/assets/plugin/tools/get-funding-context.js +16 -0
- package/assets/plugin/tools/get-liquidation-levels.d.ts +7 -0
- package/assets/plugin/tools/get-liquidation-levels.js +7 -0
- package/assets/plugin/tools/get-liquidation-pulse.d.ts +9 -0
- package/assets/plugin/tools/get-liquidation-pulse.js +22 -0
- package/assets/plugin/tools/get-market-breadth.d.ts +6 -0
- package/assets/plugin/tools/get-market-breadth.js +8 -0
- package/assets/plugin/tools/get-market-intel.d.ts +19 -0
- package/assets/plugin/tools/get-market-intel.js +116 -0
- package/assets/plugin/tools/get-market-structure.d.ts +47 -0
- package/assets/plugin/tools/get-market-structure.js +198 -0
- package/assets/plugin/tools/get-my-mined-patterns.d.ts +20 -0
- package/assets/plugin/tools/get-my-mined-patterns.js +61 -0
- package/assets/plugin/tools/get-my-proposed-learnings.d.ts +20 -0
- package/assets/plugin/tools/get-my-proposed-learnings.js +55 -0
- package/assets/plugin/tools/get-my-recent-reviews.d.ts +22 -0
- package/assets/plugin/tools/get-my-recent-reviews.js +66 -0
- package/assets/plugin/tools/get-orderbook.d.ts +21 -0
- package/assets/plugin/tools/get-orderbook.js +32 -0
- package/assets/plugin/tools/get-pattern-scan.d.ts +7 -0
- package/assets/plugin/tools/get-pattern-scan.js +8 -0
- package/assets/plugin/tools/get-regime.d.ts +6 -0
- package/assets/plugin/tools/get-regime.js +7 -0
- package/assets/plugin/tools/get-relevant-learnings.d.ts +21 -0
- package/assets/plugin/tools/get-relevant-learnings.js +65 -0
- package/assets/plugin/tools/get-resting-liquidity.d.ts +6 -0
- package/assets/plugin/tools/get-resting-liquidity.js +11 -0
- package/assets/plugin/tools/get-risk-scenario.d.ts +29 -0
- package/assets/plugin/tools/get-risk-scenario.js +47 -0
- package/assets/plugin/tools/get-risk-summary.d.ts +51 -0
- package/assets/plugin/tools/get-risk-summary.js +118 -0
- package/assets/plugin/tools/get-sentiment.d.ts +4 -0
- package/assets/plugin/tools/get-sentiment.js +6 -0
- package/assets/plugin/tools/get-session-review.d.ts +7 -0
- package/assets/plugin/tools/get-session-review.js +8 -0
- package/assets/plugin/tools/get-setup-detail.d.ts +7 -0
- package/assets/plugin/tools/get-setup-detail.js +322 -0
- package/assets/plugin/tools/get-signals.d.ts +15 -0
- package/assets/plugin/tools/get-signals.js +54 -0
- package/assets/plugin/tools/get-sizing.d.ts +6 -0
- package/assets/plugin/tools/get-sizing.js +6 -0
- package/assets/plugin/tools/get-trade-feedback.d.ts +7 -0
- package/assets/plugin/tools/get-trade-feedback.js +8 -0
- package/assets/plugin/tools/get-trade-flow.d.ts +7 -0
- package/assets/plugin/tools/get-trade-flow.js +7 -0
- package/assets/plugin/tools/get-volume-analysis.d.ts +21 -0
- package/assets/plugin/tools/get-volume-analysis.js +74 -0
- package/assets/plugin/tools/get-volume-profile.d.ts +7 -0
- package/assets/plugin/tools/get-volume-profile.js +7 -0
- package/assets/plugin/tools/get-wave9-status.d.ts +127 -0
- package/assets/plugin/tools/get-wave9-status.js +796 -0
- package/assets/plugin/tools/helpers.d.ts +26 -0
- package/assets/plugin/tools/helpers.js +39 -0
- package/assets/plugin/tools/intel-api.d.ts +34 -0
- package/assets/plugin/tools/intel-api.js +119 -0
- package/assets/plugin/tools/intel-cache.d.ts +25 -0
- package/assets/plugin/tools/intel-cache.js +148 -0
- package/assets/plugin/tools/list-strategies.d.ts +17 -0
- package/assets/plugin/tools/list-strategies.js +23 -0
- package/assets/plugin/tools/modify-stop.d.ts +21 -0
- package/assets/plugin/tools/modify-stop.js +120 -0
- package/assets/plugin/tools/modify-target.d.ts +21 -0
- package/assets/plugin/tools/modify-target.js +110 -0
- package/assets/plugin/tools/propose-learning.d.ts +22 -0
- package/assets/plugin/tools/propose-learning.js +65 -0
- package/assets/plugin/tools/query-review-outcomes.d.ts +30 -0
- package/assets/plugin/tools/query-review-outcomes.js +64 -0
- package/assets/plugin/tools/query-trades.d.ts +21 -0
- package/assets/plugin/tools/query-trades.js +37 -0
- package/assets/plugin/tools/record-position-reviews.d.ts +38 -0
- package/assets/plugin/tools/record-position-reviews.js +147 -0
- package/assets/plugin/tools/save-strategy.d.ts +16 -0
- package/assets/plugin/tools/save-strategy.js +46 -0
- package/assets/plugin/tools/scan-pairs.d.ts +22 -0
- package/assets/plugin/tools/scan-pairs.js +234 -0
- package/assets/plugin/tools/score-setup.d.ts +31 -0
- package/assets/plugin/tools/score-setup.js +268 -0
- package/assets/plugin/tools/set-bracket-requirement.d.ts +18 -0
- package/assets/plugin/tools/set-bracket-requirement.js +81 -0
- package/assets/plugin/tools/set-exchange-credentials.d.ts +25 -0
- package/assets/plugin/tools/set-exchange-credentials.js +80 -0
- package/assets/plugin/tools/set-trading-mode.d.ts +26 -0
- package/assets/plugin/tools/set-trading-mode.js +152 -0
- package/assets/plugin/tools/test-exchange-credentials.d.ts +16 -0
- package/assets/plugin/tools/test-exchange-credentials.js +100 -0
- package/assets/plugin/tools/toggle-strategy.d.ts +8 -0
- package/assets/plugin/tools/toggle-strategy.js +15 -0
- package/assets/plugin/trading-params-cache.d.ts +26 -0
- package/assets/plugin/trading-params-cache.js +52 -0
- package/assets/plugin/types.d.ts +134 -0
- package/assets/plugin/types.js +7 -0
- package/assets/plugin/util/plugin-paths.d.ts +3 -0
- package/assets/plugin/util/plugin-paths.js +15 -0
- package/assets/plugin/venues/hyperliquid/hl-balance.d.ts +116 -0
- package/assets/plugin/venues/hyperliquid/hl-balance.js +145 -0
- package/assets/plugin/venues/hyperliquid/hl-bracket-coordinator.d.ts +123 -0
- package/assets/plugin/venues/hyperliquid/hl-bracket-coordinator.js +533 -0
- package/assets/plugin/venues/hyperliquid/hl-brackets.d.ts +102 -0
- package/assets/plugin/venues/hyperliquid/hl-brackets.js +172 -0
- package/assets/plugin/venues/hyperliquid/hl-cloid.d.ts +22 -0
- package/assets/plugin/venues/hyperliquid/hl-cloid.js +82 -0
- package/assets/plugin/venues/hyperliquid/hl-info-cache.d.ts +46 -0
- package/assets/plugin/venues/hyperliquid/hl-info-cache.js +125 -0
- package/assets/plugin/venues/hyperliquid/hl-live-adapter.d.ts +146 -0
- package/assets/plugin/venues/hyperliquid/hl-live-adapter.js +728 -0
- package/assets/plugin/venues/hyperliquid/hl-precision.d.ts +61 -0
- package/assets/plugin/venues/hyperliquid/hl-precision.js +176 -0
- package/assets/plugin/venues/hyperliquid/hl-private.d.ts +88 -0
- package/assets/plugin/venues/hyperliquid/hl-private.js +357 -0
- package/assets/plugin/venues/hyperliquid/hl-public.d.ts +79 -0
- package/assets/plugin/venues/hyperliquid/hl-public.js +436 -0
- package/assets/plugin/venues/hyperliquid/hl-rate-gate.d.ts +57 -0
- package/assets/plugin/venues/hyperliquid/hl-rate-gate.js +220 -0
- package/assets/plugin/venues/hyperliquid/hl-user-stream.d.ts +90 -0
- package/assets/plugin/venues/hyperliquid/hl-user-stream.js +220 -0
- package/assets/plugin/venues/registry.d.ts +38 -0
- package/assets/plugin/venues/registry.js +46 -0
- package/assets/plugin/venues/symbols.d.ts +43 -0
- package/assets/plugin/venues/symbols.js +107 -0
- package/assets/plugin/wave9/live-account-capture.d.ts +67 -0
- package/assets/plugin/wave9/live-account-capture.js +435 -0
- package/assets/plugin/wave9/live-autonomous-protection.d.ts +39 -0
- package/assets/plugin/wave9/live-autonomous-protection.js +112 -0
- package/assets/plugin/wave9/live-durable-reconciliation-scheduler.d.ts +33 -0
- package/assets/plugin/wave9/live-durable-reconciliation-scheduler.js +115 -0
- package/assets/plugin/wave9/live-execution-ledger.d.ts +107 -0
- package/assets/plugin/wave9/live-execution-ledger.js +498 -0
- package/assets/plugin/wave9/live-position-confirmation.d.ts +18 -0
- package/assets/plugin/wave9/live-position-confirmation.js +111 -0
- package/assets/plugin/wave9/live-residual-protection.d.ts +18 -0
- package/assets/plugin/wave9/live-residual-protection.js +250 -0
- package/assets/plugin/wave9/live-startup-reconciliation.d.ts +38 -0
- package/assets/plugin/wave9/live-startup-reconciliation.js +454 -0
- package/assets/plugin/wave9/live-symbol-ownership.d.ts +20 -0
- package/assets/plugin/wave9/live-symbol-ownership.js +132 -0
- package/assets/plugin/wave9/paper-admission-guard.d.ts +199 -0
- package/assets/plugin/wave9/paper-admission-guard.js +650 -0
- package/assets/plugin/wave9/usdm-evidence-provider.d.ts +42 -0
- package/assets/plugin/wave9/usdm-evidence-provider.js +133 -0
- package/dist/plugin.js +24 -15
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { CcxtTicker, CcxtOHLCV } from '../types.js';
|
|
2
|
+
import type { OrderBookDepth } from '../simulator/types.js';
|
|
3
|
+
import type { PublicMarketDataApi } from './public-market-data-api.js';
|
|
4
|
+
export declare class BinancePublicApi implements PublicMarketDataApi {
|
|
5
|
+
private exchange;
|
|
6
|
+
constructor();
|
|
7
|
+
/** Fetch raw CCXT ticker (includes funding rate, OI, info). Returns null on error. */
|
|
8
|
+
fetchTickerRaw(symbol: string): Promise<Record<string, any> | null>;
|
|
9
|
+
/** Fetch current ticker for a symbol. Returns null on error. */
|
|
10
|
+
fetchTicker(symbol: string): Promise<CcxtTicker | null>;
|
|
11
|
+
/** Fetch funding rate for a perpetual futures symbol. Returns null on error. */
|
|
12
|
+
fetchFundingRate(symbol: string): Promise<Record<string, any> | null>;
|
|
13
|
+
/** Fetch open interest for a perpetual futures symbol. Returns null on error. */
|
|
14
|
+
fetchOpenInterest(symbol: string): Promise<Record<string, any> | null>;
|
|
15
|
+
/** Fetch order book depth. Returns null on error. */
|
|
16
|
+
fetchOrderBook(symbol: string, limit?: number): Promise<OrderBookDepth | null>;
|
|
17
|
+
/** Fetch OHLCV candles. Returns null on error. */
|
|
18
|
+
fetchOHLCV(symbol: string, timeframe?: string, limit?: number): Promise<CcxtOHLCV[] | null>;
|
|
19
|
+
/** Probe Binance USD-M FUTURES reachability from this host — the readiness
|
|
20
|
+
* gate's core signal. Calls the futures-explicit implicit method so it hits
|
|
21
|
+
* `fapi.binance.com` (a bare `fetchTime()` on this instance resolves to spot
|
|
22
|
+
* `api.binance.com`, since the public client doesn't set defaultType:'future').
|
|
23
|
+
* HTTP 451 = Binance geo-restriction; the ban gate does NOT classify 451, so
|
|
24
|
+
* we inspect the message here. Ban-gate compliant (assertNotBanned/noteSuccess/
|
|
25
|
+
* noteBinanceError). Outcomes:
|
|
26
|
+
* - 'reachable' clean response (driftMs = serverTime − localTime)
|
|
27
|
+
* - 'geo_blocked' HTTP 451 — host is in a restricted region (actionable)
|
|
28
|
+
* - 'unknown' the ban/weight gate paused us — NOT a host problem
|
|
29
|
+
* - 'unreachable' network / DNS / timeout / other error */
|
|
30
|
+
probeReachability(): Promise<{
|
|
31
|
+
outcome: 'reachable' | 'geo_blocked' | 'unreachable' | 'unknown';
|
|
32
|
+
driftMs: number | null;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// Thin wrapper around CCXT for Binance public API endpoints.
|
|
2
|
+
// No API keys required — only uses public market data.
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { logger } from '../logger.js';
|
|
5
|
+
import { assertNotBanned, noteBinanceError, noteSuccess, BinanceBannedError } from './binance-ban-gate.js';
|
|
6
|
+
const TAG = 'binance-public';
|
|
7
|
+
// Load ccxt via CJS require — OpenClaw's ESM loader gives wrong module shape
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
let ccxtCjs;
|
|
10
|
+
try {
|
|
11
|
+
const _require = createRequire(import.meta.url);
|
|
12
|
+
ccxtCjs = _require('ccxt');
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Fallback: try global require (available in OpenClaw's loader context)
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
|
+
ccxtCjs = require('ccxt');
|
|
18
|
+
}
|
|
19
|
+
export class BinancePublicApi {
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
exchange;
|
|
22
|
+
constructor() {
|
|
23
|
+
const BinanceClass = ccxtCjs.binance ?? ccxtCjs.default?.binance;
|
|
24
|
+
if (!BinanceClass) {
|
|
25
|
+
throw new Error('CCXT binance class not found — check ccxt version');
|
|
26
|
+
}
|
|
27
|
+
this.exchange = new BinanceClass({
|
|
28
|
+
enableRateLimit: true,
|
|
29
|
+
});
|
|
30
|
+
logger.info(TAG, 'Binance public API initialized (no auth)');
|
|
31
|
+
}
|
|
32
|
+
/** Fetch raw CCXT ticker (includes funding rate, OI, info). Returns null on error. */
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
async fetchTickerRaw(symbol) {
|
|
35
|
+
try {
|
|
36
|
+
assertNotBanned('fetchTickerRaw');
|
|
37
|
+
const r = await this.exchange.fetchTicker(symbol);
|
|
38
|
+
noteSuccess();
|
|
39
|
+
return r;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
noteBinanceError(err);
|
|
43
|
+
logger.error(TAG, `fetchTickerRaw(${symbol}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Fetch current ticker for a symbol. Returns null on error. */
|
|
48
|
+
async fetchTicker(symbol) {
|
|
49
|
+
try {
|
|
50
|
+
assertNotBanned('fetchTicker');
|
|
51
|
+
const raw = await this.exchange.fetchTicker(symbol);
|
|
52
|
+
noteSuccess();
|
|
53
|
+
return {
|
|
54
|
+
symbol: raw.symbol,
|
|
55
|
+
last: raw.last ?? 0,
|
|
56
|
+
bid: raw.bid ?? 0,
|
|
57
|
+
ask: raw.ask ?? 0,
|
|
58
|
+
baseVolume: raw.baseVolume ?? 0,
|
|
59
|
+
quoteVolume: raw.quoteVolume ?? 0,
|
|
60
|
+
change: raw.change ?? 0,
|
|
61
|
+
percentage: raw.percentage ?? 0,
|
|
62
|
+
timestamp: raw.timestamp ?? Date.now(),
|
|
63
|
+
datetime: raw.datetime ?? new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
noteBinanceError(err);
|
|
68
|
+
logger.error(TAG, `fetchTicker(${symbol}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Fetch funding rate for a perpetual futures symbol. Returns null on error. */
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
74
|
+
async fetchFundingRate(symbol) {
|
|
75
|
+
try {
|
|
76
|
+
assertNotBanned('fetchFundingRate');
|
|
77
|
+
const r = await this.exchange.fetchFundingRate(symbol);
|
|
78
|
+
noteSuccess();
|
|
79
|
+
return r;
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
noteBinanceError(err);
|
|
83
|
+
logger.error(TAG, `fetchFundingRate(${symbol}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Fetch open interest for a perpetual futures symbol. Returns null on error. */
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
|
+
async fetchOpenInterest(symbol) {
|
|
90
|
+
try {
|
|
91
|
+
assertNotBanned('fetchOpenInterest');
|
|
92
|
+
const r = await this.exchange.fetchOpenInterest(symbol);
|
|
93
|
+
noteSuccess();
|
|
94
|
+
return r;
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
noteBinanceError(err);
|
|
98
|
+
logger.error(TAG, `fetchOpenInterest(${symbol}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Fetch order book depth. Returns null on error. */
|
|
103
|
+
async fetchOrderBook(symbol, limit = 20) {
|
|
104
|
+
try {
|
|
105
|
+
assertNotBanned('fetchOrderBook');
|
|
106
|
+
const raw = await this.exchange.fetchOrderBook(symbol, limit);
|
|
107
|
+
noteSuccess();
|
|
108
|
+
return {
|
|
109
|
+
bids: (raw.bids ?? []).map((l) => [l[0], l[1]]),
|
|
110
|
+
asks: (raw.asks ?? []).map((l) => [l[0], l[1]]),
|
|
111
|
+
timestamp: raw.timestamp ?? Date.now(),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
noteBinanceError(err);
|
|
116
|
+
logger.error(TAG, `fetchOrderBook(${symbol}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** Fetch OHLCV candles. Returns null on error. */
|
|
121
|
+
async fetchOHLCV(symbol, timeframe = '1h', limit = 100) {
|
|
122
|
+
try {
|
|
123
|
+
assertNotBanned('fetchOHLCV');
|
|
124
|
+
const raw = await this.exchange.fetchOHLCV(symbol, timeframe, undefined, limit);
|
|
125
|
+
noteSuccess();
|
|
126
|
+
// Validate each candle has 6 numeric values
|
|
127
|
+
const valid = [];
|
|
128
|
+
for (const candle of raw) {
|
|
129
|
+
if (candle.length >= 6 &&
|
|
130
|
+
typeof candle[0] === 'number' &&
|
|
131
|
+
typeof candle[1] === 'number' &&
|
|
132
|
+
typeof candle[2] === 'number' &&
|
|
133
|
+
typeof candle[3] === 'number' &&
|
|
134
|
+
typeof candle[4] === 'number' &&
|
|
135
|
+
typeof candle[5] === 'number') {
|
|
136
|
+
valid.push(candle);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return valid;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
noteBinanceError(err);
|
|
143
|
+
logger.error(TAG, `fetchOHLCV(${symbol}, ${timeframe}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Probe Binance USD-M FUTURES reachability from this host — the readiness
|
|
148
|
+
* gate's core signal. Calls the futures-explicit implicit method so it hits
|
|
149
|
+
* `fapi.binance.com` (a bare `fetchTime()` on this instance resolves to spot
|
|
150
|
+
* `api.binance.com`, since the public client doesn't set defaultType:'future').
|
|
151
|
+
* HTTP 451 = Binance geo-restriction; the ban gate does NOT classify 451, so
|
|
152
|
+
* we inspect the message here. Ban-gate compliant (assertNotBanned/noteSuccess/
|
|
153
|
+
* noteBinanceError). Outcomes:
|
|
154
|
+
* - 'reachable' clean response (driftMs = serverTime − localTime)
|
|
155
|
+
* - 'geo_blocked' HTTP 451 — host is in a restricted region (actionable)
|
|
156
|
+
* - 'unknown' the ban/weight gate paused us — NOT a host problem
|
|
157
|
+
* - 'unreachable' network / DNS / timeout / other error */
|
|
158
|
+
async probeReachability() {
|
|
159
|
+
try {
|
|
160
|
+
assertNotBanned('reachabilityProbe');
|
|
161
|
+
const r = await this.exchange.fapiPublicGetTime({});
|
|
162
|
+
noteSuccess();
|
|
163
|
+
const serverTime = Number(r?.serverTime);
|
|
164
|
+
const driftMs = Number.isFinite(serverTime) ? serverTime - Date.now() : null;
|
|
165
|
+
return { outcome: 'reachable', driftMs };
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
noteBinanceError(err);
|
|
169
|
+
if (err instanceof BinanceBannedError) {
|
|
170
|
+
// Gate paused us (418/429 backoff or weight pacer) — we didn't actually
|
|
171
|
+
// reach the host, so the result is UNKNOWN, not a reachability failure.
|
|
172
|
+
return { outcome: 'unknown', driftMs: null };
|
|
173
|
+
}
|
|
174
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
175
|
+
const geo = msg.includes('451');
|
|
176
|
+
logger.warn(TAG, `probeReachability failed${geo ? ' (HTTP 451 geo-block)' : ''}: ${msg}`);
|
|
177
|
+
return { outcome: geo ? 'geo_blocked' : 'unreachable', driftMs: null };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type IntelApiDeps } from '../tools/intel-api.js';
|
|
2
|
+
import type { CcxtTicker, CcxtOHLCV } from '../types.js';
|
|
3
|
+
import type { OrderBookDepth } from '../simulator/types.js';
|
|
4
|
+
import type { PublicMarketDataApi } from './public-market-data-api.js';
|
|
5
|
+
type RawCcxt = Record<string, any>;
|
|
6
|
+
export declare class IntelPublicApi implements PublicMarketDataApi {
|
|
7
|
+
private readonly deps;
|
|
8
|
+
constructor(deps: IntelApiDeps);
|
|
9
|
+
/** Latest price for `symbol` as a CcxtTicker (last=bid=ask=intel 1m close;
|
|
10
|
+
* zero modeled spread — the paper fill engine models slippage itself).
|
|
11
|
+
* Returns null on any intel error, matching BinancePublicApi's contract. */
|
|
12
|
+
fetchTicker(symbol: string): Promise<CcxtTicker | null>;
|
|
13
|
+
/** Intel has no raw-ticker/funding/OI HTTP route yet — null (same as a 451). */
|
|
14
|
+
fetchTickerRaw(): Promise<RawCcxt | null>;
|
|
15
|
+
fetchFundingRate(): Promise<RawCcxt | null>;
|
|
16
|
+
fetchOpenInterest(): Promise<RawCcxt | null>;
|
|
17
|
+
/** No intel depth route yet — null. The paper fill engine falls back to
|
|
18
|
+
* random slippage when the book is absent (see helpers.ts fetchOrderBook). */
|
|
19
|
+
fetchOrderBook(): Promise<OrderBookDepth | null>;
|
|
20
|
+
/** No intel candle route yet — null (candle-consuming analysis tools degrade
|
|
21
|
+
* exactly as they do under a 451; the agent's decisioning reads intel
|
|
22
|
+
* signals/scan tools, not raw candles). */
|
|
23
|
+
fetchOHLCV(): Promise<CcxtOHLCV[] | null>;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Intel-backed public market-data source for PAPER mode on hosts that Binance
|
|
2
|
+
// geo-blocks (HTTP 451). Paper execution is fully simulated; it only needs a
|
|
3
|
+
// price, which the intel service serves from its own (permitted-region) feeds
|
|
4
|
+
// via GET /api/price/:symbol (latest 1m close, ≤~60s stale). See
|
|
5
|
+
// docs/AGENT_READINESS_GATE_PLAN.md sibling + the wisekid 451 findings.
|
|
6
|
+
//
|
|
7
|
+
// Selected only when plugin-config `paperMarketDataSource: 'intel'` AND paper
|
|
8
|
+
// mode (index.ts). Live trading NEVER uses this — live needs the real exchange.
|
|
9
|
+
//
|
|
10
|
+
// Increment 1 serves PRICE only (fetchTicker), which is the trading-critical
|
|
11
|
+
// path: create_order / close_position price + the PaperMarketFeed mark loop.
|
|
12
|
+
// Candles / order book / funding / OI have no intel HTTP route yet, so those
|
|
13
|
+
// return null here — the SAME shape a 451 produces today (no regression), and
|
|
14
|
+
// order-book absence is already handled by the fill engine's random-slippage
|
|
15
|
+
// fallback. Candle/book/OI intel routes are a follow-up.
|
|
16
|
+
import { logger } from '../logger.js';
|
|
17
|
+
import { fetchIntelApi } from '../tools/intel-api.js';
|
|
18
|
+
const TAG = 'intel-public';
|
|
19
|
+
/** CCXT symbol (`BTC/USDT`, `BTC/USDT:USDT`) → intel format (`BTCUSDT`). */
|
|
20
|
+
function toIntelSymbol(symbol) {
|
|
21
|
+
return symbol.replace('/', '').replace(/:.*$/, '');
|
|
22
|
+
}
|
|
23
|
+
export class IntelPublicApi {
|
|
24
|
+
deps;
|
|
25
|
+
constructor(deps) {
|
|
26
|
+
this.deps = deps;
|
|
27
|
+
logger.info(TAG, 'Intel public market-data source active (paper mode, Binance reads routed to intel)');
|
|
28
|
+
}
|
|
29
|
+
/** Latest price for `symbol` as a CcxtTicker (last=bid=ask=intel 1m close;
|
|
30
|
+
* zero modeled spread — the paper fill engine models slippage itself).
|
|
31
|
+
* Returns null on any intel error, matching BinancePublicApi's contract. */
|
|
32
|
+
async fetchTicker(symbol) {
|
|
33
|
+
const res = await fetchIntelApi(`/api/price/${toIntelSymbol(symbol)}`, this.deps);
|
|
34
|
+
if ('error' in res) {
|
|
35
|
+
logger.warn(TAG, `fetchTicker(${symbol}) via intel failed: ${res.error}`);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const body = res;
|
|
39
|
+
const price = Number(body.price);
|
|
40
|
+
if (!Number.isFinite(price) || price <= 0) {
|
|
41
|
+
logger.warn(TAG, `fetchTicker(${symbol}) via intel returned a bad price: ${body.price}`);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const timestamp = Number.isFinite(body.time) ? body.time : Date.now();
|
|
45
|
+
return {
|
|
46
|
+
// Key on the ORIGINAL ccxt symbol so the simulator's per-symbol maps line up.
|
|
47
|
+
symbol,
|
|
48
|
+
last: price,
|
|
49
|
+
bid: price,
|
|
50
|
+
ask: price,
|
|
51
|
+
baseVolume: 0,
|
|
52
|
+
quoteVolume: 0,
|
|
53
|
+
change: 0,
|
|
54
|
+
percentage: 0,
|
|
55
|
+
timestamp,
|
|
56
|
+
datetime: new Date(timestamp).toISOString(),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Intel has no raw-ticker/funding/OI HTTP route yet — null (same as a 451). */
|
|
60
|
+
async fetchTickerRaw() {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
async fetchFundingRate() {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
async fetchOpenInterest() {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
/** No intel depth route yet — null. The paper fill engine falls back to
|
|
70
|
+
* random slippage when the book is absent (see helpers.ts fetchOrderBook). */
|
|
71
|
+
async fetchOrderBook() {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
/** No intel candle route yet — null (candle-consuming analysis tools degrade
|
|
75
|
+
* exactly as they do under a 451; the agent's decisioning reads intel
|
|
76
|
+
* signals/scan tools, not raw candles). */
|
|
77
|
+
async fetchOHLCV() {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CcxtTicker, CcxtOHLCV } from '../types.js';
|
|
2
|
+
import type { OrderBookDepth } from '../simulator/types.js';
|
|
3
|
+
type RawCcxt = Record<string, any>;
|
|
4
|
+
export interface PublicMarketDataApi {
|
|
5
|
+
fetchTickerRaw(symbol: string): Promise<RawCcxt | null>;
|
|
6
|
+
fetchTicker(symbol: string): Promise<CcxtTicker | null>;
|
|
7
|
+
fetchFundingRate(symbol: string): Promise<RawCcxt | null>;
|
|
8
|
+
fetchOpenInterest(symbol: string): Promise<RawCcxt | null>;
|
|
9
|
+
fetchOrderBook(symbol: string, limit?: number): Promise<OrderBookDepth | null>;
|
|
10
|
+
fetchOHLCV(symbol: string, timeframe?: string, limit?: number): Promise<CcxtOHLCV[] | null>;
|
|
11
|
+
}
|
|
12
|
+
/** Which exchange serves the public market-data tools (fetch_ticker,
|
|
13
|
+
* fetch_ohlcv, get_orderbook, get_market_structure, …).
|
|
14
|
+
*
|
|
15
|
+
* The configured VENUE decides, in BOTH books — a hyperliquid venue must
|
|
16
|
+
* never read Binance prices (live included: the agent would be running
|
|
17
|
+
* technical analysis on the wrong exchange's data while trading real money
|
|
18
|
+
* on HL). The intel price relay is a Binance-venue, paper-only escape hatch
|
|
19
|
+
* for 451-geo-blocked hosts. */
|
|
20
|
+
export declare function resolveMarketDataSource(opts: {
|
|
21
|
+
venue: 'binance' | 'hyperliquid';
|
|
22
|
+
isLive: boolean;
|
|
23
|
+
paperDataSource: 'binance' | 'intel';
|
|
24
|
+
hasConnectionToken: boolean;
|
|
25
|
+
}): 'hyperliquid' | 'intel' | 'binance';
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// The public market-data surface paper mode reads (prices, candles, book,
|
|
2
|
+
// funding, OI). Both BinancePublicApi (direct Binance) and IntelPublicApi
|
|
3
|
+
// (via the intel service, for Binance-451-geo-blocked hosts) implement it, so
|
|
4
|
+
// the paper wiring can select a source without any consumer knowing which.
|
|
5
|
+
//
|
|
6
|
+
// Deliberately EXCLUDES probeReachability: that is Binance-specific and only
|
|
7
|
+
// the readiness reporter uses it — it must always probe the REAL Binance host
|
|
8
|
+
// to detect the 451, so it keeps a concrete BinancePublicApi, never this.
|
|
9
|
+
/** Which exchange serves the public market-data tools (fetch_ticker,
|
|
10
|
+
* fetch_ohlcv, get_orderbook, get_market_structure, …).
|
|
11
|
+
*
|
|
12
|
+
* The configured VENUE decides, in BOTH books — a hyperliquid venue must
|
|
13
|
+
* never read Binance prices (live included: the agent would be running
|
|
14
|
+
* technical analysis on the wrong exchange's data while trading real money
|
|
15
|
+
* on HL). The intel price relay is a Binance-venue, paper-only escape hatch
|
|
16
|
+
* for 451-geo-blocked hosts. */
|
|
17
|
+
export function resolveMarketDataSource(opts) {
|
|
18
|
+
if (opts.venue === 'hyperliquid')
|
|
19
|
+
return 'hyperliquid';
|
|
20
|
+
if (!opts.isLive && opts.paperDataSource === 'intel' && opts.hasConnectionToken)
|
|
21
|
+
return 'intel';
|
|
22
|
+
return 'binance';
|
|
23
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** Central operational-gate values. Each gate is validated against its own enum
|
|
2
|
+
* PLUGIN-SIDE (§5b: central can never express a value the plugin doesn't
|
|
3
|
+
* already consider safe); an invalid field is dropped — field-level fallback,
|
|
4
|
+
* never whole-payload rejection. Gates are added one at a time
|
|
5
|
+
* (TOOL_DISTRIBUTION_ARCHITECTURE.md §11 step 3): `exitGate` (slice 2) →
|
|
6
|
+
* `positionReviewMode` (slice 3, the Position Decision Journal
|
|
7
|
+
* heartbeat-mandate + superset gate, file key `positionReview.mode`). Both
|
|
8
|
+
* ride the same four-stage `off → shadow → observe → enforce` ladder. */
|
|
9
|
+
export interface AgentGates {
|
|
10
|
+
exitGate?: 'off' | 'shadow' | 'observe' | 'enforce';
|
|
11
|
+
positionReviewMode?: 'off' | 'shadow' | 'observe' | 'enforce';
|
|
12
|
+
}
|
|
13
|
+
/** Server-resolved entitlement verdict (webapp lib/entitlements.ts, computed
|
|
14
|
+
* from the users row and delivered on the config channel). The plugin NEVER
|
|
15
|
+
* re-derives billing state — it consumes `paidAccess` as-is. Absent field =
|
|
16
|
+
* unknown = the entitlement gate fails OPEN (older webapp, outage, garbage):
|
|
17
|
+
* billing enforcement must never depend on this read succeeding; the
|
|
18
|
+
* server-side 403 walls (webapp Pro routes + intel) are the hard layer. */
|
|
19
|
+
export interface AgentEntitlement {
|
|
20
|
+
state: 'active' | 'trialing' | 'grace' | 'expired' | 'none';
|
|
21
|
+
paidAccess: boolean;
|
|
22
|
+
tier?: string;
|
|
23
|
+
expiresAt?: string;
|
|
24
|
+
graceUntil?: string;
|
|
25
|
+
}
|
|
26
|
+
/** The slice of /api/internal/config the plugin consumes today. `limits`
|
|
27
|
+
* arrives in the payload but is deliberately not modeled yet. */
|
|
28
|
+
export interface AgentConfig {
|
|
29
|
+
version: number;
|
|
30
|
+
tools: {
|
|
31
|
+
disabled: string[];
|
|
32
|
+
};
|
|
33
|
+
gates: AgentGates;
|
|
34
|
+
/** Absent when the server omitted it or the field failed validation. */
|
|
35
|
+
entitlement?: AgentEntitlement;
|
|
36
|
+
}
|
|
37
|
+
/** Hardcoded safe default — identical to pre-central behavior (nothing
|
|
38
|
+
* disabled, no central gate values → local file / defaults rule). */
|
|
39
|
+
export declare function defaultAgentConfig(): AgentConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Validate an untrusted payload (network response OR cache file) into an
|
|
42
|
+
* AgentConfig. Returns null when the payload as a whole is malformed —
|
|
43
|
+
* partial application is never allowed (§5b: central cannot express a value
|
|
44
|
+
* the plugin doesn't already consider safe).
|
|
45
|
+
*/
|
|
46
|
+
export declare function validateAgentConfig(raw: unknown): AgentConfig | null;
|
|
47
|
+
/** Per-field entitlement validation: a structurally-valid `{state, paidAccess}`
|
|
48
|
+
* pair (state in the enum, paidAccess a real boolean) is kept; ANYTHING else
|
|
49
|
+
* → undefined, and an absent entitlement makes the gate fail open. Garbage
|
|
50
|
+
* can pause new entries only by forging a syntactically-perfect verdict —
|
|
51
|
+
* and even then it can never touch closes/stops/emergency (those aren't in
|
|
52
|
+
* the gated set at all — see entitlement-gate.ts). */
|
|
53
|
+
export declare function validateEntitlement(raw: unknown): AgentEntitlement | undefined;
|
|
54
|
+
/** Version-monotonic acceptance (basic rollback/replay protection): a fetched
|
|
55
|
+
* config older than what we already applied is rejected. Equal versions are
|
|
56
|
+
* acceptable (idempotent re-apply is a no-op for the gate). */
|
|
57
|
+
export declare function isAcceptableVersion(fetched: AgentConfig, current: AgentConfig | null): boolean;
|
|
58
|
+
export interface FetchAgentConfigOptions {
|
|
59
|
+
apiBaseUrl: string;
|
|
60
|
+
token: string;
|
|
61
|
+
/** Injectable for unit tests + observability shims. */
|
|
62
|
+
fetchImpl?: typeof fetch;
|
|
63
|
+
timeoutMs?: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Fetch the central config. Returns a VALIDATED AgentConfig, or null on any
|
|
67
|
+
* failure (network, non-200, non-JSON, invalid shape). Never throws.
|
|
68
|
+
*/
|
|
69
|
+
export declare function fetchAgentConfig(opts: FetchAgentConfigOptions): Promise<AgentConfig | null>;
|
|
70
|
+
export declare function defaultCachePath(): string;
|
|
71
|
+
/** Read + validate the cached config. Missing/corrupt/invalid → null (the
|
|
72
|
+
* caller falls through to safe defaults). Never throws. */
|
|
73
|
+
export declare function readCachedConfig(path?: string): AgentConfig | null;
|
|
74
|
+
/** Atomically persist the last-known-good config (tmp + rename, 0o600 — the
|
|
75
|
+
* plugin-config-io convention). Failures are logged, never thrown: cache
|
|
76
|
+
* persistence is an optimization, not a correctness requirement. */
|
|
77
|
+
export declare function writeCachedConfig(config: AgentConfig, path?: string): void;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// Central per-user agent config — fetch + validate + last-known-good cache.
|
|
2
|
+
//
|
|
3
|
+
// Slice 1 of docs/TOOL_DISTRIBUTION_ARCHITECTURE.md §5: the plugin PULLS
|
|
4
|
+
// `GET /api/internal/config` (webapp, rc_ token → tenant) and applies the
|
|
5
|
+
// tool-enablement OFF-list through the ToolGate. The critical contract (§5b):
|
|
6
|
+
// only a successful, authenticated, VALIDATED, version-acceptable response
|
|
7
|
+
// ever changes behavior. A network error, 5xx, 401, garbage payload, or
|
|
8
|
+
// corrupt cache file can NEVER change what the agent does — the caller keeps
|
|
9
|
+
// the last-known-good config, or the hardcoded safe default (nothing
|
|
10
|
+
// disabled).
|
|
11
|
+
//
|
|
12
|
+
// The cache file lives next to plugin-config.json (`~/.reefclaw/
|
|
13
|
+
// agent-config-cache.json`) and follows the same atomic write convention
|
|
14
|
+
// (tmp + rename, mode 0o600 — see plugin-config-io.ts). It is validated on
|
|
15
|
+
// read with the same validator as the network path: a poisoned cache is as
|
|
16
|
+
// untrusted as a poisoned response.
|
|
17
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
18
|
+
import { dirname, join } from 'node:path';
|
|
19
|
+
import { homedir } from 'node:os';
|
|
20
|
+
import { logger, formatError } from '../logger.js';
|
|
21
|
+
const TAG = 'agent-config';
|
|
22
|
+
/** Shared four-stage ladder for the gates migrated so far. Kept as one set
|
|
23
|
+
* because exitGate + positionReviewMode use identical values; a future gate
|
|
24
|
+
* with a different enum gets its own constant. */
|
|
25
|
+
const MODE_LADDER_VALUES = new Set(['off', 'shadow', 'observe', 'enforce']);
|
|
26
|
+
const ENTITLEMENT_STATES = new Set([
|
|
27
|
+
'active',
|
|
28
|
+
'trialing',
|
|
29
|
+
'grace',
|
|
30
|
+
'expired',
|
|
31
|
+
'none',
|
|
32
|
+
]);
|
|
33
|
+
/** Hardcoded safe default — identical to pre-central behavior (nothing
|
|
34
|
+
* disabled, no central gate values → local file / defaults rule). */
|
|
35
|
+
export function defaultAgentConfig() {
|
|
36
|
+
return { version: 0, tools: { disabled: [] }, gates: {} };
|
|
37
|
+
}
|
|
38
|
+
/** Tool names must look like tool names. Anything else is dropped — central
|
|
39
|
+
* can never smuggle a weird value into the gate's set. */
|
|
40
|
+
const TOOL_NAME_RE = /^[a-z0-9_]{1,64}$/;
|
|
41
|
+
/**
|
|
42
|
+
* Validate an untrusted payload (network response OR cache file) into an
|
|
43
|
+
* AgentConfig. Returns null when the payload as a whole is malformed —
|
|
44
|
+
* partial application is never allowed (§5b: central cannot express a value
|
|
45
|
+
* the plugin doesn't already consider safe).
|
|
46
|
+
*/
|
|
47
|
+
export function validateAgentConfig(raw) {
|
|
48
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
49
|
+
return null;
|
|
50
|
+
const obj = raw;
|
|
51
|
+
const version = obj.version;
|
|
52
|
+
if (typeof version !== 'number' || !Number.isFinite(version) || version < 0)
|
|
53
|
+
return null;
|
|
54
|
+
const tools = obj.tools;
|
|
55
|
+
if (!tools || typeof tools !== 'object' || Array.isArray(tools))
|
|
56
|
+
return null;
|
|
57
|
+
const disabledRaw = tools.disabled;
|
|
58
|
+
if (!Array.isArray(disabledRaw))
|
|
59
|
+
return null;
|
|
60
|
+
const disabled = disabledRaw.filter((v) => typeof v === 'string' && TOOL_NAME_RE.test(v));
|
|
61
|
+
const config = {
|
|
62
|
+
version,
|
|
63
|
+
tools: { disabled },
|
|
64
|
+
gates: validateGates(obj.gates),
|
|
65
|
+
};
|
|
66
|
+
const entitlement = validateEntitlement(obj.entitlement);
|
|
67
|
+
if (entitlement)
|
|
68
|
+
config.entitlement = entitlement;
|
|
69
|
+
return config;
|
|
70
|
+
}
|
|
71
|
+
/** Per-field entitlement validation: a structurally-valid `{state, paidAccess}`
|
|
72
|
+
* pair (state in the enum, paidAccess a real boolean) is kept; ANYTHING else
|
|
73
|
+
* → undefined, and an absent entitlement makes the gate fail open. Garbage
|
|
74
|
+
* can pause new entries only by forging a syntactically-perfect verdict —
|
|
75
|
+
* and even then it can never touch closes/stops/emergency (those aren't in
|
|
76
|
+
* the gated set at all — see entitlement-gate.ts). */
|
|
77
|
+
export function validateEntitlement(raw) {
|
|
78
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
79
|
+
return undefined;
|
|
80
|
+
const obj = raw;
|
|
81
|
+
const state = obj.state;
|
|
82
|
+
const paidAccess = obj.paidAccess;
|
|
83
|
+
if (typeof state !== 'string' || !ENTITLEMENT_STATES.has(state))
|
|
84
|
+
return undefined;
|
|
85
|
+
if (typeof paidAccess !== 'boolean')
|
|
86
|
+
return undefined;
|
|
87
|
+
const entitlement = {
|
|
88
|
+
state: state,
|
|
89
|
+
paidAccess,
|
|
90
|
+
};
|
|
91
|
+
if (typeof obj.tier === 'string')
|
|
92
|
+
entitlement.tier = obj.tier;
|
|
93
|
+
if (typeof obj.expiresAt === 'string')
|
|
94
|
+
entitlement.expiresAt = obj.expiresAt;
|
|
95
|
+
if (typeof obj.graceUntil === 'string')
|
|
96
|
+
entitlement.graceUntil = obj.graceUntil;
|
|
97
|
+
return entitlement;
|
|
98
|
+
}
|
|
99
|
+
/** Per-field gate validation (§5b): a structurally-absent/garbage `gates`
|
|
100
|
+
* becomes `{}` (no central values → local config rules); each known gate is
|
|
101
|
+
* kept only when its value is in that gate's enum. Unknown keys are dropped. */
|
|
102
|
+
function validateGates(raw) {
|
|
103
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
104
|
+
return {};
|
|
105
|
+
const obj = raw;
|
|
106
|
+
const gates = {};
|
|
107
|
+
const exitGate = obj.exitGate;
|
|
108
|
+
if (typeof exitGate === 'string' && MODE_LADDER_VALUES.has(exitGate)) {
|
|
109
|
+
gates.exitGate = exitGate;
|
|
110
|
+
}
|
|
111
|
+
const positionReviewMode = obj.positionReviewMode;
|
|
112
|
+
if (typeof positionReviewMode === 'string' && MODE_LADDER_VALUES.has(positionReviewMode)) {
|
|
113
|
+
gates.positionReviewMode = positionReviewMode;
|
|
114
|
+
}
|
|
115
|
+
return gates;
|
|
116
|
+
}
|
|
117
|
+
/** Version-monotonic acceptance (basic rollback/replay protection): a fetched
|
|
118
|
+
* config older than what we already applied is rejected. Equal versions are
|
|
119
|
+
* acceptable (idempotent re-apply is a no-op for the gate). */
|
|
120
|
+
export function isAcceptableVersion(fetched, current) {
|
|
121
|
+
if (!current)
|
|
122
|
+
return true;
|
|
123
|
+
return fetched.version >= current.version;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Fetch the central config. Returns a VALIDATED AgentConfig, or null on any
|
|
127
|
+
* failure (network, non-200, non-JSON, invalid shape). Never throws.
|
|
128
|
+
*/
|
|
129
|
+
export async function fetchAgentConfig(opts) {
|
|
130
|
+
const { apiBaseUrl, token, fetchImpl = fetch, timeoutMs = 10_000 } = opts;
|
|
131
|
+
const url = `${apiBaseUrl.replace(/\/+$/, '')}/api/internal/config`;
|
|
132
|
+
try {
|
|
133
|
+
const res = await fetchImpl(url, {
|
|
134
|
+
headers: { authorization: `Bearer ${token}` },
|
|
135
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
136
|
+
});
|
|
137
|
+
if (!res.ok) {
|
|
138
|
+
logger.debug(TAG, `config fetch non-200: ${res.status}`);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
const body = (await res.json());
|
|
142
|
+
const validated = validateAgentConfig(body);
|
|
143
|
+
if (!validated)
|
|
144
|
+
logger.warn(TAG, 'config fetch returned an invalid payload — ignored');
|
|
145
|
+
return validated;
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
logger.debug(TAG, `config fetch failed: ${formatError(err)}`);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// ---- last-known-good cache file ---------------------------------------------
|
|
153
|
+
export function defaultCachePath() {
|
|
154
|
+
return join(homedir(), '.reefclaw', 'agent-config-cache.json');
|
|
155
|
+
}
|
|
156
|
+
/** Read + validate the cached config. Missing/corrupt/invalid → null (the
|
|
157
|
+
* caller falls through to safe defaults). Never throws. */
|
|
158
|
+
export function readCachedConfig(path = defaultCachePath()) {
|
|
159
|
+
try {
|
|
160
|
+
if (!existsSync(path))
|
|
161
|
+
return null;
|
|
162
|
+
const raw = readFileSync(path, 'utf-8');
|
|
163
|
+
return validateAgentConfig(JSON.parse(raw));
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
logger.warn(TAG, `config cache unreadable (${formatError(err)}) — using safe defaults`);
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** Atomically persist the last-known-good config (tmp + rename, 0o600 — the
|
|
171
|
+
* plugin-config-io convention). Failures are logged, never thrown: cache
|
|
172
|
+
* persistence is an optimization, not a correctness requirement. */
|
|
173
|
+
export function writeCachedConfig(config, path = defaultCachePath()) {
|
|
174
|
+
try {
|
|
175
|
+
const dir = dirname(path);
|
|
176
|
+
if (!existsSync(dir))
|
|
177
|
+
mkdirSync(dir, { recursive: true });
|
|
178
|
+
const tmpPath = `${path}.tmp`;
|
|
179
|
+
writeFileSync(tmpPath, JSON.stringify(config, null, 2) + '\n', {
|
|
180
|
+
encoding: 'utf-8',
|
|
181
|
+
mode: 0o600,
|
|
182
|
+
});
|
|
183
|
+
renameSync(tmpPath, path);
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
logger.warn(TAG, `config cache write failed: ${formatError(err)}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type AgentConfig, type AgentEntitlement, type AgentGates } from './agent-config-client.js';
|
|
2
|
+
import type { ToolGate } from './tool-gate.js';
|
|
3
|
+
export declare function resolvePollIntervalMs(): number;
|
|
4
|
+
export interface AgentConfigPollerOptions {
|
|
5
|
+
gate: ToolGate;
|
|
6
|
+
/** Central operational-gates consumer (slice 2 — exitGate). Optional so the
|
|
7
|
+
* tool-allowlist path stands alone; wired from index.ts with the module
|
|
8
|
+
* singleton `gateStore`. */
|
|
9
|
+
gateStore?: {
|
|
10
|
+
apply(gates: AgentGates): void;
|
|
11
|
+
};
|
|
12
|
+
/** Entitlement consumer (account-level enforcement). Optional, wired from
|
|
13
|
+
* index.ts with the module singleton `entitlementGate`. Receives the
|
|
14
|
+
* config's entitlement slice — including `undefined` when the server
|
|
15
|
+
* omitted it, which clears any held verdict (fail-open). */
|
|
16
|
+
entitlementGate?: {
|
|
17
|
+
apply(entitlement: AgentEntitlement | undefined): void;
|
|
18
|
+
};
|
|
19
|
+
apiBaseUrl: string;
|
|
20
|
+
token: string;
|
|
21
|
+
fetchImpl?: typeof fetch;
|
|
22
|
+
intervalMs?: number;
|
|
23
|
+
cachePath?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface AgentConfigPollerHandle {
|
|
26
|
+
stop(): void;
|
|
27
|
+
/** Exposed for tests/diagnostics — the currently applied config. */
|
|
28
|
+
getCurrent(): AgentConfig;
|
|
29
|
+
}
|
|
30
|
+
/** Test-only — allows the singleton guard to be reset between unit tests. */
|
|
31
|
+
export declare function __resetPollerSingleton(): void;
|
|
32
|
+
export declare function startAgentConfigPoller(opts: AgentConfigPollerOptions): AgentConfigPollerHandle;
|