Add explorer liquidity access and live route proxies

This commit is contained in:
defiQUG
2026-03-27 12:02:36 -07:00
parent d02ee71cf6
commit 2491336b8e
17 changed files with 2746 additions and 125 deletions

View File

@@ -129,12 +129,18 @@
--bridge-blue: #3b82f6;
--dark: #1f2937;
--light: #f9fafb;
--card-bg: #ffffff;
--muted-surface: rgba(15, 23, 42, 0.04);
--muted-surface-strong: rgba(15, 23, 42, 0.08);
--border: #e5e7eb;
--text: #111827;
--text-light: #6b7280;
}
body.dark-theme {
--light: #111827;
--card-bg: #1e293b;
--muted-surface: rgba(148, 163, 184, 0.08);
--muted-surface-strong: rgba(148, 163, 184, 0.14);
--border: #374151;
--text: #f9fafb;
--text-light: #9ca3af;
@@ -159,7 +165,7 @@
.navbar {
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
color: white;
padding: 1rem 2rem;
padding: 0.85rem 2rem;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
position: sticky;
top: 0;
@@ -169,6 +175,7 @@
max-width: 1400px;
margin: 0 auto;
display: flex;
gap: 1rem;
justify-content: space-between;
align-items: center;
}
@@ -178,6 +185,22 @@
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.45rem 0.7rem;
border-radius: 14px;
transition: background 0.2s, transform 0.2s, box-shadow 0.2s;
text-decoration: none;
color: inherit;
}
.logo:hover,
.logo:focus-visible {
background: rgba(255,255,255,0.12);
transform: translateY(-1px);
box-shadow: 0 8px 20px rgba(0,0,0,0.08);
outline: none;
}
.logo i {
width: 1.2rem;
text-align: center;
}
.nav-links {
display: flex;
@@ -189,18 +212,20 @@
.nav-links a, .nav-dropdown-trigger {
color: white;
text-decoration: none;
transition: opacity 0.2s;
transition: opacity 0.2s, background 0.2s;
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.45rem 0.7rem;
border-radius: 999px;
}
.nav-links a:hover, .nav-dropdown-trigger:hover { opacity: 0.9; }
.nav-links a:hover, .nav-dropdown-trigger:hover { opacity: 1; background: rgba(255,255,255,0.12); }
.nav-dropdown-trigger {
background: none;
border: none;
cursor: pointer;
font: inherit;
padding: 0.5rem 0.25rem;
padding: 0.45rem 0.7rem;
}
.nav-dropdown-trigger i.fa-chevron-down {
font-size: 0.7rem;
@@ -244,8 +269,25 @@
.nav-dropdown-menu li { margin: 0; }
.search-box {
flex: 1;
max-width: 600px;
margin: 0 2rem;
max-width: 560px;
margin: 0 1.25rem;
}
.search-box .btn {
flex-shrink: 0;
}
.search-box .btn,
.search-box .search-hint {
white-space: nowrap;
}
.search-box .search-label {
display: inline;
}
.nav-actions {
display: flex;
align-items: center;
gap: 0.75rem;
flex-wrap: wrap;
justify-content: flex-end;
}
.search-input {
width: 100%;
@@ -816,16 +858,124 @@
.nav-dropdown-trigger { width: 100%; justify-content: space-between; padding: 0.6rem 0.5rem; }
}
@media (max-width: 768px) {
.nav-container { flex-direction: column; gap: 1rem; align-items: stretch; }
.search-box { max-width: 100%; margin: 0; }
.nav-container { flex-direction: column; gap: 0.75rem; align-items: stretch; }
.logo {
align-self: flex-start;
padding: 0.3rem 0.5rem;
font-size: 1.2rem;
border-radius: 12px;
}
.logo > div > span:first-child { line-height: 1.1; }
.logo > div > span:last-child { font-size: 0.68rem !important; }
.search-box { max-width: 100%; margin: 0; width: 100%; gap: 0.4rem; }
.search-box .btn {
padding: 0.55rem 0.7rem !important;
min-width: 2.75rem;
justify-content: center;
}
.search-box .search-label { display: none; }
.search-box .search-hint { display: none; }
.nav-actions { width: 100%; justify-content: space-between; gap: 0.5rem; }
.nav-actions > * { flex: 0 0 auto; }
.nav-actions #walletConnect { margin-left: auto; }
.nav-actions #walletConnectBtn,
.nav-actions #themeToggle,
.nav-actions #localeSelect { padding-left: 0.55rem; padding-right: 0.55rem; }
.nav-links { flex-wrap: wrap; justify-content: center; }
}
#gasNetworkContent { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 600px) {
#gasNetworkContent { grid-template-columns: 1fr; }
.gas-network-card { margin-bottom: 1rem; }
.gas-network-header {
display: flex;
flex-direction: column;
gap: 0.75rem;
align-items: stretch;
}
.gas-network-row,
.gas-network-compact,
.gas-network-pill,
.gas-network-spark {
display: flex;
}
.gas-network-row,
.gas-network-pill,
.gas-network-spark {
align-items: center;
}
.gas-network-row {
justify-content: space-between;
gap: 1rem;
flex-wrap: wrap;
}
.gas-network-compact { align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.gas-network-pill { gap: 0.4rem; padding: 0.45rem 0.7rem; border-radius: 999px; background: rgba(37, 99, 235, 0.08); color: var(--text); font-size: 0.86rem; border: 1px solid rgba(37, 99, 235, 0.12); white-space: nowrap; }
.gas-network-pill strong { font-size: 0.92rem; }
.gas-network-spark { align-items: flex-end; gap: 3px; height: 36px; min-width: 110px; }
.gas-network-spark span {
width: 8px;
border-radius: 4px 4px 0 0;
background: var(--primary);
opacity: 0.85;
}
.gas-network-subtle { color: var(--text-light); font-size: 0.82rem; white-space: nowrap; }
.btn-copy { background: none; border: none; cursor: pointer; padding: 0.25rem; margin-left: 0.35rem; color: var(--text-light); vertical-align: middle; }
.btn-copy:hover { color: var(--primary); }
.site-footer {
margin-top: 2.5rem;
padding: 2rem 0 2.5rem;
border-top: 1px solid var(--border);
background: rgba(255, 255, 255, 0.65);
backdrop-filter: blur(8px);
}
body.dark-theme .site-footer {
background: rgba(15, 23, 42, 0.78);
}
.site-footer-grid {
display: grid;
grid-template-columns: minmax(0, 1.6fr) repeat(2, minmax(0, 1fr));
gap: 1.5rem;
align-items: start;
}
.site-footer-title {
font-size: 0.78rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--text-light);
margin-bottom: 0.6rem;
}
.site-footer-links {
display: grid;
gap: 0.45rem;
font-size: 0.92rem;
}
.site-footer-links a {
color: var(--text);
}
.site-footer-links a:hover {
color: var(--primary);
}
.site-footer-note {
color: var(--text-light);
font-size: 0.9rem;
line-height: 1.65;
}
@media (max-width: 900px) {
.site-footer-grid { grid-template-columns: 1fr; }
}
body.dark-theme #smartSearchModal .btn.btn-secondary {
background: rgba(148, 163, 184, 0.12);
color: var(--text);
border-color: rgba(148, 163, 184, 0.24);
}
body.dark-theme #smartSearchModal aside {
background: linear-gradient(180deg, var(--muted-surface), var(--muted-surface-strong));
}
body.dark-theme #smartSearchModal main > div:first-of-type {
background: rgba(15, 23, 42, 0.72);
}
body.dark-theme #smartSearchModal #smartSearchPreview .loading {
color: var(--text-light);
}
</style>
</head>
<body>
@@ -857,20 +1007,19 @@
</script>
<nav class="navbar">
<div class="nav-container">
<div class="logo">
<a class="logo" href="/home" aria-label="Go to explorer home" style="text-decoration:none; color:inherit;">
<i class="fas fa-cube"></i>
<div style="display: flex; flex-direction: column; gap: 0.25rem;">
<span>SolaceScanScout</span>
<span style="font-size: 0.75rem; font-weight: normal; opacity: 0.9;">The Defi Oracle Meta Explorer</span>
</div>
</div>
<div class="search-box" style="display: flex; gap: 0.5rem;">
<label for="searchInput" class="sr-only">Search blockchain explorer</label>
<input type="text" class="search-input" id="searchInput" placeholder="Address, tx hash, block number, or token/contract name..." aria-label="Search blockchain explorer" aria-describedby="search-help-text" style="flex: 1;">
<button id="searchBtn" class="btn btn-primary" style="padding: 0.5rem 1rem; white-space: nowrap;" aria-label="Search">
<i class="fas fa-search"></i>
</a>
<div class="search-box" style="display: flex; gap: 0.5rem; align-items: center;">
<button id="searchLauncherBtn" type="button" class="btn btn-primary" style="padding: 0.5rem 1rem; white-space: nowrap;" aria-label="Open explorer search">
<i class="fas fa-search" aria-hidden="true"></i>
<span class="search-label" style="margin-left: 0.4rem;">Search</span>
</button>
<span id="search-help-text" class="sr-only">Search by address (0x...40 hex), transaction hash (0x...64 hex), block number, or token/contract name</span>
<span class="search-hint" style="font-size: 0.82rem; opacity: 0.9;">Press <strong>/</strong> or <strong>Ctrl+K</strong></span>
</div>
<button type="button" class="nav-toggle" id="navToggle" aria-label="Toggle menu" aria-expanded="false"><i class="fas fa-bars" id="navToggleIcon"></i></button>
<ul class="nav-links" id="navLinks">
@@ -880,6 +1029,7 @@
<li role="none"><a href="/home" role="menuitem" onclick="event.preventDefault(); showHome(); updatePath('/home'); closeNavMenu();" aria-label="Navigate to home page"><i class="fas fa-home" aria-hidden="true"></i> <span data-i18n="home">Home</span></a></li>
<li role="none"><a href="/blocks" role="menuitem" onclick="event.preventDefault(); showBlocks(); updatePath('/blocks'); closeNavMenu();" aria-label="View all blocks"><i class="fas fa-cubes" aria-hidden="true"></i> <span data-i18n="blocks">Blocks</span></a></li>
<li role="none"><a href="/transactions" role="menuitem" onclick="event.preventDefault(); showTransactions(); updatePath('/transactions'); closeNavMenu();" aria-label="View all transactions"><i class="fas fa-exchange-alt" aria-hidden="true"></i> <span data-i18n="transactions">Transactions</span></a></li>
<li role="none"><a href="/addresses" role="menuitem" onclick="event.preventDefault(); showAddresses(); updatePath('/addresses'); closeNavMenu();" aria-label="View all addresses"><i class="fas fa-address-book" aria-hidden="true"></i> <span data-i18n="addresses">Addresses</span></a></li>
</ul>
</li>
<li class="nav-dropdown" id="navDropdownTools">
@@ -887,15 +1037,16 @@
<ul class="nav-dropdown-menu" id="navMenuTools" role="menu">
<li role="none"><a href="/bridge" role="menuitem" onclick="event.preventDefault(); showBridgeMonitoring(); updatePath('/bridge'); closeNavMenu();" aria-label="View bridge monitoring"><i class="fas fa-bridge" aria-hidden="true"></i> <span data-i18n="bridge">Bridge</span></a></li>
<li role="none"><a href="/weth" role="menuitem" onclick="event.preventDefault(); showWETHUtilities(); updatePath('/weth'); closeNavMenu();" aria-label="View WETH utilities"><i class="fas fa-coins" aria-hidden="true"></i> <span data-i18n="weth">WETH</span></a></li>
<li role="none"><a href="/liquidity" role="menuitem" onclick="event.preventDefault(); showLiquidityAccess(); updatePath('/liquidity'); closeNavMenu();" aria-label="View liquidity access"><i class="fas fa-wave-square" aria-hidden="true"></i> <span>Liquidity</span></a></li>
<li role="none"><a href="/tokens" role="menuitem" onclick="event.preventDefault(); if(typeof showTokensList==='function')showTokensList();else focusSearchWithHint('token'); updatePath('/tokens'); closeNavMenu();" aria-label="View token list"><i class="fas fa-tag" aria-hidden="true"></i> <span data-i18n="tokens">Tokens</span></a></li>
<li role="none"><a href="/pools" role="menuitem" onclick="event.preventDefault(); showPools(); updatePath('/pools'); closeNavMenu();" aria-label="View pools"><i class="fas fa-water" aria-hidden="true"></i> <span data-i18n="pools">Pools</span></a></li>
<li role="none"><a href="/pools" role="menuitem" onclick="event.preventDefault(); showPools(); updatePath('/pools'); closeNavMenu();" aria-label="View pools"><i class="fas fa-water" aria-hidden="true"></i> <span data-i18n="pools">Pools</span> <span id="poolsMissingQuoteBadge" class="badge badge-warning" style="display:none; margin-left:0.35rem; vertical-align:middle;">0</span></a></li>
<li role="none"><a href="/watchlist" role="menuitem" onclick="event.preventDefault(); showWatchlist(); updatePath('/watchlist'); closeNavMenu();" aria-label="Watchlist"><i class="fas fa-star" aria-hidden="true"></i> <span data-i18n="watchlist">Watchlist</span></a></li>
</ul>
</li>
<li><a href="/snap/" target="_self" rel="noopener" aria-label="Chain 138 MetaMask Snap"><i class="fas fa-wallet" aria-hidden="true"></i> <span>MetaMask Snap</span></a></li>
<li role="none"><a href="/more" role="menuitem" onclick="event.preventDefault(); showMore(); updatePath('/more'); closeNavMenu();" aria-label="View more pages"><i class="fas fa-ellipsis-h" aria-hidden="true"></i> <span data-i18n="more">More</span></a></li>
</ul>
<div style="display: flex; align-items: center; gap: 0.75rem;">
<div class="nav-actions">
<select id="localeSelect" onchange="setLocale(this.value)" style="padding: 0.35rem 0.5rem; border-radius: 6px; background: rgba(255,255,255,0.2); color: white; border: 1px solid rgba(255,255,255,0.3); font-size: 0.875rem;" aria-label="Language">
<option value="en">EN</option>
<option value="de">DE</option>
@@ -912,6 +1063,64 @@
</div>
</nav>
<div id="smartSearchModal" class="smart-search-modal" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="smartSearchTitle" style="display:none; position:fixed; inset:0; z-index:20000;">
<div id="smartSearchBackdrop" style="position:absolute; inset:0; background: rgba(8, 15, 32, 0.62); backdrop-filter: blur(10px);"></div>
<div style="position:relative; z-index:1; display:flex; justify-content:center; align-items:flex-start; padding: 6vh 1rem 2rem; min-height:100%;">
<div style="width:min(920px, 100%); background: var(--card-bg, var(--light)); color: var(--text); border:1px solid var(--border); border-radius: 24px; box-shadow: 0 24px 80px rgba(0,0,0,0.35); overflow:hidden;">
<div style="padding: 1.1rem 1.25rem; border-bottom:1px solid var(--border); display:flex; align-items:flex-start; justify-content:space-between; gap:1rem;">
<div>
<div id="smartSearchTitle" style="font-size:1.05rem; font-weight:700;">Search Explorer</div>
<div style="margin-top:0.3rem; color:var(--text-light); font-size:0.9rem;">Type an address, transaction, block, token, or contract. Press Esc to close.</div>
</div>
<div style="display:flex; gap:0.5rem; align-items:center;">
<span style="padding:0.3rem 0.55rem; border:1px solid var(--border); border-radius:999px; font-size:0.8rem; color:var(--text-light);">Esc</span>
<button id="smartSearchCloseBtn" type="button" class="btn btn-secondary" style="padding:0.45rem 0.75rem;">Close</button>
</div>
</div>
<div style="padding:1.1rem 1.25rem 1.25rem;">
<div style="display:grid; grid-template-columns: 160px minmax(0, 1fr); gap:1rem; align-items:start;">
<aside style="border:1px solid var(--border); border-radius:18px; background: linear-gradient(180deg, rgba(0,0,0,0.02), rgba(0,0,0,0.05)); padding:0.9rem; position:sticky; top:1rem;">
<div style="font-size:0.78rem; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-light); margin-bottom:0.65rem;">Quick Filters</div>
<div style="display:grid; gap:0.5rem;">
<button type="button" class="btn btn-secondary smart-search-scope-btn" data-scope="all" onclick="setSmartSearchScope('all'); updateSmartSearchPreview(document.getElementById('smartSearchInput') ? document.getElementById('smartSearchInput').value : '')" style="justify-content:flex-start; padding:0.62rem 0.75rem;">All</button>
<button type="button" class="btn btn-secondary smart-search-scope-btn" data-scope="addresses" onclick="setSmartSearchScope('addresses'); updateSmartSearchPreview(document.getElementById('smartSearchInput') ? document.getElementById('smartSearchInput').value : '')" style="justify-content:flex-start; padding:0.62rem 0.75rem;">Addresses</button>
<button type="button" class="btn btn-secondary smart-search-scope-btn" data-scope="tokens" onclick="setSmartSearchScope('tokens'); updateSmartSearchPreview(document.getElementById('smartSearchInput') ? document.getElementById('smartSearchInput').value : '')" style="justify-content:flex-start; padding:0.62rem 0.75rem;">Tokens</button>
<button type="button" class="btn btn-secondary smart-search-scope-btn" data-scope="blocks" onclick="setSmartSearchScope('blocks'); updateSmartSearchPreview(document.getElementById('smartSearchInput') ? document.getElementById('smartSearchInput').value : '')" style="justify-content:flex-start; padding:0.62rem 0.75rem;">Blocks</button>
<button type="button" class="btn btn-secondary smart-search-scope-btn" data-scope="transactions" onclick="setSmartSearchScope('transactions'); updateSmartSearchPreview(document.getElementById('smartSearchInput') ? document.getElementById('smartSearchInput').value : '')" style="justify-content:flex-start; padding:0.62rem 0.75rem;">Transactions</button>
</div>
<div style="margin-top:0.9rem; padding-top:0.9rem; border-top:1px solid var(--border);">
<div style="font-size:0.78rem; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-light); margin-bottom:0.55rem;">Mode</div>
<div id="smartSearchDetected" class="badge" style="display:inline-block; background: var(--accent, #2563eb); color:#fff;">All</div>
</div>
<div style="margin-top:0.9rem; padding-top:0.9rem; border-top:1px solid var(--border);">
<div style="font-size:0.78rem; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-light); margin-bottom:0.55rem;">Keys</div>
<div style="display:grid; gap:0.45rem; color:var(--text-light); font-size:0.84rem; line-height:1.45;">
<div style="display:flex; justify-content:space-between; gap:0.75rem;"><span>Tab</span><span>Move focus</span></div>
<div style="display:flex; justify-content:space-between; gap:0.75rem;"><span>Enter</span><span>Run search</span></div>
<div style="display:flex; justify-content:space-between; gap:0.75rem;"><span>Esc</span><span>Close</span></div>
</div>
</div>
</aside>
<main style="min-width:0;">
<label for="smartSearchInput" class="sr-only">Search blockchain explorer</label>
<div style="display:flex; gap:0.75rem; align-items:center; padding:0.9rem 1rem; border:1px solid var(--border); border-radius:16px; background: var(--light);">
<i class="fas fa-search" aria-hidden="true" style="color:var(--text-light);"></i>
<input type="text" id="smartSearchInput" placeholder="Search address, tx, block, token, contract..." aria-label="Search blockchain explorer" autocomplete="off" spellcheck="false" style="flex:1; border:none; background:transparent; outline:none; color:var(--text); font-size:1rem;">
<button id="smartSearchSubmitBtn" type="button" class="btn btn-primary" style="padding:0.5rem 0.85rem;">Search</button>
</div>
<div style="display:flex; flex-wrap:wrap; gap:0.5rem; margin-top:0.85rem; align-items:center;">
<span style="color:var(--text-light); font-size:0.88rem;">Recent searches, trending tokens, and scoped matches appear below.</span>
</div>
<div id="smartSearchPreview" style="margin-top:1rem; display:grid; gap:1rem;">
<div class="loading"><i class="fas fa-spinner"></i> Waiting for a query...</div>
</div>
</main>
</div>
</div>
</div>
</div>
</div>
<div id="explorerLiveRegion" aria-live="polite" aria-atomic="true" class="sr-only" role="status"></div>
<div class="container" id="mainContent">
<!-- Home View -->
@@ -920,22 +1129,26 @@
<!-- Stats loaded dynamically -->
</div>
<div class="card" id="gasNetworkCard" style="margin-bottom: 1rem;">
<div class="card-header">
<h2 class="card-title"><i class="fas fa-gas-pump"></i> Gas &amp; Network</h2>
<button type="button" class="btn btn-secondary" onclick="loadGasAndNetworkStats()" aria-label="Refresh gas and network"><i class="fas fa-sync-alt"></i> Refresh</button>
</div>
<div id="gasNetworkContent">
<div>
<div style="font-size: 0.875rem; color: var(--text-light); margin-bottom: 0.25rem;">Current base fee</div>
<div id="gasCurrentValue" style="font-size: 1.5rem; font-weight: 600;"></div>
<div style="margin-top: 0.75rem; font-size: 0.875rem;">TPS: <span id="gasTpsValue"></span></div>
<div style="font-size: 0.875rem;">Block time: <span id="gasBlockTimeValue"></span></div>
<div style="font-size: 0.875rem; margin-top: 0.25rem;">Failed (recent): <span id="gasFailedRateValue"></span></div>
<div class="card gas-network-card" id="gasNetworkCard">
<div class="card-header gas-network-header">
<div class="gas-network-row">
<h2 class="card-title"><i class="fas fa-gas-pump"></i> Gas &amp; Network</h2>
<button type="button" class="btn btn-secondary" onclick="loadGasAndNetworkStats()" aria-label="Refresh gas and network"><i class="fas fa-sync-alt"></i> Refresh</button>
</div>
<div>
<div style="font-size: 0.875rem; color: var(--text-light); margin-bottom: 0.5rem;">Gas history (last 10 blocks)</div>
<div id="gasHistoryBars" style="display: flex; align-items: flex-end; gap: 4px; height: 60px;"></div>
<div class="gas-network-row">
<div class="gas-network-compact">
<div class="gas-network-pill"><span class="gas-network-subtle">Base fee</span> <strong id="gasCurrentValue"></strong></div>
<div class="gas-network-pill"><span class="gas-network-subtle">Block time</span> <strong id="gasBlockTimeValue"></strong></div>
<div class="gas-network-pill"><span class="gas-network-subtle">TPS</span> <strong id="gasTpsValue"></strong></div>
<div class="gas-network-pill"><span class="gas-network-subtle">Failed</span> <strong id="gasFailedRateValue"></strong></div>
</div>
<div style="display:flex; align-items:center; gap:0.75rem; flex-wrap:wrap;">
<div>
<div style="font-size: 0.78rem; color: var(--text-light); margin-bottom: 0.25rem;">History (10 blocks)</div>
<div id="gasHistoryBars" class="gas-network-spark"></div>
</div>
<div id="gasNetworkSummary" class="gas-network-subtle">Live chain health for Chain 138.</div>
</div>
</div>
</div>
</div>
@@ -1178,11 +1391,22 @@
</div>
</div>
<div id="addressesView" class="detail-view">
<div class="card">
<div class="card-header">
<h2 class="card-title">All Addresses</h2>
</div>
<div id="addressesList">
<div class="loading"><i class="fas fa-spinner"></i> Loading addresses...</div>
</div>
</div>
</div>
<div id="addressDetailView" class="detail-view">
<div class="breadcrumb" id="addressDetailBreadcrumb"></div>
<div class="card">
<div class="card-header">
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back to home page"><i class="fas fa-arrow-left" aria-hidden="true"></i> Back</button>
<button class="btn btn-secondary" onclick="showAddresses()" aria-label="Go back to addresses list"><i class="fas fa-arrow-left" aria-hidden="true"></i> Back</button>
<h2 class="card-title">Address Details</h2>
</div>
<div id="addressDetail"></div>
@@ -1252,6 +1476,10 @@
<div class="card-header">
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back to home page"><i class="fas fa-arrow-left" aria-hidden="true"></i> Back</button>
<h2 class="card-title"><i class="fas fa-water"></i> Pools</h2>
<div style="display:flex; gap:0.5rem; margin-left:auto; flex-wrap:wrap;">
<button type="button" class="btn btn-primary" onclick="exportPoolsCSV()" style="padding: 0.5rem 1rem;"><i class="fas fa-file-csv"></i> Export CSV</button>
<button type="button" class="btn btn-secondary" onclick="exportPoolsJSON()" style="padding: 0.5rem 1rem;"><i class="fas fa-download"></i> Export JSON</button>
</div>
</div>
<div id="poolsContent">
<div class="loading"><i class="fas fa-spinner"></i> Loading pools...</div>
@@ -1259,6 +1487,22 @@
</div>
</div>
<div id="liquidityView" class="detail-view">
<div class="breadcrumb" id="liquidityBreadcrumb"><a href="/home">Home</a><span class="breadcrumb-separator">/</span><span class="breadcrumb-current">Liquidity</span></div>
<div class="card">
<div class="card-header">
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back to home page"><i class="fas fa-arrow-left" aria-hidden="true"></i> Back</button>
<h2 class="card-title"><i class="fas fa-wave-square"></i> Liquidity Access</h2>
<div style="display:flex; gap:0.5rem; margin-left:auto; flex-wrap:wrap;">
<button type="button" class="btn btn-primary" onclick="renderLiquidityAccessView()" style="padding: 0.5rem 1rem;"><i class="fas fa-sync-alt"></i> Refresh</button>
</div>
</div>
<div id="liquidityContent">
<div class="loading"><i class="fas fa-spinner"></i> Loading liquidity access...</div>
</div>
</div>
</div>
<div id="moreView" class="detail-view">
<div class="breadcrumb" id="moreBreadcrumb"><a href="/home">Home</a><span class="breadcrumb-separator">/</span><span class="breadcrumb-current">More</span></div>
<div class="card">
@@ -1297,6 +1541,41 @@
</div>
</div>
<script src="/explorer-spa.js?v=16"></script>
<footer class="site-footer">
<div class="container">
<div class="site-footer-grid">
<div>
<div style="font-size: 1.05rem; font-weight: 700; margin-bottom: 0.5rem;">SolaceScanScout</div>
<div class="site-footer-note">
Built on Blockscout foundations and Solace Bank Group PLC frontend development.
Explorer data, block indexing, and public chain visibility are powered by Blockscout,
Chain 138 RPC, and the MetaMask Snap companion.
</div>
<div class="site-footer-note" style="margin-top: 0.8rem;">
© 2026 Solace Bank Group PLC. All rights reserved.
</div>
</div>
<div>
<div class="site-footer-title">Documentation</div>
<div class="site-footer-links">
<a href="/docs.html">Docs landing page</a>
<a href="/liquidity">Liquidity access</a>
<a href="/privacy.html">Privacy Policy</a>
<a href="/terms.html">Terms of Service</a>
</div>
</div>
<div>
<div class="site-footer-title">Acknowledgments & Contact</div>
<div class="site-footer-links">
<a href="/acknowledgments.html">Acknowledgments</a>
<a href="mailto:support@d-bis.org">support@d-bis.org</a>
<a href="/snap/">MetaMask Snap companion</a>
</div>
</div>
</div>
</div>
</footer>
<script src="/explorer-spa.js?v=28"></script>
</body>
</html>