@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,436 @@
|
|
|
1
|
+
// Hyperliquid public market-data source (keyless) — Phase 1 of
|
|
2
|
+
// docs/HYPERLIQUID_INTEGRATION_PLAN.md. Implements PublicMarketDataApi so
|
|
3
|
+
// PAPER mode on venue='hyperliquid' prices the simulator, the stop-watcher,
|
|
4
|
+
// and every market-data tool from Hyperliquid instead of Binance. Live
|
|
5
|
+
// trading does NOT use this class (the Phase 3 adapter owns its own reads).
|
|
6
|
+
//
|
|
7
|
+
// Protocol facts (verified 2026-07-11, plan §3 + live probe):
|
|
8
|
+
// - REST is POST-only: /info on api.hyperliquid.xyz (testnet:
|
|
9
|
+
// api.hyperliquid-testnet.xyz). CCXT@4.5.37 wraps everything we need.
|
|
10
|
+
// - `exchangeStatus` (weight 2) returns `{specialStatuses, time}` — the
|
|
11
|
+
// reachability probe AND a clock-drift source in one call.
|
|
12
|
+
// - `allMids` (weight 2) returns the mid price for EVERY coin in one call —
|
|
13
|
+
// the docs' recommended price read (plan §3: ccxt fetchTicker is
|
|
14
|
+
// 'emulated' — prefer allMids). fetchTicker serves its PRICE from one
|
|
15
|
+
// TTL-cached allMids call; volume/change context rides the last full
|
|
16
|
+
// fetchTickers snapshot, refreshed in the background at most every
|
|
17
|
+
// FULL_SNAPSHOT_REFRESH_MS. Why the split: ccxt@4.5.37's hyperliquid
|
|
18
|
+
// fetchTickers() literally calls fetchMarkets() — the full perp+spot
|
|
19
|
+
// meta/ctx pipeline — measured ~13s on the first HL soak box, which
|
|
20
|
+
// starved every 10s-timeout skill-poller call 100% of the time. allMids
|
|
21
|
+
// measured ~1.4s on the same box. The full address/IP rate gate is a
|
|
22
|
+
// Phase 3 concern (live cadences); paper-mode cadence here is bounded by
|
|
23
|
+
// the caches: ≤ (60s/TTL) weight-2 calls/min + ≤ weight-20 every 5 min.
|
|
24
|
+
// - CCXT auto-monetization landmine (plan §3.8): initializeClient() only
|
|
25
|
+
// fires on AUTHENTICATED clients, and this class is keyless — but we pin
|
|
26
|
+
// `builderFee:false, refSet:true` in options anyway so a future
|
|
27
|
+
// credentialed refactor can never silently enroll CCXT's builder fee or
|
|
28
|
+
// referral code. hl-public.test.ts asserts these options forever.
|
|
29
|
+
//
|
|
30
|
+
// Error contract mirrors BinancePublicApi/IntelPublicApi: null on ANY failure,
|
|
31
|
+
// never throw to consumers. Binance-shaped symbols (…/USDT) are a caller bug
|
|
32
|
+
// on this venue — logged clearly, null returned (never silently translated).
|
|
33
|
+
import { createRequire } from 'node:module';
|
|
34
|
+
import { logger } from '../../logger.js';
|
|
35
|
+
import { toCcxtSymbol, toHyperliquidCoin } from '../symbols.js';
|
|
36
|
+
const TAG = 'hl-public';
|
|
37
|
+
// Load ccxt via CJS require — OpenClaw's ESM loader gives wrong module shape
|
|
38
|
+
// (same pattern as binance-public.ts / binance-private.ts).
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
|
+
let ccxtCjs;
|
|
41
|
+
try {
|
|
42
|
+
const _require = createRequire(import.meta.url);
|
|
43
|
+
ccxtCjs = _require('ccxt');
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
47
|
+
ccxtCjs = require('ccxt');
|
|
48
|
+
}
|
|
49
|
+
/** Base URLs verified against the official docs + pinned ccxt source (plan §3.1). */
|
|
50
|
+
const HL_MAINNET_API = 'https://api.hyperliquid.xyz';
|
|
51
|
+
const HL_TESTNET_API = 'https://api.hyperliquid-testnet.xyz';
|
|
52
|
+
const DEFAULT_TICKER_TTL_MS = 4_000;
|
|
53
|
+
/** How stale the full fetchTickers snapshot (volume/change context) may get
|
|
54
|
+
* before fetchTicker kicks a background refresh. Deliberately long: the
|
|
55
|
+
* snapshot's ccxt call re-runs the whole fetchMarkets pipeline (weight ~60,
|
|
56
|
+
* ~13s on a slow host) and nothing price-critical reads these fields. */
|
|
57
|
+
const FULL_SNAPSHOT_REFRESH_MS = 300_000;
|
|
58
|
+
function resolveTickerTtlMs() {
|
|
59
|
+
const raw = Number(process.env.RC_HL_TICKER_TTL_MS);
|
|
60
|
+
if (!Number.isFinite(raw) || raw < 500)
|
|
61
|
+
return DEFAULT_TICKER_TTL_MS;
|
|
62
|
+
return raw;
|
|
63
|
+
}
|
|
64
|
+
export class HyperliquidPublicApi {
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
+
exchange;
|
|
67
|
+
testnet;
|
|
68
|
+
fetchImpl;
|
|
69
|
+
tickerTtlMs = resolveTickerTtlMs();
|
|
70
|
+
/** One upstream fetchTickers call serves every symbol within the TTL. */
|
|
71
|
+
tickersCache = null;
|
|
72
|
+
tickersInflight = null;
|
|
73
|
+
/** Coin → mid from one weight-2 allMids call (fetchTicker's price source). */
|
|
74
|
+
midsCache = null;
|
|
75
|
+
midsInflight = null;
|
|
76
|
+
constructor(opts = {}) {
|
|
77
|
+
this.testnet = opts.testnet === true;
|
|
78
|
+
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
79
|
+
if (opts.exchange) {
|
|
80
|
+
this.exchange = opts.exchange;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const HlClass = ccxtCjs.hyperliquid ?? ccxtCjs.default?.hyperliquid;
|
|
84
|
+
if (!HlClass) {
|
|
85
|
+
throw new Error('CCXT hyperliquid class not found — check ccxt version');
|
|
86
|
+
}
|
|
87
|
+
this.exchange = new HlClass({
|
|
88
|
+
enableRateLimit: true,
|
|
89
|
+
options: {
|
|
90
|
+
// ★ Never let CCXT enroll its own builder fee / referral code —
|
|
91
|
+
// plan §3.8. Keyless clients can't sign those actions anyway, but
|
|
92
|
+
// the pin is deliberate defense-in-depth for future refactors.
|
|
93
|
+
builderFee: false,
|
|
94
|
+
refSet: true,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
if (this.testnet) {
|
|
98
|
+
this.exchange.setSandboxMode(true);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
logger.info(TAG, `Hyperliquid public API initialized (no auth${this.testnet ? ', TESTNET' : ''})`);
|
|
102
|
+
}
|
|
103
|
+
baseUrl() {
|
|
104
|
+
return this.testnet ? HL_TESTNET_API : HL_MAINNET_API;
|
|
105
|
+
}
|
|
106
|
+
/** Canonical/ccxt symbol → this venue's ccxt symbol, or null (logged) when
|
|
107
|
+
* the symbol isn't a Hyperliquid USDC perp — a caller bug we surface
|
|
108
|
+
* loudly rather than silently translating quote assets. */
|
|
109
|
+
venueSymbol(symbol, ctx) {
|
|
110
|
+
try {
|
|
111
|
+
return toCcxtSymbol('hyperliquid', symbol);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
logger.warn(TAG, `${ctx}(${symbol}) — not a Hyperliquid symbol (${err instanceof Error ? err.message : String(err)}); use USDC pairs like BTC/USDC`);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** Fetch-all-tickers with a short TTL + inflight dedup. Returns a map keyed
|
|
119
|
+
* by ccxt symbol, or null on failure. */
|
|
120
|
+
async getTickers() {
|
|
121
|
+
const now = Date.now();
|
|
122
|
+
if (this.tickersCache && now - this.tickersCache.at < this.tickerTtlMs) {
|
|
123
|
+
return this.tickersCache.bySymbol;
|
|
124
|
+
}
|
|
125
|
+
if (this.tickersInflight)
|
|
126
|
+
return this.tickersInflight;
|
|
127
|
+
this.tickersInflight = (async () => {
|
|
128
|
+
try {
|
|
129
|
+
const raw = await this.exchange.fetchTickers();
|
|
130
|
+
const bySymbol = new Map(Object.entries(raw ?? {}));
|
|
131
|
+
this.tickersCache = { at: Date.now(), bySymbol };
|
|
132
|
+
return bySymbol;
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
logger.error(TAG, `fetchTickers failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
this.tickersInflight = null;
|
|
140
|
+
}
|
|
141
|
+
})();
|
|
142
|
+
return this.tickersInflight;
|
|
143
|
+
}
|
|
144
|
+
/** Coin → mid price from one weight-2 `allMids` call (TTL-cached, inflight-
|
|
145
|
+
* deduped; docs: hyperliquid.gitbook.io → Info endpoint → "Retrieve mids
|
|
146
|
+
* for all coins"). Null on ANY failure — callers fall back to the full
|
|
147
|
+
* snapshot path. Spot entries (`@<idx>` keys) parse fine and are simply
|
|
148
|
+
* never looked up (we key by perp coin name). */
|
|
149
|
+
async getMids() {
|
|
150
|
+
const now = Date.now();
|
|
151
|
+
if (this.midsCache && now - this.midsCache.at < this.tickerTtlMs) {
|
|
152
|
+
return this.midsCache.byCoin;
|
|
153
|
+
}
|
|
154
|
+
if (this.midsInflight)
|
|
155
|
+
return this.midsInflight;
|
|
156
|
+
this.midsInflight = (async () => {
|
|
157
|
+
try {
|
|
158
|
+
const raw = await this.exchange.publicPostInfo({ type: 'allMids' });
|
|
159
|
+
const byCoin = new Map();
|
|
160
|
+
for (const [coin, mid] of Object.entries(raw ?? {})) {
|
|
161
|
+
const n = Number(mid);
|
|
162
|
+
if (Number.isFinite(n) && n > 0)
|
|
163
|
+
byCoin.set(coin, n);
|
|
164
|
+
}
|
|
165
|
+
if (byCoin.size === 0) {
|
|
166
|
+
logger.warn(TAG, 'allMids returned no parseable mids');
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
this.midsCache = { at: Date.now(), byCoin };
|
|
170
|
+
return byCoin;
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
logger.error(TAG, `allMids failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
this.midsInflight = null;
|
|
178
|
+
}
|
|
179
|
+
})();
|
|
180
|
+
return this.midsInflight;
|
|
181
|
+
}
|
|
182
|
+
/** Fire-and-forget full-snapshot refresh once it ages past
|
|
183
|
+
* FULL_SNAPSHOT_REFRESH_MS — fetchTicker must never block on the heavy
|
|
184
|
+
* fetchTickers call when a fresh mid is available. getTickers' own
|
|
185
|
+
* inflight dedup + error handling make this safe to kick repeatedly. */
|
|
186
|
+
maybeRefreshSnapshot() {
|
|
187
|
+
const at = this.tickersCache?.at ?? 0;
|
|
188
|
+
if (Date.now() - at < FULL_SNAPSHOT_REFRESH_MS)
|
|
189
|
+
return;
|
|
190
|
+
if (this.tickersInflight)
|
|
191
|
+
return;
|
|
192
|
+
void this.getTickers();
|
|
193
|
+
}
|
|
194
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
195
|
+
async fetchTickerRaw(symbol) {
|
|
196
|
+
const vs = this.venueSymbol(symbol, 'fetchTickerRaw');
|
|
197
|
+
if (!vs)
|
|
198
|
+
return null;
|
|
199
|
+
const tickers = await this.getTickers();
|
|
200
|
+
return tickers?.get(vs) ?? null;
|
|
201
|
+
}
|
|
202
|
+
/** Price from the weight-2 allMids fast path; volume/change context from
|
|
203
|
+
* the last full snapshot (background-refreshed). Hyperliquid's asset
|
|
204
|
+
* contexts carry mark/mid rather than a trade-tape bid/ask; absent fields
|
|
205
|
+
* fall back to `last` with zero modeled spread — the paper fill engine
|
|
206
|
+
* models slippage itself (same convention as IntelPublicApi). Falls back
|
|
207
|
+
* to the original blocking full-snapshot path when allMids fails. */
|
|
208
|
+
async fetchTicker(symbol) {
|
|
209
|
+
const vs = this.venueSymbol(symbol, 'fetchTicker');
|
|
210
|
+
if (!vs)
|
|
211
|
+
return null;
|
|
212
|
+
const coin = toHyperliquidCoin(symbol);
|
|
213
|
+
const mids = await this.getMids();
|
|
214
|
+
const mid = mids?.get(coin);
|
|
215
|
+
if (mid !== undefined) {
|
|
216
|
+
this.maybeRefreshSnapshot();
|
|
217
|
+
const base = this.tickersCache?.bySymbol.get(vs);
|
|
218
|
+
const timestamp = this.midsCache?.at ?? Date.now();
|
|
219
|
+
return {
|
|
220
|
+
symbol,
|
|
221
|
+
last: mid,
|
|
222
|
+
bid: mid,
|
|
223
|
+
ask: mid,
|
|
224
|
+
baseVolume: Number(base?.baseVolume ?? 0) || 0,
|
|
225
|
+
quoteVolume: Number(base?.quoteVolume ?? 0) || 0,
|
|
226
|
+
change: Number(base?.change ?? 0) || 0,
|
|
227
|
+
percentage: Number(base?.percentage ?? 0) || 0,
|
|
228
|
+
timestamp,
|
|
229
|
+
datetime: new Date(timestamp).toISOString(),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
const tickers = await this.getTickers();
|
|
233
|
+
const raw = tickers?.get(vs);
|
|
234
|
+
if (!raw) {
|
|
235
|
+
if (tickers)
|
|
236
|
+
logger.warn(TAG, `fetchTicker(${symbol}) — ${vs} not in Hyperliquid universe`);
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
const last = Number(raw.last ?? raw.close ?? raw.markPrice ?? NaN);
|
|
240
|
+
if (!Number.isFinite(last) || last <= 0) {
|
|
241
|
+
logger.warn(TAG, `fetchTicker(${symbol}) — no usable price on ticker`);
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
// Timestamp honesty (issue #202): this fallback serves the background-
|
|
245
|
+
// refreshed FULL SNAPSHOT price, which can be minutes old. When the raw
|
|
246
|
+
// ticker carries no timestamp, stamp the snapshot's fetch time — never
|
|
247
|
+
// Date.now(), which would disguise a stale price as fresh and defeat the
|
|
248
|
+
// paper engine's stale-quote fill guard.
|
|
249
|
+
const timestamp = Number.isFinite(raw.timestamp)
|
|
250
|
+
? Number(raw.timestamp)
|
|
251
|
+
: this.tickersCache?.at ?? Date.now();
|
|
252
|
+
return {
|
|
253
|
+
// Key on the symbol the CALLER used so per-symbol maps line up.
|
|
254
|
+
symbol,
|
|
255
|
+
last,
|
|
256
|
+
bid: Number(raw.bid ?? NaN) > 0 ? Number(raw.bid) : last,
|
|
257
|
+
ask: Number(raw.ask ?? NaN) > 0 ? Number(raw.ask) : last,
|
|
258
|
+
baseVolume: Number(raw.baseVolume ?? 0) || 0,
|
|
259
|
+
quoteVolume: Number(raw.quoteVolume ?? 0) || 0,
|
|
260
|
+
change: Number(raw.change ?? 0) || 0,
|
|
261
|
+
percentage: Number(raw.percentage ?? 0) || 0,
|
|
262
|
+
timestamp,
|
|
263
|
+
datetime: raw.datetime ?? new Date(timestamp).toISOString(),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
267
|
+
async fetchFundingRate(symbol) {
|
|
268
|
+
const vs = this.venueSymbol(symbol, 'fetchFundingRate');
|
|
269
|
+
if (!vs)
|
|
270
|
+
return null;
|
|
271
|
+
try {
|
|
272
|
+
const r = await this.exchange.fetchFundingRate(vs);
|
|
273
|
+
return r ?? null;
|
|
274
|
+
}
|
|
275
|
+
catch (err) {
|
|
276
|
+
logger.error(TAG, `fetchFundingRate(${symbol}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
281
|
+
async fetchOpenInterest(symbol) {
|
|
282
|
+
const vs = this.venueSymbol(symbol, 'fetchOpenInterest');
|
|
283
|
+
if (!vs)
|
|
284
|
+
return null;
|
|
285
|
+
try {
|
|
286
|
+
const r = await this.exchange.fetchOpenInterest(vs);
|
|
287
|
+
return r ?? null;
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
logger.error(TAG, `fetchOpenInterest(${symbol}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/** l2Book — Hyperliquid serves at most 20 levels/side (plan §3.6). */
|
|
295
|
+
async fetchOrderBook(symbol, limit = 20) {
|
|
296
|
+
const vs = this.venueSymbol(symbol, 'fetchOrderBook');
|
|
297
|
+
if (!vs)
|
|
298
|
+
return null;
|
|
299
|
+
try {
|
|
300
|
+
const raw = await this.exchange.fetchOrderBook(vs, Math.min(limit, 20));
|
|
301
|
+
return {
|
|
302
|
+
bids: (raw.bids ?? []).map((l) => [l[0], l[1]]),
|
|
303
|
+
asks: (raw.asks ?? []).map((l) => [l[0], l[1]]),
|
|
304
|
+
timestamp: raw.timestamp ?? Date.now(),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
catch (err) {
|
|
308
|
+
logger.error(TAG, `fetchOrderBook(${symbol}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/** candleSnapshot — only the most recent 5000 candles exist per (coin,
|
|
313
|
+
* interval) (plan §3.6); requests inside that window behave like Binance. */
|
|
314
|
+
async fetchOHLCV(symbol, timeframe = '1h', limit = 100) {
|
|
315
|
+
const vs = this.venueSymbol(symbol, 'fetchOHLCV');
|
|
316
|
+
if (!vs)
|
|
317
|
+
return null;
|
|
318
|
+
try {
|
|
319
|
+
const raw = await this.exchange.fetchOHLCV(vs, timeframe, undefined, limit);
|
|
320
|
+
const valid = [];
|
|
321
|
+
for (const candle of raw) {
|
|
322
|
+
if (candle.length >= 6 &&
|
|
323
|
+
typeof candle[0] === 'number' &&
|
|
324
|
+
typeof candle[1] === 'number' &&
|
|
325
|
+
typeof candle[2] === 'number' &&
|
|
326
|
+
typeof candle[3] === 'number' &&
|
|
327
|
+
typeof candle[4] === 'number' &&
|
|
328
|
+
typeof candle[5] === 'number') {
|
|
329
|
+
valid.push(candle);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return valid;
|
|
333
|
+
}
|
|
334
|
+
catch (err) {
|
|
335
|
+
logger.error(TAG, `fetchOHLCV(${symbol}, ${timeframe}) failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/** Probe Hyperliquid reachability from this host — the readiness gate's
|
|
340
|
+
* venue signal, mirroring BinancePublicApi.probeReachability's outcome
|
|
341
|
+
* shape. Hand-rolled POST /info `exchangeStatus` (weight 2) so the probe
|
|
342
|
+
* has zero ccxt-method-shape dependence; the response's `time` field
|
|
343
|
+
* (verified live 2026-07-11: `{"specialStatuses":null,"time":…}`) doubles
|
|
344
|
+
* as the clock-drift source. Geo classification is best-effort — HL's
|
|
345
|
+
* API-level geo behavior is UNVERIFIED (plan §3.9); a 403/451 maps to
|
|
346
|
+
* geo_blocked, anything else non-2xx/network maps to unreachable. */
|
|
347
|
+
async probeReachability() {
|
|
348
|
+
const ac = new AbortController();
|
|
349
|
+
const tid = setTimeout(() => ac.abort(), 10_000);
|
|
350
|
+
try {
|
|
351
|
+
const res = await this.fetchImpl(`${this.baseUrl()}/info`, {
|
|
352
|
+
method: 'POST',
|
|
353
|
+
headers: { 'content-type': 'application/json' },
|
|
354
|
+
body: JSON.stringify({ type: 'exchangeStatus' }),
|
|
355
|
+
signal: ac.signal,
|
|
356
|
+
});
|
|
357
|
+
if (res.status === 451 || res.status === 403) {
|
|
358
|
+
logger.warn(TAG, `probeReachability: HTTP ${res.status} (geo/policy block)`);
|
|
359
|
+
return { outcome: 'geo_blocked', driftMs: null };
|
|
360
|
+
}
|
|
361
|
+
if (res.status < 200 || res.status >= 300) {
|
|
362
|
+
logger.warn(TAG, `probeReachability: HTTP ${res.status}`);
|
|
363
|
+
return { outcome: 'unreachable', driftMs: null };
|
|
364
|
+
}
|
|
365
|
+
const body = (await res.json());
|
|
366
|
+
const serverTime = Number(body?.time);
|
|
367
|
+
const driftMs = Number.isFinite(serverTime) ? serverTime - Date.now() : null;
|
|
368
|
+
return { outcome: 'reachable', driftMs };
|
|
369
|
+
}
|
|
370
|
+
catch (err) {
|
|
371
|
+
logger.warn(TAG, `probeReachability failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
372
|
+
return { outcome: 'unreachable', driftMs: null };
|
|
373
|
+
}
|
|
374
|
+
finally {
|
|
375
|
+
clearTimeout(tid);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
/** `meta` — the asset universe (szDecimals, maxLeverage, positional assetIndex).
|
|
379
|
+
* Keyless info read, weight 20. Feeds HyperliquidInfoCache. Returns null on any
|
|
380
|
+
* failure (never a partial universe — a half-loaded rules table would silently
|
|
381
|
+
* reject orders). */
|
|
382
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
383
|
+
async fetchMeta() {
|
|
384
|
+
try {
|
|
385
|
+
const res = await this.fetchImpl(`${this.baseUrl()}/info`, {
|
|
386
|
+
method: 'POST',
|
|
387
|
+
headers: { 'content-type': 'application/json' },
|
|
388
|
+
body: JSON.stringify({ type: 'meta' }),
|
|
389
|
+
signal: AbortSignal.timeout(15_000),
|
|
390
|
+
});
|
|
391
|
+
if (!res.ok) {
|
|
392
|
+
logger.warn(TAG, `fetchMeta: HTTP ${res.status}`);
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
return await res.json();
|
|
396
|
+
}
|
|
397
|
+
catch (err) {
|
|
398
|
+
logger.warn(TAG, `fetchMeta failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/** ★ MARK price — the price HL trigger orders fire on (there is no workingType
|
|
403
|
+
* choice on this venue). Stop-distance validation and every trigger MUST use
|
|
404
|
+
* this, never `last`: the mark is a CEX-composite median that can diverge from
|
|
405
|
+
* HL's own last trade. Sourced from `metaAndAssetCtxs` (one weight-20 call
|
|
406
|
+
* covers every asset). Returns null on failure — never a stale guess. */
|
|
407
|
+
async fetchMarkPrice(symbol) {
|
|
408
|
+
try {
|
|
409
|
+
const res = await this.fetchImpl(`${this.baseUrl()}/info`, {
|
|
410
|
+
method: 'POST',
|
|
411
|
+
headers: { 'content-type': 'application/json' },
|
|
412
|
+
body: JSON.stringify({ type: 'metaAndAssetCtxs' }),
|
|
413
|
+
signal: AbortSignal.timeout(15_000),
|
|
414
|
+
});
|
|
415
|
+
if (!res.ok) {
|
|
416
|
+
logger.warn(TAG, `fetchMarkPrice: HTTP ${res.status}`);
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
const body = (await res.json());
|
|
420
|
+
const universe = body?.[0]?.universe ?? [];
|
|
421
|
+
const ctxs = body?.[1] ?? [];
|
|
422
|
+
const coin = toHyperliquidCoin(symbol);
|
|
423
|
+
const idx = universe.findIndex((u) => u?.name === coin);
|
|
424
|
+
if (idx < 0) {
|
|
425
|
+
logger.warn(TAG, `fetchMarkPrice: ${coin} not in meta.universe`);
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
const mark = Number(ctxs[idx]?.markPx);
|
|
429
|
+
return Number.isFinite(mark) && mark > 0 ? mark : null;
|
|
430
|
+
}
|
|
431
|
+
catch (err) {
|
|
432
|
+
logger.warn(TAG, `fetchMarkPrice failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Info-request weights, from the docs (§3.3). Anything unlisted defaults to 20 —
|
|
2
|
+
* the conservative side. `/exchange` actions are `1 + floor(batch/40)`. */
|
|
3
|
+
export declare const HL_INFO_WEIGHTS: Record<string, number>;
|
|
4
|
+
export declare class HyperliquidRateLimitedError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
/** Thrown by the proactive pacer BEFORE a call goes out. Subclass so every
|
|
8
|
+
* existing `catch (HyperliquidRateLimitedError)` absorbs it — the same
|
|
9
|
+
* relationship `BinanceWeightPacedError` has to `BinanceBannedError`. */
|
|
10
|
+
export declare class HyperliquidPacedError extends HyperliquidRateLimitedError {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
/** Current 60s IP-weight estimate. */
|
|
14
|
+
export declare function currentIpWeight(now?: number): number;
|
|
15
|
+
/** Weight for an info context (defaults to the conservative 20). */
|
|
16
|
+
export declare function infoWeight(ctx: string): number;
|
|
17
|
+
/** `/exchange` IP weight for a batch of n actions: 1 + floor(n/40). */
|
|
18
|
+
export declare function exchangeIpWeight(batchLen: number): number;
|
|
19
|
+
/** FIRST LINE of every gated read's try-block.
|
|
20
|
+
*
|
|
21
|
+
* Throws when:
|
|
22
|
+
* - a 429 backoff is active (hard stop — like an active Binance ban), or
|
|
23
|
+
* - the IP weight window is over its soft ceiling (proactive pacing), or
|
|
24
|
+
* - the address budget is below the floor AND this context is shed-able.
|
|
25
|
+
*
|
|
26
|
+
* Order/cancel/close paths must NOT call this — they arm the gate via
|
|
27
|
+
* `noteError` only, so a limit can never block an exit. */
|
|
28
|
+
export declare function assertNotLimited(ctx: string): void;
|
|
29
|
+
/** Record a successful call's cost. `addressActions` is 0 for pure info reads
|
|
30
|
+
* (they cost IP weight only) and n for an `/exchange` batch of n actions. */
|
|
31
|
+
export declare function noteSuccess(ctx: string, cost?: {
|
|
32
|
+
ipWeight?: number;
|
|
33
|
+
addressActions?: number;
|
|
34
|
+
}): void;
|
|
35
|
+
/** Arm the gate from a caught error. Called in EVERY catch — including on the
|
|
36
|
+
* order/cancel paths that are never pre-gated (so a burst of rejects still
|
|
37
|
+
* backs the gate off). */
|
|
38
|
+
export declare function noteError(err: unknown, ctx?: string): void;
|
|
39
|
+
/** HL surfaces rate limiting as HTTP 429 and/or a text body; match on shape, not
|
|
40
|
+
* on a venue flag, so the skill-side breaker can reuse this predicate. */
|
|
41
|
+
export declare function isRateLimitError(err: unknown): boolean;
|
|
42
|
+
/** Feed the address budget from info `userRateLimit` (`nRequestsCap −
|
|
43
|
+
* nRequestsUsed`). Poll it every ~5 min — it costs weight 20. */
|
|
44
|
+
export declare function updateAddressBudget(args: {
|
|
45
|
+
nRequestsUsed: number;
|
|
46
|
+
nRequestsCap: number;
|
|
47
|
+
}): void;
|
|
48
|
+
/** Snapshot for tests + the readiness/diagnostic surfaces. */
|
|
49
|
+
export declare function getGateState(): {
|
|
50
|
+
ipWeight60s: number;
|
|
51
|
+
weightCeiling: number;
|
|
52
|
+
addressRemaining?: number;
|
|
53
|
+
limited: boolean;
|
|
54
|
+
limitedForMs: number;
|
|
55
|
+
};
|
|
56
|
+
/** Test-only reset. */
|
|
57
|
+
export declare function __resetGateForTests(): void;
|