Blockscout /api/v2/stats returns average_block_time in milliseconds;
ReportingPage displays it as `${value.toFixed(1)}s` which rendered
~4424s instead of the real ~4.4s. Normalize in the service layer so
every caller gets seconds regardless of upstream format.
Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
Extends the POC from #2 beyond the Dashboard so every portal page that
can benefit from on-chain signal now pulls from live backends while
preserving its existing UX. Pages without an on-chain analogue (the
IFRS/GAAP/IPSAS report rows, the dbis_core compliance alerts) stay on
sample data with an explicit 'mocked' note.
New shared primitives
---------------------
src/hooks/useLatestTransactions.ts — polls SolaceScan /transactions every 15s
src/hooks/useAddressTransactions.ts — per-address tx feed, 60s polling
src/components/portal/LiveTransactionsPanel.tsx — reusable live-tx card
src/components/portal/LiveChainBanner.tsx — slim status banner
src/components/portal/OnChainBalanceTag.tsx — shared live/off-chain pill
Per-page wiring
---------------
AccountsPage — on-chain pill + META balance + SolaceScan link on
each account row that carries a walletAddress;
overlay renders only on wallet rows (negative check).
SettlementsPage — replaces the static 'Settlement Rate' tile with a
live Chain-138 block + tx-today tile; adds a
LiveTransactionsPanel above the CSD queue so the
page no longer renders identical output when RPC
is dead.
ReportingPage — new On-Chain Reporting Snapshot row (Blockscout
/stats: block depth, total tx, total addrs,
utilisation, avg block time). Clear note that
the IFRS/GAAP/IPSAS rows come from dbis_core and
are still mocked.
TreasuryPage — two new summary tiles: live Chain-138 gas +
aggregated on-chain custody (META) from sample
wallet addresses. Uses the same
useOnChainBalances hook as Accounts.
CompliancePage — AML monitor strip with wallet selector; dedicated
'On-Chain Tx Feed' card shows IN/OUT per tracked
wallet via SolaceScan. dbis_core alerts still
mocked (no public deploy).
TransactionBuilder — LiveChainBanner inserted above the composer so
users know chain health + gas + latency before
composing; transaction-builder-module made a
flex column so the banner doesn't cover the
canvas.
Assertions baked into every live widget
---------------------------------------
- RPC failure flips colour + text to 'degraded'/'—' (no silent freeze).
- Loading state is distinct from both live and degraded.
- Each overlay is only rendered where real data differs from sample data
(walletAddress rows for balances, tracked custody for AML, etc.) so a
page without live overlays is proof-of-scope, not proof-of-brokenness.
Verified locally
----------------
- tsc --noEmit: clean
- npm run build: clean (2066 modules, 565 ms)
Still intentionally mocked
--------------------------
- proxmox.ts — CF-Access protected; a BFF route is now open in
orchestrator PR (see companion PR for /api/proxmox/*).
- dbisCore.ts — no public deployment exists yet.