Files
2026-03-28 15:15:23 -07:00

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 &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 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>