- Chain 138 Liquidity Access
+ Liquidity
Public liquidity, route discovery, and execution access points
@@ -282,9 +286,14 @@ export default function LiquidityOperationsPage({
{loadingError ? (
-
- {loadingError}
-
+ {
+ setLoadingError(null)
+ setReloadKey((value) => value + 1)
+ }}
+ />
) : null}
diff --git a/frontend/src/components/home/HomePage.tsx b/frontend/src/components/home/HomePage.tsx
index c449200..eb76a59 100644
--- a/frontend/src/components/home/HomePage.tsx
+++ b/frontend/src/components/home/HomePage.tsx
@@ -650,7 +650,7 @@ export default function Home({
href="/bridge"
className="inline-flex items-center justify-center rounded-xl bg-gray-900 px-4 py-2.5 text-sm font-semibold text-white hover:bg-black dark:bg-white dark:text-gray-900 dark:hover:bg-gray-100"
>
- Open bridge monitoring
+ Open bridge
Search
+
+ Account access
+
Tokens
diff --git a/frontend/src/components/wallet/WalletConnectPostureNote.tsx b/frontend/src/components/wallet/WalletConnectPostureNote.tsx
new file mode 100644
index 0000000..1b4ca8e
--- /dev/null
+++ b/frontend/src/components/wallet/WalletConnectPostureNote.tsx
@@ -0,0 +1,32 @@
+'use client'
+
+import { useEffect, useState } from 'react'
+import { getWalletConnectConfig, type WalletConnectConfigResponse } from '@/services/api/walletConnect'
+
+export default function WalletConnectPostureNote() {
+ const [config, setConfig] = useState(null)
+
+ useEffect(() => {
+ let cancelled = false
+ getWalletConnectConfig()
+ .then((value) => {
+ if (!cancelled) setConfig(value)
+ })
+ .catch(() => {
+ if (!cancelled) setConfig(null)
+ })
+ return () => {
+ cancelled = true
+ }
+ }, [])
+
+ if (!config) return null
+
+ return (
+
+ WalletConnect v2 posture: {config.enabled ? 'enabled' : config.status}. Browser extension wallets use{' '}
+ {config.fallbackAuth} today.
+ {config.message ? ` ${config.message}` : ''}
+
+ )
+}
diff --git a/frontend/src/components/wallet/WalletPage.tsx b/frontend/src/components/wallet/WalletPage.tsx
index 79889e5..cc9f558 100644
--- a/frontend/src/components/wallet/WalletPage.tsx
+++ b/frontend/src/components/wallet/WalletPage.tsx
@@ -6,6 +6,7 @@ import type {
TokenListCatalog,
} from '@/components/wallet/AddToMetaMask'
import { AddToMetaMask } from '@/components/wallet/AddToMetaMask'
+import WalletConnectPostureNote from '@/components/wallet/WalletConnectPostureNote'
import Link from 'next/link'
import { Explain, useUiMode } from '@/components/common/UiModeContext'
import { accessApi, type WalletAccessSession } from '@/services/api/access'
@@ -192,6 +193,7 @@ export default function WalletPage(props: WalletPageProps) {
? 'Use the explorer-served network catalog, token list, and capability metadata to connect Chain 138 (DeFi Oracle Meta Mainnet) and Ethereum Mainnet to MetaMask and other Web3 wallets.'
: 'Use explorer-served network and token metadata to connect Chain 138 and Ethereum Mainnet wallets.'}
+
@@ -483,7 +485,7 @@ export default function WalletPage(props: WalletPageProps) {
<>
Need swap and liquidity discovery too? Visit the{' '}
- Liquidity Access
+ Liquidity
{' '}
page for live Chain 138 pools, route matrix links, partner payload templates, and the internal fallback execution plan endpoints.
>
@@ -492,7 +494,7 @@ export default function WalletPage(props: WalletPageProps) {
<>
Liquidity and planner posture lives on the{' '}
- Liquidity Access
+ Liquidity
{' '}
surface.
>
diff --git a/frontend/src/data/explorerOperations.ts b/frontend/src/data/explorerOperations.ts
index c1e470c..f7a56b0 100644
--- a/frontend/src/data/explorerOperations.ts
+++ b/frontend/src/data/explorerOperations.ts
@@ -21,7 +21,7 @@ const sharedOperationsNote =
export const explorerFeaturePages = {
bridge: {
- eyebrow: 'Bridge Monitoring',
+ eyebrow: 'Bridge',
title: 'Bridge & Relay Monitoring',
description:
'Inspect the CCIP relay status, follow the live mission-control stream, trace bridge transactions, and review the managed Mainnet, BSC, Avalanche, Avalanche cW, and Avalanche to Chain 138 lanes.',
@@ -81,7 +81,7 @@ export const explorerFeaturePages = {
title: 'Liquidity access',
description: 'Review the public Chain 138 PMM access points, route helpers, and fallback execution endpoints.',
href: '/liquidity',
- label: 'Open liquidity access',
+ label: 'Open liquidity',
},
{
title: 'Pools inventory',
@@ -93,7 +93,7 @@ export const explorerFeaturePages = {
title: 'Bridge monitoring',
description: 'Cross-check route availability with live relay and bridge health before operator actions.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Operations hub',
@@ -114,7 +114,7 @@ export const explorerFeaturePages = {
title: 'Bridge monitoring',
description: 'Start with relay and bridge health before reviewing WETH-specific flows.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Visual command center',
@@ -175,8 +175,8 @@ export const explorerFeaturePages = {
],
},
operator: {
- eyebrow: 'Operator Surface',
- title: 'Operator Surface',
+ eyebrow: 'Operator',
+ title: 'Operator',
description:
'Expose the public operator surface for bridge checks, route validation, planner providers, liquidity entry points, and documentation.',
note: sharedOperationsNote,
@@ -188,7 +188,7 @@ export const explorerFeaturePages = {
title: 'Bridge monitoring',
description: 'Open relay status, queue posture, and bridge trace tools.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Routes',
@@ -200,7 +200,7 @@ export const explorerFeaturePages = {
title: 'Liquidity access',
description: 'Open partner payload helpers, route APIs, and execution-plan endpoints.',
href: '/liquidity',
- label: 'Open liquidity access',
+ label: 'Open liquidity',
},
{
title: 'Explorer docs',
@@ -235,7 +235,7 @@ export const explorerFeaturePages = {
title: 'Bridge monitoring',
description: 'Correlate topology context with the live bridge and relay status surface.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Explorer docs',
@@ -252,8 +252,8 @@ export const explorerFeaturePages = {
],
},
operations: {
- eyebrow: 'Operations Hub',
- title: 'Operations Hub',
+ eyebrow: 'Operations hub',
+ title: 'Operations hub',
description:
'This hub exposes the public operational surfaces for bridge monitoring, routes, wrapped-asset references, analytics shortcuts, operator links, and topology views.',
note: sharedOperationsNote,
@@ -262,7 +262,7 @@ export const explorerFeaturePages = {
title: 'Bridge & relay monitoring',
description: 'Open mission-control status, SSE monitoring, and bridge trace helpers.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Routes & liquidity',
diff --git a/scripts/e2e-sprint-smoke.spec.ts b/scripts/e2e-sprint-smoke.spec.ts
index 7167cf8..9bcd551 100644
--- a/scripts/e2e-sprint-smoke.spec.ts
+++ b/scripts/e2e-sprint-smoke.spec.ts
@@ -15,6 +15,11 @@ test.describe('Explorer sprint smoke', () => {
await expect(page.getByRole('heading', { name: /Wallet Tools/i })).toBeVisible({ timeout: 10000 })
})
+ test('wallet page shows WalletConnect posture note', async ({ page }) => {
+ await page.goto(`${EXPLORER_URL}/wallet`, { waitUntil: 'domcontentloaded', timeout: 20000 })
+ await expect(page.getByText(/WalletConnect v2 posture/i)).toBeVisible({ timeout: 10000 })
+ })
+
test('tokens page loads', async ({ page }) => {
await page.goto(`${EXPLORER_URL}/tokens`, { waitUntil: 'domcontentloaded', timeout: 20000 })
await expect(page.getByRole('heading', { name: /^Tokens$/i })).toBeVisible({ timeout: 10000 })
@@ -28,7 +33,7 @@ test.describe('Explorer sprint smoke', () => {
test('operations hub loads extended token list note', async ({ page }) => {
await page.goto(`${EXPLORER_URL}/operations`, { waitUntil: 'networkidle', timeout: 30000 })
- await expect(page.getByRole('heading', { name: /Operations Hub/i })).toBeVisible({ timeout: 10000 })
+ await expect(page.getByRole('heading', { name: /Operations hub/i })).toBeVisible({ timeout: 10000 })
await expect(page.getByText(/Extended Metamask dual-chain catalog/i).first()).toBeVisible({ timeout: 10000 })
})
@@ -49,9 +54,15 @@ test.describe('Explorer sprint smoke', () => {
await expect(page.getByRole('contentinfo').getByText(/Public APIs/i)).toBeVisible({ timeout: 10000 })
await expect(page.getByRole('contentinfo').getByRole('link', { name: /Blockscout stats/i })).toBeVisible({ timeout: 10000 })
await expect(page.getByRole('contentinfo').getByRole('link', { name: /Wallet tools/i })).toBeVisible({ timeout: 10000 })
+ await expect(page.getByRole('contentinfo').getByRole('button', { name: /Copy URL for Blockscout stats/i })).toBeVisible({ timeout: 10000 })
await expect(page.getByRole('contentinfo').getByRole('link', { name: /Account access/i })).toBeVisible({ timeout: 10000 })
})
+ test('homepage quick links include account access', async ({ page }) => {
+ await page.goto(`${EXPLORER_URL}/`, { waitUntil: 'domcontentloaded', timeout: 20000 })
+ await expect(page.getByRole('link', { name: /Account access/i }).first()).toBeVisible({ timeout: 10000 })
+ })
+
test('tablet viewport exposes mobile navigation menu', async ({ page }) => {
await page.setViewportSize({ width: 1100, height: 800 })
await page.goto(`${EXPLORER_URL}/`, { waitUntil: 'domcontentloaded', timeout: 20000 })
@@ -68,7 +79,7 @@ test.describe('Explorer sprint smoke', () => {
test('operator page shows track 4 surface note', async ({ page }) => {
await page.goto(`${EXPLORER_URL}/operator`, { waitUntil: 'domcontentloaded', timeout: 30000 })
- await expect(page.getByRole('heading', { name: /^Operator Surface$/i })).toBeVisible({ timeout: 15000 })
+ await expect(page.getByRole('heading', { name: /^Operator$/i })).toBeVisible({ timeout: 15000 })
await expect(page.getByText(/Track 4 public surface/i).first()).toBeVisible({ timeout: 10000 })
})
{loadingError}
-
diff --git a/frontend/src/components/home/HomePage.tsx b/frontend/src/components/home/HomePage.tsx
index c449200..eb76a59 100644
--- a/frontend/src/components/home/HomePage.tsx
+++ b/frontend/src/components/home/HomePage.tsx
@@ -650,7 +650,7 @@ export default function Home({
href="/bridge"
className="inline-flex items-center justify-center rounded-xl bg-gray-900 px-4 py-2.5 text-sm font-semibold text-white hover:bg-black dark:bg-white dark:text-gray-900 dark:hover:bg-gray-100"
>
- Open bridge monitoring
+ Open bridge
Search
+
+ Account access
+
Tokens
diff --git a/frontend/src/components/wallet/WalletConnectPostureNote.tsx b/frontend/src/components/wallet/WalletConnectPostureNote.tsx
new file mode 100644
index 0000000..1b4ca8e
--- /dev/null
+++ b/frontend/src/components/wallet/WalletConnectPostureNote.tsx
@@ -0,0 +1,32 @@
+'use client'
+
+import { useEffect, useState } from 'react'
+import { getWalletConnectConfig, type WalletConnectConfigResponse } from '@/services/api/walletConnect'
+
+export default function WalletConnectPostureNote() {
+ const [config, setConfig] = useState(null)
+
+ useEffect(() => {
+ let cancelled = false
+ getWalletConnectConfig()
+ .then((value) => {
+ if (!cancelled) setConfig(value)
+ })
+ .catch(() => {
+ if (!cancelled) setConfig(null)
+ })
+ return () => {
+ cancelled = true
+ }
+ }, [])
+
+ if (!config) return null
+
+ return (
+
+ WalletConnect v2 posture: {config.enabled ? 'enabled' : config.status}. Browser extension wallets use{' '}
+ {config.fallbackAuth} today.
+ {config.message ? ` ${config.message}` : ''}
+
@@ -483,7 +485,7 @@ export default function WalletPage(props: WalletPageProps) {
<>
Need swap and liquidity discovery too? Visit the{' '}
- Liquidity Access
+ Liquidity
{' '}
page for live Chain 138 pools, route matrix links, partner payload templates, and the internal fallback execution plan endpoints.
>
@@ -492,7 +494,7 @@ export default function WalletPage(props: WalletPageProps) {
<>
Liquidity and planner posture lives on the{' '}
- Liquidity Access
+ Liquidity
{' '}
surface.
>
diff --git a/frontend/src/data/explorerOperations.ts b/frontend/src/data/explorerOperations.ts
index c1e470c..f7a56b0 100644
--- a/frontend/src/data/explorerOperations.ts
+++ b/frontend/src/data/explorerOperations.ts
@@ -21,7 +21,7 @@ const sharedOperationsNote =
export const explorerFeaturePages = {
bridge: {
- eyebrow: 'Bridge Monitoring',
+ eyebrow: 'Bridge',
title: 'Bridge & Relay Monitoring',
description:
'Inspect the CCIP relay status, follow the live mission-control stream, trace bridge transactions, and review the managed Mainnet, BSC, Avalanche, Avalanche cW, and Avalanche to Chain 138 lanes.',
@@ -81,7 +81,7 @@ export const explorerFeaturePages = {
title: 'Liquidity access',
description: 'Review the public Chain 138 PMM access points, route helpers, and fallback execution endpoints.',
href: '/liquidity',
- label: 'Open liquidity access',
+ label: 'Open liquidity',
},
{
title: 'Pools inventory',
@@ -93,7 +93,7 @@ export const explorerFeaturePages = {
title: 'Bridge monitoring',
description: 'Cross-check route availability with live relay and bridge health before operator actions.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Operations hub',
@@ -114,7 +114,7 @@ export const explorerFeaturePages = {
title: 'Bridge monitoring',
description: 'Start with relay and bridge health before reviewing WETH-specific flows.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Visual command center',
@@ -175,8 +175,8 @@ export const explorerFeaturePages = {
],
},
operator: {
- eyebrow: 'Operator Surface',
- title: 'Operator Surface',
+ eyebrow: 'Operator',
+ title: 'Operator',
description:
'Expose the public operator surface for bridge checks, route validation, planner providers, liquidity entry points, and documentation.',
note: sharedOperationsNote,
@@ -188,7 +188,7 @@ export const explorerFeaturePages = {
title: 'Bridge monitoring',
description: 'Open relay status, queue posture, and bridge trace tools.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Routes',
@@ -200,7 +200,7 @@ export const explorerFeaturePages = {
title: 'Liquidity access',
description: 'Open partner payload helpers, route APIs, and execution-plan endpoints.',
href: '/liquidity',
- label: 'Open liquidity access',
+ label: 'Open liquidity',
},
{
title: 'Explorer docs',
@@ -235,7 +235,7 @@ export const explorerFeaturePages = {
title: 'Bridge monitoring',
description: 'Correlate topology context with the live bridge and relay status surface.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Explorer docs',
@@ -252,8 +252,8 @@ export const explorerFeaturePages = {
],
},
operations: {
- eyebrow: 'Operations Hub',
- title: 'Operations Hub',
+ eyebrow: 'Operations hub',
+ title: 'Operations hub',
description:
'This hub exposes the public operational surfaces for bridge monitoring, routes, wrapped-asset references, analytics shortcuts, operator links, and topology views.',
note: sharedOperationsNote,
@@ -262,7 +262,7 @@ export const explorerFeaturePages = {
title: 'Bridge & relay monitoring',
description: 'Open mission-control status, SSE monitoring, and bridge trace helpers.',
href: '/bridge',
- label: 'Open bridge monitoring',
+ label: 'Open bridge',
},
{
title: 'Routes & liquidity',
diff --git a/scripts/e2e-sprint-smoke.spec.ts b/scripts/e2e-sprint-smoke.spec.ts
index 7167cf8..9bcd551 100644
--- a/scripts/e2e-sprint-smoke.spec.ts
+++ b/scripts/e2e-sprint-smoke.spec.ts
@@ -15,6 +15,11 @@ test.describe('Explorer sprint smoke', () => {
await expect(page.getByRole('heading', { name: /Wallet Tools/i })).toBeVisible({ timeout: 10000 })
})
+ test('wallet page shows WalletConnect posture note', async ({ page }) => {
+ await page.goto(`${EXPLORER_URL}/wallet`, { waitUntil: 'domcontentloaded', timeout: 20000 })
+ await expect(page.getByText(/WalletConnect v2 posture/i)).toBeVisible({ timeout: 10000 })
+ })
+
test('tokens page loads', async ({ page }) => {
await page.goto(`${EXPLORER_URL}/tokens`, { waitUntil: 'domcontentloaded', timeout: 20000 })
await expect(page.getByRole('heading', { name: /^Tokens$/i })).toBeVisible({ timeout: 10000 })
@@ -28,7 +33,7 @@ test.describe('Explorer sprint smoke', () => {
test('operations hub loads extended token list note', async ({ page }) => {
await page.goto(`${EXPLORER_URL}/operations`, { waitUntil: 'networkidle', timeout: 30000 })
- await expect(page.getByRole('heading', { name: /Operations Hub/i })).toBeVisible({ timeout: 10000 })
+ await expect(page.getByRole('heading', { name: /Operations hub/i })).toBeVisible({ timeout: 10000 })
await expect(page.getByText(/Extended Metamask dual-chain catalog/i).first()).toBeVisible({ timeout: 10000 })
})
@@ -49,9 +54,15 @@ test.describe('Explorer sprint smoke', () => {
await expect(page.getByRole('contentinfo').getByText(/Public APIs/i)).toBeVisible({ timeout: 10000 })
await expect(page.getByRole('contentinfo').getByRole('link', { name: /Blockscout stats/i })).toBeVisible({ timeout: 10000 })
await expect(page.getByRole('contentinfo').getByRole('link', { name: /Wallet tools/i })).toBeVisible({ timeout: 10000 })
+ await expect(page.getByRole('contentinfo').getByRole('button', { name: /Copy URL for Blockscout stats/i })).toBeVisible({ timeout: 10000 })
await expect(page.getByRole('contentinfo').getByRole('link', { name: /Account access/i })).toBeVisible({ timeout: 10000 })
})
+ test('homepage quick links include account access', async ({ page }) => {
+ await page.goto(`${EXPLORER_URL}/`, { waitUntil: 'domcontentloaded', timeout: 20000 })
+ await expect(page.getByRole('link', { name: /Account access/i }).first()).toBeVisible({ timeout: 10000 })
+ })
+
test('tablet viewport exposes mobile navigation menu', async ({ page }) => {
await page.setViewportSize({ width: 1100, height: 800 })
await page.goto(`${EXPLORER_URL}/`, { waitUntil: 'domcontentloaded', timeout: 20000 })
@@ -68,7 +79,7 @@ test.describe('Explorer sprint smoke', () => {
test('operator page shows track 4 surface note', async ({ page }) => {
await page.goto(`${EXPLORER_URL}/operator`, { waitUntil: 'domcontentloaded', timeout: 30000 })
- await expect(page.getByRole('heading', { name: /^Operator Surface$/i })).toBeVisible({ timeout: 15000 })
+ await expect(page.getByRole('heading', { name: /^Operator$/i })).toBeVisible({ timeout: 15000 })
await expect(page.getByText(/Track 4 public surface/i).first()).toBeVisible({ timeout: 10000 })
})