security & trust
what dexterm does with your machine, your network and your money (nothing), stated so you can check it against the source. the app is at 87b598f (2026-10-09); the host table below is cross-checked against that commit by the site build.
at a glance
- read-onlyno wallet connection, no signing, no transactions. there is no code path on main that builds or sends one; the paper module imports no wallet or signing library, and a key scan of the sources is part of verification.
- no keys handleddexterm ships no API key. the only key it can read is a free RPC key you created, from a file you own, used in memory and never printed.
- no accounts, no telemetryno login, no server of ours, no analytics, no crash reporter. every request goes from your machine to a public data API.
- no paid data requiredevery feature has a keyless path; a free key only raises limits.
- honest when downa source that fails shows
unavailable: reasonorneeds key, never a number. - the model can only proposethe analyst navigates and opens PAPER tickets; your keys arm and confirm. in scan mode it cannot even do that.
- planned: signed releasespublic repo, build provenance, checksums, sbom, third-party scans on this page. license decision pending. no date.
what dexterm can do
- read public market, chain and security data about Solana tokens from the hosts listed below, and cache it in a local SQLite file.
- keep a local watchlist and alert rules; fire an armed alert into an on-screen log.
- run your own
claudelogin as a local process against a read-only MCP server, and let it navigate the app (open a coin, filter, watch, switch feed, open a PAPER ticket) within an allow-list of what is on screen. - simulate trades: a PAPER wallet booked from live quotes, in the same local file.
- keep a local history of the coins it saw and how they turned out (the history recorder), in the same local file; nothing is uploaded, and
--no-recorderturns it off. - rank a trending board from public trending lists and publishers' RSS feeds, and keep your KOL lists locally.
- open a chart window served from a loopback-only server on your machine.
- fetch a token's advertised website, read-only, when you press the key for it; open advertised links in your browser after showing you the URL.
- during install, download an official Node build if none is found, verified against Node's published checksums; build a small Rust shell if
cargois present.
what dexterm can never do
- ask for a seed phrase, a private key or a wallet connection. anything that does is not dexterm.
- sign, hold or send a transaction. no signer exists on main. the PAPER ticket is a simulation booked into a local file; the quote adapter is quote-only (no build, no execute endpoint is called).
- send anything to a dexterm server. there is none.
- act on a model's say-so. every UI action the analyst requests is re-validated by the app against the current screen, rate-limited, and limited to navigation; a mint not on screen is rejected and changes nothing.
open_ticketopens a ticket in its editing phase and nothing else. - trade from the scan. scan sessions have an empty action allow-list at the validator, the MCP server, the
claudelaunch (--disallowedTools) and the app; a compromised-model test proves it. - follow text in a token's name, description or website. it is wrapped as untrusted data and flagged if it looks like an instruction.
- fabricate data. the health registry degrades every source visibly.
- run anything from a popup. popups receive view models only, send events from a closed list, and are pinned to the loopback origin.
- open a non-http(s) link. the open-link keys re-parse the URL and pass it as a single argument to the OS opener;
file:,javascript:and friends never reach a shell. - post, follow, or log in to X or anywhere else. there is no X API client and no scraper; the social layer reads public trending lists and RSS only.
- dm you first, run a token, or promise returns.
no custody, no private keys, ever
today there is nothing to hold: the app has no wallet code. the design for real trading, built on an unmerged branch and reviewed three rounds, keeps it that way: Phantom signs in your browser over a loopback page and only the signed bytes and your public key ever return to the terminal; dexterm stores the public key alone (mode 600) and refuses to store anything else; caps (per trade, per day, price impact) and a positive description of what a swap transaction may contain live in a signer-side policy that re-checks every transaction and refuses out of policy even if the UI, the model or a popup is compromised; the keypress gate is on by default. none of that is live, and the features page will say when it is.
what the analyst can never do
- sign, confirm or trade. there is no tool for it. its only write-shaped tool opens a PAPER ticket for you to confirm.
- use its memory as fact. every fact about a token must come from a tool result in the session, with its source and age; the knowledge base holds mechanics and patterns only.
- act outside the screen. actions name mints that are on screen, feeds that exist, sort keys that exist, or they are rejected. actions are rate-limited.
- treat untrusted text as instructions. token names, descriptions, socials, social posts, news headlines, RugCheck text and fetched pages pass a prompt firewall (normalised, control and bidi characters stripped, URLs and addresses masked, wrapped as untrusted, breakout tags stripped); instruction-like text inside is reported as a red flag.
- reach anything else. the launch uses
--tools '',--strict-mcp-configwith the dexterm server only,--setting-sources ''and--permission-mode dontAsk: no shell, no files, no other servers, no prompts to you. - see your keys. it never sees the RPC key or your Claude credentials; dexterm only spawns the
claudebinary you already log into.
what it can be: wrong. its output is labelled model output with data ages and is not financial advice.
AI scan mode is observe-only
the scan reads data already in memory and the local cache (zero extra requests, proven by a test and by measured req/min), scores it, opens a coin's screen and starts a short analyst read. four structural layers, not a prompt, keep that session from taking any UI action, and a static test fails if the scan code ever imports a trade module. details in the scan docs.
what leaves your machine, and to whom
every host the app at 87b598f can contact. none of these are ours; each provider sees your IP and the addresses you look up, under its own terms (attribution and terms). a request-budget meter in the app counts every call per source so you can see usage.
| host | purpose | when | what is sent | key |
|---|---|---|---|---|
api.dexscreener.com | screener rows, token market data, watchlist prices, buy/sell flow, paper position marks; the top paid boosts, which count against a coin on the trending board; the history recorder's outcome re-checks | every ~10 s while the screener, token, watchlist or positions screen is open; boosts once a minute while the live app runs; recorder re-checks at the lowest priority, ≤ 6 calls a minute and ≤ 1,500 a day, skipped while DexScreener is rate-limiting | the mint addresses on screen; your IP | none |
cdn.dexscreener.com (and the token's own image host) | coin images: DexScreener's image CDN first (asked for a 128 px rendition), otherwise whatever URL the token's metadata advertises (an IPFS gateway, a project site) | once per coin, for the rows on screen and the open token; never again while the thumbnail is in the local cache (~/.local/share/dexterm/images/, 32 MB LRU); never from the chart popup, which is served the cached copy; off with --no-images | the image URL path; your IP | none |
lite-api.jup.ag · api.jup.ag | token list and metadata, organic score, holder count and top-10 concentration, SOL price, swap quotes for the PAPER ticket; the trending and organic-score top lists for the trending board | with the screener refresh; when you open a token or a paper ticket; the trending lists once a minute while the live app runs | mint addresses; your IP (the quote request carries no wallet) | none (a free Jupiter key only raises the rate) |
api.geckoterminal.com | candles and the trade tape; trending pools for the trending board | when you open a token or switch to an uncached timeframe (≤10 calls/min, chart first); trending pools once a minute while the live app runs (same budget) | the pool address; your IP | none |
api.mainnet-beta.solana.com · solana-rpc.publicnode.com (or the RPC you configure) | mint and freeze authority; the ranked holder list where the endpoint allows it; the fast-lane price WebSocket on pump.fun bonding curves | when you open a token; one WebSocket while a token or your watchlist is open | account addresses; your IP | none (any free RPC URL in DEXTERM_RPC_URL joins the pool) |
mainnet.helius-rpc.com | the same RPC calls and WebSocket, faster and with the ranked holders, when you saved a free Helius key | only if ~/.dexterm/helius.key exists; a credit meter caps spend per day and per run | account addresses and your key, to Helius only; the key is never printed or recorded | your own free key |
api.rugcheck.xyz | RugCheck summary; the new-token poll | when you open a token; every 30 s on new pairs | mint addresses; your IP | none |
api.gopluslabs.io | second-opinion security checks and the pump.fun metadata link | when you open a token | mint addresses; your IP | none |
pumpportal.fun (WebSocket) | new token and migration events | one connection while the new-pairs screen or a live-backed preset is open | two subscribe messages; your IP | none |
api.coingecko.com | CoinGecko trending coins, as macro context on the trending board (matched to board coins by symbol only) | once a minute while the live app runs (≤ 10 calls/min bucket); not in --fixtures, and in --replay only if the recording carries it | nothing but the request; your IP | none |
www.coindesk.com · cointelegraph.com · www.theblock.co · decrypt.co | the NEWS column on the trending board: each publisher's official RSS feed (headlines are context, not signal, and pass the prompt firewall). A headline link opens in your browser only when you press ⏎; dexterm never fetches the article | every 10 min while the live app runs; not in --fixtures, and in --replay only if the recording carries it | a plain GET for the feed; your IP | none |
rdap.org · api.github.com · the token's advertised website, X and Telegram | the LARP detector: domain registration age, GitHub activity, a read-only page fetch (SSRF-safe, size-capped, robots.txt honoured) and the open-link keys | only when you press V, W, X, T or L on a token; never automatically | the domain or URL the token claims; your IP to those hosts | none |
nodejs.org | the installer downloads Node only if none ≥ 22.18 is found, and verifies it against the published SHASUMS256.txt | during ./install.sh, once (crates.io is fetched too if it builds the native chart window with cargo) | the download request | none |
your `claude` CLI → Anthropic | the analyst runs your own Claude Code login | only when you press a, V, ask a question, or a scan lock starts a read | the prompt dexterm builds (tool results about the coin you chose, token text wrapped as untrusted) under your own account and billing | your own Claude login; dexterm ships no API key |
127.0.0.1 (loopback only) | the chart popup server: random port, single-use ticket, strict Host and Origin, no CORS | while a chart popup is open | view models and theme tokens to the popup page; never keys | none |
hosts that appear in the source but are never contacted by the app:
docs.gopluslabs.io: documentation link in a source commentclaude.com: printed in a doctor fix line (install Claude Code); never fetcheddashboard.helius.dev: printed in a doctor fix line (make a free key); never fetchedrustup.rs: printed by install.sh and doctor when cargo is missing; never fetchedwww.tradingview.com: the Lightweight Charts attribution link in the chart popup footer; the page loads nothing from itevil.example: negative test fixture in the native shell's origin-pin tests127.0.0.1.evil.example: negative test fixture in the native shell's origin-pin testsjson-schema.org: $schema identifiers in the analyst output schemas; never fetchedx.com: only inside made-up demo post text and links in the --fixtures social demo (packages/cli/src/social/demo.ts); dexterm has no X API client and never contacts x.com itself (the X key opens a token's advertised link in your browser)
source: every https://, http:// and wss:// literal under packages/*/src, packages/cli/assets and install.sh at 87b598f, extracted by the site build and compared with this table; the build fails on a host in the source that this page does not account for. if you find one anyway, that is a bug: report it.
what stays on your machine
~/.local/share/dexterm/dexterm.db: the cache, your watchlist and alerts, request and credit counters, the PAPER wallet, your KOL lists, and the history recorder's tables (about 100 MB per 8-hour live day, measured; retention and off switch).~/.dexterm/state.json(launch count),~/.dexterm/helius.key(only if you made one),~/.dexterm/popup.jsonand~/.dexterm/images.json(only if you wrote them);~/.local/share/dexterm/images/: the coin-picture cache (the app's own re-encoded thumbnails, 32 MB LRU).- nothing else. delete them and dexterm forgets everything. details in configuration.
privacy
- images and APIs contact third-party hosts. every request above goes to a provider that sees your IP; the LARP detector and the open-link keys contact whatever site a token advertises, only when you press the key. coin pictures are fetched once, through the app's own local cache, from DexScreener's image CDN or the token's own metadata host, which therefore sees your IP once per coin; the chart popup is served the cached copy, so an image host never sees a popup load.
--no-imagesturns the feature off entirely. - the analyst's prompt goes to Anthropic through your own login, under your own agreement and billing, only when you start a run.
- nothing goes to us. no analytics, no telemetry, no crash reports, no accounts, in the app or on this site. the legal page has the full statement.
- keys never leave a file you own. the RPC key is read in code, the URL is built in memory, every URL in an error, a verbose log or a recording passes a redactor, and a recording that still carries a key refuses to save.
the popup chart
the chart window is served by a server that binds 127.0.0.1 only, on a random port, with a single-use ticket per window, a one-time WebSocket token, strict Host and Origin checks, no CORS, a nonce CSP, one static file, and an event allow-list; the native shell receives the URL over stdin and pins every navigation to the exact loopback origin. a 50-probe attack suite runs against it in the test suite. the vendored chart library is byte-identical to its npm release and loads from the loopback server, never a CDN. details in the popup docs.
source, builds and provenance
A public GitHub repo, releases with build provenance, checksums and an SBOM, third-party scan results on the trust page. License decision pending; no date.
what the release pipeline will publish for every version, and what this page will show for each:
- a public git tag and commit the release was built from.
- the npm tarball with provenance: npm's trusted publishing records which public workflow built which commit.
- a github build-provenance attestation (sigstore / slsa) for every artifact, verifiable offline.
SHA256SUMSfor every artifact.- a cyclonedx sbom. dexterm has zero runtime dependencies; the one vendored library (Lightweight Charts, Apache-2.0) will be listed.
- reproduce the build: clone the tag, run the documented build from a clean checkout, compare checksums.
- third-party scans of every artifact, re-run on a schedule, written to
scan-results.jsonand rendered below with links to the public reports.
third-party scan results
pipeline: dexterm release pipeline (card 1301, not built yet) · workflow .github/workflows/release.yml · run: not yet: public run · re-scan: weekly (sunday 06:00 utc) and on every release
release: 0.0.1-sample · published not yet · not yet: release page
dexterm-0.0.1-sample.tgz npm-tarball · size not yet
- sha-256
0000000000000000000000000000000000000000000000000000000000000000- download
- not yet
- attestation
- not yet
- sbom
- not yet
virustotal pending scanned not yet
- engines
- 0 total · 0 malicious · 0 suspicious · 0 harmless · 0 undetected
- report
- not yet: public report
- note
- SAMPLE: no artifact has been uploaded to VirusTotal. An upload makes the file public to the VirusTotal community and needs Joey's explicit go (card 1301).
what a clean scan proves, and what it does not
it proves that, at the time shown, the named engines did not recognise the exact file with that sha-256 as known malware. with provenance and a matching checksum it also proves the file you hold is the one that was scanned and that a public workflow built it from a public commit.
it does not prove that the code is safe, correct or free of bugs; that a future version is clean; that the data it shows is right; or that any token it displays is a good idea. scanners look for known patterns, and a cli that opens websockets and reads a key file can trip heuristics and produce a false positive: when that happens we will leave the result visible here, link the engine's label, and explain it next to it instead of hiding it.
the only things that make software trustworthy are readable source, reproducible builds, and your own review. the scans are one more check, not a certificate.
verify your download
once releases exist, three independent checks, from weakest to strongest:
- checksum: the file is byte-identical to the one we published.
$ curl -fsSLO <release-url>/SHA256SUMS $ shasum -a 256 -c SHA256SUMS --ignore-missing - attestation: a public github workflow built this exact file from a public commit.
$ gh attestation verify dexterm-<version>.tgz --owner <github-org> - npm provenance: the package on npm carries a verified provenance statement pointing at the same workflow and commit.
$ npm view dexterm@<version> --json | grep -A3 '"provenance"' $ npm audit signatures
and the check that beats all three: read the source, run the tests, build it yourself.
this website
- static html, css and one small first-party script. no analytics, no cookies, no fonts, scripts or embeds from third parties. the script's only network request is for the same-origin search index, after you start typing.
- content security policy
default-src 'none'withscript-src 'self'andstyle-src 'self', sent as a header and repeated in a meta tag;frame-ancestors 'none',Referrer-Policy: no-referrer, no-sniff, no permissions. - every feature label comes from
features.json; the keyboard, CLI, MCP and host references are generated from the app source and checked for drift. the site cannot say "live" about a thing the file does not.
report a problem
security reports, a host missing from the table above, a label that overclaims, a flagged scan: a responsible-disclosure address and a SECURITY.md land with the public repo. a contact address goes here once Joey picks one (security reports and takedowns). we will acknowledge reports, we will not pay bounties we have not announced, and we will never dm you first.