Every data source, every cache, every limitation — listed in plain text on this page. If a number on this site is wrong, this is where you find out why.
Why this page exists. Most XRPL dashboards say "live" without telling you what that means. We commit to the opposite: every claim of "live" is backed by a measurable cadence below, and every cache is named with its TTL. If you disagree with our numbers, this page is the audit trail.
Page last revised 2026-05-13. Versioned in git alongside the code that ships these features.
Three states: Live means a WebSocket pushes new data without a page refresh. Cached means we re-query the XRP Ledger on a fixed cadence and serve the most recent answer to all visitors during the cache window.
| Page / surface | State | Cadence / TTL | Underlying source |
|---|---|---|---|
| /api/ledger-tip | Cached | 20 sec | server_info on public XRPL node |
| Ledger heartbeat chip (every page header) |
Cached | polls every 30 sec → 20 sec server cache | /api/ledger-tip |
| /wallet/<addr> tx counter, last seen, sparkline today bin |
Live | WebSocket push (~3–5 sec per validated ledger) | Browser subscribes directly to wss://xrplcluster.com |
| /wallet/<addr> balances, holdings, network graph, AMM positions |
Cached | 5 min | account_info, account_lines, account_tx, amm_info |
| /whales large-XRP / tagged / trustset feed |
Live | WebSocket push (~3–5 sec per validated ledger) | Browser subscribes directly to wss://xrplcluster.com; initial page load is from worker → Neon |
| /tokens, /token/<currency>/<issuer> per-token swap activity |
Live | WebSocket push for new swaps; aggregates rebuild on next reload | Browser WS to wss://xrplcluster.com; rollups from worker → Neon |
| /pools constellation swap pulses + per-pool TVL |
Live | WebSocket push; TVL adjusts on each AMM LP-token delta | Browser WS to wss://xrplcluster.com; static pool index seeded from amm_info |
| /api/pools/recent_events | Live | worker writes pool swaps as they happen; API reads on each call | Worker → Neon Postgres |
| /cold-storage | Cached | 5 min | account_info on labeled cold wallets |
| /rlusd cross-chain supply, mint/burn events |
Cached | 5 min | Ethereum public JSON-RPC (1rpc.io/eth) + XRPL public node (s1.ripple.com) |
| /api/rlusd/state | Cached | 5 min | eth_call, eth_getLogs, gateway_balances, account_tx |
| /mpts MPT registry + holder counts |
Cached | hourly snapshot worker | daily ledger_data walk seeds the registry; hourly mpt_holders + ledger_entry refresh holder counts and outstanding supply |
| /mpt/<id> detail page + supply history chart |
Cached | hourly snapshot; history chart from 90-day time-series | same hourly worker; time-series written to mpt_supply_history on each successful walk |
| /mpt/issuer/<wallet> issuer roll-up + attestation badge |
Cached | hourly snapshot | aggregated from same hourly worker snapshot; domain attestation verified at index time against .well-known/xrp-ledger.toml |
| /lending amendment status + protocol explainer |
Cached | 5 min | feature RPC (amendment voting status); switches to live broker/vault data once LendingProtocol amendment activates |
Five surfaces use browser-side WebSocket push (Live) from wss://xrplcluster.com. The remaining cached surfaces are derived from RPC calls or background snapshot workers — either there's no streaming equivalent, or the data changes on a cadence where a short TTL is the honest framing.
All on-chain data is read from public XRPL nodes — peers in the consensus network. A node can't lie about ledger contents without the rest of the network rejecting it.
wss://xrplcluster.com — Community-operated full-history cluster run by the XRP Ledger Foundation. Used by the browser for all per-page real-time subscriptions (whales, tokens, pools, wallet, liveness chip).wss://s2.ripple.com — Ripple-operated full-history node. Used by the server-side worker for streaming validated transactions into Postgres. Also kept as the first browser fallback if xrplcluster.com is unreachable.s1.ripple.com:51234 — Ripple-operated general-purpose JSON-RPC node. Used by the network pulse, ledger-tip, and RLUSD-issuer endpoints.RLUSD is a stablecoin that lives on Ethereum as well as the XRP Ledger. To surface the Ethereum-side supply and treasury activity we query a public Ethereum JSON-RPC endpoint directly — no API key, no third-party gateway. The node only sees standard public reads (totalSupply, recent Transfer logs) and cannot lie about contract state without producing an inconsistent block that the rest of the Ethereum network would reject.
1rpc.io/eth — Public, key-free Ethereum JSON-RPC endpoint. Used by /api/rlusd/state to read the RLUSD ERC-20 totalSupply and recent Transfer logs at contract 0x8292…17eD.
Disclosure. Ripple's documentation explicitly states their public servers are not intended for sustained business use. Browser-side traffic has now been migrated to the community-operated cluster
wss://xrplcluster.com (run by the XRP Ledger Foundation), with wss://s2.ripple.com and wss://s1.ripple.com retained as automatic fallbacks. The server-side worker still streams from wss://s2.ripple.com; the plan is to migrate it next, and to run our own
rippled node as the project grows.
Worker writes to Neon Postgres (managed Postgres, US-hosted) and a redundant local SQLite snapshot. The web app prefers Postgres for fresh reads and falls back to the SQLite snapshot if the Postgres connection is unavailable. No third-party analytics API (Bithomp, XRPSCAN, xrpl.to, XPMarket, DefiLlama, CoinGecko) feeds any of our metrics — price, volume, TVL, balances are all computed directly from the ledger.
Token display names are hand-curated in
token_names.json
in the public GitHub repo, each with a verifiable source URL (exchange page, project .toml, or audit), accepted via public PR review. Account labels are layered by priority:
named_accounts.json in the repo; highest trust, manually reviewed.Domain field and the domain's .well-known/xrp-ledger.toml form a verified two-way chain (see Domain attestation below). Stored with source=\'toml\'.Every label is stored with its source so users can tell first-party from TOML-attested from reference.
Every UTC day we capture a small canonical set of headline metrics (validated ledger index, AMM pool count and total TVL, MPT count, named-accounts count), hash that capture into a Merkle leaf, extend a global append-only Merkle chain, and sign the resulting envelope with our Ed25519 private key. The signed JSON is published at /.well-known/snapshots/YYYY-MM-DD.json and the cumulative chain root at /.well-known/snapshots/chain.json. Both are static, cacheable, and independently verifiable forever.
Why this exists. Web dashboards can silently re-render history. A number that was true yesterday can quietly become a different number today, and visitors have no way to tell. Daily signed snapshots make that class of drift detectable: if the JSON you fetch today doesn't pass cryptographic verification against our published public key, something is wrong — either with the file, the chain, or the signing key. No other XRPL dashboard publishes a verifiable history of its own numbers.
Anatomy of one snapshot.
Each daily file contains: the metrics block (name → value+unit pairs), a canonical-JSON SHA-256 leaf hash, the leaf's index in the global chain, the audit path proving inclusion under that day's chain root, the previous chain root, the new chain root, and an Ed25519 signature over the canonical envelope summary. All hashing follows RFC 6962-style domain separation — 0x00 byte prefix for leaves, 0x01 for internal nodes — so leaves and intermediate hashes can never collide.
How to verify yourself. Three independent checks, all server-side-free:
_xrpld-snapshot-key.xrpldashboard.com. All four sources must agree.0x00 || canonical-JSON of the {signing_domain, schema_version, snapshot_date_utc, metrics} subset).audit_path from the leaf, hashing each pair with the 0x01 domain separator. The result must equal the published chain_root.signature_ed25519 against the canonical-JSON of the envelope summary {signing_domain, schema_version, snapshot_date_utc, leaf_hash, leaf_index, leaves_total, chain_root, previous_root}, using the public key from step 1.Our one-click verification form runs all three checks server-side and shows each pass/fail independently — the same verification you can run locally with any Ed25519 library plus a SHA-256.
Trust model. A signed snapshot proves only that the published number existed on the recorded date and was signed by the key whose public half we pin in four places. It does not prove the number was correct — that depends on the source data and our collection logic, both documented in the rest of this page. Signed snapshots make it impossible for us to quietly rewrite history without being caught, but they are not a substitute for the rest of the methodology audit; they are the audit's lower bound.
Signing key fingerprint.
7F:D4:F2:F4:D2:57:7C:BE
Schema version: 1.
Signing domain: xrpldashboard.com/signed_snapshot/v1.
Curve: Ed25519.
Browse the public snapshot index at /snapshots/.
A "domain-attested" issuer is one we can cryptographically link to a public web domain by following a two-way chain. First, the issuer's on-ledger Domain field (set via AccountSet) points to a hostname (e.g. sivax.io). Second, that hostname publishes an xrp-ledger.toml file at /.well-known/xrp-ledger.toml whose [[ISSUERS]] block explicitly names the same on-ledger wallet. Both directions have to agree — if either side is missing or contradicts, no badge.
This matters because anyone can mint an MPT and claim to be an institutional issuer. Attestation lets a visitor verify the claim without trusting xrpldashboard: the domain is the badge, the .well-known/xrp-ledger.toml file is publicly readable, and the entire chain is independently checkable.
What the green ✓ does NOT mean: it is not an endorsement, not KYC, not legal or regulatory verification, not a signal of financial soundness. It only certifies that the on-ledger account and the named domain are operated by the same party. Whether that party is trustworthy in any other sense is for the visitor to research.
Where the badge renders:
Currently on /mpt/issuer/<wallet> pages for verified MPT issuers. Will extend to /tokens, /whales, and homepage label surfaces as more issuers publish xrp-ledger.toml attestations.
How institutional Real-World Asset families surface on /rwa — and what we deliberately exclude.
Domain field → matching xrp-ledger.toml listing the same wallet. No name-pattern matching alone — a pool called "Foo/BlackRock" is not evidence BlackRock issues anything.token_names.json form a brand-protection allowlist. When a pool surfaces a currency code on the allowlist but the issuer wallet is not on the allowlist for that brand, the pool is annotated as an unverified-brand spoof and renders with a ⚠ marker on /pools. The same substrate gates inclusion on /rwa — the spoofs never appear as part of a verified family.excluded for cases we believe are spoofs / mislabels; pending for cases that may clear once domain attestation lands). The list is editorial, public, and updated as evidence changes — readers can see what we considered and chose not to surface.A wallet with vanity prefix rondo4tPzRyU72uNpY97iCqXGYd35AmYv
set its on-ledger Domain field to ondo.finance/ousg.
A one-way Domain check would have validated this as Ondo. The two-way TOML chain caught it:
ondo.finance/ousghttps://ondo.finance/.well-known/xrp-ledger.toml[[ISSUERS]] block lists rHuiXXjHLpMP8ZE9sSQU5aADQVWDwv6h5p as canonical OUSG issuer — NOT the rondo vanity walletThis same wallet also issues a fabricated ONDO token (Ondo's governance token is Ethereum-only — no XRPL presence) and pairs with the BlackRock and Franklin Templeton vanity wallets in self-referential spoof pools. After adding OUSG and ONDO to the verified-brand allowlist, all 12 spoof pool sides auto-flag with ⚠ on /pools.
Payment
transaction of 100,000 XRP or more. Smaller transfers don't appear on /whales. We do
not aggregate multiple smaller transfers — each row is one on-chain payment.Payment +
OfferCreate fills + AMM swap legs touching that currency/issuer pair, over a 30-day window.account_info + account_lines),
same constant-product formula the protocol uses internally. This is the spot price at the moment of fetch — it changes with every swap.account_tx entries. Sparse wallets (under 3 counterparties in 30 days) display a note explaining the gap, usually because most activity is order-book trading without a single counterparty.ledger_data walk, 1-5 hours), and an hourly worker re-walks the mpt_holders RPC + refreshes current OutstandingAmount via ledger_entry for each known issuance. Results are stored with a non-null reason enum so the source state is machine-readable, not just visible in a tooltip. The enum values are: complete (walked cleanly, at least one non-issuer holder), no_holders (walked cleanly, zero non-issuer holders), incomplete (walk hit the page cap before exhausting markers; partial counts are suppressed), skipped_test (TEST/TMPT tickers or "Test ..." names — not walked, labelled distinctly from "we haven't walked yet"), pending (never walked, or the RPC errored on this cycle). The headline number is the count of holders with a positive balance; "authorized" is stored alongside. Holders count excludes the issuer's own treasury balance, matching CMC circulating-supply convention.OutstandingAmount — so the ratio is faithful even though our stored top-N list is capped at 20 entries.mpt_supply_history. Both the holders walk and the current OutstandingAmount are re-fetched per cycle, so each row is internally consistent — top-1/top-3 share are never computed against a stale denominator. Pending, incomplete, ledger_entry-failed, and skipped-test runs are excluded — the time-series is gap-free where it has data, not gap-filled across uncertainty. Raw rows retained 90 days; daily rollup beyond. Initial seed (2026-05-12 23:29 UTC): 203 issuances entered the time-series — 143 with zero positive-balance holders, 60 with active distribution. Current count grows as new MPTs are minted; see /mpts for the live figure. Anyone curious can verify against the live table./mpts table defaults to two presentational filters that hide the long tail: "Has name" (excludes MPTs missing XLS-89 metadata) and "Has supply" (excludes never-minted issuances where OutstandingAmount = 0). Both default-on, both togglable from the chip row, both persist in localStorage. The full data is always present in the page — filters only affect display — and /api/mpts returns every row unfiltered. Power users can override the supply threshold via ?outstanding_min=N (e.g. ?outstanding_min=100 for a tighter view); the chip label updates to reflect the override./api/whales/recent every 10 seconds, dedupes by transaction hash, and renders one halo-pulse roughly every 5 seconds for each new event seen. Each halo-pulse corresponds to an actual transaction recorded on /whales. On fetch failure the whale layer falls silent rather than faking traffic; under prefers-reduced-motion both layers pause and the static sphere remains./whales,
/tokens) show data up to the last successful write. Per-page WebSockets continue working independently.server_info (validated_ledger), cached 10 minutes. Reserves only change via on-chain amendment, so the cache is safe; the literal numbers in the calculation will reflect the network's current parameters automatically.
This methodology page is part of the same git repository as the code. Any time the site's caching behavior, data sources, or methodology changes, the corresponding edit lands in this file in the same commit. The commit history of templates/methodology.html
is the canonical change log.
Found a discrepancy? Open an issue on GitHub or email contact@xrpldashboard.com. We'll either fix the data, fix the explanation, or — if it's a genuine ambiguity — add it to the limitations list above.