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.
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.NODE_ENV=production the "Page Errors" box shows only the error id
and message; raw errors and stack traces stay in the server log./admin/resetUserSettings to /user-settings/reset./changelog shows this file instead of the upstream history./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)./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 no longer fails (500) when visited again within 5 seconds.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%./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:
difficultyAdjustmentBlockCount=0 would produce a NaN height);
blocksPerYear / initialSubsidyJomas / tailSubsidyJomas are now
exported from app/coins/qan.js (documented L1 constants).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.
/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.
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.
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.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.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).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.
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.
Release of the changes accumulated locally since v0.1.7 (commits dd3e98f, 0341caf, 79b3ea5, f8ea1ce, fff5b82, 6cef217):
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).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).
/undefined 404 spamTwo 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.
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.
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.
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.
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).
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).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.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.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).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.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.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.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.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.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.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./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/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).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/QANUM.md, TESTSUITE.md).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.
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).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).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.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.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).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.
BTCEXP_ → QANEXP_, and BTCEXP_BITCOIND_* →
QANEXP_QANUMD_* across code + docs. app/credentials.js reads
QANEXP_QANUMD_HOST/PORT/USER/PASS/COOKIE/URI.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.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.)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).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.docs/QANUM.md; QANEXP_QANUMD_* env var names (real config).net_v2 is enabled at the node with -listen=1.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./next-block and /tx-stats work for QanumrpcApi.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.QANEXP_PROJECT_URL / QANEXP_PROJECT_NAME config (default
https://github.com/qanum/qanum-rpc-explorer)./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).config.js, layout.pug,
global.currencyTypes, valueDisplay).getRawTransaction alignment: verbose=true (boolean), no 3rd blockhash
arg; coinbase-input normalization; vout.scriptPubKey.{address,type,asm}.rpcApi.qanumTxIndexAvailable).getAddress robust to {result:null} for missing methods; safe
getnettotals fallback.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.qanumd (app/api/coreApi.js, app/api/rpcApi.js),
block/tx normalization, getAddress fallback, hashrate fallback,
mining-pools JSON-only parse.vout.address.qanumd regtest: /, /blocks, /block/:hash,
/block-height/:h, /tx/:txid render.