From af71a5d4d2bbf314ffa02f6d1855f4eb4faa132b Mon Sep 17 00:00:00 2001 From: "Amine E." Date: Thu, 30 Jan 2025 14:57:40 +0100 Subject: [PATCH] Sei CCIP (#2288) * update * update * update * update * update --- package-lock.json | 8 + package.json | 3 +- public/assets/chains/sei.svg | 10 + src/components/CCIP/Chain/Chain.astro | 2 +- src/components/CCIP/Chain/ChainTokenGrid.tsx | 5 +- src/components/CCIP/ChainHero/ChainHero.tsx | 15 +- .../CCIP/ChainHero/LaneDetailsHero.tsx | 13 +- .../CCIP/ChainHero/TokenDetailsHero.tsx | 7 +- src/components/CCIP/Drawer/LaneDrawer.tsx | 9 +- src/components/CCIP/Drawer/TokenDrawer.tsx | 8 +- src/components/CCIP/Hero/Hero.tsx | 3 +- src/components/CCIP/Search/Search.tsx | 18 +- src/components/CCIP/Tables/ChainTable.tsx | 10 +- .../CCIP/Tables/TokenChainsTable.tsx | 7 +- src/components/CCIP/Token/Token.astro | 5 +- .../ContractVerificationStep.tsx | 11 +- .../QuickLinks/data/productChainLinks.ts | 3 + src/config/data/ccip/data.ts | 21 +- src/config/data/ccip/types.ts | 4 +- .../data/ccip/v1_2_0/mainnet/chains.json | 20 + .../data/ccip/v1_2_0/mainnet/lanes.json | 514 ++++++++++++++++- .../data/ccip/v1_2_0/mainnet/tokens.json | 27 + .../data/ccip/v1_2_0/testnet/chains.json | 20 + .../data/ccip/v1_2_0/testnet/lanes.json | 74 +++ .../data/ccip/v1_2_0/testnet/tokens.json | 18 + src/config/data/chain-to-technology.json | 4 +- src/config/data/chains.json | 334 ++++++++--- src/config/types.ts | 38 +- src/config/web3Providers.ts | 2 + .../resources/link-token-contracts.mdx | 22 + src/features/utils/index.ts | 21 +- src/scripts/chains-metadata.ts | 519 ++++++++++++++++-- src/scripts/reference/chains.json | 26 + src/scripts/reference/linkNameSymbol.json | 8 + 34 files changed, 1589 insertions(+), 220 deletions(-) create mode 100644 public/assets/chains/sei.svg diff --git a/package-lock.json b/package-lock.json index cf1c00ad332..8c820937d7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,6 +59,7 @@ "@nomiclabs/hardhat-ethers": "^2.2.3", "@project-serum/anchor": "^0.26.0", "@rollup/plugin-yaml": "^4.1.2", + "@types/lodash": "^4.17.15", "@types/node": "^20.12.12", "@types/node-fetch": "^2.6.12", "@types/prismjs": "^1.26.4", @@ -10408,6 +10409,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", diff --git a/package.json b/package.json index 809b32263dc..f5d8de69b9d 100644 --- a/package.json +++ b/package.json @@ -37,10 +37,10 @@ "@astrojs/partytown": "^2.1.2", "@astrojs/preact": "^3.5.2", "@astrojs/prism": "^3.1.0", - "@chainlink/components": "^0.4.18", "@astrojs/react": "^3.6.2", "@astrojs/sitemap": "^3.1.6", "@astrojs/vercel": "^7.8.0", + "@chainlink/components": "^0.4.18", "@chainlink/contracts": "1.2.0", "@chainlink/contracts-ccip": "1.5.1-beta.0", "@chainlink/design-system": "^0.2.8", @@ -80,6 +80,7 @@ "@nomiclabs/hardhat-ethers": "^2.2.3", "@project-serum/anchor": "^0.26.0", "@rollup/plugin-yaml": "^4.1.2", + "@types/lodash": "^4.17.15", "@types/node": "^20.12.12", "@types/node-fetch": "^2.6.12", "@types/prismjs": "^1.26.4", diff --git a/public/assets/chains/sei.svg b/public/assets/chains/sei.svg new file mode 100644 index 00000000000..e5cec161886 --- /dev/null +++ b/public/assets/chains/sei.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/components/CCIP/Chain/Chain.astro b/src/components/CCIP/Chain/Chain.astro index 512ff852cc7..bd0f2693ee2 100644 --- a/src/components/CCIP/Chain/Chain.astro +++ b/src/components/CCIP/Chain/Chain.astro @@ -68,7 +68,7 @@ const searchLanes = getSearchLanes({ environment }) environment={environment} lanes={lanes} client:load - explorerUrl={network.explorerUrl} + explorer={network.explorer} sourceNetwork={{ name: network.name, logo: network.logo, diff --git a/src/components/CCIP/Chain/ChainTokenGrid.tsx b/src/components/CCIP/Chain/ChainTokenGrid.tsx index 2e4f99d9f67..0cb2f28289c 100644 --- a/src/components/CCIP/Chain/ChainTokenGrid.tsx +++ b/src/components/CCIP/Chain/ChainTokenGrid.tsx @@ -6,6 +6,7 @@ import { directoryToSupportedChain, getChainIcon, getTitle } from "~/features/ut import { useState } from "react" import "./ChainTokenGrid.css" import SeeMore from "../SeeMore/SeeMore" +import { ExplorerInfo } from "~/config/types" interface ChainTokenGridProps { tokens: { @@ -25,7 +26,7 @@ interface ChainTokenGridProps { tokenAddress: string tokenPoolType: PoolType tokenPoolAddress: string - explorerUrl: string + explorer: ExplorerInfo } environment: Environment } @@ -66,7 +67,7 @@ function ChainTokenGrid({ tokens, network, environment }: ChainTokenGridProps) { tokenAddress: data[key].tokenAddress, tokenPoolType: data[key].poolType, tokenPoolAddress: data[key].poolAddress || "", - explorerUrl: network.explorerUrl, + explorer: network.explorer, } }) .find((n) => n.key === network.key) diff --git a/src/components/CCIP/ChainHero/ChainHero.tsx b/src/components/CCIP/ChainHero/ChainHero.tsx index 7f5cfefa8fd..fae27ddaf16 100644 --- a/src/components/CCIP/ChainHero/ChainHero.tsx +++ b/src/components/CCIP/ChainHero/ChainHero.tsx @@ -12,6 +12,7 @@ import { fallbackTokenIconUrl, } from "~/features/utils" import { Tooltip } from "~/features/common/Tooltip" +import { ExplorerInfo } from "~/config/types" interface ChainHeroProps { chains: { @@ -36,7 +37,7 @@ interface ChainHeroProps { name: string logo: string key: string - explorerUrl: string + explorer: ExplorerInfo } lane: LaneConfig }[] @@ -52,7 +53,7 @@ interface ChainHeroProps { name: string address: string } - explorerUrl: string + explorer: ExplorerInfo routerExplorerUrl: string chainSelector: string feeTokens?: string[] @@ -83,8 +84,8 @@ function ChainHero({ chains, tokens, network, token, environment, lanes }: Chain version: Version.V1_2_0, tokenId: feeToken, }) - const explorerUrl = network.explorerUrl - const address = getExplorerAddressUrl(explorerUrl)(token[network.chain].tokenAddress) + const explorer = network.explorer + const address = getExplorerAddressUrl(explorer)(token[network.chain].tokenAddress) return { logo, @@ -192,7 +193,7 @@ function ChainHero({ chains, tokens, network, token, environment, lanes }: Chain {network.armProxy ? (
) : ( "n/a" @@ -219,7 +220,7 @@ function ChainHero({ chains, tokens, network, token, environment, lanes }: Chain {network.tokenAdminRegistry ? (
) : ( "n/a" @@ -246,7 +247,7 @@ function ChainHero({ chains, tokens, network, token, environment, lanes }: Chain {network.registryModule ? (
) : ( "n/a" diff --git a/src/components/CCIP/ChainHero/LaneDetailsHero.tsx b/src/components/CCIP/ChainHero/LaneDetailsHero.tsx index 714a9df8737..0f9dc026146 100644 --- a/src/components/CCIP/ChainHero/LaneDetailsHero.tsx +++ b/src/components/CCIP/ChainHero/LaneDetailsHero.tsx @@ -4,6 +4,7 @@ import "./LaneDetailsHero.css" import { getExplorerAddressUrl } from "~/features/utils" import CopyValue from "../CopyValue/CopyValue" import { LaneFilter } from "~/config/data/ccip" +import { ExplorerInfo } from "~/config/types" interface LaneDetailsHeroProps { sourceNetwork: { @@ -18,7 +19,7 @@ interface LaneDetailsHeroProps { offRamp: string destinationAddress: string enforceOutOfOrder?: boolean - explorerUrl: string + explorer: ExplorerInfo rmnPermeable: boolean inOutbound: LaneFilter } @@ -30,7 +31,7 @@ function LaneDetailsHero({ offRamp, destinationAddress, enforceOutOfOrder, - explorerUrl, + explorer, rmnPermeable, inOutbound, }: LaneDetailsHeroProps) { @@ -63,7 +64,7 @@ function LaneDetailsHero({ @@ -71,11 +72,7 @@ function LaneDetailsHero({ <>
OnRamp address
- +
)} diff --git a/src/components/CCIP/ChainHero/TokenDetailsHero.tsx b/src/components/CCIP/ChainHero/TokenDetailsHero.tsx index 9dcbcee340b..0ef6af7d0d4 100644 --- a/src/components/CCIP/ChainHero/TokenDetailsHero.tsx +++ b/src/components/CCIP/ChainHero/TokenDetailsHero.tsx @@ -2,12 +2,13 @@ import Address from "~/components/AddressReact" import { getExplorerAddressUrl, fallbackTokenIconUrl } from "~/features/utils" import { PoolType, tokenPoolDisplay } from "~/config/data/ccip" import "./ChainHero.css" +import { ExplorerInfo } from "~/config/types" interface TokenDetailsHeroProps { network: { name: string logo: string - explorerUrl: string + explorer: ExplorerInfo } token: { id: string @@ -55,7 +56,7 @@ function TokenDetailsHero({ network, token }: TokenDetailsHeroProps) {
Token address
-
+
@@ -65,7 +66,7 @@ function TokenDetailsHero({ network, token }: TokenDetailsHeroProps) {
Token pool address
-
+
diff --git a/src/components/CCIP/Drawer/LaneDrawer.tsx b/src/components/CCIP/Drawer/LaneDrawer.tsx index 3b8ed87aa48..790d8cb87a1 100644 --- a/src/components/CCIP/Drawer/LaneDrawer.tsx +++ b/src/components/CCIP/Drawer/LaneDrawer.tsx @@ -17,6 +17,7 @@ import { getExplorerAddressUrl, getTokenIconUrl, fallbackTokenIconUrl } from "~/ import TableSearchInput from "../Tables/TableSearchInput" import RateTooltip from "../Tooltip/RateTooltip" import { Tooltip } from "~/features/common/Tooltip" +import { ExplorerInfo } from "~/config/types" function LaneDrawer({ lane, @@ -24,12 +25,12 @@ function LaneDrawer({ destinationNetwork, environment, inOutbound, - explorerUrl, + explorer, }: { lane: LaneConfig sourceNetwork: { name: string; logo: string; key: string } destinationNetwork: { name: string; logo: string; key: string } - explorerUrl: string + explorer: ExplorerInfo environment: Environment inOutbound: LaneFilter }) { @@ -54,7 +55,7 @@ function LaneDrawer({ onRamp={lane.onRamp.address} offRamp={lane.offRamp.address} enforceOutOfOrder={lane.onRamp.enforceOutOfOrder} - explorerUrl={explorerUrl || ""} + explorer={explorer} destinationAddress={destinationNetworkDetails?.chainSelector || ""} rmnPermeable={lane.rmnPermeable} inOutbound={inOutbound} @@ -157,7 +158,7 @@ function LaneDrawer({
{data[sourceNetwork.key].decimals} diff --git a/src/components/CCIP/Drawer/TokenDrawer.tsx b/src/components/CCIP/Drawer/TokenDrawer.tsx index c3cf86b9d06..3af2f29bc99 100644 --- a/src/components/CCIP/Drawer/TokenDrawer.tsx +++ b/src/components/CCIP/Drawer/TokenDrawer.tsx @@ -15,7 +15,7 @@ import { LaneConfig, } from "~/config/data/ccip" import { useState } from "react" -import { SupportedChain } from "~/config" +import { ExplorerInfo, SupportedChain } from "~/config" import LaneDrawer from "../Drawer/LaneDrawer" import TableSearchInput from "../Tables/TableSearchInput" import Tabs from "../Tables/Tabs" @@ -46,7 +46,7 @@ function TokenDrawer({ tokenAddress: string tokenPoolType: PoolType tokenPoolAddress: string - explorerUrl: string + explorer: ExplorerInfo } destinationLanes: { [sourceChain: string]: SupportedTokenConfig @@ -128,7 +128,7 @@ function TokenDrawer({ network={{ name: network.name, logo: network.logo, - explorerUrl: network.explorerUrl, + explorer: network.explorer, }} />
@@ -231,7 +231,7 @@ function TokenDrawer({ key: destinationChain, }} inOutbound={inOutbound} - explorerUrl={network.explorerUrl} + explorer={network.explorer} /> )) }} diff --git a/src/components/CCIP/Hero/Hero.tsx b/src/components/CCIP/Hero/Hero.tsx index 8b1b876cb0f..0d75332f436 100644 --- a/src/components/CCIP/Hero/Hero.tsx +++ b/src/components/CCIP/Hero/Hero.tsx @@ -1,6 +1,7 @@ import { Environment, LaneConfig } from "~/config/data/ccip" import Search from "../Search/Search" import "./Hero.css" +import { ExplorerInfo } from "~/config/types" interface HeroProps { chains: { @@ -25,7 +26,7 @@ interface HeroProps { name: string logo: string key: string - explorerUrl: string + explorer: ExplorerInfo } lane: LaneConfig }[] diff --git a/src/components/CCIP/Search/Search.tsx b/src/components/CCIP/Search/Search.tsx index 5a2037d296d..0df27e0cc62 100644 --- a/src/components/CCIP/Search/Search.tsx +++ b/src/components/CCIP/Search/Search.tsx @@ -6,6 +6,7 @@ import { Environment, LaneConfig, LaneFilter } from "~/config/data/ccip" import { directoryToSupportedChain, getExplorer, fallbackTokenIconUrl } from "~/features/utils" import { drawerContentStore } from "../Drawer/drawerStore" import LaneDrawer from "../Drawer/LaneDrawer" +import { ExplorerInfo } from "~/config/types" interface SearchProps { chains: { @@ -30,7 +31,7 @@ interface SearchProps { name: string logo: string key: string - explorerUrl: string + explorer: ExplorerInfo } lane: LaneConfig }[] @@ -71,9 +72,18 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) { useClickOutside(searchRef, () => setOpenSearchMenu(false)) - const generateExplorerUrl = (lane) => { + const generateExplorerUrl = (lane): ExplorerInfo => { const directory = directoryToSupportedChain(lane.sourceNetwork.key) - return getExplorer(directory) || "" + const explorer = getExplorer(directory) + + if (!explorer) { + // Provide an empty object if no explorer is found + return { + baseUrl: "", + } + } + + return explorer } return ( <> @@ -178,7 +188,7 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) { ...lane.destinationNetwork, }} inOutbound={LaneFilter.Outbound} - explorerUrl={generateExplorerUrl(lane)} + explorer={generateExplorerUrl(lane)} /> )) } diff --git a/src/components/CCIP/Tables/ChainTable.tsx b/src/components/CCIP/Tables/ChainTable.tsx index ab947a7268c..f12ea58d362 100644 --- a/src/components/CCIP/Tables/ChainTable.tsx +++ b/src/components/CCIP/Tables/ChainTable.tsx @@ -8,7 +8,7 @@ import { drawerContentStore } from "../Drawer/drawerStore" import LaneDrawer from "../Drawer/LaneDrawer" import { Environment, Version } from "~/config/data/ccip/types" import { getLane, LaneFilter } from "~/config/data/ccip" -import { SupportedChain } from "~/config" +import { ExplorerInfo, SupportedChain } from "~/config" import { clsx } from "~/lib" import SeeMore from "../SeeMore/SeeMore" import { getOperationalState } from "~/config/data/ccip/data" @@ -30,12 +30,12 @@ interface TableProps { key: string directory: SupportedChain }[] - explorerUrl: string + explorer: ExplorerInfo } const BEFORE_SEE_MORE = 12 // Number of networks to show before the "See more" button, 7 rows -function ChainTable({ lanes, explorerUrl, sourceNetwork, environment }: TableProps) { +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) @@ -115,7 +115,7 @@ function ChainTable({ lanes, explorerUrl, sourceNetwork, environment }: TablePro key: network.key, }} inOutbound={inOutbound} - explorerUrl={explorerUrl} + explorer={explorer} /> )) }} @@ -128,7 +128,7 @@ function ChainTable({ lanes, explorerUrl, sourceNetwork, environment }: TablePro
diff --git a/src/components/CCIP/Tables/TokenChainsTable.tsx b/src/components/CCIP/Tables/TokenChainsTable.tsx index b69003f0c27..e8fe992e3c9 100644 --- a/src/components/CCIP/Tables/TokenChainsTable.tsx +++ b/src/components/CCIP/Tables/TokenChainsTable.tsx @@ -2,6 +2,7 @@ import Address from "~/components/AddressReact" import "./Table.css" import { drawerContentStore } from "../Drawer/drawerStore" import { Environment, SupportedTokenConfig, tokenPoolDisplay, PoolType } from "~/config/data/ccip" +import { ExplorerInfo } from "~/config/types" import TableSearchInput from "./TableSearchInput" import { useState } from "react" import { getExplorerAddressUrl, fallbackTokenIconUrl } from "~/features/utils" @@ -20,7 +21,7 @@ interface TableProps { tokenAddress: string tokenPoolType: PoolType tokenPoolAddress: string - explorerUrl: string + explorer: ExplorerInfo }[] token: { id: string @@ -107,7 +108,7 @@ function TokenChainsTable({ networks, token, lanes, environment }: TableProps) { {network.tokenDecimals}
@@ -115,7 +116,7 @@ function TokenChainsTable({ networks, token, lanes, environment }: TableProps) { {tokenPoolDisplay(network.tokenPoolType)}
diff --git a/src/components/CCIP/Token/Token.astro b/src/components/CCIP/Token/Token.astro index 9cde2a10ca3..cb1e09a246c 100644 --- a/src/components/CCIP/Token/Token.astro +++ b/src/components/CCIP/Token/Token.astro @@ -88,7 +88,8 @@ const searchLanes = getSearchLanes({ environment }) const directory = directoryToSupportedChain(key || "") const title = getTitle(directory) || "" const networkLogo = getChainIcon(directory) || "" - const explorerUrl = getExplorer(directory) + const explorer = getExplorer(directory) + if (!explorer) throw new Error(`Explorer not found for ${key}`) return { name: title, key: key, @@ -101,7 +102,7 @@ const searchLanes = getSearchLanes({ environment }) tokenAddress: data[key].tokenAddress || "", tokenPoolType: data[key].poolType, tokenPoolAddress: data[key].poolAddress || "", - explorerUrl: explorerUrl || "", + explorer: explorer, } }) .sort((a, b) => a.name.localeCompare(b.name))} diff --git a/src/components/CCIP/TutorialBlockchainSelector/ContractVerificationStep.tsx b/src/components/CCIP/TutorialBlockchainSelector/ContractVerificationStep.tsx index 09c6b41cd5b..3dbc0f0e935 100644 --- a/src/components/CCIP/TutorialBlockchainSelector/ContractVerificationStep.tsx +++ b/src/components/CCIP/TutorialBlockchainSelector/ContractVerificationStep.tsx @@ -2,6 +2,7 @@ import { TutorialStep } from "../TutorialSetup/TutorialStep" import { Callout } from "../TutorialSetup/Callout" import type { Network } from "@config/data/ccip/types" import styles from "./ContractVerificationStep.module.css" +import { getExplorerAddressUrl } from "~/features/utils" interface ContractVerificationStepProps { stepId: string @@ -17,7 +18,7 @@ export const ContractVerificationStep = ({ contractType, }: ContractVerificationStepProps) => { const explorerContractUrl = - contractAddress && network?.explorerUrl ? `${network.explorerUrl}/address/${contractAddress}#code` : undefined + contractAddress && network?.explorer ? getExplorerAddressUrl(network.explorer)(contractAddress) : undefined return ( @@ -37,17 +38,17 @@ export const ContractVerificationStep = ({
  • Access the Blockchain Explorer
    - {network?.explorerUrl ? ( + {network?.explorer ? ( @@ -109,7 +110,7 @@ export const ContractVerificationStep = ({
  • You should now see your contract's source code in the "Code" tab
  • - {!network?.explorerUrl ? ( + {!network?.explorer ? (
    Contract verification link will be available once you select a network.
    diff --git a/src/components/QuickLinks/data/productChainLinks.ts b/src/components/QuickLinks/data/productChainLinks.ts index 499be5b0fb6..d2a2373c1b3 100644 --- a/src/components/QuickLinks/data/productChainLinks.ts +++ b/src/components/QuickLinks/data/productChainLinks.ts @@ -54,6 +54,7 @@ export const productChainLinks: ProductChainLinks = { bitlayer: "/ccip/directory/mainnet/chain/bitcoin-mainnet-bitlayer-1", hashkey: "/ccip/directory/mainnet/chain/ethereum-mainnet-hashkey-1", botanix: "/ccip/directory/testnet/chain/bitcoin-testnet-botanix", + sei: "/ccip/directory/mainnet/chain/sei-mainnet", }, }, "Data Feeds": { @@ -184,6 +185,7 @@ export const productChainLinks: ProductChainLinks = { bitlayer: "/resources/link-token-contracts#bitlayer", hashkey: "/resources/link-token-contracts#hashkey", botanix: "/resources/link-token-contracts#botanix", + sei: "/resources/link-token-contracts#sei", }, } @@ -230,4 +232,5 @@ export const chainNames: Record = { bitlayer: "Bitlayer", hashkey: "HashKey Chain", botanix: "Botanix", + sei: "Sei Network", } diff --git a/src/config/data/ccip/data.ts b/src/config/data/ccip/data.ts index 5a63ca728ef..d4ab29416b9 100644 --- a/src/config/data/ccip/data.ts +++ b/src/config/data/ccip/data.ts @@ -12,7 +12,7 @@ import { LaneConfig, Network, } from "." -import { SupportedChain } from "@config/types" +import { ExplorerInfo, SupportedChain } from "@config/types" import { directoryToSupportedChain, getChainIcon, @@ -393,7 +393,7 @@ export const getAllNetworks = ({ filter }: { filter: Environment }): Network[] = key: string chainSelector: string tokenAdminRegistry?: string - explorerUrl: string + explorer: ExplorerInfo registryModule?: string router?: { address: string @@ -425,10 +425,10 @@ export const getAllNetworks = ({ filter }: { filter: Environment }): Network[] = const logo = getChainIcon(directory) if (!logo) throw Error(`Logo not found for ${directory}`) const token = getTokensOfChain({ chain, filter }) - const explorerUrl = getExplorer(directory) + const explorer = getExplorer(directory) const router = chains[chain].router - if (!explorerUrl) throw Error(`Explorer url not found for ${directory}`) - const routerExplorerUrl = getExplorerAddressUrl(explorerUrl)(router.address) + if (!explorer) throw Error(`Explorer not found for ${directory}`) + const routerExplorerUrl = getExplorerAddressUrl(explorer)(router.address) allChains.push({ name: title, logo, @@ -436,7 +436,7 @@ export const getAllNetworks = ({ filter }: { filter: Environment }): Network[] = totalTokens: token.length, chain, key: chain, - explorerUrl, + explorer, tokenAdminRegistry: chains[chain]?.tokenAdminRegistry?.address, registryModule: chains[chain]?.registryModule?.address, router, @@ -476,7 +476,7 @@ export const getNetwork = ({ chain, filter }: { chain: string; filter: Environme return { name: network.name, logo: network.logo, - explorerUrl: network.explorerUrl, + explorer: network.explorer, ...chainDetails, } } @@ -630,7 +630,7 @@ export function getSearchLanes({ environment }: { environment: Environment }) { name: string logo: string key: string - explorerUrl: string + explorer: ExplorerInfo } lane: LaneConfig }[] = [] @@ -646,7 +646,8 @@ export function getSearchLanes({ environment }: { environment: Environment }) { const destinationChainLogo = getChainIcon(destinationChainDirectory) const lane = lanes[sourceChain][destinationChain] - const explorerUrl = getExplorer(destinationChainDirectory) || "" + const explorer = getExplorer(destinationChainDirectory) + if (!explorer) throw Error(`Explorer not found for ${destinationChainDirectory}`) allLanes.push({ sourceNetwork: { name: sourceChainTitle || "", @@ -657,7 +658,7 @@ export function getSearchLanes({ environment }: { environment: Environment }) { name: destinationChainTitle || "", logo: destinationChainLogo || "", key: destinationChain, - explorerUrl, + explorer, }, lane, }) diff --git a/src/config/data/ccip/types.ts b/src/config/data/ccip/types.ts index 76c224703f9..8120d2a94d2 100644 --- a/src/config/data/ccip/types.ts +++ b/src/config/data/ccip/types.ts @@ -1,3 +1,5 @@ +import { ExplorerInfo } from "~/config/types" + export type RateLimiterConfig = { capacity: string isEnabled: boolean @@ -157,7 +159,7 @@ export interface Network { totalTokens: number key: string tokenAdminRegistry?: string - explorerUrl: string + explorer: ExplorerInfo registryModule?: string router?: { address: string diff --git a/src/config/data/ccip/v1_2_0/mainnet/chains.json b/src/config/data/ccip/v1_2_0/mainnet/chains.json index d53c307c13d..44b949d3984 100644 --- a/src/config/data/ccip/v1_2_0/mainnet/chains.json +++ b/src/config/data/ccip/v1_2_0/mainnet/chains.json @@ -559,6 +559,26 @@ "version": "1.5.0" } }, + "sei-mainnet": { + "armProxy": { + "address": "0x32C67585dA17839245c75D80d36c8CBD7d35E1a5", + "version": "1.5.0" + }, + "chainSelector": "9027416829622342829", + "feeTokens": ["LINK", "WSEI"], + "registryModule": { + "address": "0xd7327405609E3f9566830b1aCF79E25AC0a9DA4B", + "version": "1.5.0" + }, + "router": { + "address": "0xAba60dA7E88F7E8f5868C2B6dE06CB759d693af0", + "version": "1.2.0" + }, + "tokenAdminRegistry": { + "address": "0x910a46cA93E8086BF1d7D65190eE6AEe5256Bd61", + "version": "1.5.0" + } + }, "shibarium-mainnet": { "armProxy": { "address": "0xD2bdb98dA1Ff575d091CA5b76412C23Cba88CA02", diff --git a/src/config/data/ccip/v1_2_0/mainnet/lanes.json b/src/config/data/ccip/v1_2_0/mainnet/lanes.json index dd3eef472d5..e97fd6aa125 100644 --- a/src/config/data/ccip/v1_2_0/mainnet/lanes.json +++ b/src/config/data/ccip/v1_2_0/mainnet/lanes.json @@ -231,7 +231,7 @@ }, "out": { "capacity": "2500000000000000000", - "isEnabled": true, + "isEnabled": false, "rate": "115740000000000" } } @@ -1440,6 +1440,46 @@ } } }, + "soneium-mainnet": { + "offRamp": { + "address": "0x39b8519F8871965DB784218DE0d6bcA3A03b2141", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x0390B87B43974b45e3fE21824A008A3cd46605De", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + }, + "sonic-mainnet": { + "offRamp": { + "address": "0x1Bb241731Fce5A650934b594D9ee6cCE55E39f32", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xF54f6623f1E714985839ac451BFA8B34007487E0", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + }, + "out": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + } + } + } + } + }, "wemix-mainnet": { "offRamp": { "address": "0x512CA54a0F6447AC41c07Da3336DFcA042D88A7B", @@ -2522,6 +2562,18 @@ } } }, + "ethereum-mainnet-mantle-1": { + "offRamp": { + "address": "0xE62f2AE9ceCbc6688a24602386f6B8FE5336b634", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x8A59Fa6a8ee352E0D0d27B7076C5132f9a34BD00", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + }, "ethereum-mainnet-mode-1": { "offRamp": { "address": "0xa964355d8eBa62E9b043Eb27eEe6d999Ecc69429", @@ -3572,6 +3624,34 @@ } } }, + "sonic-mainnet": { + "offRamp": { + "address": "0xf88166dB9E9B7c59068f2dC9bD5d53A719a41e68", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x6cb060f7f8b0F8C58A4032C82dCf917c6d438f46", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + }, + "out": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + } + } + } + } + }, "wemix-mainnet": { "offRamp": { "address": "0x893c14bA328A49336a188F972f997C0d7286B8E4", @@ -5126,6 +5206,34 @@ } } }, + "sonic-mainnet": { + "offRamp": { + "address": "0x9c32DfE3237d280Dc703Ee8D42aae379b7BDea73", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xBc8e6602aEa1FE65Dc5656b77360ddAbBB52f894", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + }, + "out": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + } + } + } + } + }, "xdai-mainnet": { "offRamp": { "address": "0x300977dBA924af14E166B31F4926892B1f310661", @@ -5322,6 +5430,52 @@ } }, "ethereum-mainnet-kroma-1": { + "mainnet": { + "supportedTokens": { + "BONE": { + "rateLimiterConfig": { + "in": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + }, + "out": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + } + } + }, + "LEASH": { + "rateLimiterConfig": { + "in": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + }, + "out": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + } + } + }, + "SHIB": { + "rateLimiterConfig": { + "in": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + }, + "out": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + } + } + } + } + }, "wemix-mainnet": { "offRamp": { "address": "0xcB154Bb4ed63FC30C416Dd16A2d1C64D8DE8DfD5", @@ -5632,6 +5786,18 @@ } }, "ethereum-mainnet-mantle-1": { + "ethereum-mainnet-arbitrum-1": { + "offRamp": { + "address": "0x86e769Df2f545d45847D8dA81DA4a25265813d13", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x6B074861f43077e537972cc55f0e986849A46095", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + }, "mainnet": { "offRamp": { "address": "0xfFdAbD352FdA50faF773503fe8BF265dFA9f7A01", @@ -5927,6 +6093,34 @@ } } } + }, + "sonic-mainnet": { + "offRamp": { + "address": "0x411ce3551a5be63c3Cb30374Cee336c3b3F84111", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xD5Fa7faca37be1644f88bB17A0E4f0df12279339", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + }, + "out": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + } + } + } + } } }, "ethereum-mainnet-optimism-1": { @@ -6630,6 +6824,34 @@ } } }, + "sonic-mainnet": { + "offRamp": { + "address": "0xd2e7b4e9dA1a969C160524Ca27E4AdB5d26e36d0", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xED13113a043C823d550d2505aa9a97e40766Dc49", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + }, + "out": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + } + } + } + } + }, "wemix-mainnet": { "offRamp": { "address": "0x2f40dCCb74d8B2dd7af065232a06778f2D019375", @@ -7016,9 +7238,9 @@ "rate": "1388800000000000" }, "out": { - "capacity": "30000000000000000000", + "capacity": "150000000000000000000", "isEnabled": true, - "rate": "1388800000000000" + "rate": "1736100000000000" } } }, @@ -7030,9 +7252,9 @@ "rate": "1388800000000000" }, "out": { - "capacity": "30000000000000000000", + "capacity": "150000000000000000000", "isEnabled": true, - "rate": "1388800000000000" + "rate": "1736100000000000" } } }, @@ -9030,6 +9252,52 @@ }, "rmnPermeable": true }, + "ethereum-mainnet-kroma-1": { + "supportedTokens": { + "BONE": { + "rateLimiterConfig": { + "in": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + }, + "out": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + } + } + }, + "LEASH": { + "rateLimiterConfig": { + "in": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + }, + "out": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + } + } + }, + "SHIB": { + "rateLimiterConfig": { + "in": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + }, + "out": { + "capacity": "0", + "isEnabled": false, + "rate": "0" + } + } + } + } + }, "ethereum-mainnet-linea-1": { "offRamp": { "address": "0x418dcbCf229897d0CCf1B8B464Db06C23879FBB4", @@ -9124,7 +9392,7 @@ "enforceOutOfOrder": false, "version": "1.5.0" }, - "rmnPermeable": false, + "rmnPermeable": true, "supportedTokens": { "BONE": { "rateLimiterConfig": { @@ -9744,9 +10012,9 @@ "rate": "1388800000000000" }, "out": { - "capacity": "30000000000000000000", + "capacity": "150000000000000000000", "isEnabled": true, - "rate": "1388800000000000" + "rate": "1736100000000000" } } }, @@ -10074,6 +10342,18 @@ } } }, + "sei-mainnet": { + "offRamp": { + "address": "0xc876D50A0Ecc147FC0cEd194cD2b66210d482f9c", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x5739E5376702AAc79a53B375ca160EE3C12025E0", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": true + }, "shibarium-mainnet": { "offRamp": { "address": "0x8B3eEed4948684c3ec1bb60967820f40285018B8", @@ -10127,14 +10407,28 @@ "SolvBTC.BBN": { "rateLimiterConfig": { "in": { - "capacity": "30000000000000000000", + "capacity": "300000000000000000000", "isEnabled": true, - "rate": "1388800000000000" + "rate": "3472000000000000" }, "out": { - "capacity": "30000000000000000000", + "capacity": "300000000000000000000", "isEnabled": true, - "rate": "1388800000000000" + "rate": "3472000000000000" + } + } + }, + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + }, + "out": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" } } } @@ -11139,6 +11433,20 @@ } } }, + "sei-mainnet": { + "mainnet": { + "offRamp": { + "address": "0x737563c69D9D84CE16D175f6b17bbC823ba5Afd5", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x47bA87120CA9047268A68d5B3b40f70a8a59a2B7", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + } + }, "shibarium-mainnet": { "mainnet": { "offRamp": { @@ -11154,6 +11462,18 @@ } }, "soneium-mainnet": { + "bsc-mainnet": { + "offRamp": { + "address": "0x45004bA967A5a6a4cB7DB9C0FF9F67Ad77E2208F", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x3381fFEb675a2018357DC8A020B721cB227b5087", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + }, "mainnet": { "offRamp": { "address": "0x409c2609856CA8B40feed2E1F887426BC36c746B", @@ -11180,6 +11500,146 @@ } }, "sonic-mainnet": { + "bsc-mainnet": { + "offRamp": { + "address": "0x34762981e807034f6c0155Fe50EdA48E9fe9B832", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xb24d54916EC661B655AfFC93c04647032E7e46Ac", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": true, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + }, + "out": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + } + } + } + } + }, + "ethereum-mainnet-arbitrum-1": { + "offRamp": { + "address": "0x78867d5D2791eFE73df1cE23Fb7bF4B2db94EE0D", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xF0592475d795FB9Ef80B2ddB511d8c6Eb14D821F", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": true, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + }, + "out": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + } + } + } + } + }, + "ethereum-mainnet-base-1": { + "offRamp": { + "address": "0xA8a877a0F7d3A837A98931b33d45aFd759F98C98", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xf54853C3502716D9673E1D71BbC94E16C20277E7", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": true, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + }, + "out": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + } + } + } + } + }, + "ethereum-mainnet-mode-1": { + "offRamp": { + "address": "0xb74319e12FAfC25eca5E28fF19192B54616DaCDA", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xc6a4FD636d6b05506b771373484C9Eb29d46b8e0", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": true, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + }, + "out": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + } + } + } + } + }, + "ethereum-mainnet-optimism-1": { + "offRamp": { + "address": "0x30bFcE34462E446aA0304850033bb5339D74AFa4", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xCe92bcE99a58cA396C0CE622f1521850535A6064", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": true, + "supportedTokens": { + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + }, + "out": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + } + } + } + } + }, "mainnet": { "offRamp": { "address": "0x7c6963669EBFf136EE36c053EcF0089d59eE2287", @@ -11195,28 +11655,42 @@ "SolvBTC": { "rateLimiterConfig": { "in": { - "capacity": "30000000000000000000", + "capacity": "300000000000000000000", "isEnabled": true, - "rate": "1388800000000000" + "rate": "3472000000000000" }, "out": { - "capacity": "30000000000000000000", + "capacity": "300000000000000000000", "isEnabled": true, - "rate": "1388800000000000" + "rate": "3472000000000000" } } }, "SolvBTC.BBN": { "rateLimiterConfig": { "in": { - "capacity": "30000000000000000000", + "capacity": "300000000000000000000", "isEnabled": true, - "rate": "1388800000000000" + "rate": "3472000000000000" }, "out": { - "capacity": "30000000000000000000", + "capacity": "300000000000000000000", "isEnabled": true, - "rate": "1388800000000000" + "rate": "3472000000000000" + } + } + }, + "wUSDx": { + "rateLimiterConfig": { + "in": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" + }, + "out": { + "capacity": "490000000000", + "isEnabled": true, + "rate": "136111000" } } } diff --git a/src/config/data/ccip/v1_2_0/mainnet/tokens.json b/src/config/data/ccip/v1_2_0/mainnet/tokens.json index e37ded62308..5f459156ee0 100644 --- a/src/config/data/ccip/v1_2_0/mainnet/tokens.json +++ b/src/config/data/ccip/v1_2_0/mainnet/tokens.json @@ -1123,6 +1123,14 @@ "symbol": "LINK", "tokenAddress": "0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b" }, + "sei-mainnet": { + "allowListEnabled": false, + "decimals": 18, + "name": "ChainLink Token", + "poolType": "feeTokenOnly", + "symbol": "LINK", + "tokenAddress": "0x71052BAe71C25C78E37fD12E5ff1101A71d9018F" + }, "shibarium-mainnet": { "allowListEnabled": false, "decimals": 18, @@ -3016,6 +3024,16 @@ "tokenAddress": "0x5F2F8818002dc64753daeDF4A6CB2CcB757CD220" } }, + "WSEI": { + "sei-mainnet": { + "allowListEnabled": false, + "decimals": 18, + "name": "Wrapped SEI", + "poolType": "feeTokenOnly", + "symbol": "WSEI", + "tokenAddress": "0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7" + } + }, "wstLINK": { "ethereum-mainnet-andromeda-1": { "allowListEnabled": false, @@ -3099,6 +3117,15 @@ "poolType": "burnMint", "symbol": "wxUSD", "tokenAddress": "0xAe770d24ec1580A13392E0B71067571351029203" + }, + "sonic-mainnet": { + "allowListEnabled": false, + "decimals": 6, + "name": "Wrapped xUSD", + "poolAddress": "0x04c5046A1f4E3fFf094c26dFCAA75eF293932f18", + "poolType": "burnMint", + "symbol": "wxUSD", + "tokenAddress": "0x29A0dc4f509873673B7682B60598d393A1e591b7" } }, "WWEMIX": { diff --git a/src/config/data/ccip/v1_2_0/testnet/chains.json b/src/config/data/ccip/v1_2_0/testnet/chains.json index 81e7b16e101..e12cce58a2f 100644 --- a/src/config/data/ccip/v1_2_0/testnet/chains.json +++ b/src/config/data/ccip/v1_2_0/testnet/chains.json @@ -619,6 +619,26 @@ "version": "1.5.0" } }, + "sei-testnet-atlantic": { + "armProxy": { + "address": "0x754aBd2496Bea05ceDE80Df8bE530f6132208c41", + "version": "1.5.0" + }, + "chainSelector": "1216300075444106652", + "feeTokens": ["LINK", "WSEI"], + "registryModule": { + "address": "0x8538DE2a0Ba5C3db87B2Dc3d391Cc0Dd147dd827", + "version": "1.5.0" + }, + "router": { + "address": "0x59F5222c5d77f8D3F56e34Ff7E75A05d2cF3a98A", + "version": "1.2.0" + }, + "tokenAdminRegistry": { + "address": "0xDF27EE0050C2D3831089B14aCC465aBF9fD12C64", + "version": "1.5.0" + } + }, "shibarium-testnet-puppynet": { "armProxy": { "address": "0x8d677784DA3707e57aC0306464552560E05dBCD7", diff --git a/src/config/data/ccip/v1_2_0/testnet/lanes.json b/src/config/data/ccip/v1_2_0/testnet/lanes.json index cb7fd38a4cf..d04d936ba4d 100644 --- a/src/config/data/ccip/v1_2_0/testnet/lanes.json +++ b/src/config/data/ccip/v1_2_0/testnet/lanes.json @@ -1976,6 +1976,18 @@ } } }, + "sei-testnet-atlantic": { + "offRamp": { + "address": "0xfaF52dceA498af1225E46996A88a2BD212421a6b", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x2fFe9Df11D276B33C1a44cec0C64021201Ca76dA", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": true + }, "shibarium-testnet-puppynet": { "offRamp": { "address": "0x9f54330D70859726c39772b6157b03A6dB17F254", @@ -2406,6 +2418,18 @@ } } }, + "polygon-testnet-amoy": { + "offRamp": { + "address": "0xB6C02E529D90B55fe64fbC27df6ad7890339A13f", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x4127A86e622603696FD4D78f5975f9F62A1f1CD2", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + }, "wemix-testnet": { "offRamp": { "address": "0x11d486E92d291704D1E25cDbAeee687237247826", @@ -2812,6 +2836,18 @@ } } }, + "polygon-testnet-amoy": { + "offRamp": { + "address": "0x9D20eF141F921048d7A4202A55711c65d316B85b", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xB388a2401A81ff9f400E0Ef1714F4d7e63520C90", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + }, "ronin-testnet-saigon": { "offRamp": { "address": "0x4C14ca01eB15aE9145042F69C1aA4883e192Ed70", @@ -4072,6 +4108,30 @@ } } }, + "ethereum-testnet-sepolia-arbitrum-1": { + "offRamp": { + "address": "0x0d8a54BdC3f223a8CDafDc2bF30C672B3C6f947b", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x5b4942F603D039650AD0CfF8Bed0C49Fa6827Ed6", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + }, + "ethereum-testnet-sepolia-base-1": { + "offRamp": { + "address": "0xc29b47fCbcbDbc356bb58C6f9449CD1058EE04ed", + "version": "1.5.0" + }, + "onRamp": { + "address": "0x82e28024D67F1e7BaF0b76FCf05e684f3aA11F96", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + }, "ethereum-testnet-sepolia-optimism-1": { "offRamp": { "address": "0xAA755Ef570986feEb6522377077e549e3013843E", @@ -4269,6 +4329,20 @@ "rmnPermeable": false } }, + "sei-testnet-atlantic": { + "ethereum-testnet-sepolia": { + "offRamp": { + "address": "0xFfD24A8B37f82571752e251E787d5ad4c980eAfA", + "version": "1.5.0" + }, + "onRamp": { + "address": "0xD150EE452747EB51EdA1ede91783A5c3CA79adFd", + "enforceOutOfOrder": false, + "version": "1.5.0" + }, + "rmnPermeable": false + } + }, "shibarium-testnet-puppynet": { "ethereum-testnet-sepolia": { "offRamp": { diff --git a/src/config/data/ccip/v1_2_0/testnet/tokens.json b/src/config/data/ccip/v1_2_0/testnet/tokens.json index dbf20e87d98..6696ed079ca 100644 --- a/src/config/data/ccip/v1_2_0/testnet/tokens.json +++ b/src/config/data/ccip/v1_2_0/testnet/tokens.json @@ -732,6 +732,14 @@ "symbol": "LINK", "tokenAddress": "0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15" }, + "sei-testnet-atlantic": { + "allowListEnabled": false, + "decimals": 18, + "name": "ChainLink Token", + "poolType": "feeTokenOnly", + "symbol": "LINK", + "tokenAddress": "0xA9d21ed8260DE08fF39DC5e7B65806d4e1CB817B" + }, "shibarium-testnet-puppynet": { "allowListEnabled": false, "decimals": 18, @@ -1125,6 +1133,16 @@ "tokenAddress": "0xbd5F3751856E11f3e80dBdA567Ef91Eb7e874791" } }, + "WSEI": { + "sei-testnet-atlantic": { + "allowListEnabled": false, + "decimals": 18, + "name": "Wrapped SEI", + "poolType": "feeTokenOnly", + "symbol": "WSEI", + "tokenAddress": "0x3921eA6Cf927BE80211Bb57f19830700285b0AdA" + } + }, "WWEMIX": { "wemix-testnet": { "allowListEnabled": false, diff --git a/src/config/data/chain-to-technology.json b/src/config/data/chain-to-technology.json index cae3825fc9c..fd5f37255b7 100644 --- a/src/config/data/chain-to-technology.json +++ b/src/config/data/chain-to-technology.json @@ -70,5 +70,7 @@ "SONIC_BLAZE": "SONIC", "BOB_MAINNET": "BOB", "BOB_SEPOLIA": "BOB", - "BOTANIX_TESTNET": "BOTANIX" + "BOTANIX_TESTNET": "BOTANIX", + "SEI_MAINNET": "SEI", + "SEI_TESTNET": "SEI" } diff --git a/src/config/data/chains.json b/src/config/data/chains.json index ea4e69922d5..f4e77c52591 100644 --- a/src/config/data/chains.json +++ b/src/config/data/chains.json @@ -6,7 +6,9 @@ "ETHEREUM_MAINNET": { "chainId": 1, "title": "Ethereum", - "explorer": "https://etherscan.io", + "explorer": { + "baseUrl": "https://etherscan.io" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -15,8 +17,10 @@ }, "ETHEREUM_SEPOLIA": { "chainId": 11155111, - "title": "Sepolia", - "explorer": "https://sepolia.etherscan.io", + "title": "Ethereum Sepolia", + "explorer": { + "baseUrl": "https://sepolia.etherscan.io" + }, "nativeCurrency": { "name": "Sepolia Ether", "symbol": "ETH", @@ -26,7 +30,9 @@ "ETHEREUM_HOLESKY": { "chainId": 17000, "title": "Holesky", - "explorer": "https://holesky.etherscan.io", + "explorer": { + "baseUrl": "https://holesky.etherscan.io" + }, "nativeCurrency": { "name": "Holesky Ether", "symbol": "ETH", @@ -42,7 +48,9 @@ "BNB_MAINNET": { "chainId": 56, "title": "BNB Chain", - "explorer": "https://bscscan.com", + "explorer": { + "baseUrl": "https://bscscan.com" + }, "nativeCurrency": { "name": "BNB Chain Native Token", "symbol": "BNB", @@ -52,7 +60,9 @@ "BNB_TESTNET": { "chainId": 97, "title": "BNB Chain Testnet", - "explorer": "https://testnet.bscscan.com", + "explorer": { + "baseUrl": "https://testnet.bscscan.com" + }, "nativeCurrency": { "name": "BNB Chain Native Token", "symbol": "tBNB", @@ -68,7 +78,9 @@ "POLYGON_MAINNET": { "chainId": 137, "title": "Polygon", - "explorer": "https://polygonscan.com", + "explorer": { + "baseUrl": "https://polygonscan.com" + }, "nativeCurrency": { "name": "POL", "symbol": "POL", @@ -78,7 +90,9 @@ "POLYGON_AMOY": { "chainId": 80002, "title": "Polygon Amoy", - "explorer": "https://amoy.polygonscan.com/", + "explorer": { + "baseUrl": "https://amoy.polygonscan.com/" + }, "nativeCurrency": { "name": "POL", "symbol": "POL", @@ -94,7 +108,9 @@ "GNOSIS_MAINNET": { "chainId": 100, "title": "Gnosis", - "explorer": "https://gnosis.blockscout.com", + "explorer": { + "baseUrl": "https://gnosis.blockscout.com" + }, "nativeCurrency": { "name": "xDAI", "symbol": "XDAI", @@ -104,7 +120,9 @@ "GNOSIS_CHIADO": { "chainId": 10200, "title": "Gnosis Chiado", - "explorer": "https://gnosis-chiado.blockscout.com", + "explorer": { + "baseUrl": "https://gnosis-chiado.blockscout.com" + }, "nativeCurrency": { "name": "xDAI", "symbol": "XDAI", @@ -120,7 +138,9 @@ "AVALANCHE_MAINNET": { "chainId": 43114, "title": "Avalanche", - "explorer": "https://snowtrace.io", + "explorer": { + "baseUrl": "https://snowtrace.io" + }, "nativeCurrency": { "name": "Avalanche", "symbol": "AVAX", @@ -130,7 +150,9 @@ "AVALANCHE_FUJI": { "chainId": 43113, "title": "Avalanche Fuji", - "explorer": "https://testnet.snowtrace.io", + "explorer": { + "baseUrl": "https://testnet.snowtrace.io" + }, "nativeCurrency": { "name": "Avalanche", "symbol": "AVAX", @@ -146,7 +168,9 @@ "FANTOM_MAINNET": { "chainId": 250, "title": "Fantom", - "explorer": "https://ftmscan.com", + "explorer": { + "baseUrl": "https://ftmscan.com" + }, "nativeCurrency": { "name": "Fantom", "symbol": "FTM", @@ -156,7 +180,9 @@ "FANTOM_TESTNET": { "chainId": 4002, "title": "Fantom Testnet", - "explorer": "https://testnet.ftmscan.com", + "explorer": { + "baseUrl": "https://testnet.ftmscan.com" + }, "nativeCurrency": { "name": "Fantom", "symbol": "FTM", @@ -172,7 +198,9 @@ "ARBITRUM_MAINNET": { "chainId": 42161, "title": "Arbitrum One", - "explorer": "https://explorer.arbitrum.io", + "explorer": { + "baseUrl": "https://explorer.arbitrum.io" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -182,7 +210,9 @@ "ARBITRUM_SEPOLIA": { "chainId": 421614, "title": "Arbitrum Sepolia", - "explorer": "https://sepolia.arbiscan.io/", + "explorer": { + "baseUrl": "https://sepolia.arbiscan.io" + }, "nativeCurrency": { "name": "Arbitrum Sepolia Ether", "symbol": "ETH", @@ -198,7 +228,9 @@ "OPTIMISM_MAINNET": { "chainId": 10, "title": "Optimism", - "explorer": "https://optimistic.etherscan.io", + "explorer": { + "baseUrl": "https://optimistic.etherscan.io" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -208,7 +240,9 @@ "OPTIMISM_SEPOLIA": { "chainId": 11155420, "title": "Optimism Sepolia", - "explorer": "https://sepolia-optimism.etherscan.io", + "explorer": { + "baseUrl": "https://sepolia-optimism.etherscan.io" + }, "nativeCurrency": { "name": "Sepolia Ether", "symbol": "ETH", @@ -224,7 +258,9 @@ "MOONRIVER_MAINNET": { "chainId": 1285, "title": "Moonriver", - "explorer": "https://moonriver.moonscan.io", + "explorer": { + "baseUrl": "https://moonriver.moonscan.io" + }, "nativeCurrency": { "name": "Moonriver", "symbol": "MOVR", @@ -240,7 +276,9 @@ "MOONBEAM_MAINNET": { "chainId": 1284, "title": "Moonbeam", - "explorer": "https://moonscan.io", + "explorer": { + "baseUrl": "https://moonscan.io" + }, "nativeCurrency": { "name": "Glimmer", "symbol": "GLMR", @@ -256,7 +294,9 @@ "METIS_MAINNET": { "chainId": 1088, "title": "Metis Andromeda", - "explorer": "https://andromeda-explorer.metis.io", + "explorer": { + "baseUrl": "https://andromeda-explorer.metis.io" + }, "nativeCurrency": { "name": "Metis", "symbol": "METIS", @@ -266,7 +306,9 @@ "METIS_SEPOLIA": { "chainId": 59902, "title": "Metis Sepolia", - "explorer": "https://sepolia-explorer.metisdevops.link/", + "explorer": { + "baseUrl": "https://sepolia-explorer.metisdevops.link" + }, "nativeCurrency": { "name": "Metis", "symbol": "METIS", @@ -282,7 +324,9 @@ "BASE_MAINNET": { "chainId": 8453, "title": "Base", - "explorer": "https://basescan.org", + "explorer": { + "baseUrl": "https://basescan.org" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -292,7 +336,9 @@ "BASE_SEPOLIA": { "chainId": 84532, "title": "Base Sepolia", - "explorer": "https://sepolia.basescan.org", + "explorer": { + "baseUrl": "https://sepolia.basescan.org" + }, "nativeCurrency": { "name": "Sepolia Ether", "symbol": "ETH", @@ -308,7 +354,9 @@ "CELO_MAINNET": { "chainId": 42220, "title": "Celo", - "explorer": "https://celoscan.io", + "explorer": { + "baseUrl": "https://celoscan.io" + }, "nativeCurrency": { "name": "CELO", "symbol": "CELO", @@ -318,7 +366,9 @@ "CELO_ALFAJORES": { "chainId": 44787, "title": "Celo Alfajores", - "explorer": "https://alfajores.celoscan.io", + "explorer": { + "baseUrl": "https://alfajores.celoscan.io" + }, "nativeCurrency": { "name": "CELO", "symbol": "CELO", @@ -334,7 +384,9 @@ "SCROLL_MAINNET": { "chainId": 534352, "title": "Scroll", - "explorer": "https://scrollscan.com", + "explorer": { + "baseUrl": "https://scrollscan.com" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -344,7 +396,9 @@ "SCROLL_SEPOLIA": { "chainId": 534351, "title": "Scroll Sepolia", - "explorer": "https://sepolia.scrollscan.dev", + "explorer": { + "baseUrl": "https://sepolia.scrollscan.dev" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -360,7 +414,9 @@ "LINEA_MAINNET": { "chainId": 59144, "title": "Linea", - "explorer": "https://lineascan.build", + "explorer": { + "baseUrl": "https://lineascan.build" + }, "nativeCurrency": { "name": "Linea Ether", "symbol": "ETH", @@ -370,7 +426,9 @@ "LINEA_GOERLI": { "chainId": 59140, "title": "Linea Goerli", - "explorer": "https://goerli.lineascan.build", + "explorer": { + "baseUrl": "https://goerli.lineascan.build" + }, "nativeCurrency": { "name": "Linea Ether", "symbol": "ETH", @@ -380,7 +438,9 @@ "LINEA_SEPOLIA": { "chainId": 59141, "title": "Linea Sepolia", - "explorer": "https://sepolia.lineascan.build", + "explorer": { + "baseUrl": "https://sepolia.lineascan.build" + }, "nativeCurrency": { "name": "Linea Ether", "symbol": "ETH", @@ -396,7 +456,9 @@ "ZKSYNC_MAINNET": { "chainId": 324, "title": "ZKsync", - "explorer": "https://explorer.zksync.io", + "explorer": { + "baseUrl": "https://explorer.zksync.io" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -406,7 +468,9 @@ "ZKSYNC_SEPOLIA": { "chainId": 300, "title": "ZKsync Sepolia", - "explorer": "https://sepolia.explorer.zksync.io", + "explorer": { + "baseUrl": "https://sepolia.explorer.zksync.io" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -422,7 +486,9 @@ "POLYGON_ZKEVM_MAINNET": { "chainId": 1101, "title": "Polygon zkEVM", - "explorer": "https://zkevm.polygonscan.com", + "explorer": { + "baseUrl": "https://zkevm.polygonscan.com" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -432,7 +498,9 @@ "POLYGON_ZKEVM_CARDONA": { "chainId": 2442, "title": "Polygon zkEVM Cardona", - "explorer": "https://cardona-zkevm.polygonscan.com", + "explorer": { + "baseUrl": "https://cardona-zkevm.polygonscan.com" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -448,7 +516,9 @@ "WEMIX_MAINNET": { "chainId": 1111, "title": "Wemix", - "explorer": "https://wemixscan.com", + "explorer": { + "baseUrl": "https://wemixscan.com" + }, "nativeCurrency": { "name": "Wemix", "symbol": "WEMIX", @@ -458,7 +528,9 @@ "WEMIX_TESTNET": { "chainId": 1112, "title": "Wemix Testnet", - "explorer": "https://testnet.wemixscan.com", + "explorer": { + "baseUrl": "https://testnet.wemixscan.com" + }, "nativeCurrency": { "name": "Testnet Wemix", "symbol": "tWEMIX", @@ -474,7 +546,9 @@ "KROMA_MAINNET": { "chainId": 255, "title": "Kroma", - "explorer": "https://kromascan.xyz", + "explorer": { + "baseUrl": "https://kromascan.xyz" + }, "nativeCurrency": { "name": "Kroma Ether", "symbol": "ETH", @@ -484,7 +558,9 @@ "KROMA_SEPOLIA": { "chainId": 2358, "title": "Kroma Sepolia", - "explorer": "https://testnet.kromascan.xyz/", + "explorer": { + "baseUrl": "https://testnet.kromascan.xyz" + }, "nativeCurrency": { "name": "Kroma Sepolia Ether", "symbol": "ETH", @@ -500,7 +576,9 @@ "MODE_MAINNET": { "chainId": 34443, "title": "Mode", - "explorer": "https://explorer.mode.network", + "explorer": { + "baseUrl": "https://explorer.mode.network" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -510,7 +588,9 @@ "MODE_SEPOLIA": { "chainId": 919, "title": "Mode Sepolia", - "explorer": "https://sepolia.explorer.mode.network", + "explorer": { + "baseUrl": "https://sepolia.explorer.mode.network" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -526,7 +606,9 @@ "BLAST_MAINNET": { "chainId": 81457, "title": "Blast", - "explorer": "https://blastscan.io", + "explorer": { + "baseUrl": "https://blastscan.io" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -536,7 +618,9 @@ "BLAST_SEPOLIA": { "chainId": 168587773, "title": "Blast Sepolia", - "explorer": "https://sepolia.blastscan.io", + "explorer": { + "baseUrl": "https://sepolia.blastscan.io" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -552,7 +636,9 @@ "SONEIUM_MAINNET": { "chainId": 1868, "title": "Soneium", - "explorer": "https://soneium.blockscout.com", + "explorer": { + "baseUrl": "https://soneium.blockscout.com" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -562,7 +648,9 @@ "SONEIUM_MINATO": { "chainId": 1946, "title": "Soneium Minato", - "explorer": "https://soneium-minato.blockscout.com", + "explorer": { + "baseUrl": "https://soneium-minato.blockscout.com" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -578,7 +666,9 @@ "WORLD_MAINNET": { "chainId": 480, "title": "World Chain", - "explorer": "https://worldscan.org", + "explorer": { + "baseUrl": "https://worldscan.org" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -588,7 +678,9 @@ "WORLD_SEPOLIA": { "chainId": 4801, "title": "World Chain Sepolia", - "explorer": "https://sepolia.worldscan.org", + "explorer": { + "baseUrl": "https://sepolia.worldscan.org" + }, "nativeCurrency": { "name": "Sepolia Ether", "symbol": "ETH", @@ -604,7 +696,9 @@ "XLAYER_MAINNET": { "chainId": 196, "title": "X Layer", - "explorer": "https://www.oklink.com/xlayer", + "explorer": { + "baseUrl": "https://www.oklink.com/xlayer" + }, "nativeCurrency": { "name": "X Layer Global Utility Token", "symbol": "OKB", @@ -614,7 +708,9 @@ "XLAYER_TESTNET": { "chainId": 195, "title": "X Layer Testnet", - "explorer": "https://www.oklink.com/xlayer-test", + "explorer": { + "baseUrl": "https://www.oklink.com/xlayer-test" + }, "nativeCurrency": { "name": "X Layer Global Utility Token in testnet", "symbol": "OKB", @@ -630,7 +726,9 @@ "BITLAYER_MAINNET": { "chainId": 200901, "title": "Bitlayer", - "explorer": "https://www.btrscan.com", + "explorer": { + "baseUrl": "https://www.btrscan.com" + }, "nativeCurrency": { "name": "BTC", "symbol": "BTC", @@ -640,7 +738,9 @@ "BITLAYER_TESTNET": { "chainId": 200810, "title": "Bitlayer Testnet", - "explorer": "https://testnet.btrscan.com", + "explorer": { + "baseUrl": "https://testnet.btrscan.com" + }, "nativeCurrency": { "name": "BTC", "symbol": "BTC", @@ -656,7 +756,9 @@ "INK_MAINNET": { "chainId": 57073, "title": "Ink", - "explorer": "https://explorer.inkonchain.com", + "explorer": { + "baseUrl": "https://explorer.inkonchain.com" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -666,7 +768,9 @@ "INK_SEPOLIA": { "chainId": 763373, "title": "Ink Sepolia", - "explorer": "https://explorer-sepolia.inkonchain.com", + "explorer": { + "baseUrl": "https://explorer-sepolia.inkonchain.com" + }, "nativeCurrency": { "name": "Sepolia Ether", "symbol": "ETH", @@ -682,7 +786,9 @@ "HASHKEY_MAINNET": { "chainId": 177, "title": "HashKey Chain", - "explorer": "https://hashkey.blockscout.com", + "explorer": { + "baseUrl": "https://hashkey.blockscout.com" + }, "nativeCurrency": { "name": "HashKey EcoPoints", "symbol": "HSK", @@ -692,7 +798,9 @@ "HASHKEY_TESTNET": { "chainId": 133, "title": "HashKey Chain Testnet", - "explorer": "https://hashkeychain-testnet-explorer.alt.technology", + "explorer": { + "baseUrl": "https://hashkeychain-testnet-explorer.alt.technology" + }, "nativeCurrency": { "name": "HashKey EcoPoints", "symbol": "HSK", @@ -708,7 +816,9 @@ "CORN_MAINNET": { "chainId": 21000000, "title": "Corn", - "explorer": "https://cornscan.io", + "explorer": { + "baseUrl": "https://cornscan.io" + }, "nativeCurrency": { "name": "Bitcorn", "symbol": "BTCN", @@ -718,7 +828,9 @@ "CORN_TESTNET": { "chainId": 21000001, "title": "Corn Testnet", - "explorer": "https://testnet.cornscan.io", + "explorer": { + "baseUrl": "https://testnet.cornscan.io" + }, "nativeCurrency": { "name": "Bitcorn", "symbol": "BTCN", @@ -734,7 +846,9 @@ "ASTAR_MAINNET": { "chainId": 592, "title": "Astar", - "explorer": "https://astar.blockscout.com/", + "explorer": { + "baseUrl": "https://astar.blockscout.com" + }, "nativeCurrency": { "name": "Astar", "symbol": "ASTR", @@ -744,7 +858,9 @@ "ASTAR_SHIBUYA": { "chainId": 81, "title": "Astar Shibuya", - "explorer": "https://shibuya.blockscout.com", + "explorer": { + "baseUrl": "https://shibuya.blockscout.com" + }, "nativeCurrency": { "name": "Shibuya testnet tokens", "symbol": "SBY", @@ -760,7 +876,9 @@ "ZIRCUIT_MAINNET": { "chainId": 48900, "title": "Zircuit", - "explorer": "https://explorer.zircuit.com", + "explorer": { + "baseUrl": "https://explorer.zircuit.com" + }, "nativeCurrency": { "name": "ETH", "symbol": "ETH", @@ -770,7 +888,9 @@ "ZIRCUIT_TESTNET": { "chainId": 48899, "title": "Zircuit Testnet", - "explorer": "https://explorer.testnet.zircuit.com", + "explorer": { + "baseUrl": "https://explorer.testnet.zircuit.com" + }, "nativeCurrency": { "name": "ETH", "symbol": "ETH", @@ -786,7 +906,9 @@ "MANTLE_MAINNET": { "chainId": 5000, "title": "Mantle", - "explorer": "https://mantlescan.xyz", + "explorer": { + "baseUrl": "https://mantlescan.xyz" + }, "nativeCurrency": { "name": "Mantle", "symbol": "MNT", @@ -796,7 +918,9 @@ "MANTLE_SEPOLIA": { "chainId": 5003, "title": "Mantle Sepolia", - "explorer": "https://sepolia.mantlescan.xyz", + "explorer": { + "baseUrl": "https://sepolia.mantlescan.xyz" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -812,7 +936,9 @@ "RONIN_MAINNET": { "chainId": 2020, "title": "Ronin", - "explorer": "https://app.roninchain.com", + "explorer": { + "baseUrl": "https://app.roninchain.com" + }, "nativeCurrency": { "name": "RON", "symbol": "RON", @@ -822,7 +948,9 @@ "RONIN_SAIGON": { "chainId": 2021, "title": "Ronin Saigon", - "explorer": "https://saigon-app.roninchain.com", + "explorer": { + "baseUrl": "https://saigon-app.roninchain.com" + }, "nativeCurrency": { "name": "RON", "symbol": "RON", @@ -838,7 +966,9 @@ "BSQUARED_MAINNET": { "chainId": 223, "title": "B²", - "explorer": "https://explorer.bsquared.network", + "explorer": { + "baseUrl": "https://explorer.bsquared.network" + }, "nativeCurrency": { "name": "Bitcoin", "symbol": "BTC", @@ -848,7 +978,9 @@ "BSQUARED_TESTNET": { "chainId": 1123, "title": "B² Testnet", - "explorer": "https://testnet-explorer.bsquared.network", + "explorer": { + "baseUrl": "https://testnet-explorer.bsquared.network" + }, "nativeCurrency": { "name": "Bitcoin", "symbol": "BTC", @@ -864,7 +996,9 @@ "SHIBARIUM_MAINNET": { "chainId": 109, "title": "Shibarium", - "explorer": "https://www.shibariumscan.io", + "explorer": { + "baseUrl": "https://www.shibariumscan.io" + }, "nativeCurrency": { "name": "BONE Shibarium", "symbol": "BONE", @@ -874,7 +1008,9 @@ "SHIBARIUM_PUPPYNET": { "chainId": 157, "title": "Shibarium Puppynet", - "explorer": "https://puppyscan.shib.io", + "explorer": { + "baseUrl": "https://puppyscan.shib.io" + }, "nativeCurrency": { "name": "BONE", "symbol": "BONE", @@ -890,7 +1026,9 @@ "SONIC_MAINNET": { "chainId": 146, "title": "Sonic", - "explorer": "https://sonicscan.org", + "explorer": { + "baseUrl": "https://sonicscan.org" + }, "nativeCurrency": { "name": "Sonic", "symbol": "S", @@ -900,7 +1038,9 @@ "SONIC_BLAZE": { "chainId": 57054, "title": "Sonic Blaze", - "explorer": "https://testnet.sonicscan.org", + "explorer": { + "baseUrl": "https://testnet.sonicscan.org" + }, "nativeCurrency": { "name": "Sonic", "symbol": "S", @@ -916,7 +1056,9 @@ "BOB_MAINNET": { "chainId": 60808, "title": "BOB", - "explorer": "https://explorer.gobob.xyz", + "explorer": { + "baseUrl": "https://explorer.gobob.xyz" + }, "nativeCurrency": { "name": "Ether", "symbol": "ETH", @@ -926,7 +1068,9 @@ "BOB_SEPOLIA": { "chainId": 808813, "title": "BOB Sepolia", - "explorer": "https://bob-sepolia.explorer.gobob.xyz/", + "explorer": { + "baseUrl": "https://bob-sepolia.explorer.gobob.xyz" + }, "nativeCurrency": { "name": "Sepolia Ether", "symbol": "ETH", @@ -942,7 +1086,9 @@ "BOTANIX_MAINNET": { "chainId": 3637, "title": "Botanix", - "explorer": "https://explorer.botanixscan.io", + "explorer": { + "baseUrl": "https://explorer.botanixscan.io" + }, "nativeCurrency": { "name": "Botanix", "symbol": "BTC", @@ -952,7 +1098,9 @@ "BOTANIX_TESTNET": { "chainId": 3636, "title": "Botanix Testnet", - "explorer": "https://testnet.botanixscan.io", + "explorer": { + "baseUrl": "https://testnet.botanixscan.io" + }, "nativeCurrency": { "name": "Botanix", "symbol": "BTC", @@ -960,5 +1108,41 @@ } } } + }, + "SEI": { + "title": "Sei", + "icon": "/assets/chains/sei.svg", + "chains": { + "SEI_MAINNET": { + "chainId": 1329, + "title": "Sei Network", + "explorer": { + "baseUrl": "https://seitrace.com", + "queryParameters": { + "chain": "pacific-1" + } + }, + "nativeCurrency": { + "name": "Sei", + "symbol": "SEI", + "decimals": 18 + } + }, + "SEI_TESTNET": { + "chainId": 1328, + "title": "Sei Testnet", + "explorer": { + "baseUrl": "https://seitrace.com", + "queryParameters": { + "chain": "atlantic-2" + } + }, + "nativeCurrency": { + "name": "Sei", + "symbol": "SEI", + "decimals": 18 + } + } + } } } diff --git a/src/config/types.ts b/src/config/types.ts index d516ec21a47..07eaa4a31c9 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -34,6 +34,8 @@ export type SupportedTechnology = | "HASHKEY" | "CORN" | "BOTANIX" + | "SEI" + export type SupportedChain = | "ETHEREUM_MAINNET" | "ETHEREUM_SEPOLIA" @@ -107,26 +109,32 @@ export type SupportedChain = | "CORN_MAINNET" | "CORN_TESTNET" | "BOTANIX_TESTNET" + | "SEI_MAINNET" + | "SEI_TESTNET" + +export type ExplorerInfo = { + baseUrl: string + queryParameters?: { + [key: string]: string + } +} + +export type ChainInfo = { + chainId: number + title: string + explorer: ExplorerInfo + nativeCurrency: { + name: string + symbol: string + decimals: number + } +} export type Chains = Record< SupportedTechnology, { title: string icon: string - chains: Partial< - Record< - SupportedChain, - { - chainId: number - title: string - explorer: string - nativeCurrency: { - name: string - symbol: string - decimals: number - } - } - > - > + chains: Partial> } > diff --git a/src/config/web3Providers.ts b/src/config/web3Providers.ts index f1aaa358102..ab8999dd047 100644 --- a/src/config/web3Providers.ts +++ b/src/config/web3Providers.ts @@ -76,6 +76,8 @@ export const chainToProvider: Record providers.Provider> = CORN_MAINNET: () => new providers.JsonRpcProvider("https://mainnet.corn-rpc.com"), CORN_TESTNET: () => new providers.JsonRpcProvider("https://testnet.corn-rpc.com"), BOTANIX_TESTNET: () => new providers.JsonRpcProvider("https://node.botanixlabs.dev"), + SEI_MAINNET: () => new providers.JsonRpcProvider("https://evm-rpc.sei-apis.com"), + SEI_TESTNET: () => new providers.JsonRpcProvider("https://evm-rpc-testnet.sei-apis.com"), } export const getRpcUrlForChain = (chain: SupportedChain): string => { diff --git a/src/content/resources/link-token-contracts.mdx b/src/content/resources/link-token-contracts.mdx index 9349e60efec..01fac09e8bd 100644 --- a/src/content/resources/link-token-contracts.mdx +++ b/src/content/resources/link-token-contracts.mdx @@ -894,6 +894,28 @@ Testnet ETH and LINK are available at [faucets.chain.link/mode-sepolia](https:// | Symbol | LINK | | Decimals | 18 | +## Sei + +### Sei Network + +| Parameter | Value | +| :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ETH_CHAIN_ID` | `1329` | +| Address |
    | +| Name | Chainlink Token | +| Symbol | LINK | +| Decimals | 18 | + +### Sei Testnet + +| Parameter | Value | +| :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ETH_CHAIN_ID` | `1328` | +| Address |
    | +| Name | Chainlink Token | +| Symbol | LINK | +| Decimals | 18 | + ## Soneium ### Soneium Mainnet diff --git a/src/features/utils/index.ts b/src/features/utils/index.ts index 7fde5aaf3b6..5aaac753437 100644 --- a/src/features/utils/index.ts +++ b/src/features/utils/index.ts @@ -1,4 +1,4 @@ -import { chains, chainToTechnology, SupportedChain, SupportedTechnology, web3Providers } from "@config" +import { chains, chainToTechnology, ExplorerInfo, SupportedChain, SupportedTechnology, web3Providers } from "@config" import { utils } from "ethers" import referenceChains from "src/scripts/reference/chains.json" @@ -53,8 +53,15 @@ export const getNativeCurrency = (supportedChain: SupportedChain) => { return chains[technology]?.chains[supportedChain]?.nativeCurrency } -export const getExplorerAddressUrl = (explorerUrl: string) => (contractAddress: string) => { - return `${explorerUrl}/address/${contractAddress}` +export const getExplorerAddressUrl = (explorer: ExplorerInfo) => (contractAddress: string) => { + const url = `${explorer.baseUrl}/address/${contractAddress}` + if (!explorer.queryParameters) return url + + const queryString = Object.entries(explorer.queryParameters) + .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) + .join("&") + + return queryString ? `${url}?${queryString}` : url } export const getTitle = (supportedChain: SupportedChain) => { @@ -263,6 +270,10 @@ export const directoryToSupportedChain = (chainInRdd: string): SupportedChain => return "POLYGON_ZKEVM_CARDONA" case "bitcoin-testnet-botanix": return "BOTANIX_TESTNET" + case "sei-mainnet": + return "SEI_MAINNET" + case "sei-testnet-atlantic": + return "SEI_TESTNET" default: throw Error(`Chain not found ${chainInRdd}`) } @@ -406,6 +417,10 @@ export const supportedChainToChainInRdd = (supportedChain: SupportedChain): stri return "ethereum-testnet-sepolia-polygon-zkevm-1" case "BOTANIX_TESTNET": return "bitcoin-testnet-botanix" + case "SEI_MAINNET": + return "sei-mainnet" + case "SEI_TESTNET": + return "sei-testnet-atlantic" default: throw Error(`Chain not found ${supportedChain}`) } diff --git a/src/scripts/chains-metadata.ts b/src/scripts/chains-metadata.ts index c0fa1ec4f72..6ceef45e1f7 100644 --- a/src/scripts/chains-metadata.ts +++ b/src/scripts/chains-metadata.ts @@ -6,69 +6,498 @@ import { writeFile } from "fs/promises" import { normalize } from "path" import { format } from "prettier" +// Configuration constants +const CONFIG = { + CHAINS_METADATA_SOURCE: "https://chainid.network/chains.json", + REQUEST_TIMEOUT_MS: 5000, + MAX_RETRIES: 3, + RETRY_DELAY_MS: 1000, + CURRENT_CHAINS_PATH: "./src/scripts/reference/chains.json", + CHAINS_TO_BE_PATH: "./src/scripts/reference/chainsToBe.json", +} as const + +// Custom error types for better error handling +class ChainMetadataError extends Error { + constructor(message: string, public readonly cause?: unknown) { + super(message) + this.name = "ChainMetadataError" + } +} + +class ValidationError extends ChainMetadataError { + constructor(message: string, public readonly invalidData?: unknown) { + super(message) + this.name = "ValidationError" + } +} + +// Type definitions +interface Explorer { + name: string + url: string + standard: string + icon?: string +} + +interface NativeCurrency { + name: string + symbol: string + decimals: number +} + interface ChainMetadata { name: string chain: string chainId: number + rpc: string[] + faucets: string[] + nativeCurrency: NativeCurrency + infoURL: string + shortName: string + networkId: number + icon?: string + explorers?: Explorer[] + title?: string + features?: Array<{ name: string }> + status?: string + redFlags?: string[] + parent?: { + type: string + chain: string + bridges?: Array<{ url: string }> + } + slip44?: number +} + +// Type guard functions +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value) +} + +function isNativeCurrency(value: unknown): value is NativeCurrency { + if (!isRecord(value)) return false + return typeof value.name === "string" && typeof value.symbol === "string" && typeof value.decimals === "number" +} + +function isExplorer(value: unknown): value is Explorer { + if (!isRecord(value)) return false + return ( + typeof value.name === "string" && + typeof value.url === "string" && + typeof value.standard === "string" && + (value.icon === undefined || typeof value.icon === "string") + ) +} + +function validateChainMetadataArray(data: unknown): ChainMetadata[] { + if (!Array.isArray(data)) { + throw new ValidationError("Expected an array of chain metadata", data) + } + + return data.map((item) => { + if (!isRecord(item)) { + throw new ValidationError("Chain metadata must be an object", item) + } + + // Essential properties that we absolutely need + if (typeof item.chainId !== "number") { + throw new ValidationError("Chain metadata must have a numeric chainId", item) + } + + // Validate known fields but keep the original object + const warnings: string[] = [] + + // Check for unknown fields by comparing with our type definition + const knownFields = new Set([ + "name", + "chain", + "chainId", + "rpc", + "faucets", + "nativeCurrency", + "infoURL", + "shortName", + "networkId", + "icon", + "explorers", + "title", + "features", + "status", + "redFlags", + "parent", + "slip44", + ]) + + Object.keys(item).forEach((key) => { + if (!knownFields.has(key)) { + warnings.push(`Unknown field detected: "${key}" with value: ${JSON.stringify(item[key])}`) + } + }) + + // Validate known fields without modifying the structure + if (item.name !== undefined && typeof item.name !== "string") { + warnings.push(`Invalid name format: expected string, got ${typeof item.name}`) + } + + if (item.chain !== undefined && typeof item.chain !== "string") { + warnings.push(`Invalid chain format: expected string, got ${typeof item.chain}`) + } + + if (item.rpc !== undefined && (!Array.isArray(item.rpc) || !item.rpc.every((url) => typeof url === "string"))) { + warnings.push("Invalid rpc format: expected array of strings") + } + + if ( + item.faucets !== undefined && + (!Array.isArray(item.faucets) || !item.faucets.every((url) => typeof url === "string")) + ) { + warnings.push("Invalid faucets format: expected array of strings") + } + + if (item.nativeCurrency !== undefined && !isNativeCurrency(item.nativeCurrency)) { + warnings.push("Invalid nativeCurrency format") + } + + if (item.infoURL !== undefined && typeof item.infoURL !== "string") { + warnings.push(`Invalid infoURL format: expected string, got ${typeof item.infoURL}`) + } + + if (item.shortName !== undefined && typeof item.shortName !== "string") { + warnings.push(`Invalid shortName format: expected string, got ${typeof item.shortName}`) + } + + if (item.networkId !== undefined && typeof item.networkId !== "number") { + warnings.push(`Invalid networkId format: expected number, got ${typeof item.networkId}`) + } + + if (item.icon !== undefined && typeof item.icon !== "string") { + warnings.push(`Invalid icon format: expected string, got ${typeof item.icon}`) + } + + if (item.explorers !== undefined) { + if (!Array.isArray(item.explorers)) { + warnings.push("Invalid explorers format: expected array") + } else { + item.explorers.forEach((explorer, index) => { + if (!isExplorer(explorer)) { + warnings.push(`Invalid explorer format at index ${index}`) + } + }) + } + } + + // Log warnings if any + if (warnings.length > 0) { + console.warn(`\nWarnings for chain ${item.chainId}:`) + warnings.forEach((warning) => console.warn(` - ${warning}`)) + } + + // Return the original item, maintaining its structure + // We've validated the essential fields above, so this cast is safe + return item as unknown as ChainMetadata + }) } /** - * Helper function to fetch chains metadata from reference api - * @returns + * Parse and validate chain IDs from command line input + * @param input Comma-separated chain IDs + * @throws {ValidationError} When input format is invalid + * @returns {number[]} Array of valid chain IDs */ -const getChainsMetadata = async () => { - const chainsMetadataSource = "https://chainid.network/chains.json" - const response = await fetch(chainsMetadataSource) - return response.json() as Promise +function parseChainIds(input: string): number[] { + try { + const chainIds = input.split(",").map((id) => { + const parsed = parseInt(id.trim(), 10) + if (isNaN(parsed)) { + throw new ValidationError(`Invalid chain ID: ${id}`, id) + } + return parsed + }) + + if (chainIds.length === 0) { + throw new ValidationError("No valid chain IDs provided", input) + } + + return chainIds + } catch (error) { + if (error instanceof ValidationError) { + throw error + } + throw new ValidationError("Failed to parse chain IDs", input) + } } +// Helper function for delayed retry +const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) + /** - * Helper function to filter the chain metadata to keep only the support chain ids. the result in then sorted by chainId asc - * @returns + * Helper function to fetch chains metadata from reference api with retry mechanism + * @throws {ChainMetadataError} When the fetch operation fails after all retries + * @returns {Promise} Array of chain metadata */ -const getSupportedChainsMetadata = async () => { - const chainsMetadata = await getChainsMetadata() - const supportedChainsMetadata = chainsMetadata.filter((chainMetadata) => { - if (!chainMetadata.chainId) { - throw new Error(`Problem with chain reference data ${JSON.stringify(chainMetadata)}`) +const getChainsMetadata = async (): Promise => { + let lastError: Error | undefined + + for (let attempt = 1; attempt <= CONFIG.MAX_RETRIES; attempt++) { + try { + const controller = new AbortController() + const timeout = setTimeout(() => controller.abort(), CONFIG.REQUEST_TIMEOUT_MS) + + const response = await fetch(CONFIG.CHAINS_METADATA_SOURCE, { + signal: controller.signal, + }) + clearTimeout(timeout) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const data = await response.json() + return validateChainMetadataArray(data) + } catch (error) { + lastError = error instanceof Error ? error : new Error(String(error)) + + if (error instanceof ValidationError) { + throw error // Don't retry validation errors + } + + if (attempt < CONFIG.MAX_RETRIES) { + await delay(CONFIG.RETRY_DELAY_MS * attempt) // Exponential backoff + continue + } } - return chainMetadata.chainId.toString() in linkNameSymbol - }) - // ensure it is sorted - supportedChainsMetadata.sort((a, b) => a.chainId - b.chainId) - return supportedChainsMetadata + } + + throw new ChainMetadataError(`Failed to fetch chain metadata after ${CONFIG.MAX_RETRIES} attempts`, lastError) } /** - * Compares current chains metadata with reference one - * @returns + * Get differences between two objects for logging + * @param oldObj Original object + * @param newObj New object + * @param parent Parent key path + * @returns Array of difference strings */ -const compareChainsMetadata = async () => { - const toBeChainsMetadata = await getSupportedChainsMetadata() - let result: { isEqual: boolean; toBeChainsMetadata?: ChainMetadata[] } - if (isEqual(currentChainsMetadata, toBeChainsMetadata)) { - result = { isEqual: true } - } else { - result = { isEqual: false, toBeChainsMetadata } +function getObjectDiffs(oldObj: unknown, newObj: unknown, parent = ""): string[] { + if (!isRecord(oldObj) || !isRecord(newObj)) { + if (oldObj !== newObj) { + return [`${parent}: "${oldObj}" -> "${newObj}"`] + } + return [] + } + + const diffs: string[] = [] + const allKeys = new Set([...Object.keys(oldObj), ...Object.keys(newObj)]) + + for (const key of allKeys) { + const oldVal = oldObj[key] + const newVal = newObj[key] + const keyPath = parent ? `${parent}.${key}` : key + + // Skip if both values are undefined or equal + if (oldVal === newVal) continue + + // Handle arrays specially + if (Array.isArray(oldVal) && Array.isArray(newVal)) { + if (!isEqual(oldVal, newVal)) { + // For arrays, just show the length change if different + if (oldVal.length !== newVal.length) { + diffs.push(`${keyPath}: array length changed from ${oldVal.length} to ${newVal.length}`) + } else { + diffs.push(`${keyPath}: array contents changed`) + } + } + continue + } + + // Recursive check for nested objects + if (isRecord(oldVal) && isRecord(newVal)) { + diffs.push(...getObjectDiffs(oldVal, newVal, keyPath)) + continue + } + + // Simple value change + if (oldVal !== newVal) { + diffs.push(`${keyPath}: "${oldVal}" -> "${newVal}"`) + } } - return result -} - -compareChainsMetadata().then(async (res) => { - if (!res.isEqual) { - const chainsTobePath = normalize("./src/scripts/reference/chainsToBe.json") - await writeFile( - chainsTobePath, - format(JSON.stringify(res.toBeChainsMetadata), { - parser: "json", - semi: true, - trailingComma: "es5", - singleQuote: true, - printWidth: 120, - }), - { - flag: "w", + + return diffs +} + +/** + * Update existing chains with new ones while maintaining sort order + * @param current Current chain metadata + * @param newChains New chain metadata to merge + * @returns {ChainMetadata[]} Merged and sorted chain metadata + */ +function mergeChainMetadata(current: ChainMetadata[], newChains: ChainMetadata[]): ChainMetadata[] { + const merged = new Map() + + // Add current chains to map + current.forEach((chain) => merged.set(chain.chainId, chain)) + + // Update/add new chains with change detection + newChains.forEach((newChain) => { + const existingChain = merged.get(newChain.chainId) + if (existingChain) { + if (!isEqual(existingChain, newChain)) { + console.warn(`\nChanges detected for chain ${newChain.chainId}:`) + const diffs = getObjectDiffs(existingChain, newChain) + diffs.forEach((diff) => console.warn(` ${diff}`)) + } else { + console.log(`\nChain ${newChain.chainId} exists and is identical - no update needed`) } + } else { + console.warn(`\nAdding new chain ${newChain.chainId}`) + } + merged.set(newChain.chainId, newChain) + }) + + // Convert back to array and sort + return Array.from(merged.values()).sort((a, b) => a.chainId - b.chainId) +} + +/** + * Handle specific chain IDs update flow + * @param chainIds Requested chain IDs + * @throws {ChainMetadataError} When update operation fails + */ +async function handleSpecificChains(chainIds: number[]): Promise { + try { + // First get the raw data without validation + const controller = new AbortController() + const timeout = setTimeout(() => controller.abort(), CONFIG.REQUEST_TIMEOUT_MS) + + const response = await fetch(CONFIG.CHAINS_METADATA_SOURCE, { + signal: controller.signal, + }) + clearTimeout(timeout) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const data = await response.json() + if (!Array.isArray(data)) { + throw new ValidationError("Expected an array of chain metadata", data) + } + + // Pre-filter the chains we're interested in + const requestedChains = data.filter( + (item) => isRecord(item) && typeof item.chainId === "number" && chainIds.includes(item.chainId) ) + + // Now validate only the chains we care about + const validatedChains = validateChainMetadataArray(requestedChains) + + if (validatedChains.length === 0) { + throw new ValidationError("No valid chains found to update", chainIds) + } + + // Check for missing chains + const foundChainIds = new Set(validatedChains.map((chain) => chain.chainId)) + const missingChainIds = chainIds.filter((id) => !foundChainIds.has(id)) + + if (missingChainIds.length > 0) { + console.warn(`Warning: The following chain IDs were not found: ${missingChainIds.join(", ")}`) + } + + // Track which chains actually need updates + const changedChains = validatedChains.filter((newChain) => { + const existingChain = currentChainsMetadata.find((chain) => chain.chainId === newChain.chainId) + return !existingChain || !isEqual(existingChain, newChain) + }) + + if (changedChains.length > 0) { + const updatedChains = mergeChainMetadata(currentChainsMetadata, validatedChains) + await writeFile( + normalize(CONFIG.CURRENT_CHAINS_PATH), + format(JSON.stringify(updatedChains), { + parser: "json", + semi: true, + trailingComma: "es5", + singleQuote: true, + printWidth: 120, + }), + { flag: "w" } + ) + console.log(`\nSuccessfully updated ${changedChains.length} chain(s)`) + } else { + console.log(`\nNo updates needed - all chains are up to date`) + } + } catch (error) { + throw new ChainMetadataError("Failed to update specific chains", error) + } +} + +/** + * Handle full comparison flow (original functionality) + */ +async function handleFullComparison(): Promise { + try { + const toBeChainsMetadata = await getSupportedChainsMetadata() + const result = isEqual(currentChainsMetadata, toBeChainsMetadata) + ? { isEqual: true } + : { isEqual: false, toBeChainsMetadata } + + if (!result.isEqual && result.toBeChainsMetadata) { + await writeFile( + normalize(CONFIG.CHAINS_TO_BE_PATH), + format(JSON.stringify(result.toBeChainsMetadata), { + parser: "json", + semi: true, + trailingComma: "es5", + singleQuote: true, + printWidth: 120, + }), + { flag: "w" } + ) + } + } catch (error) { + throw new ChainMetadataError("Failed to handle full comparison", error) } -}) +} + +/** + * Helper function to filter the chain metadata to keep only the supported chain ids + * The result is then sorted by chainId in ascending order + * @throws {ChainMetadataError} When filtering or sorting operations fail + * @returns {Promise} Filtered and sorted chain metadata + */ +const getSupportedChainsMetadata = async (): Promise => { + try { + const chainsMetadata = await getChainsMetadata() + const supportedChainsMetadata = chainsMetadata.filter((chainMetadata) => { + if (!chainMetadata.chainId) { + throw new ValidationError("Chain metadata missing chainId", chainMetadata) + } + return chainMetadata.chainId.toString() in linkNameSymbol + }) + + return supportedChainsMetadata.sort((a, b) => a.chainId - b.chainId) + } catch (error) { + if (error instanceof ChainMetadataError) { + throw error + } + throw new ChainMetadataError("Failed to process supported chains metadata", error) + } +} + +// Main execution +const main = async () => { + try { + const chainIdsArg = process.argv[2] + if (chainIdsArg) { + const chainIds = parseChainIds(chainIdsArg) + await handleSpecificChains(chainIds) + } else { + await handleFullComparison() + } + } catch (error) { + console.error("Error:", error instanceof Error ? error.message : String(error)) + process.exit(1) + } +} + +main() diff --git a/src/scripts/reference/chains.json b/src/scripts/reference/chains.json index ddbdd07ceb1..dafb9215dce 100644 --- a/src/scripts/reference/chains.json +++ b/src/scripts/reference/chains.json @@ -623,6 +623,32 @@ "networkId": 1285, "explorers": [{ "name": "moonscan", "url": "https://moonriver.moonscan.io", "standard": "none" }] }, + { + "name": "Sei Testnet", + "chain": "Sei", + "rpc": ["https://evm-rpc-testnet.sei-apis.com", "wss://evm-ws-testnet.sei-apis.com"], + "faucets": ["https://atlantic-2.app.sei.io/faucet"], + "nativeCurrency": { "name": "Sei", "symbol": "SEI", "decimals": 18 }, + "infoURL": "https://www.sei.io", + "shortName": "sei-testnet", + "chainId": 1328, + "networkId": 1328, + "icon": "sei", + "explorers": [{ "name": "Seitrace", "url": "https://seitrace.com", "standard": "EIP3091" }] + }, + { + "name": "Sei Network", + "chain": "Sei", + "rpc": ["https://evm-rpc.sei-apis.com", "wss://evm-ws.sei-apis.com"], + "faucets": [], + "nativeCurrency": { "name": "Sei", "symbol": "SEI", "decimals": 18 }, + "infoURL": "https://www.sei.io", + "shortName": "sei", + "chainId": 1329, + "networkId": 1329, + "icon": "seiv2", + "explorers": [{ "name": "Seitrace", "url": "https://seitrace.com", "standard": "EIP3091" }] + }, { "name": "Soneium", "shortName": "soneium", diff --git a/src/scripts/reference/linkNameSymbol.json b/src/scripts/reference/linkNameSymbol.json index e3ca8b2dfbd..df7284d54f3 100644 --- a/src/scripts/reference/linkNameSymbol.json +++ b/src/scripts/reference/linkNameSymbol.json @@ -295,5 +295,13 @@ "3636": { "name": "ChainLink Token", "symbol": "LINK" + }, + "1328": { + "name": "ChainLink Token", + "symbol": "LINK" + }, + "1329": { + "name": "ChainLink Token", + "symbol": "LINK" } }