dexterm-cli 0.0.0-stage → 0.1.1
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/LICENSE +661 -0
- package/dist/packages/agents/src/audit.js +122 -0
- package/dist/packages/agents/src/bus.js +379 -0
- package/dist/packages/agents/src/executor.js +177 -0
- package/dist/packages/agents/src/gate.js +176 -0
- package/dist/packages/agents/src/identity.js +179 -0
- package/dist/packages/agents/src/index.js +15 -0
- package/dist/packages/agents/src/proposals.js +153 -0
- package/dist/packages/agents/src/schema.js +87 -0
- package/dist/packages/agents/src/sdk.js +140 -0
- package/dist/packages/agents/src/tiers.js +114 -0
- package/dist/packages/agents/src/tools.js +69 -0
- package/dist/packages/agents/src/ws.js +158 -0
- package/dist/packages/cli/assets/claude/analyst-system.md +76 -0
- package/dist/packages/cli/assets/claude/plugin/.claude-plugin/plugin.json +5 -0
- package/dist/packages/cli/assets/claude/plugin/skills/REGISTRY.json +16 -0
- package/dist/packages/cli/assets/claude/plugin/skills/larp-check/SKILL.md +67 -0
- package/dist/packages/cli/assets/claude/plugin/skills/rug-check/SKILL.md +64 -0
- package/dist/packages/cli/assets/claude/plugin/skills/token-dossier/SKILL.md +63 -0
- package/dist/packages/cli/assets/claude/plugin/skills/trench-scan/SKILL.md +44 -0
- package/dist/packages/cli/assets/claude/schemas/larp.schema.json +117 -0
- package/dist/packages/cli/assets/claude/schemas/trench-scan.schema.json +71 -0
- package/dist/packages/cli/assets/claude/schemas/verdict.schema.json +115 -0
- package/dist/packages/cli/bin/dexterm.mjs +11 -0
- package/dist/packages/cli/src/agent-cmd.js +303 -0
- package/dist/packages/cli/src/agent-roster.js +26 -0
- package/dist/packages/cli/src/analyst/backend.js +526 -0
- package/dist/packages/cli/src/analyst/results.js +38 -0
- package/dist/packages/cli/src/analyst/session.js +319 -0
- package/dist/packages/cli/src/audit.js +51 -0
- package/dist/packages/cli/src/backtest-cmd.js +149 -0
- package/dist/packages/cli/src/boot-state.js +62 -0
- package/dist/packages/cli/src/custom.js +261 -0
- package/dist/packages/cli/src/display.js +191 -0
- package/dist/packages/cli/src/doctor.js +361 -0
- package/dist/packages/cli/src/feed.js +634 -0
- package/dist/packages/cli/src/fixtures.js +275 -0
- package/dist/packages/cli/src/follow-cmd.js +221 -0
- package/dist/packages/cli/src/images-config.js +59 -0
- package/dist/packages/cli/src/index.js +31 -0
- package/dist/packages/cli/src/kb-skill-cmd.js +240 -0
- package/dist/packages/cli/src/larp-record.js +21 -0
- package/dist/packages/cli/src/live/copy.js +80 -0
- package/dist/packages/cli/src/live/flow.js +233 -0
- package/dist/packages/cli/src/live/index.js +509 -0
- package/dist/packages/cli/src/live/intel.js +227 -0
- package/dist/packages/cli/src/live/newpairs.js +334 -0
- package/dist/packages/cli/src/live/screens/newpairs-live.js +219 -0
- package/dist/packages/cli/src/live/screens/token-live.js +459 -0
- package/dist/packages/cli/src/live/screens/watchlist-live.js +149 -0
- package/dist/packages/cli/src/live/token.js +585 -0
- package/dist/packages/cli/src/live/trade.js +929 -0
- package/dist/packages/cli/src/live/watchlist.js +178 -0
- package/dist/packages/cli/src/main.js +5583 -0
- package/dist/packages/cli/src/narrative-cmd.js +76 -0
- package/dist/packages/cli/src/pack-cmd.js +323 -0
- package/dist/packages/cli/src/plan-cmd.js +278 -0
- package/dist/packages/cli/src/popup.js +810 -0
- package/dist/packages/cli/src/rules-cmd.js +131 -0
- package/dist/packages/cli/src/rules.js +339 -0
- package/dist/packages/cli/src/scan/command.js +57 -0
- package/dist/packages/cli/src/scan/engine.js +419 -0
- package/dist/packages/cli/src/scan/observe.js +64 -0
- package/dist/packages/cli/src/scan/ui.js +98 -0
- package/dist/packages/cli/src/screener/filter.js +241 -0
- package/dist/packages/cli/src/screener/presets.js +80 -0
- package/dist/packages/cli/src/screener/rows.js +146 -0
- package/dist/packages/cli/src/screener/rug.js +50 -0
- package/dist/packages/cli/src/screener/sort.js +52 -0
- package/dist/packages/cli/src/screener/view.js +183 -0
- package/dist/packages/cli/src/screens/analyst-session.js +343 -0
- package/dist/packages/cli/src/screens/analyst.js +326 -0
- package/dist/packages/cli/src/screens/boot.js +74 -0
- package/dist/packages/cli/src/screens/bubbles.js +255 -0
- package/dist/packages/cli/src/screens/coin.js +33 -0
- package/dist/packages/cli/src/screens/follows.js +201 -0
- package/dist/packages/cli/src/screens/kol.js +90 -0
- package/dist/packages/cli/src/screens/narrative.js +90 -0
- package/dist/packages/cli/src/screens/newpairs.js +150 -0
- package/dist/packages/cli/src/screens/overlay.js +257 -0
- package/dist/packages/cli/src/screens/plans.js +126 -0
- package/dist/packages/cli/src/screens/positions.js +176 -0
- package/dist/packages/cli/src/screens/rules.js +170 -0
- package/dist/packages/cli/src/screens/screener.js +459 -0
- package/dist/packages/cli/src/screens/social-panel.js +107 -0
- package/dist/packages/cli/src/screens/ticket.js +342 -0
- package/dist/packages/cli/src/screens/token.js +312 -0
- package/dist/packages/cli/src/screens/trending.js +181 -0
- package/dist/packages/cli/src/screens/watchlist.js +104 -0
- package/dist/packages/cli/src/social/demo.js +96 -0
- package/dist/packages/cli/src/social/view.js +250 -0
- package/dist/packages/cli/src/state.js +463 -0
- package/dist/packages/cli/src/theme-cmd.js +126 -0
- package/dist/packages/cli/src/trade.js +319 -0
- package/dist/packages/cli/src/voice-hud.js +42 -0
- package/dist/packages/cli/src/wallet-cmd.js +440 -0
- package/dist/packages/cli/src/wallet-command.js +31 -0
- package/dist/packages/cli/src/widgets.js +208 -0
- package/dist/packages/cli/src/workspace-cmd.js +68 -0
- package/dist/packages/cli/src/x-cmd.js +154 -0
- package/dist/packages/custom/src/config.js +213 -0
- package/dist/packages/custom/src/index.js +10 -0
- package/dist/packages/custom/src/keymap.js +107 -0
- package/dist/packages/custom/src/layout.js +235 -0
- package/dist/packages/custom/src/packs.js +633 -0
- package/dist/packages/custom/src/rules.js +704 -0
- package/dist/packages/custom/src/schema.js +515 -0
- package/dist/packages/custom/src/themes.js +176 -0
- package/dist/packages/custom/src/widget-html.js +222 -0
- package/dist/packages/custom/src/workspace.js +141 -0
- package/dist/packages/data/src/analyst-actions.js +133 -0
- package/dist/packages/data/src/budget.js +88 -0
- package/dist/packages/data/src/cache.js +142 -0
- package/dist/packages/data/src/candles.js +168 -0
- package/dist/packages/data/src/clock.js +64 -0
- package/dist/packages/data/src/credits.js +137 -0
- package/dist/packages/data/src/detail.js +97 -0
- package/dist/packages/data/src/fast-lane.js +321 -0
- package/dist/packages/data/src/fixtures.js +135 -0
- package/dist/packages/data/src/health.js +245 -0
- package/dist/packages/data/src/http.js +277 -0
- package/dist/packages/data/src/images/cache.js +141 -0
- package/dist/packages/data/src/images/decode-worker.js +28 -0
- package/dist/packages/data/src/images/decode.js +81 -0
- package/dist/packages/data/src/images/fetch.js +162 -0
- package/dist/packages/data/src/images/gif.js +214 -0
- package/dist/packages/data/src/images/index.js +10 -0
- package/dist/packages/data/src/images/jpeg.js +544 -0
- package/dist/packages/data/src/images/png.js +310 -0
- package/dist/packages/data/src/images/service.js +334 -0
- package/dist/packages/data/src/images/types.js +27 -0
- package/dist/packages/data/src/index.js +208 -0
- package/dist/packages/data/src/intel/helius-history.js +59 -0
- package/dist/packages/data/src/intel/holder-class.js +125 -0
- package/dist/packages/data/src/intel/rules.js +421 -0
- package/dist/packages/data/src/intel/scan.js +170 -0
- package/dist/packages/data/src/larp/evidence.js +288 -0
- package/dist/packages/data/src/larp/links.js +137 -0
- package/dist/packages/data/src/larp/robots.js +90 -0
- package/dist/packages/data/src/larp/safe-fetch.js +389 -0
- package/dist/packages/data/src/limiter.js +341 -0
- package/dist/packages/data/src/model.js +12 -0
- package/dist/packages/data/src/paper.js +331 -0
- package/dist/packages/data/src/rpc-config.js +126 -0
- package/dist/packages/data/src/rpc-pool.js +166 -0
- package/dist/packages/data/src/social/chain.js +83 -0
- package/dist/packages/data/src/social/dedupe.js +205 -0
- package/dist/packages/data/src/social/feed.js +462 -0
- package/dist/packages/data/src/social/firewall.js +110 -0
- package/dist/packages/data/src/social/index.js +11 -0
- package/dist/packages/data/src/social/kol.js +269 -0
- package/dist/packages/data/src/social/model.js +11 -0
- package/dist/packages/data/src/social/rank.js +184 -0
- package/dist/packages/data/src/social/rss.js +113 -0
- package/dist/packages/data/src/social/summary.js +104 -0
- package/dist/packages/data/src/social/venues.js +186 -0
- package/dist/packages/data/src/sources/dexscreener.js +170 -0
- package/dist/packages/data/src/sources/geckoterminal.js +133 -0
- package/dist/packages/data/src/sources/goplus.js +161 -0
- package/dist/packages/data/src/sources/jupiter-swap.js +236 -0
- package/dist/packages/data/src/sources/jupiter.js +198 -0
- package/dist/packages/data/src/sources/pda.js +113 -0
- package/dist/packages/data/src/sources/pump-curve.js +58 -0
- package/dist/packages/data/src/sources/pumpportal.js +247 -0
- package/dist/packages/data/src/sources/rugcheck.js +71 -0
- package/dist/packages/data/src/sources/solana-rpc.js +299 -0
- package/dist/packages/data/src/sources/solana-ws.js +287 -0
- package/dist/packages/data/src/store.js +289 -0
- package/dist/packages/data/src/trade/bridge.js +464 -0
- package/dist/packages/data/src/trade/caps.js +323 -0
- package/dist/packages/data/src/trade/copy/auto.js +385 -0
- package/dist/packages/data/src/trade/copy/follows.js +103 -0
- package/dist/packages/data/src/trade/copy/index.js +9 -0
- package/dist/packages/data/src/trade/copy/mirror.js +91 -0
- package/dist/packages/data/src/trade/copy/stats.js +120 -0
- package/dist/packages/data/src/trade/copy/tracker.js +158 -0
- package/dist/packages/data/src/trade/copy/trades.js +87 -0
- package/dist/packages/data/src/trade/copy/types.js +6 -0
- package/dist/packages/data/src/trade/executor.js +933 -0
- package/dist/packages/data/src/trade/kill-switch.js +47 -0
- package/dist/packages/data/src/trade/link-store.js +52 -0
- package/dist/packages/data/src/trade/plans/confirm.js +157 -0
- package/dist/packages/data/src/trade/plans/engine.js +784 -0
- package/dist/packages/data/src/trade/plans/executor-live.js +220 -0
- package/dist/packages/data/src/trade/plans/executor-paper.js +44 -0
- package/dist/packages/data/src/trade/plans/executor.js +11 -0
- package/dist/packages/data/src/trade/plans/index.js +12 -0
- package/dist/packages/data/src/trade/plans/journal.js +77 -0
- package/dist/packages/data/src/trade/plans/mandate.js +129 -0
- package/dist/packages/data/src/trade/plans/plan.js +179 -0
- package/dist/packages/data/src/trade/plans/service.js +168 -0
- package/dist/packages/data/src/trade/plans/types.js +6 -0
- package/dist/packages/data/src/trade/rpc-exec.js +229 -0
- package/dist/packages/data/src/trade/signer/client.js +197 -0
- package/dist/packages/data/src/trade/signer/fast-wallet.js +154 -0
- package/dist/packages/data/src/trade/signer/host.js +97 -0
- package/dist/packages/data/src/trade/signer/main.js +121 -0
- package/dist/packages/data/src/trade/signer/probe-builder.js +85 -0
- package/dist/packages/data/src/trade/signer/protocol.js +92 -0
- package/dist/packages/data/src/trade/signer/service.js +400 -0
- package/dist/packages/data/src/trade/signer/sol-usd-feed.js +98 -0
- package/dist/packages/data/src/trade/sol-usd.js +86 -0
- package/dist/packages/data/src/trade/swap-build.js +108 -0
- package/dist/packages/data/src/trade/token-delta.js +201 -0
- package/dist/packages/data/src/trade/tx-decode.js +632 -0
- package/dist/packages/data/src/util.js +24 -0
- package/dist/packages/data/src/watchlist.js +176 -0
- package/dist/packages/data/src/x/api.js +256 -0
- package/dist/packages/data/src/x/budget.js +66 -0
- package/dist/packages/data/src/x/config.js +49 -0
- package/dist/packages/data/src/x/index.js +10 -0
- package/dist/packages/data/src/x/mock-server.js +217 -0
- package/dist/packages/data/src/x/oauth.js +242 -0
- package/dist/packages/data/src/x/pkce.js +21 -0
- package/dist/packages/data/src/x/source.js +285 -0
- package/dist/packages/data/src/x/token-store.js +134 -0
- package/dist/packages/data/src/x/transport.js +71 -0
- package/dist/packages/data/vendor/solana-web3/LICENSE +20 -0
- package/dist/packages/data/vendor/solana-web3/NOTICE.md +13 -0
- package/dist/packages/data/vendor/solana-web3/index.iife.min.js +20 -0
- package/dist/packages/mcp/assets/cases.json +1194 -0
- package/dist/packages/mcp/assets/kb/entries/cabal-and-coordinated-launches.md +28 -0
- package/dist/packages/mcp/assets/kb/entries/common-rug-patterns.md +40 -0
- package/dist/packages/mcp/assets/kb/entries/dbc-mechanics.md +30 -0
- package/dist/packages/mcp/assets/kb/entries/dev-wallet-behaviour.md +33 -0
- package/dist/packages/mcp/assets/kb/entries/glossary.md +35 -0
- package/dist/packages/mcp/assets/kb/entries/holder-concentration.md +30 -0
- package/dist/packages/mcp/assets/kb/entries/jito-bundles.md +29 -0
- package/dist/packages/mcp/assets/kb/entries/launchlab-curve.md +31 -0
- package/dist/packages/mcp/assets/kb/entries/lp-burn-vs-lock.md +31 -0
- package/dist/packages/mcp/assets/kb/entries/metadata-and-copycats.md +29 -0
- package/dist/packages/mcp/assets/kb/entries/mint-freeze-authority.md +31 -0
- package/dist/packages/mcp/assets/kb/entries/narrative-lifecycle.md +32 -0
- package/dist/packages/mcp/assets/kb/entries/pump-bonding-curve.md +33 -0
- package/dist/packages/mcp/assets/kb/entries/pumpswap-migration.md +29 -0
- package/dist/packages/mcp/assets/kb/entries/sniping-and-snipers.md +29 -0
- package/dist/packages/mcp/assets/kb/entries/token2022-extensions-risk.md +32 -0
- package/dist/packages/mcp/assets/kb/entries/wash-trading-fake-volume.md +33 -0
- package/dist/packages/mcp/assets/skills/rug-check.md +52 -0
- package/dist/packages/mcp/assets/skills/token-dossier.md +57 -0
- package/dist/packages/mcp/assets/skills/trench-scan.md +40 -0
- package/dist/packages/mcp/bin/dexterm-mcp.mjs +16 -0
- package/dist/packages/mcp/src/dossier.js +78 -0
- package/dist/packages/mcp/src/firewall.js +21 -0
- package/dist/packages/mcp/src/index.js +22 -0
- package/dist/packages/mcp/src/server.js +849 -0
- package/dist/packages/mcp/src/user-content.js +434 -0
- package/dist/packages/packs/src/backtest.js +183 -0
- package/dist/packages/packs/src/digest.js +95 -0
- package/dist/packages/packs/src/firewall.js +57 -0
- package/dist/packages/packs/src/index.js +19 -0
- package/dist/packages/packs/src/larp-eval.js +100 -0
- package/dist/packages/packs/src/narrative.js +309 -0
- package/dist/packages/packs/src/reason.js +135 -0
- package/dist/packages/packs/src/rug-model.js +137 -0
- package/dist/packages/packs/src/schema.js +54 -0
- package/dist/packages/packs/src/token-dossier.js +174 -0
- package/dist/packages/packs/src/verdicts.js +17 -0
- package/dist/packages/packs/src/wallet-dossier.js +105 -0
- package/dist/packages/popup/src/config.js +71 -0
- package/dist/packages/popup/src/dock.js +271 -0
- package/dist/packages/popup/src/host.js +210 -0
- package/dist/packages/popup/src/index.js +12 -0
- package/dist/packages/popup/src/loopback.js +53 -0
- package/dist/packages/popup/src/open.js +183 -0
- package/dist/packages/popup/src/pages/bubbles-lib.js +160 -0
- package/dist/packages/popup/src/pages/bubbles.css +23 -0
- package/dist/packages/popup/src/pages/bubbles.html +36 -0
- package/dist/packages/popup/src/pages/bubbles.js +214 -0
- package/dist/packages/popup/src/pages/chart-lib.js +262 -0
- package/dist/packages/popup/src/pages/chart.css +50 -0
- package/dist/packages/popup/src/pages/chart.html +56 -0
- package/dist/packages/popup/src/pages/chart.js +554 -0
- package/dist/packages/popup/src/pages/common.css +34 -0
- package/dist/packages/popup/src/pages/common.js +187 -0
- package/dist/packages/popup/src/pages/feeds.html +20 -0
- package/dist/packages/popup/src/pages/feeds.js +77 -0
- package/dist/packages/popup/src/pages/narrative.html +20 -0
- package/dist/packages/popup/src/pages/narrative.js +61 -0
- package/dist/packages/popup/src/pages/plans.css +30 -0
- package/dist/packages/popup/src/pages/plans.html +26 -0
- package/dist/packages/popup/src/pages/plans.js +82 -0
- package/dist/packages/popup/src/pages/roster.css +41 -0
- package/dist/packages/popup/src/pages/roster.html +25 -0
- package/dist/packages/popup/src/pages/roster.js +75 -0
- package/dist/packages/popup/src/pages/token.html +20 -0
- package/dist/packages/popup/src/pages/token.js +112 -0
- package/dist/packages/popup/src/pages/widget-sdk.js +224 -0
- package/dist/packages/popup/src/pages/widget.css +5 -0
- package/dist/packages/popup/src/pages/widget.html +21 -0
- package/dist/packages/popup/src/pages/widget.js +85 -0
- package/dist/packages/popup/src/protocol.js +31 -0
- package/dist/packages/popup/src/selftest.js +156 -0
- package/dist/packages/popup/src/server.js +582 -0
- package/dist/packages/popup/src/sinkproxy.js +167 -0
- package/dist/packages/popup/src/widget-html.js +231 -0
- package/dist/packages/popup/vendor/lightweight-charts/LICENSE +201 -0
- package/dist/packages/popup/vendor/lightweight-charts/NOTICE +2 -0
- package/dist/packages/popup/vendor/lightweight-charts/README.md +30 -0
- package/dist/packages/popup/vendor/lightweight-charts/VERSION +1 -0
- package/dist/packages/popup/vendor/lightweight-charts/lightweight-charts.standalone.production.js +7 -0
- package/dist/packages/recorder/bin/dexterm-recorder.mjs +11 -0
- package/dist/packages/recorder/src/cli.js +113 -0
- package/dist/packages/recorder/src/export.js +71 -0
- package/dist/packages/recorder/src/index.js +20 -0
- package/dist/packages/recorder/src/labels.js +151 -0
- package/dist/packages/recorder/src/open.js +29 -0
- package/dist/packages/recorder/src/recorder.js +553 -0
- package/dist/packages/recorder/src/schedule.js +43 -0
- package/dist/packages/recorder/src/schema.js +135 -0
- package/dist/packages/recorder/src/snapshot.js +191 -0
- package/dist/packages/recorder/src/sweep.js +52 -0
- package/dist/packages/recorder/src/verdicts.js +52 -0
- package/dist/packages/tui/src/bubbles.js +415 -0
- package/dist/packages/tui/src/canvas.js +370 -0
- package/dist/packages/tui/src/chrome.js +85 -0
- package/dist/packages/tui/src/color.js +133 -0
- package/dist/packages/tui/src/flush.js +62 -0
- package/dist/packages/tui/src/fmt.js +188 -0
- package/dist/packages/tui/src/fx-trade.js +278 -0
- package/dist/packages/tui/src/fx.js +527 -0
- package/dist/packages/tui/src/images/blocks.js +141 -0
- package/dist/packages/tui/src/images/coin.js +22 -0
- package/dist/packages/tui/src/images/detect.js +140 -0
- package/dist/packages/tui/src/images/index.js +7 -0
- package/dist/packages/tui/src/images/layer.js +146 -0
- package/dist/packages/tui/src/images/pixels.js +157 -0
- package/dist/packages/tui/src/images/protocols.js +87 -0
- package/dist/packages/tui/src/index.js +15 -0
- package/dist/packages/tui/src/keymap.js +355 -0
- package/dist/packages/tui/src/layout.js +11 -0
- package/dist/packages/tui/src/sound.js +177 -0
- package/dist/packages/tui/src/theme.js +182 -0
- package/dist/packages/tui/src/widgets.js +598 -0
- package/dist/packages/voice/src/controller.js +395 -0
- package/dist/packages/voice/src/doctor.js +63 -0
- package/dist/packages/voice/src/engines.js +44 -0
- package/dist/packages/voice/src/index.js +16 -0
- package/dist/packages/voice/src/router.js +502 -0
- package/dist/packages/voice/src/stt/apple-helper.swift.js +103 -0
- package/dist/packages/voice/src/stt/apple.js +179 -0
- package/dist/packages/voice/src/stt/fake.js +34 -0
- package/dist/packages/voice/src/stt/whisper.js +102 -0
- package/dist/packages/voice/src/summary.js +44 -0
- package/dist/packages/voice/src/tts/fake.js +30 -0
- package/dist/packages/voice/src/tts/say.js +96 -0
- package/dist/packages/voice/src/types.js +3 -0
- package/package.json +42 -4
- package/README.md +0 -3
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// @dexterm/data public surface. Lane B (D-02) owns this package; the shared model
|
|
2
|
+
// types were agreed on day 1 (D-01) and live in ./model.ts.
|
|
3
|
+
export * from "./model.js";
|
|
4
|
+
export * from "./clock.js";
|
|
5
|
+
export * from "./limiter.js";
|
|
6
|
+
export * from "./health.js";
|
|
7
|
+
export * from "./cache.js";
|
|
8
|
+
export * from "./http.js";
|
|
9
|
+
export * from "./fixtures.js";
|
|
10
|
+
export * from "./store.js";
|
|
11
|
+
export * from "./sources/dexscreener.js";
|
|
12
|
+
export * from "./sources/jupiter.js";
|
|
13
|
+
export * from "./sources/jupiter-swap.js";
|
|
14
|
+
export * from "./sources/geckoterminal.js";
|
|
15
|
+
export * from "./sources/solana-rpc.js";
|
|
16
|
+
export * from "./sources/rugcheck.js";
|
|
17
|
+
export * from "./sources/goplus.js";
|
|
18
|
+
export * from "./sources/pumpportal.js";
|
|
19
|
+
export * from "./sources/solana-ws.js";
|
|
20
|
+
export * from "./sources/pump-curve.js";
|
|
21
|
+
export * from "./sources/pda.js";
|
|
22
|
+
export * from "./fast-lane.js";
|
|
23
|
+
export * from "./candles.js";
|
|
24
|
+
export * from "./detail.js";
|
|
25
|
+
export * from "./rpc-config.js";
|
|
26
|
+
export * from "./rpc-pool.js";
|
|
27
|
+
export * from "./credits.js";
|
|
28
|
+
export * from "./budget.js";
|
|
29
|
+
export * from "./watchlist.js";
|
|
30
|
+
export * from "./paper.js";
|
|
31
|
+
export * from "./trade/caps.js";
|
|
32
|
+
export * from "./trade/bridge.js";
|
|
33
|
+
export * from "./trade/swap-build.js";
|
|
34
|
+
export * from "./trade/rpc-exec.js";
|
|
35
|
+
export * from "./trade/executor.js";
|
|
36
|
+
export * from "./trade/link-store.js";
|
|
37
|
+
export * from "./trade/tx-decode.js";
|
|
38
|
+
export * from "./trade/sol-usd.js";
|
|
39
|
+
export * from "./trade/kill-switch.js";
|
|
40
|
+
export * from "./trade/token-delta.js";
|
|
41
|
+
export * from "./trade/signer/protocol.js";
|
|
42
|
+
export * from "./trade/signer/service.js";
|
|
43
|
+
export * from "./trade/signer/host.js";
|
|
44
|
+
export * from "./trade/signer/client.js";
|
|
45
|
+
export * from "./trade/signer/probe-builder.js";
|
|
46
|
+
export * from "./trade/signer/fast-wallet.js";
|
|
47
|
+
export * from "./trade/signer/sol-usd-feed.js";
|
|
48
|
+
export { parseSignerArgs, buildSignerService } from "./trade/signer/main.js";
|
|
49
|
+
export * from "./larp/links.js";
|
|
50
|
+
export * from "./larp/safe-fetch.js";
|
|
51
|
+
export * from "./larp/evidence.js";
|
|
52
|
+
export * from "./analyst-actions.js";
|
|
53
|
+
export * from "./intel/rules.js";
|
|
54
|
+
export * from "./intel/holder-class.js";
|
|
55
|
+
export * from "./intel/helius-history.js";
|
|
56
|
+
export * from "./intel/scan.js";
|
|
57
|
+
export * from "./images/index.js";
|
|
58
|
+
// task-1330 (I-03): social / news / trending layer. `Provenance` and `Credibility`-style names are
|
|
59
|
+
// namespaced under `Social*` where they would collide with the core model.
|
|
60
|
+
export { POST_DISPLAY_MAX, POST_STORED_MAX, BIO_MAX, } from "./social/model.js";
|
|
61
|
+
export * from "./social/firewall.js";
|
|
62
|
+
export * from "./social/dedupe.js";
|
|
63
|
+
export * from "./social/rank.js";
|
|
64
|
+
export * from "./social/kol.js";
|
|
65
|
+
export * from "./social/venues.js";
|
|
66
|
+
export * from "./social/rss.js";
|
|
67
|
+
export * from "./social/chain.js";
|
|
68
|
+
export * from "./social/summary.js";
|
|
69
|
+
export * from "./social/feed.js";
|
|
70
|
+
// task-1357 (I-02): Login with X (OAuth2 PKCE on a loopback callback) + the user-authorized X read adapter.
|
|
71
|
+
export * from "./x/index.js";
|
|
72
|
+
import { Cache } from "./cache.js";
|
|
73
|
+
import { systemClock } from "./clock.js";
|
|
74
|
+
import { HealthRegistry } from "./health.js";
|
|
75
|
+
import { HttpClient, liveTransport } from "./http.js";
|
|
76
|
+
import { DEFAULT_BUCKETS, RateLimiter, SOURCE_BUCKET } from "./limiter.js";
|
|
77
|
+
import { DexScreener } from "./sources/dexscreener.js";
|
|
78
|
+
import { Jupiter } from "./sources/jupiter.js";
|
|
79
|
+
import { JupiterSwap } from "./sources/jupiter-swap.js";
|
|
80
|
+
import { GeckoTerminal } from "./sources/geckoterminal.js";
|
|
81
|
+
import { RugCheck } from "./sources/rugcheck.js";
|
|
82
|
+
import { GoPlus } from "./sources/goplus.js";
|
|
83
|
+
import { SOLANA_PUBLIC_RPC, SolanaRpc } from "./sources/solana-rpc.js";
|
|
84
|
+
import { CandleStore } from "./candles.js";
|
|
85
|
+
import { TokenDetail } from "./detail.js";
|
|
86
|
+
import { Store } from "./store.js";
|
|
87
|
+
import { HELIUS_RPC_HOST, PUBLIC_RPC_POOL } from "./rpc-config.js";
|
|
88
|
+
import { RpcPool, bucketFor } from "./rpc-pool.js";
|
|
89
|
+
import { CreditMeter } from "./credits.js";
|
|
90
|
+
import { BudgetMeter } from "./budget.js";
|
|
91
|
+
/** `helius` for a Helius endpoint (keyed source S9), else the public/custom RPC source S6. */
|
|
92
|
+
export function rpcSourceFor(url) {
|
|
93
|
+
if (!url)
|
|
94
|
+
return 'solana-rpc';
|
|
95
|
+
try {
|
|
96
|
+
return new URL(url).hostname === HELIUS_RPC_HOST ? 'helius' : 'solana-rpc';
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return 'solana-rpc';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export function createDataLayer(opts = {}) {
|
|
103
|
+
const clock = opts.clock ?? systemClock;
|
|
104
|
+
const limiter = new RateLimiter(opts.buckets ?? DEFAULT_BUCKETS, clock, opts.safety);
|
|
105
|
+
const rpcSource = rpcSourceFor(opts.rpcUrl);
|
|
106
|
+
const keys = { ...opts.keys };
|
|
107
|
+
if (rpcSource === 'helius')
|
|
108
|
+
keys.helius = true;
|
|
109
|
+
const health = new HealthRegistry({
|
|
110
|
+
clock,
|
|
111
|
+
keys,
|
|
112
|
+
disabled: opts.disabled,
|
|
113
|
+
usage: (source) => {
|
|
114
|
+
const bucket = SOURCE_BUCKET[source];
|
|
115
|
+
if (!bucket)
|
|
116
|
+
return undefined;
|
|
117
|
+
const s = limiter.bucket(bucket).stats();
|
|
118
|
+
return { rpmUsed: s.rpmUsed, rpmLimit: s.rpmLimit };
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
const cache = new Cache({ path: opts.dbPath, clock });
|
|
122
|
+
// Helius credit meter: every request to the keyed endpoint is charged; at 90 % of the day budget or the
|
|
123
|
+
// per-run cap the source is switched off (health `disabled`) so holders fall back to the public RPC.
|
|
124
|
+
const credits = rpcSource === 'helius'
|
|
125
|
+
? new CreditMeter({
|
|
126
|
+
...opts.credits,
|
|
127
|
+
clock,
|
|
128
|
+
cache,
|
|
129
|
+
onLevel: (level) => health.setDisabled('helius', level === 'degraded'),
|
|
130
|
+
})
|
|
131
|
+
: null;
|
|
132
|
+
if (credits && credits.level() === 'degraded')
|
|
133
|
+
health.setDisabled('helius', true);
|
|
134
|
+
// Per-source request budget meter: counts every request (persisted per UTC day) so usage is visible.
|
|
135
|
+
const budget = new BudgetMeter({ ...opts.budget, clock, cache });
|
|
136
|
+
const onRequest = (req, meta, o) => {
|
|
137
|
+
budget.charge(meta.source);
|
|
138
|
+
if (credits && meta.source === 'helius') {
|
|
139
|
+
let method = null;
|
|
140
|
+
try {
|
|
141
|
+
method = req.body ? (JSON.parse(req.body).method ?? null) : null;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
method = null;
|
|
145
|
+
}
|
|
146
|
+
credits.charge(CreditMeter.costOf(method));
|
|
147
|
+
}
|
|
148
|
+
opts.onRequest?.(req, meta, o);
|
|
149
|
+
};
|
|
150
|
+
// Shutdown signal (task-1319): close() aborts it so any in-flight live fetch rejects immediately and
|
|
151
|
+
// the event loop is not held for the per-request timeout. A caller that builds its own transport must
|
|
152
|
+
// pass its controller as opts.shutdownController and build that transport with its signal, so close()
|
|
153
|
+
// reaches the real app's transport (createLiveFeed does exactly this); otherwise we own the controller
|
|
154
|
+
// and wire it into the default live transport.
|
|
155
|
+
const shutdown = opts.shutdownController ?? new AbortController();
|
|
156
|
+
const http = new HttpClient({ transport: opts.transport ?? liveTransport({ shutdownSignal: shutdown.signal }), limiter, health, clock, onRequest, ...(opts.rateLimitPauseMs !== undefined ? { rateLimitPauseMs: opts.rateLimitPauseMs } : {}) });
|
|
157
|
+
const dexscreener = new DexScreener(http);
|
|
158
|
+
const jupiter = new Jupiter(http);
|
|
159
|
+
const jupiterSwap = new JupiterSwap(http);
|
|
160
|
+
const gecko = new GeckoTerminal(http);
|
|
161
|
+
const rpc = new SolanaRpc(http, { url: opts.rpcUrl, source: rpcSource });
|
|
162
|
+
const fallbackUrl = opts.rpcFallbackUrl === undefined ? (rpc.url === SOLANA_PUBLIC_RPC ? null : SOLANA_PUBLIC_RPC) : opts.rpcFallbackUrl;
|
|
163
|
+
const rpcFallback = fallbackUrl && fallbackUrl !== rpc.url ? new SolanaRpc(http, { url: fallbackUrl, source: 'solana-rpc' }) : null;
|
|
164
|
+
// The pool the detail layer reads through. By default it mirrors the old primary+fallback pair exactly
|
|
165
|
+
// (so behaviour is unchanged); extra user endpoints and the keyless public seed list are opt-in.
|
|
166
|
+
const pool = new RpcPool(http, limiter, buildEndpointSpecs({ rpcUrl: rpc.url, rpcSource, fallbackUrl, opts }), { clock });
|
|
167
|
+
// Keyless holder aggregate: Jupiter's holder count + top-10 share, used when no RPC endpoint serves the ranked list.
|
|
168
|
+
const holdersAggregate = async (mint) => {
|
|
169
|
+
const views = await jupiter.search(mint);
|
|
170
|
+
const v = views.find((x) => x.token.mint === mint) ?? views[0];
|
|
171
|
+
if (!v)
|
|
172
|
+
return null;
|
|
173
|
+
return { holderCount: v.stats.holderCount, top10Pct: v.audit.top10Pct, source: 'jupiter-tokens', fetchedAt: v.stats.fetchedAt };
|
|
174
|
+
};
|
|
175
|
+
const rugcheck = new RugCheck(http);
|
|
176
|
+
const goplus = new GoPlus(http);
|
|
177
|
+
const candles = new CandleStore({ cache, gecko, clock });
|
|
178
|
+
const detail = new TokenDetail({ cache, gecko, pool, holdersAggregate, rugcheck, goplus, candles });
|
|
179
|
+
const store = new Store({ cache, dexscreener, jupiter });
|
|
180
|
+
return { clock, cache, limiter, health, http, dexscreener, jupiter, jupiterSwap, gecko, rpc, rpcFallback, rpcPool: pool, rugcheck, goplus, credits, budget, candles, detail, store, close: () => { shutdown.abort(); limiter.close(); cache.close(); } };
|
|
181
|
+
}
|
|
182
|
+
/** Pool endpoints: the primary first (keyed when Helius/custom), then the public fallback, then any opt-in extras. */
|
|
183
|
+
function buildEndpointSpecs(args) {
|
|
184
|
+
const { rpcUrl, rpcSource, fallbackUrl, opts } = args;
|
|
185
|
+
const specs = [];
|
|
186
|
+
const seen = new Set();
|
|
187
|
+
const add = (spec) => {
|
|
188
|
+
if (seen.has(spec.url))
|
|
189
|
+
return;
|
|
190
|
+
seen.add(spec.url);
|
|
191
|
+
specs.push(spec);
|
|
192
|
+
};
|
|
193
|
+
// Primary keeps its natural source bucket (helius 600rpm / solana-rpc 30rpm) and credit-meter semantics.
|
|
194
|
+
const keyed = rpcSource === 'helius';
|
|
195
|
+
add({ url: rpcUrl, source: rpcSource, bucket: rpcSource, rpm: keyed ? 600 : 30, burst: keyed ? 5 : 1, label: keyed ? 'Helius (free key)' : 'public RPC', keyed });
|
|
196
|
+
if (fallbackUrl && fallbackUrl !== rpcUrl)
|
|
197
|
+
add({ url: fallbackUrl, source: 'solana-rpc', bucket: 'solana-rpc', rpm: 30, burst: 1, label: 'public RPC (fallback)' });
|
|
198
|
+
for (const url of opts.rpcExtraUrls ?? []) {
|
|
199
|
+
const src = rpcSourceFor(url);
|
|
200
|
+
add({ url, source: src, bucket: bucketFor(url), rpm: src === 'helius' ? 600 : 30, burst: src === 'helius' ? 5 : 1, label: 'user RPC', basis: 'env DEXTERM_RPC_URLS', keyed: src === 'helius' });
|
|
201
|
+
}
|
|
202
|
+
if (opts.rpcPublicPool) {
|
|
203
|
+
for (const p of PUBLIC_RPC_POOL)
|
|
204
|
+
add({ url: p.url, source: 'solana-rpc', bucket: bucketFor(p.url), rpm: 30, burst: 1, label: p.label, basis: p.basis });
|
|
205
|
+
}
|
|
206
|
+
return specs;
|
|
207
|
+
}
|
|
208
|
+
export { fetchPage, robotsAllows } from "./larp/robots.js";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { rpcBodyCheck } from "../sources/solana-rpc.js";
|
|
2
|
+
export const HISTORY_METHODS = new Set(['getTransactionsForAddress']);
|
|
3
|
+
export class HeliusHistory {
|
|
4
|
+
http;
|
|
5
|
+
/** May carry an api-key: never print it. */
|
|
6
|
+
url;
|
|
7
|
+
meta = { source: 'helius', bucket: 'helius' };
|
|
8
|
+
constructor(http, url) {
|
|
9
|
+
this.http = http;
|
|
10
|
+
this.url = url;
|
|
11
|
+
}
|
|
12
|
+
async call(method, params) {
|
|
13
|
+
if (!HISTORY_METHODS.has(method))
|
|
14
|
+
throw new Error(`refusing non-history RPC method ${method}`);
|
|
15
|
+
const body = { jsonrpc: '2.0', id: 1, method, params };
|
|
16
|
+
const r = await this.http.postJson(this.url, body, this.meta, rpcBodyCheck);
|
|
17
|
+
if (r.data.result === undefined)
|
|
18
|
+
throw new Error(`rpc ${method}: no result`);
|
|
19
|
+
return { result: r.data.result, fetchedAt: r.fetchedAt };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Succeeded transactions referencing `address`, full jsonParsed, oldest first by default. `limit` ≤ 1000
|
|
23
|
+
* (Helius pages at 100 credits-wise: 10 credits per 100 txs).
|
|
24
|
+
*/
|
|
25
|
+
async transactions(address, opts) {
|
|
26
|
+
const limit = Math.max(1, Math.min(1000, Math.floor(opts.limit)));
|
|
27
|
+
const params = {
|
|
28
|
+
transactionDetails: 'full', sortOrder: opts.sortOrder ?? 'asc', limit, encoding: 'jsonParsed', maxSupportedTransactionVersion: 0,
|
|
29
|
+
filters: { status: 'succeeded' },
|
|
30
|
+
};
|
|
31
|
+
if (opts.paginationToken)
|
|
32
|
+
params.paginationToken = opts.paginationToken;
|
|
33
|
+
const { result, fetchedAt } = await this.call('getTransactionsForAddress', [address, params]);
|
|
34
|
+
return { data: Array.isArray(result.data) ? result.data.map(slimTx) : [], paginationToken: result.paginationToken ?? null, fetchedAt };
|
|
35
|
+
}
|
|
36
|
+
/** A wallet's oldest 3 succeeded txs (funding source + wallet age). 10 credits. */
|
|
37
|
+
firstTxs(wallet) {
|
|
38
|
+
return this.transactions(wallet, { limit: 3, sortOrder: 'asc' });
|
|
39
|
+
}
|
|
40
|
+
/** The mint's oldest `limit` succeeded txs (launch window). 10 credits per 100. */
|
|
41
|
+
launchWindow(mint, limit, paginationToken) {
|
|
42
|
+
return this.transactions(mint, { limit, sortOrder: 'asc', paginationToken });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Keep only the fields the rules read (account keys with the signer flag, balances, token balances, slot,
|
|
47
|
+
* time, first signature). A full jsonParsed tx is 10–15 KB; this is ≈ 1–3 KB, which is what the cache stores.
|
|
48
|
+
*/
|
|
49
|
+
export function slimTx(tx) {
|
|
50
|
+
const keys = (tx.transaction?.message?.accountKeys ?? []).map((k) => (typeof k === 'string' ? k : { pubkey: k.pubkey, signer: !!k.signer }));
|
|
51
|
+
const tb = (arr) => (arr ?? []).map((b) => ({ accountIndex: b.accountIndex, mint: b.mint, owner: b.owner, uiTokenAmount: { amount: b.uiTokenAmount.amount } }));
|
|
52
|
+
return {
|
|
53
|
+
slot: tx.slot,
|
|
54
|
+
blockTime: tx.blockTime ?? null,
|
|
55
|
+
transactionIndex: tx.transactionIndex ?? null,
|
|
56
|
+
transaction: { signatures: tx.transaction?.signatures?.slice(0, 1) ?? [], message: { accountKeys: keys } },
|
|
57
|
+
meta: tx.meta ? { preBalances: tx.meta.preBalances ?? [], postBalances: tx.meta.postBalances ?? [], preTokenBalances: tb(tx.meta.preTokenBalances), postTokenBalances: tb(tx.meta.postTokenBalances) } : null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// Holder CLASSIFICATION (task-1367): what kind of owner holds a top token account — a pool, a bonding curve, a
|
|
2
|
+
// launch/escrow vault, a lock, an exchange, the burn address, the creator, a wallet linked to other top holders —
|
|
3
|
+
// or UNLABELLED when the chain facts we already have do not say. Pure: the inputs are the token account's owner
|
|
4
|
+
// (getMultipleAccounts over the token accounts) and the OWNER account's program (getMultipleAccounts over the
|
|
5
|
+
// owners), both fetched by the wallet-intel scan already, plus the launch-window labels the rules derived. No new
|
|
6
|
+
// request, no paid API, no scraping.
|
|
7
|
+
//
|
|
8
|
+
// Never a guess. A class is only given when the owner is (a) a program authority we can re-derive (the constant
|
|
9
|
+
// pool-authority PDAs below are checked in the tests with findProgramAddress), (b) an account owned by a program
|
|
10
|
+
// in PROGRAM_CLASS, (c) the incinerator / system address, (d) a seed-list exchange wallet (always "unverified"),
|
|
11
|
+
// or (e) an on-chain launch rule (D1 creator, P1 pool, linked cluster). Anything else — a plain wallet, an account
|
|
12
|
+
// of a program we do not list, a PDA with no account — is UNLABELLED with what we do know, and is COUNTED in the
|
|
13
|
+
// ex-pool concentration: an unknown program could be the dev's own contract, so it is never hidden.
|
|
14
|
+
import { SYSTEM_PROGRAM } from "../trade/tx-decode.js";
|
|
15
|
+
import { TOKEN_PROGRAM, TOKEN_2022_PROGRAM } from "../sources/solana-rpc.js";
|
|
16
|
+
import { PUMP_PROGRAM_ID, pumpBondingCurve, base58Decode, isOnCurve } from "../sources/pda.js";
|
|
17
|
+
/** Classes whose balance is not a person's position: dropped from the ex-pool top-10. */
|
|
18
|
+
export const EX_POOL_TAGS = new Set(['POOL', 'CURVE', 'VAULT', 'LOCK', 'BURN']);
|
|
19
|
+
/** An unlabelled (or creator / linked) owner above this share is called out as the main risk. */
|
|
20
|
+
export const BIG_HOLDER_PCT = 30;
|
|
21
|
+
/**
|
|
22
|
+
* Programs whose ACCOUNTS own token accounts that are not a person's position. Keyed by program id: when the
|
|
23
|
+
* token account's owner is an account owned by one of these programs, the owner is that program's pool / curve
|
|
24
|
+
* / vault / escrow state.
|
|
25
|
+
*/
|
|
26
|
+
export const PROGRAM_CLASS = {
|
|
27
|
+
'675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8': { tag: 'POOL', name: 'Raydium AMM v4', what: 'AMM pool vault' },
|
|
28
|
+
CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C: { tag: 'POOL', name: 'Raydium CPMM', what: 'AMM pool vault' },
|
|
29
|
+
CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK: { tag: 'POOL', name: 'Raydium CLMM', what: 'concentrated-liquidity pool vault' },
|
|
30
|
+
LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj: { tag: 'CURVE', name: 'Raydium LaunchLab', what: 'bonding-curve vault' },
|
|
31
|
+
whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc: { tag: 'POOL', name: 'Orca Whirlpool', what: 'concentrated-liquidity pool vault' },
|
|
32
|
+
LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo: { tag: 'POOL', name: 'Meteora DLMM', what: 'DLMM pool reserve' },
|
|
33
|
+
Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB: { tag: 'POOL', name: 'Meteora DAMM v1', what: 'dynamic AMM pool' },
|
|
34
|
+
cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG: { tag: 'POOL', name: 'Meteora DAMM v2', what: 'dynamic AMM pool' },
|
|
35
|
+
dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN: { tag: 'CURVE', name: 'Meteora DBC', what: 'dynamic bonding-curve vault (Jupiter Studio / Meteora launches)' },
|
|
36
|
+
'24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi': { tag: 'VAULT', name: 'Meteora dynamic vault', what: 'vault backing Meteora pool liquidity' },
|
|
37
|
+
vaU6kP7iNEGkbmPkLmZfGwiGxd4Mob24QQCie5R9kd2: { tag: 'VAULT', name: 'Meteora Alpha Vault', what: 'launch vault: tokens owed to its depositors' },
|
|
38
|
+
[PUMP_PROGRAM_ID]: { tag: 'CURVE', name: 'pump.fun', what: 'bonding curve' },
|
|
39
|
+
pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA: { tag: 'POOL', name: 'PumpSwap', what: 'AMM pool vault' },
|
|
40
|
+
strmRqUCoQUgGUan5YhzUZa6KqdzwX5L6FpUxfmKg5m: { tag: 'LOCK', name: 'Streamflow', what: 'vesting / lock escrow' },
|
|
41
|
+
LocpQgucEQHbqNABEYvBvwoxCPsSbG91A1QaQhQQqjn: { tag: 'LOCK', name: 'Jupiter Lock', what: 'vesting / lock escrow' },
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Constant program-derived authorities that own the vaults of EVERY pool of their program. They are PDAs with no
|
|
45
|
+
* account of their own, so the owner-program lookup cannot see them; the tests re-derive each with
|
|
46
|
+
* findProgramAddress(seed, program) so a typo can never ship.
|
|
47
|
+
*/
|
|
48
|
+
export const AUTHORITY_CLASS = {
|
|
49
|
+
'5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1': { tag: 'POOL', name: 'Raydium AMM v4', what: 'pool authority', program: '675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8', seed: 'amm authority' },
|
|
50
|
+
GpMZbSM2GgvTKHJirzeGfMFoaZ8UR2X7F4v8vHTvxFbL: { tag: 'POOL', name: 'Raydium CPMM', what: 'vault authority', program: 'CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C', seed: 'vault_and_lp_mint_auth_seed' },
|
|
51
|
+
WLHv2UAZm6z4KyaaELi5pjdbJh6RESMva1Rnn8pJVVh: { tag: 'CURVE', name: 'Raydium LaunchLab', what: 'curve vault authority', program: 'LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj', seed: 'vault_auth_seed' },
|
|
52
|
+
FhVo3mqL8PW5pH5U2CN4XE33DokiyZnUwuGpH2hmHLuM: { tag: 'CURVE', name: 'Meteora DBC', what: 'pool authority (holds every DBC curve vault: Jupiter Studio / Meteora launches)', program: 'dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN', seed: 'pool_authority' },
|
|
53
|
+
HLnpSz9h2S4hiLQ43rnSD9XkcUThA7B8hQMKmDaiTLcC: { tag: 'POOL', name: 'Meteora DAMM v2', what: 'pool authority', program: 'cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG', seed: 'pool_authority' },
|
|
54
|
+
};
|
|
55
|
+
export const INCINERATOR = '1nc1nerator11111111111111111111111111111111';
|
|
56
|
+
const short = (a) => (a ? `${a.slice(0, 4)}…${a.slice(-4)}` : '—');
|
|
57
|
+
/** Whether `a` is a valid ed25519 point (a keypair can sign) — false for a PDA. Null for a malformed address. */
|
|
58
|
+
export function onCurve(a) {
|
|
59
|
+
try {
|
|
60
|
+
const b = base58Decode(a);
|
|
61
|
+
return b.length === 32 ? isOnCurve(b) : null;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const curveCache = new Map();
|
|
68
|
+
function pumpCurveOf(mint) {
|
|
69
|
+
if (!curveCache.has(mint)) {
|
|
70
|
+
let c = null;
|
|
71
|
+
try {
|
|
72
|
+
c = pumpBondingCurve(mint);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
c = null;
|
|
76
|
+
}
|
|
77
|
+
curveCache.set(mint, c);
|
|
78
|
+
if (curveCache.size > 512)
|
|
79
|
+
curveCache.delete(curveCache.keys().next().value);
|
|
80
|
+
}
|
|
81
|
+
return curveCache.get(mint) ?? null;
|
|
82
|
+
}
|
|
83
|
+
function escrowOf(owner, e) {
|
|
84
|
+
if (e.tag !== 'LOCK' && e.tag !== 'VAULT')
|
|
85
|
+
return null;
|
|
86
|
+
return { escrow: owner, program: e.name, unlock: null, authority: null, note: `unlock schedule not decoded: open escrow ${short(owner)} on ${e.name} to read it` };
|
|
87
|
+
}
|
|
88
|
+
/** Classify one top holder. Order: burn → derived authority → owner program → creator → linked → exchange → P1 → unlabelled. */
|
|
89
|
+
export function classifyHolder(x) {
|
|
90
|
+
const { owner, meta } = x;
|
|
91
|
+
if (owner === INCINERATOR)
|
|
92
|
+
return { tag: 'BURN', reason: 'owner is the incinerator address (1nc1nerator…): tokens sent there can never move', program: null, lock: null };
|
|
93
|
+
if (owner === SYSTEM_PROGRAM)
|
|
94
|
+
return { tag: 'BURN', reason: 'owner is the System Program address (1111…1111): no key can sign for it', program: null, lock: null };
|
|
95
|
+
const auth = AUTHORITY_CLASS[owner];
|
|
96
|
+
if (auth)
|
|
97
|
+
return { tag: auth.tag, reason: `${auth.name} ${auth.what} (${short(owner)}, a PDA of the ${auth.name} program)`, program: auth.name, lock: null };
|
|
98
|
+
if (owner === pumpCurveOf(x.mint))
|
|
99
|
+
return { tag: 'CURVE', reason: `pump.fun bonding curve of this mint (${short(owner)} = PDA "bonding-curve" + mint)`, program: 'pump.fun', lock: null };
|
|
100
|
+
const prog = meta?.exists ? meta.programOwner : null;
|
|
101
|
+
const pe = prog ? PROGRAM_CLASS[prog] : undefined;
|
|
102
|
+
if (pe)
|
|
103
|
+
return { tag: pe.tag, reason: `owner ${short(owner)} is an account of the ${pe.name} program: ${pe.what}`, program: pe.name, lock: escrowOf(owner, pe) };
|
|
104
|
+
if (x.dev)
|
|
105
|
+
return { tag: 'DEV', reason: x.dev, program: null, lock: null };
|
|
106
|
+
if (x.linked)
|
|
107
|
+
return { tag: 'LINKED', reason: x.linked, program: null, lock: null };
|
|
108
|
+
if (x.cex)
|
|
109
|
+
return { tag: 'CEX', reason: `exchange hot wallet: ${x.cex} (seed list, unverified by a second source)`, program: null, lock: null };
|
|
110
|
+
if (x.poolRule)
|
|
111
|
+
return { tag: 'POOL', reason: x.poolRule, program: null, lock: null };
|
|
112
|
+
// ---- unlabelled: say what we know, never what it "probably" is
|
|
113
|
+
if (!meta)
|
|
114
|
+
return { tag: 'UNLABELLED', reason: 'owner kind not resolved (account lookup did not answer): treat as a person', program: null, lock: null };
|
|
115
|
+
if (prog === TOKEN_PROGRAM || prog === TOKEN_2022_PROGRAM) {
|
|
116
|
+
const self = x.tokenAccounts.includes(owner);
|
|
117
|
+
return { tag: 'UNLABELLED', reason: `owner ${short(owner)} is ${self ? 'its own token account' : 'an SPL Token account'}: a program escrow, but the program that controls it is not identified, so it is counted`, program: null, lock: null };
|
|
118
|
+
}
|
|
119
|
+
if (meta.exists && prog !== SYSTEM_PROGRAM)
|
|
120
|
+
return { tag: 'UNLABELLED', reason: `owner is an account of program ${short(prog)}, which is not in dexterm's program list: not a keypair wallet, but not a known pool or lock either, so it is counted`, program: null, lock: null };
|
|
121
|
+
const curve = onCurve(owner);
|
|
122
|
+
if (curve === false)
|
|
123
|
+
return { tag: 'UNLABELLED', reason: `owner ${short(owner)} is a PDA (off-curve${meta.exists ? ', System-owned' : ', no account'}) of an unidentified program: counted`, program: null, lock: null };
|
|
124
|
+
return { tag: 'UNLABELLED', reason: `plain wallet (${meta.exists ? 'System-owned' : 'no SOL account'}${curve ? ', a keypair address' : ''}): no pool, lock, exchange or launch rule matched`, program: null, lock: null };
|
|
125
|
+
}
|