@oracle-agent/oracle 0.13.1 → 0.14.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/CONTRIBUTING.md +99 -0
- package/README.md +20 -14
- package/SECURITY.md +6 -8
- package/SETUP.md +25 -27
- package/bin/desk-server.mjs +473 -0
- package/bin/oracle-data-mcp.mjs +1252 -0
- package/bin/oracle-equities.mjs +168 -0
- package/bin/oracle-init.mjs +525 -0
- package/bin/oracle-public-server.mjs +36 -0
- package/bin/oracle-route.mjs +254 -0
- package/bin/oracle-scan.mjs +192 -0
- package/bin/oracle-upgrade.mjs +42 -0
- package/bin/oracle.mjs +34 -0
- package/docs/adding-a-chain.md +229 -0
- package/docs/architecture.md +139 -0
- package/docs/buzz-integration.md +115 -0
- package/docs/cli.md +143 -0
- package/docs/connectors.md +13 -0
- package/docs/hyperliquid-builder-code.md +50 -0
- package/docs/locals-only-fee-waiver.md +34 -0
- package/docs/oracle-pack-standard.md +29 -0
- package/docs/profiles.md +151 -0
- package/docs/public-surface.md +206 -0
- package/examples/add-a-chain.mjs +65 -0
- package/examples/oracle-pack-template.mjs +38 -0
- package/examples/research-a-token.mjs +70 -0
- package/package.json +78 -32
- package/plugins/oracle-owner-gate/__init__.py +288 -0
- package/plugins/oracle-owner-gate/plugin.yaml +9 -0
- package/{dist/assets/profiles → profiles}/oracle/SOUL.md +0 -14
- package/protocols/templates/safe-erc20/SECURITY.md +16 -0
- package/protocols/templates/safe-erc20/foundry.toml +12 -0
- package/protocols/templates/safe-erc20/remappings.txt +2 -0
- package/protocols/templates/safe-erc20/src/SafeERC20.sol +53 -0
- package/protocols/templates/safe-erc20/test/SafeERC20.t.sol +72 -0
- package/public/oracle-splash/_variants/ice.html +3 -3
- package/public/oracle-splash/_variants/ivory.html +3 -3
- package/public/oracle-splash/downloads/index.html +34 -223
- package/public/oracle-splash/index.html +11 -11
- package/scripts/adversarial-bench.mjs +114 -0
- package/scripts/build-dist.mjs +119 -0
- package/scripts/build-inscription.py +230 -0
- package/scripts/check-doc-drift.mjs +123 -0
- package/scripts/check-test-count.mjs +105 -0
- package/scripts/e2e-hl-markets.mjs +21 -0
- package/scripts/e2e-hl-perps.mjs +48 -0
- package/scripts/e2e-hypercore-staking.mjs +128 -0
- package/scripts/e2e-solana-bitcoin.mjs +183 -0
- package/scripts/guard-publish.mjs +22 -0
- package/scripts/protocol-template-gate.mjs +15 -0
- package/scripts/public-api-scan.mjs +23 -0
- package/scripts/publish-dist.mjs +67 -0
- package/scripts/record-hero-cli.sh +80 -0
- package/scripts/secret-scan.mjs +168 -0
- package/scripts/smoke-dist-bins.mjs +89 -0
- package/scripts/verify-dist.mjs +29 -0
- package/scripts/verify-v3-venues.mjs +233 -0
- package/skins/oracle.yaml +56 -0
- package/src/action-receipts.mjs +265 -0
- package/src/action-semantics.mjs +62 -0
- package/src/address-book.mjs +208 -0
- package/src/agent-auth.mjs +206 -0
- package/src/approval-guard.mjs +282 -0
- package/src/attestation-secret.mjs +94 -0
- package/src/audit-log.mjs +196 -0
- package/src/auth/oauth.mjs +672 -0
- package/src/auto-slippage.mjs +378 -0
- package/src/capability-posture.mjs +125 -0
- package/src/cards.mjs +422 -0
- package/src/chains.mjs +62 -0
- package/src/cli/chain-catalog.mjs +215 -0
- package/src/cli/chain-state.mjs +74 -0
- package/src/cli/commands/auth.mjs +193 -0
- package/src/cli/commands/bootstrap.mjs +87 -0
- package/src/cli/commands/chain.mjs +143 -0
- package/src/cli/commands/chat.mjs +465 -0
- package/src/cli/commands/credential.mjs +9 -0
- package/src/cli/commands/data-mcp.mjs +18 -0
- package/src/cli/commands/data.mjs +75 -0
- package/src/cli/commands/doctor.mjs +136 -0
- package/src/cli/commands/equities.mjs +41 -0
- package/src/cli/commands/farm.mjs +129 -0
- package/src/cli/commands/fees.mjs +109 -0
- package/src/cli/commands/follow.mjs +130 -0
- package/src/cli/commands/harness.mjs +63 -0
- package/src/cli/commands/help.mjs +7 -0
- package/src/cli/commands/init.mjs +27 -0
- package/src/cli/commands/mcp.mjs +154 -0
- package/src/cli/commands/model.mjs +106 -0
- package/src/cli/commands/plugins.mjs +241 -0
- package/src/cli/commands/prepare.mjs +12 -0
- package/src/cli/commands/public.mjs +20 -0
- package/src/cli/commands/resolve.mjs +64 -0
- package/src/cli/commands/route.mjs +12 -0
- package/src/cli/commands/runner.mjs +9 -0
- package/src/cli/commands/scan.mjs +12 -0
- package/src/cli/commands/setup.mjs +294 -0
- package/src/cli/commands/sign.mjs +21 -0
- package/src/cli/commands/signer.mjs +9 -0
- package/src/cli/commands/swap.mjs +102 -0
- package/src/cli/commands/upgrade.mjs +12 -0
- package/src/cli/commands/vault.mjs +9 -0
- package/src/cli/commands/version.mjs +22 -0
- package/src/cli/first-run.mjs +23 -0
- package/src/cli/kernel.mjs +262 -0
- package/src/cli/mcp-targets/chatgpt.mjs +51 -0
- package/src/cli/mcp-targets/claude-code.mjs +39 -0
- package/src/cli/mcp-targets/claude-desktop.mjs +24 -0
- package/src/cli/mcp-targets/codex.mjs +41 -0
- package/src/cli/mcp-targets/cursor.mjs +32 -0
- package/src/cli/mcp-targets/shared.mjs +71 -0
- package/src/cli/mcp-targets/vscode.mjs +39 -0
- package/src/cli/messaging-platforms.mjs +217 -0
- package/src/cli/model-config.mjs +78 -0
- package/src/cli/operator-dispatch.mjs +257 -0
- package/src/cli/oracle-harness.py +415 -0
- package/src/cli/paths.mjs +107 -0
- package/src/cli/runtime.mjs +351 -0
- package/src/cli/setup-state.mjs +168 -0
- package/src/cli/spawn-child.mjs +43 -0
- package/src/data/catalog.mjs +858 -0
- package/src/data/desk-data.mjs +877 -0
- package/src/data/http.mjs +253 -0
- package/src/data/names.mjs +188 -0
- package/src/data/provider-endpoint.mjs +94 -0
- package/src/data/providers/aave-v3.mjs +139 -0
- package/src/data/providers/across-bridge.mjs +41 -0
- package/src/data/providers/aerodrome.mjs +245 -0
- package/src/data/providers/aevo.mjs +33 -0
- package/src/data/providers/approval-indexer.mjs +133 -0
- package/src/data/providers/approvals.mjs +594 -0
- package/src/data/providers/babylon-staking.mjs +149 -0
- package/src/data/providers/balancer.mjs +209 -0
- package/src/data/providers/beefy-yields.mjs +45 -0
- package/src/data/providers/birdeye-tokens.mjs +33 -0
- package/src/data/providers/bisq-markets.mjs +145 -0
- package/src/data/providers/bitcoin-esplora.mjs +216 -0
- package/src/data/providers/bitcoin-meta.mjs +378 -0
- package/src/data/providers/blockscout.mjs +14 -0
- package/src/data/providers/bob-rootstock.mjs +198 -0
- package/src/data/providers/braiins-insights.mjs +103 -0
- package/src/data/providers/bridge-aggregator.mjs +259 -0
- package/src/data/providers/bridges.mjs +242 -0
- package/src/data/providers/bungee.mjs +29 -0
- package/src/data/providers/celestia-da.mjs +38 -0
- package/src/data/providers/changenow.mjs +135 -0
- package/src/data/providers/compound.mjs +32 -0
- package/src/data/providers/connext.mjs +28 -0
- package/src/data/providers/convex.mjs +30 -0
- package/src/data/providers/cow-protocol.mjs +110 -0
- package/src/data/providers/cowswap.mjs +415 -0
- package/src/data/providers/curve.mjs +201 -0
- package/src/data/providers/das-assets.mjs +59 -0
- package/src/data/providers/debridge.mjs +109 -0
- package/src/data/providers/defillama.mjs +88 -0
- package/src/data/providers/dexscreener.mjs +43 -0
- package/src/data/providers/drift.mjs +32 -0
- package/src/data/providers/dydx.mjs +41 -0
- package/src/data/providers/evm-rpc.mjs +225 -0
- package/src/data/providers/farming.mjs +291 -0
- package/src/data/providers/geckoterminal.mjs +34 -0
- package/src/data/providers/gmx.mjs +496 -0
- package/src/data/providers/hiro-stacks.mjs +150 -0
- package/src/data/providers/hl-assets.mjs +165 -0
- package/src/data/providers/hl-info.mjs +108 -0
- package/src/data/providers/hl-markets.mjs +210 -0
- package/src/data/providers/hl-outcome.mjs +61 -0
- package/src/data/providers/hl-perps.mjs +419 -0
- package/src/data/providers/hl-staking.mjs +353 -0
- package/src/data/providers/hl-ws.mjs +119 -0
- package/src/data/providers/hyperevm-dex.mjs +49 -0
- package/src/data/providers/jito-mev.mjs +117 -0
- package/src/data/providers/jupiter-venues.mjs +119 -0
- package/src/data/providers/jupiter.mjs +315 -0
- package/src/data/providers/kamino-strategies.mjs +143 -0
- package/src/data/providers/l2beat-tvl.mjs +42 -0
- package/src/data/providers/lifi.mjs +166 -0
- package/src/data/providers/liquid-esplora.mjs +152 -0
- package/src/data/providers/magiceden-ordinals.mjs +141 -0
- package/src/data/providers/magiceden-sol.mjs +406 -0
- package/src/data/providers/mempool-lightning.mjs +144 -0
- package/src/data/providers/mempool-mining.mjs +142 -0
- package/src/data/providers/meteora-dlmm.mjs +168 -0
- package/src/data/providers/morpho.mjs +177 -0
- package/src/data/providers/nft-gallery.mjs +163 -0
- package/src/data/providers/nft-portfolio.mjs +494 -0
- package/src/data/providers/odos.mjs +156 -0
- package/src/data/providers/ondo.mjs +31 -0
- package/src/data/providers/oneinch.mjs +174 -0
- package/src/data/providers/opensea-multichain.mjs +136 -0
- package/src/data/providers/opensea-nft.mjs +371 -0
- package/src/data/providers/orca.mjs +29 -0
- package/src/data/providers/ordinals-runes.mjs +180 -0
- package/src/data/providers/pancakeswap.mjs +28 -0
- package/src/data/providers/paraswap.mjs +125 -0
- package/src/data/providers/pendle.mjs +188 -0
- package/src/data/providers/poly-clob.mjs +283 -0
- package/src/data/providers/poly-public.mjs +96 -0
- package/src/data/providers/poly-ws.mjs +103 -0
- package/src/data/providers/polygon-staking.mjs +227 -0
- package/src/data/providers/portfolio-history.mjs +394 -0
- package/src/data/providers/portfolio.mjs +600 -0
- package/src/data/providers/pyth-price-feeds.mjs +172 -0
- package/src/data/providers/raydium.mjs +35 -0
- package/src/data/providers/relayscan-mev.mjs +72 -0
- package/src/data/providers/rfq.mjs +15 -0
- package/src/data/providers/rh-agent.mjs +59 -0
- package/src/data/providers/sanctum-lst.mjs +180 -0
- package/src/data/providers/satflow.mjs +341 -0
- package/src/data/providers/signed-material-guard.mjs +108 -0
- package/src/data/providers/solana-rpc.mjs +197 -0
- package/src/data/providers/solend-lending.mjs +166 -0
- package/src/data/providers/spark-lend.mjs +42 -0
- package/src/data/providers/squid-router.mjs +29 -0
- package/src/data/providers/stargate.mjs +29 -0
- package/src/data/providers/sushiswap.mjs +30 -0
- package/src/data/providers/symbiotic-restaking.mjs +41 -0
- package/src/data/providers/thorchain.mjs +36 -0
- package/src/data/providers/traderjoe.mjs +28 -0
- package/src/data/providers/twap.mjs +152 -0
- package/src/data/providers/uniswap-v3.mjs +457 -0
- package/src/data/providers/uniswap-v4.mjs +414 -0
- package/src/data/providers/vertex.mjs +41 -0
- package/src/data/providers/wallet-watch.mjs +264 -0
- package/src/data/providers/wormhole.mjs +28 -0
- package/src/data/providers/yearn.mjs +31 -0
- package/src/data/providers/zerox.mjs +167 -0
- package/src/data/public-api-scan.mjs +61 -0
- package/src/data/quote-placeholder.mjs +31 -0
- package/src/desk/swap-prepare.mjs +194 -0
- package/src/equities/bridge.mjs +388 -0
- package/src/equities/fixtures/bridge_routes.json +159 -0
- package/src/equities/fixtures/dst_transitions.json +29 -0
- package/src/equities/fixtures/equity_dex_pools.json +154 -0
- package/src/equities/fixtures/hip3_l2books.json +2711 -0
- package/src/equities/fixtures/nyse_holidays.json +1 -0
- package/src/equities/fixtures/oracles.json +100 -0
- package/src/equities/fixtures/rh_pool_state.json +244 -0
- package/src/equities/fixtures/solana_xstocks.json +704 -0
- package/src/equities/fixtures/ton_xstocks.json +35 -0
- package/src/equities/fixtures/universe.json +411 -0
- package/src/equities/fixtures/venues.json +3542 -0
- package/src/equities/fixtures.mjs +405 -0
- package/src/equities/funding.mjs +142 -0
- package/src/equities/index.mjs +166 -0
- package/src/equities/liveness.mjs +148 -0
- package/src/equities/marketHours.mjs +249 -0
- package/src/equities/normalize.mjs +295 -0
- package/src/equities/num.mjs +146 -0
- package/src/equities/prepare.mjs +95 -0
- package/src/equities/rank.mjs +260 -0
- package/src/equities/sourceNum.mjs +69 -0
- package/src/equities/types.mjs +220 -0
- package/src/equities/venues/arcus-perp.mjs +84 -0
- package/src/equities/venues/arcus-spot.mjs +105 -0
- package/src/equities/venues/hyperliquid-hip3.mjs +224 -0
- package/src/equities/venues/rh-uniswap.mjs +216 -0
- package/src/equities/venues/solana-xstocks.mjs +139 -0
- package/src/equities/venues/ton-stonfi.mjs +139 -0
- package/src/exact-integer.mjs +72 -0
- package/src/exec-policy.mjs +419 -0
- package/src/flags.mjs +15 -0
- package/src/fresh-window.mjs +76 -0
- package/src/gmx-attestation.mjs +176 -0
- package/src/index.mjs +107 -0
- package/src/licensing/locals-only.mjs +25 -0
- package/src/nft-gas-war-guard.mjs +139 -0
- package/src/onboarding/agent-keys.mjs +161 -0
- package/src/onboarding/harness-configs.mjs +102 -0
- package/src/onboarding/index.mjs +18 -0
- package/src/onboarding/tiers.mjs +139 -0
- package/src/oracle-env.mjs +55 -0
- package/src/package-manifest.mjs +42 -0
- package/src/plugins/agent-plugin-loader.mjs +225 -0
- package/src/portfolio-risk.mjs +170 -0
- package/src/prepare-envelope.mjs +204 -0
- package/src/profile-upgrade.mjs +277 -0
- package/src/protocol-execution.mjs +84 -0
- package/src/protocol-templates/gate.mjs +179 -0
- package/src/protocol-templates/prepare-deploy.mjs +81 -0
- package/src/public-api/agent-grants.mjs +57 -0
- package/src/public-api/buzz-integration.mjs +267 -0
- package/src/public-api/connect-agent.mjs +424 -0
- package/src/public-api/grants.mjs +142 -0
- package/src/public-api/http.mjs +707 -0
- package/src/public-api/metering.mjs +111 -0
- package/src/public-control/aa-adapter.mjs +402 -0
- package/src/public-control/build-registry.mjs +227 -0
- package/src/public-control/bundler-client.mjs +357 -0
- package/src/public-control/grant-indexer.mjs +296 -0
- package/src/public-control/policy-render.mjs +69 -0
- package/src/public-control/policy-schema.mjs +322 -0
- package/src/public-control/runtime-config.mjs +275 -0
- package/src/public-control/session-key-model.mjs +379 -0
- package/src/public-control/session-orchestrator.mjs +418 -0
- package/src/rfq/intent.mjs +180 -0
- package/src/rfq/sources.mjs +181 -0
- package/src/route-attestation.mjs +132 -0
- package/src/router/best-execution.mjs +326 -0
- package/src/router/index.mjs +250 -0
- package/src/router/integrator-fee.mjs +135 -0
- package/src/router/prepare-bridge.mjs +293 -0
- package/src/router/prepare-route.mjs +398 -0
- package/src/router/proposal.mjs +311 -0
- package/src/router/risk-classifier.mjs +119 -0
- package/src/router/route-sources.mjs +364 -0
- package/src/scanner/chains.config.mjs +543 -0
- package/src/scanner/contract.mjs +270 -0
- package/src/scanner/evm-scanner.mjs +394 -0
- package/src/scanner/index.mjs +9 -0
- package/src/scanner/v2-venue.mjs +351 -0
- package/src/scanner/v3-venue.mjs +308 -0
- package/src/scopes.mjs +44 -0
- package/src/sell-simulation.mjs +167 -0
- package/src/signals/engine.mjs +146 -0
- package/src/signals/index.mjs +1 -0
- package/src/token-transfer-guard.mjs +188 -0
- package/src/tui/app.mjs +438 -0
- package/src/tui/backend.mjs +215 -0
- package/src/tui/format.mjs +272 -0
- package/src/tui/gateway-client.mjs +177 -0
- package/src/tui/input.mjs +501 -0
- package/src/tui/memory.mjs +105 -0
- package/src/tui/meta-learn.mjs +85 -0
- package/src/tui/renderer.mjs +443 -0
- package/src/tui/scheduler.mjs +205 -0
- package/src/tui/skills-loader.mjs +140 -0
- package/src/tui/standalone-client.mjs +752 -0
- package/src/tui/theme.mjs +81 -0
- package/src/vault-attestation.mjs +146 -0
- package/src/venues.mjs +206 -0
- package/src/watch-preferences.mjs +85 -0
- package/dist/action-receipts.mjs +0 -1
- package/dist/action-semantics.mjs +0 -1
- package/dist/address-book.mjs +0 -2
- package/dist/bin/desk-server.mjs +0 -59
- package/dist/bin/oracle-data-mcp.mjs +0 -8
- package/dist/bin/oracle-equities.mjs +0 -20
- package/dist/bin/oracle-init.mjs +0 -24
- package/dist/bin/oracle-public-server.mjs +0 -5
- package/dist/bin/oracle-route.mjs +0 -22
- package/dist/bin/oracle-scan.mjs +0 -18
- package/dist/bin/oracle-upgrade.mjs +0 -21
- package/dist/bin/oracle.mjs +0 -76
- package/dist/chains.mjs +0 -1
- package/dist/cli/commands/auth.mjs +0 -16
- package/dist/cli/commands/bootstrap.mjs +0 -18
- package/dist/cli/commands/chain.mjs +0 -21
- package/dist/cli/commands/chat.mjs +0 -45
- package/dist/cli/commands/credential.mjs +0 -1
- package/dist/cli/commands/data-mcp.mjs +0 -2
- package/dist/cli/commands/data.mjs +0 -12
- package/dist/cli/commands/doctor.mjs +0 -5
- package/dist/cli/commands/equities.mjs +0 -15
- package/dist/cli/commands/farm.mjs +0 -59
- package/dist/cli/commands/follow.mjs +0 -28
- package/dist/cli/commands/gate.mjs +0 -13
- package/dist/cli/commands/harness.mjs +0 -15
- package/dist/cli/commands/help.mjs +0 -1
- package/dist/cli/commands/init.mjs +0 -3
- package/dist/cli/commands/mcp.mjs +0 -60
- package/dist/cli/commands/model.mjs +0 -54
- package/dist/cli/commands/plugins.mjs +0 -38
- package/dist/cli/commands/prepare.mjs +0 -2
- package/dist/cli/commands/public.mjs +0 -3
- package/dist/cli/commands/resolve.mjs +0 -23
- package/dist/cli/commands/route.mjs +0 -2
- package/dist/cli/commands/runner.mjs +0 -1
- package/dist/cli/commands/scan.mjs +0 -2
- package/dist/cli/commands/setup.mjs +0 -34
- package/dist/cli/commands/sign.mjs +0 -21
- package/dist/cli/commands/signer.mjs +0 -1
- package/dist/cli/commands/swap.mjs +0 -36
- package/dist/cli/commands/upgrade.mjs +0 -2
- package/dist/cli/commands/vault.mjs +0 -1
- package/dist/cli/commands/version.mjs +0 -2
- package/dist/data/desk-data.mjs +0 -55
- package/dist/data/names.mjs +0 -2
- package/dist/data/providers/farming.mjs +0 -2
- package/dist/equities/index.mjs +0 -1
- package/dist/index.mjs +0 -60
- package/dist/nft-gas-war-guard.mjs +0 -1
- package/dist/onboarding/harness-configs.mjs +0 -4
- package/dist/portfolio-risk.mjs +0 -1
- package/dist/prepare-envelope.mjs +0 -1
- package/dist/public-api/agent-grants.mjs +0 -3
- package/dist/public-control/policy-schema.mjs +0 -1
- package/dist/router/index.mjs +0 -2
- package/dist/scanner/index.mjs +0 -4
- package/dist/signals/index.mjs +0 -1
- package/dist/watch-preferences.mjs +0 -1
- /package/{dist/assets/profiles → profiles}/_template/SOUL.md +0 -0
- /package/{dist/assets/profiles → profiles}/_template/profile.json +0 -0
- /package/{dist/assets/profiles → profiles}/bitcoin-agent/SOUL.md +0 -0
- /package/{dist/assets/profiles → profiles}/bitcoin-agent/profile.json +0 -0
- /package/{dist/assets/profiles → profiles}/hyperliquid-agent/SOUL.md +0 -0
- /package/{dist/assets/profiles → profiles}/hyperliquid-agent/profile.json +0 -0
- /package/{dist/assets/profiles → profiles}/oracle/profile.json +0 -0
- /package/{dist/assets/profiles → profiles}/polymarket-agent/SOUL.md +0 -0
- /package/{dist/assets/profiles → profiles}/polymarket-agent/profile.json +0 -0
- /package/{dist/assets/profiles → profiles}/profile.schema.json +0 -0
- /package/{dist/assets/profiles → profiles}/protocol-builder/SOUL.md +0 -0
- /package/{dist/assets/profiles → profiles}/protocol-builder/profile.json +0 -0
- /package/{dist/assets/profiles → profiles}/robinhood-agent/SOUL.md +0 -0
- /package/{dist/assets/profiles → profiles}/robinhood-agent/profile.json +0 -0
- /package/{dist/assets/profiles → profiles}/solana-agent/SOUL.md +0 -0
- /package/{dist/assets/profiles → profiles}/solana-agent/profile.json +0 -0
- /package/{dist/assets/profiles → profiles}/stable-agent/SOUL.md +0 -0
- /package/{dist/assets/profiles → profiles}/stable-agent/profile.json +0 -0
- /package/{dist/assets/skills → skills}/balance/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/bitcoin-l1.md +0 -0
- /package/{dist/assets/skills → skills}/chain-defi-ecosystem-profiling.md +0 -0
- /package/{dist/assets/skills → skills}/evm-contract-research.md +0 -0
- /package/{dist/assets/skills → skills}/hyperliquid.md +0 -0
- /package/{dist/assets/skills → skills}/multichain-exec-desk.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-action-semantics/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-best-execution/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-best-execution.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-bitcoin/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-chain-graphs-telegram-cards/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-chat/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-chat/chain.SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-chat/setup.SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-circuit-breaker/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-contract-research/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-desk/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-desk.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-dex-launch/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-equities/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-grants/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-hypercore-staking/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-hyperliquid/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-meme-token-sniper/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-multichain-nft-launch/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-multichain-token-launch/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-nft-gacha-launch/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-nft-mint-gas-war/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-polymarket/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-protocol-builder/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-protocol-security/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-public-product/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-receipts/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-receipts.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-rfq-tokenized-assets/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-smart-wallet-scanner/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-solana/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-solana-nft/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/oracle-token-research/SKILL.md +0 -0
- /package/{dist/assets/skills → skills}/solana.md +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Locals Only fee waiver
|
|
2
|
+
|
|
3
|
+
Oracle is public to everyone. Source access, npm installation, CLI commands,
|
|
4
|
+
desktop downloads, ordinary product use, and execution arming are not gated by
|
|
5
|
+
an NFT.
|
|
6
|
+
|
|
7
|
+
It does not gate Oracle downloads, access, source, CLI use, desktop use, or
|
|
8
|
+
execution preparation.
|
|
9
|
+
|
|
10
|
+
A wallet holding a Locals Only NFT receives a **0% Oracle integrator fee**. A
|
|
11
|
+
non-holder can use the same product and routes, but the standard disclosed
|
|
12
|
+
Oracle fee applies when fee collection is configured.
|
|
13
|
+
|
|
14
|
+
## Collection
|
|
15
|
+
|
|
16
|
+
- Chain: HyperEVM, chain ID `999`
|
|
17
|
+
- Contract: `0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75`
|
|
18
|
+
- Check: read-only ERC-721 `balanceOf(address)`
|
|
19
|
+
|
|
20
|
+
The balance check does not request a signature, approval, private key, seed
|
|
21
|
+
phrase, or transaction. Run `oracle fees status` for the configured wallet or
|
|
22
|
+
`oracle fees check <address>` for any public address.
|
|
23
|
+
|
|
24
|
+
## Fee behavior
|
|
25
|
+
|
|
26
|
+
- No fee recipient configured: Oracle charges no integrator fee to anyone.
|
|
27
|
+
- Fee recipient configured, non-holder: the configured fee applies, capped at
|
|
28
|
+
100 basis points.
|
|
29
|
+
- Fee recipient configured, Locals Only holder: Oracle's integrator fee is 0%.
|
|
30
|
+
- Hyperliquid builder fees are not waived. Provider fees, bridge fees, gas,
|
|
31
|
+
slippage, LP fees, and network costs also remain separate.
|
|
32
|
+
|
|
33
|
+
Fee resolution stays separate from custody. The public package remains keyless
|
|
34
|
+
and prepare-only; the user's wallet reviews, signs, and submits.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Oracle protocol pack standard
|
|
2
|
+
|
|
3
|
+
An Oracle protocol pack is a package-safe ESM module that turns an intent into an unsigned action and decodes independently obtained receipts. A pack is an adapter, not a wallet, signer, broadcaster, or authority. See `examples/oracle-pack-template.mjs` for the smallest complete shape.
|
|
4
|
+
|
|
5
|
+
## Required surface
|
|
6
|
+
|
|
7
|
+
Every pack exports a default object with these members (named exports may mirror them):
|
|
8
|
+
|
|
9
|
+
- `provider`: stable provider identity, semantic version, supported chain IDs, and provenance/trust metadata. Remote token names, symbols, descriptions, image fields, URLs, and NFT metadata remain untrusted data.
|
|
10
|
+
- `prepare(intent)`: validates the intent and returns an unsigned transaction or typed action. It must not accept keys, sign, submit, broadcast, or report execution success.
|
|
11
|
+
- `decode(receipt)`: validates and converts a chain/provider receipt into a documented result. Unknown or malformed receipts fail closed.
|
|
12
|
+
- `riskRules`: an array or function describing enforceable limits and refusal conditions. Human-readable warnings alone are not rules.
|
|
13
|
+
- `tests`: non-empty metadata naming the local test command and covered properties. Tests must be deterministic and require no credentials or network.
|
|
14
|
+
|
|
15
|
+
## Prompt-injection boundary
|
|
16
|
+
|
|
17
|
+
Treat every provider response and token/NFT metadata string as inert data. Never concatenate metadata into system/developer instructions, interpret it as tool directions, or let it modify recipients, calldata, limits, and policy. Render or quote it through a data channel and retain its provenance. Packs should test adversarial values such as “ignore previous instructions,” requests for secrets, and demands to sign or invoke tools.
|
|
18
|
+
|
|
19
|
+
## Custody boundary
|
|
20
|
+
|
|
21
|
+
Pack exports must not expose signers, wallets, private keys, seed phrases, signing functions, transaction submission, or broadcasting. `prepare` returns data to a separately authorized custody surface. Environment variables and provider credentials must not appear in prepared output, logs, errors, fixtures, or metadata. Imports should be side-effect free; merely loading a pack must not make network calls.
|
|
22
|
+
|
|
23
|
+
## Receipt gate
|
|
24
|
+
|
|
25
|
+
Preparation is not execution. A prepared result declares a `receiptGate` and consumers must not mark an action successful until `decode` receives a receipt from an independent, trusted transport and verifies its chain, transaction identity, status, and required confirmations. Timeouts, pending receipts, mismatches, reverts, and undecodable responses are not success.
|
|
26
|
+
|
|
27
|
+
## Local adversarial benchmark
|
|
28
|
+
|
|
29
|
+
Run `node scripts/adversarial-bench.mjs <pack.mjs> [...]`. It imports only the named local modules, invokes no pack functions, emits one deterministic JSON summary, and exits `1` when a gate fails (`2` for usage/load errors). It checks required surface fields, forbidden custody exports, missing test metadata, and prompt-injection strings nested in provider or pack metadata. This static public gate complements, rather than replaces, behavioral tests of preparation and receipt verification.
|
package/docs/profiles.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Agent profiles
|
|
2
|
+
|
|
3
|
+
Oracle is not one agent. It's a mesh of specialists with a router in front.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
you
|
|
7
|
+
|
|
|
8
|
+
Task
|
|
9
|
+
|
|
|
10
|
+
oracle <- routes, never authorizes custody
|
|
11
|
+
|
|
|
12
|
+
+------+------+------+------+------+------+------+
|
|
13
|
+
| | | | | | | |
|
|
14
|
+
poly hyper robin solana bitcoin stable protocol
|
|
15
|
+
market liquid hood builder
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Each lane is a [Hermes](https://github.com/NousResearch/hermes-agent) **profile**:
|
|
19
|
+
its own system prompt, skill set, memory, and session store. They share a wallet
|
|
20
|
+
policy and a receipts discipline, nothing else.
|
|
21
|
+
|
|
22
|
+
## Why profiles instead of one big agent
|
|
23
|
+
|
|
24
|
+
Three practical reasons, learned the hard way:
|
|
25
|
+
|
|
26
|
+
1. **Context stays small.** A Polymarket question shouldn't load Bitcoin
|
|
27
|
+
ordinals knowledge. Smaller context is cheaper, faster, and more accurate.
|
|
28
|
+
2. **Memory doesn't cross-contaminate.** What the perps lane learned about
|
|
29
|
+
funding rates should not leak into the NFT lane's judgment.
|
|
30
|
+
3. **Blast radius is bounded.** A grant scoped to one lane's venues can't be
|
|
31
|
+
spent by another.
|
|
32
|
+
|
|
33
|
+
## The lanes
|
|
34
|
+
|
|
35
|
+
| Profile | Owns | Typical grant |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `oracle` | routing, synthesis, multi-chain comparison, `/balance` portfolio aggregation | read + simulate only |
|
|
38
|
+
| `polymarket-agent` | prediction markets, event odds, CLOB cards/API-key order intents | read, quote, prepare |
|
|
39
|
+
| `hyperliquid-agent` | perps, spot, HIP-3 builder dexs, HIP-4 outcomes | read, quote, prepare |
|
|
40
|
+
| `robinhood-agent` | Robinhood Chain (4663) tokens, NFTs, tokenized Robinhood-style assets, capped NFT mints | read, quote, prepare |
|
|
41
|
+
| `solana-agent` | Solana swaps, research, Jupiter routes | read, quote, prepare |
|
|
42
|
+
| `bitcoin-agent` | Bitcoin L1, Ordinals/runes, inscriptions | read, prepare:inscription |
|
|
43
|
+
| `stable-agent` | Stable (988), USDT-native gas quirks | read, quote, prepare |
|
|
44
|
+
| `protocol-builder` | scaffold, review, prepare chain-family token/NFT collections, gacha, DEX, and protocol deploys | prepare:deploy, prepare:mint, simulate |
|
|
45
|
+
| `_template` | your new lane | you decide |
|
|
46
|
+
|
|
47
|
+
These grants describe the public prepare plane, not every capability an operator may install beside it. The generic unattended signer exposes six bounded surfaces (`hl`, `poly`, `evm-swap`, `evm-bridge`, `btc`, `sol`), each of which decodes its own envelope and refuses while its allowlists are empty. A separately installed, same-host, owner-gated EVM executor may expose one exact bounded action after explicit `arm`; profiles must verify it before claiming availability. `watch`, `watch this`, and `ping me` remain `alert_only` regardless of executor presence.
|
|
48
|
+
|
|
49
|
+
`protocol-builder` classifies each launch by chain family, then designs and
|
|
50
|
+
prepares unsigned token, NFT collection, protocol, or mint-bot transactions. It
|
|
51
|
+
fails closed when no verified adapter exists, never house-signs, and keeps deploy,
|
|
52
|
+
metadata, liquidity, mint, and authority actions as separate user approvals.
|
|
53
|
+
|
|
54
|
+
The root `oracle` lane owns `/balance`, natural-language balance, and portfolio
|
|
55
|
+
history requests. Its `balance` skill calls the read-only
|
|
56
|
+
`portfolio_snapshot` MCP tool once, records a compact profile-local observation,
|
|
57
|
+
reports partial coverage and unavailable providers, and labels `knownUsd` as
|
|
58
|
+
incomplete instead of inventing a full portfolio total. `portfolio_history`
|
|
59
|
+
reads those observations and `portfolio_value_graph` renders the known-value
|
|
60
|
+
series while omitting unavailable values rather than plotting fake zeroes.
|
|
61
|
+
|
|
62
|
+
## Model choice is yours
|
|
63
|
+
|
|
64
|
+
Oracle makes **no model calls**. It has no LLM client, no API key, no inference
|
|
65
|
+
dependency — its runtime deps are `ethers`, `viem`, and three `@noble`/`@scure`
|
|
66
|
+
crypto libraries. Every lane inherits whatever provider your Hermes is configured
|
|
67
|
+
with.
|
|
68
|
+
|
|
69
|
+
So there is nothing to sign up for. If Hermes already talks to a model, Oracle
|
|
70
|
+
works.
|
|
71
|
+
|
|
72
|
+
What profiles *do* give you is **per-lane** model choice, because each profile has
|
|
73
|
+
its own `config.yaml`:
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
# ~/.hermes/profiles/<name>/config.yaml
|
|
77
|
+
model:
|
|
78
|
+
provider: anthropic # or openai-codex, nous, xai-oauth, a local model...
|
|
79
|
+
default: claude-opus-5
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
That lets you put a heavy reasoner on the router and something cheap and fast on
|
|
83
|
+
a polling lane:
|
|
84
|
+
|
|
85
|
+
| Lane | Wants | Why |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| `oracle` | strongest reasoner | routing and synthesis need judgment |
|
|
88
|
+
| `protocol-builder` | strongest reasoner | contract review is unforgiving |
|
|
89
|
+
| `hyperliquid-agent` | fast, numeric, tool-heavy | many small tool calls |
|
|
90
|
+
| `polymarket-agent` | news-shaped reasoning | event pricing is narrative |
|
|
91
|
+
| research fan-out | cheap and parallel | breadth over depth |
|
|
92
|
+
|
|
93
|
+
Starting point, not doctrine. Benchmark on your own workload.
|
|
94
|
+
|
|
95
|
+
### If you want one login for many models
|
|
96
|
+
|
|
97
|
+
Optional convenience, not a requirement: [Nous
|
|
98
|
+
Portal](https://nousresearch.com) fronts the frontier set (Claude, GPT, Grok,
|
|
99
|
+
DeepSeek, Qwen and more) behind a single Hermes credential, so each lane can pick
|
|
100
|
+
a different model without five separate API keys and five bills.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
hermes auth add nous
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Any Hermes-supported provider works equally well. Oracle does not care.
|
|
107
|
+
|
|
108
|
+
## Creating a lane
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
hermes profile create polymarket-agent
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Then give it a `SOUL.md` (who it is, what it owns, what it must refuse) and a
|
|
115
|
+
`config.yaml` (model + provider). Point it at Oracle's MCP read plane.
|
|
116
|
+
|
|
117
|
+
`oracle-init --apply` writes this for you. Manual form (Hermes wants command and
|
|
118
|
+
args as separate tokens):
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# terminal 1 — local read plane the MCP tools call
|
|
122
|
+
npx oracle-data
|
|
123
|
+
|
|
124
|
+
# terminal 2 — wire MCP into a lane
|
|
125
|
+
hermes -p polymarket-agent mcp add oracle-data --command oracle-data-mcp
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Now that lane can read 70 provider modules covering 219 protocols/venues across
|
|
129
|
+
EVM, Solana, and Bitcoin, quote real routes, and
|
|
130
|
+
prepare unsigned transactions — and it still cannot sign anything.
|
|
131
|
+
|
|
132
|
+
## Posture
|
|
133
|
+
|
|
134
|
+
Every lane starts `DISARMED`. Arming is a deliberate, scoped, expiring act:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
grant:
|
|
138
|
+
chain: 8453
|
|
139
|
+
actions: [read:chain, simulate:tx, prepare:swap]
|
|
140
|
+
targets: [<router address>]
|
|
141
|
+
maxValueWei: <cap>
|
|
142
|
+
expiresAt: <unix ts>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
An action outside the grant is refused, not negotiated. When the grant expires,
|
|
146
|
+
the lane goes back to reading.
|
|
147
|
+
|
|
148
|
+
## A rule worth keeping
|
|
149
|
+
|
|
150
|
+
Give a lane the narrowest grant that makes it useful, and let it expire. A
|
|
151
|
+
permanent broad grant is just a hot wallet with extra steps.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Public surface
|
|
2
|
+
|
|
3
|
+
Every supported import subpath, executable, and runtime environment variable in
|
|
4
|
+
`@oracle-agent/oracle`. If something is in `exports`/`bin` it is a public
|
|
5
|
+
contract and belongs here; if it is not meant to be public it should be removed
|
|
6
|
+
from the manifest rather than left undocumented.
|
|
7
|
+
|
|
8
|
+
Generated counts are asserted by `test/public-surface-doc.test.mjs`, so this
|
|
9
|
+
file cannot silently drift from `package.json`.
|
|
10
|
+
|
|
11
|
+
## Import subpaths
|
|
12
|
+
|
|
13
|
+
| Subpath | What it gives you |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `@oracle-agent/oracle` | package root — re-exports the common surface |
|
|
16
|
+
| `@oracle-agent/oracle/data` | provider catalog + `dataCall` read plane |
|
|
17
|
+
| `@oracle-agent/oracle/policy` | grant policy schema: validation, canonicalization, caps constants |
|
|
18
|
+
| `@oracle-agent/oracle/chains` | chain registry and per-chain metadata |
|
|
19
|
+
| `@oracle-agent/oracle/scanner` | token/contract scanner capabilities |
|
|
20
|
+
| `@oracle-agent/oracle/router` | route sources and quote routing |
|
|
21
|
+
| `@oracle-agent/oracle/equities` | cross-chain on-chain equities best execution (HIP-3 / Arcus / RH / Solana / TON), prepare-only |
|
|
22
|
+
| `@oracle-agent/oracle/action-semantics` | decoded-action semantics for review |
|
|
23
|
+
| `@oracle-agent/oracle/address-book` | label store — refuses key material |
|
|
24
|
+
| `@oracle-agent/oracle/agent-grants` | bounded, revocable, time-boxed agent permissions: `planConnection` builds the unsigned grant, `activateSession` accepts the owner's signature, `revokeSession` revokes, and `listActiveGrants`/`getGrant`/`classifyGrant` read it back. Reads are pure over an injected store with an explicit clock. Oracle prepares and validates; the user signs and Oracle never holds a key |
|
|
25
|
+
| `@oracle-agent/oracle/names` | cross-chain name resolution: `.hl` (HLNames), `.hype` (dotHYPE), `.eth` (ENS), Basenames. Forward and reverse, keyless on-chain reads via the read-only RPC allowlist; never signs or broadcasts |
|
|
26
|
+
| `@oracle-agent/oracle/nft-gas-war` | NFT mint/gas-war helpers |
|
|
27
|
+
| `@oracle-agent/oracle/prepare-envelope` | `stampPrepared` / `assertPreparedEnvelope` |
|
|
28
|
+
| `@oracle-agent/oracle/connect` | deterministic MCP harness configuration snippets for Hermes, Claude Code, Codex, Cursor, and generic clients |
|
|
29
|
+
| `@oracle-agent/oracle/receipts` | caller-fact action-receipt normalization — refuses secret-bearing fields; does not verify chain success |
|
|
30
|
+
| `@oracle-agent/oracle/risk` | risk scoring helpers |
|
|
31
|
+
| `@oracle-agent/oracle/watch` | watch/alert subscriptions |
|
|
32
|
+
| `@oracle-agent/oracle/signals` | signal feed helpers |
|
|
33
|
+
| `@oracle-agent/oracle/farming` | farming method presets, live farm scoring (`discoverFarms`), and airdrop expected-value math (`airdropEV`) — read-only discovery and prepare-plan design; never signs or broadcasts |
|
|
34
|
+
|
|
35
|
+
`./package.json` is deliberately **not** exported. Do not derive internal paths
|
|
36
|
+
with `require.resolve('@oracle-agent/oracle/package.json')` — it throws
|
|
37
|
+
`ERR_PACKAGE_PATH_NOT_EXPORTED`. Invoke the shipped bins by name instead.
|
|
38
|
+
|
|
39
|
+
## Executables
|
|
40
|
+
|
|
41
|
+
| Bin | Purpose |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `oracle` | main CLI |
|
|
44
|
+
| `oracle-data` | local read-plane server (`oracle data serve`) |
|
|
45
|
+
| `oracle-public` | public-plane server (`oracle public serve`) |
|
|
46
|
+
| `oracle-data-mcp` | MCP stdio server for agent lanes |
|
|
47
|
+
| `oracle-init` | write config + attestation secret (`oracle init --apply`) |
|
|
48
|
+
| `oracle-upgrade` | in-place upgrade helper (`oracle upgrade`) |
|
|
49
|
+
| `oracle-scan` | scanner entrypoint |
|
|
50
|
+
| `oracle-route` | route/quote entrypoint |
|
|
51
|
+
| `oracle-equities` | on-chain equities best execution (HIP-3 / Arcus / RH / Solana / TON) |
|
|
52
|
+
|
|
53
|
+
## Environment variables
|
|
54
|
+
|
|
55
|
+
### Arming flags — default OFF, enable only on literal `1`
|
|
56
|
+
|
|
57
|
+
These are the gates that decide whether anything can ever be signed or
|
|
58
|
+
broadcast. `envFlag` is strict: `true`, `yes`, `on`, or any other value leaves
|
|
59
|
+
them OFF. Setting them is not sufficient to move funds — the signer's own
|
|
60
|
+
policy and custody wall still apply.
|
|
61
|
+
|
|
62
|
+
| Name | Default | Meaning |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| `ORACLE_EXECUTE_ENABLED` | off | allow the signing surface to arm at all |
|
|
65
|
+
| `ORACLE_DEPLOY_ENABLED` | off | allow contract deployment paths to arm |
|
|
66
|
+
| `ORACLE_ONBOARD_HTTP` | off | expose onboarding routes over HTTP |
|
|
67
|
+
| `ORACLE_PUBLIC_API_MODE` | off | run the server in public-plane mode |
|
|
68
|
+
| `ORACLE_ALLOW_CREATE` | off | allow create/deploy-shaped actions |
|
|
69
|
+
| `ORACLE_ALLOW_EPHEMERAL_CAPS` | off | allow ephemeral cap grants |
|
|
70
|
+
|
|
71
|
+
### Guard rails — default ON, honor disable words
|
|
72
|
+
|
|
73
|
+
| Name | Default | Meaning |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `ORACLE_VALUE_CAPS_ENABLED` | on | per-transaction value caps. Uses strict `!== "0"` so a stray `false` leaves the cap wall standing |
|
|
76
|
+
|
|
77
|
+
### Integrity and attestation
|
|
78
|
+
|
|
79
|
+
| Name | Meaning |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `ORACLE_ROUTE_ATTESTATION_SECRET` | keyed route attestation HMAC. Written by `oracle init --apply` |
|
|
82
|
+
| `MAD_ROUTE_ATTESTATION_SECRET` | legacy alias for the above |
|
|
83
|
+
| `ORACLE_ATTESTATION_SECRET` | alternate attestation secret name |
|
|
84
|
+
| `ORACLE_STAMP_HMAC_SECRET` | keyed MAC over prepared envelopes. A verifier holding this secret **requires** a valid MAC — an envelope with the MAC stripped is refused, so the keyed mode cannot be silently downgraded to the unkeyed checksum |
|
|
85
|
+
| `ORACLE_STAMP_REQUIRE_MAC` | set `1` to require a MAC even when the verifier has no secret configured. With a secret set this is already implied |
|
|
86
|
+
| `ORACLE_PREPARE_HARD_MAX_AGE_MS` | hard ceiling on prepared-envelope age |
|
|
87
|
+
|
|
88
|
+
### Servers and endpoints
|
|
89
|
+
|
|
90
|
+
| Name | Default | Meaning |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| `ORACLE_INTEGRATOR_FEE_BPS` | unset (no fee) | Integrator fee in basis points on routed swaps, clamped to 100 (1%). Unset, zero, negative or malformed means **no fee**. Locals Only holders receive a 0% Oracle integrator-fee rate regardless of this value; ownership never changes product access |
|
|
93
|
+
| `ORACLE_INTEGRATOR_FEE_RECIPIENT` | unset | EVM address that receives the fee. **Required**: a fee configured without a valid recipient fails closed to no fee, because otherwise the basis points are charged and silently kept by the aggregator |
|
|
94
|
+
| `ORACLE_INTEGRATOR_ID` | `oracle` | Integrator/partner string sent to route providers. ParaSwap accepts any value with no registration; LI.FI requires the id to be registered at portal.li.fi or the quote 400s |
|
|
95
|
+
| `ORACLE_DATA_HOST` | `127.0.0.1` | read-plane bind host (loopback enforced) |
|
|
96
|
+
| `ORACLE_DATA_PORT` | `8787` | read-plane port |
|
|
97
|
+
| `ORACLE_DATA_URL` | `http://127.0.0.1:8787` | where the CLI looks for the data server |
|
|
98
|
+
| `ORACLE_PUBLIC_HOST` | `127.0.0.1` | public-plane bind host (loopback enforced) |
|
|
99
|
+
| `ORACLE_PUBLIC_PORT` | — | public-plane port |
|
|
100
|
+
| `ORACLE_TRUST_PROXY` | unset (off) | when `1`, read the caller IP from `X-Forwarded-For` for rate limiting. Set this ONLY when the service sits behind a proxy you control that overwrites the header. Enabling it on a directly-exposed server lets any client spoof a fresh identity per request and bypass the rate limit entirely. |
|
|
101
|
+
| `ORACLE_INDEXER_RPC_<CHAINID>` | unset | optional `eth_getLogs`-capable endpoint for one chain, e.g. `ORACLE_INDEXER_RPC_1`. Enables full approval discovery on that chain instead of the curated candidate probe. |
|
|
102
|
+
| `ORACLE_INDEXER_RPC_DEFAULT` | unset | fallback indexer endpoint for chains without a specific override. |
|
|
103
|
+
| `ORACLE_INDEXER_CHUNK_SPAN` | `10000` | max block span per `eth_getLogs` query. Many endpoints refuse wider ranges; lower it if yours caps harder. |
|
|
104
|
+
|
|
105
|
+
### Approval discovery coverage
|
|
106
|
+
|
|
107
|
+
Without an indexer endpoint, approval scanning probes a curated set of known
|
|
108
|
+
routers and tokens with `allowance()`. That works on any public RPC but is
|
|
109
|
+
scoped: an approval to a spender outside the list is not found, so an empty
|
|
110
|
+
result means "nothing found in that scope", never "this wallet is safe". The UI
|
|
111
|
+
states the scope rather than implying safety.
|
|
112
|
+
|
|
113
|
+
Configuring `ORACLE_INDEXER_RPC_*` upgrades discovery to log-derived, covering
|
|
114
|
+
all tokens and spenders. Liveness is still confirmed by re-reading
|
|
115
|
+
`allowance()` / `isApprovedForAll()`, because log state alone reports
|
|
116
|
+
long-revoked approvals as active.
|
|
117
|
+
|
|
118
|
+
### Rate limiting and admission
|
|
119
|
+
|
|
120
|
+
#### `0.12.0` clock migration
|
|
121
|
+
|
|
122
|
+
`buildConnectRequest`, `assembleUnsignedGrant`, and `planConnection` now require
|
|
123
|
+
`opts.now` even when the input already supplies an absolute `expiresAt`. Callers
|
|
124
|
+
migrating from `0.11.x` must pass a positive unix-seconds integer. This is an
|
|
125
|
+
intentional fail-closed API change: live construction no longer silently falls
|
|
126
|
+
back to shape-only validation. Hosted HTTP callers should not send a security
|
|
127
|
+
clock; the server replaces caller time with its own clock.
|
|
128
|
+
|
|
129
|
+
Live grants have a hard maximum TTL of 24 hours. Direct library calls to
|
|
130
|
+
`buildConnectRequest` and `assembleUnsignedGrant` require an explicit
|
|
131
|
+
`opts.now` so deterministic tests and offline clients cannot fall back to an
|
|
132
|
+
implicit clock. At the HTTP boundary, caller-provided `opts.now` is ignored:
|
|
133
|
+
the server clock is authoritative for connect, assemble, active-list, and
|
|
134
|
+
grant-status routes. Caller-provided `allowWildcardActions` is also ignored;
|
|
135
|
+
hosted grant routes always reject wildcard scope. Shape-only normalization
|
|
136
|
+
without `now` is reserved for historical identification/indexing and does not
|
|
137
|
+
establish live authority.
|
|
138
|
+
|
|
139
|
+
The public plane is unauthenticated, so both planes are throttled per caller IP
|
|
140
|
+
in fixed 60-second windows: 120 requests for cheap reads, and 10 for
|
|
141
|
+
`/public/approvals`, which fans a single request out to many upstream RPC calls.
|
|
142
|
+
A throttled caller gets `429` with `Retry-After` before any request body is
|
|
143
|
+
parsed. `chainIds` is additionally capped at 12 per request so one call cannot
|
|
144
|
+
cost as much as many.
|
|
145
|
+
|
|
146
|
+
This limiter is an abuse brake, not authentication. Keep the server on loopback;
|
|
147
|
+
a hosted service requires server-side authentication and per-user isolation.
|
|
148
|
+
Buzz discovery, capability verification, and audit routes are documented in
|
|
149
|
+
[buzz-integration.md](buzz-integration.md).
|
|
150
|
+
|
|
151
|
+
Counters are in memory and reset on restart. That is sufficient for accidental
|
|
152
|
+
hammering and casual abuse; a distributed flood still needs an edge/WAF in
|
|
153
|
+
front.
|
|
154
|
+
|
|
155
|
+
The data server serves `/health`; `/` intentionally returns 404 with a route
|
|
156
|
+
list.
|
|
157
|
+
|
|
158
|
+
### Paths and config
|
|
159
|
+
|
|
160
|
+
| Name | Meaning |
|
|
161
|
+
|---|---|
|
|
162
|
+
| `ORACLE_CONFIG_DIR` | config directory (default `~/.config/oracle`) |
|
|
163
|
+
| `ORACLE_EXEC_ENV_FILE` | path to `exec.env` |
|
|
164
|
+
| `ORACLE_AGENT_KEYS_PATH` | agent key store path |
|
|
165
|
+
| `ORACLE_AUTH_FILE_STORE` | auth file store path |
|
|
166
|
+
| `ORACLE_ADDRESS_BOOK` | address-book path |
|
|
167
|
+
| `ORACLE_OPERATOR_BIN_DIR` | operator binary directory |
|
|
168
|
+
| `ORACLE_AUDIT_STREAM` | audit stream destination |
|
|
169
|
+
|
|
170
|
+
### Packaged desktop mode
|
|
171
|
+
|
|
172
|
+
The desktop app sets these itself. They are documented because they change
|
|
173
|
+
security-relevant behavior, and an operator should be able to find out exactly
|
|
174
|
+
what the bundled app does differently from a plain `npm i -g` install.
|
|
175
|
+
|
|
176
|
+
| Name | Default | Meaning |
|
|
177
|
+
|---|---|---|
|
|
178
|
+
| `ORACLE_PUBLIC_DESKTOP` | off | Marks the process as the packaged public desktop. While on: the sign-plane operator is never resolved even if one is installed on the host, remote compute backends are refused, and legacy `~/.config/mad-desk` fallbacks resolve to the app-owned config dir instead of the host's. |
|
|
179
|
+
| `ORACLE_REMOTE_COMPUTE_DISABLE` | off | Refuses any remote/SSH chat compute backend regardless of stored config. |
|
|
180
|
+
|
|
181
|
+
### Routing and defaults
|
|
182
|
+
|
|
183
|
+
| Name | Meaning |
|
|
184
|
+
|---|---|
|
|
185
|
+
| `ORACLE_ALLOWED_CHAINS` | restrict routing to a chain allowlist |
|
|
186
|
+
| `ORACLE_DEFAULT_ADDRESS` | default address for reads |
|
|
187
|
+
| `ORACLE_PROFILE` | active profile name |
|
|
188
|
+
| `ORACLE_PRIVY_APP_ID` | Privy app id for connect flows |
|
|
189
|
+
|
|
190
|
+
### Runtime integration
|
|
191
|
+
|
|
192
|
+
| Name | Meaning |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `ORACLE_HERMES_BIN` | path to the agent runtime binary |
|
|
195
|
+
| `ORACLE_CLAUDE_CODE_VERSION` | pinned agent runtime version |
|
|
196
|
+
| `ORACLE_PYTHON` / `ORACLE_UV_BIN` | interpreter overrides |
|
|
197
|
+
| `ORACLE_NATIVE_TUI` / `ORACLE_FORCE_CHAT` / `ORACLE_PLAIN_HARNESS` | CLI presentation modes |
|
|
198
|
+
| `ORACLE_NO_BOOTSTRAP` | skip bootstrap on start |
|
|
199
|
+
| `ORACLE_CLI_DEBUG` | verbose CLI diagnostics |
|
|
200
|
+
|
|
201
|
+
### Test-only
|
|
202
|
+
|
|
203
|
+
| Name | Meaning |
|
|
204
|
+
|---|---|
|
|
205
|
+
| `ORACLE_TEST_ISOLATE_SECRETS` | isolate secrets during tests |
|
|
206
|
+
| `ORACLE_FAKE_HOME` | redirect `$HOME` during tests |
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Example: register a chain Oracle has never seen, then use it.
|
|
2
|
+
//
|
|
3
|
+
// Run: node examples/add-a-chain.mjs
|
|
4
|
+
//
|
|
5
|
+
// The point of this example is that there is no adapter to write. A chain is a
|
|
6
|
+
// config object; the generic EVM scanner supplies the capabilities.
|
|
7
|
+
|
|
8
|
+
import { registerCustomChain } from "../src/scanner/chains.config.mjs";
|
|
9
|
+
import { scannerCoverage } from "../src/scanner/contract.mjs";
|
|
10
|
+
|
|
11
|
+
// 1. Describe the chain. Note rpcEnv holds VARIABLE NAMES, not URLs -- endpoints
|
|
12
|
+
// stay in the environment so nothing sensitive lands in source control.
|
|
13
|
+
const scanner = registerCustomChain({
|
|
14
|
+
key: "examplechain",
|
|
15
|
+
chainId: 424242,
|
|
16
|
+
name: "Example Chain",
|
|
17
|
+
rpcEnv: ["EXAMPLECHAIN_RPC_URL"],
|
|
18
|
+
nativeCurrency: { symbol: "EXC", decimals: 18 },
|
|
19
|
+
explorer: "https://explorer.example",
|
|
20
|
+
|
|
21
|
+
// Omitted deliberately: dexscreenerSlug. Without it, pool discovery reports
|
|
22
|
+
// UNAVAILABLE rather than guessing -- a wrong slug would return another chain's
|
|
23
|
+
// pools, which is worse than no answer.
|
|
24
|
+
|
|
25
|
+
// Omitted deliberately: venues. With none, the chain is read/research capable and
|
|
26
|
+
// fail-closed for routing value. Adding one requires recorded provenance; see
|
|
27
|
+
// docs/adding-a-chain.md.
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
console.log(`registered: ${scanner.name} (chain ${scanner.chainId})`);
|
|
31
|
+
|
|
32
|
+
// 2. Ask what it can actually do. The answer is honest -- unimplemented
|
|
33
|
+
// capabilities are listed as unsupported, not silently absent.
|
|
34
|
+
const caps = scanner.capabilities();
|
|
35
|
+
console.log(`\nsupported (${caps.supported.length}): ${caps.supported.join(", ")}`);
|
|
36
|
+
console.log(`unsupported (${caps.unsupported.length}): ${caps.unsupported.join(", ")}`);
|
|
37
|
+
|
|
38
|
+
// 3. An unimplemented capability throws with an actionable message. It never
|
|
39
|
+
// returns undefined, which a caller could mistake for "no result".
|
|
40
|
+
try {
|
|
41
|
+
await scanner.quote({ from: "0x", to: "0x", amount: "1" });
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.log(`\nquote() correctly refused:\n ${err.message.split("\n")[0]}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 4. Pool discovery is UNAVAILABLE, and says why.
|
|
47
|
+
const pools = await scanner.resolvePools("0x1111111111111111111111111111111111111111");
|
|
48
|
+
console.log(`\nresolvePools evidence: ${pools.evidence}`);
|
|
49
|
+
console.log(` reason: ${pools.reason}`);
|
|
50
|
+
|
|
51
|
+
// 5. Live reads need an RPC. Show the exact variable to set rather than failing
|
|
52
|
+
// with a generic network error.
|
|
53
|
+
console.log(`\nto make live reads, set one of: ${scanner.rpcEnv.join(", ")}`);
|
|
54
|
+
try {
|
|
55
|
+
const head = await scanner.blockNumber();
|
|
56
|
+
console.log(` head: ${head.blockNumber} (${head.evidence})`);
|
|
57
|
+
} catch {
|
|
58
|
+
console.log(" (no RPC configured -- expected for this example chain)");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 6. The coverage matrix now includes it alongside the built-ins.
|
|
62
|
+
const cov = scannerCoverage();
|
|
63
|
+
console.log(`\ncoverage: ${cov.chainCount} chain(s) registered`);
|
|
64
|
+
const mine = cov.chains[424242];
|
|
65
|
+
console.log(` examplechain failClosed for routing: ${mine.failClosed}`);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
|
|
3
|
+
// Minimal Oracle protocol pack. It prepares unsigned actions; it never receives
|
|
4
|
+
// keys, signs, broadcasts, or claims that untrusted metadata is an instruction.
|
|
5
|
+
|
|
6
|
+
export const provider = Object.freeze({
|
|
7
|
+
id: "example-protocol",
|
|
8
|
+
version: "1.0.0",
|
|
9
|
+
chains: [8453],
|
|
10
|
+
metadata: { source: "on-chain", trust: "untrusted-data" },
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export function prepare(intent) {
|
|
14
|
+
assert.ok(intent && provider.chains.includes(intent.chainId), "unsupported chain");
|
|
15
|
+
return {
|
|
16
|
+
kind: "unsigned-transaction",
|
|
17
|
+
chainId: intent.chainId,
|
|
18
|
+
transaction: { to: intent.to, data: intent.data ?? "0x", value: intent.value ?? "0" },
|
|
19
|
+
receiptGate: { required: true, confirmations: 1, match: ["chainId", "transaction.to"] },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function decode(receipt) {
|
|
24
|
+
assert.ok(receipt && typeof receipt.status !== "undefined", "receipt required");
|
|
25
|
+
return { success: receipt.status === 1 || receipt.status === "0x1", transactionHash: receipt.transactionHash };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const riskRules = Object.freeze([
|
|
29
|
+
{ id: "explicit-recipient", field: "transaction.to", required: true },
|
|
30
|
+
{ id: "receipt-before-success", field: "receiptGate.required", equals: true },
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
export const tests = Object.freeze({
|
|
34
|
+
command: "node --test test/oracle-pack-standard.test.mjs",
|
|
35
|
+
covers: ["prepare-is-unsigned", "decode-requires-receipt", "metadata-is-untrusted"],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export default Object.freeze({ provider, prepare, decode, riskRules, tests });
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Example: research a token end to end, honestly.
|
|
2
|
+
//
|
|
3
|
+
// Run: node examples/research-a-token.mjs
|
|
4
|
+
// node examples/research-a-token.mjs base 0x<address>
|
|
5
|
+
//
|
|
6
|
+
// Demonstrates the discipline the desk is built around: read the identity off the
|
|
7
|
+
// chain, find pools with real liquidity, and report UNKNOWN where a check could not
|
|
8
|
+
// run rather than letting silence read as approval.
|
|
9
|
+
|
|
10
|
+
import { registerBuiltinScanners } from "../src/scanner/chains.config.mjs";
|
|
11
|
+
import { getScanner, listScanners, EVIDENCE, RISK } from "../src/scanner/contract.mjs";
|
|
12
|
+
|
|
13
|
+
registerBuiltinScanners();
|
|
14
|
+
|
|
15
|
+
const chainRef = process.argv[2] || "base";
|
|
16
|
+
// Base USDC by default -- a token whose answers are easy to sanity-check.
|
|
17
|
+
const token = process.argv[3] || "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
18
|
+
|
|
19
|
+
const scanner =
|
|
20
|
+
listScanners().find((s) => s.key === chainRef) || getScanner(Number(chainRef));
|
|
21
|
+
if (!scanner) {
|
|
22
|
+
console.error(`unknown chain "${chainRef}"`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`chain: ${scanner.name} (${scanner.chainId})`);
|
|
27
|
+
console.log(`token: ${token}\n`);
|
|
28
|
+
|
|
29
|
+
// 1. Identity from the CONTRACT, not a token list. A list can be stale or omit a
|
|
30
|
+
// two-hour-old launch, and the on-chain answer is what governs a transfer.
|
|
31
|
+
const meta = await scanner.resolveToken(token);
|
|
32
|
+
if (meta.evidence !== EVIDENCE.LIVE) {
|
|
33
|
+
console.log(`identity: ${meta.evidence} -- ${meta.warning ?? meta.error}`);
|
|
34
|
+
console.log("stopping: without ERC-20 metadata there is nothing to price.");
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
console.log(`identity: ${meta.symbol} (${meta.name}), ${meta.decimals} decimals`);
|
|
38
|
+
|
|
39
|
+
// 2. Pools, ranked by liquidity. Depth is what determines your fill; the headline
|
|
40
|
+
// price is a fiction for anything but the smallest clip.
|
|
41
|
+
const pools = await scanner.resolvePools(token);
|
|
42
|
+
console.log(`\npools: ${pools.evidence}`);
|
|
43
|
+
if (pools.reason) console.log(` ${pools.reason}`);
|
|
44
|
+
for (const p of pools.pools.slice(0, 5)) {
|
|
45
|
+
const liq = p.liquidityUsd == null ? "unknown" : `$${Math.round(p.liquidityUsd).toLocaleString()}`;
|
|
46
|
+
console.log(` ${p.dex.padEnd(14)} ${liq.padStart(14)} ${p.pair}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 3. Structural risk. Read the verdict AND the individual checks -- an overall
|
|
50
|
+
// UNKNOWN often hides several passes plus one unprovable item, and which item is
|
|
51
|
+
// unprovable is the decision-relevant part.
|
|
52
|
+
const risk = await scanner.scoreRisk(token);
|
|
53
|
+
console.log(`\nrisk verdict: ${risk.verdict}`);
|
|
54
|
+
for (const c of risk.checks) {
|
|
55
|
+
console.log(` ${c.result.padEnd(8)} ${c.check.padEnd(16)} ${c.detail ?? ""}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 4. The honest close. UNKNOWN is not PASS, and a buy path is not an exit path.
|
|
59
|
+
console.log("");
|
|
60
|
+
if (risk.verdict === RISK.FAIL) {
|
|
61
|
+
console.log("FAIL: disqualifying finding above. Do not trade.");
|
|
62
|
+
} else if (risk.verdict === RISK.UNKNOWN) {
|
|
63
|
+
console.log(
|
|
64
|
+
"UNKNOWN is not PASS. Structural checks looked fine, but sellability is\n" +
|
|
65
|
+
"unproven without a verified router on this chain. Until a round-trip sell\n" +
|
|
66
|
+
"simulation succeeds, treat this token as not exitable.",
|
|
67
|
+
);
|
|
68
|
+
} else {
|
|
69
|
+
console.log(`${risk.verdict}: structural checks only -- still not a recommendation.`);
|
|
70
|
+
}
|