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

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Acknowledgments | SolaceScanScout</title>
<meta name="description" content="Acknowledgments for the SolaceScanScout explorer.">
<style>
body { margin: 0; font-family: Arial, Helvetica, sans-serif; background: linear-gradient(180deg, #0f172a 0%, #111827 45%, #f8fafc 46%, #ffffff 100%); color: #0f172a; }
.shell { max-width: 980px; margin: 0 auto; padding: 2rem 1rem 3rem; }
.card { background: #fff; border: 1px solid #e5e7eb; border-radius: 20px; padding: 1.5rem; box-shadow: 0 18px 60px rgba(15,23,42,0.12); }
a { color: #2563eb; text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: #64748b; }
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.brand { color: #fff; font-weight: 700; }
</style>
</head>
<body>
<div class="shell">
<div class="topbar">
<div class="brand">SolaceScanScout Acknowledgments</div>
<a href="/">Back to explorer</a>
</div>
<div class="card">
<h1 style="margin-top:0;">Acknowledgments</h1>
<p class="muted">This explorer and its companion tools are built with help from the open-source and infrastructure tools below.</p>
<ul>
<li><strong>Blockscout</strong> for explorer indexing and API compatibility.</li>
<li><strong>MetaMask</strong> for wallet connectivity and Snap support.</li>
<li><strong>Chainlink CCIP</strong> for bridge-related routing and transport.</li>
<li><strong>ethers.js</strong> for wallet and Ethereum interaction support.</li>
<li><strong>Font Awesome</strong> for iconography.</li>
<li><strong>Next.js</strong> and the frontend contributors at Solace Bank Group PLC.</li>
</ul>
<p class="muted">If we have missed a contributor or dependency, please let us know at <a href="mailto:support@d-bis.org">support@d-bis.org</a>.</p>
</div>
</div>
</body>
</html>

54
frontend/public/docs.html Normal file
View File

@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documentation | SolaceScanScout</title>
<meta name="description" content="Documentation landing page for the SolaceScanScout explorer.">
<style>
body { margin: 0; font-family: Arial, Helvetica, sans-serif; background: linear-gradient(180deg, #0f172a 0%, #111827 45%, #f8fafc 46%, #ffffff 100%); color: #0f172a; }
.shell { max-width: 980px; margin: 0 auto; padding: 2rem 1rem 3rem; }
.card { background: #fff; border: 1px solid #e5e7eb; border-radius: 20px; padding: 1.5rem; box-shadow: 0 18px 60px rgba(15,23,42,0.12); }
a { color: #2563eb; text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: #64748b; }
.grid { display: grid; gap: 0.85rem; }
.link { display: block; padding: 0.85rem 1rem; border: 1px solid #e5e7eb; border-radius: 14px; background: #f8fafc; }
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.brand { color: #fff; font-weight: 700; }
</style>
</head>
<body>
<div class="shell">
<div class="topbar">
<div class="brand">SolaceScanScout Documentation</div>
<a href="/">Back to explorer</a>
</div>
<div class="card">
<h1 style="margin-top:0;">Documentation</h1>
<p class="muted">This landing page collects the key explorer and deployment references used by the SolaceScanScout stack.</p>
<div class="grid" style="margin-top:1rem;">
<a class="link" href="/privacy.html">Privacy Policy</a>
<a class="link" href="/terms.html">Terms of Service</a>
<a class="link" href="/acknowledgments.html">Acknowledgments</a>
<a class="link" href="/liquidity">
<strong>Liquidity access</strong>
<div class="muted" style="margin-top:0.35rem;">Public Chain 138 pool snapshot, live Mainnet stable bridge paths, route matrix links, partner payload templates, and the internal fallback execution plan endpoint.</div>
</a>
<div class="link">
<strong>Repository docs</strong>
<div class="muted" style="margin-top:0.35rem;">The full technical documentation lives in the repository's <code>docs/</code> directory, including API access, deployment, and explorer guidance.</div>
</div>
<div class="link">
<strong>Public routing API base</strong>
<div class="muted" style="margin-top:0.35rem;"><code>/token-aggregation/api/v1</code> on <code>explorer.d-bis.org</code> is the public access path for route discovery, partner payload generation, and internal execution planning.</div>
</div>
<div class="link">
<strong>Need help?</strong>
<div class="muted" style="margin-top:0.35rem;">Email <a href="mailto:support@d-bis.org">support@d-bis.org</a> for explorer-related questions.</div>
</div>
</div>
</div>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

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>

View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Privacy Policy | SolaceScanScout</title>
<meta name="description" content="Privacy policy for the SolaceScanScout explorer.">
<style>
body { margin: 0; font-family: Arial, Helvetica, sans-serif; background: linear-gradient(180deg, #0f172a 0%, #111827 45%, #f8fafc 46%, #ffffff 100%); color: #0f172a; }
.shell { max-width: 980px; margin: 0 auto; padding: 2rem 1rem 3rem; }
.card { background: #fff; border: 1px solid #e5e7eb; border-radius: 20px; padding: 1.5rem; box-shadow: 0 18px 60px rgba(15,23,42,0.12); }
a { color: #2563eb; text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: #64748b; }
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.brand { color: #fff; font-weight: 700; }
</style>
</head>
<body>
<div class="shell">
<div class="topbar">
<div class="brand">SolaceScanScout Privacy Policy</div>
<a href="/">Back to explorer</a>
</div>
<div class="card">
<h1 style="margin-top:0;">Privacy Policy</h1>
<p class="muted">Last updated: 2026-03-25</p>
<p>SolaceScanScout is a blockchain explorer. Most content you view comes from public blockchain data and public APIs. We do not ask for personal information to browse the explorer.</p>
<ul>
<li>We may store theme preference, locale, recent searches, and similar local UI settings in your browser.</li>
<li>When you use wallet features or the Snap companion, the app may interact with your wallet provider to complete the request you initiate.</li>
<li>Explorer queries are sent to the configured blockchain APIs and RPC endpoints so the site can display blocks, transactions, addresses, and related data.</li>
<li>We do not sell personal data. We also do not intentionally track users with advertising cookies on this explorer.</li>
</ul>
<p>If you have privacy questions, contact <a href="mailto:support@d-bis.org">support@d-bis.org</a>.</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Terms of Service | SolaceScanScout</title>
<meta name="description" content="Terms of service for the SolaceScanScout explorer.">
<style>
body { margin: 0; font-family: Arial, Helvetica, sans-serif; background: linear-gradient(180deg, #0f172a 0%, #111827 45%, #f8fafc 46%, #ffffff 100%); color: #0f172a; }
.shell { max-width: 980px; margin: 0 auto; padding: 2rem 1rem 3rem; }
.card { background: #fff; border: 1px solid #e5e7eb; border-radius: 20px; padding: 1.5rem; box-shadow: 0 18px 60px rgba(15,23,42,0.12); }
a { color: #2563eb; text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: #64748b; }
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.brand { color: #fff; font-weight: 700; }
</style>
</head>
<body>
<div class="shell">
<div class="topbar">
<div class="brand">SolaceScanScout Terms of Service</div>
<a href="/">Back to explorer</a>
</div>
<div class="card">
<h1 style="margin-top:0;">Terms of Service</h1>
<p class="muted">Last updated: 2026-03-25</p>
<p>This explorer is provided for informational and operational purposes. By using it, you agree that:</p>
<ul>
<li>Blockchain data may be delayed, incomplete, or temporarily unavailable.</li>
<li>You are responsible for verifying addresses, transactions, and contract details before acting on them.</li>
<li>We may update features, endpoints, and policies as the explorer evolves.</li>
<li>The explorer is not legal, financial, or tax advice.</li>
</ul>
<p>For service questions, contact <a href="mailto:support@d-bis.org">support@d-bis.org</a>.</p>
</div>
</div>
</body>
</html>