From 651cb412cd6e0146fbaebbd8a962f276794ed464 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Fri, 1 Aug 2025 15:19:27 -0700 Subject: [PATCH 1/9] temporary solution parsing svr feed variants --- src/features/feeds/components/FeedList.tsx | 2 + .../feeds/components/Tables.module.css | 13 ++++ src/features/feeds/components/Tables.tsx | 69 +++++++++++++++---- 3 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/features/feeds/components/FeedList.tsx b/src/features/feeds/components/FeedList.tsx index 863ce9d1556..4f30031fd49 100644 --- a/src/features/feeds/components/FeedList.tsx +++ b/src/features/feeds/components/FeedList.tsx @@ -469,6 +469,7 @@ export const FeedList = ({ network={network} showExtraDetails={showExtraDetails} showOnlySVR={showOnlySVR} + svrFilter="all" showOnlyMVRFeeds={showOnlyMVRFeeds} showOnlyDEXFeeds={showOnlyDEXFeeds} dataFeedType={dataFeedType} @@ -836,6 +837,7 @@ export const FeedList = ({ network={network} showExtraDetails={showExtraDetails} showOnlySVR={showOnlySVR} + svrFilter="all" showOnlyMVRFeeds={showOnlyMVRFeeds} showOnlyDEXFeeds={false} dataFeedType={dataFeedType} diff --git a/src/features/feeds/components/Tables.module.css b/src/features/feeds/components/Tables.module.css index a8d5790e887..e3418ccc3b6 100644 --- a/src/features/feeds/components/Tables.module.css +++ b/src/features/feeds/components/Tables.module.css @@ -195,6 +195,19 @@ text-align: left; } +.sharedCallout { + background-color: #e6f3ff; + border-radius: 4px; + padding: 10px 12px; + margin-top: 10px; + margin-bottom: 10px; + font-size: 0.9rem; + color: #0066cc; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + width: 100%; + text-align: left; +} + .feedVariantBadge { display: inline-block; font-size: 0.75rem; diff --git a/src/features/feeds/components/Tables.tsx b/src/features/feeds/components/Tables.tsx index 6ffcab6f00a..0bbf3b7c5e5 100644 --- a/src/features/feeds/components/Tables.tsx +++ b/src/features/feeds/components/Tables.tsx @@ -9,9 +9,20 @@ import button from "@chainlink/design-system/button.module.css" import { CheckHeartbeat } from "./pause-notice/CheckHeartbeat.tsx" import { monitoredFeeds, FeedDataItem } from "~/features/data/index.ts" import { StreamsNetworksData, type NetworkData } from "../data/StreamsNetworksData.ts" -import { type Docs } from "~/features/data/api/index.ts" +import { type ChainMetadata } from "~/features/data/api/index.ts" const feedItems = monitoredFeeds.mainnet + +// Helper functions for SVR feed categorization +const isSharedSVR = (metadata: ChainMetadata): boolean => { + // Check for marketing.path or fallback to path field + const pathToCheck = (metadata as ChainMetadata & { marketing?: { path?: string } })?.marketing?.path || metadata.path + return typeof pathToCheck === "string" && /-shared-svr$/.test(pathToCheck) +} + +const isAaveSVR = (metadata: ChainMetadata): boolean => { + return !!metadata?.secondaryProxyAddress && !isSharedSVR(metadata) +} const feedCategories = { low: ( ( href="/data-feeds/svr-feeds" target="_blank" className={tableStyles.feedVariantBadge} - title="SVR-enabled Feed" + title={ + isAaveSVR(metadata) + ? "Aave Dedicated SVR Feed" + : isSharedSVR(metadata) + ? "Shared SVR Feed" + : "SVR-enabled Feed" + } > - SVR + {isAaveSVR(metadata) ? "Aave SVR" : isSharedSVR(metadata) ? "Shared SVR" : "SVR"} )} @@ -304,7 +321,7 @@ const DefaultTr = ({ network, metadata, showExtraDetails }) => (
- AAVE SVR Proxy: + {isAaveSVR(metadata) ? "AAVE SVR Proxy:" : "SVR Proxy:"}
-
- ⚠️ Aave Dedicated Feed: This SVR proxy feed is dedicated exclusively for use by the - Aave protocol. Learn more about{" "} - - SVR-enabled Feeds - - . -
+ {isAaveSVR(metadata) && ( +
+ ⚠️ Aave Dedicated Feed: This SVR proxy feed is dedicated exclusively for use by the + Aave protocol. Learn more about{" "} + + SVR-enabled Feeds + + . +
+ )} + {isSharedSVR(metadata) && ( +
+ 🔗 Shared SVR Feed: This SVR proxy feed is usable by any protocol. Learn more about{" "} + + SVR-enabled Feeds + + . +
+ )} )} @@ -903,6 +931,7 @@ export const MainnetTable = ({ network, showExtraDetails, showOnlySVR, + svrFilter = "all", // "all" | "aave" | "shared" showOnlyMVRFeeds, showOnlyDEXFeeds, dataFeedType, @@ -918,6 +947,7 @@ export const MainnetTable = ({ network: ChainNetwork showExtraDetails: boolean showOnlySVR: boolean + svrFilter?: "all" | "aave" | "shared" showOnlyMVRFeeds: boolean showOnlyDEXFeeds: boolean dataFeedType: string @@ -940,8 +970,17 @@ export const MainnetTable = ({ const filteredMetadata = network.metadata .sort((a, b) => (a.name < b.name ? -1 : 1)) .filter((metadata) => { - if (showOnlySVR && !metadata.secondaryProxyAddress) { - return false + // Handle SVR filtering with granular options + if (showOnlySVR) { + if (svrFilter === "aave" && !isAaveSVR(metadata)) { + return false + } + if (svrFilter === "shared" && !isSharedSVR(metadata)) { + return false + } + if (svrFilter === "all" && !metadata.secondaryProxyAddress) { + return false + } } if (isDeprecating) return !!metadata.docs.shutdownDate @@ -1095,7 +1134,7 @@ export const TestnetTable = ({ lastAddr = 1000, addrPerPage = 8, currentPage = 1, - paginate = (_page: number) => { + paginate = () => { /* Default no-op function */ }, searchValue = "", From 972c89836309993177eb033fe5bd6d3bfdbc832a Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 5 Aug 2025 11:31:22 -0700 Subject: [PATCH 2/9] update --- src/features/feeds/components/FeedList.tsx | 2 - src/features/feeds/components/Tables.tsx | 43 ++-------------------- 2 files changed, 3 insertions(+), 42 deletions(-) diff --git a/src/features/feeds/components/FeedList.tsx b/src/features/feeds/components/FeedList.tsx index 4f30031fd49..863ce9d1556 100644 --- a/src/features/feeds/components/FeedList.tsx +++ b/src/features/feeds/components/FeedList.tsx @@ -469,7 +469,6 @@ export const FeedList = ({ network={network} showExtraDetails={showExtraDetails} showOnlySVR={showOnlySVR} - svrFilter="all" showOnlyMVRFeeds={showOnlyMVRFeeds} showOnlyDEXFeeds={showOnlyDEXFeeds} dataFeedType={dataFeedType} @@ -837,7 +836,6 @@ export const FeedList = ({ network={network} showExtraDetails={showExtraDetails} showOnlySVR={showOnlySVR} - svrFilter="all" showOnlyMVRFeeds={showOnlyMVRFeeds} showOnlyDEXFeeds={false} dataFeedType={dataFeedType} diff --git a/src/features/feeds/components/Tables.tsx b/src/features/feeds/components/Tables.tsx index 0bbf3b7c5e5..4e2f784684b 100644 --- a/src/features/feeds/components/Tables.tsx +++ b/src/features/feeds/components/Tables.tsx @@ -15,9 +15,8 @@ const feedItems = monitoredFeeds.mainnet // Helper functions for SVR feed categorization const isSharedSVR = (metadata: ChainMetadata): boolean => { - // Check for marketing.path or fallback to path field - const pathToCheck = (metadata as ChainMetadata & { marketing?: { path?: string } })?.marketing?.path || metadata.path - return typeof pathToCheck === "string" && /-shared-svr$/.test(pathToCheck) + // Check the path field for feeds ending with "-shared-svr" + return typeof metadata.path === "string" && /-shared-svr$/.test(metadata.path) } const isAaveSVR = (metadata: ChainMetadata): boolean => { @@ -931,7 +930,6 @@ export const MainnetTable = ({ network, showExtraDetails, showOnlySVR, - svrFilter = "all", // "all" | "aave" | "shared" showOnlyMVRFeeds, showOnlyDEXFeeds, dataFeedType, @@ -947,7 +945,6 @@ export const MainnetTable = ({ network: ChainNetwork showExtraDetails: boolean showOnlySVR: boolean - svrFilter?: "all" | "aave" | "shared" showOnlyMVRFeeds: boolean showOnlyDEXFeeds: boolean dataFeedType: string @@ -970,15 +967,8 @@ export const MainnetTable = ({ const filteredMetadata = network.metadata .sort((a, b) => (a.name < b.name ? -1 : 1)) .filter((metadata) => { - // Handle SVR filtering with granular options if (showOnlySVR) { - if (svrFilter === "aave" && !isAaveSVR(metadata)) { - return false - } - if (svrFilter === "shared" && !isSharedSVR(metadata)) { - return false - } - if (svrFilter === "all" && !metadata.secondaryProxyAddress) { + if (!metadata.secondaryProxyAddress) { return false } } @@ -1042,33 +1032,6 @@ export const MainnetTable = ({ selectedFeedCategories.map((cat) => cat.toLowerCase()).includes(metadata.feedCategory?.toLowerCase()) ) }) - .filter( - (metadata) => - metadata.name.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.proxyAddress - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.secondaryProxyAddress - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.assetName.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.feedType.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.docs.porType - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.docs.porAuditor - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.docs.porSource - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.feedId?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) - ) const slicedFilteredMetadata = filteredMetadata.slice(firstAddr, lastAddr) From a5e636eeb8fd4e459b5d7ca5480be2ad35de9e87 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 5 Aug 2025 11:38:40 -0700 Subject: [PATCH 3/9] restored filter (mistakingly removed) --- src/features/feeds/components/Tables.tsx | 32 ++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/features/feeds/components/Tables.tsx b/src/features/feeds/components/Tables.tsx index 4e2f784684b..7f72c736553 100644 --- a/src/features/feeds/components/Tables.tsx +++ b/src/features/feeds/components/Tables.tsx @@ -1192,13 +1192,31 @@ export const TestnetTable = ({ ) }) .filter( - (pair) => - !searchValue || - pair.name?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - pair.proxyAddress?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - pair.assetName?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - pair.feedType?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - pair.feedId?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) + (metadata) => + metadata.name.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.proxyAddress + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.secondaryProxyAddress + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.assetName.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.feedType.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.docs.porType + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.docs.porAuditor + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.docs.porSource + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.feedId?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) ) const slicedFilteredMetadata = filteredMetadata.slice(firstAddr, lastAddr) From c6e3f6de5d25e0210898f12b64c98e2c5139a677 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 5 Aug 2025 11:46:49 -0700 Subject: [PATCH 4/9] return filter --- src/features/feeds/components/Tables.tsx | 61 ++++++++++++++---------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/src/features/feeds/components/Tables.tsx b/src/features/feeds/components/Tables.tsx index 58a2f16eb70..363395aa33a 100644 --- a/src/features/feeds/components/Tables.tsx +++ b/src/features/feeds/components/Tables.tsx @@ -1032,6 +1032,33 @@ export const MainnetTable = ({ selectedFeedCategories.map((cat) => cat.toLowerCase()).includes(metadata.feedCategory?.toLowerCase()) ) }) + .filter( + (metadata) => + metadata.name.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.proxyAddress + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.secondaryProxyAddress + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.assetName.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.feedType.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.docs.porType + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.docs.porAuditor + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.docs.porSource + ?.toLowerCase() + .replaceAll(" ", "") + .includes(searchValue.toLowerCase().replaceAll(" ", "")) || + metadata.feedId?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) + ) const slicedFilteredMetadata = filteredMetadata.slice(firstAddr, lastAddr) @@ -1097,7 +1124,7 @@ export const TestnetTable = ({ lastAddr = 1000, addrPerPage = 8, currentPage = 1, - paginate = () => { + paginate = (_page: number) => { /* Default no-op function */ }, searchValue = "", @@ -1192,31 +1219,13 @@ export const TestnetTable = ({ ) }) .filter( - (metadata) => - metadata.name.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.proxyAddress - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.secondaryProxyAddress - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.assetName.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.feedType.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.docs.porType - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.docs.porAuditor - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.docs.porSource - ?.toLowerCase() - .replaceAll(" ", "") - .includes(searchValue.toLowerCase().replaceAll(" ", "")) || - metadata.feedId?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) + (pair) => + !searchValue || + pair.name?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + pair.proxyAddress?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + pair.assetName?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + pair.feedType?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) || + pair.feedId?.toLowerCase().replaceAll(" ", "").includes(searchValue.toLowerCase().replaceAll(" ", "")) ) const slicedFilteredMetadata = filteredMetadata.slice(firstAddr, lastAddr) From 02bb71dbadaedef888838ae24fa9f826d79259b8 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 5 Aug 2025 11:53:13 -0700 Subject: [PATCH 5/9] restore logic --- src/features/feeds/components/Tables.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/features/feeds/components/Tables.tsx b/src/features/feeds/components/Tables.tsx index 363395aa33a..3f62a61e526 100644 --- a/src/features/feeds/components/Tables.tsx +++ b/src/features/feeds/components/Tables.tsx @@ -967,10 +967,8 @@ export const MainnetTable = ({ const filteredMetadata = network.metadata .sort((a, b) => (a.name < b.name ? -1 : 1)) .filter((metadata) => { - if (showOnlySVR) { - if (!metadata.secondaryProxyAddress) { - return false - } + if (showOnlySVR && !metadata.secondaryProxyAddress) { + return false } if (isDeprecating) return !!metadata.docs.shutdownDate From dc1f02304497ba34ca0dbc96aed72534f9f31178 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 5 Aug 2025 12:35:27 -0700 Subject: [PATCH 6/9] shared->canonical for user display --- src/features/feeds/components/Tables.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/features/feeds/components/Tables.tsx b/src/features/feeds/components/Tables.tsx index 3f62a61e526..02c02acf97e 100644 --- a/src/features/feeds/components/Tables.tsx +++ b/src/features/feeds/components/Tables.tsx @@ -227,11 +227,11 @@ const DefaultTr = ({ network, metadata, showExtraDetails }) => ( isAaveSVR(metadata) ? "Aave Dedicated SVR Feed" : isSharedSVR(metadata) - ? "Shared SVR Feed" + ? "Canonical SVR Feed" : "SVR-enabled Feed" } > - {isAaveSVR(metadata) ? "Aave SVR" : isSharedSVR(metadata) ? "Shared SVR" : "SVR"} + {isAaveSVR(metadata) ? "Aave SVR" : isSharedSVR(metadata) ? "Canonical SVR" : "SVR"}
)} @@ -359,7 +359,8 @@ const DefaultTr = ({ network, metadata, showExtraDetails }) => ( )} {isSharedSVR(metadata) && (
- 🔗 Shared SVR Feed: This SVR proxy feed is usable by any protocol. Learn more about{" "} + 🔗 Canonical SVR Feed: This SVR proxy feed is usable by any protocol. Learn more + about{" "} SVR-enabled Feeds From dbc8fc2cf6faa96fb15a3f4c2ba40a44b9bd0af9 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 5 Aug 2025 13:24:00 -0700 Subject: [PATCH 7/9] created util to avoid duplicate regex filtering --- src/features/feeds/components/Tables.tsx | 12 +----------- src/features/feeds/utils/svrDetection.ts | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 src/features/feeds/utils/svrDetection.ts diff --git a/src/features/feeds/components/Tables.tsx b/src/features/feeds/components/Tables.tsx index 02c02acf97e..a00f0aa170f 100644 --- a/src/features/feeds/components/Tables.tsx +++ b/src/features/feeds/components/Tables.tsx @@ -9,19 +9,9 @@ import button from "@chainlink/design-system/button.module.css" import { CheckHeartbeat } from "./pause-notice/CheckHeartbeat.tsx" import { monitoredFeeds, FeedDataItem } from "~/features/data/index.ts" import { StreamsNetworksData, type NetworkData } from "../data/StreamsNetworksData.ts" -import { type ChainMetadata } from "~/features/data/api/index.ts" +import { isSharedSVR, isAaveSVR } from "~/features/feeds/utils/svrDetection.ts" const feedItems = monitoredFeeds.mainnet - -// Helper functions for SVR feed categorization -const isSharedSVR = (metadata: ChainMetadata): boolean => { - // Check the path field for feeds ending with "-shared-svr" - return typeof metadata.path === "string" && /-shared-svr$/.test(metadata.path) -} - -const isAaveSVR = (metadata: ChainMetadata): boolean => { - return !!metadata?.secondaryProxyAddress && !isSharedSVR(metadata) -} const feedCategories = { low: ( { + // Check the path field for feeds ending with "-shared-svr" + return typeof metadata.path === "string" && /-shared-svr$/.test(metadata.path) +} + +/** + * Determines if a feed is an Aave dedicated SVR feed + * @param metadata - The feed metadata object + * @returns true if the feed has a secondary proxy address but is not a shared SVR feed + */ +export const isAaveSVR = (metadata: ChainMetadata): boolean => { + return !!metadata?.secondaryProxyAddress && !isSharedSVR(metadata) +} From f86abf56f952851abdad836043e5a592f666b69c Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 5 Aug 2025 14:13:38 -0700 Subject: [PATCH 8/9] updated svr-feeds page, updated links --- src/content/data-feeds/svr-feeds/index.mdx | 78 ++++++++++++++++++---- src/features/data/chains.ts | 3 +- src/features/feeds/components/Tables.tsx | 16 +++-- 3 files changed, 78 insertions(+), 19 deletions(-) diff --git a/src/content/data-feeds/svr-feeds/index.mdx b/src/content/data-feeds/svr-feeds/index.mdx index dfdc76f0ebc..18c2f265492 100644 --- a/src/content/data-feeds/svr-feeds/index.mdx +++ b/src/content/data-feeds/svr-feeds/index.mdx @@ -14,6 +14,7 @@ whatsnext: import { Aside, ClickToZoom, CodeSample, CopyText } from "@components" import { Tabs } from "@components/Tabs" import { CHAINS } from "@features/data/chains" +import { isSharedSVR, isAaveSVR } from "~/features/feeds/utils/svrDetection.ts" export async function getFeeds() { const ethereumMainnet = CHAINS.find((chain) => chain.page === "ethereum")?.networks.find( @@ -33,6 +34,7 @@ const data = await response.json() const targetFeeds = [ "AAVE/USD-RefPrice-DF-Ethereum-001", "BTC/USD-RefPrice-DF-Ethereum-001", + "COMP/USD-RefPrice-DF-Ethereum-001", "ETH/USD-RefPrice-DF-Ethereum-001", "LINK/USD-RefPrice-DF-Ethereum-001", "USDC/USD-RefPrice-DF-Ethereum-001", @@ -44,13 +46,33 @@ const data = await response.json() feed.secondaryProxyAddress && feed.docs?.clicProductName && targetFeeds.includes(feed.docs.clicProductName) ) - return svrFeeds - .map((feed) => ({ - name: feed.name.replace(" / ", "/"), - address: feed.contractAddress, - })) + // Group feeds by their base name (e.g., "BTC/USD", "ETH/USD") + const feedGroups = {} + + svrFeeds.forEach(feed => { + const baseName = feed.name.replace(" / ", "/") + + if (!feedGroups[baseName]) { + feedGroups[baseName] = { + name: baseName, + aaveAddress: null, + canonicalAddress: null + } + } + + if (isAaveSVR(feed)) { + feedGroups[baseName].aaveAddress = feed.contractAddress + } else if (isSharedSVR(feed)) { + feedGroups[baseName].canonicalAddress = feed.contractAddress + } + }) + + // Convert to array and sort + const combinedFeeds = Object.values(feedGroups) .sort((a, b) => a.name.localeCompare(b.name)) + return combinedFeeds + } catch (error) { return [] } @@ -136,6 +158,22 @@ Chainlink Smart Value Recapture (SVR) extends standard Chainlink Price Feeds wit **Fail-Safe Fallback Mechanism** If the **private route** fails or times out, the SVR feed automatically **reverts** to the **Standard Feed price** after a configurable delay. This delay can be set to any amount of seconds. This helps ensures the feed doesn't stall and that price data is accessible through the public route if the private channel is unavailable. +## SVR Feed Variants + +Chainlink SVR Feeds are currently available in two variants: [Canonical SVR Feeds](#canonical-svr-feeds) and [Aave SVR Feeds](#aave-svr-feeds). + +### Canonical SVR Feeds + +Canonical SVR feeds are designed to be used by any protocol. + +{/* [More info] */} + +### Aave SVR Feeds + +Aave SVR feeds are specifically tailored for the Aave protocol. + +{/* [More info] */} + ## How Protocols Can Utilize SVR Feeds ### 1. Identify the SVR Feed Address @@ -293,30 +331,44 @@ The following code samples demonstrate the complete decoding process, including -#### 4. Detect SVR-enabled Feeds for the Aave Protocol +#### 4. Detect SVR-enabled Feeds When processing forward calls, verify that the `to` address from the code sample above (the destination of the forward call) matches one of these feed addresses. This tells you which SVR data feed the price update is for: - - + + + {feeds && feeds.map((feed) => ( - - + + + ))} {(!feeds || feeds.length === 0) && ( - + )} @@ -393,7 +445,7 @@ For gas management, simulations, and other advanced usage, see the official [Fla 3. **Stay Updated** - Keep track of any updates to the SVR aggregator address, function signatures, or Flashbots MEV-Share changes. - - Monitor for changes in Aave liquidation parameters (e.g., new assets, different collateral thresholds). + - Monitor for changes in liquidation parameters (e.g., new assets, different collateral thresholds). ## Economics and Revenue Split diff --git a/src/features/data/chains.ts b/src/features/data/chains.ts index b0a51831a62..a94e21969aa 100644 --- a/src/features/data/chains.ts +++ b/src/features/data/chains.ts @@ -257,7 +257,8 @@ export const CHAINS: Chain[] = [ name: "Ethereum Mainnet", explorerUrl: "https://etherscan.io/address/%s", networkType: "mainnet", - rddUrl: "https://reference-data-directory.vercel.app/feeds-mainnet.json", + rddUrl: + "https://gist.githubusercontent.com/dev-dist/ce452c3a623a754998ebda361ef59448/raw/ed425feb9efc37c43f7994c51ea16e7a4d98ca73/feed-mainnet-svr-test-.json", rddBundleUrl: "https://reference-data-directory.vercel.app/bundle-proxies-mainnet.json", queryString: "ethereum-mainnet", tags: ["smartData"], diff --git a/src/features/feeds/components/Tables.tsx b/src/features/feeds/components/Tables.tsx index a00f0aa170f..63b58cd397a 100644 --- a/src/features/feeds/components/Tables.tsx +++ b/src/features/feeds/components/Tables.tsx @@ -210,7 +210,13 @@ const DefaultTr = ({ network, metadata, showExtraDetails }) => ( {metadata.secondaryProxyAddress && (
( @@ -351,8 +357,8 @@ const DefaultTr = ({ network, metadata, showExtraDetails }) => (
🔗 Canonical SVR Feed: This SVR proxy feed is usable by any protocol. Learn more about{" "} - - SVR-enabled Feeds + + Canonical SVR Feeds .
From 49b282e2192f6338a13d9c2917eae6ee3ea22ab7 Mon Sep 17 00:00:00 2001 From: Devin DiStefano Date: Tue, 5 Aug 2025 14:15:58 -0700 Subject: [PATCH 9/9] nit --- src/features/data/chains.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/features/data/chains.ts b/src/features/data/chains.ts index a94e21969aa..b0a51831a62 100644 --- a/src/features/data/chains.ts +++ b/src/features/data/chains.ts @@ -257,8 +257,7 @@ export const CHAINS: Chain[] = [ name: "Ethereum Mainnet", explorerUrl: "https://etherscan.io/address/%s", networkType: "mainnet", - rddUrl: - "https://gist.githubusercontent.com/dev-dist/ce452c3a623a754998ebda361ef59448/raw/ed425feb9efc37c43f7994c51ea16e7a4d98ca73/feed-mainnet-svr-test-.json", + rddUrl: "https://reference-data-directory.vercel.app/feeds-mainnet.json", rddBundleUrl: "https://reference-data-directory.vercel.app/bundle-proxies-mainnet.json", queryString: "ethereum-mainnet", tags: ["smartData"],
Feed nameAddressFeedAave Dedicated SVR FeedCanonical SVR Feed
{feed.name}
+ {feed.name} + + {feed.aaveAddress ? ( + + ) : ( + Not available + )} + - + {feed.canonicalAddress ? ( + + ) : ( + Not available + )}
No SVR feeds found.No SVR feeds found.