Changelog / Release Notes

CHANGELOG — Qanum-specific changes

Changes made on top of the upstream janoside/btc-rpc-explorer v3.5.1 to align the explorer with the Qanum L1. See CHANGELOG.md for the upstream history and docs/QANUM.md for architecture/alignment notes.

[Unreleased]

Public deployment clean-up

  • New options, all true by default: QANEXP_UI_HIDE_QUOTES, QANEXP_UI_HIDE_HOLIDAYS, QANEXP_UI_HIDE_FUN (the curated Bitcoin quotes, "holidays" and fun facts, until they have Qanum content) and QANEXP_UI_HIDE_PROJECT_LINKS (links to the source repository while it is private). Hidden pages leave the menus and answer 404.
  • With NODE_ENV=production the "Page Errors" box shows only the error id and message; raw errors and stack traces stay in the server log.
  • The "Admin Dashboard" menu item is gone; the settings reset moved from /admin/resetUserSettings to /user-settings/reset.
  • /changelog shows this file instead of the upstream history.
  • Fee rates read "jomas/byte" and sizes "B" (Qanum has no SegWit).
  • /utxo-set, the block-range presets and /block-stats no longer use Bitcoin amounts, halvings or SegWit.
  • /api/docs: no "BitcoinExplorer" wording; examples come from block 1 of the live chain; xpub, price (when rates are off), quotes and holidays calls are not listed.
  • /favicon.ico serves the network's icon (raw API responses showed the Bitcoin logo).
  • The node's filesystem paths (datadir, mempool file, snapshot) are hidden.
  • Unknown or malformed blocks answer 404 instead of 500.
  • API fixes: /api/blockchain/coins, /api/blockchain/next-halving (Qanum subsidy schedule), /api/tx/volume/24h, the new /api/mempool/count, /api/mining/diff-adj-estimate (404: not applicable with ASERT), and empty-template fee rates.
  • Next-block total fees and the mining summary convert jomas to QAN (the summary showed 116,000,000,000 QAN of subsidy for 145 blocks).
  • /next-block no longer fails (500) when visited again within 5 seconds.
  • Safe with QANEXP_SLOW_DEVICE_MODE=false: the difficulty history is skipped on chains that adjust every block (it never finished on Qanum), and the 24-hour volume reads a day of blocks for this chain (1152 on Qanum, not Bitcoin's 144) plus 25%.

[v0.1.9] — 2026-09-11

Feature: /next-halving adapted to Qanum (real subsidy schedule)

/next-halving previously showed Qanum a static alert ("This coin does not use Bitcoin-style subsidy halvings … There is no halving to predict") — vague wording with a Bitcoin reference. The page now shows Qanum's real subsidy schedule, computed from the coin's blockRewardFunction (a mirror of the L1 subsidy_at_height, qanum/src/constants.rs + src/economics.rs) and the live chain tip:

  • Summary: current subsidy era (e.g. "0 of 36 decay steps"), current block subsidy (8 QAN), next subsidy step (block 420,480).
  • Timeline/progress: blocks remaining until the next ×0.9 decay, estimated date at the 75s target block rate (the rate ASERT targets), era progress bar.
  • Upcoming subsidy schedule table: the next 12 epochs — start block, exact per-block subsidy, real % change, blocks remaining, estimated date — including the epoch (36) where the subsidy reaches the permanent 0.2 QAN tail.
  • Supply reference: cumulative subsidy until the tail begins (~32.7M QAN), explicitly a reference figure and not a hard cap (the tail is permanent).
  • The route no longer fetches the era-start header for Qanum (difficultyAdjustmentBlockCount=0 would produce a NaN height); blocksPerYear / initialSubsidyJomas / tailSubsidyJomas are now exported from app/coins/qan.js (documented L1 constants).
  • The BTC branch is byte-identical; any coin without a schedule gets a generic explanatory alert (no Bitcoin reference).

Verified in sandbox (regtest): page renders the era 0 schedule (8 QAN, next step block 420,480, correct progress and dates), the 12-row table with exact subsidies and ~-10% changes, tail note at era 36 (block 15,137,280); jsdom client E2E clean; BTC branch unchanged; 27+ route sweep clean; npm test passes.

Bugfix: /tx-stats took ~3.1x longer to load and 500'd on fresh nodes

/tx-stats ("no carga" report): the page computed 1094 data points (250 all-time + 144 day + 200 week + 250 month + 250 year). Each point costs 2 RPC calls (getblockhash + getchaintxstats), so one cold page load fired ~2188 RPC calls serialized through the explorer's RPC concurrency (10): measured 20.7 s on a 6k-block regtest chain and several minutes on slow nodes — the user gives up before it renders. Additionally, getTxStats() returns null for freshly started / still-syncing nodes, and the template dereferenced every window without a null-check (each ... in txStatsDay.txCounts, new Decimal(txStatsDay.avgTimespan)) → Pug render crash → HTTP 500 on the whole page.

  • routes/baseRouter.js (/tx-stats): data points reduced to 100 / 48 / 56 / 60 / 90 (all / day / week / month / year) = 354 points = ~708 RPC calls per cold load — 3.1x less server work. Chart shape is preserved: qanumd serves getchaintxstats in O(1) per window (running counters), so a point count does not change the curve — only the sample density (measured in sandbox: identical ~5-30 ms cost for 10-block and 1680-block windows).
  • views/tx-stats.pug: all txStats* dereferences are now null-safe (x ? x.field : [] ternaries — no re-indent, zero behavior change when data is present). When any window is null a warning banner is shown: "Some transaction statistics are unavailable (the node may still be catching up)" instead of a 500.

Repeat loads are still instant (60-min miscCache, unchanged): measured ~35 ms warm vs ~20.7 s cold before the fix (now ~6.7 s cold).

Verified in sandbox (regtest, 6158 blocks): cold /tx-stats 20.75 s → 6.66 s; warm 35 ms; jsdom client E2E with the real page JS renders 10/10 charts with 0 JS errors; standalone render with all five windows null renders cleanly (banner + 10 empty canvases, no crash); 27-route sweep clean; difficulty-history E2E still green; npm test passes.

Bugfix: Difficulty History page crashed (infinite loop) for Qanum

views/difficulty-history.pug: the height loop did height += coinConfig.difficultyAdjustmentBlockCount, which is 0 for Qanum (ASERT adjusts difficulty every block; there is no epoch count) → browser infinite loop: the page showed "Loading data" forever and the tab froze/died within seconds.

  • The loop now steps diffHistStep = difficultyAdjustmentBlockCount > 0 ? difficultyAdjustmentBlockCount : blocksPerDay — BTC keeps its epoch boundaries (201600); Qanum samples one difficulty value per day (1152 blocks), which keeps the page light on mainnet too.
  • Year-range buttons: the yearIndex divisor was hardcoded 26 (BTC epochs/yr); now samplesPerYear = 26 for BTC (unchanged) and 365 for Qanum (one sample/day), so "1 yr" shows the last 365 daily samples. The button labels/values themselves are unchanged.
  • The "Raw Data" table's Start Block used BTC-hardcoded 2016 math; it now uses the actual sampled block height of each row (also fixes the off-by-100 start blocks on the BTC page).
  • Note box and table header adapted for Qanum: "adjusts automatically with every block (ASERT, continuous adjustment)" + "samples one value every 1,152 blocks (~1 day)" instead of "every 0 blocks"; header "Epoch" → "Sample" for no-epoch coins.

Verified E2E (jsdom, real page JS + real XHR against the regtest stack): page completes, internal-api/difficulty-by-height/0,1152 returns {0,1152}, table fills with 2 rows (blocks 0 and 1,152, correct difficulty/date), no infinite loop; all 63 Pug views compile; 27-route sweep clean; npm test passes.

Bugfixes: iframe layout compile error, halving countdown 500, xyzpub error spam (post v0.1.8)

  • views/layout-iframe.pug: the two web-app meta tags added in v0.1.8 (apple-mobile-web-app-title, application-name) were indented under the previous <link> line, making Pug treat them as nested content of a self-closing element. Any request served by that layout (the /snippet/quote/random footer quote iframe, i.e. the bottom of every page) crashed with PUG:SELF_CLOSING_CONTENT: link is a self closing element: <link/> but contains nested content (layout-iframe.pug:38). Fixed the indentation; the footer iframe now renders.
  • views/snippets/index-halving-countdown.pug: crashed with TypeError: Cannot read properties of null (reading 'nextHalvingIndex') (HTTP 500) because utils.nextHalvingEstimates() intentionally returns null for coins without a halving schedule (Qanum's subsidy decays continuously). The snippet now guards for null and renders a short note instead; the progress bar only renders when a next halving actually exists (also protects terminal-halving coins).
  • routes/baseRouter.js: the hidden /xyzpub/:xpub route is now 404 for Qanum (and the search box no longer redirects xpub/tpub-style queries there). BIP32 xpub derivation is Bitcoin-secp256k1-specific; Qanum uses post-quantum signatures and has no xpub concept, and visiting the page with a Bitcoin xpub on a Qanum instance spammed the logs with one Invalid Qanum address electrum error per derived address (~30 per visit). Same treatment as the Whitepaper Extractor in v0.1.8.

Verified E2E on the regtest stack (qanumd v0.36.8 + qanum-electrs): all 63 Pug views compile cleanly; home, blocks, block, tx, address, mempool-summary, mempool-transactions, node-details, peers, next-block, predicted-blocks, difficulty-history, utxo-set, next-halving, tx-stats, rpc-browser, user-settings, quotes, holidays, fun, block-stats, block-analysis, changelog, all /snippet/* routes and mining-summary return 200 with zero error strings in the HTML; the server log is clean (no more electrum error spam). npm test passes.

[v0.1.8] — 2026-09-09

Release of the changes accumulated locally since v0.1.7 (commits dd3e98f, 0341caf, 79b3ea5, f8ea1ce, fff5b82, 6cef217):

Defaults & onboarding: no Bitcoin wording in Qanum deployments

Audit of every default value that runs without configuration (env vars, config.js, CLI defaults, coin defaults, docs) plus the always-visible UI strings, so that a default node bin/cli.js -C QAN run shows no Bitcoin branding:

  • views/layout.pug / views/layout-iframe.pug: the web-app meta tags (apple-mobile-web-app-title, application-name) were hardcoded to "BTC Explorer"; they now use coinConfig.name ("Qanum Explorer").
  • views/layout.pug: the footer quote iframe title was "A Bitcoin Quote of the Day"; it now reads "A Qanum Quote of the Day" for Qanum (the quote content itself remains upstream's curated dataset — P2 content branding is out of scope for this change).
  • Whitepaper Extractor (tool #13) is Bitcoin-specific (it decodes the whitepaper from data embedded in the BTC chain). It is now hidden for Qanum (qanumHidden marked in config.js, filtered in the navbar dropdown and the home Tools grid; /bitcoin-whitepaper and /bitcoin.pdf return 404 on Qanum).
  • views/quotes.pug, views/holidays.pug, views/fun.pug: the "About Bitcoin Quotes/Holidays/Fun..." notes now use coinConfig.name ("About Qanum Quotes..." etc.).
  • views/block-analysis.pug: the "BTC Days Destroyed" column header and its "Bitcoin Days" tooltip now render "QAN Days Destroyed" / "Qanum Days" for Qanum.
  • views/extended-public-key.pug: "represents a Bitcoin address" → "represents a Qanum address" for Qanum.
  • views/next-halving.pug: the "May humanity enjoy the Bitcoin Renaissance" line is gated to the BTC coin (Qanum has no halving tail state that reaches it).
  • views/mempool-summary.pug: the satsPerBitcoin client variable was renamed to smallestUnitsPerCoin.
  • app/config.js: the cookie-secret derivation input string btc-rpc-explorer-cookie-secret was renamed to qanum-rpc-explorer-cookie-secret and the hard-fallback (the Bitcoin genesis block hash) was replaced with a neutral string; the displayDefaults.displayCurrency fallback "btc" became "qan".
  • docs/api.js: the public API docs now say "jomas/vB" and "price of 1 QAN" instead of "sats/vB" and "price of 1 BTC".

Verified E2E against qanumd v0.36.8 regtest with the full default stack: home, blocks, tx-stats, mempool-summary, mempool-transactions, node-details, peers, next-block, predicted-blocks, mining-summary, difficulty-history, utxo-set, next-halving, rpc-browser, quotes, fun, user-settings and the xpub page all render with zero occurrences of "Bitcoin Core", "bitcoind", "BTC Explorer" or "Made for Bitcoiners" (the only remaining "bitcoin" matches are inside the curated quotes / holidays datasets and a Twitter handle); the navbar and home Tools grid no longer list the Whitepaper Extractor, /bitcoin-whitepaper 404s and the page meta tags read "Qanum Explorer". npm test passes.

Note (no change, reported for awareness): QANEXP_ADDRESS_API still has no default — upstream's default was "bitcoind"; leaving it unset means address-detail lookups find no API (the fork deliberately requires an explicit --address-api/env value and validates it at startup).

Bugfix: Mempool Summary stuck on "Loading..." with an empty mempool + /undefined 404 spam

Two defects found while testing the live preview against a regtest node:

  • app/api/coreApi.js (buildMempoolSummary): with an empty mempool the "merge top fee-rate buckets" code ran with topIndex = -1 and threw TypeError: Cannot set properties of undefined (setting 'buckets') (coreApi.js:1851). The build never completed, the status endpoint kept returning {} and the page polled forever on "Loading...". The bucket-merge/labels logic is now gated on summary.count > 0, and averageFee / averageFeePerByte default to 0 instead of 0/0 = NaN.
  • views/mempool-summary.pug (updateStatus()): a finished-but-empty build ({"count":0,"done":0}) was treated as "not started" (the !res.count guard) and empty summaries were never rendered (the summaryResult && summaryResult.count guard), so the polling interval never stopped. It now only treats a missing count key as "not started", renders the empty state (tables/charts hidden, values "-") and stops polling; the progress bar shows 100% instead of NaN%.
  • routes/baseRouter.js (/changeSetting, /session-data) and routes/adminRouter.js redirected to req.headers.referer unconditionally. When the browser sends no Referer (e.g. the app being embedded in a sandboxed preview iframe) Express answered with Location: undefined, and the browser then requested /undefined (harmless but polluting the logs with 404s). The redirects now fall back to "./".

Verified E2E against qanumd v0.36.8 regtest with an empty mempool (previously the crash reproduced every time): the backend returns a zeroed summary (250 fee-rate buckets) and the page completes immediately (build → status → summary → empty state, polling stops); with the node reachable, /changeSetting without a Referer redirects to / instead of /undefined; npm test passes.

UI: remove Bitcoin wording from Qanum-facing texts

Reported by a live deployment: when the RPC connection failed, the browser shown a page referencing "Bitcoin Core". All user-visible strings now use the coin-conditional wording (Qanum → "qanumd", BTC → upstream text):

  • views/error.pug: the "No RPC Connection" page now says "your qanumd node" / "host & port for qanumd" (was "Bitcoin Core").
  • views/index.pug: the "Unable to get basic blockchain data" alert now says "qanumd" (was "bitcoind"); the welcome banner drops the "Made for Bitcoiners by Bitcoiners" slogan for Qanum and hides the upstream Donate/@BitcoinExplorer buttons; the Taproot activation alerts are gated to the BTC coin.
  • views/layout.pug (footer): the upstream donate / @BitcoinExplorer links are gated to the BTC coin (Qanum shows only the project link).
  • views/block-stats.pug / views/mining-summary.pug: tool descriptions say "qanumd" instead of "Bitcoin Core".
  • views/extended-public-key.pug: privacy notice says "your funds" instead of "your bitcoin".

Verified E2E (qanumd v0.36.8 regtest): home / block-stats / mining-summary render with 0 occurrences of "bitcoind", "Bitcoin Core", "Bitcoiners" or the upstream donate/twitter links; booting the explorer with the node unreachable renders the "No RPC Connection" page reading "your qanumd node"; npm test passes.

UI: fee-rate unit labels fixed for Qanum (jomas/vB)

Found by a live deployment (reported by the user: the home page showed "Smart Fees (sat/vB)" while running against qanumd). Every view now uses the same coin-conditional unit label already used by /tx, /mempool-summary and the shared tx mixins, so the Qanum branch shows jomas/vB and the upstream BTC branch keeps sat/vB:

  • views/includes/index-network-summary.pug: "Smart Fees" (home) + the disabled "Next Block (est.)" block.
  • views/snippets/index-next-block.pug: next-block snippet fee-rate label (loaded by the home page).
  • views/includes/blocks-list.pug: "Fee Rates" / "Avg Fee" tooltips.
  • views/block.pug: "Rate Percentiles" + "Min / Max Rates".
  • views/block-analysis.pug: top-fee-rate table header.
  • views/next-block.pug: "Fee Rates" summary item + table header.
  • views/predicted-blocks.pug, views/projected-blocks-old.pug: table headers/tooltips.

Note: Pug does not interpolate #{...} inside attribute values/backtick strings (known lesson from this project) — the tooltips use JS string concatenation in the attribute expression instead.

Verified end-to-end against qanumd v0.36.8 regtest + qanum-electrs: home renders "Smart Fees" with jomas/vB (0 occurrences of sat/vB), the next-block snippet, /block, /next-block and /mempool-summary all render jomas/vB with no leftover sat/vB or literal #{...} from these labels; /tx-stats, /block-stats, /blocks HTTP 200; npm test passes.

Mining Summary: exempt internal API from rate limiting (429 fix)

Reported by a live deployment: Tools → Mining Summary logged Rate-limiting request: req={"method":"GET","url":"/internal-api/mining-summary-status?statusId=..."} repeatedly and the page's progress polls failed.

Cause: the global rate limiter (200 req / 15 min per IP) counted the app's own AJAX polls. The mining-summary page polls /internal-api/mining-summary-status every 125 ms (≈8 req/s) until the server-side build finishes, so the limit was exhausted in ~25 s — a problem inherited from upstream (v3.5.1 has the same limiter and the same polling; it also does not exempt /internal-api/), aggravated on Qanum because the build walks the chain via RPC and takes longer.

Fix (app.js): the limiter's skip function now also exempts req.originalUrl containing /internal-api/, following the existing exemptions for /snippet/ and /api/. The limiter still applies to all regular pages (and /api/ remains exempt as before).

Verified E2E with QANEXP_RATE_LIMIT_WINDOW_MAX_REQUESTS=10 (artificial limit): 30 consecutive requests to /internal-api/mining-summary-status → all 200, 0×429; the build endpoint /internal-api/build-mining-summary/... + its status polling complete ({"count":436,"done":436}) with no 429; meanwhile 12 requests to /blocks → 10×200 then 429, proving regular pages are still rate-limited. npm test passes.

[v0.1.7] — 2026-09-08

P0: mempool/address/halving pages, jomas/QAN units, version parsing

Verified end-to-end against qanumd v0.36.8 regtest + qanum-electrs v0.1.6 (/tx, /address, /api/address, /api/tx, /next-halving, /mempool-summary, /block, home page — all HTTP 200; npm test passes).

  • Node version parsing (app.js): qanumd reports /Qanum:0.36.8/; the explorer now parses it instead of falling back to 1000.1000.0 (which silenced the RPC version gates and logged a scary error at every boot).
  • Mempool detection (routes/baseRouter.js, routes/apiRouter.js): Bitcoin Core omits confirmations for mempool txs; qanumd sets it to 0. The mempool branch now also matches confirmations == 0, so unconfirmed transactions get their mempool details (First Seen, Fee Rate, Total Fee, ancestors/descendants) instead of rendering a broken/500 page.
  • Resilient mempool details (app/api/rpcApi.js): getMempoolTxDetails never rejects; entry is null on failure and ancestors/descendants are always arrays. qanumd mempool entries are flat (fee, fee_rate, depends, time, ... with no Core-style fees object); they are normalized to fees.{base,modified,ancestor,descendant} in the default unit (QAN) plus ancestorsize/ancestorcount defaults, so downstream fee math is unchanged.
  • Prevout resolution (app/api/rpcApi.js): qanumd vouts omit the index field n (Bitcoin Core includes it); the explorer keys prevouts by ${txid}:${n}, so every input silently lost its value and fees showed as ?. The vout index is now restored from the array position. The same normalization covers coinbase inputs (all-zero txid + vout: 0xFFFFFFFF → Bitcoin-style coinbase marker, skipping the prevout lookup).
  • Units: jomas vs QAN (display layer). RPC values stay in jomas (1 QAN = 1e8 jomas); views convert to QAN for display:
    • views/includes/tx-mixins.pug: input/output values, truncated totals and totalIOValues (jomas → QAN) for Qanum.
    • views/transaction.pug: Total Fee / Fee Rate (fee rate shown in jomas/vB), coinbase "Fees Collected" and "Value Destroyed".
    • views/includes/shared-mixins.pug: tx-list fees (flat mempool fee converted to QAN; mempoolDetailsByTxid[txid].entry null-safe) and jomas/vB label.
    • views/includes/index-network-summary.pug: estimated supply converted jomas → QAN (was displaying jomas as QAN).
    • routes/apiRouter.js: /api/tx fee amounts in the coin's default unit (QAN) with unit: "QAN"; coinbase reports fee: 0; vins without a scriptSig get a placeholder so address/type annotations don't throw.
  • Mempool summary (views/mempool-summary.pug): fee-rate unit labels are now dynamic (jomas/vB for Qanum, sat/vB for BTC) everywhere, including the custom-fee input placeholder and the Chart.js axes.
  • Address page (views/address.pug): new "Script Type" row (script_type / template_id), "Script Pub Key" row guarded when validateaddress doesn't return scriptPubKey (synthesized from script_type/template_id, or "" fallback) — the page no longer 500s.
  • Next halving (views/next-halving.pug): Qanum has no halvings (the subsidy decays continuously: 8 QAN initially, ×0.9 per year over 420,480 blocks, permanent 0.2 QAN tail); the page now explains this instead of erroring on a null nextHalvingEstimates result. Bitcoin behavior unchanged.
  • Error-path fix (routes/baseRouter.js): the /tx error handler referenced the txid variable out of scope (a secondary crash that masked the real error); it now uses req.params.transactionId.

P1: use the L1's native Core-shaped RPC (drop obsolete Qanum fallbacks)

Verified end-to-end against qanumd v0.36.8 regtest + qanum-electrs v0.1.6 (/tx-stats day/week/month/year/all windows, /tx mempool, /address, /block-stats, home — all HTTP 200; npm test passes).

  • /tx-stats: qanumd (v0.36.8+) implements getchaintxstats with the Core result shape (window_tx_count, window_interval, txrate, ...). getTxStats now uses the native path for Qanum instead of counting transactions block by block; removed qanumGetTxStats, its module-level block cache and the dedicated rpcApi.getBlockTxStats helper (~120 lines of per-block RPC work). The first load is no longer data-heavy for the explorer.
  • txindex detection: qanumd implements getindexinfo, so the standard boot check is used (txindex check: available!); removed the Qanum-specific qanumTxIndexAvailable (getblockcount → getblock → getrawtransaction lookup) and its branch in app.js.
  • getNetTotals / getNetworkHashrate: qanumd implements getnettotals and getnetworkhashps; the fallbacks stay only as defensive guards, and the "qanumd does not implement ..." comments were updated.
  • Mempool fee rate: /tx now displays the node-computed mempoolentry.fee_rate (jomas/vB) directly when present, falling back to fee/vsize otherwise (identical values, no double rounding).
  • Docs: docs/QANUM.md, README.md and TESTSUITE.md updated to the v0.36.8 reality (native getchaintxstats/getindexinfo/getnetworkhashps, validateaddress-based getAddress, feerate_percentiles[2] as median in block-stats).

RPC concurrency (previously unreleased)

  • qanumd v0.30.3 makes RPC concurrency configurable (-rpcthreads / -rpcworkqueue, defaults 16/64; HTTP 503 when the queue is full).
  • app/config.js: rpcConcurrency back to the plain (QANEXP_RPC_CONCURRENCY || (slowDeviceMode ? 3 : 10)) — removed the cap that limited Qanum to 12. QANEXP_RPC_CONCURRENCY can now be set to match the node's -rpcworkqueue (e.g. 16–24).
  • Docs updated (README, docs/QANUM.md, TESTSUITE.md).

Packaging & install paths: CLI Qanum flags, npm/Docker publication readiness

Verified end-to-end: regtest boot driven by CLI flags only (-C QAN, --qanumd-host, --qanumd-port, --address-api electrum) connects to qanumd v0.36.8 and serves 200s; npm test passes.

  • CLI (bin/cli.js): the node-connection flags are now Qanum-named and actually wired to the config loaders — --bitcoind-uri set QANEXP_BITCOIND_URI, which nothing reads, so CLI node config was broken; new flags -b/--qanumd-uri, -H/--qanumd-host, -P/--qanumd-port, -c/--qanumd-cookie, -u/--qanumd-user, -w/--qanumd-pass map to QANEXP_QANUMD_* (read by app/credentials.js). The upstream --bitcoind-* spellings are still accepted as compatibility aliases (Qanum names win). Usage text/help updated (Qanum defaults, regtest examples).
  • Qanum defaults (app/credentials.js, app/config.js): default RPC port is now 8338 (Qanum mainnet; L1: 8338/18338/28338 verified in qanum_cli/cli.rs), default cookie ~/.qanum/mainnet/.cookie (qanumd: datadir/.cookie, datadir ~/.qanum/<network>), and QANEXP_COIN defaults to QAN (was BTC).
  • Config paths (app.js): env files are now ~/.config/qanum-rpc-explorer.env, /etc/qanum-rpc-explorer/.env and ./.env (previously named after the upstream project).
  • Package metadata (package.json, npm-shrinkwrap.json): name qanum-rpc-explorer (npm name verified free), explicit bin (qanum-rpc-explorer command), preferGlobal, engines >=16, prepublishOnly: npm test, Qanum repository/keywords.
  • Docker: image/compose names qanum/qanum-rpc-explorer:latest, container qanum-rpc-explorer, builder uses npm ci --omit=dev, runtime gets HEALTHCHECK (3002) and NODE_ENV=production; new .dockerignore (node_modules, .git, logs, .env private files).
  • Docs: README now documents the fully operational install paths (npm global, source, Docker published image + compose), configuration (env files, QANEXP_* table, CLI Qanum flags), Qanum RPC port/cookie defaults; .env-sample updated to Qanum values (8338, ~/.qanum/..., QANEXP_COIN=QAN). New docs/PUBLISHING.md runbook + GitHub Actions publish.yml (npm + Docker Hub on v* tags).

Note: the pre-publication work above (P0, P1, RPC concurrency and packaging changes) is released as a single v0.1.7 — the first public release after v0.1.6.

[v0.1.6] — 2026-08-21

Qanum branding (logo, version) + env-var rename + L1 cap

  • Env-var rename: BTCEXP_ → QANEXP_, and BTCEXP_BITCOIND_* → QANEXP_QANUMD_* across code + docs. app/credentials.js reads QANEXP_QANUMD_HOST/PORT/USER/PASS/COOKIE/URI.
  • Branding: replaced the upstream Bitcoin logo/icons with the official Qanum logo; version in package.json/npm-shrinkwrap.json → 0.1.6 (footer "version:"). Added the Qanum logo inside a per-network globe (mainnet black, testnet green, regtest grey) for header, coin-icon and favicons.
  • L1 RPC cap (interim, superseded in Unreleased): qanumd v0.30.2 rejected RPC beyond 16 concurrent workers, so config.js temporarily capped rpcConcurrency to 12 for Qanum. (Removed once the L1 became configurable in v0.30.3 — see Unreleased.)

[v0.1.5] — 2026-08-20

Docs aligned with Qanum (qanum.org)

  • docs/Server-Setup.md, docs/Server-Setup-Docker.md: rewritten for qanum/qanum-rpc-explorer (was janoside/btc-rpc-explorer on bitcoinexplorer.org).
  • docs/btc-explorer.com.conf, docs/explorer.btc21.org.conf: server_name changed to explorer.qanum.org (official domain subdomain).
  • Added docs/qanum-explorer.conf as the canonical nginx template.
  • docs/api.js: API descriptions made coin-agnostic (supply / market cap of the coin, quotes / holidays for the coin) instead of Bitcoin.
  • Kept: upstream MIT attribution and technical Bitcoin comparisons in docs/QANUM.md; QANEXP_QANUMD_* env var names (real config).

[v0.1.4] — 2026-08-20

Footer Links restore + respect L1 RPC concurrency

  • Restored the github/donate/twitter icons in the footer Links section; the github icon is now unconditional and points at the Qanum repo.
  • Documented that net_v2 is enabled at the node with -listen=1.
  • L1 protection: qanumd rejects RPC connections beyond its 16 concurrent workers. config.js now caps rpcConcurrency to 12 for Qanum so QANEXP_RPC_CONCURRENCY can never trip it.

[v0.1.3] — 2026-08-20

/next-block and /tx-stats work for Qanum

  • rpcApi.getBlockTemplate: for Qanum, build the next-block candidate from the node mempool (getrawmempool verbose) — transactions[{txid,fee,weight, fee_rate,depends}], height, coinbasevalue; depends txids mapped to 1-based indexes. (getblocktemplate needs net_v2 and its native shape differs.)
  • getTxStats: for Qanum, qanumGetTxStats counts tx per block with a lightweight getblock (by height, no coinbase resolution via new rpcApi.getBlockTxStats), shared cache, blockStart>=0 clamp, batched parallel fetch.
  • /tx-stats windows use the coin blocksPerDay (QAN = 1152) instead of Bitcoin's 144/day.
  • coins/qan.js: added blocksPerDay = 1152.

[v0.1.2] — 2026-08-20

Rebrand to the Qanum project URL

  • New QANEXP_PROJECT_URL / QANEXP_PROJECT_NAME config (default https://github.com/qanum/qanum-rpc-explorer).
  • GitHub metadata (stars/forks), footer project/commit/fork links, "View source", canonical/OG/twitter meta and page titles now point at the Qanum repo / use the coin name.
  • Later restored (by operator request) the Bitcoin-specific tools and messages (Whitepaper, Quotes, Holidays, "Made for Bitcoiners", "Bitcoin Core") so they can be aligned with Qanum later.

[v0.1.1] — 2026-08-20

/address + QAN display

  • /address/:addr and /api/address/:addr — balances, tx history and per-tx in/out, wired to qanum-electrs over the Electrum protocol with scripthash = address (QANEXP_ADDRESS_API=electrum + QANEXP_ELECTRUM_SERVERS).
  • Qanum display currency (QAN/jomas) as the default (config.js, layout.pug, global.currencyTypes, valueDisplay).
  • getRawTransaction alignment: verbose=true (boolean), no 3rd blockhash arg; coinbase-input normalization; vout.scriptPubKey.{address,type,asm}.
  • txindex detection for qanumd (rpcApi.qanumTxIndexAvailable).
  • getAddress robust to {result:null} for missing methods; safe getnettotals fallback.

[v0.1.0] — 2026-08-20

Fase A scaffold

  • Independent repo (clean history, no upstream git / fork relationship).
  • app/coins/qan.js — Qanum coin definition verified against the L1 (jomas, 75 s block time, ASERT, subsidy function, regtest genesis hash).
  • app/coins.js — registers the QAN coin.
  • RPC layer aligned to qanumd (app/api/coreApi.js, app/api/rpcApi.js), block/tx normalization, getAddress fallback, hashrate fallback, mining-pools JSON-only parse.
  • Transaction/block parser uses vout.address.
  • Live E2E against a qanumd regtest: /, /blocks, /block/:hash, /block-height/:h, /tx/:txid render.