From dfc6893d7a0ef0d2149a73be68e1e7bc21de7778 Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Mon, 22 Jun 2026 14:26:58 -0300 Subject: [PATCH 1/3] feat: env extend h assets --- .env.example | 4 +++ pages/reserve-overview.page.tsx | 15 +++++++++ src/modules/dashboard/lists/constants.ts | 42 +++++++++++++++++++++++- 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index eb7fe1530b..b14753df1c 100644 --- a/.env.example +++ b/.env.example @@ -21,6 +21,10 @@ NEXT_PUBLIC_FIAT_ON_RAMP=true NEXT_PUBLIC_IS_CYPRESS_ENABLED=false NEXT_PUBLIC_AMPLITUDE_API_KEY=6b28cb736c53d59f0951a50f59597aae NEXT_PUBLIC_PRIVATE_RPC_ENABLED=false +# Comma-separated reserves to hide from the markets/dashboard lists and reserve detail page. +# Each entry is either a bare underlying address (hidden in all markets) or a `market:address` +# pair (hidden only in that market). e.g. 0xabc...,proto_base_v3:0xdef... +NEXT_PUBLIC_HIDDEN_RESERVES= diff --git a/pages/reserve-overview.page.tsx b/pages/reserve-overview.page.tsx index 02c6281c25..93cde66d37 100644 --- a/pages/reserve-overview.page.tsx +++ b/pages/reserve-overview.page.tsx @@ -13,6 +13,7 @@ import { import { AssetCapsProvider } from 'src/hooks/useAssetCaps'; import { AssetCapsProviderSDK } from 'src/hooks/useAssetCapsSDK'; import { MainLayout } from 'src/layouts/MainLayout'; +import { isAssetHidden } from 'src/modules/dashboard/lists/constants'; import { ReserveActions } from 'src/modules/reserve-overview/ReserveActions'; import { ReserveConfigurationWrapper } from 'src/modules/reserve-overview/ReserveConfigurationWrapper'; import { ReserveTopDetailsWrapper } from 'src/modules/reserve-overview/ReserveTopDetailsWrapper'; @@ -51,6 +52,16 @@ export default function ReserveOverview() { const [mode, setMode] = useState<'overview' | 'actions' | ''>('overview'); const trackEvent = useRootStore((store) => store.trackEvent); + const currentMarket = useRootStore((store) => store.currentMarket); + + // Hidden reserves shouldn't be reachable via deep link either. + const reserveHidden = !!underlyingAsset && isAssetHidden(currentMarket, underlyingAsset); + + useEffect(() => { + if (router.isReady && reserveHidden) { + router.replace('/markets'); + } + }, [router, reserveHidden]); //With SDK const reserve = supplyReserves.find((reserve) => { @@ -76,6 +87,10 @@ export default function ReserveOverview() { const isOverview = mode === 'overview'; + if (reserveHidden) { + return null; + } + return ( diff --git a/src/modules/dashboard/lists/constants.ts b/src/modules/dashboard/lists/constants.ts index 3e21ccaa39..06a24371a7 100644 --- a/src/modules/dashboard/lists/constants.ts +++ b/src/modules/dashboard/lists/constants.ts @@ -6,6 +6,46 @@ export const HIDDEN_ASSETS: Partial> = { ], }; +// Reserves can also be hidden at build/deploy time via the NEXT_PUBLIC_HIDDEN_RESERVES env var. +// It's a comma-separated list of entries where each entry is either: +// - a bare underlying asset address: hidden in every market, e.g. `0xabc...` +// - a `market:address` pair: hidden only in that market, e.g. `proto_mainnet_v3:0xabc...` +// Example: NEXT_PUBLIC_HIDDEN_RESERVES=0xabc...,proto_base_v3:0xdef... +const parseHiddenReservesEnv = () => { + const global = new Set(); + const byMarket: Partial>> = {}; + + const raw = process.env.NEXT_PUBLIC_HIDDEN_RESERVES; + if (!raw) { + return { global, byMarket }; + } + + raw + .split(',') + .map((entry) => entry.trim()) + .filter(Boolean) + .forEach((entry) => { + const [first, second] = entry.split(':').map((part) => part.trim()); + if (second) { + const market = first as CustomMarket; + const address = second.toLowerCase(); + if (!address) return; + (byMarket[market] ??= new Set()).add(address); + } else if (first) { + global.add(first.toLowerCase()); + } + }); + + return { global, byMarket }; +}; + +const { global: ENV_HIDDEN_GLOBAL, byMarket: ENV_HIDDEN_BY_MARKET } = parseHiddenReservesEnv(); + export const isAssetHidden = (market: CustomMarket, underlyingAsset: string) => { - return HIDDEN_ASSETS[market]?.includes(underlyingAsset.toLowerCase()); + const address = underlyingAsset.toLowerCase(); + return Boolean( + HIDDEN_ASSETS[market]?.includes(address) || + ENV_HIDDEN_GLOBAL.has(address) || + ENV_HIDDEN_BY_MARKET[market]?.has(address) + ); }; From bf849e5a743a33efe3c826b23928100a894e2c31 Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Mon, 22 Jun 2026 14:29:57 -0300 Subject: [PATCH 2/3] feat: comments --- .env.example | 4 +--- pages/reserve-overview.page.tsx | 1 - src/modules/dashboard/lists/constants.ts | 5 ----- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.env.example b/.env.example index b14753df1c..5eef4d42e1 100644 --- a/.env.example +++ b/.env.example @@ -21,9 +21,7 @@ NEXT_PUBLIC_FIAT_ON_RAMP=true NEXT_PUBLIC_IS_CYPRESS_ENABLED=false NEXT_PUBLIC_AMPLITUDE_API_KEY=6b28cb736c53d59f0951a50f59597aae NEXT_PUBLIC_PRIVATE_RPC_ENABLED=false -# Comma-separated reserves to hide from the markets/dashboard lists and reserve detail page. -# Each entry is either a bare underlying address (hidden in all markets) or a `market:address` -# pair (hidden only in that market). e.g. 0xabc...,proto_base_v3:0xdef... +# e.g. 0xabc...,proto_base_v3:0xdef... NEXT_PUBLIC_HIDDEN_RESERVES= diff --git a/pages/reserve-overview.page.tsx b/pages/reserve-overview.page.tsx index 93cde66d37..e6fca4aaf3 100644 --- a/pages/reserve-overview.page.tsx +++ b/pages/reserve-overview.page.tsx @@ -54,7 +54,6 @@ export default function ReserveOverview() { const trackEvent = useRootStore((store) => store.trackEvent); const currentMarket = useRootStore((store) => store.currentMarket); - // Hidden reserves shouldn't be reachable via deep link either. const reserveHidden = !!underlyingAsset && isAssetHidden(currentMarket, underlyingAsset); useEffect(() => { diff --git a/src/modules/dashboard/lists/constants.ts b/src/modules/dashboard/lists/constants.ts index 06a24371a7..b81eb917bc 100644 --- a/src/modules/dashboard/lists/constants.ts +++ b/src/modules/dashboard/lists/constants.ts @@ -6,11 +6,6 @@ export const HIDDEN_ASSETS: Partial> = { ], }; -// Reserves can also be hidden at build/deploy time via the NEXT_PUBLIC_HIDDEN_RESERVES env var. -// It's a comma-separated list of entries where each entry is either: -// - a bare underlying asset address: hidden in every market, e.g. `0xabc...` -// - a `market:address` pair: hidden only in that market, e.g. `proto_mainnet_v3:0xabc...` -// Example: NEXT_PUBLIC_HIDDEN_RESERVES=0xabc...,proto_base_v3:0xdef... const parseHiddenReservesEnv = () => { const global = new Set(); const byMarket: Partial>> = {}; From 284006edc3d5847362d5fa2ec9e996856bd5374f Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Mon, 22 Jun 2026 16:30:08 -0300 Subject: [PATCH 3/3] chore: added to map --- src/modules/dashboard/lists/constants.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/dashboard/lists/constants.ts b/src/modules/dashboard/lists/constants.ts index b81eb917bc..6cba180fb8 100644 --- a/src/modules/dashboard/lists/constants.ts +++ b/src/modules/dashboard/lists/constants.ts @@ -3,6 +3,7 @@ import { CustomMarket } from 'src/ui-config/marketsConfig'; export const HIDDEN_ASSETS: Partial> = { [CustomMarket.proto_horizon_v3]: [ '0x17418038ecf73ba4026c4f428547bf099706f27b'.toLowerCase(), // aCRED + '0x7433806912Eae67919e66aea853d46Fa0aef98A8'.toLowerCase(), ], };