deviant/Parameters/CoinSpectrum
walerikus cdb598daee docs(coinspectrum): design record for the CoinSpectrum aggregator
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 22:12:03 +02:00
..
README.md docs(coinspectrum): design record for the CoinSpectrum aggregator 2026-06-26 22:12:03 +02:00

CoinSpectrum — design record

This is a design record / pointer, not the code. The CoinSpectrum codebase lives in its own git repo at D:\Dev\coinspectrum (a sibling of Deviant, not inside it). That repo + its commit history are the source of truth; this file captures the thesis, architecture, and status so the design is recorded alongside Deviant's other Parameters records.

What it is

An opinionated crypto aggregator (a CoinGecko / CoinPaprika rival) with one editorial thesis:

Only pure cryptocurrencies count — an asset with its own base-layer blockchain secured by its own consensus mechanism. Everything else is segregated: stablecoins are fiat synthetics, wrapped assets are representations, tokens ride someone else's chain, and a "memecoin" is just a token. The headline view is the actual ranking of cryptocurrencies once that noise is stripped out — and the primary lens is consensus mechanism.

Why it's a separate repo (do not move into Deviant)

Split out deliberately on 2026-06-17 so that (a) Deviant's private IP never ships with the public-facing CoinSpectrum product, and (b) CoinSpectrum can be open-sourced / deployed on its own. Moving the code into Deviant would reverse that and re-introduce the leak risk, plus nest a git repo inside a git repo. Keep the standalone repo as the source of truth.

Relationship to Deviant: philosophically identical taxonomy (tokens = NBA; stablecoins = off-chain unenforced backing; PoW coins = direct value). Could become Deviant's "honest explorer" arm later, but stays standalone for now.

Classification logic

  • Three top-level categories, by where value comes from:
    • Cryptocurrencies — native asset of an independent L1 with its own consensus.
    • Tokens — ride a host chain, value from their own utility/speculation (no backing): sectors DEX/DeFi/Gaming/AI/Other + Memecoins (a token sub-type; an own-chain meme like DOGE stays a cryptocurrency, because the chain rule overrides the meme label).
    • Representations — all IOUs: a redeemable claim on an underlying that someone holds. Grouped by what's claimed: Stablecoins (fiat-backed reserves · debt-based CDP) · Asset-backed (crypto/wrapped · commodity/metals).
      • Custody follows the backing, not the token. Custodial = a party or protocol holds or encumbers the underlying — fiat issuers, commodity vaults, BTC custodians, LSTs (staking protocol holds the ETH), and all CDPs (collateral locked in the protocol). Non-custodial = only a pure 1:1 self-wrap held in immutable code you fully control (WETH/WBNB/WSOL/…).
      • A CDP is debt-based, not debt-backed; you self-custody the CDP token, but its collateral sits in the protocol's custody, so the asset is custodial.
    • Engine emits per-token family / sub / custody; curated sets CDP, COMMODITY, NON_CUSTODIAL (native-coin 1:1 wrappers) + provider sector tags drive it.
  • The engine (classify.mjs) matches a curated SYMBOL → consensus table (chains.mjs). A curated native L1 wins over the "non-empty platforms → token" heuristic — this fixed Zcash + ~14 native coins that also have wrapped deployments and were vanishing from the list.
  • Consensus families: PoW (by algorithm) · PoS · BFT/Tendermint · DAG · PoSpace · Hybrid · Other/Federated. ~122 cryptocurrencies at top-1000, fully curated (0 uncurated).

