Ship bridge lanes, public API access doc, and WalletConnect client stack.
Align CCIP catalog UX with 11-lane config-ready routes, document the no-key public API decision, and enable browser WalletConnect pairing with backend session registration and deploy-time project ID wiring. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -472,7 +472,15 @@ export default function BridgeMonitoringPage({
|
||||
{bridgeRoutes.lastModified ? ` · updated ${relativeAge(bridgeRoutes.lastModified)}` : ''})
|
||||
</>
|
||||
) : null}
|
||||
.
|
||||
. Gnosis, Cronos, Celo, and Wemix lanes are aligned to deployed CCIP receivers — fund LINK on each remote bridge before live traffic.
|
||||
</p>
|
||||
<p className="mb-4 text-sm text-gray-600 dark:text-gray-400">
|
||||
Operator runbook:{' '}
|
||||
<Link href="/docs/public-api-access" className="text-primary-600 hover:underline">
|
||||
public API access
|
||||
</Link>{' '}
|
||||
· config-ready chain completion in repo{' '}
|
||||
<code className="rounded bg-gray-100 px-1.5 py-0.5 text-xs dark:bg-gray-900">CONFIG_READY_CHAINS_COMPLETION_RUNBOOK.md</code>
|
||||
</p>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="min-w-full text-sm">
|
||||
|
||||
@@ -7,6 +7,8 @@ import type {
|
||||
} from '@/components/wallet/AddToMetaMask'
|
||||
import { AddToMetaMask } from '@/components/wallet/AddToMetaMask'
|
||||
import WalletConnectPostureNote from '@/components/wallet/WalletConnectPostureNote'
|
||||
import { connectAndAuthenticateWalletConnect, getActiveWalletConnectSessionId, isWalletConnectClientReady, loadWalletConnectConfig } from '@/services/wallet/walletConnectClient'
|
||||
import { registerWalletConnectSession } from '@/services/api/walletConnect'
|
||||
import Link from 'next/link'
|
||||
import { Explain, useUiMode } from '@/components/common/UiModeContext'
|
||||
import { accessApi, type WalletAccessSession } from '@/services/api/access'
|
||||
@@ -48,6 +50,8 @@ export default function WalletPage(props: WalletPageProps) {
|
||||
const [walletSession, setWalletSession] = useState<WalletAccessSession | null>(null)
|
||||
const [connectingWallet, setConnectingWallet] = useState(false)
|
||||
const [walletError, setWalletError] = useState<string | null>(null)
|
||||
const [walletConnectReady, setWalletConnectReady] = useState(false)
|
||||
const [connectingWalletConnect, setConnectingWalletConnect] = useState(false)
|
||||
const [copiedAddress, setCopiedAddress] = useState(false)
|
||||
const [watchlistEntries, setWatchlistEntries] = useState<string[]>([])
|
||||
const [addressInfo, setAddressInfo] = useState<AddressInfo | null>(null)
|
||||
@@ -68,6 +72,7 @@ export default function WalletPage(props: WalletPageProps) {
|
||||
|
||||
syncSession()
|
||||
syncWatchlist()
|
||||
void loadWalletConnectConfig().then((config) => setWalletConnectReady(isWalletConnectClientReady(config)))
|
||||
window.addEventListener('explorer-access-session-changed', syncSession)
|
||||
window.addEventListener('storage', syncWatchlist)
|
||||
return () => {
|
||||
@@ -76,6 +81,30 @@ export default function WalletPage(props: WalletPageProps) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleConnectWalletConnect = async () => {
|
||||
setConnectingWalletConnect(true)
|
||||
setWalletError(null)
|
||||
try {
|
||||
const config = await loadWalletConnectConfig()
|
||||
if (!isWalletConnectClientReady(config)) {
|
||||
throw new Error('WalletConnect is not enabled. Set WALLETCONNECT_PROJECT_ID on the explorer backend.')
|
||||
}
|
||||
const result = await connectAndAuthenticateWalletConnect(config, async (resolveAddress, signMessage) => {
|
||||
const session = await accessApi.connectWalletSessionWithSigner(resolveAddress, signMessage)
|
||||
setWalletSession(session)
|
||||
return { address: session.address }
|
||||
})
|
||||
const sessionId = getActiveWalletConnectSessionId()
|
||||
if (sessionId && result.address) {
|
||||
await registerWalletConnectSession({ sessionId, address: result.address, chainId: 138 })
|
||||
}
|
||||
} catch (error) {
|
||||
setWalletError(error instanceof Error ? error.message : 'WalletConnect connection failed.')
|
||||
} finally {
|
||||
setConnectingWalletConnect(false)
|
||||
}
|
||||
}
|
||||
|
||||
const handleConnectWallet = async () => {
|
||||
setConnectingWallet(true)
|
||||
setWalletError(null)
|
||||
@@ -279,12 +308,25 @@ export default function WalletPage(props: WalletPageProps) {
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleConnectWallet}
|
||||
onClick={() => void handleConnectWallet()}
|
||||
disabled={connectingWallet}
|
||||
className="rounded-lg bg-primary-600 px-3 py-2 text-sm font-semibold text-white hover:bg-primary-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 disabled:cursor-not-allowed disabled:opacity-70"
|
||||
>
|
||||
{connectingWallet ? 'Connecting wallet…' : 'Connect wallet'}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void handleConnectWalletConnect()}
|
||||
disabled={!walletConnectReady || connectingWalletConnect}
|
||||
title={
|
||||
walletConnectReady
|
||||
? 'Pair a mobile wallet via WalletConnect QR'
|
||||
: 'Set WALLETCONNECT_PROJECT_ID on the explorer backend to enable WalletConnect'
|
||||
}
|
||||
className="rounded-lg border border-indigo-300 px-3 py-2 text-sm font-semibold text-indigo-700 hover:bg-indigo-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 disabled:cursor-not-allowed disabled:opacity-60 dark:border-indigo-800 dark:text-indigo-300 dark:hover:bg-indigo-950/20"
|
||||
>
|
||||
{connectingWalletConnect ? 'Opening WalletConnect…' : 'WalletConnect'}
|
||||
</button>
|
||||
<Link
|
||||
href="/access"
|
||||
className="rounded-lg border border-gray-300 px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 dark:border-gray-700 dark:text-gray-200 dark:hover:bg-gray-900/60"
|
||||
|
||||
Reference in New Issue
Block a user