Skip to content
Open
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
14 changes: 14 additions & 0 deletions src/config/cdn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* CDN Base URLs and asset path configuration
* Centralized configuration for all CDN-hosted assets
*/

// CloudFront CDN base URL
export const CLOUDFRONT_CDN_BASE = "https://d2f70xi62kby8n.cloudfront.net"

// Asset-specific paths
export const TOKEN_ICONS_PATH = `${CLOUDFRONT_CDN_BASE}/tokens`
export const VERIFIER_LOGOS_PATH = `${CLOUDFRONT_CDN_BASE}/verifiers`

// Other CDNs (for future centralization if needed)
export const IMGIX_CDN_BASE = "https://smartcontract.imgix.net"
238 changes: 238 additions & 0 deletions src/config/data/ccip/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ import {
Network,
DecomConfig,
DecommissionedNetwork,
VerifiersConfig,
Verifier,
VerifierType,
} from "./types.ts"
import { determineTokenMechanism } from "./utils.ts"
import { ExplorerInfo, SupportedChain, ChainType } from "@config/types.ts"
import { VERIFIER_LOGOS_PATH } from "@config/cdn.ts"
import {
directoryToSupportedChain,
getChainIcon,
Expand All @@ -42,6 +46,10 @@ import tokensTestnetv120 from "@config/data/ccip/v1_2_0/testnet/tokens.json" wit
import decomMainnetv120 from "@config/data/ccip/v1_2_0/mainnet/decom.json" with { type: "json" }
import decomTestnetv120 from "@config/data/ccip/v1_2_0/testnet/decom.json" with { type: "json" }

// For verifiers
import verifiersMainnetv120 from "@config/data/ccip/v1_2_0/mainnet/verifiers.json" with { type: "json" }
import verifiersTestnetv120 from "@config/data/ccip/v1_2_0/testnet/verifiers.json" with { type: "json" }

// Import errors by version
// eslint-disable-next-line camelcase
import * as errors_v1_5_0 from "./errors/v1_5_0/index.ts"
Expand Down Expand Up @@ -815,3 +823,233 @@ export const getDecommissionedNetwork = ({ chain, filter }: { chain: string; fil
const decommissionedChains = getAllDecommissionedNetworks({ filter })
return decommissionedChains.find((network) => network.chain === chain)
}

// ============================================================================
// Verifier utilities
// ============================================================================

/**
* Load verifiers data for a specific environment and version
*/
export const loadVerifiersData = ({ environment, version }: { environment: Environment; version: Version }) => {
let verifiersReferenceData: VerifiersConfig

if (environment === Environment.Mainnet && version === Version.V1_2_0) {
verifiersReferenceData = verifiersMainnetv120 as unknown as VerifiersConfig
} else if (environment === Environment.Testnet && version === Version.V1_2_0) {
verifiersReferenceData = verifiersTestnetv120 as unknown as VerifiersConfig
} else {
throw new Error(`Invalid environment/version combination for verifiers: ${environment}/${version}`)
}

return { verifiersReferenceData }
}

/**
* Get logo URL for a verifier by ID
* Uses CloudFront CDN, same infrastructure as token icons
*/
export const getVerifierLogoUrl = (verifierId: string): string => {
return `${VERIFIER_LOGOS_PATH}/${verifierId}.svg`
}

/**
* Map verifier type to display-friendly name
*/
export const getVerifierTypeDisplay = (type: VerifierType): string => {
const VERIFIER_TYPE_DISPLAY: Record<VerifierType, string> = {
committee: "Committee",
api: "API",
}

return VERIFIER_TYPE_DISPLAY[type] || type
}

/**
* Get all verifiers for a specific environment as a flattened list
*/
export const getAllVerifiers = ({
environment,
version = Version.V1_2_0,
}: {
environment: Environment
version?: Version
}): Verifier[] => {
const { verifiersReferenceData } = loadVerifiersData({ environment, version })

const verifiers: Verifier[] = []

// Flatten the network -> address -> metadata structure
for (const [networkId, addressMap] of Object.entries(verifiersReferenceData)) {
for (const [address, metadata] of Object.entries(addressMap)) {
verifiers.push({
...metadata,
network: networkId,
address,
logo: getVerifierLogoUrl(metadata.id),
})
}
}

// Sort by verifier name, then by network
return verifiers.sort((a, b) => {
const nameComparison = a.name.localeCompare(b.name)
if (nameComparison !== 0) return nameComparison
return a.network.localeCompare(b.network)
})
}

/**
* Get all verifiers for a specific network
*/
export const getVerifiersByNetwork = ({
networkId,
environment,
version = Version.V1_2_0,
}: {
networkId: string
environment: Environment
version?: Version
}): Verifier[] => {
const { verifiersReferenceData } = loadVerifiersData({ environment, version })

const addressMap = verifiersReferenceData[networkId]
if (!addressMap) {
return []
}

const verifiers: Verifier[] = []
for (const [address, metadata] of Object.entries(addressMap)) {
verifiers.push({
...metadata,
network: networkId,
address,
logo: getVerifierLogoUrl(metadata.id),
})
}

return verifiers.sort((a, b) => a.name.localeCompare(b.name))
}

/**
* Get all verifiers of a specific type (committee or api)
*/
export const getVerifiersByType = ({
type,
environment,
version = Version.V1_2_0,
}: {
type: VerifierType
environment: Environment
version?: Version
}): Verifier[] => {
const allVerifiers = getAllVerifiers({ environment, version })
return allVerifiers.filter((verifier) => verifier.type === type)
}

/**
* Get all networks where a specific verifier exists (by verifier ID)
*/
export const getVerifierById = ({
id,
environment,
version = Version.V1_2_0,
}: {
id: string
environment: Environment
version?: Version
}): Verifier[] => {
const allVerifiers = getAllVerifiers({ environment, version })
return allVerifiers.filter((verifier) => verifier.id === id)
}

/**
* Get a specific verifier by network and address
*/
export const getVerifier = ({
networkId,
address,
environment,
version = Version.V1_2_0,
}: {
networkId: string
address: string
environment: Environment
version?: Version
}): Verifier | undefined => {
const { verifiersReferenceData } = loadVerifiersData({ environment, version })

const addressMap = verifiersReferenceData[networkId]
if (!addressMap) {
return undefined
}

const metadata = addressMap[address]
if (!metadata) {
return undefined
}

return {
...metadata,
network: networkId,
address,
logo: getVerifierLogoUrl(metadata.id),
}
}

/**
* Get all network IDs where a specific verifier exists
* Similar to getChainsOfToken for tokens
*/
export const getNetworksOfVerifier = ({
id,
environment,
version = Version.V1_2_0,
}: {
id: string
environment: Environment
version?: Version
}): string[] => {
const verifiers = getVerifierById({ id, environment, version })
return verifiers.map((v) => v.network)
}

/**
* Get unique verifiers for display (deduplicated by ID)
* Returns one entry per verifier with totalNetworks count
* Useful for landing page display where each verifier should appear once
*/
export const getAllUniqueVerifiers = ({
environment,
version = Version.V1_2_0,
}: {
environment: Environment
version?: Version
}): Array<{
id: string
name: string
type: VerifierType
logo: string
totalNetworks: number
}> => {
const allVerifiers = getAllVerifiers({ environment, version })

// Get unique verifier IDs
const uniqueIds = Array.from(new Set(allVerifiers.map((v) => v.id)))

// Map to display format with network count
return uniqueIds
.map((id) => {
const instances = allVerifiers.filter((v) => v.id === id)
const firstInstance = instances[0]

return {
id,
name: firstInstance.name,
type: firstInstance.type,
logo: firstInstance.logo,
totalNetworks: instances.length,
}
})
.sort((a, b) => a.name.localeCompare(b.name))
}
21 changes: 21 additions & 0 deletions src/config/data/ccip/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,24 @@ export interface DecommissionedNetwork {
explorer: ExplorerInfo
chainType: ChainType
}

// Verifier types
export type VerifierType = "committee" | "api"

export interface VerifierMetadata {
id: string
name: string
type: VerifierType
}

export interface VerifiersConfig {
[networkId: string]: {
[address: string]: VerifierMetadata
}
}

export interface Verifier extends VerifierMetadata {
network: string
address: string
logo: string
}
60 changes: 60 additions & 0 deletions src/config/data/ccip/v1_2_0/mainnet/verifiers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"mainnet": {
"0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D": {
"id": "chainlink",
"name": "Chainlink",
"type": "committee"
},
"0xF4c7E640EdA248ef95972845a62bdC74237805dB": {
"id": "lombard",
"name": "Lombard",
"type": "api"
},
"0x768a1a3B321126A8B214d7376D48465C7f6Fa061": {
"id": "cctp",
"name": "CCTP",
"type": "api"
},
"0xcBD48A8eB077381c3c4Eb36b402d7283aB2b11Bc": {
"id": "symbiotic",
"name": "Symbiotic",
"type": "api"
}
},
"ethereum-mainnet-base-1": {
"0x0aA145a62153190B8f0D3cA00c441e451529f755": {
"id": "chainlink-labs",
"name": "Chainlink Labs",
"type": "committee"
},
"0x09521B0B5BB2d4406124c0207Cf551829B45f84d": {
"id": "cctp",
"name": "CCTP",
"type": "api"
}
},
"ethereum-mainnet-arbitrum-1": {
"0xe9c6945281028cb6530d43F998eE539dFE2a9191": {
"id": "chainlink-labs",
"name": "Chainlink Labs",
"type": "committee"
},
"0xBF38331E34ef7f248020611bB31Be0576D06413D": {
"id": "lombard",
"name": "Lombard",
"type": "api"
}
},
"ethereum-mainnet-optimism-1": {
"0x2edAc8B8928c4e1Ed559e619b6A8a4aaCe9Ef18A": {
"id": "cctp",
"name": "CCTP",
"type": "api"
},
"0x76Aa17dCda9E8529149E76e9ffaE4aD1C4AD701B": {
"id": "symbiotic",
"name": "Symbiotic",
"type": "api"
}
}
}
Loading
Loading