Add explorer liquidity access and live route proxies
This commit is contained in:
257
frontend/src/app/liquidity/page.tsx
Normal file
257
frontend/src/app/liquidity/page.tsx
Normal file
@@ -0,0 +1,257 @@
|
||||
import Link from 'next/link'
|
||||
import { Card } from '@/libs/frontend-ui-primitives/Card'
|
||||
|
||||
const publicApiBase = '/token-aggregation/api/v1'
|
||||
|
||||
const livePools = [
|
||||
{
|
||||
pair: 'cUSDT / cUSDC',
|
||||
poolAddress: '0xff8d3b8fDF7B112759F076B69f4271D4209C0849',
|
||||
reserves: '10,000,000 / 10,000,000',
|
||||
},
|
||||
{
|
||||
pair: 'cUSDT / USDT',
|
||||
poolAddress: '0x6fc60DEDc92a2047062294488539992710b99D71',
|
||||
reserves: '10,000,000 / 10,000,000',
|
||||
},
|
||||
{
|
||||
pair: 'cUSDC / USDC',
|
||||
poolAddress: '0x0309178ae30302D83c76d6Dd402a684eF3160eec',
|
||||
reserves: '10,000,000 / 10,000,000',
|
||||
},
|
||||
{
|
||||
pair: 'cUSDT / cXAUC',
|
||||
poolAddress: '0x1AA55E2001E5651349AfF5A63FD7A7Ae44f0F1b0',
|
||||
reserves: '2,666,965 / 519.477000',
|
||||
},
|
||||
{
|
||||
pair: 'cUSDC / cXAUC',
|
||||
poolAddress: '0xEA9Ac6357CaCB42a83b9082B870610363B177cBa',
|
||||
reserves: '1,000,000 / 194.782554',
|
||||
},
|
||||
{
|
||||
pair: 'cEURT / cXAUC',
|
||||
poolAddress: '0xbA99bc1eAAC164569d5AcA96C806934DDaF970Cf',
|
||||
reserves: '1,000,000 / 225.577676',
|
||||
},
|
||||
]
|
||||
|
||||
const publicEndpoints = [
|
||||
{
|
||||
name: 'Canonical route matrix',
|
||||
method: 'GET',
|
||||
href: `${publicApiBase}/routes/matrix`,
|
||||
notes: 'All live and optional non-live route inventory with counts and filters.',
|
||||
},
|
||||
{
|
||||
name: 'Live ingestion export',
|
||||
method: 'GET',
|
||||
href: `${publicApiBase}/routes/ingestion?family=LiFi`,
|
||||
notes: 'Flat live-route export for adapter ingestion and route discovery.',
|
||||
},
|
||||
{
|
||||
name: 'Partner payload templates',
|
||||
method: 'GET',
|
||||
href: `${publicApiBase}/routes/partner-payloads?partner=0x&amount=1000000&includeUnsupported=true`,
|
||||
notes: 'Builds exact 1inch, 0x, and LiFi request templates from live routes.',
|
||||
},
|
||||
{
|
||||
name: 'Resolve supported partner payloads',
|
||||
method: 'POST',
|
||||
href: `${publicApiBase}/routes/partner-payloads/resolve`,
|
||||
notes: 'Accepts partner, amount, and addresses and returns supported payloads by default.',
|
||||
},
|
||||
{
|
||||
name: 'Dispatch supported partner payload',
|
||||
method: 'POST',
|
||||
href: `${publicApiBase}/routes/partner-payloads/dispatch`,
|
||||
notes: 'Resolves then dispatches a single supported partner payload when the chain is supported.',
|
||||
},
|
||||
{
|
||||
name: 'Internal Chain 138 execution plan',
|
||||
method: 'POST',
|
||||
href: `${publicApiBase}/routes/internal-execution-plan`,
|
||||
notes: 'Returns the internal DODO PMM fallback plan when external partner support is unavailable.',
|
||||
},
|
||||
]
|
||||
|
||||
const routeHighlights = [
|
||||
'Direct live routes: cUSDT <-> cUSDC, cUSDT <-> USDT, cUSDC <-> USDC, cUSDT <-> cXAUC, cUSDC <-> cXAUC, cEURT <-> cXAUC.',
|
||||
'Multi-hop public routes exist through cXAUC for cEURT <-> cUSDT, cEURT <-> cUSDC, and an alternate cUSDT <-> cUSDC path.',
|
||||
'Mainnet bridge discovery is live for cUSDT -> USDT and cUSDC -> USDC through the configured UniversalCCIPBridge lane.',
|
||||
'External partner templates are available for 1inch, 0x, and LiFi, but Chain 138 remains unsupported on those public partner networks today.',
|
||||
'When partner support is unavailable, the explorer can surface the internal DODO PMM execution plan instead of a dead end.',
|
||||
]
|
||||
|
||||
const requestExamples = [
|
||||
{
|
||||
title: 'Inspect the full route matrix',
|
||||
code: `GET ${publicApiBase}/routes/matrix?includeNonLive=true`,
|
||||
},
|
||||
{
|
||||
title: 'Filter live same-chain swap routes on Chain 138',
|
||||
code: `GET ${publicApiBase}/routes/ingestion?fromChainId=138&routeType=swap`,
|
||||
},
|
||||
{
|
||||
title: 'Generate partner templates for review',
|
||||
code: `GET ${publicApiBase}/routes/partner-payloads?partner=LiFi&amount=1000000&includeUnsupported=true`,
|
||||
},
|
||||
{
|
||||
title: 'Resolve a dispatch candidate',
|
||||
code: `POST ${publicApiBase}/routes/partner-payloads/resolve`,
|
||||
},
|
||||
{
|
||||
title: 'Build the internal fallback plan',
|
||||
code: `POST ${publicApiBase}/routes/internal-execution-plan`,
|
||||
},
|
||||
]
|
||||
|
||||
export default function LiquidityPage() {
|
||||
return (
|
||||
<main className="container mx-auto px-4 py-8">
|
||||
<div className="mb-8 max-w-4xl">
|
||||
<div className="mb-3 inline-flex rounded-full border border-amber-200 bg-amber-50 px-3 py-1 text-xs font-semibold uppercase tracking-[0.2em] text-amber-700">
|
||||
Chain 138 Liquidity Access
|
||||
</div>
|
||||
<h1 className="mb-3 text-4xl font-bold text-gray-900 dark:text-white">
|
||||
Public liquidity, route discovery, and execution access points
|
||||
</h1>
|
||||
<p className="text-lg leading-8 text-gray-600 dark:text-gray-400">
|
||||
This explorer page pulls together the live public DODO PMM liquidity on Chain 138 and the
|
||||
token-aggregation endpoints that DEX aggregators, integrators, and operators can use for
|
||||
route discovery, payload generation, and internal fallback execution planning.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-8 grid gap-4 md:grid-cols-3">
|
||||
<Card>
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">Live public pools</div>
|
||||
<div className="mt-2 text-3xl font-bold text-gray-900 dark:text-white">6</div>
|
||||
<div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Verified public DODO PMM pools on Chain 138.
|
||||
</div>
|
||||
</Card>
|
||||
<Card>
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">Public access path</div>
|
||||
<div className="mt-2 text-lg font-bold text-gray-900 dark:text-white">/token-aggregation/api/v1</div>
|
||||
<div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Explorer-hosted proxy path for route, quote, and reporting APIs.
|
||||
</div>
|
||||
</Card>
|
||||
<Card>
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">Partner status</div>
|
||||
<div className="mt-2 text-3xl font-bold text-gray-900 dark:text-white">Fallback Ready</div>
|
||||
<div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
Mainnet stable bridge routing is live; 1inch, 0x, and LiFi templates remain available for partner integrations, with internal fallback for unsupported Chain 138 execution.
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="mb-8 grid gap-6 lg:grid-cols-[1.2fr_0.8fr]">
|
||||
<Card title="Live Pool Snapshot">
|
||||
<div className="space-y-4">
|
||||
{livePools.map((pool) => (
|
||||
<div
|
||||
key={pool.poolAddress}
|
||||
className="rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40"
|
||||
>
|
||||
<div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
|
||||
<div>
|
||||
<div className="text-base font-semibold text-gray-900 dark:text-white">{pool.pair}</div>
|
||||
<div className="mt-1 break-all text-xs text-gray-500 dark:text-gray-400">
|
||||
Pool: {pool.poolAddress}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Reserves: {pool.reserves}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card title="What Integrators Need To Know">
|
||||
<div className="space-y-3 text-sm leading-6 text-gray-600 dark:text-gray-400">
|
||||
{routeHighlights.map((item) => (
|
||||
<p key={item}>{item}</p>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="mb-8">
|
||||
<Card title="Explorer Access Points">
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
{publicEndpoints.map((endpoint) => (
|
||||
<a
|
||||
key={endpoint.href}
|
||||
href={endpoint.href}
|
||||
className="rounded-2xl border border-gray-200 bg-white p-5 transition hover:border-primary-400 hover:shadow-md dark:border-gray-700 dark:bg-gray-800"
|
||||
>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="text-base font-semibold text-gray-900 dark:text-white">{endpoint.name}</div>
|
||||
<span className="rounded-full bg-primary-50 px-2.5 py-1 text-xs font-semibold uppercase tracking-wide text-primary-700 dark:bg-primary-900/30 dark:text-primary-300">
|
||||
{endpoint.method}
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-3 break-all rounded-xl bg-gray-50 p-3 text-xs text-gray-700 dark:bg-gray-900 dark:text-gray-300">
|
||||
{endpoint.href}
|
||||
</div>
|
||||
<div className="mt-3 text-sm leading-6 text-gray-600 dark:text-gray-400">{endpoint.notes}</div>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="mb-8 grid gap-6 lg:grid-cols-[1fr_1fr]">
|
||||
<Card title="Quick Request Examples">
|
||||
<div className="space-y-4">
|
||||
{requestExamples.map((example) => (
|
||||
<div key={example.title} className="rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40">
|
||||
<div className="mb-2 text-sm font-semibold text-gray-900 dark:text-white">{example.title}</div>
|
||||
<code className="block break-all text-xs leading-6 text-gray-700 dark:text-gray-300">
|
||||
{example.code}
|
||||
</code>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card title="Related Explorer Tools">
|
||||
<div className="space-y-4 text-sm leading-6 text-gray-600 dark:text-gray-400">
|
||||
<p>
|
||||
Use the wallet page for network onboarding and the explorer token list URL, then use this
|
||||
page for route and execution discovery.
|
||||
</p>
|
||||
<p>
|
||||
The route APIs complement the existing route decision tree and market-data APIs already
|
||||
proxied through the explorer.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Link
|
||||
href="/wallet"
|
||||
className="rounded-full bg-primary-600 px-4 py-2 text-sm font-medium text-white transition hover:bg-primary-700"
|
||||
>
|
||||
Open wallet tools
|
||||
</Link>
|
||||
<a
|
||||
href={`${publicApiBase}/routes/tree?chainId=138&amountIn=1000000`}
|
||||
className="rounded-full border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 transition hover:border-primary-400 hover:text-primary-700 dark:border-gray-600 dark:text-gray-300 dark:hover:text-primary-300"
|
||||
>
|
||||
Route tree API
|
||||
</a>
|
||||
<a
|
||||
href="/docs.html"
|
||||
className="rounded-full border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 transition hover:border-primary-400 hover:text-primary-700 dark:border-gray-600 dark:text-gray-300 dark:hover:text-primary-300"
|
||||
>
|
||||
Explorer docs
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { Card } from '@/libs/frontend-ui-primitives'
|
||||
import { Card } from '@/libs/frontend-ui-primitives/Card'
|
||||
import Link from 'next/link'
|
||||
import { blocksApi } from '@/services/api/blocks'
|
||||
|
||||
@@ -93,12 +93,37 @@ export default function Home() {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<div className="mt-4">
|
||||
<Link href="/blocks" className="text-primary-600 hover:underline">
|
||||
View all blocks →
|
||||
</Link>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<div className="mt-8 grid grid-cols-1 gap-4 lg:grid-cols-2">
|
||||
<Card title="Liquidity & Routes">
|
||||
<p className="text-sm leading-6 text-gray-600 dark:text-gray-400">
|
||||
Explore the public Chain 138 DODO PMM liquidity mesh, the canonical route matrix, and the
|
||||
partner payload endpoints exposed through the explorer.
|
||||
</p>
|
||||
<div className="mt-4">
|
||||
<Link href="/liquidity" className="text-primary-600 hover:underline">
|
||||
Open liquidity access →
|
||||
</Link>
|
||||
</div>
|
||||
</Card>
|
||||
<Card title="Wallet & Token Discovery">
|
||||
<p className="text-sm leading-6 text-gray-600 dark:text-gray-400">
|
||||
Add Chain 138, Ethereum Mainnet, and ALL Mainnet to MetaMask, then use the explorer token
|
||||
list URL so supported tokens appear automatically.
|
||||
</p>
|
||||
<div className="mt-4">
|
||||
<Link href="/wallet" className="text-primary-600 hover:underline">
|
||||
Open wallet tools →
|
||||
</Link>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AddToMetaMask } from '@/components/wallet/AddToMetaMask'
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function WalletPage() {
|
||||
return (
|
||||
@@ -8,6 +9,13 @@ export default function WalletPage() {
|
||||
Connect Chain 138 (DeFi Oracle Meta Mainnet) and Ethereum Mainnet to MetaMask and other Web3 wallets. Use the token list URL so tokens and oracles are discoverable.
|
||||
</p>
|
||||
<AddToMetaMask />
|
||||
<div className="mt-6 rounded-lg border border-gray-200 bg-white p-4 text-sm text-gray-600 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400">
|
||||
Need swap and liquidity discovery too? Visit the{' '}
|
||||
<Link href="/liquidity" className="font-medium text-primary-600 hover:underline dark:text-primary-400">
|
||||
Liquidity Access
|
||||
</Link>{' '}
|
||||
page for live Chain 138 pools, route matrix links, partner payload templates, and the internal fallback execution plan endpoints.
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
65
frontend/src/components/common/Footer.tsx
Normal file
65
frontend/src/components/common/Footer.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
const footerLinkClass =
|
||||
'text-gray-600 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-400 transition-colors'
|
||||
|
||||
export default function Footer() {
|
||||
const year = new Date().getFullYear()
|
||||
|
||||
return (
|
||||
<footer className="mt-auto border-t border-gray-200 dark:border-gray-700 bg-white/90 dark:bg-gray-900/90 backdrop-blur">
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<div className="grid gap-6 md:grid-cols-[1.5fr_1fr_1fr]">
|
||||
<div className="space-y-3">
|
||||
<div className="text-lg font-semibold text-gray-900 dark:text-white">
|
||||
SolaceScanScout
|
||||
</div>
|
||||
<p className="max-w-xl text-sm leading-6 text-gray-600 dark:text-gray-400">
|
||||
Built from Blockscout foundations and Solace Bank Group PLC frontend
|
||||
work. Explorer data is powered by Blockscout, Chain 138 RPC, and the
|
||||
companion MetaMask Snap.
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-500">
|
||||
© {year} Solace Bank Group PLC. All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="mb-3 text-sm font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||
Resources
|
||||
</div>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li><a className={footerLinkClass} href="/docs.html">Documentation</a></li>
|
||||
<li><a className={footerLinkClass} href="/liquidity">Liquidity Access</a></li>
|
||||
<li><a className={footerLinkClass} href="/privacy.html">Privacy Policy</a></li>
|
||||
<li><a className={footerLinkClass} href="/terms.html">Terms of Service</a></li>
|
||||
<li><a className={footerLinkClass} href="/acknowledgments.html">Acknowledgments</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="mb-3 text-sm font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||
Contact
|
||||
</div>
|
||||
<div className="space-y-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
<p>
|
||||
Support:{' '}
|
||||
<a className={footerLinkClass} href="mailto:support@d-bis.org">
|
||||
support@d-bis.org
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
Snap site:{' '}
|
||||
<a className={footerLinkClass} href="https://explorer.d-bis.org/snap/">
|
||||
explorer.d-bis.org/snap/
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-xs leading-5 text-gray-500 dark:text-gray-500">
|
||||
Questions about the explorer, chain metadata, route discovery, or liquidity access
|
||||
can be sent to the support mailbox above.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
@@ -91,9 +91,21 @@ export default function Navbar() {
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="flex items-center justify-between h-16">
|
||||
<div className="flex items-center gap-4 md:gap-8">
|
||||
<Link href="/" className="text-xl font-bold text-primary-600 dark:text-primary-400 flex flex-col" onClick={() => setMobileMenuOpen(false)}>
|
||||
<span>SolaceScanScout</span>
|
||||
<span className="text-xs font-normal text-gray-500 dark:text-gray-400">The Defi Oracle Meta Explorer</span>
|
||||
<Link
|
||||
href="/"
|
||||
className="group inline-flex flex-col rounded-xl px-3 py-2 text-xl font-bold text-primary-600 transition-colors hover:bg-primary-50 dark:text-primary-400 dark:hover:bg-gray-700/70"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
aria-label="Go to explorer home"
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="inline-flex h-8 w-8 items-center justify-center rounded-lg bg-primary-600 text-white shadow-sm transition-transform group-hover:-translate-y-0.5 dark:bg-primary-500">
|
||||
<svg className="h-4 w-4" viewBox="0 0 24 24" fill="currentColor" aria-hidden>
|
||||
<path d="M12 2.5 3.5 6.5v11l8.5 4 8.5-4v-11L12 2.5Zm0 2.24 6.44 3.03L12 10.8 5.56 7.77 12 4.74Zm-7 4.63L11 13.1v6.07L5 16.4V9.37Zm9 9.8v-6.07l6-2.92v6.03l-6 2.96Z" />
|
||||
</svg>
|
||||
</span>
|
||||
<span>SolaceScanScout</span>
|
||||
</span>
|
||||
<span className="mt-0.5 text-xs font-normal text-gray-500 transition-colors group-hover:text-gray-700 dark:text-gray-400 dark:group-hover:text-gray-200">The Defi Oracle Meta Explorer</span>
|
||||
</Link>
|
||||
<div className="hidden md:flex items-center gap-1">
|
||||
<NavDropdown
|
||||
@@ -110,6 +122,7 @@ export default function Navbar() {
|
||||
>
|
||||
<DropdownItem href="/search">Search</DropdownItem>
|
||||
<DropdownItem href="/wallet">Wallet</DropdownItem>
|
||||
<DropdownItem href="/liquidity">Liquidity</DropdownItem>
|
||||
</NavDropdown>
|
||||
</div>
|
||||
</div>
|
||||
@@ -154,6 +167,7 @@ export default function Navbar() {
|
||||
<ul className="pl-4 mt-1 space-y-0.5">
|
||||
<li><Link href="/search" className={`block px-3 py-2 rounded-md ${navLink}`} onClick={() => setMobileMenuOpen(false)}>Search</Link></li>
|
||||
<li><Link href="/wallet" className={`block px-3 py-2 rounded-md ${navLink}`} onClick={() => setMobileMenuOpen(false)}>Wallet</Link></li>
|
||||
<li><Link href="/liquidity" className={`block px-3 py-2 rounded-md ${navLink}`} onClick={() => setMobileMenuOpen(false)}>Liquidity</Link></li>
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user