diff --git a/public/assets/icons/external-button-link.svg b/public/assets/icons/external-button-link.svg
new file mode 100644
index 00000000000..d2500a01efe
--- /dev/null
+++ b/public/assets/icons/external-button-link.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/public/assets/icons/plus.svg b/public/assets/icons/plus.svg
new file mode 100644
index 00000000000..53b4fe4ff2e
--- /dev/null
+++ b/public/assets/icons/plus.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/components/CCIP/Chain/Chain.astro b/src/components/CCIP/Chain/Chain.astro
index 7d421e23d16..f4f5ec766ac 100644
--- a/src/components/CCIP/Chain/Chain.astro
+++ b/src/components/CCIP/Chain/Chain.astro
@@ -3,6 +3,7 @@ import CcipLayout from "~/layouts/CcipLayout.astro"
import { getEntry, render } from "astro:content"
import {
Environment,
+ Network,
getAllNetworkLanes,
getAllNetworks,
getSearchLanes,
@@ -16,7 +17,7 @@ import ChainTokenGrid from "./ChainTokenGrid"
interface Props {
environment: Environment
- network: any
+ network: Network
}
const { environment, network } = Astro.props as Props
@@ -79,7 +80,18 @@ const searchLanes = getSearchLanes({ environment })
diff --git a/src/components/CCIP/Chain/ChainTokenGrid.tsx b/src/components/CCIP/Chain/ChainTokenGrid.tsx
index 703d27672f8..ad2502efcff 100644
--- a/src/components/CCIP/Chain/ChainTokenGrid.tsx
+++ b/src/components/CCIP/Chain/ChainTokenGrid.tsx
@@ -1,4 +1,4 @@
-import { Environment, Version, PoolType } from "~/config/data/ccip/types.ts"
+import { Environment, Version, Network } from "~/config/data/ccip/types.ts"
import { getAllTokenLanes, getTokenData } from "~/config/data/ccip/data.ts"
import TokenCard from "../Cards/TokenCard.tsx"
import { drawerContentStore } from "../Drawer/drawerStore.ts"
@@ -7,7 +7,6 @@ import { directoryToSupportedChain, getChainIcon, getChainTypeAndFamily, getTitl
import { useState } from "react"
import "./ChainTokenGrid.css"
import SeeMore from "../SeeMore/SeeMore.tsx"
-import { ExplorerInfo } from "~/config/types.ts"
interface ChainTokenGridProps {
tokens: {
@@ -15,20 +14,7 @@ interface ChainTokenGridProps {
logo: string
totalNetworks: number
}[]
- network: {
- name: string
- key: string
- logo: string
- tokenId: string
- tokenLogo: string
- tokenName: string
- tokenSymbol: string
- tokenDecimals: number
- tokenAddress: string
- tokenPoolType: PoolType
- tokenPoolAddress: string
- explorer: ExplorerInfo
- }
+ network: Network
environment: Environment
}
diff --git a/src/components/CCIP/ChainHero/ChainHero.tsx b/src/components/CCIP/ChainHero/ChainHero.tsx
index 89ff9848c0b..b797482737f 100644
--- a/src/components/CCIP/ChainHero/ChainHero.tsx
+++ b/src/components/CCIP/ChainHero/ChainHero.tsx
@@ -1,4 +1,4 @@
-import { Environment, LaneConfig, Version } from "~/config/data/ccip/types.ts"
+import { Environment, LaneConfig, Network, Version } from "~/config/data/ccip/types.ts"
import { getTokenData } from "~/config/data/ccip/data.ts"
import Address from "~/components/AddressReact.tsx"
import Breadcrumb from "../Breadcrumb/Breadcrumb.tsx"
@@ -44,35 +44,7 @@ interface ChainHeroProps {
}
lane: LaneConfig
}[]
- network?: {
- name: string
- logo: string
- totalLanes: number
- totalTokens: number
- chain: string
- chainType: ChainType
- tokenAdminRegistry?: string
- registryModule?: string
- router?: {
- name: string
- address: string
- }
- explorer: ExplorerInfo
- routerExplorerUrl: string
- chainSelector: string
- feeTokens?: string[]
- nativeToken?: {
- name: string
- symbol: string
- logo: string
- }
- armProxy: {
- address: string
- version: string
- }
- feeQuoter?: string
- rmnPermeable?: boolean
- }
+ network?: Network
token?: {
id: string
name: string
@@ -85,11 +57,11 @@ interface ChainHeroProps {
function ChainHero({ chains, tokens, network, token, environment, lanes }: ChainHeroProps) {
const feeTokensWithAddress =
network?.feeTokens?.map((feeToken) => {
- const logo = getTokenIconUrl(feeToken)
+ const logo = feeToken.logo
const token = getTokenData({
environment,
version: Version.V1_2_0,
- tokenId: feeToken,
+ tokenId: feeToken.name,
})
const explorer = network.explorer || {}
const address = token[network.chain]?.tokenAddress
@@ -113,7 +85,7 @@ function ChainHero({ chains, tokens, network, token, environment, lanes }: Chain
if (!network) return
// We making sure the Native Currency is not already part of the FeeToken
return feeTokensWithAddress?.some((feeToken) => {
- return feeToken.token.toLowerCase() === nativeCurrency?.symbol.toLowerCase()
+ return feeToken.token.name.toLowerCase() === nativeCurrency?.symbol.toLowerCase()
})
}
@@ -346,9 +318,9 @@ function ChainHero({ chains, tokens, network, token, environment, lanes }: Chain
height="20px"
className="ccip-chain-hero__feeTokens__item__logo"
>
-
+
- {token}
+ {token.name}
))}
diff --git a/src/components/CCIP/Tables/ChainTable.tsx b/src/components/CCIP/Tables/ChainTable.tsx
index 492295373ac..c6a7cf871ff 100644
--- a/src/components/CCIP/Tables/ChainTable.tsx
+++ b/src/components/CCIP/Tables/ChainTable.tsx
@@ -7,9 +7,8 @@ import { getExplorerAddressUrl } from "~/features/utils/index.ts"
import { drawerContentStore } from "../Drawer/drawerStore.ts"
import LaneDrawer from "../Drawer/LaneDrawer.tsx"
import { Environment, Version, LaneFilter } from "~/config/data/ccip/types.ts"
-import { getLane, getOperationalState } from "~/config/data/ccip/data.ts"
+import { getLane } from "~/config/data/ccip/data.ts"
import { ExplorerInfo, SupportedChain, ChainType } from "~/config/types.ts"
-import { clsx } from "~/lib/clsx/clsx.ts"
import SeeMore from "../SeeMore/SeeMore.tsx"
import { Tooltip } from "~/features/common/Tooltip/Tooltip.tsx"
@@ -38,14 +37,12 @@ interface TableProps {
explorer: ExplorerInfo
}
-const BEFORE_SEE_MORE = 12 // Number of networks to show before the "See more" button, 7 rows
+const BEFORE_SEE_MORE = 12
function ChainTable({ lanes, explorer, sourceNetwork, environment }: TableProps) {
const [inOutbound, setInOutbound] = useState(LaneFilter.Outbound)
const [search, setSearch] = useState("")
const [seeMore, setSeeMore] = useState(lanes.length <= BEFORE_SEE_MORE)
- const [statuses, setStatuses] = useState>({})
- const [loadingStatuses, setLoadingStatuses] = useState(true)
useEffect(() => {
if (search.length > 0) {
@@ -53,20 +50,9 @@ function ChainTable({ lanes, explorer, sourceNetwork, environment }: TableProps)
}
}, [search])
- useEffect(() => {
- const fetchOperationalState = async (network) => {
- if (network) {
- const result = await getOperationalState(network)
- setStatuses(result)
- setLoadingStatuses(false)
- }
- }
- fetchOperationalState(sourceNetwork.key)
- }, [sourceNetwork])
-
return (
<>
-
+
setInOutbound(key as LaneFilter)}
/>
-
+
{inOutbound === LaneFilter.Outbound ? "Destination" : "Source"} network |
-
+ |
{inOutbound === LaneFilter.Outbound ? (
<>
OnRamp address
@@ -95,13 +99,8 @@ function ChainTable({ lanes, explorer, sourceNetwork, environment }: TableProps)
)}
>
@@ -109,7 +108,6 @@ function ChainTable({ lanes, explorer, sourceNetwork, environment }: TableProps)
"OffRamp address"
)}
|
- Status |
@@ -150,7 +148,10 @@ function ChainTable({ lanes, explorer, sourceNetwork, environment }: TableProps)
{network.name}
-
+ |
|
-
- {loadingStatuses ? (
- "Loading..."
- ) : (
-
- {statuses[network.key]?.toLocaleLowerCase() && (
-
- )}
- {statuses[network.key]?.toLocaleLowerCase() || "Status unavailable"}
-
- )}
- |
))}
diff --git a/src/components/CCIP/Tables/Table.css b/src/components/CCIP/Tables/Table.css
index cfac6cd8533..e0c6734178d 100644
--- a/src/components/CCIP/Tables/Table.css
+++ b/src/components/CCIP/Tables/Table.css
@@ -192,3 +192,64 @@
display: inline-block !important;
vertical-align: middle !important;
}
+
+/* ChainTable specific filter layout */
+.ccip-table__filters--chain {
+ flex-wrap: nowrap;
+}
+
+.ccip-table__filters__actions {
+ display: flex;
+ align-items: center;
+ gap: var(--space-3x);
+ flex-shrink: 0;
+}
+
+.ccip-table__filters__search-container {
+ max-width: 150px;
+ flex-shrink: 0;
+}
+
+.ccip-table__filters__external-button {
+ white-space: nowrap;
+ display: flex;
+ align-items: center;
+ gap: var(--space-2x);
+}
+
+.ccip-table__filters__external-icon {
+ width: 1em;
+ height: 1em;
+}
+
+/* Responsive behavior for ChainTable */
+@media (max-width: 768px) {
+ .ccip-table__filters--chain {
+ flex-direction: column;
+ align-items: stretch;
+ gap: var(--space-3x);
+ }
+
+ .ccip-table__filters__actions {
+ justify-content: space-between;
+ width: 100%;
+ }
+
+ .ccip-table__filters__search-container {
+ min-width: 0;
+ max-width: none;
+ flex: 1;
+ }
+}
+
+@media (max-width: 480px) {
+ .ccip-table__filters__actions {
+ flex-direction: column;
+ gap: var(--space-3x);
+ }
+
+ .ccip-table__filters__external-button {
+ width: 100%;
+ justify-content: center;
+ }
+}
diff --git a/src/components/DocsNavigation/DocsNavigationDesktop/DocsNavigationDesktop.tsx b/src/components/DocsNavigation/DocsNavigationDesktop/DocsNavigationDesktop.tsx
index 6d4a2482118..ac24d6ab91a 100644
--- a/src/components/DocsNavigation/DocsNavigationDesktop/DocsNavigationDesktop.tsx
+++ b/src/components/DocsNavigation/DocsNavigationDesktop/DocsNavigationDesktop.tsx
@@ -44,6 +44,7 @@ function DocsNavigationDesktop({
diff --git a/src/config/data/ccip/data.ts b/src/config/data/ccip/data.ts
index f52c5d29527..efd6eab4dcd 100644
--- a/src/config/data/ccip/data.ts
+++ b/src/config/data/ccip/data.ts
@@ -21,6 +21,8 @@ import {
getTitle,
getChainTypeAndFamily,
supportedChainToChainInRdd,
+ getTokenIconUrl,
+ getNativeCurrency,
} from "@features/utils/index.ts"
// For mainnet
@@ -409,6 +411,8 @@ export const getAllNetworks = ({ filter }: { filter: Environment }): Network[] =
const router = chains[chain].router
if (!explorer) throw Error(`Explorer not found for ${supportedChain}`)
const routerExplorerUrl = getExplorerAddressUrl(explorer)(router.address)
+ const nativeToken = getNativeCurrency(supportedChain)
+ if (!nativeToken) throw Error(`Native token not found for ${supportedChain}`)
// Determine chain type based on chain name
const { chainType } = getChainTypeAndFamily(supportedChain)
@@ -428,11 +432,14 @@ export const getAllNetworks = ({ filter }: { filter: Environment }): Network[] =
routerExplorerUrl,
chainSelector: chains[chain].chainSelector,
nativeToken: {
- name: chains[chain]?.nativeToken?.name || "",
- symbol: chains[chain]?.nativeToken?.symbol || "",
- logo: chains[chain]?.nativeToken?.logo || "",
+ name: nativeToken.name,
+ symbol: nativeToken.symbol,
+ logo: getTokenIconUrl(nativeToken.symbol),
},
- feeTokens: chains[chain].feeTokens,
+ feeTokens: chains[chain].feeTokens?.map((tokenName: string) => ({
+ name: tokenName,
+ logo: getTokenIconUrl(tokenName),
+ })),
armProxy: chains[chain].armProxy,
feeQuoter: chainType === "solana" ? chains[chain]?.feeQuoter : undefined,
rmnPermeable: chains[chain]?.rmnPermeable,
@@ -667,12 +674,3 @@ export function getSearchLanes({ environment }: { environment: Environment }) {
return 0
})
}
-
-export async function getOperationalState(chain: string) {
- const url = `/api/ccip/lane-statuses?sourceNetworkId=${chain}`
- const response = await fetch(url)
- if (response.status !== 200) {
- return {}
- }
- return response.json()
-}
diff --git a/src/features/utils/index.ts b/src/features/utils/index.ts
index e3ee0e61116..85652327c5d 100644
--- a/src/features/utils/index.ts
+++ b/src/features/utils/index.ts
@@ -133,7 +133,7 @@ const transformTokenName = (token: string): string => {
}
export const getTokenIconUrl = (token: string) => {
- if (!token) return
+ if (!token) return ""
return `https://d2f70xi62kby8n.cloudfront.net/tokens/${transformTokenName(token)}.webp?auto=compress%2Cformat`
}
diff --git a/src/pages/api/ccip/lane-statuses.ts b/src/pages/api/ccip/lane-statuses.ts
deleted file mode 100644
index 50bd6cc888c..00000000000
--- a/src/pages/api/ccip/lane-statuses.ts
+++ /dev/null
@@ -1,318 +0,0 @@
-import type { APIRoute } from "astro"
-import { client } from "@graphql/graphqlClient.ts"
-import {
- LaneStatusesFilteredDocument,
- LaneStatusesFilteredQuery,
- LaneStatusesFilteredQueryVariables,
-} from "@graphql/generated.ts"
-import {
- commonHeaders,
- getEnvironmentAndConfig,
- resolveChainOrThrow,
- checkIfChainIsCursed,
- withTimeout,
- structuredLog,
- LogLevel,
-} from "./utils.ts"
-import { ChainType, SupportedChain } from "@config/index.ts"
-import { getProviderForChain } from "@config/web3Providers.ts"
-import { Environment, getSelectorEntry, LaneStatus } from "@config/data/ccip/index.ts"
-import { getChainId, getChainTypeAndFamily } from "@features/utils/index.ts"
-
-export const prerender = false
-const timeoutCurseCheck = 10000
-
-export const GET: APIRoute = async ({ request }) => {
- try {
- const url = new URL(request.url)
- const sourceNetworkId = url.searchParams.get("sourceNetworkId")
- const requestId = request.headers.get("x-request-id") || "unknown"
-
- structuredLog(LogLevel.INFO, {
- message: "Fetching lane statuses",
- requestId,
- sourceNetworkId,
- })
-
- // Validate required parameters
- if (!sourceNetworkId) {
- return new Response(
- JSON.stringify({
- errorType: "MissingParameters",
- errorMessage: "Missing required parameters: sourceNetworkId is required.",
- }),
- { status: 400, headers: commonHeaders }
- )
- }
-
- // Determine the environment and load the configuration
- const envConfig = getEnvironmentAndConfig(sourceNetworkId)
- if (!envConfig) {
- structuredLog(LogLevel.ERROR, {
- message: "Invalid source network ID",
- requestId,
- sourceNetworkId,
- })
- return new Response(
- JSON.stringify({
- errorType: "InvalidNetwork",
- errorMessage: `Invalid source network ID: ${sourceNetworkId}`,
- }),
- { status: 400, headers: commonHeaders }
- )
- }
-
- const { environment, chainsConfig, sourceRouterAddress, destinationNetworkIds } = envConfig
-
- // Resolve the source chain
- let sourceChain: SupportedChain
- let sourceChainAtlas: string
- let sourceChainType: ChainType
- try {
- sourceChain = resolveChainOrThrow(sourceNetworkId)
- const { chainType } = getChainTypeAndFamily(sourceChain)
- sourceChainType = chainType
- const sourceChainId = getChainId(sourceChain)
- sourceChainAtlas = sourceChainId ? getSelectorEntry(sourceChainId, chainType)?.name || "" : ""
- } catch (error) {
- structuredLog(LogLevel.ERROR, {
- message: "Error resolving source chain",
- requestId,
- sourceNetworkId,
- error: error instanceof Error ? error.message : String(error),
- })
- return new Response(
- JSON.stringify({
- errorType: "InvalidNetwork",
- errorMessage: error.message,
- }),
- { status: 500, headers: commonHeaders }
- )
- }
-
- // Check if the source chain is cursed
- let isSourceChainCursed = false
- if (sourceChainType === "evm") {
- try {
- const sourceProvider = getProviderForChain(sourceChain)
- isSourceChainCursed = await withTimeout(
- checkIfChainIsCursed(sourceProvider, sourceChain, sourceRouterAddress),
- timeoutCurseCheck,
- `Timeout while checking if source chain ${sourceChain} is cursed`
- )
- } catch (error) {
- structuredLog(LogLevel.ERROR, {
- message: "Error checking if source chain is cursed",
- requestId,
- sourceChain,
- error: error instanceof Error ? error.message : String(error),
- })
- // Continue execution instead of returning 500
- }
- }
-
- const statuses: Record = {}
- const failedCurseChecks: string[] = []
-
- if (isSourceChainCursed) {
- destinationNetworkIds.forEach((id) => {
- statuses[id] = LaneStatus.CURSED
- })
- return new Response(JSON.stringify(statuses), {
- status: 200,
- headers: {
- ...commonHeaders,
- "Cache-Control": "s-max-age=300, stale-while-revalidate",
- "CDN-Cache-Control": "max-age=300",
- "Vercel-CDN-Cache-Control": "max-age=300",
- },
- })
- }
-
- const validDestinationNetworkIds: string[] = []
- const destinationChecks: Promise[] = []
-
- const atlasNameToIdMap: Record = {}
-
- for (const id of destinationNetworkIds) {
- const destinationCheck = async () => {
- try {
- const destinationChain = resolveChainOrThrow(id)
- const { chainType: destinationChainType } = getChainTypeAndFamily(destinationChain)
- const destinationChainId = getChainId(destinationChain)
- const destinationChainAtlas = destinationChainId
- ? getSelectorEntry(destinationChainId, destinationChainType)?.name || ""
- : ""
-
- atlasNameToIdMap[destinationChainAtlas] = id
-
- // Attempt to get the provider and check if the chain is cursed
- if (destinationChainType === "evm") {
- try {
- const provider = getProviderForChain(destinationChain)
- const destinationRouterAddress = chainsConfig[id].router.address
-
- const isDestinationCursed = await withTimeout(
- checkIfChainIsCursed(provider, destinationChain, destinationRouterAddress),
- timeoutCurseCheck,
- `Timeout while checking if destination chain ${destinationChain} is cursed`
- )
-
- if (isDestinationCursed) {
- statuses[id] = LaneStatus.CURSED
- } else {
- validDestinationNetworkIds.push(destinationChainAtlas) // Push if no curse detected
- }
- } catch (innerError) {
- console.error(
- `Error during provider resolution or curse check for destination network ID ${id}:`,
- innerError
- )
- failedCurseChecks.push(id) // Track failed curse checks
- validDestinationNetworkIds.push(destinationChainAtlas) // Push if curse check fails
- }
- }
- } catch (outerError) {
- console.error(`Error resolving destination chain or mapping to atlas for network ID ${id}:`, outerError)
- }
- }
-
- destinationChecks.push(destinationCheck())
- }
-
- await Promise.all(destinationChecks)
-
- if (validDestinationNetworkIds.length === 0) {
- return new Response(JSON.stringify(statuses), {
- status: 200,
- headers: {
- ...commonHeaders,
- "Cache-Control": "s-max-age=300, stale-while-revalidate",
- "CDN-Cache-Control": "max-age=300",
- "Vercel-CDN-Cache-Control": "max-age=300",
- },
- })
- }
- const variables: LaneStatusesFilteredQueryVariables = {
- sourceRouterAddress: sourceRouterAddress.toLowerCase(),
- sourceNetworkId: sourceChainAtlas,
- destinationNetworkIds: validDestinationNetworkIds,
- }
-
- const response = await client.query({
- query: LaneStatusesFilteredDocument,
- variables,
- })
-
- const graphqlReturnedNetworkNames = response.data.allCcipAllLaneStatuses?.nodes.map((node) => node.destNetworkName)
- const missingFromGraphQL = validDestinationNetworkIds.filter(
- (network) => !graphqlReturnedNetworkNames?.includes(network)
- )
-
- if (failedCurseChecks.length > 0) {
- structuredLog(LogLevel.WARN, {
- message: "Curse check failed for destination chains",
- requestId,
- failedChains: failedCurseChecks,
- })
- }
-
- if (missingFromGraphQL.length > 0) {
- structuredLog(LogLevel.WARN, {
- message: "Destination chains missing from GraphQL response",
- requestId,
- missingChains: missingFromGraphQL,
- })
-
- // Add missing networks as OPERATIONAL by default
- missingFromGraphQL.forEach((network) => {
- const networkId = atlasNameToIdMap[network]
- if (networkId) {
- statuses[networkId] = LaneStatus.OPERATIONAL
- }
- })
- }
-
- if (response.data.allCcipAllLaneStatuses?.nodes.length) {
- for (const node of response.data.allCcipAllLaneStatuses.nodes) {
- let status = LaneStatus.OPERATIONAL
-
- if (node.successRate === 0) {
- const newStatus = environment === Environment.Testnet ? LaneStatus.MAINTENANCE : LaneStatus.DEGRADED
- status = newStatus
- structuredLog(LogLevel.WARN, {
- message: "Lane status changed due to zero success rate",
- requestId,
- lane: {
- source: sourceChainAtlas,
- destination: node.destNetworkName || "unknown",
- status: newStatus,
- successRate: node.successRate,
- },
- })
- }
-
- if (node.destNetworkName) {
- const destNetworkId = atlasNameToIdMap[node.destNetworkName]
- if (destNetworkId) {
- statuses[destNetworkId] = status
- } else {
- structuredLog(LogLevel.ERROR, {
- message: "Could not find destination network ID for network name",
- requestId,
- destNetworkName: node.destNetworkName,
- })
- }
- } else {
- structuredLog(LogLevel.ERROR, {
- message: "No destination network name found for lane",
- requestId,
- node,
- })
- }
- }
- return new Response(JSON.stringify(statuses), {
- status: 200,
- headers: {
- ...commonHeaders,
- "Cache-Control": "s-max-age=300, stale-while-revalidate",
- "CDN-Cache-Control": "max-age=300",
- "Vercel-CDN-Cache-Control": "max-age=300",
- },
- })
- } else {
- structuredLog(LogLevel.WARN, {
- message: "No lane statuses found",
- requestId,
- sourceNetworkId,
- destinationNetworkIds,
- })
- destinationNetworkIds.forEach((id) => {
- statuses[id] = LaneStatus.OPERATIONAL
- })
-
- return new Response(JSON.stringify(statuses), {
- status: 200,
- headers: {
- ...commonHeaders,
- "Cache-Control": "s-max-age=300, stale-while-revalidate",
- "CDN-Cache-Control": "max-age=300",
- "Vercel-CDN-Cache-Control": "max-age=300",
- },
- })
- }
- } catch (error) {
- structuredLog(LogLevel.ERROR, {
- message: "Error fetching lane statuses",
- requestId: request.headers.get("x-request-id") || "unknown",
- error: error instanceof Error ? error.message : String(error),
- })
- return new Response(
- JSON.stringify({
- errorType: "ServerError",
- errorMessage: "Failed to fetch lane statuses",
- }),
- { status: 500, headers: commonHeaders }
- )
- }
-}
diff --git a/src/pages/ccip/directory/mainnet/chain/[...chain].astro b/src/pages/ccip/directory/mainnet/chain/[...chain].astro
index dbbca92d434..461c1c2f3ab 100644
--- a/src/pages/ccip/directory/mainnet/chain/[...chain].astro
+++ b/src/pages/ccip/directory/mainnet/chain/[...chain].astro
@@ -1,6 +1,6 @@
---
import Chain from "~/components/CCIP/Chain/Chain.astro"
-import { Environment, getAllNetworks } from "~/config/data/ccip"
+import { Environment, getAllNetworks, Network } from "~/config/data/ccip"
export async function getStaticPaths() {
const networks = getAllNetworks({ filter: Environment.Mainnet })
@@ -10,7 +10,7 @@ export async function getStaticPaths() {
return {
params: { chain },
props: {
- network: networks.find((network) => network.chain === chain),
+ network: networks.find((network) => network.chain === chain) as Network,
environment: Environment.Mainnet,
},
}