1600 lines
79 KiB
HTML
1600 lines
79 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
<meta http-equiv="Pragma" content="no-cache">
|
|
<meta http-equiv="Expires" content="0">
|
|
<!-- CSP: unsafe-eval required by ethers.js v5 UMD from CDN (uses new Function for ABI). Our code avoids eval/string setTimeout. Can be removed when moving to ethers v6 build (no UMD eval). -->
|
|
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://unpkg.com https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; font-src 'self' https://cdnjs.cloudflare.com; img-src 'self' data: https:; connect-src 'self' https://explorer.d-bis.org https://rpc-http-pub.d-bis.org wss://rpc-ws-pub.d-bis.org http://192.168.11.221:8545 ws://192.168.11.221:8546;">
|
|
<title>SolaceScanScout | The Defi Oracle Meta Explorer | d-bis.org</title>
|
|
<meta name="description" content="SolaceScanScout - The Defi Oracle Meta Explorer. Comprehensive blockchain explorer for ChainID 138 with cross-chain bridge monitoring, WETH utilities, and real-time transaction tracking.">
|
|
<meta name="keywords" content="blockchain explorer, ChainID 138, CCIP bridge, WETH, DeFi Oracle, SolaceScanScout, blockchain, ethereum, blockscout">
|
|
<meta name="author" content="SolaceScanScout">
|
|
<meta name="application-name" content="SolaceScanScout">
|
|
<meta name="theme-color" content="#667eea">
|
|
<script>
|
|
(function(){function t(){var e=document.getElementById('navLinks'),n=document.getElementById('navToggle'),r=document.getElementById('navToggleIcon');if(e&&n){var o=e.classList.toggle('nav-open');n.setAttribute('aria-expanded',o?'true':'false');if(r)r.className=o?'fas fa-times':'fas fa-bars';}}function c(){var e=document.getElementById('navLinks'),n=document.getElementById('navToggle'),r=document.getElementById('navToggleIcon');if(e)e.classList.remove('nav-open');if(n)n.setAttribute('aria-expanded','false');if(r)r.className='fas fa-bars';}window.toggleNavMenu=t;window.closeNavMenu=c;})();
|
|
</script>
|
|
<!-- Open Graph / Facebook -->
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:url" content="https://explorer.d-bis.org/">
|
|
<meta property="og:title" content="SolaceScanScout - The Defi Oracle Meta Explorer">
|
|
<meta property="og:description" content="Comprehensive blockchain explorer for ChainID 138 with cross-chain bridge monitoring and WETH utilities.">
|
|
<meta property="og:image" content="https://explorer.d-bis.org/og-image.png">
|
|
<meta property="og:site_name" content="SolaceScanScout">
|
|
|
|
<!-- Twitter -->
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<meta name="twitter:url" content="https://explorer.d-bis.org/">
|
|
<meta name="twitter:title" content="SolaceScanScout - The Defi Oracle Meta Explorer">
|
|
<meta name="twitter:description" content="Comprehensive blockchain explorer for ChainID 138 with cross-chain bridge monitoring and WETH utilities.">
|
|
<meta name="twitter:image" content="https://explorer.d-bis.org/og-image.png">
|
|
|
|
<!-- Favicon -->
|
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<!-- Load ethers.js with multiple fallback CDNs -->
|
|
<script>
|
|
(function() {
|
|
var ethersLoaded = false;
|
|
var cdnIndex = 0;
|
|
var cdns = [
|
|
'https://cdn.jsdelivr.net/npm/ethers@5.7.2/dist/ethers.umd.min.js',
|
|
'https://unpkg.com/ethers@5.7.2/dist/ethers.umd.min.js',
|
|
'https://cdnjs.cloudflare.com/ajax/libs/ethers/5.7.2/ethers.umd.min.js'
|
|
];
|
|
|
|
function loadEthers() {
|
|
if (ethersLoaded || typeof ethers !== 'undefined') {
|
|
window.ethersReady = true;
|
|
console.log('✅ Ethers.js library loaded successfully');
|
|
window.dispatchEvent(new Event('ethersReady'));
|
|
return;
|
|
}
|
|
|
|
if (cdnIndex >= cdns.length) {
|
|
console.error('❌ All ethers.js CDNs failed to load');
|
|
// Try one more time with a different approach
|
|
setTimeout(function() {
|
|
if (typeof ethers === 'undefined') {
|
|
console.error('Ethers.js failed to load from all sources');
|
|
} else {
|
|
window.ethersReady = true;
|
|
window.dispatchEvent(new Event('ethersReady'));
|
|
}
|
|
}, 1000);
|
|
return;
|
|
}
|
|
|
|
var script = document.createElement('script');
|
|
script.src = cdns[cdnIndex];
|
|
script.async = false; // Load synchronously to ensure it's available
|
|
|
|
script.onload = function() {
|
|
// Double check after load
|
|
setTimeout(function() {
|
|
if (typeof ethers !== 'undefined') {
|
|
ethersLoaded = true;
|
|
window.ethersReady = true;
|
|
console.log('✅ Ethers.js loaded from:', cdns[cdnIndex]);
|
|
window.dispatchEvent(new Event('ethersReady'));
|
|
} else {
|
|
console.warn('Script loaded but ethers not defined, trying next CDN...');
|
|
cdnIndex++;
|
|
loadEthers();
|
|
}
|
|
}, 100);
|
|
};
|
|
|
|
script.onerror = function() {
|
|
console.warn('Failed to load from:', cdns[cdnIndex]);
|
|
cdnIndex++;
|
|
loadEthers();
|
|
};
|
|
|
|
document.head.appendChild(script);
|
|
}
|
|
|
|
// Start loading immediately
|
|
loadEthers();
|
|
|
|
// Also check periodically in case it loads via another method
|
|
var checkInterval = setInterval(function() {
|
|
if (typeof ethers !== 'undefined' && !ethersLoaded) {
|
|
clearInterval(checkInterval);
|
|
ethersLoaded = true;
|
|
window.ethersReady = true;
|
|
console.log('✅ Ethers.js detected');
|
|
window.dispatchEvent(new Event('ethersReady'));
|
|
}
|
|
}, 100);
|
|
|
|
// Clear interval after 20 seconds
|
|
setTimeout(function() {
|
|
clearInterval(checkInterval);
|
|
}, 20000);
|
|
})();
|
|
</script>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
:root {
|
|
--primary: #667eea;
|
|
--secondary: #764ba2;
|
|
--success: #10b981;
|
|
--warning: #f59e0b;
|
|
--danger: #ef4444;
|
|
--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;
|
|
background: #0f172a;
|
|
color: var(--text);
|
|
}
|
|
body.dark-theme .stat-card,
|
|
body.dark-theme .card,
|
|
body.dark-theme .block-card {
|
|
background: #1e293b;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
}
|
|
body.dark-theme .table th { background: #334155; color: var(--text); }
|
|
body.dark-theme .table tr:hover { background: #1e293b; }
|
|
body.dark-theme .skeleton { background: linear-gradient(90deg, #334155 25%, #475569 50%, #334155 75%); }
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
background: var(--light);
|
|
color: var(--text);
|
|
line-height: 1.6;
|
|
}
|
|
.navbar {
|
|
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
|
|
color: white;
|
|
padding: 0.85rem 2rem;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 1000;
|
|
}
|
|
.nav-container {
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
display: flex;
|
|
gap: 1rem;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
.logo {
|
|
font-size: 1.5rem;
|
|
font-weight: bold;
|
|
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;
|
|
gap: 0.5rem;
|
|
list-style: none;
|
|
align-items: center;
|
|
}
|
|
.nav-links > li { position: relative; }
|
|
.nav-links a, .nav-dropdown-trigger {
|
|
color: white;
|
|
text-decoration: none;
|
|
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: 1; background: rgba(255,255,255,0.12); }
|
|
.nav-dropdown-trigger {
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
font: inherit;
|
|
padding: 0.45rem 0.7rem;
|
|
}
|
|
.nav-dropdown-trigger i.fa-chevron-down {
|
|
font-size: 0.7rem;
|
|
transition: transform 0.2s;
|
|
}
|
|
.nav-dropdown.open .nav-dropdown-trigger i.fa-chevron-down { transform: rotate(180deg); }
|
|
.nav-dropdown-menu {
|
|
position: absolute;
|
|
top: 100%;
|
|
left: 0;
|
|
min-width: 200px;
|
|
background: rgba(30, 41, 59, 0.98);
|
|
border-radius: 8px;
|
|
box-shadow: 0 10px 40px rgba(0,0,0,0.25);
|
|
padding: 0.5rem 0;
|
|
list-style: none;
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transform: translateY(-6px);
|
|
transition: opacity 0.2s, transform 0.2s, visibility 0.2s;
|
|
z-index: 1001;
|
|
margin-top: 0.25rem;
|
|
}
|
|
.nav-dropdown.open .nav-dropdown-menu {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
transform: translateY(0);
|
|
}
|
|
.nav-dropdown-menu a {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.6rem 1rem;
|
|
color: rgba(255,255,255,0.95);
|
|
white-space: nowrap;
|
|
}
|
|
.nav-dropdown-menu a:hover {
|
|
background: rgba(255,255,255,0.1);
|
|
opacity: 1;
|
|
}
|
|
.nav-dropdown-menu li { margin: 0; }
|
|
.search-box {
|
|
flex: 1;
|
|
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%;
|
|
padding: 0.75rem 1rem;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 1rem;
|
|
background: rgba(255,255,255,0.2);
|
|
color: white;
|
|
backdrop-filter: blur(10px);
|
|
}
|
|
.search-input::placeholder { color: rgba(255,255,255,0.7); }
|
|
.search-input:focus {
|
|
outline: none;
|
|
background: rgba(255,255,255,0.3);
|
|
}
|
|
.container {
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
padding: 2rem;
|
|
}
|
|
.stats-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
gap: 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.stat-card {
|
|
background: white;
|
|
padding: 1rem;
|
|
border-radius: 12px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
transition: transform 0.2s, box-shadow 0.2s;
|
|
}
|
|
|
|
/* Block animation */
|
|
@keyframes blockPulse {
|
|
0%, 100% { transform: scale(1); opacity: 1; }
|
|
50% { transform: scale(1.02); opacity: 0.95; }
|
|
}
|
|
|
|
@keyframes slideInFromTop {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.table tbody tr {
|
|
animation: slideInFromTop 0.3s ease-out;
|
|
}
|
|
|
|
.table tbody tr.new-block {
|
|
animation: blockPulse 1s ease-in-out;
|
|
background: rgba(74, 144, 226, 0.05);
|
|
}
|
|
|
|
.table tbody tr.new-transaction {
|
|
animation: slideInFromTop 0.5s ease-out;
|
|
background: rgba(74, 144, 226, 0.05);
|
|
}
|
|
|
|
/* Horizontal scrolling blocks */
|
|
.blocks-scroll-container {
|
|
display: flex;
|
|
overflow-x: hidden;
|
|
overflow-y: hidden;
|
|
gap: 1rem;
|
|
padding: 0.5rem 0;
|
|
scroll-behavior: smooth;
|
|
-webkit-overflow-scrolling: touch;
|
|
scrollbar-width: none;
|
|
position: relative;
|
|
width: 100%;
|
|
}
|
|
|
|
.blocks-scroll-container::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.blocks-scroll-content {
|
|
display: flex;
|
|
gap: 1rem;
|
|
will-change: transform;
|
|
}
|
|
|
|
.blocks-scroll-container::-webkit-scrollbar {
|
|
height: 8px;
|
|
}
|
|
|
|
.blocks-scroll-container::-webkit-scrollbar-track {
|
|
background: var(--light);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.blocks-scroll-container::-webkit-scrollbar-thumb {
|
|
background: var(--primary);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.blocks-scroll-container::-webkit-scrollbar-thumb:hover {
|
|
background: var(--primary-dark);
|
|
}
|
|
|
|
.block-card {
|
|
min-width: 200px;
|
|
max-width: 200px;
|
|
background: white;
|
|
border-radius: 8px;
|
|
padding: 1rem;
|
|
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
|
cursor: pointer;
|
|
transition: transform 0.2s, box-shadow 0.2s;
|
|
border: 2px solid transparent;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.block-card:hover {
|
|
transform: translateY(-4px);
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
border-color: var(--primary);
|
|
}
|
|
|
|
.block-card.new-block {
|
|
animation: blockPulse 1s ease-in-out;
|
|
border-color: var(--primary);
|
|
background: rgba(74, 144, 226, 0.05);
|
|
}
|
|
|
|
.block-number {
|
|
font-size: 1.25rem;
|
|
font-weight: bold;
|
|
color: var(--primary);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.block-hash {
|
|
font-size: 0.75rem;
|
|
color: var(--text-light);
|
|
font-family: monospace;
|
|
margin-bottom: 0.5rem;
|
|
word-break: break-all;
|
|
}
|
|
|
|
.block-info {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.25rem;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.block-info-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
color: var(--text);
|
|
}
|
|
|
|
.block-info-label {
|
|
color: var(--text-light);
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.block-info-value {
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
}
|
|
.stat-card:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
}
|
|
.stat-card.bridge-card {
|
|
border-left: 4px solid var(--bridge-blue);
|
|
}
|
|
.stat-label {
|
|
color: var(--text-light);
|
|
font-size: 0.875rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.stat-value {
|
|
font-size: 2rem;
|
|
font-weight: bold;
|
|
color: var(--primary);
|
|
}
|
|
.stat-value.bridge-value {
|
|
color: var(--bridge-blue);
|
|
}
|
|
.card {
|
|
background: white;
|
|
border-radius: 12px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
padding: 1.25rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 0.75rem;
|
|
padding-bottom: 0.75rem;
|
|
border-bottom: 2px solid var(--border);
|
|
}
|
|
.card-title {
|
|
font-size: 1.5rem;
|
|
font-weight: bold;
|
|
color: var(--text);
|
|
}
|
|
.tabs {
|
|
display: flex;
|
|
gap: 1rem;
|
|
margin-bottom: 1.5rem;
|
|
border-bottom: 2px solid var(--border);
|
|
flex-wrap: wrap;
|
|
}
|
|
.tab {
|
|
padding: 1rem 1.5rem;
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
font-size: 1rem;
|
|
color: var(--text-light);
|
|
border-bottom: 3px solid transparent;
|
|
transition: all 0.2s;
|
|
}
|
|
.tab.active {
|
|
color: var(--primary);
|
|
border-bottom-color: var(--primary);
|
|
font-weight: 600;
|
|
}
|
|
.bridge-tab.active {
|
|
color: var(--bridge-blue);
|
|
border-bottom-color: var(--bridge-blue);
|
|
}
|
|
.weth-tab.active {
|
|
color: var(--success);
|
|
border-bottom-color: var(--success);
|
|
}
|
|
.table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
.table th {
|
|
text-align: left;
|
|
padding: 0.5rem 0.75rem;
|
|
background: var(--light);
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
border-bottom: 2px solid var(--border);
|
|
font-size: 0.875rem;
|
|
}
|
|
.table td {
|
|
padding: 0.5rem 0.75rem;
|
|
border-bottom: 1px solid var(--border);
|
|
font-size: 0.875rem;
|
|
}
|
|
.table tr:hover { background: var(--light); }
|
|
.hash {
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 0.875rem;
|
|
color: var(--primary);
|
|
word-break: break-all;
|
|
}
|
|
.hash:hover { text-decoration: underline; cursor: pointer; }
|
|
.badge {
|
|
display: inline-block;
|
|
padding: 0.25rem 0.75rem;
|
|
border-radius: 20px;
|
|
font-size: 0.875rem;
|
|
font-weight: 600;
|
|
}
|
|
.badge-success { background: #d1fae5; color: var(--success); }
|
|
.badge-warning { background: #fef3c7; color: var(--warning); }
|
|
.badge-danger { background: #fee2e2; color: var(--danger); }
|
|
.badge-chain {
|
|
background: #dbeafe;
|
|
color: var(--bridge-blue);
|
|
}
|
|
.loading {
|
|
text-align: center;
|
|
padding: 3rem;
|
|
color: var(--text-light);
|
|
}
|
|
.loading i {
|
|
font-size: 2rem;
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
@keyframes spin {
|
|
from { transform: rotate(0deg); }
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
/* Skeleton Loaders */
|
|
.skeleton {
|
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
|
background-size: 200% 100%;
|
|
animation: loading 1.5s ease-in-out infinite;
|
|
border-radius: 4px;
|
|
}
|
|
@keyframes loading {
|
|
0% { background-position: 200% 0; }
|
|
100% { background-position: -200% 0; }
|
|
}
|
|
.skeleton-text {
|
|
height: 1em;
|
|
margin: 0.5rem 0;
|
|
}
|
|
.skeleton-title {
|
|
height: 1.5em;
|
|
width: 60%;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.skeleton-table-row {
|
|
height: 3rem;
|
|
margin: 0.5rem 0;
|
|
}
|
|
/* Breadcrumb Navigation */
|
|
.breadcrumb {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 1rem 0;
|
|
margin-bottom: 1rem;
|
|
font-size: 0.9rem;
|
|
}
|
|
.breadcrumb a {
|
|
color: var(--primary);
|
|
text-decoration: none;
|
|
transition: opacity 0.2s;
|
|
}
|
|
.breadcrumb a:hover {
|
|
opacity: 0.7;
|
|
}
|
|
.breadcrumb-separator {
|
|
color: var(--text-light);
|
|
}
|
|
.breadcrumb-current {
|
|
color: var(--text);
|
|
font-weight: 600;
|
|
}
|
|
.error {
|
|
background: #fee2e2;
|
|
color: var(--danger);
|
|
padding: 1rem;
|
|
border-radius: 8px;
|
|
margin: 1rem 0;
|
|
}
|
|
.success {
|
|
background: #d1fae5;
|
|
color: var(--success);
|
|
padding: 1rem;
|
|
border-radius: 8px;
|
|
margin: 1rem 0;
|
|
}
|
|
.bridge-chain-card {
|
|
background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
|
|
padding: 1.5rem;
|
|
border-radius: 12px;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.weth-card {
|
|
background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
|
|
padding: 1.5rem;
|
|
border-radius: 12px;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.weth-form {
|
|
background: white;
|
|
padding: 1.5rem;
|
|
border-radius: 8px;
|
|
margin-top: 1rem;
|
|
}
|
|
.form-group {
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.form-label {
|
|
display: block;
|
|
margin-bottom: 0.5rem;
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
}
|
|
.form-input {
|
|
width: 100%;
|
|
padding: 0.75rem;
|
|
border: 2px solid var(--border);
|
|
border-radius: 8px;
|
|
font-size: 1rem;
|
|
transition: border-color 0.2s;
|
|
}
|
|
.form-input:focus {
|
|
outline: none;
|
|
border-color: var(--primary);
|
|
}
|
|
.form-input-group {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
}
|
|
.form-input-group .form-input {
|
|
flex: 1;
|
|
}
|
|
.btn {
|
|
padding: 0.75rem 1.5rem;
|
|
border: none;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
font-size: 1rem;
|
|
font-weight: 600;
|
|
transition: all 0.2s;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
.btn-primary {
|
|
background: var(--primary);
|
|
color: white;
|
|
}
|
|
.btn-primary:hover { background: var(--secondary); }
|
|
.btn-bridge {
|
|
background: var(--bridge-blue);
|
|
color: white;
|
|
}
|
|
.btn-bridge:hover { background: #2563eb; }
|
|
.btn-success {
|
|
background: var(--success);
|
|
color: white;
|
|
}
|
|
.btn-success:hover { background: #059669; }
|
|
.btn-warning {
|
|
background: var(--warning);
|
|
color: white;
|
|
}
|
|
.btn-warning:hover { background: #d97706; }
|
|
.btn:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
.btn-add-token-wallet {
|
|
padding: 0.35rem 0.5rem;
|
|
margin-left: 0.35rem;
|
|
border: none;
|
|
border-radius: 6px;
|
|
background: var(--primary);
|
|
color: white;
|
|
cursor: pointer;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
vertical-align: middle;
|
|
transition: background 0.2s;
|
|
}
|
|
.btn-add-token-wallet:hover {
|
|
background: var(--secondary);
|
|
}
|
|
.btn-add-token-wallet:focus {
|
|
outline: 2px solid var(--primary);
|
|
outline-offset: 2px;
|
|
}
|
|
.btn-add-token-wallet-prominent {
|
|
padding: 0.6rem 1rem;
|
|
font-size: 1rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
.balance-display {
|
|
background: var(--light);
|
|
padding: 1rem;
|
|
border-radius: 8px;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.balance-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 0.5rem 0;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
.balance-row:last-child {
|
|
border-bottom: none;
|
|
}
|
|
.balance-label {
|
|
color: var(--text-light);
|
|
}
|
|
.balance-value {
|
|
font-weight: bold;
|
|
color: var(--text);
|
|
}
|
|
.chain-name {
|
|
font-size: 1.25rem;
|
|
font-weight: bold;
|
|
color: var(--bridge-blue);
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.sr-only {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 1px;
|
|
padding: 0;
|
|
margin: -1px;
|
|
overflow: hidden;
|
|
clip: rect(0, 0, 0, 0);
|
|
white-space: nowrap;
|
|
border-width: 0;
|
|
}
|
|
.chain-info {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
gap: 1rem;
|
|
margin-top: 1rem;
|
|
}
|
|
.chain-stat {
|
|
font-size: 0.875rem;
|
|
}
|
|
.chain-stat-label {
|
|
color: var(--text-light);
|
|
}
|
|
.chain-stat-value {
|
|
font-weight: bold;
|
|
color: var(--text);
|
|
margin-top: 0.25rem;
|
|
}
|
|
.detail-view {
|
|
display: none;
|
|
}
|
|
.detail-view.active { display: block; }
|
|
.info-row {
|
|
display: flex;
|
|
padding: 1rem;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
.info-label {
|
|
font-weight: 600;
|
|
min-width: 200px;
|
|
color: var(--text-light);
|
|
}
|
|
.info-value {
|
|
flex: 1;
|
|
word-break: break-all;
|
|
}
|
|
.metamask-status {
|
|
padding: 1rem;
|
|
border-radius: 8px;
|
|
margin-bottom: 1rem;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
.metamask-status.connected {
|
|
background: #d1fae5;
|
|
color: var(--success);
|
|
}
|
|
.metamask-status.disconnected {
|
|
background: #fee2e2;
|
|
color: var(--danger);
|
|
}
|
|
.nav-toggle { display: none; background: none; border: none; color: white; padding: 0.5rem; cursor: pointer; font-size: 1.5rem; }
|
|
.nav-toggle:focus { outline: 2px solid rgba(255,255,255,0.5); }
|
|
@media (max-width: 900px) {
|
|
.nav-toggle { display: block; }
|
|
.nav-links { display: none; flex-direction: column; align-items: stretch; position: absolute; top: 100%; left: 0; right: 0; background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%); padding: 1rem; gap: 0; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 999; }
|
|
.nav-links.nav-open { display: flex; }
|
|
.nav-container { position: relative; flex-wrap: wrap; }
|
|
.nav-dropdown { position: static; }
|
|
.nav-dropdown-menu { position: static; opacity: 1; visibility: visible; transform: none; background: rgba(0,0,0,0.2); border-radius: 6px; margin: 0.25rem 0 0 0.5rem; padding: 0.25rem 0; max-height: 0; overflow: hidden; transition: max-height 0.2s; }
|
|
.nav-dropdown.open .nav-dropdown-menu { max-height: 400px; }
|
|
.nav-dropdown-trigger { width: 100%; justify-content: space-between; padding: 0.6rem 0.5rem; }
|
|
}
|
|
@media (max-width: 768px) {
|
|
.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; }
|
|
}
|
|
.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>
|
|
<script>
|
|
(function() {
|
|
function doToggleNav() {
|
|
var links = document.getElementById('navLinks');
|
|
var btn = document.getElementById('navToggle');
|
|
var icon = document.getElementById('navToggleIcon');
|
|
if (!links || !btn) return;
|
|
var isOpen = links.classList.toggle('nav-open');
|
|
btn.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
|
|
if (icon) icon.className = isOpen ? 'fas fa-times' : 'fas fa-bars';
|
|
}
|
|
function doCloseNav() {
|
|
var links = document.getElementById('navLinks');
|
|
var btn = document.getElementById('navToggle');
|
|
var icon = document.getElementById('navToggleIcon');
|
|
if (links) links.classList.remove('nav-open');
|
|
if (btn) btn.setAttribute('aria-expanded', 'false');
|
|
if (icon) icon.className = 'fas fa-bars';
|
|
}
|
|
window.toggleNavMenu = doToggleNav;
|
|
window.closeNavMenu = doCloseNav;
|
|
document.addEventListener('click', function(e) {
|
|
if (e.target.closest('#navToggle')) { doToggleNav(); }
|
|
});
|
|
})();
|
|
</script>
|
|
<nav class="navbar">
|
|
<div class="nav-container">
|
|
<a class="logo" href="/" 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>
|
|
</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 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">
|
|
<li class="nav-dropdown" id="navDropdownExplore">
|
|
<button type="button" class="nav-dropdown-trigger" aria-expanded="false" aria-haspopup="true" aria-controls="navMenuExplore" id="navTriggerExplore"><i class="fas fa-compass" aria-hidden="true"></i> <span data-i18n="explore">Explore</span> <i class="fas fa-chevron-down" aria-hidden="true"></i></button>
|
|
<ul class="nav-dropdown-menu" id="navMenuExplore" role="menu">
|
|
<li role="none"><a href="/" role="menuitem" onclick="event.preventDefault(); showHome(); updatePath('/'); 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">
|
|
<button type="button" class="nav-dropdown-trigger" aria-expanded="false" aria-haspopup="true" aria-controls="navMenuTools" id="navTriggerTools"><i class="fas fa-tools" aria-hidden="true"></i> <span data-i18n="tools">Tools</span> <i class="fas fa-chevron-down" aria-hidden="true"></i></button>
|
|
<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="/routes" role="menuitem" onclick="event.preventDefault(); showRoutes(); updatePath('/routes'); closeNavMenu();" aria-label="View route decision tree"><i class="fas fa-diagram-project" aria-hidden="true"></i> <span>Routes</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> <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/" 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 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>
|
|
<option value="fr">FR</option>
|
|
</select>
|
|
<button id="themeToggle" type="button" class="btn btn-primary" onclick="toggleDarkMode()" style="padding: 0.5rem 0.75rem; background: rgba(255,255,255,0.2);" aria-label="Toggle dark mode" title="Toggle dark/light theme"><i class="fas fa-moon" id="themeIcon"></i></button>
|
|
<div id="walletConnect" style="display: flex; align-items: center; gap: 0.5rem;">
|
|
<button id="walletConnectBtn" class="btn btn-primary" onclick="connectWallet()" style="display: none;" aria-label="Connect wallet">Connect Wallet</button>
|
|
<div id="walletStatus" style="display: none; padding: 0.5rem 1rem; background: var(--success); color: white; border-radius: 8px; font-size: 0.875rem;">
|
|
<i class="fas fa-wallet"></i> <span id="walletAddress"></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</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 -->
|
|
<div id="homeView">
|
|
<div class="stats-grid" id="statsGrid">
|
|
<!-- Stats loaded dynamically -->
|
|
</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 & 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 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>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2 class="card-title">Latest Blocks</h2>
|
|
<button class="btn btn-primary" onclick="showBlocks()" aria-label="View all blocks">View All</button>
|
|
</div>
|
|
<div id="latestBlocks">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading blocks...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2 class="card-title">Latest Transactions</h2>
|
|
<button class="btn btn-primary" onclick="showTransactions()" aria-label="View all transactions">View All</button>
|
|
</div>
|
|
<div id="latestTransactions">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading transactions...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- WETH Utilities View -->
|
|
<div id="wethView" class="detail-view">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2 class="card-title"><i class="fas fa-coins"></i> WETH9 & WETH10 Utilities</h2>
|
|
<button class="btn btn-success" onclick="refreshWETHBalances()" aria-label="Refresh WETH balances"><i class="fas fa-sync-alt" aria-hidden="true"></i> Refresh</button>
|
|
</div>
|
|
|
|
<!-- MetaMask Connection Status -->
|
|
<div id="metamaskStatus" class="metamask-status disconnected">
|
|
<i class="fas fa-wallet"></i>
|
|
<span>MetaMask not connected</span>
|
|
<button class="btn btn-success" onclick="connectMetaMask()" style="margin-left: auto;" aria-label="Connect MetaMask wallet">Connect MetaMask</button>
|
|
</div>
|
|
|
|
<div class="tabs">
|
|
<button class="tab weth-tab active" onclick="showWETHTab('weth9', this)" aria-label="Switch to WETH9 tab" role="tab" aria-selected="true">WETH9</button>
|
|
<button class="tab weth-tab" onclick="showWETHTab('weth10', this)" aria-label="Switch to WETH10 tab" role="tab" aria-selected="false">WETH10</button>
|
|
<button class="tab weth-tab" onclick="showWETHTab('info', this)" aria-label="Switch to information tab" role="tab" aria-selected="false">Information</button>
|
|
</div>
|
|
|
|
<!-- WETH9 Tab -->
|
|
<div id="weth9Tab" class="weth-tab-content">
|
|
<div class="weth-card">
|
|
<div class="chain-name">WETH9 Token</div>
|
|
<div style="color: var(--text-light); margin-bottom: 1rem;">
|
|
Contract: <a class="hash" href="/address/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" onclick="event.preventDefault(); showAddressDetail('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2')" style="color: inherit; text-decoration: none;">0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2</a>
|
|
<button type="button" class="btn-add-token-wallet" onclick="event.stopPropagation(); window.addTokenToWallet && window.addTokenToWallet('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', 'WETH', 18, 'Wrapped Ether');" aria-label="Add WETH9 to wallet" title="Add to wallet"><i class="fas fa-wallet" aria-hidden="true"></i></button>
|
|
</div>
|
|
|
|
<div class="balance-display" id="weth9Balance">
|
|
<div class="balance-row">
|
|
<span class="balance-label">ETH Balance:</span>
|
|
<span class="balance-value" id="weth9EthBalance">-</span>
|
|
</div>
|
|
<div class="balance-row">
|
|
<span class="balance-label">WETH9 Balance:</span>
|
|
<span class="balance-value" id="weth9TokenBalance">-</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="weth-form">
|
|
<h3 style="margin-bottom: 1rem;">Wrap ETH → WETH9</h3>
|
|
<div class="form-group">
|
|
<label for="weth9WrapAmount" class="form-label">Amount (ETH or wei)</label>
|
|
<div class="form-input-group">
|
|
<input type="text" inputmode="decimal" class="form-input" id="weth9WrapAmount" placeholder="e.g. 100 or 100000000000000000000 (wei)" aria-label="WETH9 wrap amount in ETH or wei">
|
|
<button class="btn btn-primary" onclick="setMaxWETH9('wrap')" aria-label="Set maximum WETH9 wrap amount">MAX</button>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-success" onclick="wrapWETH9()" id="weth9WrapBtn" disabled aria-label="Wrap ETH to WETH9">
|
|
<i class="fas fa-arrow-right"></i> Wrap ETH to WETH9
|
|
</button>
|
|
</div>
|
|
|
|
<div class="weth-form">
|
|
<h3 style="margin-bottom: 1rem;">Unwrap WETH9 → ETH</h3>
|
|
<div class="form-group">
|
|
<label for="weth9UnwrapAmount" class="form-label">Amount (WETH9 in ETH or wei)</label>
|
|
<div class="form-input-group">
|
|
<input type="text" inputmode="decimal" class="form-input" id="weth9UnwrapAmount" placeholder="e.g. 100 or 100000000000000000000 (wei)" aria-label="WETH9 unwrap amount in ETH or wei">
|
|
<button class="btn btn-primary" onclick="setMaxWETH9('unwrap')" aria-label="Set maximum WETH9 unwrap amount">MAX</button>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-warning" onclick="unwrapWETH9()" id="weth9UnwrapBtn" disabled aria-label="Unwrap WETH9 to ETH">
|
|
<i class="fas fa-arrow-left"></i> Unwrap WETH9 to ETH
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- WETH10 Tab -->
|
|
<div id="weth10Tab" class="weth-tab-content" style="display: none;">
|
|
<div class="weth-card">
|
|
<div class="chain-name">WETH10 Token</div>
|
|
<div style="color: var(--text-light); margin-bottom: 1rem;">
|
|
Contract: <a class="hash" href="/address/0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f" onclick="event.preventDefault(); showAddressDetail('0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f')" style="color: inherit; text-decoration: none;">0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f</a>
|
|
<button type="button" class="btn-add-token-wallet" onclick="event.stopPropagation(); window.addTokenToWallet && window.addTokenToWallet('0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f', 'WETH', 18, 'Wrapped Ether v10');" aria-label="Add WETH10 to wallet" title="Add to wallet"><i class="fas fa-wallet" aria-hidden="true"></i></button>
|
|
</div>
|
|
|
|
<div class="balance-display" id="weth10Balance">
|
|
<div class="balance-row">
|
|
<span class="balance-label">ETH Balance:</span>
|
|
<span class="balance-value" id="weth10EthBalance">-</span>
|
|
</div>
|
|
<div class="balance-row">
|
|
<span class="balance-label">WETH10 Balance:</span>
|
|
<span class="balance-value" id="weth10TokenBalance">-</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="weth-form">
|
|
<h3 style="margin-bottom: 1rem;">Wrap ETH → WETH10</h3>
|
|
<div class="form-group">
|
|
<label for="weth10WrapAmount" class="form-label">Amount (ETH or wei)</label>
|
|
<div class="form-input-group">
|
|
<input type="text" inputmode="decimal" class="form-input" id="weth10WrapAmount" placeholder="e.g. 100 or 100000000000000000000 (wei)" aria-label="WETH10 wrap amount in ETH or wei">
|
|
<button class="btn btn-primary" onclick="setMaxWETH10('wrap')" aria-label="Set maximum WETH10 wrap amount">MAX</button>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-success" onclick="wrapWETH10()" id="weth10WrapBtn" disabled aria-label="Wrap ETH to WETH10">
|
|
<i class="fas fa-arrow-right"></i> Wrap ETH to WETH10
|
|
</button>
|
|
</div>
|
|
|
|
<div class="weth-form">
|
|
<h3 style="margin-bottom: 1rem;">Unwrap WETH10 → ETH</h3>
|
|
<div class="form-group">
|
|
<label for="weth10UnwrapAmount" class="form-label">Amount (WETH10 in ETH or wei)</label>
|
|
<div class="form-input-group">
|
|
<input type="text" inputmode="decimal" class="form-input" id="weth10UnwrapAmount" placeholder="e.g. 100 or 100000000000000000000 (wei)" aria-label="WETH10 unwrap amount in ETH or wei">
|
|
<button class="btn btn-primary" onclick="setMaxWETH10('unwrap')" aria-label="Set maximum WETH10 unwrap amount">MAX</button>
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-warning" onclick="unwrapWETH10()" id="weth10UnwrapBtn" disabled aria-label="Unwrap WETH10 to ETH">
|
|
<i class="fas fa-arrow-left"></i> Unwrap WETH10 to ETH
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Information Tab -->
|
|
<div id="wethInfoTab" class="weth-tab-content" style="display: none;">
|
|
<div class="card">
|
|
<h3>About WETH9 and WETH10</h3>
|
|
<div style="margin-top: 1rem; line-height: 1.8;">
|
|
<p><strong>WETH9</strong> and <strong>WETH10</strong> are wrapped versions of native ETH (Ether) that allow you to use ETH in smart contracts and DeFi protocols.</p>
|
|
|
|
<h4 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">What is Wrapping?</h4>
|
|
<p>Wrapping ETH converts your native ETH into an ERC-20 token (WETH9 or WETH10) that can be used in DeFi applications, smart contracts, and cross-chain bridging.</p>
|
|
|
|
<h4 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">Contract Addresses</h4>
|
|
<ul style="margin-left: 2rem; margin-top: 0.5rem;">
|
|
<li><strong>WETH9:</strong> <a class="hash" href="/address/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" onclick="event.preventDefault(); showAddressDetail('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2')" style="color: inherit; text-decoration: none;">0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2</a> <button type="button" class="btn-add-token-wallet" onclick="event.stopPropagation(); window.addTokenToWallet && window.addTokenToWallet('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', 'WETH', 18);" aria-label="Add WETH9 to wallet" title="Add to wallet"><i class="fas fa-wallet"></i></button></li>
|
|
<li><strong>WETH10:</strong> <a class="hash" href="/address/0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f" onclick="event.preventDefault(); showAddressDetail('0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f')" style="color: inherit; text-decoration: none;">0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f</a> <button type="button" class="btn-add-token-wallet" onclick="event.stopPropagation(); window.addTokenToWallet && window.addTokenToWallet('0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f', 'WETH', 18);" aria-label="Add WETH10 to wallet" title="Add to wallet"><i class="fas fa-wallet"></i></button></li>
|
|
</ul>
|
|
|
|
<h4 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">How to Use</h4>
|
|
<ol style="margin-left: 2rem; margin-top: 0.5rem;">
|
|
<li>Connect your MetaMask wallet</li>
|
|
<li>Select WETH9 or WETH10 tab</li>
|
|
<li>Enter the amount to wrap or unwrap</li>
|
|
<li>Confirm the transaction in MetaMask</li>
|
|
</ol>
|
|
|
|
<h4 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">Cross-Chain Bridging</h4>
|
|
<p>Both WETH9 and WETH10 can be bridged to other chains using the CCIP bridge contracts:</p>
|
|
<ul style="margin-left: 2rem; margin-top: 0.5rem;">
|
|
<li><strong>WETH9 Bridge:</strong> <span class="hash">0x971cD9D156f193df8051E48043C476e53ECd4693</span></li>
|
|
<li><strong>WETH10 Bridge:</strong> <span class="hash">0xe0E93247376aa097dB308B92e6Ba36bA015535D0</span></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bridge Monitoring View -->
|
|
<div id="bridgeView" class="detail-view">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2 class="card-title"><i class="fas fa-bridge"></i> Bridge Monitoring</h2>
|
|
<button class="btn btn-primary" onclick="refreshBridgeData()" aria-label="Refresh bridge data"><i class="fas fa-sync-alt" aria-hidden="true"></i> Refresh</button>
|
|
</div>
|
|
<div id="bridgeContent">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading bridge data...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Other views -->
|
|
<div id="blocksView" class="detail-view">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2 class="card-title">All Blocks</h2>
|
|
<button type="button" class="btn btn-primary" onclick="exportBlocksCSV()" style="padding: 0.5rem 1rem;"><i class="fas fa-file-csv"></i> Export CSV</button>
|
|
</div>
|
|
<div id="blocksList">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading blocks...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="transactionsView" class="detail-view">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h2 class="card-title">All Transactions</h2>
|
|
<button type="button" class="btn btn-primary" onclick="exportTransactionsListCSV()" style="padding: 0.5rem 1rem;"><i class="fas fa-file-csv"></i> Export CSV</button>
|
|
</div>
|
|
<div id="transactionsList">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading transactions...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="blockDetailView" class="detail-view">
|
|
<div class="breadcrumb" id="blockDetailBreadcrumb"></div>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<button class="btn btn-secondary" onclick="showBlocks()" aria-label="Go back to blocks view"><i class="fas fa-arrow-left" aria-hidden="true"></i> Back</button>
|
|
<h2 class="card-title">Block Details</h2>
|
|
</div>
|
|
<div id="blockDetail"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="transactionDetailView" class="detail-view">
|
|
<div class="breadcrumb" id="transactionDetailBreadcrumb"></div>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<button class="btn btn-secondary" onclick="showTransactions()" aria-label="Go back to transactions view"><i class="fas fa-arrow-left" aria-hidden="true"></i> Back</button>
|
|
<h2 class="card-title">Transaction Details</h2>
|
|
</div>
|
|
<div id="transactionDetail"></div>
|
|
</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="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>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="tokenDetailView" class="detail-view">
|
|
<div class="breadcrumb" id="tokenDetailBreadcrumb"></div>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back"><i class="fas fa-arrow-left"></i> Back</button>
|
|
<h2 class="card-title">Token</h2>
|
|
</div>
|
|
<div id="tokenDetail"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="nftDetailView" class="detail-view">
|
|
<div class="breadcrumb" id="nftDetailBreadcrumb"></div>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back"><i class="fas fa-arrow-left"></i> Back</button>
|
|
<h2 class="card-title">NFT</h2>
|
|
</div>
|
|
<div id="nftDetail"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="searchResultsView" class="detail-view">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back"><i class="fas fa-arrow-left"></i> Back</button>
|
|
<h2 class="card-title">Search results</h2>
|
|
</div>
|
|
<div id="searchResultsContent"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="tokensView" class="detail-view">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back"><i class="fas fa-arrow-left"></i> Back</button>
|
|
<h2 class="card-title"><i class="fas fa-coins"></i> Tokens</h2>
|
|
</div>
|
|
<div id="tokensListContent">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="watchlistView" class="detail-view">
|
|
<div class="breadcrumb" id="watchlistBreadcrumb"><a href="/">Home</a><span class="breadcrumb-separator">/</span><span class="breadcrumb-current">Watchlist</span></div>
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back"><i class="fas fa-arrow-left"></i> Back</button>
|
|
<h2 class="card-title"><i class="fas fa-star"></i> Watchlist</h2>
|
|
</div>
|
|
<div id="watchlistContent">
|
|
<p style="color: var(--text-light);">Add addresses from their detail page to track them here.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="poolsView" class="detail-view">
|
|
<div class="breadcrumb" id="poolsBreadcrumb"><a href="/">Home</a><span class="breadcrumb-separator">/</span><span class="breadcrumb-current">Pools</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-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>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="liquidityView" class="detail-view">
|
|
<div class="breadcrumb" id="liquidityBreadcrumb"><a href="/">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="routesView" class="detail-view">
|
|
<div class="breadcrumb" id="routesBreadcrumb"><a href="/">Home</a><span class="breadcrumb-separator">/</span><span class="breadcrumb-current">Routes</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-diagram-project"></i> Routes</h2>
|
|
<div style="display:flex; gap:0.5rem; margin-left:auto; flex-wrap:wrap;">
|
|
<button type="button" class="btn btn-primary" onclick="renderRoutesView()" style="padding: 0.5rem 1rem;"><i class="fas fa-sync-alt"></i> Refresh</button>
|
|
</div>
|
|
</div>
|
|
<div id="routesContent">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading routes...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="moreView" class="detail-view">
|
|
<div class="breadcrumb" id="moreBreadcrumb"><a href="/">Home</a><span class="breadcrumb-separator">/</span><span class="breadcrumb-current">More</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-ellipsis-h"></i> More</h2>
|
|
</div>
|
|
<div id="moreContent">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading more pages...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="analyticsView" class="detail-view">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back"><i class="fas fa-arrow-left"></i> Back</button>
|
|
<h2 class="card-title"><i class="fas fa-chart-line"></i> Analytics Dashboard</h2>
|
|
</div>
|
|
<div id="analyticsContent">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading analytics access...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="operatorView" class="detail-view">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<button class="btn btn-secondary" onclick="showHome()" aria-label="Go back"><i class="fas fa-arrow-left"></i> Back</button>
|
|
<h2 class="card-title"><i class="fas fa-cog"></i> Operator Panel</h2>
|
|
</div>
|
|
<div id="operatorContent">
|
|
<div class="loading"><i class="fas fa-spinner"></i> Loading operator access...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<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="/routes">Routes</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=29"></script>
|
|
</body>
|
|
</html>
|