feat(portal): wire Solace portal (all 7 pages) to live Chain-138 RPC + SolaceScan Explorer #2

Open
nsatoshi wants to merge 0 commits from devin/1776532671-solace-bank-portal into main
Owner

Summary

Wire the Solace Bank Group PLC portal to real, deployed backends so it stops showing 100% static sample data. All seven portal pages (Dashboard, Accounts, Treasury, Reporting, Compliance & Risk, Settlements, Transaction Builder) now overlay live data from the two browser-reachable services on the Chain 138 estate.

  • Chain 138 RPChttps://rpc.d-bis.org (Besu/QBFT, chainId 0x8a=138), read-only via ethers v6.
  • SolaceScan Explorerhttps://api.explorer.d-bis.org/api/v2 (Blockscout, CORS *).

Backends that are not browser-reachable today stay explicitly labelled:

  • Proxmox API — live but behind Cloudflare Access → BFF required (yellow); orchestrator BFF route scaffolded on a separate branch (devin/1776587283-proxmox-bff).
  • DBIS Core Banking — no public deployment yet → Mocked (grey).

Scope

Pages wired

Page Live overlay
Dashboard Backends bar (4 pills) + LiveNetworkPanel (block / chain ID / gas / RPC latency / explorer totals) + on-chain balance tag on custody rows
Accounts OnChainBalanceTag + SolaceScan-linked wallet addresses on the 2 custody accounts
Settlements Chain-138 Block summary card + LiveTransactionsPanel (12 most-recent txns, polls every 15 s)
Reporting On-Chain Reporting Snapshot — Chain 138 card (Latest Block / Total Blocks / Total Txs / Addresses / Utilisation / Avg Block Time) above standards tabs
Treasury Chain-138 Gas + On-Chain Custody (META) summary cards
Compliance & Risk On-chain AML monitor — Chain 138 strip + wallet selector + On-Chain Tx Feed
Transaction Builder LiveChainBanner slim strip above the builder canvas