Data sources (all behind a DataProvider seam)

  • CoinGecko REST (primary): markets + /coins/list?include_platform (native-vs-token signal)
    • category membership (stablecoin/meme/wrapped). Demo-key pool via COINGECKO_KEYS (rotated)
    • 429 retry/backoff. Reliable to ~top-600 keyless; top-1000 needs a free demo key.
  • CoinPaprika (keyless fallback, --source=paprika): loses per-chain tokens + meme detection.
  • Network hashrate (PoW only): stitched from blockchair /{chain}/stats + WhatToMine in hashrate.mjs (minerstat went key-gated). Gaps with no free source: KAS, BSV, DGB, SC, Verge.
  • The deployed site reads a committed web/data.json snapshot; only the build calls the APIs.
  • Attribution (required by CoinGecko's demo-tier terms): the UI footer credits the active market-data source — Data provided by CoinGecko linked to coingecko.com, switching to CoinPaprika when that fallback is used; the hashrate column credits Blockchair & WhatToMine.

Architecture (files in D:\Dev\coinspectrum)

classify.mjs                 the opinionated engine (symbol-keyed)
chains.mjs                   curated consensus table + stablecoin/wrapped sets (editorial moat)
providers/provider.mjs       the DataProvider contract
providers/coingecko.mjs      CoinGecko impl (key pool, category cache, retry)
providers/coinpaprika.mjs    keyless fallback
cache.mjs                    per-source + last-good-category degraded-fetch protection
hashrate.mjs                 PoW network hashrate (blockchair + whattomine)
build-data.mjs               fetch + classify → web/data.json
web/index.html               static single-page UI (vanilla JS, zero deps)
web/data.json                committed snapshot (so the site deploys with no build step)
report.mjs                   CLI
netlify.toml, .github/workflows/pages.yml   deploy configs

Web UI (current state)

  • Cryptocurrencies tab — the actual ranking. Multi-select consensus-algorithm dropdown (all-checked by default, uncheck to exclude; the list re-numbers 1..N per selection). Sortable columns: Consensus (power-ordered — groups by algorithm, ordered by the group's top hashrate, SHA-256 first), Hashrate (PoW block first even without data, then consensus families bound by market cap), Price, Market cap. PoW network hashrate column.

  • Ledger-model filter (single-select, beside the algorithm dropdown; composes with it and re-numbers 1..N) — segments cryptocurrencies by what their ledger can carry, on one axis:

    • Single-Asset — the ledger tracks only its native coin (XMR, ZEC, LTC, DASH, …).
    • Overlay-Asset — tokens written into the chain's own blocks but not validated by its consensus; off-chain indexers decide validity (Ordinals/BRC-20 on BTC, KRC-20 on KAS, SLP-derived eTokens). Same ledger, off-consensus — deliberately not a sidechain/L2 (those are separate ledgers, off-axis). Currently BTC, DOGE, KAS, BSV, XEC, DGB.
    • Multi-Asset — consensus-/contract-level token support (ERC-20, BCH CashTokens, native asset ledgers ADA/XRP/ALGO/…). Precedence native > overlay > single, so BCH is Multi (CashTokens) despite its legacy SLP overlay.

    Curated in chains.mjs (MULTI_ASSET + OVERLAY sets), emitted as a ledger field by classify.mjs → build-data.mjs. At top-1000: 19 single / 6 overlay / 97 multi (most obscure L1s are EVM/Cosmos token hosts, so Multi-Asset dominates once everything is curated).

  • Tokens (NBA) tab — non-backed assets (utility + meme). Multi-select category checkbox dropdown (DEX · DeFi · Gaming · AI · Other · Memecoins) + chain + search.

  • Representations tab — all IOUs. Multi-select category dropdown grouped Stablecoins (Fiat-backed · CDP synthetic) vs Asset-backed IOU (Crypto-backed · Commodity-backed) + a custody dropdown + a Currency dropdown (USD/EUR/GBP/JPY/CHF/BRL… — narrows stablecoins by peg currency; shown in the Type cell) + chain + search, and a Custody column. Custody follows the backing, not the token: custodial unless the asset is a pure 1:1 self-wrap in immutable code you fully control (WETH) — so all CDPs and LSTs are custodial (collateral/stake held by the protocol).

  • Controls order (Tokens & Representations): chain checkbox dropdown first (multi-select, scrollable; the count/mcap sort stays a single-select since the two options are mutually exclusive), then category, then custody + currency (reps), then the sort. Search is a single right-aligned input in the tabs row (persistent across tabs). Tokens & Representations tables carry a market-cap rank # column (the cryptocurrency tab has its own selection-relative rank). Top-level tabs: Cryptocurrencies · Tokens · Representations — the three-way value-origin split. Every tab's results line shows the total market cap of the current selection.

  • The CoinGecko market rank is intentionally not shown in the list — reserved for a future asset detail page (where the mixed-rank-vs-pure-rank comparison will live).

Build / run / deploy

npm run build     # node build-data.mjs 600 → web/data.json
npm run web       # serve web/ at http://localhost:5183

Deploy (static, snapshot committed → no host build step):

npx netlify-cli deploy --dir=web --prod    # Netlify (reads netlify.toml)
npx wrangler pages deploy web              # Cloudflare Pages
npx vercel deploy web --prod               # Vercel
# GitHub Pages: push to a repo → the included pages.yml workflow publishes web/

Status / open items

Needs the user (account-gated — can't be done from the assistant):

  • Run the deploy (pick a host, log in once).
  • A miner key (minerstat / CryptoCompare) → fill the hashrate gaps.

Done:

  • ✅ CoinGecko demo key — provided; stored in gitignored .env (read by coingecko.mjs, auto-loaded via node --env-file-if-exists=.env). The committed snapshot is now a clean top-1000 build (122 cryptocurrencies). CoinGecko omits staked/wrapped derivatives (stETH, WBTC) from its market-cap ranking to avoid double-counting; coingecko.mjs merges them back from the category endpoints, so the wrapped list is complete (~496, incl. WBTC/stETH) while those representations stay out of the cryptocurrency ranking.

Buildable next without the user:

  • Asset detail pages (home of the market-rank-vs-pure-rank diff + per-coin consensus / hashrate / supply).
  • "Popular options" quick-jump row (Stablecoins · Wrapped · Memecoins · Utility).
  • Phase-2 CcxtProvider (direct exchange feeds).

Changelog (commit history, newest first)

0e2d5ed 3 top-level tabs: Cryptocurrencies, Tokens, Representations
eafa3f9 token taxonomy engine: family/group/sub/custody (Representations = IOU + CDP)
5a0859d add CDP and Commodity curated sets (prep for IOU subcategory restructure)
2fe77b2 estimate BSV network hashrate from WhatsOnChain difficulty
be0e043 include wrapped/staked derivatives (WBTC, stETH) in the wrapped list
73806db curate the 38 uncurated L1s; drop 3 non-L1 tokens (TCY/GCOIN/XEF) from the ranking
1bb2712 ledger filter is a multi-select checkbox dropdown; All rows show totals
1f745e6 attribute the data source in the footer (CoinGecko demo-tier requirement)
9405c7a clean top-1000 build via demo key (125 cryptocurrencies)
a4fdfe7 overlay-asset ledgers — third ledger class for off-consensus metaprotocol tokens
ebb40da single-asset / multi-asset ledger filter on the cryptocurrency view
3604c50 "All chains" option shows the aggregate total (count or total token market cap)
f6c8c04 move the token-sort dropdown after the category dropdown
66adac3 rename chain-sort options to "By token count" / "By token market cap"
24c95c0 chain-sort control is now a dropdown matching the other selects
ee5607f move chain-sort toggle before the chain dropdown + match dropdown styling
a221c2f tokens chain dropdown sorted by token count + toggle for market-cap order
cf0ea94 hashrate sort — PoW block first, then consensus families bound by market cap
275cca0 capitalize chain names (Ethereum, Binance Smart Chain) via a display-name map
b56d835 consensus sort is power-ordered (hashrate) by algorithm group
9ae0ad1 tokens — chain + category filters apply simultaneously
8ea8a76 sortable Consensus column + Tokens dropdowns (Token Category / By chain)
1137065 deploy prep — netlify.toml + GitHub Pages workflow + README deploy section
080a8f2 token sub-categories by type — fold Stablecoins/Memecoins under Tokens (NBA)
135da01 curation sweep — label 33 native L1s that were "needs curation"
ef5101b clickable column sort (rank by hashrate/price/mcap) + curate Verge (XVG)
9f8883b network hashrate for PoW cryptocurrencies
e5b18a0 rank re-numbers for any selection — contiguous 1..N within the selected algorithm types
2f4ad78 fix: native L1s with wrapped deployments mis-classified as tokens (Zcash + 14 others)
f0183ac algorithm filter — all-checked default (exclude to deselect) + single-algo re-ranking
64d48b4 per-asset prices + deeper build (top-600) so Siacoin and the tail appear
a47d63d tokens tab → Host chains + Tokens sub-tabs with per-chain filter
89005c5 commit data.json snapshot so web/ deploys as static files (no build step)
01b120f flat ranking + multi-select algorithm filter; drop secondary rank from list
fd19760 actual cryptocurrency ranking — pure rank primary, CoinGecko rank secondary
9d385a4 static web UI — top-500 classified view (consensus groups + tabs)
2d97b4a depth control (--top) + curate DigiByte (multi-algo PoW)
8c23574 reliability + multi-source (demo-key pool, CoinPaprika fallback, cache protection)
0d92a29 rename project Spectrum → CoinSpectrum
0d3aba8 init: opinionated crypto aggregator (pure cryptocurrencies by consensus)