@oracle-agent/oracle 0.14.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/SETUP.md +4 -4
- package/dist/action-receipts.mjs +1 -0
- package/dist/action-semantics.mjs +1 -0
- package/dist/address-book.mjs +2 -0
- package/dist/bin/desk-server.mjs +60 -0
- package/dist/bin/oracle-data-mcp.mjs +9 -0
- package/dist/bin/oracle-equities.mjs +20 -0
- package/dist/bin/oracle-init.mjs +24 -0
- package/dist/bin/oracle-public-server.mjs +5 -0
- package/dist/bin/oracle-route.mjs +22 -0
- package/dist/bin/oracle-scan.mjs +18 -0
- package/dist/bin/oracle-upgrade.mjs +21 -0
- package/dist/bin/oracle.mjs +63 -0
- package/dist/chains.mjs +1 -0
- package/dist/cli/commands/auth.mjs +16 -0
- package/dist/cli/commands/bootstrap.mjs +18 -0
- package/dist/cli/commands/chain.mjs +21 -0
- package/dist/cli/commands/chat.mjs +45 -0
- package/dist/cli/commands/credential.mjs +1 -0
- package/dist/cli/commands/data-mcp.mjs +2 -0
- package/dist/cli/commands/data.mjs +12 -0
- package/dist/cli/commands/doctor.mjs +5 -0
- package/dist/cli/commands/equities.mjs +15 -0
- package/dist/cli/commands/farm.mjs +59 -0
- package/dist/cli/commands/fees.mjs +10 -0
- package/dist/cli/commands/follow.mjs +28 -0
- package/dist/cli/commands/harness.mjs +15 -0
- package/dist/cli/commands/help.mjs +1 -0
- package/dist/cli/commands/init.mjs +3 -0
- package/dist/cli/commands/mcp.mjs +36 -0
- package/dist/cli/commands/model.mjs +54 -0
- package/dist/cli/commands/plugins.mjs +43 -0
- package/dist/cli/commands/prepare.mjs +2 -0
- package/dist/cli/commands/public.mjs +3 -0
- package/dist/cli/commands/resolve.mjs +23 -0
- package/dist/cli/commands/route.mjs +2 -0
- package/dist/cli/commands/runner.mjs +1 -0
- package/dist/cli/commands/scan.mjs +2 -0
- package/dist/cli/commands/setup.mjs +34 -0
- package/dist/cli/commands/sign.mjs +4 -0
- package/dist/cli/commands/signer.mjs +1 -0
- package/dist/cli/commands/strategy.mjs +18 -0
- package/dist/cli/commands/swap.mjs +36 -0
- package/dist/cli/commands/upgrade.mjs +2 -0
- package/dist/cli/commands/vault.mjs +1 -0
- package/dist/cli/commands/version.mjs +2 -0
- package/dist/data/desk-data.mjs +55 -0
- package/dist/data/names.mjs +2 -0
- package/dist/data/providers/farming.mjs +2 -0
- package/dist/equities/index.mjs +1 -0
- package/dist/index.mjs +60 -0
- package/dist/nft-gas-war-guard.mjs +1 -0
- package/dist/onboarding/harness-configs.mjs +4 -0
- package/dist/portfolio-risk.mjs +1 -0
- package/dist/prepare-envelope.mjs +1 -0
- package/dist/public-api/agent-grants.mjs +3 -0
- package/dist/public-control/policy-schema.mjs +1 -0
- package/dist/router/index.mjs +2 -0
- package/dist/scanner/index.mjs +4 -0
- package/dist/signals/index.mjs +1 -0
- package/dist/strategy/index.mjs +3 -0
- package/dist/watch-preferences.mjs +1 -0
- package/package.json +33 -78
- package/public/oracle-splash/_variants/ice.html +5 -18
- package/public/oracle-splash/_variants/ivory.html +5 -18
- package/public/oracle-splash/downloads/index.html +4 -4
- package/public/oracle-splash/index.html +113 -34
- package/CONTRIBUTING.md +0 -99
- package/bin/desk-server.mjs +0 -473
- package/bin/oracle-data-mcp.mjs +0 -1252
- package/bin/oracle-equities.mjs +0 -168
- package/bin/oracle-init.mjs +0 -525
- package/bin/oracle-public-server.mjs +0 -36
- package/bin/oracle-route.mjs +0 -254
- package/bin/oracle-scan.mjs +0 -192
- package/bin/oracle-upgrade.mjs +0 -42
- package/bin/oracle.mjs +0 -34
- package/docs/adding-a-chain.md +0 -229
- package/docs/architecture.md +0 -139
- package/docs/buzz-integration.md +0 -115
- package/docs/cli.md +0 -143
- package/docs/connectors.md +0 -13
- package/docs/hyperliquid-builder-code.md +0 -50
- package/docs/locals-only-fee-waiver.md +0 -34
- package/docs/oracle-pack-standard.md +0 -29
- package/docs/profiles.md +0 -151
- package/docs/public-surface.md +0 -206
- package/examples/add-a-chain.mjs +0 -65
- package/examples/oracle-pack-template.mjs +0 -38
- package/examples/research-a-token.mjs +0 -70
- package/plugins/oracle-owner-gate/__init__.py +0 -288
- package/plugins/oracle-owner-gate/plugin.yaml +0 -9
- package/protocols/templates/safe-erc20/SECURITY.md +0 -16
- package/protocols/templates/safe-erc20/foundry.toml +0 -12
- package/protocols/templates/safe-erc20/remappings.txt +0 -2
- package/protocols/templates/safe-erc20/src/SafeERC20.sol +0 -53
- package/protocols/templates/safe-erc20/test/SafeERC20.t.sol +0 -72
- package/scripts/adversarial-bench.mjs +0 -114
- package/scripts/build-dist.mjs +0 -119
- package/scripts/build-inscription.py +0 -230
- package/scripts/check-doc-drift.mjs +0 -123
- package/scripts/check-test-count.mjs +0 -105
- package/scripts/e2e-hl-markets.mjs +0 -21
- package/scripts/e2e-hl-perps.mjs +0 -48
- package/scripts/e2e-hypercore-staking.mjs +0 -128
- package/scripts/e2e-solana-bitcoin.mjs +0 -183
- package/scripts/guard-publish.mjs +0 -22
- package/scripts/protocol-template-gate.mjs +0 -15
- package/scripts/public-api-scan.mjs +0 -23
- package/scripts/publish-dist.mjs +0 -67
- package/scripts/record-hero-cli.sh +0 -80
- package/scripts/secret-scan.mjs +0 -169
- package/scripts/smoke-dist-bins.mjs +0 -89
- package/scripts/verify-dist.mjs +0 -29
- package/scripts/verify-v3-venues.mjs +0 -233
- package/skins/oracle.yaml +0 -56
- package/src/action-receipts.mjs +0 -265
- package/src/action-semantics.mjs +0 -62
- package/src/address-book.mjs +0 -208
- package/src/agent-auth.mjs +0 -206
- package/src/approval-guard.mjs +0 -282
- package/src/attestation-secret.mjs +0 -94
- package/src/audit-log.mjs +0 -196
- package/src/auth/oauth.mjs +0 -672
- package/src/auto-slippage.mjs +0 -378
- package/src/capability-posture.mjs +0 -125
- package/src/cards.mjs +0 -422
- package/src/chains.mjs +0 -62
- package/src/cli/chain-catalog.mjs +0 -215
- package/src/cli/chain-state.mjs +0 -74
- package/src/cli/commands/auth.mjs +0 -193
- package/src/cli/commands/bootstrap.mjs +0 -87
- package/src/cli/commands/chain.mjs +0 -143
- package/src/cli/commands/chat.mjs +0 -465
- package/src/cli/commands/credential.mjs +0 -9
- package/src/cli/commands/data-mcp.mjs +0 -18
- package/src/cli/commands/data.mjs +0 -75
- package/src/cli/commands/doctor.mjs +0 -136
- package/src/cli/commands/equities.mjs +0 -41
- package/src/cli/commands/farm.mjs +0 -129
- package/src/cli/commands/fees.mjs +0 -109
- package/src/cli/commands/follow.mjs +0 -130
- package/src/cli/commands/harness.mjs +0 -63
- package/src/cli/commands/help.mjs +0 -7
- package/src/cli/commands/init.mjs +0 -27
- package/src/cli/commands/mcp.mjs +0 -154
- package/src/cli/commands/model.mjs +0 -106
- package/src/cli/commands/plugins.mjs +0 -275
- package/src/cli/commands/prepare.mjs +0 -12
- package/src/cli/commands/public.mjs +0 -20
- package/src/cli/commands/resolve.mjs +0 -64
- package/src/cli/commands/route.mjs +0 -12
- package/src/cli/commands/runner.mjs +0 -9
- package/src/cli/commands/scan.mjs +0 -12
- package/src/cli/commands/setup.mjs +0 -294
- package/src/cli/commands/sign.mjs +0 -21
- package/src/cli/commands/signer.mjs +0 -9
- package/src/cli/commands/swap.mjs +0 -102
- package/src/cli/commands/upgrade.mjs +0 -12
- package/src/cli/commands/vault.mjs +0 -9
- package/src/cli/commands/version.mjs +0 -22
- package/src/cli/first-run.mjs +0 -23
- package/src/cli/kernel.mjs +0 -262
- package/src/cli/mcp-targets/chatgpt.mjs +0 -51
- package/src/cli/mcp-targets/claude-code.mjs +0 -39
- package/src/cli/mcp-targets/claude-desktop.mjs +0 -24
- package/src/cli/mcp-targets/codex.mjs +0 -41
- package/src/cli/mcp-targets/cursor.mjs +0 -32
- package/src/cli/mcp-targets/shared.mjs +0 -71
- package/src/cli/mcp-targets/vscode.mjs +0 -39
- package/src/cli/messaging-platforms.mjs +0 -217
- package/src/cli/model-config.mjs +0 -78
- package/src/cli/operator-dispatch.mjs +0 -194
- package/src/cli/oracle-harness.py +0 -415
- package/src/cli/paths.mjs +0 -107
- package/src/cli/runtime.mjs +0 -351
- package/src/cli/setup-state.mjs +0 -168
- package/src/cli/spawn-child.mjs +0 -43
- package/src/data/catalog.mjs +0 -858
- package/src/data/desk-data.mjs +0 -877
- package/src/data/http.mjs +0 -253
- package/src/data/names.mjs +0 -188
- package/src/data/provider-endpoint.mjs +0 -94
- package/src/data/providers/aave-v3.mjs +0 -139
- package/src/data/providers/across-bridge.mjs +0 -41
- package/src/data/providers/aerodrome.mjs +0 -245
- package/src/data/providers/aevo.mjs +0 -33
- package/src/data/providers/approval-indexer.mjs +0 -133
- package/src/data/providers/approvals.mjs +0 -594
- package/src/data/providers/babylon-staking.mjs +0 -149
- package/src/data/providers/balancer.mjs +0 -209
- package/src/data/providers/beefy-yields.mjs +0 -45
- package/src/data/providers/birdeye-tokens.mjs +0 -33
- package/src/data/providers/bisq-markets.mjs +0 -145
- package/src/data/providers/bitcoin-esplora.mjs +0 -216
- package/src/data/providers/bitcoin-meta.mjs +0 -378
- package/src/data/providers/blockscout.mjs +0 -14
- package/src/data/providers/bob-rootstock.mjs +0 -198
- package/src/data/providers/braiins-insights.mjs +0 -103
- package/src/data/providers/bridge-aggregator.mjs +0 -259
- package/src/data/providers/bridges.mjs +0 -242
- package/src/data/providers/bungee.mjs +0 -29
- package/src/data/providers/celestia-da.mjs +0 -38
- package/src/data/providers/changenow.mjs +0 -135
- package/src/data/providers/compound.mjs +0 -32
- package/src/data/providers/connext.mjs +0 -28
- package/src/data/providers/convex.mjs +0 -30
- package/src/data/providers/cow-protocol.mjs +0 -110
- package/src/data/providers/cowswap.mjs +0 -415
- package/src/data/providers/curve.mjs +0 -201
- package/src/data/providers/das-assets.mjs +0 -59
- package/src/data/providers/debridge.mjs +0 -109
- package/src/data/providers/defillama.mjs +0 -88
- package/src/data/providers/dexscreener.mjs +0 -43
- package/src/data/providers/drift.mjs +0 -32
- package/src/data/providers/dydx.mjs +0 -41
- package/src/data/providers/evm-rpc.mjs +0 -225
- package/src/data/providers/farming.mjs +0 -291
- package/src/data/providers/geckoterminal.mjs +0 -34
- package/src/data/providers/gmx.mjs +0 -496
- package/src/data/providers/hiro-stacks.mjs +0 -150
- package/src/data/providers/hl-assets.mjs +0 -165
- package/src/data/providers/hl-info.mjs +0 -108
- package/src/data/providers/hl-markets.mjs +0 -210
- package/src/data/providers/hl-outcome.mjs +0 -61
- package/src/data/providers/hl-perps.mjs +0 -419
- package/src/data/providers/hl-staking.mjs +0 -353
- package/src/data/providers/hl-ws.mjs +0 -119
- package/src/data/providers/hyperevm-dex.mjs +0 -49
- package/src/data/providers/jito-mev.mjs +0 -117
- package/src/data/providers/jupiter-venues.mjs +0 -119
- package/src/data/providers/jupiter.mjs +0 -315
- package/src/data/providers/kamino-strategies.mjs +0 -143
- package/src/data/providers/l2beat-tvl.mjs +0 -42
- package/src/data/providers/lifi.mjs +0 -166
- package/src/data/providers/liquid-esplora.mjs +0 -152
- package/src/data/providers/magiceden-ordinals.mjs +0 -141
- package/src/data/providers/magiceden-sol.mjs +0 -406
- package/src/data/providers/mempool-lightning.mjs +0 -144
- package/src/data/providers/mempool-mining.mjs +0 -142
- package/src/data/providers/meteora-dlmm.mjs +0 -168
- package/src/data/providers/morpho.mjs +0 -177
- package/src/data/providers/nft-gallery.mjs +0 -163
- package/src/data/providers/nft-portfolio.mjs +0 -494
- package/src/data/providers/odos.mjs +0 -156
- package/src/data/providers/ondo.mjs +0 -31
- package/src/data/providers/oneinch.mjs +0 -174
- package/src/data/providers/opensea-multichain.mjs +0 -136
- package/src/data/providers/opensea-nft.mjs +0 -371
- package/src/data/providers/orca.mjs +0 -29
- package/src/data/providers/ordinals-runes.mjs +0 -180
- package/src/data/providers/pancakeswap.mjs +0 -28
- package/src/data/providers/paraswap.mjs +0 -125
- package/src/data/providers/pendle.mjs +0 -188
- package/src/data/providers/poly-clob.mjs +0 -283
- package/src/data/providers/poly-public.mjs +0 -96
- package/src/data/providers/poly-ws.mjs +0 -103
- package/src/data/providers/polygon-staking.mjs +0 -227
- package/src/data/providers/portfolio-history.mjs +0 -394
- package/src/data/providers/portfolio.mjs +0 -600
- package/src/data/providers/pyth-price-feeds.mjs +0 -172
- package/src/data/providers/raydium.mjs +0 -35
- package/src/data/providers/relayscan-mev.mjs +0 -72
- package/src/data/providers/rfq.mjs +0 -15
- package/src/data/providers/rh-agent.mjs +0 -59
- package/src/data/providers/sanctum-lst.mjs +0 -180
- package/src/data/providers/satflow.mjs +0 -341
- package/src/data/providers/signed-material-guard.mjs +0 -108
- package/src/data/providers/solana-rpc.mjs +0 -197
- package/src/data/providers/solend-lending.mjs +0 -166
- package/src/data/providers/spark-lend.mjs +0 -42
- package/src/data/providers/squid-router.mjs +0 -29
- package/src/data/providers/stargate.mjs +0 -29
- package/src/data/providers/sushiswap.mjs +0 -30
- package/src/data/providers/symbiotic-restaking.mjs +0 -41
- package/src/data/providers/thorchain.mjs +0 -36
- package/src/data/providers/traderjoe.mjs +0 -28
- package/src/data/providers/twap.mjs +0 -152
- package/src/data/providers/uniswap-v3.mjs +0 -457
- package/src/data/providers/uniswap-v4.mjs +0 -414
- package/src/data/providers/vertex.mjs +0 -41
- package/src/data/providers/wallet-watch.mjs +0 -264
- package/src/data/providers/wormhole.mjs +0 -28
- package/src/data/providers/yearn.mjs +0 -31
- package/src/data/providers/zerox.mjs +0 -167
- package/src/data/public-api-scan.mjs +0 -61
- package/src/data/quote-placeholder.mjs +0 -31
- package/src/desk/swap-prepare.mjs +0 -194
- package/src/equities/bridge.mjs +0 -388
- package/src/equities/fixtures/bridge_routes.json +0 -159
- package/src/equities/fixtures/dst_transitions.json +0 -29
- package/src/equities/fixtures/equity_dex_pools.json +0 -154
- package/src/equities/fixtures/hip3_l2books.json +0 -2711
- package/src/equities/fixtures/nyse_holidays.json +0 -1
- package/src/equities/fixtures/oracles.json +0 -100
- package/src/equities/fixtures/rh_pool_state.json +0 -244
- package/src/equities/fixtures/solana_xstocks.json +0 -704
- package/src/equities/fixtures/ton_xstocks.json +0 -35
- package/src/equities/fixtures/universe.json +0 -411
- package/src/equities/fixtures/venues.json +0 -3542
- package/src/equities/fixtures.mjs +0 -405
- package/src/equities/funding.mjs +0 -142
- package/src/equities/index.mjs +0 -166
- package/src/equities/liveness.mjs +0 -148
- package/src/equities/marketHours.mjs +0 -249
- package/src/equities/normalize.mjs +0 -295
- package/src/equities/num.mjs +0 -146
- package/src/equities/prepare.mjs +0 -95
- package/src/equities/rank.mjs +0 -260
- package/src/equities/sourceNum.mjs +0 -69
- package/src/equities/types.mjs +0 -220
- package/src/equities/venues/arcus-perp.mjs +0 -84
- package/src/equities/venues/arcus-spot.mjs +0 -105
- package/src/equities/venues/hyperliquid-hip3.mjs +0 -224
- package/src/equities/venues/rh-uniswap.mjs +0 -216
- package/src/equities/venues/solana-xstocks.mjs +0 -139
- package/src/equities/venues/ton-stonfi.mjs +0 -139
- package/src/exact-integer.mjs +0 -72
- package/src/exec-policy.mjs +0 -419
- package/src/flags.mjs +0 -15
- package/src/fresh-window.mjs +0 -76
- package/src/gmx-attestation.mjs +0 -176
- package/src/index.mjs +0 -107
- package/src/licensing/locals-only.mjs +0 -25
- package/src/nft-gas-war-guard.mjs +0 -139
- package/src/onboarding/agent-keys.mjs +0 -161
- package/src/onboarding/harness-configs.mjs +0 -102
- package/src/onboarding/index.mjs +0 -18
- package/src/onboarding/tiers.mjs +0 -139
- package/src/oracle-env.mjs +0 -55
- package/src/package-manifest.mjs +0 -42
- package/src/plugins/agent-plugin-loader.mjs +0 -225
- package/src/portfolio-risk.mjs +0 -170
- package/src/prepare-envelope.mjs +0 -204
- package/src/profile-upgrade.mjs +0 -277
- package/src/protocol-execution.mjs +0 -84
- package/src/protocol-templates/gate.mjs +0 -179
- package/src/protocol-templates/prepare-deploy.mjs +0 -81
- package/src/public-api/agent-grants.mjs +0 -57
- package/src/public-api/buzz-integration.mjs +0 -267
- package/src/public-api/connect-agent.mjs +0 -424
- package/src/public-api/grants.mjs +0 -142
- package/src/public-api/http.mjs +0 -707
- package/src/public-api/metering.mjs +0 -111
- package/src/public-control/aa-adapter.mjs +0 -402
- package/src/public-control/build-registry.mjs +0 -227
- package/src/public-control/bundler-client.mjs +0 -357
- package/src/public-control/grant-indexer.mjs +0 -296
- package/src/public-control/policy-render.mjs +0 -69
- package/src/public-control/policy-schema.mjs +0 -322
- package/src/public-control/runtime-config.mjs +0 -275
- package/src/public-control/session-key-model.mjs +0 -379
- package/src/public-control/session-orchestrator.mjs +0 -418
- package/src/rfq/intent.mjs +0 -180
- package/src/rfq/sources.mjs +0 -181
- package/src/route-attestation.mjs +0 -132
- package/src/router/best-execution.mjs +0 -326
- package/src/router/index.mjs +0 -250
- package/src/router/integrator-fee.mjs +0 -135
- package/src/router/prepare-bridge.mjs +0 -293
- package/src/router/prepare-route.mjs +0 -398
- package/src/router/proposal.mjs +0 -311
- package/src/router/risk-classifier.mjs +0 -119
- package/src/router/route-sources.mjs +0 -364
- package/src/scanner/chains.config.mjs +0 -543
- package/src/scanner/contract.mjs +0 -270
- package/src/scanner/evm-scanner.mjs +0 -394
- package/src/scanner/index.mjs +0 -9
- package/src/scanner/v2-venue.mjs +0 -351
- package/src/scanner/v3-venue.mjs +0 -308
- package/src/scopes.mjs +0 -44
- package/src/sell-simulation.mjs +0 -167
- package/src/signals/engine.mjs +0 -146
- package/src/signals/index.mjs +0 -1
- package/src/token-transfer-guard.mjs +0 -188
- package/src/tui/app.mjs +0 -438
- package/src/tui/backend.mjs +0 -215
- package/src/tui/format.mjs +0 -272
- package/src/tui/gateway-client.mjs +0 -177
- package/src/tui/input.mjs +0 -501
- package/src/tui/memory.mjs +0 -105
- package/src/tui/meta-learn.mjs +0 -85
- package/src/tui/renderer.mjs +0 -443
- package/src/tui/scheduler.mjs +0 -205
- package/src/tui/skills-loader.mjs +0 -140
- package/src/tui/standalone-client.mjs +0 -752
- package/src/tui/theme.mjs +0 -81
- package/src/vault-attestation.mjs +0 -146
- package/src/venues.mjs +0 -206
- package/src/watch-preferences.mjs +0 -85
- /package/{profiles → dist/assets/profiles}/_template/SOUL.md +0 -0
- /package/{profiles → dist/assets/profiles}/_template/profile.json +0 -0
- /package/{profiles → dist/assets/profiles}/bitcoin-agent/SOUL.md +0 -0
- /package/{profiles → dist/assets/profiles}/bitcoin-agent/profile.json +0 -0
- /package/{profiles → dist/assets/profiles}/hyperliquid-agent/SOUL.md +0 -0
- /package/{profiles → dist/assets/profiles}/hyperliquid-agent/profile.json +0 -0
- /package/{profiles → dist/assets/profiles}/oracle/SOUL.md +0 -0
- /package/{profiles → dist/assets/profiles}/oracle/profile.json +0 -0
- /package/{profiles → dist/assets/profiles}/polymarket-agent/SOUL.md +0 -0
- /package/{profiles → dist/assets/profiles}/polymarket-agent/profile.json +0 -0
- /package/{profiles → dist/assets/profiles}/profile.schema.json +0 -0
- /package/{profiles → dist/assets/profiles}/protocol-builder/SOUL.md +0 -0
- /package/{profiles → dist/assets/profiles}/protocol-builder/profile.json +0 -0
- /package/{profiles → dist/assets/profiles}/robinhood-agent/SOUL.md +0 -0
- /package/{profiles → dist/assets/profiles}/robinhood-agent/profile.json +0 -0
- /package/{profiles → dist/assets/profiles}/solana-agent/SOUL.md +0 -0
- /package/{profiles → dist/assets/profiles}/solana-agent/profile.json +0 -0
- /package/{profiles → dist/assets/profiles}/stable-agent/SOUL.md +0 -0
- /package/{profiles → dist/assets/profiles}/stable-agent/profile.json +0 -0
- /package/{skills → dist/assets/skills}/balance/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/bitcoin-l1.md +0 -0
- /package/{skills → dist/assets/skills}/chain-defi-ecosystem-profiling.md +0 -0
- /package/{skills → dist/assets/skills}/evm-contract-research.md +0 -0
- /package/{skills → dist/assets/skills}/hyperliquid.md +0 -0
- /package/{skills → dist/assets/skills}/multichain-exec-desk.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-action-semantics/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-best-execution/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-best-execution.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-bitcoin/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-chain-graphs-telegram-cards/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-chat/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-chat/chain.SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-chat/setup.SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-circuit-breaker/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-contract-research/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-desk/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-desk.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-dex-launch/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-equities/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-grants/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-hypercore-staking/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-hyperliquid/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-meme-token-sniper/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-multichain-nft-launch/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-multichain-token-launch/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-nft-gacha-launch/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-nft-mint-gas-war/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-polymarket/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-protocol-builder/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-protocol-security/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-public-product/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-receipts/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-receipts.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-rfq-tokenized-assets/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-smart-wallet-scanner/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-solana/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-solana-nft/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/oracle-token-research/SKILL.md +0 -0
- /package/{skills → dist/assets/skills}/solana.md +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{spawnSync as o}from"node:child_process";var t={name:"route",summary:"swap/bridge prepare helpers",group:"read",usage:"oracle route <swap|bridge|prepare|prepare-bridge> ...",async run(e){let a=e.bin("oracle-route.mjs"),r=o(process.execPath,[a,...e.argv],{stdio:"inherit"});return r.error?(process.stderr.write(`oracle: failed to spawn oracle-route: ${r.error.message}
|
|
2
|
+
`),1):typeof r.status=="number"?r.status:1}};export{t as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var n={name:"runner",summary:"action runner daemon",group:"sign",usage:"oracle runner [--interval-ms N ...]",async run(r){return r.dispatchOperator("oracle-runner",r.argv,{appendHintOnError:!0})}};export{n as default};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{spawnSync as a}from"node:child_process";var o={name:"scan",summary:"chain scanner",group:"read",usage:"oracle scan <chains|head|token|pools|risk|quote|sell> ...",async run(e){let s=e.bin("oracle-scan.mjs"),r=a(process.execPath,[s,...e.argv],{stdio:"inherit"});return r.error?(process.stderr.write(`oracle: failed to spawn oracle-scan: ${r.error.message}
|
|
2
|
+
`),1):typeof r.status=="number"?r.status:1}};export{o as default};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import{spawnSync as we}from"node:child_process";import{stdin as m,stdout as J}from"node:process";var j=Object.freeze([{key:"telegram",name:"telegram",hermes:["gateway","setup"],required:["TELEGRAM_BOT_TOKEN"],optional:["TELEGRAM_ALLOWED_USERS","TELEGRAM_PROXY"],note:"dms \xB7 groups \xB7 topics"},{key:"discord",name:"discord",hermes:["gateway","setup"],required:["DISCORD_BOT_TOKEN"],optional:["DISCORD_ALLOWED_USERS"],note:"dms \xB7 channels \xB7 threads"},{key:"slack",name:"slack",hermes:["gateway","setup"],required:["SLACK_BOT_TOKEN","SLACK_APP_TOKEN"],optional:["SLACK_ALLOWED_USERS"],note:"socket mode"},{key:"whatsapp",name:"whatsapp",hermes:["whatsapp"],required:[],optional:["WHATSAPP_ALLOWED_USERS","WHATSAPP_MODE"],note:"qr bridge"},{key:"whatsapp-cloud",name:"whatsapp cloud",hermes:["whatsapp-cloud"],required:[],optional:[],note:"business cloud api"},{key:"signal",name:"signal",hermes:["gateway","setup"],required:["SIGNAL_HTTP_URL","SIGNAL_ACCOUNT"],optional:["SIGNAL_ALLOWED_USERS"],note:"signal-cli rest bridge"},{key:"matrix",name:"matrix",hermes:["gateway","setup"],required:["MATRIX_HOMESERVER","MATRIX_ACCESS_TOKEN","MATRIX_USER_ID"],optional:["MATRIX_ALLOWED_USERS"],note:"rooms \xB7 dms"},{key:"mattermost",name:"mattermost",hermes:["gateway","setup"],required:["MATTERMOST_URL","MATTERMOST_TOKEN"],optional:["MATTERMOST_ALLOWED_USERS"],note:"channels \xB7 dms"},{key:"email",name:"email",hermes:["gateway","setup"],required:["EMAIL_ADDRESS","EMAIL_PASSWORD","EMAIL_IMAP_HOST","EMAIL_SMTP_HOST"],optional:[],note:"imap/smtp mailbox"},{key:"bluebubbles",name:"bluebubbles",hermes:["gateway","setup"],required:[],optional:[],note:"imessage via bluebubbles"},{key:"photon",name:"photon",hermes:["photon"],required:["PHOTON_PROJECT_ID","PHOTON_PROJECT_SECRET"],optional:["PHOTON_ALLOWED_USERS","PHOTON_HOME_CHANNEL"],note:"imessage via spectrum (no mac)"},{key:"homeassistant",name:"homeassistant",hermes:["gateway","setup"],required:["HASS_URL","HASS_TOKEN"],optional:[],note:"smart home"},{key:"webhook",name:"webhook",hermes:["gateway","setup"],required:[],optional:[],note:"http ingress"},{key:"api-server",name:"api server",hermes:["gateway","setup"],required:[],optional:[],note:"local http api"},{key:"dingtalk",name:"dingtalk",hermes:["gateway","setup"],required:[],optional:[],note:"dingtalk bot"},{key:"feishu",name:"feishu",hermes:["gateway","setup"],required:[],optional:[],note:"feishu / lark"},{key:"wecom",name:"wecom",hermes:["gateway","setup"],required:[],optional:[],note:"wecom"},{key:"weixin",name:"weixin",hermes:["gateway","setup"],required:[],optional:[],note:"weixin"},{key:"qqbot",name:"qqbot",hermes:["gateway","setup"],required:[],optional:[],note:"qq bot"}]);function K(t){return String(t||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function T(){return j.slice()}function v(t){let r=K(t);if(!r)return null;for(let e of j)if(e.key===r||K(e.name)===r)return e;return null}function W({profile:t="oracle",statuses:r={}}={}){let e=["oracle setup","","one oracle. many models. every connected channel.",`profile: ${t}`,"","messaging platforms:",""];for(let n of j){let s=r[n.key]||"unset";e.push(` ${n.key.padEnd(16)} ${String(s).padEnd(8)} ${n.note}`)}return e.push(""),e.push("commands:"),e.push(" oracle setup this menu"),e.push(" oracle setup messaging open hermes gateway setup"),e.push(" oracle setup telegram configure telegram bot token"),e.push(" oracle setup discord configure discord bot token"),e.push(" oracle setup status show configured platforms (no secrets)"),e.push(" oracle setup gateway start/status hermes gateway"),e.push(" /setup same menu inside chat"),e.push(""),e.push("notes:"),e.push(" tokens stay in the hermes profile .env on this machine"),e.push(" oracle never prints bot tokens or app secrets"),e.push(" after setup: hermes -p oracle gateway restart"),e.join(`
|
|
2
|
+
`)+`
|
|
3
|
+
`}import f from"node:fs";import se from"node:os";import C from"node:path";import Q from"node:fs";import ee from"node:os";import y from"node:path";import{fileURLToPath as te}from"node:url";var re=y.dirname(te(import.meta.url)),Ae=y.resolve(re,"../..");function S(){return process.env.ORACLE_FAKE_HOME||ee.homedir()}function ne(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function _(){return ne()?process.env.ORACLE_CONFIG_DIR||y.join(S(),".config","oracle"):y.join(S(),".config","oracle")}function k(){return process.env.HERMES_HOME?y.resolve(process.env.HERMES_HOME):y.join(S(),".hermes")}function h(t){return Q.mkdirSync(t,{recursive:!0}),t}var oe=/(TOKEN|SECRET|PASSWORD|KEY|AUTH|PRIVATE|MNEMONIC|SEED)/i;function b(t="oracle"){return C.join(k(),"profiles",t,".env")}function ie(t){let r={};for(let e of String(t||"").split(/\r?\n/)){let n=e.trim();if(!n||n.startsWith("#"))continue;let s=n.indexOf("=");if(s<=0)continue;let i=n.slice(0,s).trim(),o=n.slice(s+1).trim();(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),r[i]=o}return r}function ae(t="oracle"){let r=b(t);return f.existsSync(r)?ie(f.readFileSync(r,"utf8")):{}}function B(t,r,e){if(!r||oe.test(r)===!1&&/[^A-Z0-9_]/.test(r),!/^[A-Z][A-Z0-9_]*$/.test(r)){let c=new Error(`invalid env key '${r}'`);throw c.code="BAD_KEY",c}if(e==null||String(e).trim()===""){let c=new Error(`empty value for ${r}`);throw c.code="EMPTY",c}let n=b(t);h(C.dirname(n));let s=f.existsSync(n)?f.readFileSync(n,"utf8"):"",i=s?s.split(/\r?\n/):[],o=[],a=!1,u=`${r}=${String(e)}`;for(let c of i)c.startsWith(`${r}=`)?(o.push(u),a=!0):(c.length||o.length)&&o.push(c);for(a||(o.length&&o[o.length-1]!==""&&o.push(""),o.push(u));o.length&&o[o.length-1]==="";)o.pop();o.push(""),f.writeFileSync(n,o.join(`
|
|
4
|
+
`),{mode:384});try{f.chmodSync(n,384)}catch{}return{path:n,key:r,set:!0}}function A(t="oracle"){let r=ae(t),e={};for(let n of T()){if(!n.required.length){e[n.key]="manual";continue}let s=n.required.filter(i=>!String(r[i]||"").trim());e[n.key]=s.length?"unset":"ready"}return{profile:t,statuses:e,envPath:b(t)}}function P(t="oracle"){let{statuses:r}=A(t);return W({profile:t,statuses:r})}function V(t,r,e,n={}){let s=v(r);if(!s){let o=new Error(`unknown platform '${r}'`);throw o.code="UNKNOWN_PLATFORM",o}if(!s.required.length){let o=new Error(`${s.key} uses hermes interactive setup (oracle setup messaging)`);throw o.code="NEEDS_INTERACTIVE",o}let i=s.required[0];B(t,i,e);for(let[o,a]of Object.entries(n||{}))a!=null&&String(a).trim()&&B(t,o,a);return{platform:s.key,set:s.required,profile:t,path:b(t)}}function ue(){return C.join(_(),"setup-state.json")}function R(t={}){h(_());let r=ue(),e={};if(f.existsSync(r))try{e=JSON.parse(f.readFileSync(r,"utf8"))}catch{e={}}let n={...e,...t,updatedAt:new Date().toISOString(),host:se.hostname()};return f.writeFileSync(r,JSON.stringify(n,null,2)+`
|
|
5
|
+
`,{mode:384}),n}import l from"node:fs";import p from"node:path";import{createHash as ce}from"node:crypto";import{spawnSync as E}from"node:child_process";var pe="0.19.0",Y=`hermes-agent==${pe}`,D=[3,11],$=[3,14],x="3.13",M="0.12.1",N=Object.freeze({posix:Object.freeze({url:`https://github.com/astral-sh/uv/releases/download/${M}/uv-installer.sh`,sha256:"d3f5412d38c99f9d024901843bf98206f0d2c6dbe64df40d0b740e2751ca62c1"}),windows:Object.freeze({url:`https://github.com/astral-sh/uv/releases/download/${M}/uv-installer.ps1`,sha256:"b9ec035151bfbb11d616dbd69886498d885551489eddf095ea3c0ad59f640eb0"})});function le(t,{windows:r=process.platform==="win32"}={}){let e=Buffer.isBuffer(t)?t:Buffer.from(t),n=r?N.windows:N.posix,s=ce("sha256").update(e).digest("hex"),i=e.toString("utf8");return s===n.sha256&&i.length>=1e3&&i.includes(M)}function g(){return p.join(_(),"runtime")}function G(){return p.join(g(),"venv")}function U(t){let r=process.platform==="win32"?"Scripts":"bin",e=process.platform==="win32"?`${t}.exe`:t;return p.join(G(),r,e)}function L(){return U("hermes")}function fe(){let t=U("python3");return l.existsSync(t)?t:U("python")}function O(){return p.join(g(),"uv",process.platform==="win32"?"uv.exe":"uv")}function w(t){let r=process.platform==="win32"&&!p.extname(t)?["",".exe",".cmd",".bat"]:[""];for(let e of(process.env.PATH||"").split(p.delimiter))if(e)for(let n of r){let s=p.join(e,`${t}${n}`);try{if(l.existsSync(s))return s}catch{}}return null}function de(t){let r=/Python (\d+)\.(\d+)\.(\d+)/.exec(t||"");return r?[Number(r[1]),Number(r[2]),Number(r[3])]:null}function me(t){if(!t)return!1;let[r,e]=t;return!(r<D[0]||r===D[0]&&e<D[1]||r>$[0]||r===$[0]&&e>=$[1])}function he(){let t=[process.env.ORACLE_PYTHON,"python3.13","python3.12","python3.11","python3","python"].filter(Boolean);for(let r of t){let e=p.isAbsolute(r)?l.existsSync(r)?r:null:w(r);if(!e)continue;let n=E(e,["--version"],{encoding:"utf8",timeout:15e3}),s=de(`${n.stdout||""}${n.stderr||""}`);if(me(s))return{bin:e,version:s.join("."),source:"host"}}return null}function ge(){return process.env.ORACLE_UV_BIN||w("uv")||(l.existsSync(p.join(S(),".local","bin","uv"))?p.join(S(),".local","bin","uv"):null)||(l.existsSync(O())?O():null)}function ye(t,r){let e=["const fs=require('node:fs');","const [url,dest]=process.argv.slice(1);","fetch(url).then(r=>{if(!r.ok)throw new Error('http '+r.status);return r.arrayBuffer()})",".then(b=>fs.writeFileSync(dest,Buffer.from(b)))",".catch(e=>{console.error(e.message);process.exit(1)});"].join("");return E(process.execPath,["-e",e,t,r],{encoding:"utf8",timeout:2*6e4})}function Se({quiet:t=!1}={}){let r=ge();if(r)return{ok:!0,bin:r,reused:!0};h(g());let e=process.platform==="win32",n=p.join(g(),e?"uv-install.ps1":"uv-install.sh"),s=e?N.windows:N.posix,i=ye(s.url,n);if(i.status!==0)return{ok:!1,reason:`could not download the uv installer (${i.status})`,stderr:(i.stderr||"").slice(-800)};let o=l.readFileSync(n);if(!le(o,{windows:e}))return{ok:!1,reason:`uv ${M} installer checksum mismatch`};let a=p.dirname(O());h(a);let u=e?w("powershell.exe")||w("powershell"):w("sh")||"/bin/sh";if(!u)return{ok:!1,reason:e?"PowerShell not found":"sh not found"};let d=E(u,e?["-NoProfile","-ExecutionPolicy","Bypass","-File",n]:[n],{stdio:t?"pipe":"inherit",encoding:"utf8",timeout:5*6e4,env:{...process.env,UV_INSTALL_DIR:a,UV_NO_MODIFY_PATH:"1"}});return d.status!==0||!l.existsSync(O())?{ok:!1,reason:`uv install failed (${d.status})`,stderr:(d.stderr||"").slice(-800)}:{ok:!0,bin:O(),reused:!1}}function F({quiet:t=!1}={}){let r=Se({quiet:t});if(!r.ok)return r;let e=r.bin,n={...process.env,UV_PYTHON_INSTALL_DIR:p.join(g(),"python"),UV_CACHE_DIR:p.join(g(),"cache")},s=E(e,["python","install","--no-bin",x],{stdio:t?"pipe":"inherit",encoding:"utf8",timeout:15*6e4,env:n});if(s.status!==0)return{ok:!1,reason:`uv python install ${x} failed (${s.status})`,stderr:(s.stderr||"").slice(-800)};let i=E(e,["python","find",x],{encoding:"utf8",timeout:6e4,env:n}),o=(i.stdout||"").trim().split(/\r?\n/)[0];return i.status!==0||!o||!l.existsSync(o)?{ok:!1,reason:`uv could not locate python ${x}`}:{ok:!0,bin:o,version:x,source:"uv"}}function z(){if(process.env.ORACLE_HERMES_BIN)return{ok:!0,bin:process.env.ORACLE_HERMES_BIN,source:"env"};let t=w("hermes");if(t)return{ok:!0,bin:t,source:"path"};let r=L();return l.existsSync(r)?{ok:!0,bin:r,source:"managed"}:{ok:!1,bin:null,source:null}}function I(t,r,{quiet:e}){return E(t,r,{stdio:e?"pipe":"inherit",encoding:"utf8",timeout:20*6e4})}function X({quiet:t=!1,upgrade:r=!1}={}){let e=he();if(!e){let c=F({quiet:t});if(c.ok)e={bin:c.bin,version:c.version,source:"uv"};else return{ok:!1,reason:`no supported python found (need 3.11-3.13) and uv could not provide one: ${c.reason}. install uv (https://docs.astral.sh/uv) or python 3.13, then re-run 'oracle bootstrap'`}}h(g());let n=G();if(l.existsSync(L())&&!r)return{ok:!0,bin:L(),reused:!0};if(!l.existsSync(p.join(n,"pyvenv.cfg"))){let c=I(e.bin,["-m","venv",n],{quiet:t});if(c.status!==0&&e.source!=="uv"){l.rmSync(n,{recursive:!0,force:!0});let d=F({quiet:t});if(d.ok)e={bin:d.bin,version:d.version,source:"uv"},c=I(e.bin,["-m","venv",n],{quiet:t});else return{ok:!1,reason:`python -m venv failed (${c.status}) and uv fallback failed: ${d.reason}`,stderr:(c.stderr||"").slice(-800)}}if(c.status!==0)return{ok:!1,reason:`isolated python -m venv failed (${c.status})`,stderr:(c.stderr||"").slice(-800)}}let i=fe();if(!l.existsSync(i))return{ok:!1,reason:`venv python missing at ${i}`};let o=["-m","pip","install","--disable-pip-version-check"];r&&o.push("--upgrade"),o.push(Y);let a=I(i,o,{quiet:t});if(a.status!==0)return{ok:!1,reason:`pip install ${Y} failed (${a.status})`,stderr:(a.stderr||"").slice(-1200)};let u=L();return l.existsSync(u)?{ok:!0,bin:u,reused:!1,python:e.version}:{ok:!1,reason:`hermes entrypoint not found after install (${u})`}}function H(){return["oracle setup \u2014 wire messaging + local agent surface",""," oracle setup menu + platform status"," oracle setup status same, machine-friendly with --json"," oracle setup messaging open hermes gateway setup wizard"," oracle setup telegram set TELEGRAM_BOT_TOKEN for profile"," oracle setup discord set DISCORD_BOT_TOKEN for profile"," oracle setup slack set slack tokens"," oracle setup <platform> any supported hermes platform"," oracle setup gateway [status|restart|start|stop]"," oracle setup profile [name] default: oracle","","chat:"," /setup"," /setup telegram"," /setup status","","tokens stay local in ~/.hermes/profiles/<profile>/.env","oracle never prints secrets."].join(`
|
|
6
|
+
`)}function Ee(t){let r=t.indexOf("--profile");if(r>=0&&t[r+1])return t[r+1];let e=t.indexOf("-p");return e>=0&&t[e+1]?t[e+1]:process.env.ORACLE_PROFILE||"oracle"}function ve(t){let r=[];for(let e=0;e<t.length;e++){if(t[e]==="--profile"||t[e]==="-p"){e+=1;continue}r.push(t[e])}return r}function q(t,{inherit:r=!0,env:e=process.env}={}){let n=z();if(!n.ok&&process.stdin.isTTY&&process.stdout.isTTY&&process.env.ORACLE_NO_BOOTSTRAP!=="1"){process.stdout.write(`setting up oracle's local messaging runtime (one time)
|
|
7
|
+
|
|
8
|
+
`);let i=X();i.ok&&(n={ok:!0,bin:i.bin})}if(!n.ok)return process.stderr.write(`oracle setup needs the local runtime
|
|
9
|
+
run: oracle bootstrap
|
|
10
|
+
`),1;let s=we(n.bin,t,{stdio:r?"inherit":"pipe",encoding:"utf8",env:e});return s.error?(process.stderr.write(`oracle setup: failed to run hermes: ${s.error.message}
|
|
11
|
+
`),1):(r||(s.stdout&&process.stdout.write(s.stdout),s.stderr&&process.stderr.write(s.stderr)),typeof s.status=="number"?s.status:1)}async function Z(t){if(!m.isTTY||typeof m.setRawMode!="function"){let r=new Error("interactive token entry requires a tty");throw r.code="NO_TTY",r}return J.write(`${t}: `),new Promise((r,e)=>{let n="",s=()=>{m.off("data",i),m.setRawMode(!1),m.pause(),J.write(`
|
|
12
|
+
`)},i=o=>{for(let a of String(o)){if(a==="\r"||a===`
|
|
13
|
+
`){s(),r(n.trim());return}if(a===""){s(),e(new Error("cancelled"));return}a==="\x7F"||a==="\b"?n=n.slice(0,-1):n+=a}};m.setRawMode(!0),m.resume(),m.on("data",i)})}async function _e(t,r,e=[]){let n=v(r);if(!n)return process.stderr.write(`oracle setup: unknown platform '${r}'
|
|
14
|
+
`),process.stderr.write(`known: ${T().map(u=>u.key).join(", ")}
|
|
15
|
+
`),1;if(!n.required.length)return process.stdout.write(`opening hermes setup for ${n.key} (interactive)
|
|
16
|
+
`),R({lastPlatform:n.key,profile:t}),q(["-p",t,...n.hermes||["gateway","setup"]]);let s={},i=[];for(let u=0;u<e.length;u++){let c=e[u];if(c==="--token"&&e[u+1]){s.token=e[++u];continue}if(c==="--allowed-users"&&e[u+1]){s.allowedUsers=e[++u];continue}if(c==="--app-token"&&e[u+1]){s.appToken=e[++u];continue}if(c.startsWith("-"))return process.stderr.write(`oracle setup: unknown flag ${c}
|
|
17
|
+
`),1;i.push(c)}let o=s.token||i[0]||"";if(!o)try{o=await Z(`${n.key} bot token`)}catch(u){if(u?.code==="NO_TTY")return process.stderr.write(`oracle setup ${n.key}: pass --token <value> in non-interactive mode
|
|
18
|
+
`),1;throw u}if(!o)return process.stderr.write(`aborted: empty token
|
|
19
|
+
`),1;let a={};if(s.allowedUsers&&(n.key==="telegram"&&(a.TELEGRAM_ALLOWED_USERS=s.allowedUsers),n.key==="discord"&&(a.DISCORD_ALLOWED_USERS=s.allowedUsers),n.key==="slack"&&(a.SLACK_ALLOWED_USERS=s.allowedUsers)),s.appToken&&n.key==="slack"&&(a.SLACK_APP_TOKEN=s.appToken),n.key==="slack"&&!a.SLACK_APP_TOKEN){let u=s.appToken||i[1]||"";if(!u&&process.stdin.isTTY&&(u=await Z("slack app token (xapp-...)")),!u)return process.stderr.write(`slack needs bot token + app token
|
|
20
|
+
`),1;a.SLACK_APP_TOKEN=u}try{let u=V(t,n.key,o,a);return R({lastPlatform:n.key,profile:t,ready:!0}),process.stdout.write(`saved ${n.key} credentials for profile '${t}'
|
|
21
|
+
path: ${u.path}
|
|
22
|
+
next: oracle setup gateway restart
|
|
23
|
+
`),0}catch(u){return process.stderr.write(`oracle setup: ${u.message}
|
|
24
|
+
`),1}}var ze={name:"setup",summary:"configure telegram/discord/slack messaging platforms",group:"read",usage:H(),async run(t){let r=[...t.argv],e=r.includes("--json"),n=Ee(r),s=ve(r).filter(a=>a!=="--json"),i=(s[0]||"menu").toLowerCase(),o=s.slice(1);if(["-h","--help","help"].includes(i))return process.stdout.write(H()+`
|
|
25
|
+
`),0;if(["menu","list","ls"].includes(i))return e?process.stdout.write(JSON.stringify(A(n),null,2)+`
|
|
26
|
+
`):process.stdout.write(P(n)),0;if(["status","show"].includes(i)){let a=A(n);return e?process.stdout.write(JSON.stringify(a,null,2)+`
|
|
27
|
+
`):(process.stdout.write(P(n)),process.stdout.write(`hermes root: ${k()}
|
|
28
|
+
`)),0}if(["messaging","gateway-setup","platforms"].includes(i))return R({lastAction:"messaging",profile:n}),process.stdout.write(`opening hermes gateway setup wizard...
|
|
29
|
+
`),q(["-p",n,"gateway","setup"]);if(i==="gateway"){let a=(o[0]||"status").toLowerCase();return["status","start","stop","restart","run","install"].includes(a)?q(["-p",n,"gateway",a]):(process.stderr.write(`usage: oracle setup gateway [status|start|stop|restart|run|install]
|
|
30
|
+
`),1)}if(i==="profile"){let a=o[0]||n;return process.stdout.write(`profile: ${a}
|
|
31
|
+
hermes: ${k()}/profiles/${a}
|
|
32
|
+
`),process.stdout.write(P(a)),0}return v(i)?_e(n,i,o):(process.stderr.write(`oracle setup: unknown verb '${i}'
|
|
33
|
+
${H()}
|
|
34
|
+
`),1)}};export{ze as default};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var i={name:"sign",summary:"provision / check the local signer (opt-in)",group:"sign",usage:"oracle sign <init|doctor> ...",async run(r){let e=r.argv[0];return e==="init"?r.dispatchOperator("oracle-agentic-init",r.argv.slice(1),{appendHintOnError:!0}):e==="doctor"?r.dispatchOperator("oracle-agentic-doctor",r.argv.slice(1),{appendHintOnError:!0}):(process.stderr.write(`usage: oracle sign <init|doctor> ...
|
|
2
|
+
oracle sign init provision keys + policy (interactive)
|
|
3
|
+
oracle sign doctor check local signer readiness
|
|
4
|
+
`),1)}};export{i as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e={name:"signer",summary:"loopback signer daemon",group:"sign",usage:"oracle signer [--port N ...]",async run(r){return r.dispatchOperator("oracle-signer",r.argv,{appendHintOnError:!0})}};export{e as default};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
var rn=Object.defineProperty;var z=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var nn=(t,e)=>{for(var r in e)rn(t,r,{get:e[r],enumerable:!0})};import{createHash as sn}from"node:crypto";function Y(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function U(t){return typeof t=="number"&&Number.isFinite(t)}function Be(t){return Number.isInteger(t)&&t>0}function ee(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)ee(e);return Object.freeze(t)}for(let e of Object.keys(t))ee(t[e]);return Object.freeze(t)}function re(t){if(Array.isArray(t))return t.map(re);if(t!=null&&typeof t=="object"){let e={};for(let r of Object.keys(t).sort())e[r]=re(t[r]);return e}return t}function y(t,e,r){t.push({path:e,message:r})}function st(t,e,r,n){for(let s of Object.keys(t))e.has(s)||y(n,r?`${r}.${s}`:s,"unknown field is not allowed")}function Je(t,e,r,n){if(!U(t)||!U(e)||!U(r)||!U(n)||n<=0||t<e||t>r)return!1;let s=(t-e)/n;if(!Number.isFinite(s))return!1;let a=Math.round(s);return Math.abs(s-a)<=1e-9}function te(t,e,r,n){if(Y(t)){if(st(t,new Set(["param"]),e,n),typeof t.param!="string"||!t.param)return y(n,`${e}.param`,"must be a parameter name string"),null;if(!Object.prototype.hasOwnProperty.call(r,t.param))return y(n,`${e}.param`,`unknown parameter "${t.param}"`),null;let s=r[t.param];return!Y(s)||![s.value,s.min,s.max,s.step].every(Be)?(y(n,`${e}.param`,"referenced period parameter value min max and step must be positive integers"),null):{param:t.param}}return Be(t)?t:(y(n,e,"must be a positive integer or {param}"),null)}function De(t,e,r,n){return Y(t)?(st(t,new Set(["param"]),e,n),typeof t.param!="string"||!t.param?(y(n,`${e}.param`,"must be a parameter name string"),null):Object.prototype.hasOwnProperty.call(r,t.param)?{param:t.param}:(y(n,`${e}.param`,`unknown parameter "${t.param}"`),null)):U(t)?t:(y(n,e,"must be a finite number or {param}"),null)}function Ht(t){switch(t.type){case"input":case"constant":return[];case"indicator":return t.input?[t.input]:[];case"compare":case"cross":return[t.left,t.right].filter(Boolean);case"logic":return Array.isArray(t.inputs)?[...t.inputs]:[];default:return[]}}function yn(t){let e=new Map,r=n=>{let s=e.get(n)||0;if(s===1)return!0;if(s===2)return!1;e.set(n,1);let a=t.get(n);if(a){for(let o of Ht(a))if(t.has(o)&&r(o))return!0}return e.set(n,2),!1};for(let n of t.keys())if(r(n))return!0;return!1}function wn(t,e){if(!Y(t))return y(e,"parameters","must be a plain object"),null;let r=Object.keys(t);if(r.length>He)return y(e,"parameters",`too many parameters (max ${He})`),null;let n={};for(let s of r){if(!ze.test(s)){y(e,`parameters.${s}`,"parameter name is malformed");continue}let a=t[s],o=`parameters.${s}`;if(!Y(a)){y(e,o,"must be a plain object");continue}st(a,je,o,e);for(let c of je)c in a||y(e,`${o}.${c}`,"required field is missing");let{value:i,min:l,max:f,step:u}=a;U(l)||y(e,`${o}.min`,"must be a finite number"),U(f)||y(e,`${o}.max`,"must be a finite number"),(!U(u)||u<=0)&&y(e,`${o}.step`,"must be a positive finite number"),U(i)||y(e,`${o}.value`,"must be a finite number"),U(l)&&U(f)&&l>f&&y(e,`${o}.min`,"min must be <= max"),U(i)&&U(l)&&U(f)&&U(u)&&u>0&&(Je(i,l,f,u)||y(e,`${o}.value`,"value must lie on the declared min/max/step grid")),n[s]={value:i,min:l,max:f,step:u}}return n}function gn(t,e,r,n){let s=`nodes.${e}`;if(!Y(t))return y(n,s,"must be a plain object"),null;if(typeof t.type!="string"||!Le[t.type])return y(n,`${s}.type`,"unknown or missing node type"),st(t,hn,s,n),null;switch(st(t,Le[t.type],s,n),(typeof t.id!="string"||!Ve.test(t.id))&&y(n,`${s}.id`,"must be a 1-64 char id starting with alphanumeric"),t.type){case"input":return(typeof t.field!="string"||!an.has(t.field))&&y(n,`${s}.field`,"must be one of open|high|low|close|volume|fundingRate|openInterest"),{id:t.id,type:"input",field:t.field};case"constant":{let a=De(t.value,`${s}.value`,r,n);return{id:t.id,type:"constant",value:a}}case"indicator":{(typeof t.indicator!="string"||!cn.has(t.indicator))&&y(n,`${s}.indicator`,"must be one of sma|ema|rsi|macd|bollinger|atr");let a=t.indicator,o={id:t.id,type:"indicator",indicator:a};if(a==="atr"){"input"in t&&(typeof t.input!="string"||!t.input?y(n,`${s}.input`,"must be a node id string when provided"):o.input=t.input);let i=te(t.period,`${s}.period`,r,n);i!=null&&(o.period=i)}else typeof t.input!="string"||!t.input?y(n,`${s}.input`,"must be a node id string"):o.input=t.input;if((a==="sma"||a==="ema"||a==="rsi"||a==="bollinger"||a==="atr")&&("period"in t,a!=="macd"))if(!("period"in t))y(n,`${s}.period`,"required field is missing");else{let i=te(t.period,`${s}.period`,r,n);i!=null&&(o.period=i)}if(a==="macd"){for(let i of["fastPeriod","slowPeriod","signalPeriod"])if(!(i in t))y(n,`${s}.${i}`,"required field is missing");else{let l=te(t[i],`${s}.${i}`,r,n);l!=null&&(o[i]=l)}"output"in t?dn.has(t.output)?o.output=t.output:y(n,`${s}.output`,"must be line|signal|histogram"):y(n,`${s}.output`,"required field is missing"),"period"in t&&y(n,`${s}.period`,"forbidden for macd"),"stdDev"in t&&y(n,`${s}.stdDev`,"forbidden for macd")}else if(a==="bollinger"){if(!("stdDev"in t))y(n,`${s}.stdDev`,"required field is missing");else{let i=De(t.stdDev,`${s}.stdDev`,r,n);i!=null&&(typeof i=="number"&&i<=0?y(n,`${s}.stdDev`,"must be > 0"):o.stdDev=i)}"output"in t?pn.has(t.output)?o.output=t.output:y(n,`${s}.output`,"must be upper|middle|lower"):y(n,`${s}.output`,"required field is missing");for(let i of["fastPeriod","slowPeriod","signalPeriod"])i in t&&y(n,`${s}.${i}`,`forbidden for ${a}`)}else{"output"in t&&y(n,`${s}.output`,`forbidden for ${a}`),"stdDev"in t&&a!=="bollinger"&&y(n,`${s}.stdDev`,`forbidden for ${a}`);for(let i of["fastPeriod","slowPeriod","signalPeriod"])i in t&&y(n,`${s}.${i}`,`forbidden for ${a}`)}return o}case"compare":return(typeof t.op!="string"||!ln.has(t.op))&&y(n,`${s}.op`,"must be gt|gte|lt|lte|eq"),(typeof t.left!="string"||!t.left)&&y(n,`${s}.left`,"must be a node id"),(typeof t.right!="string"||!t.right)&&y(n,`${s}.right`,"must be a node id"),{id:t.id,type:"compare",op:t.op,left:t.left,right:t.right};case"logic":{if((typeof t.op!="string"||!un.has(t.op))&&y(n,`${s}.op`,"must be and|or|not"),!Array.isArray(t.inputs))return y(n,`${s}.inputs`,"must be an array of node ids"),{id:t.id,type:"logic",op:t.op,inputs:[]};let a=[];for(let o=0;o<t.inputs.length;o++){let i=t.inputs[o];typeof i!="string"||!i?y(n,`${s}.inputs.${o}`,"must be a node id"):a.push(i)}return t.op==="not"?a.length!==1&&y(n,`${s}.inputs`,"not requires exactly one input"):(t.op==="and"||t.op==="or")&&a.length<2&&y(n,`${s}.inputs`,`${t.op} requires at least two inputs`),{id:t.id,type:"logic",op:t.op,inputs:a}}case"cross":return(typeof t.direction!="string"||!fn.has(t.direction))&&y(n,`${s}.direction`,"must be above|below"),(typeof t.left!="string"||!t.left)&&y(n,`${s}.left`,"must be a node id"),(typeof t.right!="string"||!t.right)&&y(n,`${s}.right`,"must be a node id"),{id:t.id,type:"cross",direction:t.direction,left:t.left,right:t.right};default:return null}}function bn(t,e,r){if(!Y(t))return y(e,"risk","must be a plain object"),null;st(t,Fe,"risk",e);for(let d of Fe)(!(d in t)||t[d]==null)&&y(e,`risk.${d}`,"required field is missing");let n={},s=t.maxLeverage;!U(s)||s<=0||s>50?y(e,"risk.maxLeverage","must be a number > 0 and <= 50"):n.maxLeverage=s;let a=t.maxNotionalUsd;!U(a)||a<=0?y(e,"risk.maxNotionalUsd","must be a number > 0"):n.maxNotionalUsd=a;let o=t.positionSizePct;!U(o)||o<=0||o>100?y(e,"risk.positionSizePct","must be a number > 0 and <= 100"):n.positionSizePct=o;let i=t.stopLossPct;!U(i)||i<=0||i>100?y(e,"risk.stopLossPct","must be a number > 0 and <= 100"):n.stopLossPct=i;let l=t.takeProfitPct;!U(l)||l<=0||l>1e3?y(e,"risk.takeProfitPct","must be a number > 0 and <= 1000"):n.takeProfitPct=l;let f=t.cooldownBars;!Number.isInteger(f)||f<0||f>1e5?y(e,"risk.cooldownBars","must be an integer >= 0 and <= 100000"):n.cooldownBars=f;let u=t.maxDailyLossPct;!U(u)||u<=0||u>100?y(e,"risk.maxDailyLossPct","must be a number > 0 and <= 100"):n.maxDailyLossPct=u;let c=t.expiresAt;return!Number.isInteger(c)||c<=0?y(e,"risk.expiresAt","must be an integer epoch milliseconds > 0"):(r.nowMs!==void 0&&(Number.isInteger(r.nowMs)?c<=r.nowMs&&y(e,"risk.expiresAt","must be strictly greater than nowMs"):y(e,"nowMs","must be an integer epoch milliseconds")),n.expiresAt=c),n}function ne(t,e={}){let r=[];if(!Y(t))return y(r,"","strategy must be a plain object"),{ok:!1,errors:r,strategy:null};st(t,Re,"",r);for(let u of Re)(!(u in t)||t[u]==null)&&y(r,u,"required field is missing");t.version!==Wt&&y(r,"version",`must be ${Wt}`),(typeof t.id!="string"||!ze.test(t.id))&&y(r,"id","must match /^[a-z0-9][a-z0-9._-]{0,63}$/"),(typeof t.name!="string"||t.name.length===0||t.name.length>Ce)&&y(r,"name",`must be a non-empty string max ${Ce}`),t.venue!=="hyperliquid"&&y(r,"venue",'must be "hyperliquid"');let n=null;Y(t.market)?(st(t.market,mn,"market",r),(typeof t.market.coin!="string"||t.market.coin.length===0||t.market.coin.length>qe)&&y(r,"market.coin",`must be a non-empty string max ${qe}`),(typeof t.market.interval!="string"||!on.has(t.market.interval))&&y(r,"market.interval","must be a supported interval"),n={coin:t.market.coin,interval:t.market.interval}):y(r,"market","must be a plain object");let s=wn(t.parameters,r),a=null,o=new Map;if(!Array.isArray(t.nodes))y(r,"nodes","must be an array");else if(t.nodes.length>Ue)y(r,"nodes",`too many nodes (max ${Ue})`);else{a=[];for(let u=0;u<t.nodes.length;u++){let c=gn(t.nodes[u],u,s||{},r);c&&(typeof c.id=="string"&&Ve.test(c.id)&&(o.has(c.id)?y(r,`nodes.${u}.id`,`duplicate node id "${c.id}"`):o.set(c.id,c)),a.push(c))}for(let u=0;u<a.length;u++){let c=a[u],d=`nodes.${u}`;for(let m of Ht(c))o.has(m)||y(r,d,`unknown node ref "${m}"`);if(c.type==="indicator"||c.type==="compare"||c.type==="cross")for(let m of Ht(c)){let p=o.get(m);p&&Zt.has(p.type)&&y(r,d,`node ref "${m}" must be numeric`)}if(c.type==="logic")for(let m of Ht(c)){let p=o.get(m);p&&!Zt.has(p.type)&&y(r,d,`node ref "${m}" must be boolean`)}}yn(o)&&y(r,"nodes","graph contains a cycle")}let i=null;if(!Y(t.rules))y(r,"rules","must be a plain object");else{st(t.rules,Qt,"rules",r);for(let u of Qt)u in t.rules||y(r,`rules.${u}`,"required field is missing");i={};for(let u of Qt){let c=t.rules[u];if(c===null){i[u]=null;continue}if(typeof c!="string"||!c){y(r,`rules.${u}`,"must be a node id or null"),i[u]=c;continue}if(!o.has(c)){y(r,`rules.${u}`,`unknown node ref "${c}"`),i[u]=c;continue}let d=o.get(c);Zt.has(d.type)||y(r,`rules.${u}`,`rule must reference a boolean node, not ${d.type}`),i[u]=c}}let l=bn(t.risk,r,e);if(r.length)return{ok:!1,errors:r,strategy:null};let f=ee({version:Wt,id:t.id,name:t.name,venue:"hyperliquid",market:n,parameters:s,nodes:a,rules:i,risk:l});return{ok:!0,errors:[],strategy:f}}function J(t,e={}){let r=ne(t,e);if(!r.ok)throw new yt(r.errors);return r.strategy}function En(t){let e=J(t);return JSON.stringify(re(e))}function wt(t){let e=En(t);return sn("sha256").update(e,"utf8").digest("hex")}function $t(t,e){if(!Y(t))throw new yt([{path:"",message:"strategy must be a plain object"}]);if(!Y(e))throw new yt([{path:"overrides",message:"must be a plain object"}]);let r=J(t),n={};for(let[a,o]of Object.entries(r.parameters))n[a]={value:o.value,min:o.min,max:o.max,step:o.step};let s=[];for(let[a,o]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(n,a)){y(s,a,`unknown parameter "${a}"`);continue}let i=n[a];if(!U(o)){y(s,a,"override must be a finite number");continue}if(!Je(o,i.min,i.max,i.step)){y(s,a,"override must lie on the declared min/max/step grid");continue}n[a]={...i,value:o}}if(s.length)throw new yt(s);return J({version:r.version,id:r.id,name:r.name,venue:r.venue,market:{coin:r.market.coin,interval:r.market.interval},parameters:n,nodes:r.nodes.map(a=>{let o={...a};return Array.isArray(a.inputs)&&(o.inputs=[...a.inputs]),o}),rules:{...r.rules},risk:{...r.risk}})}var Wt,ze,Ve,on,an,cn,ln,un,fn,dn,pn,Zt,Re,mn,je,Qt,Fe,hn,Le,He,Ue,Ce,qe,yt,ut=z(()=>{Wt=1,ze=/^[a-z0-9][a-z0-9._-]{0,63}$/,Ve=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/,on=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),an=new Set(["open","high","low","close","volume","fundingRate","openInterest"]),cn=new Set(["sma","ema","rsi","macd","bollinger","atr"]),ln=new Set(["gt","gte","lt","lte","eq"]),un=new Set(["and","or","not"]),fn=new Set(["above","below"]),dn=new Set(["line","signal","histogram"]),pn=new Set(["upper","middle","lower"]),Zt=new Set(["compare","logic","cross"]),Re=new Set(["version","id","name","venue","market","parameters","nodes","rules","risk"]),mn=new Set(["coin","interval"]),je=new Set(["value","min","max","step"]),Qt=new Set(["entryLong","entryShort","exitLong","exitShort"]),Fe=new Set(["maxLeverage","maxNotionalUsd","positionSizePct","stopLossPct","takeProfitPct","cooldownBars","maxDailyLossPct","expiresAt"]),hn=new Set(["id","type"]),Le={input:new Set(["id","type","field"]),constant:new Set(["id","type","value"]),indicator:new Set(["id","type","indicator","input","period","fastPeriod","slowPeriod","signalPeriod","stdDev","output"]),compare:new Set(["id","type","op","left","right"]),logic:new Set(["id","type","op","inputs"]),cross:new Set(["id","type","direction","left","right"])},He=16,Ue=128,Ce=100,qe=32,yt=class extends Error{constructor(e){let r=e.map(n=>`${n.path}: ${n.message}`);super(`invalid strategy (${e.length} error${e.length===1?"":"s"}): ${r.join("; ")}`),this.name="StrategyValidationError",this.errors=e}}});function Tt(t){if(!Array.isArray(t))throw new TypeError("values must be an array");for(let e=0;e<t.length;e++){let r=t[e];if(typeof r!="number"||!Number.isFinite(r))throw new TypeError(`values[${e}] must be a finite number`)}}function ct(t){if(!Number.isInteger(t)||t<=0)throw new TypeError("period must be a positive integer")}function xn(t){if(!Array.isArray(t))throw new TypeError("bars must be an array");for(let e=0;e<t.length;e++){let r=t[e];if(r==null||typeof r!="object")throw new TypeError(`bars[${e}] must be an object`);for(let n of["o","h","l","c"]){let s=r[n];if(typeof s!="number"||!Number.isFinite(s))throw new TypeError(`bars[${e}].${n} must be a finite number`)}if(r.h<r.l)throw new TypeError(`bars[${e}] high must be >= low`)}}function Ye(t,e){Tt(t),ct(e);let r=new Array(t.length).fill(null);if(t.length<e)return r;let n=0;for(let s=0;s<t.length;s++)n+=t[s],s>=e&&(n-=t[s-e]),s>=e-1&&(r[s]=n/e);return r}function Ut(t,e){Tt(t),ct(e);let r=new Array(t.length).fill(null);if(t.length<e)return r;let n=0;for(let o=0;o<e;o++)n+=t[o];let s=n/e;r[e-1]=s;let a=2/(e+1);for(let o=e;o<t.length;o++)s=a*t[o]+(1-a)*s,r[o]=s;return r}function Ge(t,e){Tt(t),ct(e);let r=new Array(t.length).fill(null);if(t.length<=e)return r;let n=0,s=0;for(let i=1;i<=e;i++){let l=t[i]-t[i-1];l>=0?n+=l:s-=l}let a=n/e,o=s/e;r[e]=Ke(a,o);for(let i=e+1;i<t.length;i++){let l=t[i]-t[i-1],f=l>0?l:0,u=l<0?-l:0;a=(a*(e-1)+f)/e,o=(o*(e-1)+u)/e,r[i]=Ke(a,o)}return r}function Ke(t,e){return t===0&&e===0?50:e===0?100:t===0?0:100-100/(1+t/e)}function Xe(t,e={}){Tt(t);let r=e.fastPeriod,n=e.slowPeriod,s=e.signalPeriod;if(ct(r),ct(n),ct(s),r>=n)throw new TypeError("fastPeriod must be < slowPeriod");let a=Ut(t,r),o=Ut(t,n),i=new Array(t.length).fill(null);for(let c=0;c<t.length;c++)a[c]!=null&&o[c]!=null&&(i[c]=a[c]-o[c]);let l=new Array(t.length).fill(null),f=new Array(t.length).fill(null),u=[];for(let c=0;c<i.length;c++)i[c]!=null&&u.push(c);if(u.length>=s){let c=0;for(let b=0;b<s;b++)c+=i[u[b]];let d=c/s,m=u[s-1];l[m]=d,f[m]=i[m]-d;let p=2/(s+1);for(let b=s;b<u.length;b++){let E=u[b];d=p*i[E]+(1-p)*d,l[E]=d,f[E]=i[E]-d}}return{line:i,signal:l,histogram:f}}function We(t,e={}){Tt(t);let r=e.period,n=e.stdDev;if(ct(r),typeof n!="number"||!Number.isFinite(n)||n<=0)throw new TypeError("stdDev must be a finite number > 0");let s=new Array(t.length).fill(null),a=new Array(t.length).fill(null),o=new Array(t.length).fill(null);if(t.length<r)return{upper:a,middle:s,lower:o};let i=0,l=0;for(let f=0;f<t.length;f++){let u=t[f];if(i+=u,l+=u*u,f>=r){let c=t[f-r];i-=c,l-=c*c}if(f>=r-1){let c=i/r,d=l/r-c*c;d<0&&d>-1e-12&&(d=0);let m=Math.sqrt(d);s[f]=c,a[f]=c+n*m,o[f]=c-n*m}}return{upper:a,middle:s,lower:o}}function Ze(t,e){xn(t),ct(e);let r=new Array(t.length).fill(null);if(t.length<e)return r;let n=new Array(t.length);for(let o=0;o<t.length;o++){let i=t[o];if(o===0)n[o]=i.h-i.l;else{let l=t[o-1].c;n[o]=Math.max(i.h-i.l,Math.abs(i.h-l),Math.abs(i.l-l))}}let s=0;for(let o=0;o<e;o++)s+=n[o];let a=s/e;r[e-1]=a;for(let o=e;o<t.length;o++)a=(a*(e-1)+n[o])/e,r[o]=a;return r}var Qe=z(()=>{});import{createHash as Sn}from"node:crypto";var se,kn,An,Pn,tr,er=z(()=>{se=2,kn="93f9c998260e73756c13871dc1a84dd6cdb26ec6113bd1941f023519939db440",An="68f5b412a9975f04024cf9b9b6209b4bccedd52f176e95f34f786b3f53479c6a",Pn="d2d75085cb3ab02724cd173abfa2bcad99cd7966a69bcaf80312f13e5b7aaa50",tr=Sn("sha256").update(JSON.stringify({version:se,compilerSourceHash:kn,indicatorsSourceHash:An,schemaSourceHash:Pn})).digest("hex")});function G(t){return typeof t=="number"&&Number.isFinite(t)}function _n(t){let e=new Map(t.map(i=>[i.id,i])),r=i=>{switch(i.type){case"indicator":return i.input?[i.input]:[];case"compare":case"cross":return[i.left,i.right];case"logic":return[...i.inputs];default:return[]}},n=new Map,s=new Map;for(let i of t)n.set(i.id,0),s.set(i.id,[]);for(let i of t)for(let l of r(i))e.has(l)&&(s.get(l).push(i.id),n.set(i.id,n.get(i.id)+1));let a=[];for(let[i,l]of n)l===0&&a.push(i);let o=[];for(;a.length;){let i=a.shift();o.push(i);for(let l of s.get(i))n.set(l,n.get(l)-1),n.get(l)===0&&a.push(l)}if(o.length!==t.length)throw new Error("strategy graph is cyclic");return o}function gt(t,e){return t!=null&&typeof t=="object"&&"param"in t?e[t.param].value:t}function In(t,e,r){if(!Array.isArray(t)||t.length===0)throw new TypeError("bars must be a non-empty array");if(!Number.isInteger(e)||e<0||e>=t.length)throw new RangeError("index out of range");let n=null;for(let s=0;s<=e;s++){let a=t[s];if(a==null||typeof a!="object"||Array.isArray(a))throw new TypeError(`bars[${s}] must be an object`);let{t:o,o:i,h:l,l:f,c:u,v:c}=a;if(!G(o)&&(typeof o=="number"&&Number.isFinite(o)),!Number.isFinite(o))throw new TypeError(`bars[${s}].t must be finite`);for(let[d,m]of[["o",i],["h",l],["l",f],["c",u],["v",c]])if(!G(m))throw new TypeError(`bars[${s}].${d} must be a finite number`);for(let[d,m]of[["o",i],["h",l],["l",f],["c",u]])if(!(m>0))throw new TypeError(`bars[${s}].${d} price must be positive`);if(c<0)throw new TypeError(`bars[${s}].v volume must be non-negative`);if(l<Math.max(i,u,f))throw new TypeError(`bars[${s}] high must be >= max(open, close, low)`);if(f>Math.min(i,u,l))throw new TypeError(`bars[${s}] low must be <= min(open, close, high)`);if(n!=null){if(!(o>n))throw new TypeError("bars t must be strictly increasing");if(o-n!==Tn[r])throw new TypeError(`bars t must match ${r} cadence`)}if(n=o,"fundingRate"in a&&a.fundingRate!=null&&!G(a.fundingRate))throw new TypeError(`bars[${s}].fundingRate must be finite when present`);if("openInterest"in a&&a.openInterest!=null){if(!G(a.openInterest))throw new TypeError(`bars[${s}].openInterest must be finite when present`);if(a.openInterest<0)throw new TypeError(`bars[${s}].openInterest must be non-negative`)}}}function ft(t,e,r,n,s,a){if(a.has(t))return a.get(t);let o=e.get(t),i;switch(o.type){case"input":{let l=$n[o.field];i=new Array(s+1);for(let f=0;f<=s;f++){let u=n[f][l];i[f]=u===void 0?null:u}break}case"constant":{let l=gt(o.value,r);i=new Array(s+1).fill(l);break}case"indicator":{let l=o.period!=null?gt(o.period,r):void 0;if(o.indicator==="atr"){let c=[];for(let d=0;d<=s;d++){let m=n[d];c.push({o:m.o,h:m.h,l:m.l,c:m.c})}i=Ze(c,l);break}let u=ft(o.input,e,r,n,s,a).map((c,d)=>{if(c==null||!G(c))throw new TypeError(`indicator input ${o.input} has non-finite value at ${d}`);return c});if(o.indicator==="sma")i=Ye(u,l);else if(o.indicator==="ema")i=Ut(u,l);else if(o.indicator==="rsi")i=Ge(u,l);else if(o.indicator==="macd")i=Xe(u,{fastPeriod:gt(o.fastPeriod,r),slowPeriod:gt(o.slowPeriod,r),signalPeriod:gt(o.signalPeriod,r)})[o.output];else if(o.indicator==="bollinger")i=We(u,{period:l,stdDev:gt(o.stdDev,r)})[o.output];else throw new Error(`unsupported indicator ${o.indicator}`);break}case"compare":{let l=ft(o.left,e,r,n,s,a),f=ft(o.right,e,r,n,s,a);i=new Array(s+1);for(let u=0;u<=s;u++){let c=l[u],d=f[u];if(c==null||d==null||!G(c)||!G(d)){i[u]=!1;continue}switch(o.op){case"gt":i[u]=c>d;break;case"gte":i[u]=c>=d;break;case"lt":i[u]=c<d;break;case"lte":i[u]=c<=d;break;case"eq":i[u]=c===d;break;default:i[u]=!1}}break}case"logic":{let l=o.inputs.map(f=>ft(f,e,r,n,s,a));i=new Array(s+1);for(let f=0;f<=s;f++)if(o.op==="not"){let u=l[0][f];i[f]=u===!0?!1:u===!1}else if(o.op==="and"){let u=!0;for(let c of l)if(c[f]!==!0){u=!1;break}i[f]=u}else if(o.op==="or"){let u=!1;for(let c of l)if(c[f]===!0){u=!0;break}i[f]=u}else i[f]=!1;break}case"cross":{let l=ft(o.left,e,r,n,s,a),f=ft(o.right,e,r,n,s,a);i=new Array(s+1),i[0]=!1;for(let u=1;u<=s;u++){let c=l[u-1],d=f[u-1],m=l[u],p=f[u];if(c==null||d==null||m==null||p==null||!G(c)||!G(d)||!G(m)||!G(p)){i[u]=!1;continue}o.direction==="above"?i[u]=c<=d&&m>p:i[u]=c>=d&&m<p}break}default:throw new Error(`unknown node type ${o.type}`)}return a.set(t,i),i}function K(t,e={}){let r=J(t);e&&Object.keys(e).length&&(r=$t(r,e));let n=new Map(r.nodes.map(m=>[m.id,m])),s=Object.freeze(_n(r.nodes)),a=r.parameters,o=new Set(r.nodes.filter(m=>m.type==="input").map(m=>m.field));if(r.nodes.some(m=>m.type==="indicator"&&m.indicator==="atr"))for(let m of["open","high","low","close"])o.add(m);let i=Object.freeze([...o].sort()),l=wt(r);function f(m,p){let b={};for(let k of s){let P=m.get(k);b[k]=P[p]}let E=k=>k!=null&&b[k]===!0;return{values:b,signals:{entryLong:E(r.rules.entryLong),entryShort:E(r.rules.entryShort),exitLong:E(r.rules.exitLong),exitShort:E(r.rules.exitShort)}}}function u(m,p){In(m,p,r.market.interval);let b=new Map;for(let E of s)ft(E,n,a,m,p,b);return b}function c(m,p){return f(u(m,p),p)}function d(m){if(!Array.isArray(m)||m.length===0)throw new TypeError("bars must be a non-empty array");let p=m.length-1,b=u(m,p);return Object.freeze(m.map((E,k)=>Object.freeze(f(b,k))))}return Object.freeze({strategy:r,strategyHash:l,compilerVersion:_t,compilerHash:dt,requiredSeries:i,nodeOrder:s,evaluate:c,evaluateAll:d})}var _t,dt,$n,Tn,pt=z(()=>{ut();Qe();er();_t=se,dt=tr,$n=Object.freeze({open:"o",high:"h",low:"l",close:"c",volume:"v",fundingRate:"fundingRate",openInterest:"openInterest"}),Tn=Object.freeze({"1m":6e4,"3m":18e4,"5m":3e5,"15m":9e5,"30m":18e5,"1h":36e5,"2h":72e5,"4h":144e5,"8h":288e5,"12h":432e5,"1d":864e5})});import{createHash as On}from"node:crypto";function vn(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function tt(t){return typeof t=="number"&&Number.isFinite(t)}function oe(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)oe(e);return Object.freeze(t)}for(let e of Object.keys(t))oe(t[e]);return Object.freeze(t)}function Ct(t){if(Array.isArray(t))return t.map(Ct);if(t!=null&&typeof t=="object"){let e={};for(let r of Object.keys(t).sort())e[r]=Ct(t[r]);return e}return t}function ie(t,e="result"){if(typeof t=="number"){if(!Number.isFinite(t))throw new Error(`non-finite backtest result at ${e}`);return}if(!(t==null||typeof t!="object")){if(Array.isArray(t)){t.forEach((r,n)=>ie(r,`${e}[${n}]`));return}for(let[r,n]of Object.entries(t))ie(n,`${e}.${r}`)}}function nr(t){if(!Array.isArray(t)||t.length===0)throw new TypeError("bars must be a non-empty array");let e=null;for(let r=0;r<t.length;r++){let n=t[r];if(n==null||typeof n!="object"||Array.isArray(n))throw new TypeError(`bars[${r}] must be an object`);let{t:s,o:a,h:o,l:i,c:l,v:f}=n;if(!tt(s))throw new TypeError(`bars[${r}].t must be finite`);for(let[u,c]of[["o",a],["h",o],["l",i],["c",l],["v",f]])if(!tt(c))throw new TypeError(`bars[${r}].${u} must be a finite number`);for(let[u,c]of[["o",a],["h",o],["l",i],["c",l]])if(!(c>0))throw new TypeError(`bars[${r}].${u} price must be positive`);if(f<0)throw new TypeError(`bars[${r}].v volume must be non-negative`);if(o<Math.max(a,l,i))throw new TypeError(`bars[${r}] high must be >= max(open, close, low)`);if(i>Math.min(a,l,o))throw new TypeError(`bars[${r}] low must be <= min(open, close, high)`);if(e!=null&&!(s>e))throw new TypeError("bars t must be strictly increasing");if(e=s,"fundingRate"in n&&n.fundingRate!=null&&!tt(n.fundingRate))throw new TypeError(`bars[${r}].fundingRate must be finite when present`);if("fundingPaymentRate"in n&&n.fundingPaymentRate!=null&&!tt(n.fundingPaymentRate))throw new TypeError(`bars[${r}].fundingPaymentRate must be finite when present`);if("openInterest"in n&&n.openInterest!=null&&!tt(n.openInterest))throw new TypeError(`bars[${r}].openInterest must be finite when present`)}}function It(t){if(!Array.isArray(t))throw new TypeError("bars must be an array");return t.length>0&&nr(t),On("sha256").update(JSON.stringify(Ct(t)),"utf8").digest("hex")}function Mn(t){if(t==null&&(t={}),!vn(t))throw new TypeError("options must be a plain object");let e={...Nn},r=new Set(["initialEquityUsd","takerFeeBps","builderFeeBps","slippageBps","latencyBars","maxVolumeParticipationPct","nowMs"]);for(let n of Object.keys(t))if(!r.has(n))throw new TypeError(`unknown option "${n}"`);if("initialEquityUsd"in t){if(!tt(t.initialEquityUsd)||t.initialEquityUsd<=0)throw new TypeError("initialEquityUsd must be a positive finite number");e.initialEquityUsd=t.initialEquityUsd}for(let n of["takerFeeBps","builderFeeBps","slippageBps"])if(n in t){let s=t[n];if(!tt(s)||s<0)throw new TypeError(`${n} must be a finite number >= 0`);if(n==="slippageBps"?s>=1e4:s>1e4)throw new TypeError(`${n} exceeds its safe basis-point bound`);e[n]=s}if("latencyBars"in t){let n=t.latencyBars;if(!Number.isInteger(n)||n<1)throw new TypeError("latencyBars must be an integer >= 1");e.latencyBars=n}if("maxVolumeParticipationPct"in t){let n=t.maxVolumeParticipationPct;if(!tt(n)||n<=0||n>100)throw new TypeError("maxVolumeParticipationPct must be in (0,100]");e.maxVolumeParticipationPct=n}if("nowMs"in t){if(!Number.isInteger(t.nowMs))throw new TypeError("nowMs must be an integer epoch milliseconds");e.nowMs=t.nowMs}return e}function qt(t){return t/1e4}function Rn(t,e,r){let n=qt(r);return e==="long"?t*(1+n):t*(1-n)}function jn(t,e,r){let n=qt(r);return e==="long"?t*(1-n):t*(1+n)}function rr(t,e,r){let n=Math.abs(t)*qt(e),s=Math.abs(t)*qt(r);return{taker:n,builder:s,total:n+s}}function Fn(t,e){let r=t*(e.positionSizePct/100)*e.maxLeverage;return Math.min(r,e.maxNotionalUsd)}function Ln(t,e,r){let n=r/100;return e==="long"?t*(1-n):t*(1+n)}function Hn(t,e,r){let n=r/100;return e==="long"?t*(1+n):t*(1-n)}function Un(t,e,r,n){if(!(r>0))return e==="long"?0:Number.POSITIVE_INFINITY;let s=Math.min(.99,1/(2*r)+n/1e4);return e==="long"?t*(1-1/r)/(1-s):t*(1+1/r)/(1+s)}function Cn(t,e,r){return e==="long"?t.l<=r:t.h>=r}function qn(t,e,r){return e==="long"?t.h>=r:t.l<=r}function Bn(t,e,r){return e==="long"?t.l<=r:t.h>=r}function Ot(t,e){for(let r of t.requiredSeries)if(["fundingRate","openInterest"].includes(r)&&!e.every(n=>tt(n?.[r])))throw new Error(`strategy required series is absent: ${r}`)}function Dn(t){if(t.length<3)return 0;let e=[];for(let o=1;o<t.length;o++){let i=t[o-1].equity,l=t[o].equity;i>0&&e.push((l-i)/i)}if(e.length<2)return 0;let r=0;for(let o of e)r+=o;let n=r/e.length,s=0;for(let o of e)s+=(o-n)**2;let a=Math.sqrt(s/(e.length-1));return a>0?n/a:0}function zn(t){let e=-1/0,r=0;for(let n of t){let s=n.equity;if(s>e&&(e=s),e>0){let a=(e-s)/e*100;a>r&&(r=a)}}return r}function lt(t,e,r={}){let n=Mn(r);nr(e);let s=It(e);n.nowMs!==void 0&&J(t,{nowMs:n.nowMs});let a=K(t);if(Ot(a,e),n.nowMs!==void 0&&a.strategy.risk.expiresAt<=n.nowMs)throw new Error("strategy is expired: risk.expiresAt must be strictly greater than nowMs");let o=a.strategy.risk,i=a.evaluateAll(e),l=n.latencyBars,f=n.slippageBps,u=n.takerFeeBps,c=n.builderFeeBps,d=n.initialEquityUsd,m=0,p=0,b=0,E=0,k=0,P=[],T=[],x=[],R=[],_=[],w=null,V=0,it=null,at=d,W=!1,h=0,A=0,N=[],j=new Array(e.length).fill(0);function F(g){N.push(g)}function I(g){let $=e[g].v*(n.maxVolumeParticipationPct/100);return Math.max(0,$-j[g])}function v(g){if(!w)return d;let $=w.side==="long"?(g-w.entryPrice)*w.qty:(w.entryPrice-g)*w.qty;return d+$}function B(g,$,S){let L=S.o,O=Fn(d,o);if(!(O>0)||!(L>0))return;let H=Rn(L,$,f),M=O/H,q=I(g),At=H*q;if(M>q){x.push({kind:"entry",barIndex:g,time:S.t,side:$,requestedNotionalUsd:O,maxFillNotionalUsd:At,reason:"volume_participation"});return}j[g]+=M;let Q=Math.abs(H-L)*M,nt=rr(O,u,c);d-=nt.total,m+=nt.taker,p+=nt.builder,E+=Q,k+=O,w={lifecycleEpoch:++A,side:$,entryBarIndex:g,entryReferencePrice:L,entryPrice:H,qty:M,notionalUsd:O,stop:Ln(H,$,o.stopLossPct),take:Hn(H,$,o.takeProfitPct),liq:Un(H,$,o.maxLeverage,u+c),entryFees:nt.taker,entryBuilderFees:nt.builder,entrySlippageUsd:Q,fundingAccrued:0}}function C(g,$,S,L){if(!w)return!1;let O=w.side,H=$,M=H;S!=="liquidation"&&L&&(M=jn(H,O,f));let q=w.qty,At=q*M;if(S!=="liquidation"){let Me=I(g),en=M*Me;if(q>Me)return x.push({kind:"exit",barIndex:g,time:e[g].t,side:O,requestedNotionalUsd:At,maxFillNotionalUsd:en,reason:"volume_participation",triggerReason:S}),!1;j[g]+=q}let Q=rr(At,u,c),nt=S==="liquidation"?0:Math.abs(M-H)*q,Pt,Xt;O==="long"?(Pt=(H-w.entryReferencePrice)*q,Xt=(M-w.entryPrice)*q):(Pt=(w.entryReferencePrice-H)*q,Xt=(w.entryPrice-M)*q),d+=Xt,d-=Q.total,m+=Q.taker,p+=Q.builder,E+=nt,k+=At;let tn={side:O,entryBarIndex:w.entryBarIndex,entryTime:e[w.entryBarIndex].t,entryPrice:w.entryPrice,exitBarIndex:g,exitTime:e[g].t,exitPrice:M,exitReason:S,qty:q,notionalUsd:w.notionalUsd,grossPnlUsd:Pt,feesUsd:w.entryFees+Q.taker,builderFeesUsd:w.entryBuilderFees+Q.builder,fundingUsd:w.fundingAccrued,slippageUsd:w.entrySlippageUsd+nt,netPnlUsd:Pt-(w.entryFees+Q.taker+w.entryBuilderFees+Q.builder)-w.fundingAccrued-(w.entrySlippageUsd+nt)};return P.push(tn),S==="liquidation"&&T.push({barIndex:g,time:e[g].t,side:O,price:M,tradeIndex:P.length-1}),w=null,A+=1,h=g+1+(o.cooldownBars||0),!0}function Z(g,$,S,L){let O=g+1;if(O>=e.length)return;N.some(M=>M.kind==="exit"&&M.side===$&&M.fillBar===O&&M.epoch===L)||F({kind:"exit",side:$,signalBar:g,fillBar:O,reason:S,epoch:L})}function jt(g){let $=N.filter(S=>S.fillBar===g);for(let S=N.length-1;S>=0;S--)N[S].fillBar===g&&N.splice(S,1);$.sort((S,L)=>{let O=H=>H.kind==="exit"?0:1;return O(S)-O(L)});for(let S of $)if(S.kind==="exit"){if(!w||w.side!==S.side||w.lifecycleEpoch!==S.epoch)continue;let L=S.reason||"rule";C(g,e[g].o,L,!0)||Z(g,S.side,L,S.epoch)}else if(S.kind==="entry"){if(w||S.epoch!==A||g<h)continue;B(g,S.side,e[g])}}function Ft(g){if(!w)return;let $=e[g],S=$.fundingPaymentRate;if(S==null||!tt(S)||S===0)return;let L=Math.abs(w.qty*$.c),O=S*L;w.side==="long"?(d-=O,w.fundingAccrued+=O,b+=O):(d+=O,w.fundingAccrued-=O,b-=O)}function Lt(g){if(!w)return;let $=e[g].o;(w.side==="long"?$<=w.liq:$>=w.liq)&&C(g,$,"liquidation",!1)}function _e(g){if(!w)return;let $=e[g],S=w.side,L=Bn($,S,w.liq),O=Cn($,S,w.stop),H=qn($,S,w.take),M=q=>S==="long"?Math.min(q,$.o):Math.max(q,$.o);if(L){C(g,M(w.liq),"liquidation",!1);return}if(O&&H){C(g,M(w.stop),"stop_loss",!0)||Z(g,S,"stop_loss",w.lifecycleEpoch);return}if(O){C(g,M(w.stop),"stop_loss",!0)||Z(g,S,"stop_loss",w.lifecycleEpoch);return}H&&(C(g,w.take,"take_profit",!0)||Z(g,S,"take_profit",w.lifecycleEpoch))}for(let g=0;g<e.length;g++){let $=Math.floor(e[g].t/864e5);$!==it&&(it=$,at=v(e[g].o),W=!1),Lt(g),jt(g),_e(g),Ft(g),!W&&v(e[g].c)<=at*(1-o.maxDailyLossPct/100)&&(W=!0,R.push({type:"daily_loss_limit",barIndex:g,time:e[g].t,message:"daily loss limit reached; new entries blocked for UTC day"}));let S=i[g].signals,L=g+l;if(w)(w.side==="long"&&S.exitLong===!0||w.side==="short"&&S.exitShort===!0)&&L<e.length&&(N.some(q=>q.kind==="exit"&&q.side===w.side&&q.fillBar===L&&q.epoch===w.lifecycleEpoch)||F({kind:"exit",side:w.side,signalBar:g,fillBar:L,reason:"rule",epoch:w.lifecycleEpoch}));else{let H=S.entryLong===!0,M=S.entryShort===!0;H&&M?R.push({type:"conflicting_entry_signals",barIndex:g,time:e[g].t,message:"conflicting entry signals; no position opened"}):!W&&(H||M)&&L<e.length&&g>=h&&F({kind:"entry",side:H?"long":"short",signalBar:g,fillBar:L,epoch:A})}let O=d;w&&(V+=1,O=v(e[g].c)),_.push({barIndex:g,time:e[g].t,equity:O,positionSide:w?w.side:null})}let Ie=null;if(w){let g=e.length-1;if(C(g,e[g].c,"end_of_data",!0))_[g]={barIndex:g,time:e[g].t,equity:d,positionSide:null};else{let S=v(e[g].c);Ie={side:w.side,entryBarIndex:w.entryBarIndex,entryTime:e[w.entryBarIndex].t,entryPrice:w.entryPrice,qty:w.qty,notionalUsd:w.notionalUsd,markPrice:e[g].c,markedEquityUsd:S},R.push({type:"open_position_at_end",barIndex:g,time:e[g].t,message:"end-of-data exit missed; position remains open and marked"})}}let Oe=(w?v(e[e.length-1].c):d)-n.initialEquityUsd,Xr=Oe/n.initialEquityUsd*100,Ne=0,Jt=0,Kt=0;for(let g of P)g.netPnlUsd>0?(Ne+=1,Jt+=g.netPnlUsd):g.netPnlUsd<0&&(Kt+=-g.netPnlUsd);let Yt=P.length,Wr=Yt===0?0:Ne/Yt,Gt=0;Kt>0?Gt=Jt/Kt:Jt>0&&(Gt=1e12);let Zr={netPnlUsd:Oe,netPnlPct:Xr,maxDrawdownPct:zn(_),winRate:Wr,profitFactor:Gt,tradeCount:Yt,sharpe:Dn(_),turnoverUsd:k,exposurePct:V/e.length*100},Qr={initialEquityUsd:n.initialEquityUsd,takerFeeBps:n.takerFeeBps,builderFeeBps:n.builderFeeBps,slippageBps:n.slippageBps,latencyBars:n.latencyBars,maxVolumeParticipationPct:n.maxVolumeParticipationPct},ve={barsHash:s,strategyHash:a.strategyHash,compilerHash:dt,compilerVersion:_t,config:Qr,trades:P,equityCurve:_,metrics:Zr,costs:{feesUsd:m,builderFeesUsd:p,fundingUsd:b,slippageUsd:E},liquidations:T,missedFills:x,openPositionAtEnd:Ie,flags:R};return ie(ve),oe(Ct(ve))}var Nn,Bt=z(()=>{pt();ut();Nn=Object.freeze({initialEquityUsd:1e4,takerFeeBps:3.5,builderFeeBps:2,slippageBps:2,latencyBars:1,maxVolumeParticipationPct:100})});import{createHash as Vn}from"node:crypto";function et(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function bt(t){return typeof t=="number"&&Number.isFinite(t)}function le(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)le(e);return Object.freeze(t)}for(let e of Object.keys(t))le(t[e]);return Object.freeze(t)}function mt(t){if(Array.isArray(t))return t.map(mt);if(t!=null&&typeof t=="object"){let e={};for(let r of Object.keys(t).sort())e[r]=mt(t[r]);return e}return t}function ae(t){return{netPnlUsd:t.metrics.netPnlUsd,netPnlPct:t.metrics.netPnlPct,maxDrawdownPct:t.metrics.maxDrawdownPct,winRate:t.metrics.winRate,profitFactor:t.metrics.profitFactor,tradeCount:t.metrics.tradeCount,sharpe:t.metrics.sharpe,turnoverUsd:t.metrics.turnoverUsd,exposurePct:t.metrics.exposurePct}}function sr(t){return{feesUsd:t.costs.feesUsd,builderFeesUsd:t.costs.builderFeesUsd,fundingUsd:t.costs.fundingUsd,slippageUsd:t.costs.slippageUsd}}function Kn(t){return(t.feesUsd||0)+(t.builderFeesUsd||0)+Math.max(0,t.fundingUsd||0)+(t.slippageUsd||0)}function Yn(t){let e=0;for(let r of t.trades)r.grossPnlUsd>0&&(e+=r.grossPnlUsd);return e}function Gn(t,e,r){return!(!t||t.tradeCount<Math.max(1,Math.min(r,3))||!(t.netPnlUsd>0)||!(t.profitFactor>1)||!(t.maxDrawdownPct<=e.maxDailyLossPct))}function ir(t){if(!et(t))throw new TypeError("evidence artifact must be a plain object");if(!Jn.includes(t.status))throw new TypeError("evidence artifact status is invalid");for(let e of["strategyHash","compilerHash","barsHash"])if(typeof t[e]!="string"||!/^[0-9a-f]{64}$/.test(t[e]))throw new TypeError(`evidence artifact ${e} must be a sha256 hash`);if(!et(t.split))throw new TypeError("evidence artifact split required");if(!Array.isArray(t.flags))throw new TypeError("evidence artifact flags must be an array");if(!et(t.walkForward)||!Array.isArray(t.walkForward.windows))throw new TypeError("evidence artifact walkForward windows required");if(t.status==="pass_live_eligible"&&(!et(t.train)||!et(t.holdout)))throw new TypeError("live-eligible evidence artifact requires train and holdout facts");return mt({barsHash:t.barsHash,compilerHash:t.compilerHash,flags:t.flags.map(e=>mt(e)),holdout:t.holdout??null,split:t.split,status:t.status,strategyHash:t.strategyHash,train:t.train??null,walkForward:{passRate:t.walkForward.passRate,windowsRun:t.walkForward.windowsRun??t.walkForward.windows.length,windows:t.walkForward.windows.map(e=>({index:e.index,trainStartIndex:e.trainStartIndex,trainEndIndex:e.trainEndIndex,passed:e.passed,reason:e.reason,evalStartIndex:e.evalStartIndex,evalEndIndex:e.evalEndIndex,metrics:e.metrics}))}})}function ar(t){return Vn("sha256").update(JSON.stringify(ir(t)),"utf8").digest("hex")}function X(t,e,r=0){if(!Number.isInteger(t)||t<r)throw new Error(`${e} must be an integer >= ${r}`);return t}function ce(t,e){if(!et(t)||!et(t.metrics))throw new Error(`${e} metrics required`);let r=X(t.tradeCount,`${e}.tradeCount`);if(t.metrics.tradeCount!==r)throw new Error(`${e} tradeCount contradicts metrics.tradeCount`);for(let n of["netPnlUsd","profitFactor","maxDrawdownPct"])if(!bt(t.metrics[n]))throw new Error(`${e}.metrics.${n} must be finite`);if(t.metrics.maxDrawdownPct<0)throw new Error(`${e}.metrics.maxDrawdownPct must be >= 0`);return t.metrics}function Xn(t,{maxDailyLossPct:e}={}){let r=t.split,n=X(r.trainStartIndex,"split.trainStartIndex"),s=X(r.trainEndIndex,"split.trainEndIndex"),a=X(r.trainBarCount,"split.trainBarCount",1),o=X(r.holdoutStartIndex,"split.holdoutStartIndex"),i=X(r.holdoutEndIndex,"split.holdoutEndIndex"),l=X(r.holdoutBarCount,"split.holdoutBarCount",1);if(n!==0||s-n+1!==a||o!==s+1||i-o+1!==l)throw new Error("evidence split must be contiguous, chronological, and count-consistent");if(!bt(r.trainFraction)||r.trainFraction<=0||r.trainFraction>=1)throw new Error("split.trainFraction must be in (0,1)");ce(t.train,"train");let f=ce(t.holdout,"holdout");if(f.tradeCount<1||f.netPnlUsd<=0||f.profitFactor<=1)throw new Error("live-eligible holdout metrics do not pass");if(bt(e)&&f.maxDrawdownPct>e)throw new Error("live-eligible holdout drawdown exceeds strategy risk");if(t.flags.length>0)throw new Error("live-eligible evidence cannot contain failure flags");let u=t.walkForward,c=u.windows;if(c.length<1||u.windowsRun!==c.length)throw new Error("live-eligible walk-forward windowsRun must match nonempty windows");let d=0,m=-1;for(let b=0;b<c.length;b++){let E=c[b];if(!et(E)||E.index!==b||typeof E.passed!="boolean")throw new Error("walk-forward windows must be ordered and structurally valid");let k=X(E.trainStartIndex,`walkForward.windows[${b}].trainStartIndex`),P=X(E.trainEndIndex,`walkForward.windows[${b}].trainEndIndex`),T=X(E.evalStartIndex,`walkForward.windows[${b}].evalStartIndex`),x=X(E.evalEndIndex,`walkForward.windows[${b}].evalEndIndex`);if(k!==0||P>=T||T>x||T<=m)throw new Error("walk-forward windows must be chronological and disjoint");if(m=x,E.passed){if(d+=1,E.reason!=="pass")throw new Error("passed walk-forward window reason must be pass");let R=ce({metrics:E.metrics,tradeCount:E.metrics?.tradeCount},`walkForward.windows[${b}]`);if(R.tradeCount<1||R.netPnlUsd<=0||R.profitFactor<=1)throw new Error("passed walk-forward window metrics do not pass");if(bt(e)&&R.maxDrawdownPct>e)throw new Error("passed walk-forward drawdown exceeds strategy risk")}else if(E.reason==="pass")throw new Error("failed walk-forward window cannot have pass reason")}let p=d/c.length;if(!bt(u.passRate)||Math.abs(u.passRate-p)>Number.EPSILON||p<.6)throw new Error("walk-forward passRate contradicts concrete windows or is below live threshold")}function cr(t,e={}){if(typeof t?.id!="string"||!/^[0-9a-f]{64}$/.test(t.id))throw new Error("evidence.id must be a sha256 evidence artifact hash");let r=ir(t),n=mt({id:t.id,...r});if(JSON.stringify(mt(t))!==JSON.stringify(n))throw new Error("evidence artifact contains fields unbound from its deterministic identity");let s=ar(t);if(t.id!==s)throw new Error("evidence.id does not match its deterministic artifact facts digest");return t.status==="pass_live_eligible"&&Xn(t,e),t}function ue({strategy:t,bars:e,backtestOptions:r={},trainFraction:n=.7,walkForwardWindows:s=3,minTrades:a=10}={}){let o=[];if(!et(t))throw new TypeError("strategy must be a plain object");if(!Array.isArray(e))throw new TypeError("bars must be an array");if(!et(r))throw new TypeError("backtestOptions must be a plain object");if(!bt(n)||n<=0||n>=1)throw new TypeError("trainFraction must be in (0,1)");if(!Number.isInteger(s)||s<1)throw new TypeError("walkForwardWindows must be a positive integer");if(!Number.isInteger(a)||a<0)throw new TypeError("minTrades must be an integer >= 0");let i=J(t),l=wt(i),f=It(e),u=e.length,c=(I=[],v={})=>or({status:"fail",strategy:i,sHash:l,barsHash:f,split:v.split||{trainStartIndex:0,trainEndIndex:-1,trainBarCount:0,holdoutStartIndex:0,holdoutEndIndex:-1,holdoutBarCount:0,trainFraction:n},train:v.train||null,holdout:v.holdout||null,walkForward:v.walkForward||{windows:[],passRate:0},flags:[...o,...I]});if(u<10)return c([{type:"insufficient_bars",message:"need at least 10 bars for evidence"}]);let d=Math.floor(u*n),m=d,p=u-m;if(d<5||p<3)return c([{type:"invalid_windowing",message:"train/holdout split too small",trainCount:d,holdoutCount:p}]);let b=e.slice(0,d),E=e.slice(m),k,P;try{k=lt(i,b,r),P=lt(i,E,r)}catch(I){return c([{type:"backtest_error",message:String(I.message||I)}])}let T={metrics:ae(k),costs:sr(k),tradeCount:k.metrics.tradeCount},x={metrics:ae(P),costs:sr(P),tradeCount:P.metrics.tradeCount},R={trainStartIndex:0,trainEndIndex:d-1,trainBarCount:d,holdoutStartIndex:m,holdoutEndIndex:u-1,holdoutBarCount:p,trainFraction:n},_=[],w=Math.floor(u/(s+1));if(w<3)o.push({type:"invalid_windowing",message:"walk-forward window size too small",wfSize:w});else for(let I=0;I<s;I++){let v=w*(I+1),B=v,C=Math.min(u,B+w);if(C-B<3||v<3){_.push({index:I,trainStartIndex:0,trainEndIndex:v-1,evalStartIndex:B,evalEndIndex:C-1,passed:!1,reason:"window_too_small",metrics:null});continue}let Z=e.slice(B,C),jt;try{jt=lt(i,Z,r)}catch{_.push({index:I,trainStartIndex:0,trainEndIndex:v-1,evalStartIndex:B,evalEndIndex:C-1,passed:!1,reason:"backtest_error",metrics:null});continue}let Ft=ae(jt),Lt=Gn(Ft,i.risk,a);_.push({index:I,trainStartIndex:0,trainEndIndex:v-1,evalStartIndex:B,evalEndIndex:C-1,passed:Lt,reason:Lt?"pass":"fail_metrics",metrics:Ft})}let V=_.filter(I=>I.passed).length,it=_.length===0?0:V/_.length,at={windows:_,passRate:it,windowsRun:_.length};x.metrics.tradeCount===0&&T.metrics.tradeCount===0&&o.push({type:"no_trades",message:"no trades in train or holdout"}),x.metrics.tradeCount===0&&o.push({type:"absent_oos_trades",message:"holdout produced no trades"}),x.metrics.netPnlUsd<0&&o.push({type:"holdout_loss",message:"holdout netPnlUsd is negative"}),T.metrics.netPnlUsd>0&&x.metrics.netPnlUsd<0&&T.metrics.netPnlUsd>Math.abs(x.metrics.netPnlUsd)*.25?o.push({type:"overfit",message:"profitable train with losing holdout (OOS collapse)"}):T.metrics.netPnlUsd>0&&x.metrics.netPnlUsd>0&&x.metrics.netPnlUsd<T.metrics.netPnlUsd*.1&&T.metrics.tradeCount>=a&&o.push({type:"severe_oos_collapse",message:"holdout pnl collapsed vs train"});let W=Kn(x.costs),h=Yn(P);h>0&&W>h&&o.push({type:"costs_exceed_gross",message:"holdout costs exceed gross gains"});let A=o.some(I=>["insufficient_bars","invalid_windowing","absent_oos_trades","holdout_loss","no_trades","severe_oos_collapse","backtest_error"].includes(I.type)),N=o.some(I=>I.type==="overfit"),j="fail";return x.metrics.tradeCount>=a&&x.metrics.netPnlUsd>0&&x.metrics.profitFactor>1&&x.metrics.maxDrawdownPct<=i.risk.maxDailyLossPct&&it>=.6&&!(h>0&&W>h)&&!N&&!o.some(I=>I.type==="severe_oos_collapse"||I.type==="invalid_windowing")?j="pass_live_eligible":!A&&x.metrics.tradeCount>0&&T.metrics.tradeCount>0&&Number.isFinite(x.metrics.netPnlUsd)?(j="pass_paper_only",x.metrics.tradeCount<a&&o.push({type:"undersampled",message:"holdout trades below minTrades"})):N&&x.metrics.tradeCount>0&&T.metrics.netPnlUsd>0?j="fail":x.metrics.tradeCount>0&&T.metrics.tradeCount>0&&!A?j="pass_paper_only":j="fail",x.metrics.netPnlUsd<0&&(j=j==="pass_live_eligible"?"fail":j==="pass_paper_only"?"pass_paper_only":"fail",j="fail"),or({status:j,strategy:i,sHash:l,barsHash:f,split:R,train:T,holdout:x,walkForward:at,flags:o})}function or({status:t,strategy:e,sHash:r,barsHash:n,split:s,train:a,holdout:o,walkForward:i,flags:l}){let f={status:t,strategyHash:r,compilerHash:dt,barsHash:n,split:s,train:a,holdout:o,walkForward:i,flags:l};return f.id=ar(f),le(mt(JSON.parse(JSON.stringify(f))))}var Jn,fe=z(()=>{pt();ut();Bt();Jn=Object.freeze(["fail","pass_paper_only","pass_live_eligible"])});import{createHash as Wn,createHmac as Zn,timingSafeEqual as Ho}from"node:crypto";function de(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?`[${t.map(de).join(",")}]`:`{${Object.keys(t).sort().map(r=>`${JSON.stringify(r)}:${de(t[r])}`).join(",")}}`}function lr(t){let e=String(t?.ORACLE_STAMP_HMAC_SECRET||"").trim();return e.length>=16?e:""}function ur(t=process.env){return lr(process.env)||lr(t)}function es(t){let{oraclePrepared:e,prepareHash:r,prepareMac:n,note:s,...a}=t||{};return a}function rs(t){let e=es(t);return Wn("sha256").update(de(e)).digest("hex")}function ns(t,e=ur()){return e?Zn("sha256",e).update(String(t)).digest("hex"):""}function fr(t,{provider:e,kind:r,env:n=process.env}={}){if(!t||typeof t!="object")throw new Error("stampPrepared: payload object required");let s={...t,provider:t.provider||e,kind:t.kind||r,requiresUserSignature:t.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!s.provider)throw new Error("stampPrepared: provider required");if(!s.kind)throw new Error("stampPrepared: kind required");let a=Date.now(),o=a+ts,l={...s,preparedAt:a,expiresAt:o,prepareVersion:Qn},f=rs(l),u=ur(n),c=u?ns(f,u):void 0,d={...l,oraclePrepared:!0,prepareHash:f};return c&&(d.prepareMac=c),d}var Qn,ts,Uo,dr=z(()=>{Qn=2,ts=300*1e3,Uo=(()=>{let t=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(t)&&t>0?t:1800*1e3})()});function Nt(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function os(t){return String(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function me(t,e="value"){if(Array.isArray(t)){t.forEach((r,n)=>me(r,`${e}[${n}]`));return}if(Nt(t))for(let[r,n]of Object.entries(t)){let s=os(r);if(ss.some(a=>s.includes(a)))throw new Error(`handoff: forbidden secret-like field at ${e}.${r}`);me(n,`${e}.${r}`)}}function pe(t){return typeof t=="number"&&Number.isFinite(t)&&t>0}function pr({strategy:t,evidence:e,shadow:r,caps:n,nowMs:s=Date.now(),env:a=process.env}={}){if(me({strategy:t,evidence:e,shadow:r,caps:n},"handoff"),!Nt(t))throw new Error("handoff: strategy required");if(!Nt(e))throw new Error("handoff: evidence required");if(!Nt(r))throw new Error("handoff: shadow required");if(!Nt(n))throw new Error("handoff: caps required");if(typeof r.id!="string"||!r.id.trim())throw new Error("handoff: shadow.id required");if(typeof r.stateHash!="string"||!/^[0-9a-f]{64}$/.test(r.stateHash))throw new Error("handoff: shadow.stateHash must be a sha256 hash");if(r.status!=="running")throw new Error("handoff: shadow.status must be running");if(!Number.isInteger(r.cursor)||r.cursor<=0)throw new Error("handoff: shadow.cursor must be a positive integer");if(!Number.isInteger(r.updatedAt)||r.updatedAt<=0||r.updatedAt>s)throw new Error("handoff: shadow.updatedAt must be a positive integer <= nowMs");let o=J(t,{nowMs:s}),i=K(o);if(cr(e,{maxDailyLossPct:o.risk.maxDailyLossPct}),e.status!=="pass_live_eligible")throw new Error("handoff: evidence.status must be pass_live_eligible");if(e.strategyHash!==i.strategyHash)throw new Error("handoff: evidence.strategyHash mismatch");if(e.compilerHash!==i.compilerHash)throw new Error("handoff: evidence.compilerHash mismatch");let l=["perStrategyNotionalUsd","maxLeverage","dailyLossCapUsd","chainAllowlist","assetAllowlist","expiresAt","killSwitchRequired"];for(let d of l)if(!(d in n)||n[d]==null)throw new Error(`handoff: caps.${d} required`);if(!pe(n.perStrategyNotionalUsd))throw new Error("handoff: caps.perStrategyNotionalUsd must be positive");if(n.perStrategyNotionalUsd>i.strategy.risk.maxNotionalUsd)throw new Error("handoff: caps.perStrategyNotionalUsd exceeds strategy.risk.maxNotionalUsd");if(!pe(n.maxLeverage))throw new Error("handoff: caps.maxLeverage must be positive");if(n.maxLeverage>i.strategy.risk.maxLeverage)throw new Error("handoff: caps.maxLeverage exceeds strategy.risk.maxLeverage");if(!pe(n.dailyLossCapUsd))throw new Error("handoff: caps.dailyLossCapUsd must be positive");let f=i.strategy.risk.maxNotionalUsd*(i.strategy.risk.maxDailyLossPct/100);if(n.dailyLossCapUsd>f)throw new Error("handoff: caps.dailyLossCapUsd exceeds strategy daily loss ceiling");if(!Array.isArray(n.chainAllowlist)||n.chainAllowlist.length===0)throw new Error("handoff: caps.chainAllowlist must be a non-empty array");if(!n.chainAllowlist.every(d=>d==="hyperliquid"))throw new Error("handoff: caps.chainAllowlist must include only hyperliquid");if(!n.chainAllowlist.includes("hyperliquid"))throw new Error("handoff: caps.chainAllowlist must include hyperliquid");if(!Array.isArray(n.assetAllowlist)||n.assetAllowlist.length===0)throw new Error("handoff: caps.assetAllowlist must be a non-empty array");if(n.assetAllowlist.length!==1||n.assetAllowlist[0]!==i.strategy.market.coin)throw new Error("handoff: caps.assetAllowlist must contain only the strategy market coin");if(!Number.isInteger(n.expiresAt)||!(n.expiresAt>s))throw new Error("handoff: caps.expiresAt must be an integer > nowMs");if(n.expiresAt>i.strategy.risk.expiresAt)throw new Error("handoff: caps.expiresAt exceeds strategy.risk.expiresAt");if(n.killSwitchRequired!==!0)throw new Error("handoff: caps.killSwitchRequired must be exactly true");let u={perStrategyNotionalUsd:n.perStrategyNotionalUsd,maxLeverage:n.maxLeverage,dailyLossCapUsd:n.dailyLossCapUsd,chainAllowlist:[...n.chainAllowlist],assetAllowlist:[...n.assetAllowlist],expiresAt:n.expiresAt,killSwitchRequired:!0},c={strategyHash:i.strategyHash,compilerHash:i.compilerHash,evidence:JSON.parse(JSON.stringify(e)),shadow:{id:r.id,stateHash:r.stateHash,status:r.status,cursor:r.cursor,updatedAt:r.updatedAt},compiled:{strategyHash:i.strategyHash,compilerHash:i.compilerHash,compilerVersion:_t,venue:"hyperliquid",market:{coin:i.strategy.market.coin,kind:"perp",interval:i.strategy.market.interval},risk:{...i.strategy.risk},strategy:JSON.parse(JSON.stringify(i.strategy))},arming:{liveBroadcast:!1,requiresExplicitUserArm:!0,caps:u},requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,executionReady:!1};return fr(c,{provider:"hl-strategy",kind:"strategy-live-handoff",env:a})}var ss,mr=z(()=>{pt();fe();ut();dr();ss=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});import{createHash as is}from"node:crypto";function us(t){let e=String(t||"").toLowerCase();return gr.includes(e)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(e)}function fs(t){let e={};for(let[r,n]of Object.entries(t||{}))us(r)||(e[r]=n);return e}function ds(t,e){if(!t)throw new Error(`HTTP redirect from ${e} missing Location`);let r=new URL(String(t),String(e));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${e} used unsupported protocol ${r.protocol}`);return r.toString()}function ps(t,e){return new URL(String(t)).origin===new URL(String(e)).origin}function ms(t,e,r){let n={};for(let[l,f]of Object.entries(r||{}))n[l.toLowerCase()]=f;let s=Object.keys(n).filter(l=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(l)),o=[...new Set([...gr,...s])].sort().map(l=>`${l}=${n[l]??""}`).join(`
|
|
2
|
+
`),i=is("sha256").update(o).digest("hex").slice(0,32);return`${t} ${e} ${i}`}function hs(t,e){let r=Number(e);return Number.isFinite(r)&&r>0?Math.min(r*1e3,yr):Math.min(250*2**t,yr)+Math.floor(Math.random()*100)}async function ws(t,{fetchImpl:e,method:r,headers:n,body:s,timeoutMs:a}){let o=new AbortController,i=setTimeout(()=>o.abort(),a);try{let l=String(t),f={...n||{}};for(let u=0;u<=wr;u+=1){let c=await e(l,{method:r,headers:f,body:s,signal:o.signal,redirect:"manual"}),d=await c.text(),m=null;if(d)try{m=JSON.parse(d)}catch{m=null}if(ls.has(c.status)){if(r!=="GET"&&r!=="HEAD"){let b=new Error(`HTTP ${c.status} ${r} ${l} redirected non-idempotent request`);throw b.status=c.status,b.body=m??d.slice(0,300),b}if(u===wr)throw new Error(`HTTP redirect loop for ${t}`);let p=ds(c.headers?.get?.("location"),l);ps(p,l)||(f=fs(f)),l=p;continue}if(!c.ok){let p=new Error(`HTTP ${c.status} ${r} ${l}`);throw p.status=c.status,p.retryAfter=c.headers?.get?.("retry-after")??null,p.body=m??d.slice(0,300),p}return m??d}throw new Error(`HTTP redirect loop for ${t}`)}finally{clearTimeout(i)}}async function br(t,e={}){let r=e.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=e.timeoutMs??12e3,s=(e.method||"GET").toUpperCase(),a={Accept:"application/json",...e.headers||{}},o=e.body;o!=null&&typeof o!="string"&&(a["Content-Type"]=a["Content-Type"]||"application/json",o=JSON.stringify(o));let i=Number.isInteger(e.retries)?Math.max(e.retries,0):cs,l=async()=>{let m;for(let p=0;p<=i;p++)try{return await ws(t,{fetchImpl:r,method:s,headers:a,body:o,timeoutMs:n})}catch(b){m=b;let E=b?.status,k=b?.name==="AbortError",P=new Set([408,425,429]),T=E!=null?P.has(E)||as.has(E)&&hr.has(s):!k&&hr.has(s);if(p===i||!T)throw b;await ys(hs(p,b?.retryAfter))}throw m};if(!(e.dedupe!==!1&&s==="GET"&&o==null))return l();let u=ms(s,t,a),c=he.get(u);if(c)return c;let d=l().finally(()=>he.delete(u));return he.set(u,d),d}var as,hr,cs,yr,gr,ls,wr,he,ys,Er=z(()=>{as=new Set([408,425,429,500,502,503,504]),hr=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),cs=2,yr=4e3,gr=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],ls=new Set([301,302,303,307,308]),wr=3;he=new Map;ys=t=>new Promise(e=>setTimeout(e,t))});function Es({testnet:t,baseUrl:e}={}){if(e)return e.replace(/\/$/,"").endsWith("/info")?e:`${e.replace(/\/$/,"")}/info`;if(process.env.HL_INFO_URL)return process.env.HL_INFO_URL;if(process.env.HL_API_URL){let r=process.env.HL_API_URL.replace(/\/$/,"");return r.endsWith("/info")?r:`${r}/info`}return t||process.env.HL_TESTNET==="1"?bs:gs}async function xr(t,e={}){if(!t||!t.type)throw new Error("hlInfo requires body.type");let r=Es(e);return br(r,{method:"POST",body:t,fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs})}async function Sr({coin:t,interval:e="1h",startTime:r,endTime:n},s={}){if(!t)throw new Error("hlCandleSnapshot requires coin");let a={type:"candleSnapshot",req:{coin:String(t),interval:e,startTime:r??Date.now()-24*3600*1e3,endTime:n??Date.now()}};return xr(a,s)}async function kr({coin:t,startTime:e,endTime:r},n={}){if(!t)throw new Error("hlFundingHistory requires coin");return xr({type:"fundingHistory",coin:String(t),startTime:e??Date.now()-24*3600*1e3,endTime:r??Date.now()},n)}var gs,bs,Ar=z(()=>{Er();gs="https://api.hyperliquid.xyz/info",bs="https://api.hyperliquid-testnet.xyz/info"});function Et(t,e){let r=Number(t);if(!Number.isFinite(r))throw new TypeError(`${e} must be finite`);return r}function xt(t,e){if(!Number.isSafeInteger(t)||t<0)throw new TypeError(`${e} must be a non-negative safe integer`);return t}function vt(t){if(Array.isArray(t))for(let e of t)vt(e);else if(t&&typeof t=="object")for(let e of Object.values(t))vt(e);return Object.freeze(t)}function Ss(t){let e=xs[t];if(!e)throw new TypeError(`unsupported strategy interval: ${t}`);return e}function ks(t,{endTime:e=Number.MAX_SAFE_INTEGER}={}){if(!Array.isArray(t))throw new TypeError("Hyperliquid candles must be an array");xt(e,"endTime");let r=new Map;for(let n=0;n<t.length;n++){let s=t[n];if(!s||typeof s!="object"||Array.isArray(s))throw new TypeError(`candles[${n}] must be an object`);let a=xt(Number(s.t),`candles[${n}].t`);if(xt(Number(s.T),`candles[${n}].T`)>e)continue;let i={t:a,o:Et(s.o,`candles[${n}].o`),h:Et(s.h,`candles[${n}].h`),l:Et(s.l,`candles[${n}].l`),c:Et(s.c,`candles[${n}].c`),v:Et(s.v,`candles[${n}].v`)};if(i.h<Math.max(i.o,i.c,i.l))throw new TypeError(`candles[${n}].h is below another price`);if(i.l>Math.min(i.o,i.c,i.h))throw new TypeError(`candles[${n}].l is above another price`);if(i.v<0)throw new TypeError(`candles[${n}].v must be non-negative`);let l=r.get(a);if(l&&JSON.stringify(l)!==JSON.stringify(i))throw new TypeError(`conflicting duplicate candle at timestamp ${a}`);l||r.set(a,i)}return vt([...r.values()].sort((n,s)=>n.t-s.t))}function As(t,e){if(!Array.isArray(t))throw new TypeError("Hyperliquid funding history must be an array");let r=new Map;for(let n=0;n<t.length;n++){let s=t[n];if(!s||typeof s!="object"||Array.isArray(s))throw new TypeError(`funding[${n}] must be an object`);let a=xt(Number(s.time),`funding[${n}].time`);a>e||r.set(a,{time:a,fundingRate:Et(s.fundingRate,`funding[${n}].fundingRate`)})}return[...r.values()].sort((n,s)=>n.time-s.time)}async function Ps({coin:t,startTime:e,endTime:r},n){let s=[],a=Math.max(0,e-288e5),o=!1;for(let i=0;i<16&&a<=r;i++){let l=await kr({coin:t,startTime:a,endTime:r},n);if(!Array.isArray(l))throw new TypeError("Hyperliquid funding history must be an array");s.push(...l);let f=a;for(let u of l){let c=Number(u?.time);Number.isSafeInteger(c)&&c>f&&(f=c)}if(l.length<500||f>=r){o=!0;break}if(f<=a)throw new Error("Hyperliquid funding history pagination did not advance");a=f+1}if(!o)throw new Error("strategy history exceeds the bounded funding history limit");return As(s,r)}function $s(t,e,r){let n=0,s=null;return t.map(a=>{let o=a.t+r,i=0;for(;n<e.length&&e[n].time<o;){let l=e[n];s=l.fundingRate,l.time>=a.t&&(i+=l.fundingRate),n+=1}return s==null?{...a,fundingPaymentRate:i}:{...a,fundingRate:s,fundingPaymentRate:i}})}async function Pr(t,e={}){if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("strategy history input must be an object");let r=String(t.coin||"").trim().toUpperCase();if(!/^[A-Z0-9][A-Z0-9._-]{0,11}$/.test(r))throw new TypeError("coin must be an uppercase Hyperliquid asset id");let n=String(t.interval||"15m"),s=Ss(n);if(t.endTime==null)throw new TypeError("endTime is required for deterministic history");let a=xt(t.endTime,"endTime"),o=t.count==null?1500:t.count;if(!Number.isInteger(o)||o<20||o>5e3)throw new TypeError("count must be an integer from 20 to 5000");let i=t.startTime==null?Math.max(0,a-o*s):xt(t.startTime,"startTime");if(i>=a)throw new TypeError("startTime must be before endTime");let[l,f]=await Promise.all([Sr({coin:r,interval:n,startTime:i,endTime:a},e),Ps({coin:r,startTime:i,endTime:a},e)]),u=ks(l,{endTime:a}),c=vt($s(u,f,s));return vt({coin:r,interval:n,range:{startTime:i,endTime:a},bars:c})}var xs,$r=z(()=>{Ar();xs=Object.freeze({"1m":6e4,"3m":18e4,"5m":3e5,"15m":9e5,"30m":18e5,"1h":36e5,"2h":72e5,"4h":144e5,"8h":288e5,"12h":432e5,"1d":864e5})});import{createHash as Ts}from"node:crypto";function js(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function ye(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)ye(e);return Object.freeze(t)}for(let e of Object.keys(t))ye(t[e]);return Object.freeze(t)}function Fs(t){return String(t).trim().replace(/\s+/g," ")}function Ls(t){let e=t.match(/\b(long|short)\b/i);return e?e[1].toLowerCase():null}function Hs(t){for(let r of Is)if(new RegExp(`\\b${r}\\b`,"i").test(t))return r;let e=t.match(/\b([A-Z][A-Z0-9]{1,11})\b/);return e?e[1]:null}function Us(t){let e=t.match(/\bon\s+(1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/i);if(!e)return"15m";let r=e[1].toLowerCase();return _s.has(r)?r:null}function Cs(t){let e={...Ns},r=t.match(/stop\s*loss\s*(\d+(?:\.\d+)?)\s*%?/i);r&&(e.stopLossPct=Number(r[1]));let n=t.match(/take\s*profit\s*(\d+(?:\.\d+)?)\s*%?/i);n&&(e.takeProfitPct=Number(n[1]));let s=t.match(/leverage\s*(\d+(?:\.\d+)?)/i);s&&(e.maxLeverage=Number(s[1]));let a=t.match(/position\s*size\s*(\d+(?:\.\d+)?)\s*%?/i);a&&(e.positionSizePct=Number(a[1]));let o=t.match(/max\s*notional\s*(?:usd\s*)?\$?\s*(\d+(?:\.\d+)?)/i);return o&&(e.maxNotionalUsd=Number(o[1])),e}function qs(t){return[/\bon\s+(?:1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/gi,/\bstop\s*loss\s*\d+(?:\.\d+)?\s*%?/gi,/\btake\s*profit\s*\d+(?:\.\d+)?\s*%?/gi,/\bleverage\s*\d+(?:\.\d+)?/gi,/\bposition\s*size\s*\d+(?:\.\d+)?\s*%?/gi,/\bmax\s*notional\s*(?:usd\s*)?\$?\s*\d+(?:\.\d+)?/gi].some(r=>(t.match(r)??[]).length>1)}function Bs(t){let e=Ts("sha256").update(t,"utf8").digest("hex").slice(0,10),r=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40),s=`${r.length?r:"draft"}-${e}`.replace(/[^a-z0-9._-]/g,"").slice(0,64);return/^[a-z0-9]/.test(s)?s:`d${s}`.slice(0,64)}function Ds(t){let e=t.match(/\bema\s*(\d+)\s*cross(?:es)?\s*(above|below)\s*ema\s*(\d+)\b/i);if(!e)return null;let r=Number(e[1]),n=e[2].toLowerCase(),s=Number(e[3]);if(!(r>0)||!(s>0)||r===s)return null;let a=/\b(exit\s+on\s+reverse|reverse\s+exit)\b/i.test(t);return{kind:"ema_cross",fast:r,slow:s,direction:n,reverse:a}}function zs(t){let e=t.match(/\brsi\s*(\d+)\s*(above|below)\s*(-?\d+(?:\.\d+)?)/i);if(!e)return null;let r=Number(e[3]);return!Number.isFinite(r)||r<=0||r>=100?null:{kind:"rsi",period:Number(e[1]),op:e[2].toLowerCase(),threshold:r}}function Vs(t){let e=t.match(/\bfunding\s*rate\s*(above|below)\s*(-?\d+(?:\.\d+)?)(%?)(?=\s|,|$)/i);if(!e)return null;let r=Number(e[2]);return e[3]==="%"&&(r=r/100),{kind:"funding",op:e[1].toLowerCase(),threshold:r}}function Js(t,e){let r=t.replace(/^(long|short)\s+[A-Z][A-Z0-9]{1,11}\s+when\s+/i,"");if(r===t)return!1;e.kind==="ema_cross"?r=r.replace(/^ema\s*\d+\s*cross(?:es)?\s*(?:above|below)\s*ema\s*\d+\b/i,""):e.kind==="rsi"?r=r.replace(/^rsi\s*\d+\s*(?:above|below)\s*\d+(?:\.\d+)?\b/i,""):r=r.replace(/^funding\s*rate\s*(?:above|below)\s*-?\d+(?:\.\d+)?%?(?=\s|,|$)/i,"");let n=[/(?:,\s*)?\bon\s+(?:1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/gi,/(?:,\s*)?\bstop\s*loss\s*\d+(?:\.\d+)?\s*%?/gi,/(?:,\s*)?\btake\s*profit\s*\d+(?:\.\d+)?\s*%?/gi,/(?:,\s*)?\bleverage\s*\d+(?:\.\d+)?/gi,/(?:,\s*)?\bposition\s*size\s*\d+(?:\.\d+)?\s*%?/gi,/(?:,\s*)?\bmax\s*notional\s*(?:usd\s*)?\$?\s*\d+(?:\.\d+)?/gi];e.kind==="ema_cross"&&n.push(/(?:,\s*)?\b(?:exit\s+on\s+reverse|reverse\s+exit)\b/gi);for(let s of n)r=r.replace(s,"");return r.replace(/[\s,;]+/g,"")===""}function Tr(t){let e=Math.max(2,Math.floor(t/2));return{value:t,min:Math.max(2,t-e),max:Math.min(500,t+e),step:1}}function Ks({side:t,coin:e,interval:r,risk:n,expiresAt:s,id:a,name:o,spec:i}){let l=[{id:"c",type:"input",field:"close"},{id:"emaLeft",type:"indicator",indicator:"ema",input:"c",period:{param:"ema_left_period"}},{id:"emaRight",type:"indicator",indicator:"ema",input:"c",period:{param:"ema_right_period"}},{id:"cross",type:"cross",direction:i.direction,left:"emaLeft",right:"emaRight"}],f={entryLong:null,entryShort:null,exitLong:null,exitShort:null};if(t==="long"?f.entryLong="cross":f.entryShort="cross",i.reverse){let u=i.direction==="above"?"below":"above";l.push({id:"crossRev",type:"cross",direction:u,left:"emaLeft",right:"emaRight"}),t==="long"?f.exitLong="crossRev":f.exitShort="crossRev"}return{version:1,id:a,name:o,venue:"hyperliquid",market:{coin:e,interval:r},parameters:{ema_left_period:Tr(i.fast),ema_right_period:Tr(i.slow)},nodes:l,rules:f,risk:{...n,expiresAt:s}}}function Ys({side:t,coin:e,interval:r,risk:n,expiresAt:s,id:a,name:o,spec:i}){let l=[{id:"c",type:"input",field:"close"},{id:"rsi",type:"indicator",indicator:"rsi",input:"c",period:i.period},{id:"thr",type:"constant",value:i.threshold},{id:"sig",type:"compare",op:i.op==="above"?"gt":"lt",left:"rsi",right:"thr"}];return{version:1,id:a,name:o,venue:"hyperliquid",market:{coin:e,interval:r},parameters:{},nodes:l,rules:{entryLong:t==="long"?"sig":null,entryShort:t==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:s}}}function Gs({side:t,coin:e,interval:r,risk:n,expiresAt:s,id:a,name:o,spec:i}){let l=[{id:"fr",type:"input",field:"fundingRate"},{id:"thr",type:"constant",value:i.threshold},{id:"sig",type:"compare",op:i.op==="above"?"gt":"lt",left:"fr",right:"thr"}];return{version:1,id:a,name:o,venue:"hyperliquid",market:{coin:e,interval:r},parameters:{},nodes:l,rules:{entryLong:t==="long"?"sig":null,entryShort:t==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:s}}}function _r(t,e={}){if(typeof t!="string")throw new D("prompt must be a string");if(t.length>1e3)throw new D("prompt length must be <= 1000");if(!js(e))throw new D("options must be a plain object");if(!Number.isInteger(e.nowMs))throw new D("options.nowMs is required integer epoch ms");let r=e.nowMs,n=Rs;if("expiresInMs"in e){if(!Number.isInteger(e.expiresInMs))throw new D("expiresInMs must be an integer");if(n=e.expiresInMs,n<vs||n>Ms)throw new D("expiresInMs must be between 1h and 30d")}if(Os.test(t))throw new D(`prompt appears to contain secrets and is rejected. ${St}`);let s=Fs(t);if(!s)throw new D(`empty prompt. ${St}`);if(qs(s))throw new D(`duplicate interval or risk clause. ${St}`);let a=Ls(s),o=Hs(s),i=Us(s);if(!a||!o||!i)throw new D(`could not parse side/coin/interval. ${St}`);let l=Cs(s);if(!(l.maxLeverage>0)||l.maxLeverage>50)throw new D("leverage out of range");if(!(l.positionSizePct>0)||l.positionSizePct>100)throw new D("position size out of range");let f=r+n,u=Bs(s),c=`Draft ${o} ${a}`.slice(0,100),d=Ds(s),m=zs(s),p=Vs(s),b=[d,m,p].filter(Boolean);if(b.length!==1)throw new D(`unsupported or ambiguous prompt. ${St}`);if(!Js(s,b[0]))throw new D(`unsupported or ambiguous prompt. ${St}`);let E,k=b[0],P={side:a,coin:o,interval:i,risk:l,expiresAt:f,id:u,name:c,spec:k};k.kind==="ema_cross"?E=Ks(P):k.kind==="rsi"?E=Ys(P):E=Gs(P);let T=ne(E,{nowMs:r});if(!T.ok)throw new D(`draft failed validation: ${T.errors.map(x=>x.message).join("; ")}`);return ye(J(E,{nowMs:r}))}var D,_s,Is,Os,St,Ns,vs,Ms,Rs,Ir=z(()=>{ut();D=class extends Error{constructor(e){super(e),this.name="StrategyDraftError"}},_s=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),Is=new Set(["BTC","ETH","SOL","HYPE"]),Os=/\b(mnemonic|private\s*key|privkey|seed\s*phrase|seed\b|api[_-]?key|secret\s*key|wallet\s*key|passphrase)\b/i,St="Supported grammar: (1) EMA cross: <long|short> <COIN> when EMA <n> crosses <above|below> EMA <m> [on <interval>] [, exit on reverse] [, risk knobs]; (2) RSI: <long|short> <COIN> when RSI <n> <above|below> <threshold> [on <interval>] [, risk knobs]; (3) funding: <long|short> <COIN> when funding rate <above|below> <decimal|percent%> [on <interval>] [, risk knobs]. Risk knobs: stop loss %, take profit %, leverage, position size %, max notional USD. Coins: BTC ETH SOL HYPE or uppercase token <=12 chars. Intervals: 1m 3m 5m 15m 30m 1h 2h 4h 8h 12h 1d.",Ns=Object.freeze({maxLeverage:1,maxNotionalUsd:100,positionSizePct:5,stopLossPct:2,takeProfitPct:4,cooldownBars:1,maxDailyLossPct:3}),vs=36e5,Ms=30*864e5,Rs=864e5});import{createHash as Xs}from"node:crypto";function vr(t){let e=String(t).toLowerCase();return e==="holdout"||e==="test"||e==="oos"||e.includes("holdout")||e.includes("oos")?!0:e==="testbars"||e.endsWith("testbars")||e.startsWith("test")||e.endsWith("test")?!e.includes("backtest"):!1}function Mr(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function ge(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)ge(e);return Object.freeze(t)}for(let e of Object.keys(t))ge(t[e]);return Object.freeze(t)}function Mt(t){if(Array.isArray(t))return t.map(Mt);if(t!=null&&typeof t=="object"){let e={};for(let r of Object.keys(t).sort())e[r]=Mt(t[r]);return e}return t}function Dt(t){return JSON.stringify(Mt(t))}function Ws(t){let{min:e,max:r,step:n}=t;if(!(n>0)||e>r)return[];let s=[],a=Math.floor((r-e)/n+1e-9);for(let i=0;i<=a;i++){let l=e+i*n;if(l>r+1e-9)break;let f=Math.abs(l-Math.round(l))<1e-9?Math.round(l):Number(l.toPrecision(12));f<e-1e-9||f>r+1e-9||s.push(f)}if(s.length===0)return[];let o=s[s.length-1];if(Math.abs(o-r)>1e-9){let i=(r-e)/n;Math.abs(i-Math.round(i))<=1e-9&&s.push(r)}return s}function Zs(t,e){if(t.length===0)return[];let r=[{}];for(let n of t){let s=e[n],a=[];for(let o of r)for(let i of s)a.push({...o,[n]:i});r=a}return r.sort((n,s)=>{let a=Dt(n),o=Dt(s);return a<o?-1:a>o?1:0}),r}function we(t,e,r,n,s){let a=0;if(t==="maxDrawdownPct"){if(a=e.maxDrawdownPct-n.maxDrawdownPct,a!==0)return a<0}else if(a=e[t]-n[t],a!==0)return a>0;let o=Dt(r),i=Dt(s);return o<i}function Rr(t,e,r={}){if(!Mr(r))throw new TypeError("options must be a plain object");for(let x of Object.keys(r))if(vr(x))throw new TypeError(`options must not include holdout/test/oos key "${x}"`);let n=new Set(["maxTrials","objective","backtestOptions"]);for(let x of Object.keys(r))if(!n.has(x))throw new TypeError(`unknown option "${x}"`);let s=64;if("maxTrials"in r){let x=r.maxTrials;if(!Number.isInteger(x)||x<1||x>Or)throw new TypeError(`maxTrials must be an integer 1..${Or}`);s=x}let a=r.objective??"netPnlUsd";if(!Nr.has(a))throw new TypeError(`objective must be one of ${[...Nr].join("|")}`);let o=r.backtestOptions??{};if(!Mr(o))throw new TypeError("backtestOptions must be a plain object");for(let x of Object.keys(o))if(vr(x))throw new TypeError(`backtestOptions must not include holdout/test/oos key "${x}"`);let i=J(t),l=Object.keys(i.parameters).sort();if(l.length===0)throw new Error("optimizeStrategy requires at least one declared parameter");let f={},u=1;for(let x of l){let R=Ws(i.parameters[x]);if(R.length===0)throw new Error(`parameter "${x}" produces an empty grid`);f[x]=R,u*=R.length}let c=Zs(l,f);if(c.length===0)throw new Error("parameter grid is empty");let d=c.slice(0,s),m=[],p=null,b=null;for(let x of d){let R=$t(i,x),_=lt(R,e,o);b==null&&(b=_.config);let w={netPnlUsd:_.metrics.netPnlUsd,netPnlPct:_.metrics.netPnlPct,maxDrawdownPct:_.metrics.maxDrawdownPct,winRate:_.metrics.winRate,profitFactor:_.metrics.profitFactor,tradeCount:_.metrics.tradeCount,sharpe:_.metrics.sharpe,turnoverUsd:_.metrics.turnoverUsd},V={parameters:{...x},metrics:w};m.push(V),(!p||we(a,w,x,p.metrics,p.parameters))&&(p=V)}m.sort((x,R)=>we(a,x.metrics,x.parameters,R.metrics,R.parameters)?-1:we(a,R.metrics,R.parameters,x.metrics,x.parameters)?1:0);let E={...p.parameters},k=$t(i,E),P={strategyHash:wt(i),compilerHash:dt,trainBarsHash:It(e),backtestConfig:b,objective:a,maxTrials:s,trialsRun:m.length,candidates:m,bestParameters:E,bestStrategy:k},T={id:Xs("sha256").update(JSON.stringify(Mt(P)),"utf8").digest("hex"),...P};return ge(Mt(JSON.parse(JSON.stringify(T))))}var Or,Nr,jr=z(()=>{pt();ut();Bt();Or=256,Nr=new Set(["netPnlUsd","profitFactor","sharpe","maxDrawdownPct"])});import ot from"node:fs";import zt from"node:path";function Vt(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function rt(t){return t==null?t:JSON.parse(JSON.stringify(t))}function to(t){return String(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function kt(t,e="record"){if(Array.isArray(t)){t.forEach((r,n)=>kt(r,`${e}[${n}]`));return}if(Vt(t))for(let[r,n]of Object.entries(t)){let s=to(r);if(Qs.some(a=>s.includes(a)))throw new Error(`shadow-store: forbidden secret-like field at ${e}.${r}`);kt(n,`${e}.${r}`)}}function eo(t){if(typeof t!="string"||!t||!zt.isAbsolute(t))throw new Error("shadow-store: path must be an absolute path")}function Fr(t){let e;try{e=ot.lstatSync(t)}catch(n){if(n&&n.code==="ENOENT")return;throw n}if(e.isSymbolicLink())throw new Error("shadow-store: store path must not be a symlink");if(!e.isFile())throw new Error("shadow-store: store path must be a regular file");if(e.mode&511&18)throw new Error("shadow-store: store file must not be group or world writable")}function ro(){return{version:Ee,runners:[]}}function Lr(t,e){let r;try{r=JSON.parse(t)}catch{throw new Error("shadow-store: malformed JSON")}if(!Vt(r))throw new Error("shadow-store: malformed JSON root");if(r.version!==Ee)throw new Error(`shadow-store: unsupported version ${r.version}`);if(!Array.isArray(r.runners))throw new Error("shadow-store: runners must be an array");return kt(r,zt.basename(e)),{version:Ee,runners:r.runners.map(n=>rt(n))}}function Hr(t,e){kt(e,"store");let r=zt.dirname(t);ot.mkdirSync(r,{recursive:!0,mode:448});let n=zt.join(r,`.shadow-store.${process.pid}.${Date.now()}.tmp`),s=`${JSON.stringify(e)}
|
|
3
|
+
`;try{ot.writeFileSync(n,s,{mode:384,flag:"wx"}),ot.renameSync(n,t);try{ot.chmodSync(t,384)}catch{}}catch(a){try{ot.unlinkSync(n)}catch{}throw a}}function Ur(t={}){let e=t.path;if(eo(e),Fr(e),ot.existsSync(e)?Lr(ot.readFileSync(e,"utf8"),e):Hr(e,ro()),be.has(e))return be.get(e);let r=!1,n=[];function s(){if(r)return;let p=n.shift();if(p){r=!0;try{let b=p.fn();r=!1,p.resolve(b),s()}catch(b){r=!1,p.reject(b),s()}}}function a(p){if(!r&&n.length===0){r=!0;try{return p()}finally{r=!1,queueMicrotask(s)}}return new Promise((b,E)=>{n.push({fn:p,resolve:b,reject:E}),queueMicrotask(s)})}function o(){return Fr(e),Lr(ot.readFileSync(e,"utf8"),e)}function i(p){Hr(e,p)}function l(p){if(!Vt(p)||typeof p.id!="string"||!p.id)throw new Error("shadow-store: create requires record with string id");kt(p,"record");let b=o();if(b.runners.some(k=>k.id===p.id))throw new Error(`shadow-store: runner id already exists: ${p.id}`);let E=rt(p);return b.runners.push(E),i(b),rt(E)}function f(p){let b=o().runners.find(E=>E.id===p);return b?rt(b):null}function u(){return o().runners.map(p=>rt(p))}function c(p,b){if(typeof b!="function")throw new Error("shadow-store: updater must be a function");let E=o(),k=E.runners.findIndex(x=>x.id===p);if(k<0)throw new Error(`shadow-store: runner not found: ${p}`);let P=rt(E.runners[k]),T=b(P);if(!Vt(T)||T.id!==p)throw new Error("shadow-store: updater must return record with same id");return kt(T,"record"),E.runners[k]=rt(T),i(E),rt(E.runners[k])}function d(p){let b=o(),E=b.runners.findIndex(P=>P.id===p);if(E<0)throw new Error(`shadow-store: runner not found: ${p}`);let k=rt(b.runners[E]);return k.status!=="stopped"&&(k.status="stopped",b.runners[E]=k,i(b)),rt(b.runners[E])}let m={create(p){return a(()=>l(p))},get(p){return f(p)},list(){return u()},update(p,b){return a(()=>c(p,b))},stop(p){return a(()=>d(p))}};return be.set(e,m),m}var Ee,Qs,be,Cr=z(()=>{Ee=1,Qs=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"];be=new Map});import{createHash as ke}from"node:crypto";function xe(t){return t==null?t:JSON.parse(JSON.stringify(t))}function Se(t){return Array.isArray(t)?t.map(Se):t&&typeof t=="object"?Object.fromEntries(Object.keys(t).sort().map(e=>[e,Se(t[e])])):t}function Br(t){if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("shadow-runner: record must be an object");return ke("sha256").update(JSON.stringify(Se(t))).digest("hex")}function no(t,e,r,n,s){return ke("sha256").update(`${t}|${e}|${r}|${n}|${s}`).digest("hex")}function so(t,e,r,n){return ke("sha256").update(`shadow|${t}|${e}|${r}|${n??""}`).digest("hex")}function oo(t){return t==="entryLong"||t==="exitShort"?"buy":t==="entryShort"||t==="exitLong"?"sell":t}function qr(t){return t==="entryLong"||t==="entryShort"}function Ae({storePath:t,clock:e=Date.now}={}){if(typeof t!="string"||!t)throw new Error("shadow-runner: storePath required");let r=Ur({path:t});function n({strategy:l,evidenceId:f=null}={}){let u=K(l),c=f==null?null:String(f),d=r.list().filter(k=>k.status==="running"&&k.strategyHash===u.strategyHash&&k.compilerHash===u.compilerHash&&k.evidenceId===c).sort((k,P)=>k.createdAt-P.createdAt||k.id.localeCompare(P.id))[0];if(d)return xe(d);let m=e(),p=so(m,u.strategyHash,u.compilerHash,c),b=r.get(p);if(b)return xe(b);let E={id:p,strategy:xe(u.strategy),strategyHash:u.strategyHash,compilerHash:u.compilerHash,evidenceId:c,status:"running",cursor:null,intendedOrders:[],fills:[],missedFills:[],markouts:[],createdAt:m,updatedAt:m,position:null,cooldownBarsRemaining:0,cooldownStartT:null,lastProcessedBarIndex:-1};return r.create(E)}function s(l){return r.get(l)}function a(){return r.list()}function o(l){return r.stop(l)}function i(l,f,{markoutHorizons:u=[1,4,12]}={}){if(!Array.isArray(f))throw new TypeError("shadow-runner: bars must be an array");return r.update(l,c=>{if(c.status!=="running")throw new Error("shadow-runner: runner is stopped");if(f.length===0)return c;let m=K(c.strategy).evaluateAll(f),p=new Map;for(let h=0;h<f.length;h++)p.set(f[h].t,h);let b=c.cursor,E=[];for(let h=0;h<f.length;h++){let A=f[h].t;(b==null||A>b)&&E.push(h)}if(E.length===0)return c;let k=new Map(c.intendedOrders.map(h=>[h.id,h])),P=new Set(c.fills.map(h=>h.orderId)),T=new Map(c.missedFills.map(h=>[h.orderId,h])),x=(h,A)=>`${h}|${A}`,R=new Map(c.markouts.map(h=>[x(h.orderId,h.horizon),h])),_=c.position?{...c.position}:null,w=Number.isInteger(c.cooldownBarsRemaining)?Math.max(0,c.cooldownBarsRemaining):0,V=Number.isFinite(c.cooldownStartT)?c.cooldownStartT:null;function it({action:h,signalBarT:A,signalIndex:N}){let j=oo(h),F=no(c.id,c.strategyHash,A,j,h);if(k.has(F))return k.get(F);let I=N+1,v=I<f.length,B={id:F,action:h,type:h,side:j,signalBarT:A,fillBarT:v?f[I].t:null,status:v?"open":"missed"};return k.set(F,B),c.intendedOrders.push(B),B}function at(h,A,N){if(P.has(h.id))return;let j={orderId:h.id,action:qr(h.action)?"entry":"exit",side:h.side,price:A.o,barT:A.t,signalBarT:h.signalBarT,barIndex:N};if(c.fills.push(j),P.add(h.id),h.status="filled",h.fillBarT=A.t,T.has(h.id)&&(T.delete(h.id),c.missedFills=c.missedFills.filter(F=>F.orderId!==h.id)),qr(h.action)){_={side:h.action==="entryLong"?"long":"short",entryOrderId:h.id,entryBarT:A.t,entryPrice:A.o,entryBarIndex:N};for(let F of u){let I=x(h.id,F);if(R.has(I))continue;let v={orderId:h.id,horizon:F,entryBarT:A.t,entryPrice:A.o,side:_.side,status:"pending",close:null,barT:null};R.set(I,v),c.markouts.push(v)}}else _=null,w=Number(c.strategy?.risk?.cooldownBars)||0,V=A.t}function W(h){if(P.has(h.id)||T.has(h.id))return;let A={orderId:h.id,action:h.action,side:h.side,signalBarT:h.signalBarT,status:"missed"};T.set(h.id,A),c.missedFills.push(A),h.status="missed"}for(let h of c.intendedOrders){if(h.status==="filled"||P.has(h.id))continue;let A=p.get(h.signalBarT);if(A==null)continue;let N=A+1;N<f.length&&(b==null||f[N].t>b)&&at(h,f[N],N)}for(let h of E){let A=f[h],N=m[h].signals,j=_,F=v=>{if(_||w>0&&(V==null||A.t>=V))return;let C=it({action:v,signalBarT:A.t,signalIndex:h}),Z=h+1;Z<f.length?at(C,f[Z],Z):W(C)},I=v=>{if(!_||_.side==="long"&&v!=="exitLong"||_.side==="short"&&v!=="exitShort")return;let B=it({action:v,signalBarT:A.t,signalIndex:h}),C=h+1;C<f.length?at(B,f[C],C):W(B)};j?(N.exitLong&&I("exitLong"),N.exitShort&&I("exitShort")):N.entryLong&&N.entryShort||(N.entryLong&&F("entryLong"),N.entryShort&&F("entryShort")),w>0&&V!=null&&A.t>=V&&(w-=1,w===0&&(V=null)),c.cursor=A.t,c.lastProcessedBarIndex=h}for(let h of c.markouts){if(h.status!=="pending")continue;let A=c.fills.find(F=>F.orderId===h.orderId&&F.action==="entry");if(!A)continue;let N=p.get(A.barT);if(N==null)continue;let j=N+h.horizon;if(j<f.length){h.close=f[j].c,h.barT=f[j].t,h.status="filled";let F=h.entryPrice;h.markout=h.side==="long"?(h.close-F)/F:(F-h.close)/F}}return c.position=_,c.cooldownBarsRemaining=w,c.cooldownStartT=V,c.updatedAt=e(),c})}return{start:n,step:i,list:a,get:s,stop:o}}var Dr=z(()=>{pt();Cr()});var Jr={};nn(Jr,{runStrategyOperation:()=>mo});import io from"node:os";import ao from"node:path";function Rt(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function lo(t){return String(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function $e(t){if(Array.isArray(t)){for(let e of t)$e(e);return}if(Rt(t))for(let[e,r]of Object.entries(t)){if(co.some(n=>lo(e).includes(n)))throw new Error(`strategy service: secret-like field "${e}" is forbidden`);$e(r)}}function uo(t){if(!Rt(t))throw new TypeError("strategy input must be a plain object");return $e(t),t}function fo(t,e){let r=e.nowMs??t.nowMs??Date.now();if(!Number.isInteger(r))throw new TypeError("nowMs must be an integer epoch milliseconds");return r}async function Pe(t,e,r,n){if(Array.isArray(e.bars))return e.bars;let a=await(r.fetchBars??Pr)({coin:t.market.coin,interval:t.market.interval,count:e.count??1500,endTime:e.endTime??n}),o=Array.isArray(a)?a:a?.bars;if(!Array.isArray(o))throw new Error("strategy history provider returned no bars");return o}function Te(t,e){let r=t.backtestOptions??{};if(!Rt(r))throw new TypeError("backtestOptions must be a plain object");return{...r,nowMs:e}}function zr(t,e,r,n,s={}){let a=t.evidenceOptions??{};if(!Rt(a))throw new TypeError("evidenceOptions must be a plain object");return{...a,...s,strategy:e,bars:r,backtestOptions:Te(t,n)}}function Vr(){return ao.join(io.homedir(),".oracle","strategy-shadow.json")}function po(t,e){return{perStrategyNotionalUsd:t.risk.maxNotionalUsd,maxLeverage:t.risk.maxLeverage,dailyLossCapUsd:t.risk.maxNotionalUsd*(t.risk.maxDailyLossPct/100),chainAllowlist:["hyperliquid"],assetAllowlist:[t.market.coin],expiresAt:Math.min(t.risk.expiresAt,e+864e5),killSwitchRequired:!0}}async function mo(t,e={},r={}){let n=uo(e),s=fo(n,r);if(t==="draft")return{strategy:_r(n.prompt,{nowMs:s})};if(t==="validate"){let a=K(n.strategy);if(a.strategy.risk.expiresAt<=s)throw new Error("strategy is expired");return{valid:!0,strategy:a.strategy,strategyHash:a.strategyHash,compilerHash:a.compilerHash,compilerVersion:a.compilerVersion,requiredSeries:a.requiredSeries}}if(t==="backtest"||t==="evidence"){let a=K(n.strategy),o=await Pe(a.strategy,n,r,s);Ot(a,o);let i=ue(zr(n,a.strategy,o,s));return t==="evidence"?i:{backtest:lt(a.strategy,o,Te(n,s)),evidence:i}}if(t==="optimize"){let a=K(n.strategy),o=await Pe(a.strategy,n,r,s);Ot(a,o);let i=n.trainFraction,l=n.evidenceOptions?.trainFraction;if(i!=null&&l!=null&&i!==l)throw new TypeError("conflicting trainFraction controls are forbidden");let f=i??l??.7;if(typeof f!="number"||f<=0||f>=1)throw new TypeError("trainFraction must be in (0,1)");let u=o.slice(0,Math.floor(o.length*f)),c=n.options??{};if(!Rt(c))throw new TypeError("options must be a plain object");let d=Rr(a.strategy,u,{...c,...n.maxTrials==null?{}:{maxTrials:n.maxTrials},backtestOptions:Te(n,s)}),m=d.bestStrategy;return{strategy:m,optimization:d,evidence:ue(zr(n,m,o,s,{trainFraction:f}))}}if(t==="shadow"){let a=Ae({storePath:r.storePath??Vr(),clock:()=>s}),o=n.action;if(o==="start")return await a.start({strategy:n.strategy,evidenceId:n.evidenceId??n.evidence?.id??null});if(o==="list")return await a.list();if(o==="get")return await a.get(n.id);if(o==="stop")return await a.stop(n.id);if(o==="step"){let i=await a.get(n.id);if(!i)throw new Error(`shadow runner not found: ${n.id}`);let l=await Pe(i.strategy,n,r,s);return Ot(K(i.strategy),l),await a.step(n.id,l,n.stepOptions??{})}throw new Error(`unknown shadow action: ${o}`)}if(t==="prepare"){let a=K(n.strategy);if(typeof n.shadowId!="string"||!n.shadowId)throw new Error("strategy prepare requires a matching shadow runner id");let i=await Ae({storePath:r.storePath??Vr(),clock:()=>s}).get(n.shadowId);if(!i)throw new Error("strategy prepare shadow runner not found");if(i.status!=="running")throw new Error("strategy prepare requires an active shadow runner");if(!Number.isFinite(i.cursor))throw new Error("strategy prepare requires a stepped shadow runner");if(i.strategyHash!==a.strategyHash||i.compilerHash!==a.compilerHash)throw new Error("strategy prepare shadow runner does not match strategy artifacts");if(i.evidenceId!==n.evidence?.id)throw new Error("strategy prepare shadow runner does not match evidence artifact");let l=n.caps??po(a.strategy,s);return pr({strategy:a.strategy,evidence:n.evidence,shadow:{id:i.id,stateHash:Br(i),status:i.status,cursor:i.cursor,updatedAt:i.updatedAt},caps:l,nowMs:s,env:r.env??process.env})}throw new Error(`unknown strategy operation: ${t}`)}var co,Kr=z(()=>{Bt();pt();fe();mr();$r();Ir();jr();Dr();co=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});import Yr from"node:fs";function ho(t){let e={},r=[];for(let n=0;n<t.length;n++){let s=t[n];if(!s.startsWith("--")){r.push(s);continue}let a=s.slice(2),o=t[n+1];o!=null&&!o.startsWith("--")?(e[a]=o,n++):e[a]=!0}return{flags:e,positional:r}}function ht(t,e){if(!t)throw new Error(`${e} path required`);let r=t==="-"?Yr.readFileSync(0,"utf8"):Yr.readFileSync(t,"utf8");try{return JSON.parse(r)}catch{throw new Error(`${e} must contain valid JSON`)}}function Gr(t,e){if(t==null)return;let r=Number(t);if(!Number.isFinite(r))throw new Error(`${e} must be a finite number`);return r}var yo=`oracle strategy <draft|validate|backtest|optimize|evidence|shadow|prepare> [args]
|
|
4
|
+
|
|
5
|
+
oracle strategy draft "Long BTC when the 20 EMA crosses above the 50 EMA"
|
|
6
|
+
oracle strategy validate strategy.json
|
|
7
|
+
oracle strategy backtest strategy.json [--bars bars.json] [--count 1500]
|
|
8
|
+
oracle strategy optimize strategy.json [--bars bars.json] [--max-trials 64]
|
|
9
|
+
oracle strategy evidence strategy.json [--bars bars.json]
|
|
10
|
+
oracle strategy shadow list
|
|
11
|
+
oracle strategy shadow start strategy.json
|
|
12
|
+
oracle strategy shadow step <id> [--bars bars.json]
|
|
13
|
+
oracle strategy shadow stop <id>
|
|
14
|
+
oracle strategy prepare strategy.json --evidence evidence.json --shadow-id <id> [--caps caps.json]
|
|
15
|
+
|
|
16
|
+
Strategy simulation and shadowing are local and deterministic. Prepare returns an integrity-bound artifact, HMAC-authenticated when local attestation is configured. Oracle public never signs or broadcasts.
|
|
17
|
+
`,Ai={name:"strategy",summary:"deterministic Hyperliquid strategy lab, evidence, shadow, prepare-only handoff",group:"read",usage:"oracle strategy <draft|validate|backtest|optimize|evidence|shadow|prepare> [args]",async run(t){let{flags:e,positional:r}=ho(t.argv);if(e.help||r.length===0)return process.stdout.write(yo),0;let[n,...s]=r,{runStrategyOperation:a}=await Promise.resolve().then(()=>(Kr(),Jr)),o={nowMs:Date.now(),count:Gr(e.count,"count")};if(n==="draft")o.prompt=s.join(" ").trim();else if(["validate","backtest","optimize","evidence"].includes(n))o.strategy=ht(s[0],"strategy"),e.bars&&(o.bars=ht(e.bars,"bars")),o.maxTrials=Gr(e["max-trials"],"max-trials");else if(n==="shadow"){let l=s[0];if(!l)throw new Error("shadow action required");o.action=l,l==="start"&&(o.strategy=ht(s[1],"strategy")),l==="step"&&(o.id=s[1],e.bars&&(o.bars=ht(e.bars,"bars"))),l==="stop"&&(o.id=s[1])}else if(n==="prepare")o.strategy=ht(s[0],"strategy"),o.evidence=ht(e.evidence,"evidence"),o.shadowId=e["shadow-id"],e.caps&&(o.caps=ht(e.caps,"caps"));else throw new Error(`unknown strategy operation: ${n}`);let i=await a(n,o);return process.stdout.write(`${JSON.stringify(i,null,2)}
|
|
18
|
+
`),0}};export{Ai as default};
|