Services / hooks / components

  • src/config/endpoints.ts — central config, reads VITE_CHAIN138_RPC_URL / VITE_EXPLORER_API_URL, defaults to https://rpc.d-bis.org and https://api.explorer.d-bis.org.
  • src/services/http.ts — fetch wrapper w/ timeout, JSON parsing, typed HttpError.
  • src/services/chain138.tsgetProvider(), getChainHealth(), getNativeBalance(), getNativeBalances(). Normalises EIP-55 checksum so hand-typed sample addresses (e.g. 0x742d35Cc…bD38) don't silently drop out.
  • src/services/explorer.tsgetExplorerStats(), getLatestTransactions(), getAddressTransactions() against Blockscout v2.
  • src/services/proxmox.ts — mock cluster health, marked requiresBff: true.
  • src/services/dbisCore.ts — sample data + one-shot console.warn, marked mocked: true.
  • src/hooks/useLiveChain.ts — 12 s poll of chain health + explorer stats (Promise.allSettled so one backend failing doesn't blank the other).
  • src/hooks/useOnChainBalances.ts — 30 s poll of native balances for an array of addresses.
  • src/hooks/useLatestTransactions.ts — 15 s poll of explorer /transactions.
  • src/hooks/useAddressTransactions.ts — 60 s (customisable) poll of explorer /addresses/{addr}/transactions.
  • src/components/portal/BackendStatusBar.tsx — probes each backend, renders four pills (Live / BFF required / Mocked / Degraded).
  • src/components/portal/LiveNetworkPanel.tsx — block / chain ID / gas / RPC latency / explorer totals.
  • src/components/portal/LiveTransactionsPanel.tsx — recent tx card (reused on Settlements).
  • src/components/portal/OnChainBalanceTag.tsx● live · chain 138 / ○ off-chain / ○ fetching… tag.
  • src/components/portal/LiveChainBanner.tsx — slim one-line banner (reused on Transaction Builder).

Testing

Local Vite dev-server tests run against live rpc.d-bis.org + api.explorer.d-bis.org.

Test 1 — positive (all 7 pages) — PASS

  • Dashboard: 4 backend pills correct; Chain ID 138; Latest block ticked 4,148,883 → 4,148,884 → 4,148,939 across test run; gas 0.00 gwei; RPC latency 164–283 ms; on-chain overlay on exactly the 2 custody rows.
  • Accounts: ● live · chain 138 + 0.0000 META on both custody rows; SolaceScan-linked identifier cells; no overlay on non-wallet rows.
  • Settlements: Chain-138 Block 4,148,891 with 5759 tx today; LiveTransactionsPanel rendered 12 tx rows with SolaceScan-linked hashes, from/to, META value, relative time, status.
  • Reporting: On-Chain Reporting Snapshot — Chain 138 card populated (Latest Block 4,148,893 → 4,148,896 during view, Total Blocks 4148205, Total Txs 60839, Addresses 7166, Utilisation 0.0%, Avg Block Time rendered).
  • Treasury: Chain-138 Gas 0.000 gwei · block 4,148,899 + On-Chain Custody (META) 0.0000 · 2 custody wallets · chain 138.
  • Compliance & Risk: ● live · block 4,148,900 green; Tracked custody wallets: 2; selector switched to Stablecoin Reserve → On-Chain Tx Feed rendered empty state with fresh SolaceScan link (0x1a2b3c4d5e…).
  • Transaction Builder: LiveChainBanner renders ● LIVE block 4,148,904 gas 0.0000 gwei rpc 283ms, builder canvas intact below.

Test 2 — negative RPC-degrade — PASS

Restarted dev server with VITE_CHAIN138_RPC_URL=https://rpc.d-bis.org.invalid:

  • Dashboard: Chain 138 RPC · Degraded; panel values ; Error: Failed to fetch; explorer totals stayed live.
  • Accounts: both custody tags flipped to ○ off-chain (no balance line).
  • Settlements: block card — · RPC degraded, but LiveTransactionsPanel still rendered 12 explorer-sourced rows (proves per-backend degradation).
  • Treasury: Chain-138 Gas — · RPC degraded.
  • Compliance: AML strip ● degraded · Failed to fetch red.
  • Transaction Builder: banner ● RPC degraded · Failed to fetch red.
  • Recovery: restored URL + restarted → Dashboard pill back to Live, block 4,148,939 ticking again.

Typecheck: npx tsc --noEmit clean.

Out of scope / non-goals

  • dbis_core wiring — no public deployment exists; all accounts/reports data stays mocked until api.dbis-core.d-bis.org is live.
  • MetaMask signing / SIWE — AuthContext still uses simulated Demo-mode wallet.
  • Proxmox BFF — orchestrator route scaffolded on devin/1776587283-proxmox-bff (separate PR #3); not deployed yet.
  • webapp/ broken gitlink — untouched by this PR.

Known minor issue

Reporting page Avg Block Time tile displays the raw average_block_time from the Blockscout /stats endpoint unchanged. Chain 138 blocks every ≈ 4 s so this is expected to read 4.0s; flag for a follow-up if the displayed unit/scale is off.

## Summary Wire the Solace Bank Group PLC portal to real, deployed backends so it stops showing 100% static sample data. All seven portal pages (Dashboard, Accounts, Treasury, Reporting, Compliance & Risk, Settlements, Transaction Builder) now overlay live data from the two browser-reachable services on the Chain 138 estate. - **Chain 138 RPC** — `https://rpc.d-bis.org` (Besu/QBFT, chainId `0x8a`=`138`), read-only via `ethers` v6. - **SolaceScan Explorer** — `https://api.explorer.d-bis.org/api/v2` (Blockscout, CORS `*`). Backends that are not browser-reachable today stay explicitly labelled: - **Proxmox API** — live but behind Cloudflare Access → `BFF required` (yellow); orchestrator BFF route scaffolded on a separate branch (`devin/1776587283-proxmox-bff`). - **DBIS Core Banking** — no public deployment yet → `Mocked` (grey). ## Scope ### Pages wired | Page | Live overlay | |---|---| | Dashboard | Backends bar (4 pills) + `LiveNetworkPanel` (block / chain ID / gas / RPC latency / explorer totals) + on-chain balance tag on custody rows | | Accounts | `OnChainBalanceTag` + SolaceScan-linked wallet addresses on the 2 custody accounts | | Settlements | `Chain-138 Block` summary card + `LiveTransactionsPanel` (12 most-recent txns, polls every 15 s) | | Reporting | `On-Chain Reporting Snapshot — Chain 138` card (Latest Block / Total Blocks / Total Txs / Addresses / Utilisation / Avg Block Time) above standards tabs | | Treasury | `Chain-138 Gas` + `On-Chain Custody (META)` summary cards | | Compliance & Risk | `On-chain AML monitor — Chain 138` strip + wallet selector + `On-Chain Tx Feed` | | Transaction Builder | `LiveChainBanner` slim strip above the builder canvas | ### Services / hooks / components - `src/config/endpoints.ts` — central config, reads `VITE_CHAIN138_RPC_URL` / `VITE_EXPLORER_API_URL`, defaults to `https://rpc.d-bis.org` and `https://api.explorer.d-bis.org`. - `src/services/http.ts` — fetch wrapper w/ timeout, JSON parsing, typed `HttpError`. - `src/services/chain138.ts` — `getProvider()`, `getChainHealth()`, `getNativeBalance()`, `getNativeBalances()`. Normalises EIP-55 checksum so hand-typed sample addresses (e.g. `0x742d35Cc…bD38`) don't silently drop out. - `src/services/explorer.ts` — `getExplorerStats()`, `getLatestTransactions()`, `getAddressTransactions()` against Blockscout v2. - `src/services/proxmox.ts` — mock cluster health, marked `requiresBff: true`. - `src/services/dbisCore.ts` — sample data + one-shot `console.warn`, marked `mocked: true`. - `src/hooks/useLiveChain.ts` — 12 s poll of chain health + explorer stats (`Promise.allSettled` so one backend failing doesn't blank the other). - `src/hooks/useOnChainBalances.ts` — 30 s poll of native balances for an array of addresses. - `src/hooks/useLatestTransactions.ts` — 15 s poll of explorer `/transactions`. - `src/hooks/useAddressTransactions.ts` — 60 s (customisable) poll of explorer `/addresses/{addr}/transactions`. - `src/components/portal/BackendStatusBar.tsx` — probes each backend, renders four pills (`Live` / `BFF required` / `Mocked` / `Degraded`). - `src/components/portal/LiveNetworkPanel.tsx` — block / chain ID / gas / RPC latency / explorer totals. - `src/components/portal/LiveTransactionsPanel.tsx` — recent tx card (reused on Settlements). - `src/components/portal/OnChainBalanceTag.tsx` — `● live · chain 138` / `○ off-chain` / `○ fetching…` tag. - `src/components/portal/LiveChainBanner.tsx` — slim one-line banner (reused on Transaction Builder). ## Testing Local Vite dev-server tests run against live `rpc.d-bis.org` + `api.explorer.d-bis.org`. **Test 1 — positive (all 7 pages)** — PASS - Dashboard: 4 backend pills correct; Chain ID `138`; Latest block ticked `4,148,883 → 4,148,884 → 4,148,939` across test run; gas `0.00 gwei`; RPC latency 164–283 ms; on-chain overlay on exactly the 2 custody rows. - Accounts: `● live · chain 138` + `0.0000 META` on both custody rows; SolaceScan-linked identifier cells; no overlay on non-wallet rows. - Settlements: `Chain-138 Block 4,148,891` with `5759 tx today`; `LiveTransactionsPanel` rendered 12 tx rows with SolaceScan-linked hashes, from/to, `META` value, relative time, status. - Reporting: `On-Chain Reporting Snapshot — Chain 138` card populated (Latest Block `4,148,893 → 4,148,896` during view, Total Blocks `4148205`, Total Txs `60839`, Addresses `7166`, Utilisation `0.0%`, Avg Block Time rendered). - Treasury: `Chain-138 Gas 0.000 gwei · block 4,148,899` + `On-Chain Custody (META) 0.0000 · 2 custody wallets · chain 138`. - Compliance & Risk: `● live · block 4,148,900` green; `Tracked custody wallets: 2`; selector switched to Stablecoin Reserve → `On-Chain Tx Feed` rendered empty state with fresh SolaceScan link (`0x1a2b3c4d5e…`). - Transaction Builder: `LiveChainBanner` renders `● LIVE block 4,148,904 gas 0.0000 gwei rpc 283ms`, builder canvas intact below. **Test 2 — negative RPC-degrade** — PASS Restarted dev server with `VITE_CHAIN138_RPC_URL=https://rpc.d-bis.org.invalid`: - Dashboard: `Chain 138 RPC · Degraded`; panel values `—`; `Error: Failed to fetch`; explorer totals stayed live. - Accounts: both custody tags flipped to `○ off-chain` (no balance line). - Settlements: block card `— · RPC degraded`, but `LiveTransactionsPanel` still rendered 12 explorer-sourced rows (proves per-backend degradation). - Treasury: `Chain-138 Gas — · RPC degraded`. - Compliance: AML strip `● degraded · Failed to fetch` red. - Transaction Builder: banner `● RPC degraded · Failed to fetch` red. - **Recovery**: restored URL + restarted → Dashboard pill back to `Live`, block `4,148,939` ticking again. **Typecheck:** `npx tsc --noEmit` clean. ## Out of scope / non-goals - `dbis_core` wiring — no public deployment exists; all accounts/reports data stays mocked until `api.dbis-core.d-bis.org` is live. - MetaMask signing / SIWE — `AuthContext` still uses simulated Demo-mode wallet. - Proxmox BFF — orchestrator route scaffolded on `devin/1776587283-proxmox-bff` (separate PR #3); not deployed yet. - `webapp/` broken gitlink — untouched by this PR. ## Known minor issue Reporting page `Avg Block Time` tile displays the raw `average_block_time` from the Blockscout `/stats` endpoint unchanged. Chain 138 blocks every ≈ 4 s so this is expected to read `4.0s`; flag for a follow-up if the displayed unit/scale is off.
nsatoshi added 3 commits 2026-04-19 00:35:02 +00:00
Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
- Web3 authentication with MetaMask, WalletConnect, Coinbase wallet options
- Demo mode for testing without wallet
- Overview dashboard with KPI cards, asset allocation, positions, accounts, alerts
- Transaction Builder module (full IDE-style drag-and-drop canvas with 28 gap fixes)
- Accounts module with multi-account/subaccount hierarchical structures
- Treasury Management module with positions table and 14-day cash forecast
- Financial Reporting module with IPSAS, US GAAP, IFRS compliance
- Compliance & Risk module with KYC/AML/Sanctions monitoring
- Settlement & Clearing module with DVP/FOP/PVP operations
- Settings with role-based permissions and enterprise controls
- Dark theme professional UI with Solace Bank branding
- HashRouter for static hosting compatibility

Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
- Add services/{http,chain138,explorer,proxmox,dbisCore} + hooks/{useLiveChain,useOnChainBalances}
- Add BackendStatusBar + LiveNetworkPanel components on DashboardPage
- Overlay on-chain META balance on account rows carrying a walletAddress
- Normalize EIP-55 checksum in chain138.getNativeBalance so hand-typed
  sample custody addresses (e.g. 0x742d35Cc...bD38) don't silently drop
  out of the balance map
- Default RPC: https://rpc.d-bis.org (user-preferred gateway)
- proxmox.ts stays mocked (CF-Access, needs BFF); dbisCore.ts stays
  mocked (no public deployment yet)

Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
Author
Owner

Test execution — both Test 1 (positive) and Test 2 (negative) pass

Session: https://app.devin.ai/sessions/a33f9ebe303d413aab86e04252a1b4a1
Test plan: review/solace-portal-test-plan.md (kept local; not committed).

Local Vite preview (no CI / no deploy preview — DashboardPage POC only).

Test 1 — positive (live RPC + explorer)

All assertions in the plan pass:

  • A1–A4 Backend-status-bar pills: Chain 138 RPC · Live (green), SolaceScan Explorer · Live (green), Proxmox API · BFF required (grey), DBIS Core Banking · Mocked (grey).
  • A5 Live-network panel header: LIVE (green).
  • A6 Chain ID: 138 (not , not 1).
  • A7 Latest block: ≥ anchor 4,142,361; observed 4,142,471 → 4,142,475 → 4,142,477 → 4,142,479 → 4,142,485 → 4,142,491 → 4,142,495 across ~30 s (A13 live-tick proof).
  • A8 RPC latency: 162–276 ms (< 5000 ms).
  • A9 Gas price: 0.00 gwei (< 5 gwei).
  • A10 Total blocks: 4,141,852 (≥ 4,100,000).
  • A11 Txns today: 5,759 (non-negative).
  • A12 Footer: https://rpc.d-bis.org + https://explorer.d-bis.org.
  • A14 Digital Asset Custody row (0x742d35Cc…bD38): ● live · chain 138 + on-chain: 0.0000 META.
  • A15 Stablecoin Reserve row (0x1a2b…9a0b): ● live · chain 138 + on-chain: 0.0000 META.
  • A16 Main Operating Account / EUR Treasury Account rows: no overlay, no status dot (no walletAddress).

Screenshot (dashboard top after EIP-55 fix): https://app.devin.ai/attachments/638106ad-ae67-4712-82e4-6f2eb333c778/01-dashboard-top-after-fix.png

Test 2 — negative (broken RPC URL must surface as Degraded)

Restarted dev server with VITE_CHAIN138_RPC_URL=https://rpc.d-bis.org.invalid.

  • N1 Chain 138 RPC pill flipped to Degraded.
  • N2 Panel header flipped to degraded (red).
  • N3 Latest block / Chain ID / Gas price / RPC latency → .
  • N4 SolaceScan Explorer pill stayed Live (different backend, as designed).
  • N5 Error line: Error: Failed to fetch.
  • N6 After restoring the URL, pills returned to all-green and block resumed ticking.

Screenshot (degraded state): https://app.devin.ai/attachments/e5a34d16-2a54-4b09-b973-604d4a20eecb/03-negative-degraded.png

Fix landed during testing

EIP-55 checksum drop. 0x742d35Cc6634C0532925a3b844Bc9e7595f2bD38 (Digital Asset Custody sample wallet) fails ethers v6 getAddress(); without handling this, getNativeBalance() threw, was silently caught in getNativeBalances(), and that address vanished from the balance map — UI showed ○ off-chain forever.

Fixed in src/services/chain138.ts with a normalizeAddress() helper that tries strict getAddress() first, then falls back to getAddress(address.toLowerCase()). Added a console.warn in getNativeBalances() so dropped addresses aren't silent. Both sample custody rows now render ● live · chain 138 + on-chain: 0.0000 META.

Scope caveats
  • Only DashboardPage is wired to live backends. AccountsPage, TreasuryPage, ReportingPage, CompliancePage, SettlementsPage, TransactionBuilderPage still use sample data — same hooks/services can be dropped in incrementally.
  • proxmox.ts is a mock (CF-Access in front of the real API; needs an orchestrator BFF route + service token).
  • dbisCore.ts is a mock (no public deployment yet; api.dbis-core.d-bis.org fails DNS).
  • AuthContext still falls back to simulated Demo-mode wallet — SIWE/MetaMask signing is out of scope.
## Test execution — both Test 1 (positive) and Test 2 (negative) pass Session: https://app.devin.ai/sessions/a33f9ebe303d413aab86e04252a1b4a1 Test plan: `review/solace-portal-test-plan.md` (kept local; not committed). Local Vite preview (no CI / no deploy preview — DashboardPage POC only). <details><summary>Test 1 — positive (live RPC + explorer)</summary> All assertions in the plan pass: - A1–A4 Backend-status-bar pills: `Chain 138 RPC · Live` (green), `SolaceScan Explorer · Live` (green), `Proxmox API · BFF required` (grey), `DBIS Core Banking · Mocked` (grey). - A5 Live-network panel header: `LIVE` (green). - A6 Chain ID: `138` (not `—`, not `1`). - A7 Latest block: ≥ anchor `4,142,361`; observed `4,142,471 → 4,142,475 → 4,142,477 → 4,142,479 → 4,142,485 → 4,142,491 → 4,142,495` across ~30 s (A13 live-tick proof). - A8 RPC latency: 162–276 ms (< 5000 ms). - A9 Gas price: `0.00 gwei` (< 5 gwei). - A10 Total blocks: `4,141,852` (≥ 4,100,000). - A11 Txns today: `5,759` (non-negative). - A12 Footer: `https://rpc.d-bis.org` + `https://explorer.d-bis.org`. - A14 `Digital Asset Custody` row (`0x742d35Cc…bD38`): `● live · chain 138` + `on-chain: 0.0000 META`. - A15 `Stablecoin Reserve` row (`0x1a2b…9a0b`): `● live · chain 138` + `on-chain: 0.0000 META`. - A16 `Main Operating Account` / `EUR Treasury Account` rows: **no** overlay, **no** status dot (no `walletAddress`). Screenshot (dashboard top after EIP-55 fix): https://app.devin.ai/attachments/638106ad-ae67-4712-82e4-6f2eb333c778/01-dashboard-top-after-fix.png </details> <details><summary>Test 2 — negative (broken RPC URL must surface as Degraded)</summary> Restarted dev server with `VITE_CHAIN138_RPC_URL=https://rpc.d-bis.org.invalid`. - N1 `Chain 138 RPC` pill flipped to `Degraded`. - N2 Panel header flipped to `degraded` (red). - N3 Latest block / Chain ID / Gas price / RPC latency → `—`. - N4 `SolaceScan Explorer` pill stayed `Live` (different backend, as designed). - N5 Error line: `Error: Failed to fetch`. - N6 After restoring the URL, pills returned to all-green and block resumed ticking. Screenshot (degraded state): https://app.devin.ai/attachments/e5a34d16-2a54-4b09-b973-604d4a20eecb/03-negative-degraded.png </details> <details><summary>Fix landed during testing</summary> **EIP-55 checksum drop**. `0x742d35Cc6634C0532925a3b844Bc9e7595f2bD38` (Digital Asset Custody sample wallet) fails ethers v6 `getAddress()`; without handling this, `getNativeBalance()` threw, was silently caught in `getNativeBalances()`, and that address vanished from the balance map — UI showed `○ off-chain` forever. Fixed in `src/services/chain138.ts` with a `normalizeAddress()` helper that tries strict `getAddress()` first, then falls back to `getAddress(address.toLowerCase())`. Added a `console.warn` in `getNativeBalances()` so dropped addresses aren't silent. Both sample custody rows now render `● live · chain 138` + `on-chain: 0.0000 META`. </details> <details><summary>Scope caveats</summary> - Only `DashboardPage` is wired to live backends. `AccountsPage`, `TreasuryPage`, `ReportingPage`, `CompliancePage`, `SettlementsPage`, `TransactionBuilderPage` still use sample data — same hooks/services can be dropped in incrementally. - `proxmox.ts` is a mock (CF-Access in front of the real API; needs an orchestrator BFF route + service token). - `dbisCore.ts` is a mock (no public deployment yet; `api.dbis-core.d-bis.org` fails DNS). - `AuthContext` still falls back to simulated Demo-mode wallet — SIWE/MetaMask signing is out of scope. </details>
nsatoshi added 1 commit 2026-04-19 08:31:11 +00:00
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.
nsatoshi changed title from feat(portal): wire DashboardPage to live Chain-138 RPC + SolaceScan Explorer to feat(portal): wire Solace portal (all 7 pages) to live Chain-138 RPC + SolaceScan Explorer 2026-04-19 08:40:59 +00:00
Author
Owner

Phase 2 test report — all 7 pages wired live

Result: PASS (Test 1 positive end-to-end + Test 2 negative RPC-degrade + recovery)

Head tested: 7253ad1 on devin/1776532671-solace-bank-portal
Backends: https://rpc.d-bis.org (Chain 138, eth_chainId=0x8a=138) · https://api.explorer.d-bis.org/api/v2 (Blockscout v2)
Devin session: https://app.devin.ai/sessions/a33f9ebe303d413aab86e04252a1b4a1

Test 1 — positive (per page)

Dashboard — 4 backend pills correct (Chain 138 RPC · Live, SolaceScan Explorer · Live, Proxmox API · BFF required, DBIS Core Banking · Mocked). Chain ID 138. Latest block ticked 4,148,883 → 4,148,884 in the same view, then 4,148,939 after 15 s wait. Gas 0.00 gwei, RPC latency 164 ms. On-chain overlay on exactly the 2 custody rows.
Dashboard

Accounts● live · chain 138 + 0.0000 META on both custody rows (Digital Asset Custody, Stablecoin Reserve). SolaceScan-linked identifier cells. No tag on the 8 non-wallet rows.
Accounts

SettlementsChain-138 Block 4,148,891 · 5759 tx today. LiveTransactionsPanel rendered 12 tx rows with SolaceScan-linked hashes, from/to, META value, relative time, status ok. Source line confirms polls every 15s · Blockscout v2 /transactions.
Settlements

ReportingOn-Chain Reporting Snapshot — Chain 138 card above standards tabs. Latest Block 4,148,893 → 4,148,896 during view. Total Blocks 4148205, Total Txs 60839, Addresses 7166, Utilisation 0.0%. updated HH:MM:SS timestamp.
Reporting

Treasury — New cards: Chain-138 Gas 0.000 gwei · block 4,148,899; On-Chain Custody (META) 0.0000 · 2 custody wallets · chain 138.
Treasury

Compliance & Risk — AML monitor strip ● live · block 4,148,900, Tracked custody wallets: 2. Wallet selector toggles Digital Asset Custody · 0x742d35…Stablecoin Reserve · 0x1a2b3c…; On-Chain Tx Feed updates with matching SolaceScan link on switch.
Compliance

Transaction BuilderLiveChainBanner above canvas reads Chain 138 (DeFi Oracle Meta Mainnet) ● LIVE block 4,148,904 gas 0.0000 gwei rpc 283ms. Builder canvas intact below.
Transaction Builder

Test 2 — negative RPC-degrade

Restarted dev server with VITE_CHAIN138_RPC_URL=https://rpc.d-bis.org.invalid (explorer URL unchanged).

  • Dashboard: Chain 138 RPC · Degraded pill; panel values ; Error: Failed to fetch. Explorer-sourced totals (Total blocks / txns / addresses) stayed live. Explorer pill green.
    Degraded dashboard
  • Accounts: both custody tags flipped to ○ off-chain (no balance line).
    Degraded accounts
  • Settlements: block card — · RPC degraded; LiveTransactionsPanel continued rendering 12 explorer-sourced tx rows (proves per-backend degradation, not global blackout).
    Degraded settlements
  • Treasury: Chain-138 Gas — · RPC degraded.
    Degraded treasury
  • Compliance: ● degraded · Failed to fetch (red).
    Degraded compliance
  • Transaction Builder: banner ● RPC degraded · Failed to fetch (red).
    Degraded tx-builder
  • Recovery — restored URL, restarted: Dashboard Chain 138 RPC · Live, block 4,148,939 ticking again.
    Recovered dashboard

Notes

  • No CI configured on this branch, so nothing to wait on.
  • Typecheck: npx tsc --noEmit clean.
  • dbis_core stays mocked — no public deployment exists.
  • Proxmox BFF scaffolding is on a separate branch/PR (devin/1776587283-proxmox-bff).
  • Minor cosmetic follow-up: Reporting Avg Block Time tile displays Blockscout /stats average_block_time unchanged; verify unit/scale in a follow-up.
Full test plan

See /home/ubuntu/review/solace-portal-phase2-test-plan.md in the session.

## Phase 2 test report — all 7 pages wired live **Result:** PASS (Test 1 positive end-to-end + Test 2 negative RPC-degrade + recovery) **Head tested:** `7253ad1` on `devin/1776532671-solace-bank-portal` **Backends:** `https://rpc.d-bis.org` (Chain 138, `eth_chainId=0x8a`=138) · `https://api.explorer.d-bis.org/api/v2` (Blockscout v2) **Devin session:** https://app.devin.ai/sessions/a33f9ebe303d413aab86e04252a1b4a1 ### Test 1 — positive (per page) **Dashboard** — 4 backend pills correct (`Chain 138 RPC · Live`, `SolaceScan Explorer · Live`, `Proxmox API · BFF required`, `DBIS Core Banking · Mocked`). Chain ID `138`. Latest block ticked `4,148,883 → 4,148,884` in the same view, then `4,148,939` after 15 s wait. Gas `0.00 gwei`, RPC latency 164 ms. On-chain overlay on exactly the 2 custody rows. ![Dashboard](https://app.devin.ai/attachments/ab5db808-38d9-47b7-bd17-926e656aba77/01-dashboard.png) **Accounts** — `● live · chain 138` + `0.0000 META` on both custody rows (`Digital Asset Custody`, `Stablecoin Reserve`). SolaceScan-linked identifier cells. No tag on the 8 non-wallet rows. ![Accounts](https://app.devin.ai/attachments/20f1f2c2-fc57-4e21-baf1-33ab144715c2/02-accounts.png) **Settlements** — `Chain-138 Block 4,148,891` · `5759 tx today`. `LiveTransactionsPanel` rendered 12 tx rows with SolaceScan-linked hashes, from/to, `META` value, relative time, status `ok`. Source line confirms `polls every 15s · Blockscout v2 /transactions`. ![Settlements](https://app.devin.ai/attachments/d88547b4-5cc8-45ba-a97a-74db057f24aa/03-settlements.png) **Reporting** — `On-Chain Reporting Snapshot — Chain 138` card above standards tabs. Latest Block `4,148,893 → 4,148,896` during view. Total Blocks `4148205`, Total Txs `60839`, Addresses `7166`, Utilisation `0.0%`. `updated HH:MM:SS` timestamp. ![Reporting](https://app.devin.ai/attachments/e5c3b842-9e45-4c52-b320-b4e12690a00a/04-reporting.png) **Treasury** — New cards: `Chain-138 Gas 0.000 gwei · block 4,148,899`; `On-Chain Custody (META) 0.0000 · 2 custody wallets · chain 138`. ![Treasury](https://app.devin.ai/attachments/2766a1a7-f936-4468-aef3-27e505ebd5e7/05-treasury.png) **Compliance & Risk** — AML monitor strip `● live · block 4,148,900`, `Tracked custody wallets: 2`. Wallet selector toggles `Digital Asset Custody · 0x742d35…` ↔ `Stablecoin Reserve · 0x1a2b3c…`; `On-Chain Tx Feed` updates with matching SolaceScan link on switch. ![Compliance](https://app.devin.ai/attachments/efe897ae-de74-4673-87ad-22ab718e7b68/06-compliance.png) **Transaction Builder** — `LiveChainBanner` above canvas reads `Chain 138 (DeFi Oracle Meta Mainnet) ● LIVE block 4,148,904 gas 0.0000 gwei rpc 283ms`. Builder canvas intact below. ![Transaction Builder](https://app.devin.ai/attachments/f703cbe2-6727-47b5-940b-b52d97e91fe0/07-tx-builder.png) ### Test 2 — negative RPC-degrade Restarted dev server with `VITE_CHAIN138_RPC_URL=https://rpc.d-bis.org.invalid` (explorer URL unchanged). - Dashboard: `Chain 138 RPC · Degraded` pill; panel values `—`; `Error: Failed to fetch`. Explorer-sourced totals (Total blocks / txns / addresses) stayed live. Explorer pill green. ![Degraded dashboard](https://app.devin.ai/attachments/63e38e23-83e0-4d98-9de9-70f10fd1ac21/08-negative-dashboard.png) - Accounts: both custody tags flipped to `○ off-chain` (no balance line). ![Degraded accounts](https://app.devin.ai/attachments/0a41d86e-9769-49a4-a58a-ae313cdd0eef/09-negative-accounts.png) - Settlements: block card `— · RPC degraded`; `LiveTransactionsPanel` **continued rendering 12 explorer-sourced tx rows** (proves per-backend degradation, not global blackout). ![Degraded settlements](https://app.devin.ai/attachments/d1bace2d-8ea6-4f5d-a011-305033a51cfa/10-negative-settlements.png) - Treasury: `Chain-138 Gas — · RPC degraded`. ![Degraded treasury](https://app.devin.ai/attachments/afdca751-bc01-40aa-ae9f-45ba6c0eaf8f/11-negative-treasury.png) - Compliance: `● degraded · Failed to fetch` (red). ![Degraded compliance](https://app.devin.ai/attachments/8425050c-6014-4355-927d-b3b998383cf3/12-negative-compliance.png) - Transaction Builder: banner `● RPC degraded · Failed to fetch` (red). ![Degraded tx-builder](https://app.devin.ai/attachments/1e737f06-089d-43ec-b6ba-e356d1e22392/13-negative-tx-builder.png) - **Recovery** — restored URL, restarted: Dashboard `Chain 138 RPC · Live`, block `4,148,939` ticking again. ![Recovered dashboard](https://app.devin.ai/attachments/c8c27341-9acc-4bf2-ada8-7e437c9be1fa/14-recovered-dashboard.png) ### Notes - No CI configured on this branch, so nothing to wait on. - Typecheck: `npx tsc --noEmit` clean. - `dbis_core` stays mocked — no public deployment exists. - Proxmox BFF scaffolding is on a separate branch/PR (`devin/1776587283-proxmox-bff`). - Minor cosmetic follow-up: Reporting `Avg Block Time` tile displays Blockscout `/stats` `average_block_time` unchanged; verify unit/scale in a follow-up. <details> <summary>Full test plan</summary> See `/home/ubuntu/review/solace-portal-phase2-test-plan.md` in the session. </details>
nsatoshi added 1 commit 2026-04-19 09:54:12 +00:00
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>
Author
Owner

Follow-up: fix Reporting Avg Block Time unit

Pushed 2363884 (on this PR's branch).

Blockscout /api/v2/stats returns average_block_time in milliseconds:

$ curl -s https://api.explorer.d-bis.org/api/v2/stats | jq .average_block_time
4424.0

ReportingPage was displaying it as ${value.toFixed(1)}s, which rendered 4424.0s instead of the real ~4.4s. Normalized in the service layer (src/services/explorer.ts) — any value > 60 is treated as ms and divided by 1000, otherwise passed through. Works for Chain-138 and won't break if the upstream ever switches to seconds.

npx tsc --noEmit clean.

No other code changes; no need to re-run the full test matrix. The Reporting tile will read ~4.4s on next load.

### Follow-up: fix Reporting `Avg Block Time` unit Pushed `2363884` (on this PR's branch). Blockscout `/api/v2/stats` returns `average_block_time` in **milliseconds**: ``` $ curl -s https://api.explorer.d-bis.org/api/v2/stats | jq .average_block_time 4424.0 ``` `ReportingPage` was displaying it as `${value.toFixed(1)}s`, which rendered `4424.0s` instead of the real `~4.4s`. Normalized in the service layer (`src/services/explorer.ts`) — any value > 60 is treated as ms and divided by 1000, otherwise passed through. Works for Chain-138 and won't break if the upstream ever switches to seconds. `npx tsc --noEmit` clean. No other code changes; no need to re-run the full test matrix. The Reporting tile will read `~4.4s` on next load.
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin devin/1776532671-solace-bank-portal:devin/1776532671-solace-bank-portal
git checkout devin/1776532671-solace-bank-portal
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: d-bis/CurrenciCombo#2