diff --git a/jest.config.js b/jest.config.js index f1f03302e8c..ce7244f818d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -4,5 +4,8 @@ module.exports = { transform: { "^.+\\.ts?$": "ts-jest", }, + moduleNameMapper: { + "\\.(css)$": "/src/__mocks__/styleMock.ts", + }, transformIgnorePatterns: ["/node_modules/"], } diff --git a/src/__mocks__/styleMock.ts b/src/__mocks__/styleMock.ts new file mode 100644 index 00000000000..4ba52ba2c8d --- /dev/null +++ b/src/__mocks__/styleMock.ts @@ -0,0 +1 @@ +module.exports = {} diff --git a/src/content/data-feeds/examples.mdx b/src/content/data-feeds/examples.mdx index 04d4ad93382..fdb4980f6f4 100644 --- a/src/content/data-feeds/examples.mdx +++ b/src/content/data-feeds/examples.mdx @@ -9,7 +9,8 @@ metadata: description: "How to use Chainlink Data Feeds in your smart contracts." --- -import { LatestPrice, priceFeedAddresses } from "@features/feeds" +import { LatestPrice } from "@features/feeds" +import { priceFeedAddresses } from "@features/data" import { Aside, CodeSample } from "@components" import { Tabs } from "@components/Tabs" import button from "@chainlink/design-system/button.module.css" diff --git a/src/content/data-feeds/feed-registry/index.mdx b/src/content/data-feeds/feed-registry/index.mdx index 0eba0a00465..cc2ce37e24e 100644 --- a/src/content/data-feeds/feed-registry/index.mdx +++ b/src/content/data-feeds/feed-registry/index.mdx @@ -13,7 +13,9 @@ whatsnext: } --- -import { RegistryPrice, registryAddresses } from "@features/feeds" +import { RegistryPrice } from "@features/feeds" +import { registryAddresses } from "@features/data" + import { Aside, ClickToZoom, CodeSample } from "@components" The Chainlink Feed Registry is an on-chain mapping of assets to feeds. It enables you to query Chainlink data feeds from asset addresses directly, without needing to know the feed contract addresses. They enable smart contracts to get the latest price of an asset in a single call, from a single contract. diff --git a/src/content/data-feeds/historical-data.mdx b/src/content/data-feeds/historical-data.mdx index a3433e22fad..bf4054955c8 100644 --- a/src/content/data-feeds/historical-data.mdx +++ b/src/content/data-feeds/historical-data.mdx @@ -8,7 +8,8 @@ metadata: description: "How to use Chainlink Data Feeds to retrieve historical data in your smart contracts." --- -import { HistoricalPrice, priceFeedAddresses } from "@features/feeds" +import { priceFeedAddresses } from "@features/data" +import { HistoricalPrice } from "@features/feeds" import { Aside, ClickToZoom, CodeSample } from "@components" import button from "@chainlink/design-system/button.module.css" diff --git a/src/features/feeds/api/backend.ts b/src/features/data/api/backend.ts similarity index 95% rename from src/features/feeds/api/backend.ts rename to src/features/data/api/backend.ts index 4267c00656e..2bdb1d7766b 100644 --- a/src/features/feeds/api/backend.ts +++ b/src/features/data/api/backend.ts @@ -1,6 +1,6 @@ import EleventyFetch from "@11ty/eleventy-fetch" import { ChainMetadata } from "." -import { Chain } from "../data/chains" +import { Chain } from "../chains" export const getServerSideChainMetadata = async (chains: Chain[]): Promise => { const cache = {} as ChainMetadata diff --git a/src/features/feeds/api/index.ts b/src/features/data/api/index.ts similarity index 97% rename from src/features/feeds/api/index.ts rename to src/features/data/api/index.ts index 159e7211257..0ce8d02da45 100644 --- a/src/features/feeds/api/index.ts +++ b/src/features/data/api/index.ts @@ -1,4 +1,4 @@ -import { Chain } from "../data/chains" +import { Chain } from "../chains" interface Docs { nftFloorUnits: any diff --git a/src/features/feeds/data/chains.ts b/src/features/data/chains.ts similarity index 93% rename from src/features/feeds/data/chains.ts rename to src/features/data/chains.ts index 0512dcc81c8..901bba4aa19 100644 --- a/src/features/feeds/data/chains.ts +++ b/src/features/data/chains.ts @@ -1,4 +1,4 @@ -import { ChainMetadata } from "../api" +import { ChainMetadata } from "./api" type ChainTags = ("default" | "proofOfReserve" | "nftFloorPrice" | "rates")[] export interface ChainNetwork { @@ -17,6 +17,7 @@ export interface Chain { networks: ChainNetwork[] label?: string tags?: ChainTags + supportedFeatures: ("vrfSubscription" | "vrfDirectFunding" | "feeds")[] } export const CHAINS: Chain[] = [ @@ -26,6 +27,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/ethereum.svg", networkStatusUrl: "https://ethstats.dev/", tags: ["default", "proofOfReserve", "nftFloorPrice", "rates"], + supportedFeatures: ["vrfSubscription", "vrfDirectFunding", "feeds"], networks: [ { name: "Ethereum Mainnet", @@ -57,6 +59,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/bnb-chain.svg", networkStatusUrl: "https://bscscan.freshstatus.io/", tags: ["default"], + supportedFeatures: ["vrfSubscription", "vrfDirectFunding", "feeds"], networks: [ { name: "BNB Chain Mainnet", @@ -80,6 +83,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/polygon.svg", networkStatusUrl: "https://polygon.io/system", tags: ["default", "proofOfReserve", "nftFloorPrice", "rates"], + supportedFeatures: ["vrfSubscription", "vrfDirectFunding", "feeds"], networks: [ { name: "Polygon Mainnet", @@ -103,6 +107,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/gnosis-chain.svg", networkStatusUrl: "https://gnosisscan.io/", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "Gnosis Chain Mainnet", @@ -119,6 +124,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/avalanche.svg", networkStatusUrl: "https://status.avax.network/", tags: ["default", "proofOfReserve", "rates"], + supportedFeatures: ["vrfSubscription", "vrfDirectFunding", "feeds"], networks: [ { name: "Avalanche Mainnet", @@ -144,6 +150,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/fantom.svg", networkStatusUrl: "https://ftmscan.com/", tags: ["default"], + supportedFeatures: ["vrfSubscription", "vrfDirectFunding", "feeds"], networks: [ { name: "Fantom Mainnet", @@ -166,6 +173,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/arbitrum.svg", networkStatusUrl: "https://arbiscan.freshstatus.io/", tags: ["default", "rates"], + supportedFeatures: ["vrfSubscription", "vrfDirectFunding", "feeds"], networks: [ { name: "Arbitrum Mainnet", @@ -189,6 +197,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/harmony.svg", networkStatusUrl: "https://status.harmony.one/", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "Harmony Mainnet", @@ -205,6 +214,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/optimism.svg", networkStatusUrl: "https://status.optimism.io/", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "Optimism Mainnet", @@ -227,6 +237,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/moonriver.svg", networkStatusUrl: "https://moonscan.freshstatus.io/", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "Moonriver Mainnet", @@ -243,6 +254,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/moonbeam.svg", networkStatusUrl: "https://moonscan.freshstatus.io/", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "Moonbeam Mainnet", @@ -259,6 +271,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/metis.svg", networkStatusUrl: "https://andromeda-explorer.metis.io/", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "Metis Mainnet", @@ -275,6 +288,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/base.svg", networkStatusUrl: "https://goerli.basescan.org", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "BASE Goerli testnet", @@ -291,6 +305,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/celo.svg", networkStatusUrl: "https://stats.celo.org/", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "Celo mainnet", @@ -313,6 +328,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/starknet.svg", networkStatusUrl: "https://testnet.starkscan.co/stats", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "StarkNet testnet", @@ -329,6 +345,7 @@ export const CHAINS: Chain[] = [ img: "/assets/chains/solana.svg", networkStatusUrl: "https://status.solana.com/", tags: ["default"], + supportedFeatures: ["feeds"], networks: [ { name: "Solana Mainnet", @@ -354,6 +371,7 @@ export const ALL_CHAINS: Chain[] = [ img: "/assets/chains/ethereum.svg", networkStatusUrl: "https://ethstats.dev/", tags: ["default", "proofOfReserve", "nftFloorPrice"], + supportedFeatures: ["feeds"], networks: [ { name: "Ethereum Mainnet", diff --git a/src/features/feeds/data/index.ts b/src/features/data/index.ts similarity index 100% rename from src/features/feeds/data/index.ts rename to src/features/data/index.ts diff --git a/src/features/feeds/components/FeedList.tsx b/src/features/feeds/components/FeedList.tsx index c8f09fcef36..b7aed9ea319 100644 --- a/src/features/feeds/components/FeedList.tsx +++ b/src/features/feeds/components/FeedList.tsx @@ -4,9 +4,9 @@ import { MainnetTable, TestnetTable } from "./Tables" import feedList from "./FeedList.module.css" import { clsx } from "~/lib" import { updateTableOfContents } from "~/components/RightSidebar/TableOfContents/tocStore" -import { Chain, CHAINS, ALL_CHAINS } from "../data/chains" +import { Chain, CHAINS, ALL_CHAINS } from "~/features/data/chains" import { useGetChainMetadata } from "./useGetChainMetadata" -import { ChainMetadata } from "../api" +import { ChainMetadata } from "../../data/api" import useQueryString from "~/hooks/useQueryString" export type DataFeedType = "default" | "por" | "nftFloor" | "rates" diff --git a/src/features/feeds/components/FeedPage.astro b/src/features/feeds/components/FeedPage.astro index 10b9dfa49f4..8a0b53a8337 100644 --- a/src/features/feeds/components/FeedPage.astro +++ b/src/features/feeds/components/FeedPage.astro @@ -8,10 +8,10 @@ export type Props = { ecosystem: string dataFeedType?: DataFeedType } -import { getServerSideChainMetadata } from "../api/backend" -import { CHAINS, ALL_CHAINS } from "../data/chains" +import { getServerSideChainMetadata } from "~/features/data//api/backend" +import { CHAINS, ALL_CHAINS } from "~/features/data/chains" import { CheckHeartbeat } from "./pause-notice/CheckHeartbeat" -import { FeedDataItem, monitoredFeeds } from "../data" +import { FeedDataItem, monitoredFeeds } from "~/features/data" const { initialNetwork, ecosystem, dataFeedType } = Astro.props diff --git a/src/features/feeds/components/Tables.tsx b/src/features/feeds/components/Tables.tsx index be3c9d19885..22763381178 100644 --- a/src/features/feeds/components/Tables.tsx +++ b/src/features/feeds/components/Tables.tsx @@ -1,10 +1,10 @@ /** @jsxImportSource preact */ import feedList from "./FeedList.module.css" import { clsx } from "../../../lib" -import { ChainNetwork } from "../data/chains" +import { ChainNetwork } from "~/features/data/chains" import tableStyles from "./Tables.module.css" import { CheckHeartbeat } from "./pause-notice/CheckHeartbeat" -import { monitoredFeeds, FeedDataItem } from "../data" +import { monitoredFeeds, FeedDataItem } from "~/features/data" const feedItems = monitoredFeeds.mainnet const feedCategories = { diff --git a/src/features/feeds/components/useGetChainMetadata.ts b/src/features/feeds/components/useGetChainMetadata.ts index 541175127ba..fd2fd5593aa 100644 --- a/src/features/feeds/components/useGetChainMetadata.ts +++ b/src/features/feeds/components/useGetChainMetadata.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from "preact/hooks" -import { getChainMetadata } from "../api" -import { Chain } from "../data/chains" +import { getChainMetadata } from "../../data/api" +import { Chain } from "~/features/data/chains" export function useGetChainMetadata(chain: Chain, { initialCache }) { const [cache, setCache] = useState(initialCache ?? { [chain.page]: chain }) diff --git a/src/features/feeds/index.ts b/src/features/feeds/index.ts index 00b2b46a161..89fb193b887 100644 --- a/src/features/feeds/index.ts +++ b/src/features/feeds/index.ts @@ -1,3 +1,2 @@ export * from "./components" -export * from "./data" export * from "./types" diff --git a/src/features/vrf/v2/components/CostTable.test.ts b/src/features/vrf/v2/components/CostTable.test.ts new file mode 100644 index 00000000000..881b59d56ec --- /dev/null +++ b/src/features/vrf/v2/components/CostTable.test.ts @@ -0,0 +1,39 @@ +import { getGasCalculatorUrl } from "./CostTable" +import { expect, test } from "@jest/globals" +import { ChainNetwork } from "~/features/data/chains" + +describe("getGasCalculatorUrl", () => { + test("works with testnet", () => { + const mainChainName = "ethereum" + const networkName = "goerli" + const chain: ChainNetwork = { + name: "Goerli Testnet", + explorerUrl: "https://goerli.etherscan.io/address/%s", + networkType: "testnet", + rddUrl: "https://reference-data-directory.vercel.app/feeds-goerli.json", + tags: ["proofOfReserve", "nftFloorPrice"], + } + const method = "vrfSubscription" + + expect(getGasCalculatorUrl({ mainChainName, networkName, chain, method })).toEqual( + "https://vrf.chain.link/api/calculator?networkName=ethereum&networkType=goerli&method=subscription" + ) + }) + + test("works with mainnet", () => { + const mainChainName = "polygon" + const networkName = "mainnet" + const chain: ChainNetwork = { + name: "Polygon Mainnet", + explorerUrl: "https://polygonscan.com/address/%s", + networkType: "mainnet", + rddUrl: "https://reference-data-directory.vercel.app/feeds-matic-mainnet.json", + tags: ["proofOfReserve"], + } + const method = "vrfDirectFunding" + + expect(getGasCalculatorUrl({ mainChainName, networkName, chain, method })).toEqual( + "https://vrf.chain.link/api/calculator?networkName=polygon&networkType=mainnet&method=directFunding" + ) + }) +}) diff --git a/src/features/vrf/v2/components/CostTable.tsx b/src/features/vrf/v2/components/CostTable.tsx index c88b0d53fb4..5acdcd5e490 100644 --- a/src/features/vrf/v2/components/CostTable.tsx +++ b/src/features/vrf/v2/components/CostTable.tsx @@ -1,13 +1,14 @@ -import { network, vrfChain } from "~/features/vrf/v2/data" +import { Chain, ChainNetwork } from "~/features/data/chains" + import "./costTable.css" -import { useEffect, useReducer } from "preact/hooks" +import { useEffect, useReducer, useState } from "preact/hooks" import { BigNumber, utils } from "ethers" import button from "@chainlink/design-system/button.module.css" interface Props { - mainChain: vrfChain - chain: network - method: "subscription" | "directFunding" + mainChain: Chain + chain: ChainNetwork + method: "vrfSubscription" | "vrfDirectFunding" } interface directFundingResponse { @@ -139,21 +140,33 @@ const reducer = (state: State, action: Action) => { const cache: Cache = {} +export const getGasCalculatorUrl = ({ + mainChainName, + networkName, + chain, + method, +}: { + mainChainName: string + networkName: string + chain: ChainNetwork + method: Props["method"] +}) => { + return `https://vrf.chain.link/api/calculator?networkName=${mainChainName}&networkType=${ + networkName === mainChainName ? chain.networkType.toLowerCase() : networkName + }&method=${method === "vrfSubscription" ? "subscription" : "directFunding"}` +} export const CostTable = ({ mainChain, chain, method }: Props) => { const [state, dispatch] = useReducer(reducer, initialState) - + const [supportedNetworkShortcut, setSupportedNetworkShortcut] = useState("") const getDataResponse = async (mainChainName: string, networkName: string): Promise => { - const cacheKey = `${mainChainName}-${networkName === mainChainName ? chain.type : networkName}-${method}` + const cacheKey = `${mainChainName}-${networkName === mainChainName ? chain.networkType : networkName}-${ + method === "vrfSubscription" ? "subscription" : "directFunding" + }` if (cache[cacheKey] && cache[cacheKey].latestCacheUpdate - Date.now() < CACHE_EXPIRY_TIME) { return cache[cacheKey].data } - const response = await fetch( - `https://vrf.chain.link/api/calculator?networkName=${mainChainName}&networkType=${ - networkName === mainChainName ? chain.type.toLowerCase() : networkName - }&method=${method}`, - { method: "GET" } - ) + const response = await fetch(getGasCalculatorUrl({ mainChainName, networkName, chain, method }), { method: "GET" }) const json: dataResponse = await response.json() cache[cacheKey] = { @@ -164,14 +177,43 @@ export const CostTable = ({ mainChain, chain, method }: Props) => { } useEffect(() => { - const mainChainName = - mainChain.name === "BNB Chain" - ? mainChain.name.replace("Chain", "").replace(" ", "").toLowerCase() - : mainChain.name.toLowerCase() - const networkName = - chain.name === "BNB Chain" - ? chain.name.replace("Chain", "").replace(" ", "").toLowerCase() - : chain.name.toLowerCase() + let mainChainName, networkName + switch (mainChain.label) { + case "BNB Chain": + mainChainName = mainChain.label.replace("Chain", "").replace(" ", "").toLowerCase() + break + case "Polygon (Matic)": + mainChainName = mainChain.label.replace(" (Matic)", "").toLowerCase() + break + default: + mainChainName = mainChain.label.toLowerCase() + } + if (chain.name.includes("Mainnet")) { + networkName = "mainnet" + } + switch (chain.name) { + case "Sepolia Testnet": + networkName = "sepolia" + break + case "Goerli Testnet": + networkName = "goerli" + break + case "BNB Chain Testnet": + networkName = "testnet" + break + case "Mumbai Testnet": + networkName = "mumbai" + break + case "Avalanche Testnet": + networkName = "fuji" + break + case "Fantom Testnet": + networkName = "testnet" + break + case "Arbitrum Goerli": + networkName = "goerli" + break + } dispatch({ type: "SET_LOADING", payload: true }) const fillInputs = async () => { const responseJson: dataResponse = await getDataResponse(mainChainName, networkName) @@ -219,7 +261,7 @@ export const CostTable = ({ mainChain, chain, method }: Props) => { dispatch({ type: "SET_LOADING", payload: false }) console.error(error) }) - + setSupportedNetworkShortcut(getsupportedNetworkShortcut(networkName)) return () => dispatch({ type: "SET_LOADING", payload: false }) }, [method, mainChain, chain]) @@ -250,7 +292,7 @@ export const CostTable = ({ mainChain, chain, method }: Props) => { const VRFL1Buffer = VRFL1CostEstimate.div(L2P) const VRFL1GasLaneBuffer = VRFL1CostEstimate.div(L2PGasLane) const bigNumberLINKPremium = utils.parseUnits(LINKPremium.toString()) - if (method === "subscription") { + if (method === "vrfSubscription") { const VRFL2SubscriptionGasSubtotal = BigNumber.from(currentVerificationGas + callbackGas) const VRFSubscriptionGasTotal = VRFL2SubscriptionGasSubtotal.add(VRFL1Buffer) const VRFSubscriptionGasEstimate = L2P.mul(VRFSubscriptionGasTotal) @@ -295,32 +337,34 @@ export const CostTable = ({ mainChain, chain, method }: Props) => { } } - const getsupportedNetworkShortcut = () => { - const mainChainName = mainChain.name.toLowerCase() - const subChainName = chain.name.toLowerCase() + const getsupportedNetworkShortcut = (networkName) => { + const mainChainName = mainChain.label.toLowerCase() switch (mainChainName) { case "ethereum": - if (subChainName !== "mainnet") { - return `${subChainName}-${chain.type}` - } - return `${mainChainName}-${chain.type}` + return `${chain.networkType !== "mainnet" ? networkName : mainChainName}-${chain.networkType}` case "bnb chain": - return `${mainChainName.replace(" ", "-")}${chain.type === "testnet" ? "-" + chain.type : ""}` - case "polygon": - return `${mainChainName}-matic-${chain.type === "testnet" ? subChainName + "-" + chain.type : chain.type}` + return `${mainChainName.replace(" ", "-")}${chain.networkType === "testnet" ? "-" + chain.networkType : ""}` + case "polygon (matic)": + return `polygon-matic-${ + chain.networkType === "testnet" ? networkName + "-" + chain.networkType : chain.networkType + }` case "avalanche": - return `${mainChainName}-${chain.type === "testnet" ? subChainName + "-" + chain.type : chain.type}` + return `${mainChainName}-${ + chain.networkType === "testnet" ? networkName + "-" + chain.networkType : chain.networkType + }` case "fantom": - return `${mainChainName}-${chain.type}` + return `${mainChainName}-${chain.networkType}` case "arbitrum": - return `${mainChainName}-${chain.type === "testnet" ? subChainName + "-" + chain.type : chain.type}` + return `${mainChainName}-${ + chain.networkType === "testnet" ? networkName + "-" + chain.networkType : chain.networkType + }` default: throw new Error("network/chain does not exist or is not supported by VRF yet.") } } const computeTotalRequestCost = () => { - if (mainChain.name.toLowerCase() === "arbitrum") { + if (mainChain.label.toLowerCase() === "arbitrum") { computeArbitrumCost() return } @@ -339,7 +383,7 @@ export const CostTable = ({ mainChain, chain, method }: Props) => { const bigNumberGasLane = utils.parseUnits(currentGasLane.toString(), "gwei") const bigNumberPriceFeed = utils.formatUnits(BigNumber.from(priceFeed), decimalPlaces) const formattedPriceFeed = utils.parseEther(bigNumberPriceFeed) - if (method === "subscription") { + if (method === "vrfSubscription") { const vrfSubscriptionGasSubTotal = BigNumber.from(callbackGas + currentVerificationGas) const addition = bigNumberGasPrice.mul(vrfSubscriptionGasSubTotal) @@ -493,7 +537,7 @@ export const CostTable = ({ mainChain, chain, method }: Props) => { /> - {mainChain.name.toLowerCase() === "arbitrum" && state.L1GasPriceEstimate && ( + {mainChain.label.toLowerCase() === "arbitrum" && state.L1GasPriceEstimate && ( L1 gas price (current is {getGasPrice(state.L1GasPriceEstimate)} gwei) @@ -522,12 +566,14 @@ export const CostTable = ({ mainChain, chain, method }: Props) => { - {method === "subscription" ? "Average verification gas" : "Coordinator gas overhead (verification gas)"} + {method === "vrfSubscription" + ? "Average verification gas" + : "Coordinator gas overhead (verification gas)"} {utils.commify(state.currentVerificationGas)} - {method === "subscription" && ( + {method === "vrfSubscription" && ( <> Gas lane (Hash) @@ -554,7 +600,7 @@ export const CostTable = ({ mainChain, chain, method }: Props) => { )} - {method === "directFunding" && ( + {method === "vrfDirectFunding" && ( Wrapper overhead gas {state.wrapperOverheadGas} @@ -572,7 +618,7 @@ export const CostTable = ({ mainChain, chain, method }: Props) => {
Estimated cost per request: {formatTotal()} LINK
- {method === "subscription" && ( + {method === "vrfSubscription" && ( <>
Maximum cost per request under the selected gas lane: {formatmaxCost()} LINK

@@ -588,7 +634,12 @@ export const CostTable = ({ mainChain, chain, method }: Props) => { )}

To see these parameters in greater detail, read the - + {" "} Supported Networks{" "} diff --git a/src/features/vrf/v2/components/DropdownMenu.tsx b/src/features/vrf/v2/components/DropdownMenu.tsx index 3a67545b7cf..ca3c6a8921a 100644 --- a/src/features/vrf/v2/components/DropdownMenu.tsx +++ b/src/features/vrf/v2/components/DropdownMenu.tsx @@ -1,23 +1,23 @@ import { useEffect, useMemo, useRef, useState } from "preact/hooks" import "./dropdown.css" import { CostTable } from "./CostTable" -import { vrfChain, network } from "~/features/vrf/v2/data" import { RefObject } from "preact" +import { CHAINS, Chain, ChainNetwork } from "~/features/data/chains" interface Props { placeholder?: string - options: vrfChain[] - method: "subscription" | "directFunding" + method: "vrfSubscription" | "vrfDirectFunding" } -export const DropDownMenu = ({ placeholder = "Select a network...", options, method }: Props) => { - const [selectedMainChain, setSelectedMainChain] = useState(null) - const [selectedChain, setSelectedChain] = useState(null) +export const DropDownMenu = ({ placeholder = "Select a network...", method }: Props) => { + const [selectedMainChain, setSelectedMainChain] = useState(null) + const [selectedChain, setSelectedChain] = useState(null) const [selectedNet, setSelectNet] = useState(placeholder) const [searchValue, setSearchValue] = useState("") const [showMenu, setShowMenu] = useState(false) const [showSubMenu, setShowSubMenu] = useState(-1) const wrapperRef = useRef(null) + const options = CHAINS.filter((chain) => chain.supportedFeatures.includes(method)) const useOutsideAlerter = (ref: RefObject) => { useEffect(() => { @@ -40,27 +40,19 @@ export const DropDownMenu = ({ placeholder = "Select a network...", options, met }, [ref]) } - const matchingOptions: vrfChain[] = useMemo(() => { - const formattedSearchValue = searchValue.replaceAll(" ", "") - const splittedSearchValueArr = formattedSearchValue.split("-") + const matchingOptions: Chain[] = useMemo(() => { + const splittedSearchValueArr = searchValue.split(" ") if (splittedSearchValueArr.length >= 2) { return options } - return options.filter((chain: vrfChain) => { - return searchValue === "" ? chain : chain.name.toLowerCase().includes(searchValue.toLowerCase()) + return options.filter((chain: Chain) => { + return searchValue === "" ? chain : chain.label.toLowerCase().includes(searchValue.toLowerCase()) }) }, [searchValue, options]) - const handleSelectedChain = (net: network, chain: vrfChain) => { - let res: string = chain.name + " - " - if (chain.name === net.name) { - res += net.type - } else { - res += net.name - } - - setSelectNet(res) - setSearchValue(res) + const handleSelectedChain = (net: ChainNetwork) => { + setSelectNet(net.name) + setSearchValue(net.name) } const handleInputChange = (event: Event) => { @@ -100,7 +92,7 @@ export const DropDownMenu = ({ placeholder = "Select a network...", options, met ref={wrapperRef} > {matchingOptions && - matchingOptions.map((item: vrfChain, index: number) => ( + matchingOptions.map((item: Chain, index: number) => (

{showSubMenu === index && - item.nets && - item.nets.length > 0 && - item.nets.map((network: network) => ( + item.networks && + item.networks.length > 0 && + item.networks.map((network: ChainNetwork) => ( ))} diff --git a/src/features/vrf/v2/components/MethodCheckbox.tsx b/src/features/vrf/v2/components/MethodCheckbox.tsx index 5dfdea4f93f..cfe0548f3e4 100644 --- a/src/features/vrf/v2/components/MethodCheckbox.tsx +++ b/src/features/vrf/v2/components/MethodCheckbox.tsx @@ -1,10 +1,9 @@ import { useState } from "preact/hooks" import "./methodCheckbox.css" import { DropDownMenu } from "./DropdownMenu" -import { supportedNetworks } from "../data" export const MethodCheckbox = () => { - const [vrfMethodUsed, setVrfMethodUsed] = useState<"subscription" | "directFunding">("subscription") + const [vrfMethodUsed, setVrfMethodUsed] = useState<"vrfSubscription" | "vrfDirectFunding">("vrfSubscription") const handleChange = (event) => { setVrfMethodUsed(event.target.value) @@ -17,10 +16,10 @@ export const MethodCheckbox = () => {
@@ -28,17 +27,17 @@ export const MethodCheckbox = () => {
- +
) } diff --git a/src/features/vrf/v2/data/index.ts b/src/features/vrf/v2/data/index.ts deleted file mode 100644 index 1390b87e440..00000000000 --- a/src/features/vrf/v2/data/index.ts +++ /dev/null @@ -1,120 +0,0 @@ -export interface network { - name: string - type: "mainnet" | "testnet" -} - -export interface vrfChain { - name: string - img?: string - nets: network[] -} - -export interface vrfNetsByMethod { - subscription: vrfChain[] - directFunding: vrfChain[] -} - -export const supportedNetworks: vrfNetsByMethod = { - subscription: [ - { - name: "Ethereum", - img: "/assets/chains/ethereum.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Goerli", type: "testnet" }, - { name: "Sepolia", type: "testnet" }, - ], - }, - { - name: "BNB Chain", - img: "/assets/chains/bnb-chain.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Testnet", type: "testnet" }, - ], - }, - { - name: "Polygon", - img: "/assets/chains/polygon.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Mumbai", type: "testnet" }, - ], - }, - { - name: "Avalanche", - img: "/assets/chains/avalanche.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Fuji", type: "testnet" }, - ], - }, - { - name: "Fantom", - img: "/assets/chains/fantom.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Testnet", type: "testnet" }, - ], - }, - { - name: "Arbitrum", - img: "/assets/chains/arbitrum.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Goerli", type: "testnet" }, - ], - }, - ], - directFunding: [ - { - name: "Ethereum", - img: "/assets/chains/ethereum.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Goerli", type: "testnet" }, - { name: "Sepolia", type: "testnet" }, - ], - }, - { - name: "BNB Chain", - img: "/assets/chains/bnb-chain.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Testnet", type: "testnet" }, - ], - }, - { - name: "Polygon", - img: "/assets/chains/polygon.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Mumbai", type: "testnet" }, - ], - }, - { - name: "Avalanche", - img: "/assets/chains/avalanche.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Fuji", type: "testnet" }, - ], - }, - { - name: "Fantom", - img: "/assets/chains/fantom.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Testnet", type: "testnet" }, - ], - }, - { - name: "Arbitrum", - img: "/assets/chains/arbitrum.svg", - nets: [ - { name: "Mainnet", type: "mainnet" }, - { name: "Goerli", type: "testnet" }, - ], - }, - ], -}