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,178 @@
|
|
|
1
|
+
import { fromSnapshot } from "../screener/rows.js";
|
|
2
|
+
export const WATCH_REFRESH_MS = 10_000;
|
|
3
|
+
export class WatchlistLive {
|
|
4
|
+
dl;
|
|
5
|
+
store;
|
|
6
|
+
now;
|
|
7
|
+
onChange;
|
|
8
|
+
rows = new Map();
|
|
9
|
+
stale = new Set();
|
|
10
|
+
errors = {};
|
|
11
|
+
refreshedAt = null;
|
|
12
|
+
refreshing = false;
|
|
13
|
+
/** One-line note for the UI after a keypress (`added $X`, `alert armed`), cleared by the next action. */
|
|
14
|
+
notice = null;
|
|
15
|
+
constructor(dl, store, opts = {}) {
|
|
16
|
+
this.dl = dl;
|
|
17
|
+
this.store = store;
|
|
18
|
+
this.now = opts.now ?? (() => Date.now());
|
|
19
|
+
this.onChange = opts.onChange;
|
|
20
|
+
}
|
|
21
|
+
list() {
|
|
22
|
+
return this.store.list().map((entry) => {
|
|
23
|
+
const row = this.rows.get(entry.mint) ?? null;
|
|
24
|
+
const price = row?.price ?? null;
|
|
25
|
+
const pnlPct = price !== null && entry.entryPrice !== null && entry.entryPrice > 0 ? (price / entry.entryPrice - 1) * 100 : null;
|
|
26
|
+
return { entry, row, pnlPct, stale: this.stale.has(entry.mint) };
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
has(mint) {
|
|
30
|
+
return this.store.has(mint);
|
|
31
|
+
}
|
|
32
|
+
/** Add (or report already watched). Proposes the two default price alerts; nothing is armed. */
|
|
33
|
+
add(c) {
|
|
34
|
+
const isNew = this.store.add({ mint: c.mint, symbol: c.symbol, name: c.name, launchpad: c.launchpad, entryPrice: c.price });
|
|
35
|
+
if (!isNew) {
|
|
36
|
+
this.notice = `$${c.symbol} is already on the watchlist`;
|
|
37
|
+
this.onChange?.();
|
|
38
|
+
return 'already';
|
|
39
|
+
}
|
|
40
|
+
let proposed = 0;
|
|
41
|
+
if (c.price !== null && c.price > 0) {
|
|
42
|
+
this.store.propose({ mint: c.mint, kind: 'price', op: '>', value: c.price * 1.25, note: '+25% vs entry' });
|
|
43
|
+
this.store.propose({ mint: c.mint, kind: 'price', op: '<', value: c.price * 0.75, note: '-25% vs entry' });
|
|
44
|
+
proposed = 2;
|
|
45
|
+
}
|
|
46
|
+
else if (c.mcap !== null && c.mcap !== undefined && c.mcap > 0) {
|
|
47
|
+
// no price yet (a pair seconds old): propose on market cap instead, the number traders actually quote
|
|
48
|
+
this.store.propose({ mint: c.mint, kind: 'mcap', op: '>', value: c.mcap * 2, note: '2x mcap vs add' });
|
|
49
|
+
this.store.propose({ mint: c.mint, kind: 'mcap', op: '<', value: c.mcap * 0.5, note: 'half mcap vs add' });
|
|
50
|
+
proposed = 2;
|
|
51
|
+
}
|
|
52
|
+
this.store.log({ mint: c.mint, kind: 'watch', level: 'info', text: `${c.symbol} added to watchlist${c.price !== null ? ` at ${fmtPrice(c.price)}` : c.mcap ? ` at ${fmtAny('mcap', c.mcap)} mcap` : ''}` });
|
|
53
|
+
this.notice = `watching $${c.symbol}${proposed ? ` · ${proposed} alert proposals (y to arm, x to dismiss)` : ' · no price or mcap yet, so no alert proposals'}`;
|
|
54
|
+
this.onChange?.();
|
|
55
|
+
return 'added';
|
|
56
|
+
}
|
|
57
|
+
remove(mint) {
|
|
58
|
+
const e = this.store.get(mint);
|
|
59
|
+
const ok = this.store.remove(mint);
|
|
60
|
+
this.rows.delete(mint);
|
|
61
|
+
if (ok) {
|
|
62
|
+
this.store.log({ mint, kind: 'watch', level: 'info', text: `${e?.symbol ?? mint.slice(0, 6)} removed from watchlist` });
|
|
63
|
+
this.notice = `removed $${e?.symbol ?? mint.slice(0, 6)}`;
|
|
64
|
+
}
|
|
65
|
+
this.onChange?.();
|
|
66
|
+
return ok;
|
|
67
|
+
}
|
|
68
|
+
/** Propose a liquidity alert for a mint (−40 % from the current liquidity) or a price one when no liquidity is known. */
|
|
69
|
+
propose(c) {
|
|
70
|
+
if (!this.store.has(c.mint))
|
|
71
|
+
this.add(c);
|
|
72
|
+
const liq = c.liq ?? this.rows.get(c.mint)?.liq ?? null;
|
|
73
|
+
let rule = null;
|
|
74
|
+
if (liq !== null && liq > 0)
|
|
75
|
+
rule = this.store.propose({ mint: c.mint, kind: 'liq', op: '<', value: liq * 0.6, note: 'liquidity -40%' });
|
|
76
|
+
else if (c.price !== null && c.price > 0)
|
|
77
|
+
rule = this.store.propose({ mint: c.mint, kind: 'price', op: '<', value: c.price * 0.8, note: '-20% from here' });
|
|
78
|
+
this.notice = rule ? `proposed: ${c.symbol} ${rule.kind} ${rule.op} ${fmtAny(rule.kind, rule.value)} · y to arm, x to dismiss` : `nothing to alert on for $${c.symbol} yet`;
|
|
79
|
+
this.onChange?.();
|
|
80
|
+
return rule;
|
|
81
|
+
}
|
|
82
|
+
proposals(mint) {
|
|
83
|
+
return this.store.rules('proposed', mint);
|
|
84
|
+
}
|
|
85
|
+
armed(mint) {
|
|
86
|
+
return this.store.rules('armed', mint);
|
|
87
|
+
}
|
|
88
|
+
/** Arm the oldest proposal (for `mint` when given). The keypress is the confirmation. */
|
|
89
|
+
confirm(mint) {
|
|
90
|
+
const p = this.proposals(mint)[0] ?? this.proposals()[0];
|
|
91
|
+
if (!p) {
|
|
92
|
+
this.notice = 'no alert proposals to confirm';
|
|
93
|
+
this.onChange?.();
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const r = this.store.confirm(p.id);
|
|
97
|
+
const sym = this.store.get(r.mint)?.symbol ?? r.mint.slice(0, 6);
|
|
98
|
+
this.store.log({ mint: r.mint, kind: 'alert', level: 'info', text: `armed: ${sym} ${r.kind} ${r.op} ${fmtAny(r.kind, r.value)}` });
|
|
99
|
+
this.notice = `armed: ${sym} ${r.kind} ${r.op} ${fmtAny(r.kind, r.value)}`;
|
|
100
|
+
this.onChange?.();
|
|
101
|
+
return r;
|
|
102
|
+
}
|
|
103
|
+
dismiss(mint) {
|
|
104
|
+
const p = this.proposals(mint)[0] ?? this.proposals()[0];
|
|
105
|
+
if (!p) {
|
|
106
|
+
this.notice = 'no alert proposals to dismiss';
|
|
107
|
+
this.onChange?.();
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const r = this.store.dismiss(p.id);
|
|
111
|
+
this.notice = `dismissed proposal for ${this.store.get(r.mint)?.symbol ?? r.mint.slice(0, 6)}`;
|
|
112
|
+
this.onChange?.();
|
|
113
|
+
return r;
|
|
114
|
+
}
|
|
115
|
+
events(limit = 40) {
|
|
116
|
+
return this.store.events(limit);
|
|
117
|
+
}
|
|
118
|
+
/** Refresh prices for every watched mint, then evaluate armed rules. Never throws. */
|
|
119
|
+
async refresh() {
|
|
120
|
+
if (this.refreshing)
|
|
121
|
+
return;
|
|
122
|
+
this.refreshing = true;
|
|
123
|
+
try {
|
|
124
|
+
const mints = this.store.list().map((e) => e.mint);
|
|
125
|
+
if (!mints.length) {
|
|
126
|
+
this.refreshedAt = this.now();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const res = await this.dl.store.enrich(mints, { price: true });
|
|
130
|
+
const now = this.now();
|
|
131
|
+
this.stale.clear();
|
|
132
|
+
for (const r of res.rows) {
|
|
133
|
+
this.rows.set(r.mint, fromSnapshot(r, now));
|
|
134
|
+
if (r.stale)
|
|
135
|
+
this.stale.add(r.mint);
|
|
136
|
+
}
|
|
137
|
+
this.errors = res.errors;
|
|
138
|
+
const values = new Map();
|
|
139
|
+
for (const [mint, row] of this.rows)
|
|
140
|
+
values.set(mint, { price: row.price, liq: row.liq, holders: row.holders, mcap: row.mcap });
|
|
141
|
+
const fired = this.store.evaluate(values, (m) => this.store.get(m)?.symbol ?? m.slice(0, 6));
|
|
142
|
+
if (fired.length)
|
|
143
|
+
this.notice = `alert: ${fired[0].text}`;
|
|
144
|
+
this.refreshedAt = now;
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
this.errors = { ...this.errors, dexscreener: err instanceof Error ? err.message : String(err) };
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
this.refreshing = false;
|
|
151
|
+
this.onChange?.();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
status() {
|
|
155
|
+
const n = this.store.list().length;
|
|
156
|
+
const h = this.dl.health;
|
|
157
|
+
const bad = ['dexscreener', 'jupiter-tokens', 'jupiter-price'].filter((s) => !h.isAvailable(s));
|
|
158
|
+
const names = [...new Set(bad.map((s) => (s.startsWith('jupiter') ? 'jup' : s)))];
|
|
159
|
+
const armed = this.armed().length;
|
|
160
|
+
const proposed = this.proposals().length;
|
|
161
|
+
return {
|
|
162
|
+
caption: `${n} token${n === 1 ? '' : 's'} · PnL vs entry · ${armed} armed · ${proposed} proposed`,
|
|
163
|
+
headerStatus: names.length ? `◐ degraded: ${names.join(', ')}` : undefined,
|
|
164
|
+
errors: this.errors,
|
|
165
|
+
refreshedAt: this.refreshedAt,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function fmtPrice(p) {
|
|
170
|
+
return p >= 1 ? `$${p.toFixed(2)}` : `$${p.toPrecision(3)}`;
|
|
171
|
+
}
|
|
172
|
+
function fmtAny(kind, v) {
|
|
173
|
+
if (kind === 'price')
|
|
174
|
+
return fmtPrice(v);
|
|
175
|
+
if (kind === 'holders')
|
|
176
|
+
return String(Math.round(v));
|
|
177
|
+
return v >= 1e6 ? `$${(v / 1e6).toFixed(1)}M` : v >= 1e3 ? `$${(v / 1e3).toFixed(0)}K` : `$${v.toFixed(0)}`;
|
|
178
|
+
}
|