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