feat: bridge lane health API and dual-chain token list updates
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1666,8 +1666,23 @@
|
||||
"tags": [
|
||||
"gru",
|
||||
"compliant",
|
||||
"electronic-money"
|
||||
]
|
||||
"electronic-money",
|
||||
"fiat",
|
||||
"cash"
|
||||
],
|
||||
"extensions": {
|
||||
"assetClass": "Cash & Equivalents",
|
||||
"assetGroup": "MMF / Repo",
|
||||
"instrumentType": "eMoney",
|
||||
"underlying": "USD",
|
||||
"gruLayer": "M1",
|
||||
"rwaEligible": false,
|
||||
"category": "gru-emoney",
|
||||
"currency": "USD",
|
||||
"settlement": "fiat",
|
||||
"cashLike": true,
|
||||
"backing": "cash,cash-equivalents"
|
||||
}
|
||||
},
|
||||
{
|
||||
"chainId": 138,
|
||||
@@ -1679,8 +1694,23 @@
|
||||
"tags": [
|
||||
"gru",
|
||||
"compliant",
|
||||
"treasury-bond"
|
||||
]
|
||||
"treasury-bond",
|
||||
"fiat",
|
||||
"cash"
|
||||
],
|
||||
"extensions": {
|
||||
"assetClass": "Cash & Equivalents",
|
||||
"assetGroup": "MMF / Repo",
|
||||
"instrumentType": "eMoney",
|
||||
"underlying": "USD",
|
||||
"gruLayer": "M1",
|
||||
"rwaEligible": false,
|
||||
"category": "gru-emoney",
|
||||
"currency": "USD",
|
||||
"settlement": "fiat",
|
||||
"cashLike": true,
|
||||
"backing": "cash,cash-equivalents"
|
||||
}
|
||||
},
|
||||
{
|
||||
"chainId": 138,
|
||||
@@ -1691,12 +1721,19 @@
|
||||
"logoURI": "https://explorer.d-bis.org/token-icons/cXAUC.png",
|
||||
"tags": [
|
||||
"gru",
|
||||
"compliant",
|
||||
"commodity"
|
||||
"compliant"
|
||||
],
|
||||
"extensions": {
|
||||
"unitOfAccount": "troy_ounce",
|
||||
"unitDescription": "1 full token (10^decimals base units) = 1 troy oz fine gold"
|
||||
"unitDescription": "1 full token (10^decimals base units) = 1 troy oz fine gold",
|
||||
"assetClass": "Commodities",
|
||||
"assetGroup": "Precious Metals",
|
||||
"instrumentType": "eMoney",
|
||||
"underlying": "Gold",
|
||||
"gruLayer": "M1",
|
||||
"rwaEligible": false,
|
||||
"category": "gru-emoney",
|
||||
"cashLike": false
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -1708,12 +1745,19 @@
|
||||
"logoURI": "https://explorer.d-bis.org/token-icons/cXAUT.png",
|
||||
"tags": [
|
||||
"gru",
|
||||
"compliant",
|
||||
"commodity"
|
||||
"compliant"
|
||||
],
|
||||
"extensions": {
|
||||
"unitOfAccount": "troy_ounce",
|
||||
"unitDescription": "1 full token (10^decimals base units) = 1 troy oz fine gold"
|
||||
"unitDescription": "1 full token (10^decimals base units) = 1 troy oz fine gold",
|
||||
"assetClass": "Commodities",
|
||||
"assetGroup": "Precious Metals",
|
||||
"instrumentType": "eMoney",
|
||||
"underlying": "Gold",
|
||||
"gruLayer": "M1",
|
||||
"rwaEligible": false,
|
||||
"category": "gru-emoney",
|
||||
"cashLike": false
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
21
config/explorer-bridge-proof-transfers.example.json
Normal file
21
config/explorer-bridge-proof-transfers.example.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"updated": "2026-05-23T13:07:00Z",
|
||||
"sprint": "tier-a-week-3",
|
||||
"note": "Example shape for MISSION_CONTROL_PROOF_TRANSFERS_JSON. Operator live file: reports/status/bridge-lane-proof-transfers-latest.json (gitignored). Populate with scripts/bridge/run-lane-proof-transfers.sh --execute.",
|
||||
"lanes": {
|
||||
"chain138": [
|
||||
{
|
||||
"tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"amount_eth": "0.001",
|
||||
"dest_chain": "mainnet",
|
||||
"dest_selector": "5009297550715157269",
|
||||
"bridge": "0xcacfd227A040002e49e2e01626363071324f820a",
|
||||
"recorded_at": "2026-05-23T00:00:00Z"
|
||||
}
|
||||
],
|
||||
"gnosis": [],
|
||||
"cronos": [],
|
||||
"celo": [],
|
||||
"wemix": []
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import SubsystemPosturePanel from '@/components/common/SubsystemPosturePanel'
|
||||
import TokenListSurfaceNote from '@/components/common/TokenListSurfaceNote'
|
||||
import OperationsSurfaceNav from '@/components/explorer/OperationsSurfaceNav'
|
||||
import OperationsActionGrid from '@/components/explorer/OperationsActionGrid'
|
||||
import BridgeLaneHealthPanel from '@/components/explorer/BridgeLaneHealthPanel'
|
||||
import { resolveEffectiveFreshness } from '@/utils/explorerFreshness'
|
||||
import { statsApi, type ExplorerStats } from '@/services/api/stats'
|
||||
|
||||
@@ -156,6 +157,25 @@ export default function OperationsHubPage({
|
||||
new Set((tokenList?.tokens || []).map((token) => token.symbol).filter(Boolean) as string[])
|
||||
).slice(0, 8)
|
||||
}, [tokenList])
|
||||
const laneSummary = useMemo(() => {
|
||||
const lanes = bridgeStatus?.data?.bridge_lanes?.lanes || []
|
||||
if (lanes.length === 0) return null
|
||||
|
||||
const funded = lanes.filter((lane) => String(lane.status || '').toLowerCase() === 'funded').length
|
||||
const unfunded = lanes.filter((lane) => String(lane.status || '').toLowerCase() === 'unfunded').length
|
||||
const proofRecorded = lanes.filter(
|
||||
(lane) => String(lane.proof_status || '').toLowerCase() === 'proof-recorded'
|
||||
).length
|
||||
|
||||
return {
|
||||
total: lanes.length,
|
||||
funded,
|
||||
unfunded,
|
||||
proofRecorded,
|
||||
updatedAt: bridgeStatus?.data?.bridge_lanes?.updated_at,
|
||||
}
|
||||
}, [bridgeStatus])
|
||||
|
||||
const activityContext = useMemo(
|
||||
() =>
|
||||
summarizeChainActivity({
|
||||
@@ -231,6 +251,14 @@ export default function OperationsHubPage({
|
||||
<div className="mt-2 text-sm text-gray-700 dark:text-gray-300">
|
||||
{relayCount} managed lanes · queue {totalQueue}
|
||||
</div>
|
||||
{laneSummary ? (
|
||||
<div className="mt-1 text-sm text-gray-700 dark:text-gray-300">
|
||||
{laneSummary.funded}/{laneSummary.total} config-ready funded
|
||||
{laneSummary.unfunded > 0 ? ` · ${laneSummary.unfunded} unfunded` : ''}
|
||||
{' · '}
|
||||
{laneSummary.proofRecorded}/{laneSummary.total} proof-recorded
|
||||
</div>
|
||||
) : null}
|
||||
</Card>
|
||||
|
||||
<Card className="border border-emerald-200 bg-emerald-50/70 dark:border-emerald-900/50 dark:bg-emerald-950/20">
|
||||
@@ -312,6 +340,23 @@ export default function OperationsHubPage({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{laneSummary ? (
|
||||
<div className="mt-4 rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-900/40">
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">Config-ready lanes</div>
|
||||
<div className="mt-1 text-lg font-semibold text-gray-900 dark:text-white">
|
||||
{laneSummary.funded}/{laneSummary.total} funded · {laneSummary.proofRecorded}/{laneSummary.total} proof-recorded
|
||||
</div>
|
||||
<div className="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||
{mode === 'guided'
|
||||
? 'Remote CCIP bridge LINK balances and operator proof hashes. Full lane table below.'
|
||||
: 'Lane funding and proof posture from bridge status API.'}
|
||||
{' '}
|
||||
<Link href="/bridge" className="font-semibold text-primary-600 hover:underline">
|
||||
Open bridge monitoring
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</Card>
|
||||
|
||||
<Card title="Public Config Highlights">
|
||||
@@ -342,6 +387,8 @@ export default function OperationsHubPage({
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<BridgeLaneHealthPanel laneHealth={bridgeStatus?.data?.bridge_lanes} />
|
||||
|
||||
<OperationsActionGrid actions={page.actions} />
|
||||
</div>
|
||||
)
|
||||
|
||||
0
scripts/deploy-explorer-ai-to-vmid5000.sh
Normal file → Executable file
0
scripts/deploy-explorer-ai-to-vmid5000.sh
Normal file → Executable file
@@ -37,6 +37,8 @@ test.describe('Explorer sprint smoke', () => {
|
||||
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.getByText(/Extended Metamask dual-chain catalog/i).first()).toBeVisible({ timeout: 10000 })
|
||||
await expect(page.getByText(/Config-ready lane health/i).first()).toBeVisible({ timeout: 15000 })
|
||||
await expect(page.getByText(/unfunded|funded/i).first()).toBeVisible({ timeout: 10000 })
|
||||
})
|
||||
|
||||
test('bridge page loads CCIP route catalog', async ({ page }) => {
|
||||
|
||||
Reference in New Issue
Block a user