Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/components/CCIP/ChainHero/ChainHero.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.ccip-chain-hero {
background: var(--Page-Background-Alt);
border-bottom: 1px solid var(--gray-200);
min-height: 241px;
}

.ccip-chain-hero__heading {
Expand Down
78 changes: 43 additions & 35 deletions src/components/CCIP/ChainHero/ChainHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ interface ChainHeroProps {
symbol: string
}
environment: Environment
breadcrumbItems?: Array<{
name: string
url: string
}>
}

function ChainHero({ chains, tokens, network, token, environment, lanes }: ChainHeroProps) {
function ChainHero({ chains, tokens, network, token, environment, lanes, breadcrumbItems }: ChainHeroProps) {
// Get chain-specific tooltip configuration
const chainTooltipConfig = network?.chain ? getChainTooltip(network.chain) : null

Expand Down Expand Up @@ -99,47 +103,51 @@ function ChainHero({ chains, tokens, network, token, environment, lanes }: Chain
<div className="ccip-chain-hero__content">
<div className="ccip-chain-hero__top">
<Breadcrumb
items={[
{
name: "CCIP Directory",
url: `/ccip/directory/${environment}`,
},
{
name: network?.name || token?.id || "Current",
url: network
? `/ccip/directory/${environment}/chain/${network.chain}`
: `/ccip/directory/${environment}/token/${token?.id}`,
},
]}
items={
breadcrumbItems || [
{
name: "CCIP Directory",
url: `/ccip/directory/${environment}`,
},
{
name: network?.name || token?.id || "Current",
url: network
? `/ccip/directory/${environment}/chain/${network.chain}`
: `/ccip/directory/${environment}/token/${token?.id}`,
},
]
}
/>
<div className="ccip-chain-hero__chainSearch">
<Search chains={chains} tokens={tokens} small environment={environment} lanes={lanes} />
</div>
</div>

<div className="ccip-chain-hero__heading">
<img
src={network?.logo || token?.logo}
alt=""
className={token?.logo ? "ccip-chain-hero__token-logo" : ""}
onError={({ currentTarget }) => {
currentTarget.onerror = null // prevents looping
currentTarget.src = fallbackTokenIconUrl
}}
/>
<h1>
{network?.name || token?.name}
<span className="ccip-chain-hero__token-logo__symbol">{token?.id}</span>
{(network || token) && (
<div className="ccip-chain-hero__heading">
<img
src={network?.logo || token?.logo}
alt=""
className={token?.logo ? "ccip-chain-hero__token-logo" : ""}
onError={({ currentTarget }) => {
currentTarget.onerror = null // prevents looping
currentTarget.src = fallbackTokenIconUrl
}}
/>
<h1>
{network?.name || token?.name}
<span className="ccip-chain-hero__token-logo__symbol">{token?.id}</span>

{chainTooltipConfig && (
<Tooltip
tip={chainTooltipConfig.content}
hoverable={chainTooltipConfig.hoverable}
hideDelay={chainTooltipConfig.hideDelay}
/>
)}
</h1>
</div>
{chainTooltipConfig && (
<Tooltip
tip={chainTooltipConfig.content}
hoverable={chainTooltipConfig.hoverable}
hideDelay={chainTooltipConfig.hideDelay}
/>
)}
</h1>
</div>
)}
{network && (
<div className="ccip-chain-hero__details">
<div className="ccip-chain-hero__details__item">
Expand Down
124 changes: 124 additions & 0 deletions src/components/CCIP/Tables/VerifiersTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import Address from "~/components/AddressReact.tsx"
import "./Table.css"
import { Environment, Verifier, getVerifierTypeDisplay } from "~/config/data/ccip/index.ts"

Check warning on line 3 in src/components/CCIP/Tables/VerifiersTable.tsx

View workflow job for this annotation

GitHub Actions / eslint

'Environment' is defined but never used

Check warning on line 3 in src/components/CCIP/Tables/VerifiersTable.tsx

View workflow job for this annotation

GitHub Actions / eslint

'Environment' is defined but never used
import TableSearchInput from "./TableSearchInput.tsx"
import { useState } from "react"
import {
getExplorerAddressUrl,
fallbackVerifierIconUrl,
getChainIcon,
getTitle,
directoryToSupportedChain,
getExplorer,
getChainTypeAndFamily,
} from "~/features/utils/index.ts"

interface VerifiersTableProps {
verifiers: Verifier[]
}

function VerifiersTable({ verifiers }: VerifiersTableProps) {
const [search, setSearch] = useState("")

// Transform verifiers data to include network information
const verifiersWithNetworkInfo = verifiers.map((verifier) => {
const supportedChain = directoryToSupportedChain(verifier.network)
const networkName = getTitle(supportedChain) || verifier.network
const networkLogo = getChainIcon(supportedChain) || ""
const explorer = getExplorer(supportedChain)
const { chainType } = getChainTypeAndFamily(supportedChain)

return {
...verifier,
networkName,
networkLogo,
supportedChain,
explorer,
chainType,
}
})

const filteredVerifiers = verifiersWithNetworkInfo.filter(
(verifier) =>
verifier.name.toLowerCase().includes(search.toLowerCase()) ||
verifier.networkName.toLowerCase().includes(search.toLowerCase()) ||
verifier.address.toLowerCase().includes(search.toLowerCase()) ||
getVerifierTypeDisplay(verifier.type).toLowerCase().includes(search.toLowerCase())
)

return (
<>
<div className="ccip-table__filters">
<div className="ccip-table__filters-title">
Verifiers <span>({verifiers.length})</span>
</div>
<TableSearchInput search={search} setSearch={setSearch} />
</div>
<div className="ccip-table__wrapper">
<table className="ccip-table">
<thead>
<tr>
<th>Verifier</th>
<th>Network</th>
<th>Verifier address</th>
<th>Verifier type</th>
</tr>
</thead>
<tbody>
{filteredVerifiers.map((verifier, index) => (

Check warning on line 68 in src/components/CCIP/Tables/VerifiersTable.tsx

View workflow job for this annotation

GitHub Actions / eslint

'index' is defined but never used

Check warning on line 68 in src/components/CCIP/Tables/VerifiersTable.tsx

View workflow job for this annotation

GitHub Actions / eslint

'index' is defined but never used
<tr key={`${verifier.network}-${verifier.address}`}>
<td>
<div className="ccip-table__network-name">
<span className="ccip-table__logoContainer">
<img
src={verifier.logo}
alt={`${verifier.name} verifier logo`}
className="ccip-table__logo"
onError={({ currentTarget }) => {
currentTarget.onerror = null // prevents looping
currentTarget.src = fallbackVerifierIconUrl
}}
/>
</span>
{verifier.name}
</div>
</td>
<td>
<div className="ccip-table__network-name">
<span className="ccip-table__logoContainer">
<img
src={verifier.networkLogo}
alt={`${verifier.networkName} blockchain logo`}
className="ccip-table__logo"
onError={({ currentTarget }) => {
currentTarget.onerror = null // prevents looping
currentTarget.src = fallbackVerifierIconUrl
}}
/>
</span>
{verifier.networkName}
</div>
</td>
<td data-clipboard-type="verifier-address">
<Address
contractUrl={
verifier.explorer
? getExplorerAddressUrl(verifier.explorer, verifier.chainType)(verifier.address)
: ""
}
address={verifier.address}
endLength={4}
/>
</td>
<td>{getVerifierTypeDisplay(verifier.type)}</td>
</tr>
))}
</tbody>
</table>
<div className="ccip-table__notFound">{filteredVerifiers.length === 0 && <>No verifiers found</>}</div>
</div>
</>
)
}

export default VerifiersTable
6 changes: 3 additions & 3 deletions src/components/CCIP/VerifierGrid/VerifierGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function VerifierGrid({ verifiers, environment }: VerifierGridProps) {
items={verifiers}
initialDisplayCount={BEFORE_SEE_MORE}
seeMoreLabel="View all verifiers"
seeMoreLink="/verifiers"
seeMoreLink={`/ccip/directory/${environment}/verifiers`}
renderItem={(verifier) => {
const subtitle = `${verifier.totalNetworks} ${verifier.totalNetworks === 1 ? "network" : "networks"}`
const logoElement = (
Expand All @@ -34,8 +34,8 @@ function VerifierGrid({ verifiers, environment }: VerifierGridProps) {
logo={logoElement}
title={verifier.name}
subtitle={subtitle}
link={`/ccip/directory/${environment}/verifier/${verifier.id}`}
ariaLabel={`View ${verifier.name} verifier details`}
link={`/ccip/directory/${environment}/verifiers`}
ariaLabel={`View verifiers page for ${verifier.name}`}
/>
)
}}
Expand Down
98 changes: 98 additions & 0 deletions src/components/CCIP/Verifiers/Verifiers.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
import CcipDirectoryLayout from "~/layouts/CcipDirectoryLayout.astro"
import { getEntry, render } from "astro:content"
import { getAllNetworks, getAllVerifiers, getSearchLanes, Version, Environment } from "~/config/data/ccip"
import Table from "~/components/CCIP/Tables/VerifiersTable"
import { getAllUniqueVerifiers } from "~/config/data/ccip/data.ts"
import { DOCS_BASE_URL } from "~/utils/structuredData"
import ChainHero from "~/components/CCIP/ChainHero/ChainHero"
import "./Verifiers.css"

interface Props {
environment: Environment
}

const { environment } = Astro.props as Props

const entry = await getEntry("ccip", "index")
if (!entry) {
throw new Error('Could not find "ccip/index" doc. Check src/content/ccip/index.mdx!')
}

const { headings } = await render(entry)

const networks = getAllNetworks({ filter: environment })

const allVerifiers = getAllVerifiers({
environment,
version: Version.V1_2_0,
})

const uniqueVerifiers = getAllUniqueVerifiers({
environment,
version: Version.V1_2_0,
})

const searchLanes = getSearchLanes({ environment })

// Generate dynamic metadata for verifiers page
const environmentText = environment === Environment.Mainnet ? "Mainnet" : "Testnet"
const verifiersMetadata = {
title: `CCIP Verifiers - ${environmentText} Networks`,
description: `View all CCIP verifiers across ${environmentText} networks. Explore ${allVerifiers.length} verifiers, their addresses, types, and supported networks for cross-chain verification.`,
image: "/assets/product-logos/ccip-logo.svg",
excerpt: `CCIP verifiers ${environmentText.toLowerCase()} networks addresses types committee api cross-chain verification blockchain interoperability`,
}

// Generate structured data for verifiers page
const currentPath = new URL(Astro.request.url).pathname
const canonicalForJsonLd = `${DOCS_BASE_URL}${currentPath}`
---

<CcipDirectoryLayout
frontmatter={{
title: verifiersMetadata.title,
section: "ccip",
metadata: {
description: verifiersMetadata.description,
image: verifiersMetadata.image,
excerpt: verifiersMetadata.excerpt,
},
}}
{headings}
environment={environment}
pageTitleOverride={verifiersMetadata.title}
metadataOverride={{
description: verifiersMetadata.description,
image: verifiersMetadata.image,
excerpt: verifiersMetadata.excerpt,
}}
>
<ChainHero
chains={networks}
tokens={uniqueVerifiers.map((verifier) => ({
id: verifier.id,
totalNetworks: verifier.totalNetworks,
logo: verifier.logo,
}))}
lanes={searchLanes}
environment={environment}
breadcrumbItems={[
{
name: "CCIP Directory",
url: `/ccip/directory/${environment}`,
},
{
name: "Verifiers",
url: `/ccip/directory/${environment}/verifiers`,
},
]}
client:load
/>

<section class="layout">
<div>
<Table client:load verifiers={allVerifiers} />
</div>
</section>
</CcipDirectoryLayout>
43 changes: 43 additions & 0 deletions src/components/CCIP/Verifiers/Verifiers.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.layout {
margin: 0 auto;
padding: var(--space-6x);
}

.layout h2 {
color: var(--gray-900);
font-size: 22px;
line-height: var(--space-10x);
padding-bottom: var(--space-4x);
border-bottom: 1px solid var(--gray-200);
margin-bottom: var(--space-6x);
}

.layout h2 span {
color: var(--gray-400);
font-weight: 600;
letter-spacing: 0.5px;
}

.networks__grid {
display: grid;
grid-template-columns: 1fr;
gap: var(--space-8x);
}

.tokens__grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-8x);
}

@media (min-width: 50em) {
.layout {
max-width: 1500px;
}
}

@media (min-width: 992px) {
.layout {
padding: var(--space-10x) var(--space-8x);
}
}
Loading
Loading