diff --git a/frontend/public/explorer-spa.js b/frontend/public/explorer-spa.js
index 53bb6b7..df42310 100644
--- a/frontend/public/explorer-spa.js
+++ b/frontend/public/explorer-spa.js
@@ -876,7 +876,7 @@
// View switch helper: works even if rest of script fails. Do NOT set location.hash here (we use path-based URLs).
function switchToView(viewName) {
- if (viewName !== 'pools' && _poolsRouteTreeRefreshTimer) {
+ if (viewName !== 'pools' && viewName !== 'routes' && _poolsRouteTreeRefreshTimer) {
clearInterval(_poolsRouteTreeRefreshTimer);
_poolsRouteTreeRefreshTimer = null;
}
@@ -885,7 +885,7 @@
_blocksScrollAnimationId = null;
}
currentView = viewName;
- var detailViews = ['blockDetail','transactionDetail','addressDetail','tokenDetail','nftDetail','watchlist','searchResults','tokens','addresses','pools','liquidity','more'];
+ var detailViews = ['blockDetail','transactionDetail','addressDetail','tokenDetail','nftDetail','watchlist','searchResults','tokens','addresses','pools','routes','liquidity','more'];
if (detailViews.indexOf(viewName) === -1) currentDetailKey = '';
var homeEl = document.getElementById('homeView');
if (homeEl) homeEl.style.display = viewName === 'home' ? 'block' : 'none';
@@ -906,6 +906,7 @@
window.openPoolsView = openPoolsView;
// Back-compat alias for older menu wiring; prefer openPoolsView() and renderPoolsView().
window.showPools = openPoolsView;
+ window.showRoutes = function() { if (_inNavHandler) return; _inNavHandler = true; try { switchToView('routes'); if (typeof renderRoutesView === 'function') renderRoutesView(); } finally { _inNavHandler = false; } };
window.showLiquidityAccess = function() { if (_inNavHandler) return; _inNavHandler = true; try { switchToView('liquidity'); if (typeof renderLiquidityAccessView === 'function') renderLiquidityAccessView(); } finally { _inNavHandler = false; } };
window.showMore = function() { if (_inNavHandler) return; _inNavHandler = true; try { switchToView('more'); if (window._showMore) window._showMore(); } finally { _inNavHandler = false; } };
window.showTokensList = function() { if (_inNavHandler) return; _inNavHandler = true; try { switchToView('tokens'); if (window._loadTokensList) window._loadTokensList(); } finally { _inNavHandler = false; } };
@@ -2316,6 +2317,7 @@
if (parts[0] === 'weth') { if (currentView !== 'weth') showWETHUtilities(); return; }
if (parts[0] === 'watchlist') { if (currentView !== 'watchlist') showWatchlist(); return; }
if (parts[0] === 'pools') { if (currentView !== 'pools') openPoolsView(); return; }
+ if (parts[0] === 'routes') { if (currentView !== 'routes') showRoutes(); return; }
if (parts[0] === 'liquidity') { if (currentView !== 'liquidity') showLiquidityAccess(); return; }
if (parts[0] === 'more') { if (currentView !== 'more') showMore(); return; }
if (parts[0] === 'tokens') { if (typeof showTokensList === 'function') showTokensList(); else focusSearchWithHint('token'); return; }
@@ -2421,6 +2423,11 @@
breadcrumbHTML += '/';
breadcrumbHTML += 'Pools';
break;
+ case 'routes':
+ breadcrumbContainer = document.getElementById('routesBreadcrumb');
+ breadcrumbHTML += '/';
+ breadcrumbHTML += 'Routes';
+ break;
case 'more':
breadcrumbContainer = document.getElementById('moreBreadcrumb');
breadcrumbHTML += '/';
@@ -3549,8 +3556,9 @@
badge.style.display = n > 0 ? 'inline-block' : 'none';
}
- async function loadLiveRouteTrees() {
- var container = document.getElementById('poolRouteTreeContent');
+ async function loadLiveRouteTrees(targetId) {
+ var containerId = targetId || (currentView === 'routes' ? 'routesRouteTreeContent' : 'poolRouteTreeContent');
+ var container = document.getElementById(containerId);
if (!container) return;
container.innerHTML = '
Loading live route tree...
';
@@ -3604,6 +3612,48 @@
}
}
+ function buildRoutesLandingHtml() {
+ var html = '';
+ html += '
';
+ html += '
';
+ html += '
';
+ html += '
Live Route Decision Tree
';
+ html += '
This dedicated view follows the Chain 138 routing graph end-to-end. It keeps the live coverage sweep, direct-pair diagnostics, and bridge-path branches together in one place so route investigations do not get buried inside the pools inventory.
';
+ html += '
';
+ html += '
';
+ html += '';
+ html += '';
+ html += '';
+ html += '
';
+ html += '
';
+ html += '
';
+ html += '
Best for
Route debugging and operator review
Use this page when a user route, destination branch, or quote-token path looks wrong.
';
+ html += '
Includes
Coverage sweep + priority route cards
The pools page now links here instead of embedding the full route tree inline.
';
+ html += '
Data source
Live token-aggregation route tree API
Every refresh re-reads current Chain 138 PMM and bridge state.
';
+ html += '
';
+ html += '
';
+ html += '
Loading live route tree...
';
+ return html;
+ }
+
+ function renderRoutesView() {
+ showView('routes');
+ if ((window.location.pathname || '').replace(/^\//, '').split('/')[0] !== 'routes') updatePath('/routes');
+ updateBreadcrumb('routes');
+ var container = document.getElementById('routesContent');
+ if (!container) return;
+ container.innerHTML = buildRoutesLandingHtml();
+ setTimeout(function() {
+ loadLiveRouteTrees('routesRouteTreeContent');
+ }, 0);
+ _poolsRouteTreeRefreshTimer = setInterval(function() {
+ if (currentView === 'routes') {
+ loadLiveRouteTrees('routesRouteTreeContent');
+ }
+ }, ROUTE_TREE_REFRESH_MS);
+ }
+ window.renderRoutesView = renderRoutesView;
+
function summarizePoolRows(rows) {
var summary = {
liveLocal: 0,
@@ -3752,21 +3802,24 @@
html += '';
html += '
';
html += '
';
- html += '
Live Route Decision Tree
';
- html += '';
+ html += '
';
+ html += '
Live Route Decision Tree
';
+ html += '
The full route sweep and priority route cards now live on their own dedicated page so investigations can open directly into the routing graph.
';
+ html += '
';
+ html += '
';
+ html += '';
+ html += '';
+ html += '
';
+ html += '
';
+ html += '
';
+ html += '
Use Routes for the live route coverage sweep, bridge-path diagnostics, and missing quote-token review. The pools table above stays focused on pool inventory and funding state.
This live panel follows the Chain 138 DEX and bridge graph end-to-end so we can see direct pool depth, bridge leg availability, destination swap branches, and any missing quote-token metadata that still needs cleanup.
';
}
@@ -3909,9 +3962,10 @@
});
html += '';
html += '
Related Explorer Tools
';
- html += '
Use Wallet for network onboarding and the explorer token list URL, then use Pools for live route-tree diagnostics and contract-state checks.
';
+ html += '
Use Wallet for network onboarding and the explorer token list URL, then open Routes for live route-tree diagnostics and Pools for contract-state inventory checks.
';
html += '
';
- html += '';
+ html += '';
+ html += '';
html += '';
html += ' Explorer docs';
html += '
';
@@ -3942,7 +3996,7 @@
title: 'Explore',
items: [
{ title: 'Gas Tracker', icon: 'fa-gas-pump', status: 'Live', badgeClass: 'badge-success', desc: 'Review live gas, block time, TPS, and chain health from the analytics and home dashboards.', action: 'showAnalytics();', href: '/analytics' },
- { title: 'DEX Tracker', icon: 'fa-chart-line', status: 'Live', badgeClass: 'badge-success', desc: 'Open liquidity discovery, PMM pool status, live route trees, and partner payload access points.', action: 'showLiquidityAccess();', href: '/liquidity' },
+ { title: 'DEX Tracker', icon: 'fa-chart-line', status: 'Live', badgeClass: 'badge-success', desc: 'Open liquidity discovery, PMM pool status, live route trees, and partner payload access points.', action: 'showRoutes();', href: '/routes' },
{ title: 'Node Tracker', icon: 'fa-server', status: 'Live', badgeClass: 'badge-success', desc: 'Inspect bridge and operator infrastructure surfaces already exposed in the Bridge and Operator panels.', action: 'showOperator();', href: '/operator' },
{ title: 'Label Cloud', icon: 'fa-tags', status: 'Live', badgeClass: 'badge-success', desc: 'Browse labeled addresses, contracts, and address activity through the explorer address index.', action: 'showAddresses();', href: '/addresses' },
{ title: 'Domain Name Lookup', icon: 'fa-magnifying-glass', status: 'Live', badgeClass: 'badge-success', desc: 'Use the smart search launcher to resolve ENS-style names, domains, addresses, hashes, and token symbols.', action: 'openSmartSearchModal(\'\');', href: '/more' }
diff --git a/frontend/public/index.html b/frontend/public/index.html
index be3f053..187ecff 100644
--- a/frontend/public/index.html
+++ b/frontend/public/index.html
@@ -1038,6 +1038,7 @@