@senpi/runtime 1.0.95-dev.20260408174401
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/README.md +155 -0
- package/dist/actions/close-position/close-position.action.d.ts +16 -0
- package/dist/actions/close-position/close-position.action.d.ts.map +1 -0
- package/dist/actions/close-position/close-position.action.js +220 -0
- package/dist/actions/close-position/close-position.action.js.map +1 -0
- package/dist/actions/decision-engine.d.ts +32 -0
- package/dist/actions/decision-engine.d.ts.map +1 -0
- package/dist/actions/decision-engine.js +103 -0
- package/dist/actions/decision-engine.js.map +1 -0
- package/dist/actions/llm-decision/anthropic-llm-decision.d.ts +12 -0
- package/dist/actions/llm-decision/anthropic-llm-decision.d.ts.map +1 -0
- package/dist/actions/llm-decision/anthropic-llm-decision.js +74 -0
- package/dist/actions/llm-decision/anthropic-llm-decision.js.map +1 -0
- package/dist/actions/llm-decision/factory.d.ts +17 -0
- package/dist/actions/llm-decision/factory.d.ts.map +1 -0
- package/dist/actions/llm-decision/factory.js +29 -0
- package/dist/actions/llm-decision/factory.js.map +1 -0
- package/dist/actions/llm-decision/index.d.ts +8 -0
- package/dist/actions/llm-decision/index.d.ts.map +1 -0
- package/dist/actions/llm-decision/index.js +5 -0
- package/dist/actions/llm-decision/index.js.map +1 -0
- package/dist/actions/llm-decision/openclaw-llm-decision.d.ts +14 -0
- package/dist/actions/llm-decision/openclaw-llm-decision.d.ts.map +1 -0
- package/dist/actions/llm-decision/openclaw-llm-decision.js +58 -0
- package/dist/actions/llm-decision/openclaw-llm-decision.js.map +1 -0
- package/dist/actions/llm-decision/shared.d.ts +41 -0
- package/dist/actions/llm-decision/shared.d.ts.map +1 -0
- package/dist/actions/llm-decision/shared.js +117 -0
- package/dist/actions/llm-decision/shared.js.map +1 -0
- package/dist/actions/open-position/open-position.action.d.ts +16 -0
- package/dist/actions/open-position/open-position.action.d.ts.map +1 -0
- package/dist/actions/open-position/open-position.action.js +278 -0
- package/dist/actions/open-position/open-position.action.js.map +1 -0
- package/dist/actions/position-tracker/position-tracker.action.d.ts +14 -0
- package/dist/actions/position-tracker/position-tracker.action.d.ts.map +1 -0
- package/dist/actions/position-tracker/position-tracker.action.js +201 -0
- package/dist/actions/position-tracker/position-tracker.action.js.map +1 -0
- package/dist/actions/types.d.ts +123 -0
- package/dist/actions/types.d.ts.map +1 -0
- package/dist/actions/types.js +3 -0
- package/dist/actions/types.js.map +1 -0
- package/dist/cli/guide-commands.d.ts +27 -0
- package/dist/cli/guide-commands.d.ts.map +1 -0
- package/dist/cli/guide-commands.js +481 -0
- package/dist/cli/guide-commands.js.map +1 -0
- package/dist/cli/senpi-cli-config.d.ts +33 -0
- package/dist/cli/senpi-cli-config.d.ts.map +1 -0
- package/dist/cli/senpi-cli-config.js +130 -0
- package/dist/cli/senpi-cli-config.js.map +1 -0
- package/dist/cli/senpi-commands.d.ts +21 -0
- package/dist/cli/senpi-commands.d.ts.map +1 -0
- package/dist/cli/senpi-commands.js +471 -0
- package/dist/cli/senpi-commands.js.map +1 -0
- package/dist/cli/senpi-config-commands.d.ts +11 -0
- package/dist/cli/senpi-config-commands.d.ts.map +1 -0
- package/dist/cli/senpi-config-commands.js +113 -0
- package/dist/cli/senpi-config-commands.js.map +1 -0
- package/dist/constants/dsl/index.d.ts +62 -0
- package/dist/constants/dsl/index.d.ts.map +1 -0
- package/dist/constants/dsl/index.js +62 -0
- package/dist/constants/dsl/index.js.map +1 -0
- package/dist/context/context-builder.d.ts +14 -0
- package/dist/context/context-builder.d.ts.map +1 -0
- package/dist/context/context-builder.js +38 -0
- package/dist/context/context-builder.js.map +1 -0
- package/dist/context/index.d.ts +5 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +5 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/interpolate.d.ts +6 -0
- package/dist/context/interpolate.d.ts.map +1 -0
- package/dist/context/interpolate.js +15 -0
- package/dist/context/interpolate.js.map +1 -0
- package/dist/context/providers/asset-trend.provider.d.ts +42 -0
- package/dist/context/providers/asset-trend.provider.d.ts.map +1 -0
- package/dist/context/providers/asset-trend.provider.js +90 -0
- package/dist/context/providers/asset-trend.provider.js.map +1 -0
- package/dist/context/providers/index.d.ts +5 -0
- package/dist/context/providers/index.d.ts.map +1 -0
- package/dist/context/providers/index.js +5 -0
- package/dist/context/providers/index.js.map +1 -0
- package/dist/context/providers/scanner-context.provider.d.ts +10 -0
- package/dist/context/providers/scanner-context.provider.d.ts.map +1 -0
- package/dist/context/providers/scanner-context.provider.js +20 -0
- package/dist/context/providers/scanner-context.provider.js.map +1 -0
- package/dist/context/providers/signal.provider.d.ts +11 -0
- package/dist/context/providers/signal.provider.d.ts.map +1 -0
- package/dist/context/providers/signal.provider.js +30 -0
- package/dist/context/providers/signal.provider.js.map +1 -0
- package/dist/context/providers/strategy.provider.d.ts +14 -0
- package/dist/context/providers/strategy.provider.d.ts.map +1 -0
- package/dist/context/providers/strategy.provider.js +71 -0
- package/dist/context/providers/strategy.provider.js.map +1 -0
- package/dist/context/types.d.ts +45 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +18 -0
- package/dist/context/types.js.map +1 -0
- package/dist/debug.d.ts +2 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +591 -0
- package/dist/debug.js.map +1 -0
- package/dist/dsl/config/exit-block.d.ts +11 -0
- package/dist/dsl/config/exit-block.d.ts.map +1 -0
- package/dist/dsl/config/exit-block.js +5 -0
- package/dist/dsl/config/exit-block.js.map +1 -0
- package/dist/dsl/config/index.d.ts +8 -0
- package/dist/dsl/config/index.d.ts.map +1 -0
- package/dist/dsl/config/index.js +6 -0
- package/dist/dsl/config/index.js.map +1 -0
- package/dist/dsl/config/parse-phase.d.ts +14 -0
- package/dist/dsl/config/parse-phase.d.ts.map +1 -0
- package/dist/dsl/config/parse-phase.js +78 -0
- package/dist/dsl/config/parse-phase.js.map +1 -0
- package/dist/dsl/config/parse-plugin-config.d.ts +8 -0
- package/dist/dsl/config/parse-plugin-config.d.ts.map +1 -0
- package/dist/dsl/config/parse-plugin-config.js +27 -0
- package/dist/dsl/config/parse-plugin-config.js.map +1 -0
- package/dist/dsl/config/parse-preset.d.ts +7 -0
- package/dist/dsl/config/parse-preset.d.ts.map +1 -0
- package/dist/dsl/config/parse-preset.js +99 -0
- package/dist/dsl/config/parse-preset.js.map +1 -0
- package/dist/dsl/config/parse-tiers.d.ts +7 -0
- package/dist/dsl/config/parse-tiers.d.ts.map +1 -0
- package/dist/dsl/config/parse-tiers.js +31 -0
- package/dist/dsl/config/parse-tiers.js.map +1 -0
- package/dist/dsl/config/parse-timeouts.d.ts +16 -0
- package/dist/dsl/config/parse-timeouts.d.ts.map +1 -0
- package/dist/dsl/config/parse-timeouts.js +75 -0
- package/dist/dsl/config/parse-timeouts.js.map +1 -0
- package/dist/dsl/config/raw-types.d.ts +45 -0
- package/dist/dsl/config/raw-types.d.ts.map +1 -0
- package/dist/dsl/config/raw-types.js +5 -0
- package/dist/dsl/config/raw-types.js.map +1 -0
- package/dist/dsl/config/unknown-keys.d.ts +7 -0
- package/dist/dsl/config/unknown-keys.d.ts.map +1 -0
- package/dist/dsl/config/unknown-keys.js +119 -0
- package/dist/dsl/config/unknown-keys.js.map +1 -0
- package/dist/dsl/config/validation.d.ts +21 -0
- package/dist/dsl/config/validation.d.ts.map +1 -0
- package/dist/dsl/config/validation.js +45 -0
- package/dist/dsl/config/validation.js.map +1 -0
- package/dist/dsl/constants/index.d.ts +3 -0
- package/dist/dsl/constants/index.d.ts.map +1 -0
- package/dist/dsl/constants/index.js +3 -0
- package/dist/dsl/constants/index.js.map +1 -0
- package/dist/dsl/engine/exchange-stop.d.ts +16 -0
- package/dist/dsl/engine/exchange-stop.d.ts.map +1 -0
- package/dist/dsl/engine/exchange-stop.js +20 -0
- package/dist/dsl/engine/exchange-stop.js.map +1 -0
- package/dist/dsl/engine/floors.d.ts +32 -0
- package/dist/dsl/engine/floors.d.ts.map +1 -0
- package/dist/dsl/engine/floors.js +115 -0
- package/dist/dsl/engine/floors.js.map +1 -0
- package/dist/dsl/engine/index.d.ts +7 -0
- package/dist/dsl/engine/index.d.ts.map +1 -0
- package/dist/dsl/engine/index.js +7 -0
- package/dist/dsl/engine/index.js.map +1 -0
- package/dist/dsl/engine/round.d.ts +5 -0
- package/dist/dsl/engine/round.d.ts.map +1 -0
- package/dist/dsl/engine/round.js +9 -0
- package/dist/dsl/engine/round.js.map +1 -0
- package/dist/dsl/engine/state-updates.d.ts +8 -0
- package/dist/dsl/engine/state-updates.d.ts.map +1 -0
- package/dist/dsl/engine/state-updates.js +60 -0
- package/dist/dsl/engine/state-updates.js.map +1 -0
- package/dist/dsl/engine/tick.d.ts +6 -0
- package/dist/dsl/engine/tick.d.ts.map +1 -0
- package/dist/dsl/engine/tick.js +174 -0
- package/dist/dsl/engine/tick.js.map +1 -0
- package/dist/dsl/events/bus-types.d.ts +7 -0
- package/dist/dsl/events/bus-types.d.ts.map +1 -0
- package/dist/dsl/events/bus-types.js +6 -0
- package/dist/dsl/events/bus-types.js.map +1 -0
- package/dist/dsl/events/guards.d.ts +17 -0
- package/dist/dsl/events/guards.d.ts.map +1 -0
- package/dist/dsl/events/guards.js +116 -0
- package/dist/dsl/events/guards.js.map +1 -0
- package/dist/dsl/events/handlers.d.ts +19 -0
- package/dist/dsl/events/handlers.d.ts.map +1 -0
- package/dist/dsl/events/handlers.js +387 -0
- package/dist/dsl/events/handlers.js.map +1 -0
- package/dist/dsl/events/index.d.ts +4 -0
- package/dist/dsl/events/index.d.ts.map +1 -0
- package/dist/dsl/events/index.js +4 -0
- package/dist/dsl/events/index.js.map +1 -0
- package/dist/dsl/events/initial-state.d.ts +7 -0
- package/dist/dsl/events/initial-state.d.ts.map +1 -0
- package/dist/dsl/events/initial-state.js +96 -0
- package/dist/dsl/events/initial-state.js.map +1 -0
- package/dist/dsl/events/normalize-position-opened.d.ts +10 -0
- package/dist/dsl/events/normalize-position-opened.d.ts.map +1 -0
- package/dist/dsl/events/normalize-position-opened.js +13 -0
- package/dist/dsl/events/normalize-position-opened.js.map +1 -0
- package/dist/dsl/index.d.ts +13 -0
- package/dist/dsl/index.d.ts.map +1 -0
- package/dist/dsl/index.js +37 -0
- package/dist/dsl/index.js.map +1 -0
- package/dist/dsl/monitor/create-monitor.d.ts +24 -0
- package/dist/dsl/monitor/create-monitor.d.ts.map +1 -0
- package/dist/dsl/monitor/create-monitor.js +162 -0
- package/dist/dsl/monitor/create-monitor.js.map +1 -0
- package/dist/dsl/monitor/effective-dex.d.ts +7 -0
- package/dist/dsl/monitor/effective-dex.d.ts.map +1 -0
- package/dist/dsl/monitor/effective-dex.js +11 -0
- package/dist/dsl/monitor/effective-dex.js.map +1 -0
- package/dist/dsl/monitor/exchange-sync.d.ts +16 -0
- package/dist/dsl/monitor/exchange-sync.d.ts.map +1 -0
- package/dist/dsl/monitor/exchange-sync.js +37 -0
- package/dist/dsl/monitor/exchange-sync.js.map +1 -0
- package/dist/dsl/monitor/index.d.ts +6 -0
- package/dist/dsl/monitor/index.d.ts.map +1 -0
- package/dist/dsl/monitor/index.js +5 -0
- package/dist/dsl/monitor/index.js.map +1 -0
- package/dist/dsl/monitor/market-price.d.ts +5 -0
- package/dist/dsl/monitor/market-price.d.ts.map +1 -0
- package/dist/dsl/monitor/market-price.js +24 -0
- package/dist/dsl/monitor/market-price.js.map +1 -0
- package/dist/dsl/monitor/process-one-position.d.ts +19 -0
- package/dist/dsl/monitor/process-one-position.d.ts.map +1 -0
- package/dist/dsl/monitor/process-one-position.js +438 -0
- package/dist/dsl/monitor/process-one-position.js.map +1 -0
- package/dist/dsl/notifications/formatter.d.ts +18 -0
- package/dist/dsl/notifications/formatter.d.ts.map +1 -0
- package/dist/dsl/notifications/formatter.js +69 -0
- package/dist/dsl/notifications/formatter.js.map +1 -0
- package/dist/dsl/notifications/index.d.ts +19 -0
- package/dist/dsl/notifications/index.d.ts.map +1 -0
- package/dist/dsl/notifications/index.js +90 -0
- package/dist/dsl/notifications/index.js.map +1 -0
- package/dist/dsl/plugin/index.d.ts +66 -0
- package/dist/dsl/plugin/index.d.ts.map +1 -0
- package/dist/dsl/plugin/index.js +398 -0
- package/dist/dsl/plugin/index.js.map +1 -0
- package/dist/dsl/plugin/options.d.ts +40 -0
- package/dist/dsl/plugin/options.d.ts.map +1 -0
- package/dist/dsl/plugin/options.js +5 -0
- package/dist/dsl/plugin/options.js.map +1 -0
- package/dist/dsl/types/index.d.ts +3 -0
- package/dist/dsl/types/index.d.ts.map +1 -0
- package/dist/dsl/types/index.js +3 -0
- package/dist/dsl/types/index.js.map +1 -0
- package/dist/health/index.d.ts +29 -0
- package/dist/health/index.d.ts.map +1 -0
- package/dist/health/index.js +191 -0
- package/dist/health/index.js.map +1 -0
- package/dist/health/types.d.ts +114 -0
- package/dist/health/types.d.ts.map +1 -0
- package/dist/health/types.js +2 -0
- package/dist/health/types.js.map +1 -0
- package/dist/index.d.ts +102 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +772 -0
- package/dist/index.js.map +1 -0
- package/dist/leverage/max-leverage-cache.d.ts +10 -0
- package/dist/leverage/max-leverage-cache.d.ts.map +1 -0
- package/dist/leverage/max-leverage-cache.js +51 -0
- package/dist/leverage/max-leverage-cache.js.map +1 -0
- package/dist/leverage/resolve-leverage.d.ts +9 -0
- package/dist/leverage/resolve-leverage.d.ts.map +1 -0
- package/dist/leverage/resolve-leverage.js +15 -0
- package/dist/leverage/resolve-leverage.js.map +1 -0
- package/dist/risk/index.d.ts +9 -0
- package/dist/risk/index.d.ts.map +1 -0
- package/dist/risk/index.js +9 -0
- package/dist/risk/index.js.map +1 -0
- package/dist/runtime/action-registry.d.ts +12 -0
- package/dist/runtime/action-registry.d.ts.map +1 -0
- package/dist/runtime/action-registry.js +22 -0
- package/dist/runtime/action-registry.js.map +1 -0
- package/dist/runtime/auto-update/command-runner.d.ts +20 -0
- package/dist/runtime/auto-update/command-runner.d.ts.map +1 -0
- package/dist/runtime/auto-update/command-runner.js +54 -0
- package/dist/runtime/auto-update/command-runner.js.map +1 -0
- package/dist/runtime/auto-update/coordinator.d.ts +90 -0
- package/dist/runtime/auto-update/coordinator.d.ts.map +1 -0
- package/dist/runtime/auto-update/coordinator.js +336 -0
- package/dist/runtime/auto-update/coordinator.js.map +1 -0
- package/dist/runtime/auto-update/gateway-restart.d.ts +49 -0
- package/dist/runtime/auto-update/gateway-restart.d.ts.map +1 -0
- package/dist/runtime/auto-update/gateway-restart.js +105 -0
- package/dist/runtime/auto-update/gateway-restart.js.map +1 -0
- package/dist/runtime/auto-update/policy.d.ts +24 -0
- package/dist/runtime/auto-update/policy.d.ts.map +1 -0
- package/dist/runtime/auto-update/policy.js +42 -0
- package/dist/runtime/auto-update/policy.js.map +1 -0
- package/dist/runtime/auto-update/preflight.d.ts +16 -0
- package/dist/runtime/auto-update/preflight.d.ts.map +1 -0
- package/dist/runtime/auto-update/preflight.js +20 -0
- package/dist/runtime/auto-update/preflight.js.map +1 -0
- package/dist/runtime/auto-update/state-store.d.ts +29 -0
- package/dist/runtime/auto-update/state-store.d.ts.map +1 -0
- package/dist/runtime/auto-update/state-store.js +51 -0
- package/dist/runtime/auto-update/state-store.js.map +1 -0
- package/dist/runtime/auto-update/types.d.ts +105 -0
- package/dist/runtime/auto-update/types.d.ts.map +1 -0
- package/dist/runtime/auto-update/types.js +56 -0
- package/dist/runtime/auto-update/types.js.map +1 -0
- package/dist/runtime/auto-update/version-source.d.ts +23 -0
- package/dist/runtime/auto-update/version-source.d.ts.map +1 -0
- package/dist/runtime/auto-update/version-source.js +25 -0
- package/dist/runtime/auto-update/version-source.js.map +1 -0
- package/dist/runtime/build-action-scan-payload.d.ts +20 -0
- package/dist/runtime/build-action-scan-payload.d.ts.map +1 -0
- package/dist/runtime/build-action-scan-payload.js +36 -0
- package/dist/runtime/build-action-scan-payload.js.map +1 -0
- package/dist/runtime/bus.d.ts +6 -0
- package/dist/runtime/bus.d.ts.map +1 -0
- package/dist/runtime/bus.js +22 -0
- package/dist/runtime/bus.js.map +1 -0
- package/dist/runtime/create-action-context.d.ts +34 -0
- package/dist/runtime/create-action-context.d.ts.map +1 -0
- package/dist/runtime/create-action-context.js +22 -0
- package/dist/runtime/create-action-context.js.map +1 -0
- package/dist/runtime/create-actions.d.ts +30 -0
- package/dist/runtime/create-actions.d.ts.map +1 -0
- package/dist/runtime/create-actions.js +70 -0
- package/dist/runtime/create-actions.js.map +1 -0
- package/dist/runtime/create-runtime-context.d.ts +35 -0
- package/dist/runtime/create-runtime-context.d.ts.map +1 -0
- package/dist/runtime/create-runtime-context.js +35 -0
- package/dist/runtime/create-runtime-context.js.map +1 -0
- package/dist/runtime/create-scanner-module.d.ts +14 -0
- package/dist/runtime/create-scanner-module.d.ts.map +1 -0
- package/dist/runtime/create-scanner-module.js +31 -0
- package/dist/runtime/create-scanner-module.js.map +1 -0
- package/dist/runtime/create-scanner-providers-for-run.d.ts +20 -0
- package/dist/runtime/create-scanner-providers-for-run.d.ts.map +1 -0
- package/dist/runtime/create-scanner-providers-for-run.js +34 -0
- package/dist/runtime/create-scanner-providers-for-run.js.map +1 -0
- package/dist/runtime/default-state-dir.d.ts +10 -0
- package/dist/runtime/default-state-dir.d.ts.map +1 -0
- package/dist/runtime/default-state-dir.js +22 -0
- package/dist/runtime/default-state-dir.js.map +1 -0
- package/dist/runtime/env-resolve.d.ts +17 -0
- package/dist/runtime/env-resolve.d.ts.map +1 -0
- package/dist/runtime/env-resolve.js +45 -0
- package/dist/runtime/env-resolve.js.map +1 -0
- package/dist/runtime/hook-system.d.ts +7 -0
- package/dist/runtime/hook-system.d.ts.map +1 -0
- package/dist/runtime/hook-system.js +16 -0
- package/dist/runtime/hook-system.js.map +1 -0
- package/dist/runtime/index.d.ts +37 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +26 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/load-runtime-config.d.ts +23 -0
- package/dist/runtime/load-runtime-config.d.ts.map +1 -0
- package/dist/runtime/load-runtime-config.js +176 -0
- package/dist/runtime/load-runtime-config.js.map +1 -0
- package/dist/runtime/map-exit-config.d.ts +11 -0
- package/dist/runtime/map-exit-config.d.ts.map +1 -0
- package/dist/runtime/map-exit-config.js +86 -0
- package/dist/runtime/map-exit-config.js.map +1 -0
- package/dist/runtime/map-strategies-registration.d.ts +14 -0
- package/dist/runtime/map-strategies-registration.d.ts.map +1 -0
- package/dist/runtime/map-strategies-registration.js +44 -0
- package/dist/runtime/map-strategies-registration.js.map +1 -0
- package/dist/runtime/map-strategies.d.ts +14 -0
- package/dist/runtime/map-strategies.d.ts.map +1 -0
- package/dist/runtime/map-strategies.js +64 -0
- package/dist/runtime/map-strategies.js.map +1 -0
- package/dist/runtime/notifications.d.ts +19 -0
- package/dist/runtime/notifications.d.ts.map +1 -0
- package/dist/runtime/notifications.js +88 -0
- package/dist/runtime/notifications.js.map +1 -0
- package/dist/runtime/parse-interval.d.ts +11 -0
- package/dist/runtime/parse-interval.d.ts.map +1 -0
- package/dist/runtime/parse-interval.js +35 -0
- package/dist/runtime/parse-interval.js.map +1 -0
- package/dist/runtime/recipe-version.d.ts +3 -0
- package/dist/runtime/recipe-version.d.ts.map +1 -0
- package/dist/runtime/recipe-version.js +3 -0
- package/dist/runtime/recipe-version.js.map +1 -0
- package/dist/runtime/reconcile-state.d.ts +37 -0
- package/dist/runtime/reconcile-state.d.ts.map +1 -0
- package/dist/runtime/reconcile-state.js +179 -0
- package/dist/runtime/reconcile-state.js.map +1 -0
- package/dist/runtime/risk-guard.d.ts +6 -0
- package/dist/runtime/risk-guard.d.ts.map +1 -0
- package/dist/runtime/risk-guard.js +14 -0
- package/dist/runtime/risk-guard.js.map +1 -0
- package/dist/runtime/run.d.ts +30 -0
- package/dist/runtime/run.d.ts.map +1 -0
- package/dist/runtime/run.js +46 -0
- package/dist/runtime/run.js.map +1 -0
- package/dist/runtime/runtime-config.d.ts +6 -0
- package/dist/runtime/runtime-config.d.ts.map +1 -0
- package/dist/runtime/runtime-config.js +5 -0
- package/dist/runtime/runtime-config.js.map +1 -0
- package/dist/runtime/runtime-schema.d.ts +1859 -0
- package/dist/runtime/runtime-schema.d.ts.map +1 -0
- package/dist/runtime/runtime-schema.js +110 -0
- package/dist/runtime/runtime-schema.js.map +1 -0
- package/dist/runtime/runtime-version.d.ts +19 -0
- package/dist/runtime/runtime-version.d.ts.map +1 -0
- package/dist/runtime/runtime-version.js +29 -0
- package/dist/runtime/runtime-version.js.map +1 -0
- package/dist/runtime/runtime.d.ts +53 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +335 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/runtime/scanner-composition.d.ts +23 -0
- package/dist/runtime/scanner-composition.d.ts.map +1 -0
- package/dist/runtime/scanner-composition.js +168 -0
- package/dist/runtime/scanner-composition.js.map +1 -0
- package/dist/runtime/scanner-registry.d.ts +28 -0
- package/dist/runtime/scanner-registry.d.ts.map +1 -0
- package/dist/runtime/scanner-registry.js +114 -0
- package/dist/runtime/scanner-registry.js.map +1 -0
- package/dist/runtime/state-layout.d.ts +50 -0
- package/dist/runtime/state-layout.d.ts.map +1 -0
- package/dist/runtime/state-layout.js +89 -0
- package/dist/runtime/state-layout.js.map +1 -0
- package/dist/runtime/strategy-registry.d.ts +79 -0
- package/dist/runtime/strategy-registry.d.ts.map +1 -0
- package/dist/runtime/strategy-registry.js +265 -0
- package/dist/runtime/strategy-registry.js.map +1 -0
- package/dist/runtime/validate-dsl-position-tracking.d.ts +3 -0
- package/dist/runtime/validate-dsl-position-tracking.d.ts.map +1 -0
- package/dist/runtime/validate-dsl-position-tracking.js +27 -0
- package/dist/runtime/validate-dsl-position-tracking.js.map +1 -0
- package/dist/scanners/__tests__/default-engine-test-composition.d.ts +9 -0
- package/dist/scanners/__tests__/default-engine-test-composition.d.ts.map +1 -0
- package/dist/scanners/__tests__/default-engine-test-composition.js +84 -0
- package/dist/scanners/__tests__/default-engine-test-composition.js.map +1 -0
- package/dist/scanners/__tests__/fixtures/index.d.ts +3 -0
- package/dist/scanners/__tests__/fixtures/index.d.ts.map +1 -0
- package/dist/scanners/__tests__/fixtures/index.js +3 -0
- package/dist/scanners/__tests__/fixtures/index.js.map +1 -0
- package/dist/scanners/__tests__/fixtures/position-tracker-scenarios.d.ts +21 -0
- package/dist/scanners/__tests__/fixtures/position-tracker-scenarios.d.ts.map +1 -0
- package/dist/scanners/__tests__/fixtures/position-tracker-scenarios.js +199 -0
- package/dist/scanners/__tests__/fixtures/position-tracker-scenarios.js.map +1 -0
- package/dist/scanners/__tests__/fixtures/scan-results.d.ts +23 -0
- package/dist/scanners/__tests__/fixtures/scan-results.d.ts.map +1 -0
- package/dist/scanners/__tests__/fixtures/scan-results.js +128 -0
- package/dist/scanners/__tests__/fixtures/scan-results.js.map +1 -0
- package/dist/scanners/__tests__/fixtures/signals.d.ts +18 -0
- package/dist/scanners/__tests__/fixtures/signals.d.ts.map +1 -0
- package/dist/scanners/__tests__/fixtures/signals.js +84 -0
- package/dist/scanners/__tests__/fixtures/signals.js.map +1 -0
- package/dist/scanners/__tests__/test-helpers.d.ts +4 -0
- package/dist/scanners/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/scanners/__tests__/test-helpers.js +23 -0
- package/dist/scanners/__tests__/test-helpers.js.map +1 -0
- package/dist/scanners/artifacts.d.ts +131 -0
- package/dist/scanners/artifacts.d.ts.map +1 -0
- package/dist/scanners/artifacts.js +72 -0
- package/dist/scanners/artifacts.js.map +1 -0
- package/dist/scanners/context-source-mapping.d.ts +4 -0
- package/dist/scanners/context-source-mapping.d.ts.map +1 -0
- package/dist/scanners/context-source-mapping.js +10 -0
- package/dist/scanners/context-source-mapping.js.map +1 -0
- package/dist/scanners/create-scanner.d.ts +13 -0
- package/dist/scanners/create-scanner.d.ts.map +1 -0
- package/dist/scanners/create-scanner.js +11 -0
- package/dist/scanners/create-scanner.js.map +1 -0
- package/dist/scanners/engine/config-validator.d.ts +7 -0
- package/dist/scanners/engine/config-validator.d.ts.map +1 -0
- package/dist/scanners/engine/config-validator.js +16 -0
- package/dist/scanners/engine/config-validator.js.map +1 -0
- package/dist/scanners/engine/data-providers.d.ts +48 -0
- package/dist/scanners/engine/data-providers.d.ts.map +1 -0
- package/dist/scanners/engine/data-providers.js +28 -0
- package/dist/scanners/engine/data-providers.js.map +1 -0
- package/dist/scanners/engine/engine.d.ts +92 -0
- package/dist/scanners/engine/engine.d.ts.map +1 -0
- package/dist/scanners/engine/engine.js +478 -0
- package/dist/scanners/engine/engine.js.map +1 -0
- package/dist/scanners/engine/index.d.ts +9 -0
- package/dist/scanners/engine/index.d.ts.map +1 -0
- package/dist/scanners/engine/index.js +7 -0
- package/dist/scanners/engine/index.js.map +1 -0
- package/dist/scanners/engine/input-resolver.d.ts +33 -0
- package/dist/scanners/engine/input-resolver.d.ts.map +1 -0
- package/dist/scanners/engine/input-resolver.js +216 -0
- package/dist/scanners/engine/input-resolver.js.map +1 -0
- package/dist/scanners/engine/lifecycle.d.ts +21 -0
- package/dist/scanners/engine/lifecycle.d.ts.map +1 -0
- package/dist/scanners/engine/lifecycle.js +2 -0
- package/dist/scanners/engine/lifecycle.js.map +1 -0
- package/dist/scanners/engine/result-builder.d.ts +30 -0
- package/dist/scanners/engine/result-builder.d.ts.map +1 -0
- package/dist/scanners/engine/result-builder.js +129 -0
- package/dist/scanners/engine/result-builder.js.map +1 -0
- package/dist/scanners/engine/strategy-registry.d.ts +48 -0
- package/dist/scanners/engine/strategy-registry.d.ts.map +1 -0
- package/dist/scanners/engine/strategy-registry.js +103 -0
- package/dist/scanners/engine/strategy-registry.js.map +1 -0
- package/dist/scanners/events.d.ts +41 -0
- package/dist/scanners/events.d.ts.map +1 -0
- package/dist/scanners/events.js +33 -0
- package/dist/scanners/events.js.map +1 -0
- package/dist/scanners/implementations/emerging-movers.d.ts +215 -0
- package/dist/scanners/implementations/emerging-movers.d.ts.map +1 -0
- package/dist/scanners/implementations/emerging-movers.js +713 -0
- package/dist/scanners/implementations/emerging-movers.js.map +1 -0
- package/dist/scanners/implementations/index.d.ts +9 -0
- package/dist/scanners/implementations/index.d.ts.map +1 -0
- package/dist/scanners/implementations/index.js +9 -0
- package/dist/scanners/implementations/index.js.map +1 -0
- package/dist/scanners/implementations/indicators.d.ts +40 -0
- package/dist/scanners/implementations/indicators.d.ts.map +1 -0
- package/dist/scanners/implementations/indicators.js +114 -0
- package/dist/scanners/implementations/indicators.js.map +1 -0
- package/dist/scanners/implementations/liquidation-watchdog.d.ts +66 -0
- package/dist/scanners/implementations/liquidation-watchdog.d.ts.map +1 -0
- package/dist/scanners/implementations/liquidation-watchdog.js +293 -0
- package/dist/scanners/implementations/liquidation-watchdog.js.map +1 -0
- package/dist/scanners/implementations/market-regime.d.ts +52 -0
- package/dist/scanners/implementations/market-regime.d.ts.map +1 -0
- package/dist/scanners/implementations/market-regime.js +205 -0
- package/dist/scanners/implementations/market-regime.js.map +1 -0
- package/dist/scanners/implementations/momentum.d.ts +21 -0
- package/dist/scanners/implementations/momentum.d.ts.map +1 -0
- package/dist/scanners/implementations/momentum.js +132 -0
- package/dist/scanners/implementations/momentum.js.map +1 -0
- package/dist/scanners/implementations/oi-tracker.d.ts +13 -0
- package/dist/scanners/implementations/oi-tracker.d.ts.map +1 -0
- package/dist/scanners/implementations/oi-tracker.js +71 -0
- package/dist/scanners/implementations/oi-tracker.js.map +1 -0
- package/dist/scanners/implementations/opportunity.d.ts +104 -0
- package/dist/scanners/implementations/opportunity.d.ts.map +1 -0
- package/dist/scanners/implementations/opportunity.js +445 -0
- package/dist/scanners/implementations/opportunity.js.map +1 -0
- package/dist/scanners/implementations/position-tracker.d.ts +120 -0
- package/dist/scanners/implementations/position-tracker.d.ts.map +1 -0
- package/dist/scanners/implementations/position-tracker.js +360 -0
- package/dist/scanners/implementations/position-tracker.js.map +1 -0
- package/dist/scanners/implementations/prescreener.d.ts +20 -0
- package/dist/scanners/implementations/prescreener.d.ts.map +1 -0
- package/dist/scanners/implementations/prescreener.js +101 -0
- package/dist/scanners/implementations/prescreener.js.map +1 -0
- package/dist/scanners/implementations/sm-flip.d.ts +43 -0
- package/dist/scanners/implementations/sm-flip.d.ts.map +1 -0
- package/dist/scanners/implementations/sm-flip.js +205 -0
- package/dist/scanners/implementations/sm-flip.js.map +1 -0
- package/dist/scanners/index.d.ts +26 -0
- package/dist/scanners/index.d.ts.map +1 -0
- package/dist/scanners/index.js +19 -0
- package/dist/scanners/index.js.map +1 -0
- package/dist/scanners/input-descriptors.d.ts +61 -0
- package/dist/scanners/input-descriptors.d.ts.map +1 -0
- package/dist/scanners/input-descriptors.js +43 -0
- package/dist/scanners/input-descriptors.js.map +1 -0
- package/dist/scanners/prepare-scanner-inputs.d.ts +12 -0
- package/dist/scanners/prepare-scanner-inputs.d.ts.map +1 -0
- package/dist/scanners/prepare-scanner-inputs.js +21 -0
- package/dist/scanners/prepare-scanner-inputs.js.map +1 -0
- package/dist/scanners/protocol/context.d.ts +95 -0
- package/dist/scanners/protocol/context.d.ts.map +1 -0
- package/dist/scanners/protocol/context.js +2 -0
- package/dist/scanners/protocol/context.js.map +1 -0
- package/dist/scanners/protocol/hooks.d.ts +18 -0
- package/dist/scanners/protocol/hooks.d.ts.map +1 -0
- package/dist/scanners/protocol/hooks.js +12 -0
- package/dist/scanners/protocol/hooks.js.map +1 -0
- package/dist/scanners/protocol/index.d.ts +5 -0
- package/dist/scanners/protocol/index.d.ts.map +1 -0
- package/dist/scanners/protocol/index.js +2 -0
- package/dist/scanners/protocol/index.js.map +1 -0
- package/dist/scanners/protocol/scanner.d.ts +47 -0
- package/dist/scanners/protocol/scanner.d.ts.map +1 -0
- package/dist/scanners/protocol/scanner.js +2 -0
- package/dist/scanners/protocol/scanner.js.map +1 -0
- package/dist/scanners/providers/adapter.d.ts +23 -0
- package/dist/scanners/providers/adapter.d.ts.map +1 -0
- package/dist/scanners/providers/adapter.js +227 -0
- package/dist/scanners/providers/adapter.js.map +1 -0
- package/dist/scanners/providers/cache.d.ts +20 -0
- package/dist/scanners/providers/cache.d.ts.map +1 -0
- package/dist/scanners/providers/cache.js +61 -0
- package/dist/scanners/providers/cache.js.map +1 -0
- package/dist/scanners/providers/client.d.ts +53 -0
- package/dist/scanners/providers/client.d.ts.map +1 -0
- package/dist/scanners/providers/client.js +174 -0
- package/dist/scanners/providers/client.js.map +1 -0
- package/dist/scanners/providers/factory.d.ts +43 -0
- package/dist/scanners/providers/factory.d.ts.map +1 -0
- package/dist/scanners/providers/factory.js +297 -0
- package/dist/scanners/providers/factory.js.map +1 -0
- package/dist/scanners/providers/types.d.ts +61 -0
- package/dist/scanners/providers/types.d.ts.map +1 -0
- package/dist/scanners/providers/types.js +6 -0
- package/dist/scanners/providers/types.js.map +1 -0
- package/dist/scanners/runtime-module.d.ts +79 -0
- package/dist/scanners/runtime-module.d.ts.map +1 -0
- package/dist/scanners/runtime-module.js +362 -0
- package/dist/scanners/runtime-module.js.map +1 -0
- package/dist/scanners/scanner-definition.d.ts +81 -0
- package/dist/scanners/scanner-definition.d.ts.map +1 -0
- package/dist/scanners/scanner-definition.js +19 -0
- package/dist/scanners/scanner-definition.js.map +1 -0
- package/dist/scanners/schema-utils.d.ts +6 -0
- package/dist/scanners/schema-utils.d.ts.map +1 -0
- package/dist/scanners/schema-utils.js +14 -0
- package/dist/scanners/schema-utils.js.map +1 -0
- package/dist/scanners/score-utils.d.ts +19 -0
- package/dist/scanners/score-utils.d.ts.map +1 -0
- package/dist/scanners/score-utils.js +47 -0
- package/dist/scanners/score-utils.js.map +1 -0
- package/dist/scanners/store/fs-utils.d.ts +12 -0
- package/dist/scanners/store/fs-utils.d.ts.map +1 -0
- package/dist/scanners/store/fs-utils.js +47 -0
- package/dist/scanners/store/fs-utils.js.map +1 -0
- package/dist/scanners/store/index.d.ts +5 -0
- package/dist/scanners/store/index.d.ts.map +1 -0
- package/dist/scanners/store/index.js +5 -0
- package/dist/scanners/store/index.js.map +1 -0
- package/dist/scanners/store/runtime-store.d.ts +50 -0
- package/dist/scanners/store/runtime-store.d.ts.map +1 -0
- package/dist/scanners/store/runtime-store.js +91 -0
- package/dist/scanners/store/runtime-store.js.map +1 -0
- package/dist/scanners/store/shared-artifact-store.d.ts +35 -0
- package/dist/scanners/store/shared-artifact-store.d.ts.map +1 -0
- package/dist/scanners/store/shared-artifact-store.js +89 -0
- package/dist/scanners/store/shared-artifact-store.js.map +1 -0
- package/dist/scanners/store/signal-store.d.ts +36 -0
- package/dist/scanners/store/signal-store.d.ts.map +1 -0
- package/dist/scanners/store/signal-store.js +135 -0
- package/dist/scanners/store/signal-store.js.map +1 -0
- package/dist/scanners/types.d.ts +115 -0
- package/dist/scanners/types.d.ts.map +1 -0
- package/dist/scanners/types.js +3 -0
- package/dist/scanners/types.js.map +1 -0
- package/dist/scripts/run-dsl-standalone-live.d.ts +48 -0
- package/dist/scripts/run-dsl-standalone-live.d.ts.map +1 -0
- package/dist/scripts/run-dsl-standalone-live.js +531 -0
- package/dist/scripts/run-dsl-standalone-live.js.map +1 -0
- package/dist/scripts/run-dsl-standalone-mock.d.ts +13 -0
- package/dist/scripts/run-dsl-standalone-mock.d.ts.map +1 -0
- package/dist/scripts/run-dsl-standalone-mock.js +264 -0
- package/dist/scripts/run-dsl-standalone-mock.js.map +1 -0
- package/dist/senpi/client.d.ts +99 -0
- package/dist/senpi/client.d.ts.map +1 -0
- package/dist/senpi/client.js +779 -0
- package/dist/senpi/client.js.map +1 -0
- package/dist/senpi/constants.d.ts +7 -0
- package/dist/senpi/constants.d.ts.map +1 -0
- package/dist/senpi/constants.js +7 -0
- package/dist/senpi/constants.js.map +1 -0
- package/dist/senpi/index.d.ts +3 -0
- package/dist/senpi/index.d.ts.map +1 -0
- package/dist/senpi/index.js +2 -0
- package/dist/senpi/index.js.map +1 -0
- package/dist/senpi/types.d.ts +162 -0
- package/dist/senpi/types.d.ts.map +1 -0
- package/dist/senpi/types.js +3 -0
- package/dist/senpi/types.js.map +1 -0
- package/dist/state/index.d.ts +3 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +3 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/paths.d.ts +18 -0
- package/dist/state/paths.d.ts.map +1 -0
- package/dist/state/paths.js +51 -0
- package/dist/state/paths.js.map +1 -0
- package/dist/state/state-manager.d.ts +83 -0
- package/dist/state/state-manager.d.ts.map +1 -0
- package/dist/state/state-manager.js +380 -0
- package/dist/state/state-manager.js.map +1 -0
- package/dist/strategy/index.d.ts +2 -0
- package/dist/strategy/index.d.ts.map +1 -0
- package/dist/strategy/index.js +2 -0
- package/dist/strategy/index.js.map +1 -0
- package/dist/strategy/strategy-state.d.ts +51 -0
- package/dist/strategy/strategy-state.d.ts.map +1 -0
- package/dist/strategy/strategy-state.js +218 -0
- package/dist/strategy/strategy-state.js.map +1 -0
- package/dist/types/action.d.ts +15 -0
- package/dist/types/action.d.ts.map +1 -0
- package/dist/types/action.js +2 -0
- package/dist/types/action.js.map +1 -0
- package/dist/types/dsl/index.d.ts +286 -0
- package/dist/types/dsl/index.d.ts.map +1 -0
- package/dist/types/dsl/index.js +5 -0
- package/dist/types/dsl/index.js.map +1 -0
- package/dist/types/event-bus.d.ts +13 -0
- package/dist/types/event-bus.d.ts.map +1 -0
- package/dist/types/event-bus.js +6 -0
- package/dist/types/event-bus.js.map +1 -0
- package/dist/types/hooks.d.ts +30 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/hooks.js +18 -0
- package/dist/types/hooks.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/notification.d.ts +4 -0
- package/dist/types/notification.d.ts.map +1 -0
- package/dist/types/notification.js +3 -0
- package/dist/types/notification.js.map +1 -0
- package/dist/types/runtime.d.ts +18 -0
- package/dist/types/runtime.d.ts.map +1 -0
- package/dist/types/runtime.js +2 -0
- package/dist/types/runtime.js.map +1 -0
- package/dist/types/scanner.d.ts +59 -0
- package/dist/types/scanner.d.ts.map +1 -0
- package/dist/types/scanner.js +13 -0
- package/dist/types/scanner.js.map +1 -0
- package/dist/types/strategy.d.ts +106 -0
- package/dist/types/strategy.d.ts.map +1 -0
- package/dist/types/strategy.js +2 -0
- package/dist/types/strategy.js.map +1 -0
- package/dist/utils/clearing-house-staleness.d.ts +47 -0
- package/dist/utils/clearing-house-staleness.d.ts.map +1 -0
- package/dist/utils/clearing-house-staleness.js +73 -0
- package/dist/utils/clearing-house-staleness.js.map +1 -0
- package/dist/utils/logger/dsl.d.ts +8 -0
- package/dist/utils/logger/dsl.d.ts.map +1 -0
- package/dist/utils/logger/dsl.js +7 -0
- package/dist/utils/logger/dsl.js.map +1 -0
- package/dist/utils/logger.d.ts +23 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +97 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/perp-coin.d.ts +19 -0
- package/dist/utils/perp-coin.d.ts.map +1 -0
- package/dist/utils/perp-coin.js +40 -0
- package/dist/utils/perp-coin.js.map +1 -0
- package/dist/utils/response.d.ts +14 -0
- package/dist/utils/response.d.ts.map +1 -0
- package/dist/utils/response.js +44 -0
- package/dist/utils/response.js.map +1 -0
- package/dist/utils/retry.d.ts +19 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +32 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/version.d.ts +6 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +21 -0
- package/dist/version.js.map +1 -0
- package/examples/.env.example +25 -0
- package/examples/README.md +89 -0
- package/examples/scanners-consumer-quickstart.mjs +134 -0
- package/examples/scanners-emerging-movers-v4.mjs +287 -0
- package/examples/scanners-liquidation-watchdog.mjs +341 -0
- package/examples/scanners-live-mcp.mjs +208 -0
- package/examples/scanners-multi-strategy.mjs +165 -0
- package/examples/scanners-position-tracker-e2e.mjs +225 -0
- package/examples/scanners-scheduled-events.mjs +96 -0
- package/examples/scanners-senpi-provider-client.mjs +182 -0
- package/examples/scanners-single-strategy.mjs +198 -0
- package/examples/strategies/README.md +45 -0
- package/examples/strategies/dsl-showcase.yaml +63 -0
- package/examples/strategies/dsl.yaml +47 -0
- package/examples/strategies/fox-minimal-loosened.yaml +225 -0
- package/examples/strategies/fox-minimal.yaml +220 -0
- package/examples/strategies/minimal.yaml +44 -0
- package/examples/strategies/viper.yaml +59 -0
- package/examples/strategies/wolf.yaml +64 -0
- package/examples/yamls/sample-with-dsl-and-emerging-movers.yaml +115 -0
- package/openclaw.plugin.json +67 -0
- package/package.json +53 -0
|
@@ -0,0 +1,779 @@
|
|
|
1
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
|
+
import { MCP_BASE_URL } from "./constants.js";
|
|
4
|
+
import { isRecord, unwrapEnvelope, asString, asNumber } from "../utils/response.js";
|
|
5
|
+
import { extractMinClearingHouseTime, createClearingHouseStalenessGuard } from "../utils/clearing-house-staleness.js";
|
|
6
|
+
import { normalizeDslCoinDex, reconcileDexFromClearingHouseKey } from "../utils/perp-coin.js";
|
|
7
|
+
import { createLogger } from "../utils/logger.js";
|
|
8
|
+
const logger = createLogger("[senpi][client]");
|
|
9
|
+
/**
|
|
10
|
+
* execution_get_order_status payloads vary: flat `{ filled, status }` vs Hyperliquid-style
|
|
11
|
+
* `{ status: "order", order: { status: "filled", order: {...} } }`. Top-level `status` may be a
|
|
12
|
+
* discriminant ("order"), not the fill state — do not treat it as filled unless it is "filled".
|
|
13
|
+
*/
|
|
14
|
+
function parseExecutionOrderFilled(obj) {
|
|
15
|
+
if (obj.filled === true)
|
|
16
|
+
return true;
|
|
17
|
+
const top = obj.status;
|
|
18
|
+
if (typeof top === "string" && top.toUpperCase() === "FILLED")
|
|
19
|
+
return true;
|
|
20
|
+
const wrap = obj.order;
|
|
21
|
+
if (isRecord(wrap)) {
|
|
22
|
+
if (wrap.filled === true)
|
|
23
|
+
return true;
|
|
24
|
+
const os = wrap.status;
|
|
25
|
+
if (typeof os === "string" && os.toUpperCase() === "FILLED")
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
export class SenpiClient {
|
|
31
|
+
// Injected mode
|
|
32
|
+
injectedTransport;
|
|
33
|
+
// Self-managed mode
|
|
34
|
+
config;
|
|
35
|
+
mcpClient = null;
|
|
36
|
+
clearingHouseStaleness = createClearingHouseStalenessGuard();
|
|
37
|
+
// Exponential backoff defaults for retrying stale clearingHouse responses.
|
|
38
|
+
staleRetryMaxAttempts = 3;
|
|
39
|
+
staleRetryBaseDelayMs = 4_000;
|
|
40
|
+
constructor(transportOrConfig) {
|
|
41
|
+
if (typeof transportOrConfig === 'function') {
|
|
42
|
+
this.injectedTransport = transportOrConfig;
|
|
43
|
+
this.config = null;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.injectedTransport = null;
|
|
47
|
+
this.config = transportOrConfig;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async connect() {
|
|
51
|
+
if (this.injectedTransport)
|
|
52
|
+
return; // no-op in injected mode
|
|
53
|
+
const apiKey = this.config?.apiKey?.trim() ||
|
|
54
|
+
process.env.SENPI_API_KEY?.trim() ||
|
|
55
|
+
'';
|
|
56
|
+
if (!apiKey) {
|
|
57
|
+
throw new Error('SenpiClient requires apiKey or SENPI_API_KEY env var');
|
|
58
|
+
}
|
|
59
|
+
const url = this.config?.mcpUrl
|
|
60
|
+
? new URL(this.config.mcpUrl)
|
|
61
|
+
: process.env.SENPI_MCP_URL
|
|
62
|
+
? new URL(process.env.SENPI_MCP_URL)
|
|
63
|
+
: new URL(MCP_BASE_URL);
|
|
64
|
+
const transport = new StreamableHTTPClientTransport(url, {
|
|
65
|
+
requestInit: {
|
|
66
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
const client = new Client({
|
|
70
|
+
name: this.config?.clientName ?? 'senpi-client',
|
|
71
|
+
version: this.config?.clientVersion ?? '0.0.1',
|
|
72
|
+
});
|
|
73
|
+
await client.connect(transport);
|
|
74
|
+
this.mcpClient = client;
|
|
75
|
+
}
|
|
76
|
+
async disconnect() {
|
|
77
|
+
if (this.injectedTransport)
|
|
78
|
+
return; // no-op in injected mode
|
|
79
|
+
if (this.mcpClient) {
|
|
80
|
+
try {
|
|
81
|
+
this.mcpClient.close();
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// ignore on teardown
|
|
85
|
+
}
|
|
86
|
+
this.mcpClient = null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async callTool(toolName, args) {
|
|
90
|
+
// Injected mode: delegate directly
|
|
91
|
+
if (this.injectedTransport) {
|
|
92
|
+
return this.injectedTransport(toolName, args);
|
|
93
|
+
}
|
|
94
|
+
// Self-managed mode: call via MCP client
|
|
95
|
+
if (!this.mcpClient) {
|
|
96
|
+
throw new Error('SenpiClient not connected — call connect() first');
|
|
97
|
+
}
|
|
98
|
+
const result = await this.mcpClient.callTool({ name: toolName, arguments: args });
|
|
99
|
+
if (result.content && Array.isArray(result.content) && result.content.length > 0) {
|
|
100
|
+
const part = result.content[0];
|
|
101
|
+
if (part && 'text' in part && typeof part.text === 'string') {
|
|
102
|
+
try {
|
|
103
|
+
return JSON.parse(part.text);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return part.text;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Returns an adapter compatible with SenpiToolClient so the same connection
|
|
114
|
+
* can be used for scanner provider MCP tool calls (e.g. leaderboard_get_markets).
|
|
115
|
+
*/
|
|
116
|
+
asToolClient() {
|
|
117
|
+
return {
|
|
118
|
+
callTool: (name, args) => this.callTool(name, args),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async createPosition(request) {
|
|
122
|
+
console.log('[SenpiClient] createPosition request:', JSON.stringify(request, null, 2));
|
|
123
|
+
const raw = await this.callTool('create_position', {
|
|
124
|
+
strategyWalletAddress: request.strategyWalletAddress,
|
|
125
|
+
orders: request.orders,
|
|
126
|
+
...(request.reason != null ? { reason: request.reason } : {}),
|
|
127
|
+
});
|
|
128
|
+
console.log('[SenpiClient] createPosition raw response:', JSON.stringify(raw, null, 2));
|
|
129
|
+
return parseCreatePositionResult(raw);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Fetch market prices. Main DEX is passed as dex: ""; use dex: "xyz" for xyz.
|
|
133
|
+
* If assets is omitted, the MCP returns all asset prices for that dex.
|
|
134
|
+
*/
|
|
135
|
+
async getMarketPrices(params) {
|
|
136
|
+
const raw = await this.callTool("market_get_prices", {
|
|
137
|
+
dex: params.dex || "",
|
|
138
|
+
...(params.assets != null && params.assets.length > 0 ? { assets: params.assets } : {}),
|
|
139
|
+
});
|
|
140
|
+
const unwrapped = unwrapEnvelope(raw) ?? raw;
|
|
141
|
+
if (unwrapped == null || typeof unwrapped !== "object")
|
|
142
|
+
return null;
|
|
143
|
+
const obj = unwrapped;
|
|
144
|
+
const prices = (obj.prices ?? obj);
|
|
145
|
+
const out = {};
|
|
146
|
+
for (const [k, v] of Object.entries(prices)) {
|
|
147
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? Number(v) : NaN;
|
|
148
|
+
if (Number.isFinite(n))
|
|
149
|
+
out[k] = n;
|
|
150
|
+
}
|
|
151
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Set/update SL (and optionally TP) on an open position. Uses MCP edit_position.
|
|
155
|
+
* For XYZ DEX pass dex: "xyz" so coin is sent as "xyz:COIN"; otherwise main DEX uses plain coin.
|
|
156
|
+
*/
|
|
157
|
+
async editPosition(wallet, payload) {
|
|
158
|
+
const coin = payload.dex === "xyz" && payload.coin && !payload.coin.startsWith("xyz:")
|
|
159
|
+
? `xyz:${payload.coin}`
|
|
160
|
+
: payload.coin;
|
|
161
|
+
const stopLoss = payload.stopLoss != null
|
|
162
|
+
? { price: payload.stopLoss.triggerPx }
|
|
163
|
+
: undefined;
|
|
164
|
+
const args = {
|
|
165
|
+
strategyWalletAddress: wallet,
|
|
166
|
+
coin,
|
|
167
|
+
...(stopLoss != null ? { stopLoss } : {}),
|
|
168
|
+
};
|
|
169
|
+
const raw = await this.callTool("edit_position", args);
|
|
170
|
+
logger.info("edit_position raw response", {
|
|
171
|
+
wallet,
|
|
172
|
+
coin,
|
|
173
|
+
rawKeys: isRecord(raw) ? Object.keys(raw) : [],
|
|
174
|
+
rawShape: isRecord(raw) ? JSON.stringify(raw).slice(0, 500) : String(raw),
|
|
175
|
+
});
|
|
176
|
+
const result = (unwrapEnvelope(raw) ?? raw);
|
|
177
|
+
if (result && typeof result === "object" && !Array.isArray(result)) {
|
|
178
|
+
const ro = result;
|
|
179
|
+
const slOrderId = extractSlOrderId(ro, raw);
|
|
180
|
+
logger.info("edit_position parsed", {
|
|
181
|
+
wallet,
|
|
182
|
+
coin,
|
|
183
|
+
slOrderId,
|
|
184
|
+
unwrappedKeys: Object.keys(ro),
|
|
185
|
+
hasStopLossOrderResult: "StopLossOrderResult" in ro || "stopLossOrderResult" in ro,
|
|
186
|
+
});
|
|
187
|
+
if (slOrderId != null && Number.isFinite(slOrderId)) {
|
|
188
|
+
return { ...result, slOrderId };
|
|
189
|
+
}
|
|
190
|
+
const actions = ro.actionsPerformed;
|
|
191
|
+
if (Array.isArray(actions) && (actions.includes("stop_loss_updated") || actions.includes("stop_loss_placed"))) {
|
|
192
|
+
logger.warn("edit_position reported SL update but slOrderId not found in response; state will have slOrderId=null", {
|
|
193
|
+
keys: Object.keys(ro),
|
|
194
|
+
rawKeys: isRecord(raw) ? Object.keys(raw) : [],
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
async getOrderStatus(wallet, orderId) {
|
|
201
|
+
const raw = await this.callTool("execution_get_order_status", { user: wallet, orderId });
|
|
202
|
+
if (raw == null || typeof raw !== "object")
|
|
203
|
+
return null;
|
|
204
|
+
const unwrapped = unwrapEnvelope(raw) ?? raw;
|
|
205
|
+
if (unwrapped == null || typeof unwrapped !== "object" || Array.isArray(unwrapped))
|
|
206
|
+
return null;
|
|
207
|
+
const obj = unwrapped;
|
|
208
|
+
return { filled: parseExecutionOrderFilled(obj) };
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Fetch full clearing house state for a wallet (main + xyz DEXes) from MCP.
|
|
212
|
+
*
|
|
213
|
+
* Retries with exponential backoff when the API returns stale data (timestamp
|
|
214
|
+
* older than previously observed). Non-stale failures (null response, error
|
|
215
|
+
* envelopes) are returned immediately without retrying.
|
|
216
|
+
*/
|
|
217
|
+
async getClearingHouseState(wallet) {
|
|
218
|
+
for (let attempt = 1; attempt <= this.staleRetryMaxAttempts; attempt++) {
|
|
219
|
+
const result = await this.fetchClearingHouseStateOnce(wallet);
|
|
220
|
+
if (result.outcome !== "stale")
|
|
221
|
+
return result.data;
|
|
222
|
+
// Last attempt — don't wait, just return null.
|
|
223
|
+
if (attempt === this.staleRetryMaxAttempts) {
|
|
224
|
+
logger.warn("getClearingHouseState: all retries exhausted, response still stale", {
|
|
225
|
+
wallet,
|
|
226
|
+
attempts: attempt,
|
|
227
|
+
});
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
const delayMs = this.staleRetryBaseDelayMs * Math.pow(2, attempt - 1);
|
|
231
|
+
logger.warn("getClearingHouseState: stale response, retrying", {
|
|
232
|
+
wallet,
|
|
233
|
+
attempt,
|
|
234
|
+
nextRetryMs: delayMs,
|
|
235
|
+
responseTime: result.responseTime,
|
|
236
|
+
lastClearingHouseTime: this.clearingHouseStaleness.getLastTime(wallet),
|
|
237
|
+
});
|
|
238
|
+
await this.delay(delayMs);
|
|
239
|
+
}
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Single fetch + validate attempt. Returns a tagged result so the caller can
|
|
244
|
+
* distinguish stale responses (retryable) from other failures (not retryable).
|
|
245
|
+
*/
|
|
246
|
+
async fetchClearingHouseStateOnce(wallet) {
|
|
247
|
+
const raw = await this.callTool("strategy_get_clearinghouse_state", { strategy_wallet: wallet });
|
|
248
|
+
const unwrapped = unwrapEnvelope(raw);
|
|
249
|
+
if (unwrapped == null || typeof unwrapped !== "object")
|
|
250
|
+
return { outcome: "error", data: null };
|
|
251
|
+
const obj = unwrapped;
|
|
252
|
+
if (obj.success === false) {
|
|
253
|
+
logger.warn("getClearingHouseState: API returned error envelope", {
|
|
254
|
+
wallet,
|
|
255
|
+
error: obj.error,
|
|
256
|
+
});
|
|
257
|
+
return { outcome: "error", data: null };
|
|
258
|
+
}
|
|
259
|
+
const responseTime = extractMinClearingHouseTime(obj);
|
|
260
|
+
if (this.clearingHouseStaleness.isStale(wallet, responseTime)) {
|
|
261
|
+
return { outcome: "stale", data: null, responseTime };
|
|
262
|
+
}
|
|
263
|
+
return { outcome: "ok", data: obj };
|
|
264
|
+
}
|
|
265
|
+
/** Overridable delay for testing. */
|
|
266
|
+
delay(ms) {
|
|
267
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Fetch position (szi, entryPx, leverage) from clearing house for a wallet+coin.
|
|
271
|
+
* Uses getClearingHouseState so one MCP call returns both main and xyz (and other) DEX positions;
|
|
272
|
+
* then looks up the position for the given coin (and optional dex).
|
|
273
|
+
*/
|
|
274
|
+
async getPosition(wallet, coin, dex) {
|
|
275
|
+
const state = await this.getClearingHouseState(wallet);
|
|
276
|
+
if (state == null)
|
|
277
|
+
return null;
|
|
278
|
+
return findPositionInClearingHouseStateOrFallback(state, coin, dex);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Resolve several assets from one clearing house fetch (single `strategy_get_clearinghouse_state` call).
|
|
282
|
+
*/
|
|
283
|
+
async getPositionsForAssets(wallet, assets, dex) {
|
|
284
|
+
const normalized = assets.map((a) => a.trim()).filter((a) => a.length > 0);
|
|
285
|
+
if (normalized.length === 0)
|
|
286
|
+
return [];
|
|
287
|
+
const state = await this.getClearingHouseState(wallet);
|
|
288
|
+
if (state == null) {
|
|
289
|
+
return normalized.map((asset) => ({ asset, position: null }));
|
|
290
|
+
}
|
|
291
|
+
return normalized.map((asset) => ({
|
|
292
|
+
asset,
|
|
293
|
+
position: findPositionInClearingHouseStateOrFallback(state, asset, dex),
|
|
294
|
+
}));
|
|
295
|
+
}
|
|
296
|
+
async closePosition(wallet, coin, params) {
|
|
297
|
+
const effectiveCoin = params.dex === "xyz" && coin && !coin.startsWith("xyz:") ? `xyz:${coin}` : coin;
|
|
298
|
+
return this.callTool("close_position", {
|
|
299
|
+
strategyWalletAddress: wallet,
|
|
300
|
+
coin: effectiveCoin,
|
|
301
|
+
...(params.reason ? { reason: params.reason } : {}),
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* List open positions for reconciliation by parsing `strategy_get_clearinghouse_state` (same source as
|
|
306
|
+
* {@link getPosition} / getPositionsForAssets). Does not call `list_open_positions`.
|
|
307
|
+
* DEX keys `main` map to reconciler dex `""` to match DSL state paths; `xyz` stays `xyz`.
|
|
308
|
+
*/
|
|
309
|
+
async listOpenPositions(wallet) {
|
|
310
|
+
const state = await this.getClearingHouseState(wallet);
|
|
311
|
+
if (state == null) {
|
|
312
|
+
logger.warn("listOpenPositions: clearing house state null", { wallet });
|
|
313
|
+
throw new Error("strategy_get_clearinghouse_state: empty or invalid response");
|
|
314
|
+
}
|
|
315
|
+
if (!clearingHouseStateLooksParsable(state)) {
|
|
316
|
+
logger.warn("listOpenPositions: clearing house response not recognizable", {
|
|
317
|
+
wallet,
|
|
318
|
+
keys: Object.keys(state),
|
|
319
|
+
});
|
|
320
|
+
throw new Error("strategy_get_clearinghouse_state: unexpected response shape");
|
|
321
|
+
}
|
|
322
|
+
return openPositionsFromClearingHouseState(state);
|
|
323
|
+
}
|
|
324
|
+
// ─── New MCP methods ────────────────────────────────────────────────────────
|
|
325
|
+
async getStrategy(wallet) {
|
|
326
|
+
const raw = await this.callTool("strategy_get", { strategy_wallet: wallet });
|
|
327
|
+
const data = unwrapEnvelope(raw);
|
|
328
|
+
if (!isRecord(data))
|
|
329
|
+
return null;
|
|
330
|
+
return {
|
|
331
|
+
strategyId: asString(data.strategyId) ?? asString(data.id) ?? "",
|
|
332
|
+
name: asString(data.name) ?? "",
|
|
333
|
+
status: asString(data.status) ?? "",
|
|
334
|
+
traderAddress: asString(data.traderAddress) ?? "",
|
|
335
|
+
initialBudget: asNumber(data.initialBudget) ?? 0,
|
|
336
|
+
totalPnl: asNumber(data.totalPnl) ?? 0,
|
|
337
|
+
pnlPercentage: asNumber(data.pnlPercentage) ?? 0,
|
|
338
|
+
createdAt: asString(data.createdAt) ?? "",
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
async listStrategies(filters) {
|
|
342
|
+
const args = {};
|
|
343
|
+
if (filters?.strategyAddresses)
|
|
344
|
+
args.strategy_addresses = filters.strategyAddresses;
|
|
345
|
+
if (filters?.status)
|
|
346
|
+
args.status = filters.status;
|
|
347
|
+
if (filters?.strategyIds)
|
|
348
|
+
args.strategy_ids = filters.strategyIds;
|
|
349
|
+
if (filters?.strategyType)
|
|
350
|
+
args.strategy_type = filters.strategyType;
|
|
351
|
+
const raw = await this.callTool("strategy_list", args);
|
|
352
|
+
const data = unwrapEnvelope(raw);
|
|
353
|
+
const strategies = isRecord(data) && Array.isArray(data.strategies)
|
|
354
|
+
? data.strategies
|
|
355
|
+
: [];
|
|
356
|
+
return strategies.filter(isRecord).map((s) => ({
|
|
357
|
+
id: asString(s.id) ?? "",
|
|
358
|
+
strategyWalletAddress: asString(s.strategyWalletAddress) ?? "",
|
|
359
|
+
traderAddress: asString(s.traderAddress) ?? "",
|
|
360
|
+
status: asString(s.status) ?? "",
|
|
361
|
+
strategyType: asString(s.strategyType) ?? "",
|
|
362
|
+
strategyName: asString(s.strategyName) ?? asString(s.name) ?? "",
|
|
363
|
+
createdAt: asString(s.createdAt) ?? "",
|
|
364
|
+
totalFunded: asNumber(s.totalFunded) ?? 0,
|
|
365
|
+
}));
|
|
366
|
+
}
|
|
367
|
+
async getOpenOrders(wallet) {
|
|
368
|
+
const raw = await this.callTool("strategy_get_open_orders", { strategy_wallet: wallet });
|
|
369
|
+
const data = unwrapEnvelope(raw);
|
|
370
|
+
const arr = Array.isArray(data) ? data : (isRecord(data) && Array.isArray(data.orders) ? data.orders : []);
|
|
371
|
+
return arr.filter(isRecord).map((o) => ({
|
|
372
|
+
orderId: asNumber(o.orderId) ?? 0,
|
|
373
|
+
coin: asString(o.coin) ?? "",
|
|
374
|
+
side: (asString(o.side) ?? "BUY"),
|
|
375
|
+
size: asNumber(o.size) ?? asNumber(o.sz) ?? 0,
|
|
376
|
+
price: asNumber(o.price) ?? asNumber(o.limitPx) ?? 0,
|
|
377
|
+
orderType: asString(o.orderType) ?? asString(o.type) ?? "",
|
|
378
|
+
status: asString(o.status) ?? "",
|
|
379
|
+
timestamp: asNumber(o.timestamp) ?? 0,
|
|
380
|
+
}));
|
|
381
|
+
}
|
|
382
|
+
async getTraderHistory(wallet, opts) {
|
|
383
|
+
const args = { traderAddress: wallet, latest: true };
|
|
384
|
+
if (opts?.limit != null)
|
|
385
|
+
args.limit = opts.limit;
|
|
386
|
+
if (opts?.offset != null)
|
|
387
|
+
args.offset = opts.offset;
|
|
388
|
+
if (opts?.sort_by != null)
|
|
389
|
+
args.sort_by = opts.sort_by;
|
|
390
|
+
if (opts?.sort_direction != null)
|
|
391
|
+
args.sort_direction = opts.sort_direction;
|
|
392
|
+
const raw = await this.callTool("discovery_get_trader_history", args);
|
|
393
|
+
const data = unwrapEnvelope(raw);
|
|
394
|
+
const arr = Array.isArray(data) ? data : (isRecord(data) && Array.isArray(data.trades) ? data.trades : []);
|
|
395
|
+
return arr.filter(isRecord).map((t) => {
|
|
396
|
+
const szi = asNumber(t.szi) ?? 0;
|
|
397
|
+
return {
|
|
398
|
+
coin: asString(t.coin) ?? "",
|
|
399
|
+
direction: (szi >= 0 ? "LONG" : "SHORT"),
|
|
400
|
+
entryPx: asNumber(t.entryPx) ?? 0,
|
|
401
|
+
closePx: asNumber(t.closePx) ?? 0,
|
|
402
|
+
szi,
|
|
403
|
+
realizedPnl: asNumber(t.realizedPnl) ?? 0,
|
|
404
|
+
closedTime: asNumber(t.closedTime) ?? asNumber(t.closeTime) ?? 0,
|
|
405
|
+
openTime: asNumber(t.openTime) ?? 0,
|
|
406
|
+
totalFees: asNumber(t.totalFees) ?? 0,
|
|
407
|
+
};
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
async topUp(wallet, amount) {
|
|
411
|
+
const raw = await this.callTool("strategy_top_up", { strategy_wallet: wallet, amount });
|
|
412
|
+
const data = unwrapEnvelope(raw);
|
|
413
|
+
if (!isRecord(data))
|
|
414
|
+
return { success: false };
|
|
415
|
+
return { success: data.success === true, message: asString(data.message) ?? undefined };
|
|
416
|
+
}
|
|
417
|
+
async withdrawFunds(wallet, amount) {
|
|
418
|
+
const raw = await this.callTool("strategy_withdraw_funds", { strategy_wallet: wallet, amount });
|
|
419
|
+
const data = unwrapEnvelope(raw);
|
|
420
|
+
if (!isRecord(data))
|
|
421
|
+
return { success: false };
|
|
422
|
+
return { success: data.success === true, message: asString(data.message) ?? undefined };
|
|
423
|
+
}
|
|
424
|
+
async closeStrategy(wallet) {
|
|
425
|
+
const raw = await this.callTool("strategy_close", { strategy_wallet: wallet });
|
|
426
|
+
const data = unwrapEnvelope(raw);
|
|
427
|
+
if (!isRecord(data))
|
|
428
|
+
return { success: false };
|
|
429
|
+
return { success: data.success === true, message: asString(data.message) ?? undefined };
|
|
430
|
+
}
|
|
431
|
+
async closePositions(wallet, positions) {
|
|
432
|
+
return this.callTool("strategy_close_positions", {
|
|
433
|
+
strategy_wallet: wallet,
|
|
434
|
+
positions,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
async cancelOrder(wallet, orderId) {
|
|
438
|
+
return this.callTool("cancel_order", {
|
|
439
|
+
strategyWalletAddress: wallet,
|
|
440
|
+
orderId,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
async getAssetTradingLimits(wallet, coin, dex) {
|
|
444
|
+
try {
|
|
445
|
+
const args = { strategy_wallet: wallet, coin };
|
|
446
|
+
if (dex != null)
|
|
447
|
+
args.dex = dex;
|
|
448
|
+
const raw = await this.callTool("strategy_get_asset_trading_limits", args);
|
|
449
|
+
const data = unwrapEnvelope(raw) ?? raw;
|
|
450
|
+
if (!isRecord(data))
|
|
451
|
+
return null;
|
|
452
|
+
const leverage = data.leverage;
|
|
453
|
+
const value = leverage != null ? asNumber(leverage.value) : asNumber(data.maxLeverage);
|
|
454
|
+
if (value == null)
|
|
455
|
+
return null;
|
|
456
|
+
return { maxLeverage: value };
|
|
457
|
+
}
|
|
458
|
+
catch (err) {
|
|
459
|
+
logger.warn("getAssetTradingLimits failed", { wallet, coin, err });
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
async listInstruments() {
|
|
464
|
+
const raw = await this.callTool("market_list_instruments", {});
|
|
465
|
+
const unwrapped = unwrapEnvelope(raw) ?? raw;
|
|
466
|
+
if (unwrapped == null || typeof unwrapped !== "object")
|
|
467
|
+
return [];
|
|
468
|
+
const obj = unwrapped;
|
|
469
|
+
const instrumentsRaw = obj.instruments;
|
|
470
|
+
if (!Array.isArray(instrumentsRaw))
|
|
471
|
+
return [];
|
|
472
|
+
const result = [];
|
|
473
|
+
for (const row of instrumentsRaw) {
|
|
474
|
+
if (!isRecord(row))
|
|
475
|
+
continue;
|
|
476
|
+
const name = asString(row.name);
|
|
477
|
+
const maxLeverage = asNumber(row.max_leverage);
|
|
478
|
+
if (name != null && maxLeverage != null) {
|
|
479
|
+
result.push({ name, maxLeverage });
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return result;
|
|
483
|
+
}
|
|
484
|
+
async getPnlHistory(wallet, opts) {
|
|
485
|
+
const args = { strategy_wallet: wallet };
|
|
486
|
+
if (opts?.period != null)
|
|
487
|
+
args.period = opts.period;
|
|
488
|
+
return this.callTool("strategy_get_pnl_and_account_value_history", args);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// ─── Response parsing ────────────────────────────────────────────────────────
|
|
492
|
+
/**
|
|
493
|
+
* Extract SL order ID from edit_position response. Tries multiple common shapes
|
|
494
|
+
* so state gets slOrderId even when MCP returns it under different keys.
|
|
495
|
+
* MCP may return: data.ordersUpdated.stopLoss.orderId or StopLossOrderResult.orderId.
|
|
496
|
+
*/
|
|
497
|
+
function extractSlOrderId(unwrapped, raw) {
|
|
498
|
+
const from = (v) => (v != null && Number.isFinite(asNumber(v)) ? asNumber(v) : null);
|
|
499
|
+
const fromObj = (obj, key) => obj && typeof obj === "object" && key in obj ? from(obj[key]) : null;
|
|
500
|
+
const ou = unwrapped.ordersUpdated;
|
|
501
|
+
const stopLossObj = ou && typeof ou === "object" && "stopLoss" in ou ? ou.stopLoss : undefined;
|
|
502
|
+
let n = from(unwrapped.slOrderId)
|
|
503
|
+
?? (ou && "slOrderId" in ou ? from(ou.slOrderId) : null)
|
|
504
|
+
?? from(unwrapped.stopLossOrderId)
|
|
505
|
+
?? from(ou?.stopLossOrderId)
|
|
506
|
+
?? fromObj(stopLossObj, "orderId")
|
|
507
|
+
?? fromObj(unwrapped.StopLossOrderResult, "orderId")
|
|
508
|
+
?? fromObj(unwrapped.stopLossOrderResult, "orderId");
|
|
509
|
+
if (n != null)
|
|
510
|
+
return n;
|
|
511
|
+
if (isRecord(raw) && isRecord(raw.data)) {
|
|
512
|
+
const data = raw.data;
|
|
513
|
+
const dataOu = data.ordersUpdated;
|
|
514
|
+
const dataStopLoss = dataOu && typeof dataOu === "object" && "stopLoss" in dataOu ? dataOu.stopLoss : undefined;
|
|
515
|
+
n =
|
|
516
|
+
from(data.slOrderId)
|
|
517
|
+
?? from(dataOu?.slOrderId)
|
|
518
|
+
?? from(data.stopLossOrderId)
|
|
519
|
+
?? fromObj(dataStopLoss, "orderId")
|
|
520
|
+
?? fromObj(data.StopLossOrderResult, "orderId")
|
|
521
|
+
?? fromObj(data.stopLossOrderResult, "orderId");
|
|
522
|
+
if (n != null)
|
|
523
|
+
return n;
|
|
524
|
+
}
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
function parseCreatePositionResult(raw) {
|
|
528
|
+
const data = unwrapEnvelope(raw);
|
|
529
|
+
if (!isRecord(data)) {
|
|
530
|
+
return { success: false, orders: [], error: 'Invalid response shape' };
|
|
531
|
+
}
|
|
532
|
+
const success = typeof data.success === 'boolean' ? data.success : false;
|
|
533
|
+
const error = typeof data.error === 'string' ? data.error
|
|
534
|
+
: typeof data.message === 'string' ? data.message
|
|
535
|
+
: null;
|
|
536
|
+
const rawOrders = Array.isArray(data.results) ? data.results : (Array.isArray(data.orders) ? data.orders : []);
|
|
537
|
+
const orders = [];
|
|
538
|
+
for (const row of rawOrders) {
|
|
539
|
+
if (!isRecord(row))
|
|
540
|
+
continue;
|
|
541
|
+
// MCP response nests fill data under mainOrder
|
|
542
|
+
const mainOrder = isRecord(row.mainOrder) ? row.mainOrder : row;
|
|
543
|
+
// error can be an object { code, description } or a string
|
|
544
|
+
const rowError = isRecord(row.error)
|
|
545
|
+
? asString(row.error.description) ?? asString(row.error.code)
|
|
546
|
+
: asString(row.error);
|
|
547
|
+
orders.push({
|
|
548
|
+
coin: asString(row.coin) ?? asString(mainOrder.coin) ?? '',
|
|
549
|
+
direction: asDirection(row.direction) ?? asDirection(mainOrder.direction) ?? 'LONG',
|
|
550
|
+
leverage: asNumber(row.leverage) ?? asNumber(mainOrder.leverage) ?? 0,
|
|
551
|
+
marginAmount: asNumber(row.marginAmount) ?? asNumber(row.marginUsed) ?? 0,
|
|
552
|
+
entryPrice: asNumber(mainOrder.avgPrice) ?? asNumber(mainOrder.entryPrice) ?? asNumber(row.avgPrice),
|
|
553
|
+
size: asNumber(mainOrder.filledSize) ?? asNumber(mainOrder.size) ?? asNumber(row.filledSize),
|
|
554
|
+
filled: String(mainOrder.status).toUpperCase() === 'FILLED' || (typeof row.filled === 'boolean' ? row.filled : false),
|
|
555
|
+
orderId: stringifyId(mainOrder.orderId) ?? stringifyId(row.orderId),
|
|
556
|
+
executionAsMaker: typeof mainOrder.executionAsMaker === 'boolean' ? mainOrder.executionAsMaker : null,
|
|
557
|
+
error: rowError,
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
return { success, orders, error };
|
|
561
|
+
}
|
|
562
|
+
// ─── Clearing house state lookup ─────────────────────────────────────────────
|
|
563
|
+
function positionFromRaw(obj) {
|
|
564
|
+
const rawSzi = asNumber(obj.szi) ?? asNumber(obj.size);
|
|
565
|
+
const entryPx = asNumber(obj.entryPx) ?? asNumber(obj.entryPrice) ?? asNumber(obj.avgPrice);
|
|
566
|
+
if (rawSzi == null || entryPx == null || !Number.isFinite(rawSzi) || !Number.isFinite(entryPx)) {
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
569
|
+
const mag = Math.abs(rawSzi);
|
|
570
|
+
if (mag === 0)
|
|
571
|
+
return null;
|
|
572
|
+
const explicitDir = asDirection(obj.direction);
|
|
573
|
+
// When the venue includes an explicit direction, trust it for the sign of `szi`. Some MCP responses
|
|
574
|
+
// briefly keep the old signed szi after a flip while `direction` already reflects the new side.
|
|
575
|
+
const szi = explicitDir === "LONG" ? mag : explicitDir === "SHORT" ? -mag : rawSzi;
|
|
576
|
+
let leverage = asNumber(obj.leverage);
|
|
577
|
+
if (leverage == null && isRecord(obj.leverage) && typeof obj.leverage.value === "number") {
|
|
578
|
+
leverage = obj.leverage.value;
|
|
579
|
+
}
|
|
580
|
+
const result = { szi, entryPx };
|
|
581
|
+
if (leverage != null && Number.isFinite(leverage))
|
|
582
|
+
result.leverage = leverage;
|
|
583
|
+
return result;
|
|
584
|
+
}
|
|
585
|
+
/** Compare using {@link normalizeDslCoinDex} (base coin + dex bucket). */
|
|
586
|
+
function coinMatches(pos, searchCoin, rowDex, searchDex) {
|
|
587
|
+
const raw = asString(pos.coin) ?? asString(pos.asset) ?? "";
|
|
588
|
+
const a = normalizeDslCoinDex(raw, rowDex);
|
|
589
|
+
const bDex = searchDex === undefined || searchDex === null ? rowDex : searchDex;
|
|
590
|
+
const b = normalizeDslCoinDex(searchCoin, bDex);
|
|
591
|
+
return a.coin === b.coin && a.dex === b.dex;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* True if the payload looks like Senpi/Hyperliquid clearing house (so an empty list means no positions,
|
|
595
|
+
* not an unrelated JSON object).
|
|
596
|
+
*/
|
|
597
|
+
function clearingHouseStateLooksParsable(state) {
|
|
598
|
+
if (Array.isArray(state.positions ?? state.positionsList))
|
|
599
|
+
return true;
|
|
600
|
+
for (const v of Object.values(state)) {
|
|
601
|
+
if (!isRecord(v))
|
|
602
|
+
continue;
|
|
603
|
+
if (Array.isArray(v.assetPositions))
|
|
604
|
+
return true;
|
|
605
|
+
if (v.crossMarginSummary != null || v.withdrawable != null)
|
|
606
|
+
return true;
|
|
607
|
+
}
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Collect non-zero-size positions from clearing house state for reconciliation.
|
|
612
|
+
*/
|
|
613
|
+
function openPositionsFromClearingHouseState(state) {
|
|
614
|
+
const out = [];
|
|
615
|
+
const flat = state.positions ?? state.positionsList;
|
|
616
|
+
if (Array.isArray(flat)) {
|
|
617
|
+
for (const p of flat) {
|
|
618
|
+
if (!isRecord(p))
|
|
619
|
+
continue;
|
|
620
|
+
const pos = isRecord(p.position) ? p.position : p;
|
|
621
|
+
const parsed = positionFromRaw(pos);
|
|
622
|
+
if (!parsed || parsed.szi === 0)
|
|
623
|
+
continue;
|
|
624
|
+
const coinRaw = asString(pos.coin) ?? asString(pos.asset) ?? "";
|
|
625
|
+
if (!coinRaw)
|
|
626
|
+
continue;
|
|
627
|
+
const dexField = asString(p.dex) ?? "";
|
|
628
|
+
const reconcileDex = reconcileDexFromClearingHouseKey(dexField);
|
|
629
|
+
const { coin, dex } = normalizeDslCoinDex(coinRaw, reconcileDex);
|
|
630
|
+
out.push({
|
|
631
|
+
coin,
|
|
632
|
+
dex,
|
|
633
|
+
szi: parsed.szi,
|
|
634
|
+
entryPx: parsed.entryPx,
|
|
635
|
+
...(parsed.leverage != null ? { leverage: parsed.leverage } : {}),
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
return out;
|
|
639
|
+
}
|
|
640
|
+
for (const key of Object.keys(state)) {
|
|
641
|
+
const dexState = state[key];
|
|
642
|
+
if (!isRecord(dexState))
|
|
643
|
+
continue;
|
|
644
|
+
const assetPositions = dexState.assetPositions;
|
|
645
|
+
if (!Array.isArray(assetPositions))
|
|
646
|
+
continue;
|
|
647
|
+
const reconcileDex = reconcileDexFromClearingHouseKey(key);
|
|
648
|
+
for (const item of assetPositions) {
|
|
649
|
+
if (!isRecord(item))
|
|
650
|
+
continue;
|
|
651
|
+
const pos = isRecord(item.position) ? item.position : item;
|
|
652
|
+
const parsed = positionFromRaw(pos);
|
|
653
|
+
if (!parsed || parsed.szi === 0)
|
|
654
|
+
continue;
|
|
655
|
+
const coinRaw = asString(pos.coin) ?? asString(pos.asset) ?? "";
|
|
656
|
+
if (!coinRaw)
|
|
657
|
+
continue;
|
|
658
|
+
const { coin, dex } = normalizeDslCoinDex(coinRaw, reconcileDex);
|
|
659
|
+
out.push({
|
|
660
|
+
coin,
|
|
661
|
+
dex,
|
|
662
|
+
szi: parsed.szi,
|
|
663
|
+
entryPx: parsed.entryPx,
|
|
664
|
+
...(parsed.leverage != null ? { leverage: parsed.leverage } : {}),
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return out;
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Find a position for the given coin (and optional dex) in clearing house state.
|
|
672
|
+
* Senpi MCP (strategy_get_clearinghouse_state) returns { main, xyz } where each value is
|
|
673
|
+
* ClearinghouseState: { assetPositions: [ { type, position: { coin, szi, entryPx, leverage } } ] }.
|
|
674
|
+
* Also supports flat { positions: [ { coin, dex?, ... } ] } or per-DEX arrays.
|
|
675
|
+
*/
|
|
676
|
+
function findPositionInClearingHouseState(state, coin, dex) {
|
|
677
|
+
// Single flat list with optional dex on each item
|
|
678
|
+
const positions = state.positions ?? state.positionsList;
|
|
679
|
+
if (Array.isArray(positions)) {
|
|
680
|
+
for (const p of positions) {
|
|
681
|
+
if (!isRecord(p))
|
|
682
|
+
continue;
|
|
683
|
+
const pos = isRecord(p.position) ? p.position : p;
|
|
684
|
+
const reconcileDex = reconcileDexFromClearingHouseKey(asString(p.dex) ?? "");
|
|
685
|
+
if (!coinMatches(pos, coin, reconcileDex, dex))
|
|
686
|
+
continue;
|
|
687
|
+
if (dex != null && dex !== "" && reconcileDex !== dex)
|
|
688
|
+
continue;
|
|
689
|
+
const result = positionFromRaw(pos);
|
|
690
|
+
if (result)
|
|
691
|
+
return result;
|
|
692
|
+
}
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
// Per-DEX keys (main, xyz): each value is ClearinghouseState with assetPositions.
|
|
696
|
+
// Never use state[dex] literally — MCP may use "XYZ" vs "xyz"; match by reconciled dex.
|
|
697
|
+
const keysToSearch = dex != null && dex !== ""
|
|
698
|
+
? Object.keys(state).filter((k) => reconcileDexFromClearingHouseKey(k) === dex)
|
|
699
|
+
: Object.keys(state);
|
|
700
|
+
for (const key of keysToSearch) {
|
|
701
|
+
const dexState = state[key];
|
|
702
|
+
if (dexState == null || typeof dexState !== "object")
|
|
703
|
+
continue;
|
|
704
|
+
const dexObj = dexState;
|
|
705
|
+
const assetPositions = dexObj.assetPositions;
|
|
706
|
+
if (!Array.isArray(assetPositions))
|
|
707
|
+
continue;
|
|
708
|
+
const rowDex = reconcileDexFromClearingHouseKey(key);
|
|
709
|
+
for (const item of assetPositions) {
|
|
710
|
+
if (!isRecord(item))
|
|
711
|
+
continue;
|
|
712
|
+
const pos = isRecord(item.position) ? item.position : item;
|
|
713
|
+
if (!coinMatches(pos, coin, rowDex, dex))
|
|
714
|
+
continue;
|
|
715
|
+
const result = positionFromRaw(pos);
|
|
716
|
+
if (result)
|
|
717
|
+
return result;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
return null;
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Prefer {@link findPositionInClearingHouseState}; if it misses with a dex filter, MCP may use a
|
|
724
|
+
* different top-level bucket name (`hip3`, builder deployers, etc.) while DSL still uses `xyz`.
|
|
725
|
+
* Then scan all rows from {@link openPositionsFromClearingHouseState} and match by base coin
|
|
726
|
+
* (case-insensitive), preferring reconciled dex when multiple rows exist.
|
|
727
|
+
*/
|
|
728
|
+
function findPositionInClearingHouseStateOrFallback(state, coin, dex) {
|
|
729
|
+
const direct = findPositionInClearingHouseState(state, coin, dex);
|
|
730
|
+
if (direct)
|
|
731
|
+
return direct;
|
|
732
|
+
if (!clearingHouseStateLooksParsable(state))
|
|
733
|
+
return null;
|
|
734
|
+
const q = normalizeDslCoinDex(coin.trim(), dex ?? "");
|
|
735
|
+
const rows = openPositionsFromClearingHouseState(state);
|
|
736
|
+
let candidates = rows.filter((r) => {
|
|
737
|
+
const n = normalizeDslCoinDex(r.coin, r.dex ?? "");
|
|
738
|
+
return n.coin.toUpperCase() === q.coin.toUpperCase();
|
|
739
|
+
});
|
|
740
|
+
if (candidates.length === 0)
|
|
741
|
+
return null;
|
|
742
|
+
if (q.dex) {
|
|
743
|
+
const byDex = candidates.filter((r) => normalizeDslCoinDex(r.coin, r.dex ?? "").dex === q.dex);
|
|
744
|
+
if (byDex.length >= 1)
|
|
745
|
+
candidates = byDex;
|
|
746
|
+
// If no bucket matches DSL dex (e.g. only `hip3`), keep all base-coin matches for single-position disambiguation.
|
|
747
|
+
}
|
|
748
|
+
const pick = candidates.length === 1
|
|
749
|
+
? candidates[0]
|
|
750
|
+
: candidates.find((r) => normalizeDslCoinDex(r.coin, r.dex ?? "").dex === q.dex) ?? candidates[0];
|
|
751
|
+
const szi = pick.szi;
|
|
752
|
+
const entryPx = pick.entryPx;
|
|
753
|
+
if (szi == null || entryPx == null || !Number.isFinite(szi) || !Number.isFinite(entryPx))
|
|
754
|
+
return null;
|
|
755
|
+
return {
|
|
756
|
+
szi,
|
|
757
|
+
entryPx,
|
|
758
|
+
...(pick.leverage != null && Number.isFinite(pick.leverage) ? { leverage: pick.leverage } : {}),
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
762
|
+
function asDirection(value) {
|
|
763
|
+
if (value === "LONG" || value === "SHORT")
|
|
764
|
+
return value;
|
|
765
|
+
if (typeof value === "string") {
|
|
766
|
+
const u = value.trim().toUpperCase();
|
|
767
|
+
if (u === "LONG" || u === "SHORT")
|
|
768
|
+
return u;
|
|
769
|
+
}
|
|
770
|
+
return null;
|
|
771
|
+
}
|
|
772
|
+
function stringifyId(value) {
|
|
773
|
+
if (typeof value === 'string')
|
|
774
|
+
return value;
|
|
775
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
776
|
+
return String(value);
|
|
777
|
+
return null;
|
|
778
|
+
}
|
|
779
|
+
//# sourceMappingURL=client.js.map
|