From afd2623181a3b2b006184d6adc9a0ad9f6691b37 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 07:51:37 +0000 Subject: [PATCH 01/15] Initial plan From 9175a60232781f36feb612d3a0425ce02ad48fad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 08:05:51 +0000 Subject: [PATCH 02/15] Fix vault display issue with per-chain caching and logs persistence - Implement per-chain caching for operated pools in NavBar to prevent disappearing vaults when switching chains - Add logs to persisted state list to maintain logs across page navigation and chain switches - Improve PoolSelect component to properly handle chain changes by resetting initialization flag - These changes ensure vaults remain visible when switching between Swap and Pool pages Co-authored-by: gabririgo <12066256+gabririgo@users.noreply.github.com> --- .../components/NavBar/PoolSelect/index.tsx | 20 ++++++++++++----- apps/web/src/components/NavBar/index.tsx | 22 +++++++++---------- apps/web/src/state/webReducer.ts | 1 + 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/apps/web/src/components/NavBar/PoolSelect/index.tsx b/apps/web/src/components/NavBar/PoolSelect/index.tsx index 9befef6dd65..1538c57d804 100644 --- a/apps/web/src/components/NavBar/PoolSelect/index.tsx +++ b/apps/web/src/components/NavBar/PoolSelect/index.tsx @@ -76,16 +76,24 @@ const PoolSelect: React.FC = ({ operatedPools }) => { // on chain switch revert to default pool if selected does not exist on new chain const activePoolExistsOnChain = operatedPools?.some(pool => pool.address === activeSmartPool?.address); - // initialize selected pool - use ref to prevent re-initialization - const hasInitialized = React.useRef(false); + // Track chain ID to reset initialization when chain changes + const currentChainId = operatedPools?.[0]?.chainId; + const prevChainIdRef = React.useRef(currentChainId); + const hasInitializedRef = React.useRef(false); useEffect(() => { - if (!hasInitialized.current && (!activeSmartPool?.name || !activePoolExistsOnChain)) { + // Reset initialization flag when chain changes + if (currentChainId !== prevChainIdRef.current) { + hasInitializedRef.current = false; + prevChainIdRef.current = currentChainId; + } + + // Initialize or re-initialize when pool doesn't exist on current chain + if (!hasInitializedRef.current && operatedPools?.[0] && (!activeSmartPool?.name || !activePoolExistsOnChain)) { onPoolSelect(operatedPools[0]); - hasInitialized.current = true; + hasInitializedRef.current = true; } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [activePoolExistsOnChain, activeSmartPool?.name]) + }, [activePoolExistsOnChain, activeSmartPool?.name, onPoolSelect, operatedPools, currentChainId]) // Memoize poolsAsCurrrencies to prevent recreation on every render const poolsAsCurrrencies = React.useMemo(() => diff --git a/apps/web/src/components/NavBar/index.tsx b/apps/web/src/components/NavBar/index.tsx index 60137c82cc5..659ec6cf11a 100644 --- a/apps/web/src/components/NavBar/index.tsx +++ b/apps/web/src/components/NavBar/index.tsx @@ -141,23 +141,23 @@ export default function Navbar() { const isSignInExperimentControl = !isEmbeddedWalletEnabled && isControl const shouldDisplayCreateAccountButton = false const rawOperatedPools = useOperatedPools() - const cachedPoolsRef = useRef(undefined) - const prevChainIdRef = useRef(account.chainId) + + // Cache pools per chain to maintain display across chain switches + const cachedPoolsByChainRef = useRef>(new Map()) useEffect(() => { - if (account.chainId !== prevChainIdRef.current) { - cachedPoolsRef.current = undefined - prevChainIdRef.current = account.chainId + if (rawOperatedPools && rawOperatedPools.length > 0 && account.chainId) { + cachedPoolsByChainRef.current.set(account.chainId, rawOperatedPools) } - }, [account.chainId]) + }, [rawOperatedPools, account.chainId]) - useEffect(() => { - if (rawOperatedPools && rawOperatedPools.length > 0) { - cachedPoolsRef.current = rawOperatedPools + const cachedOperatedPools = useMemo(() => { + if (account.chainId && cachedPoolsByChainRef.current.has(account.chainId)) { + return cachedPoolsByChainRef.current.get(account.chainId) } - }, [rawOperatedPools]) + return rawOperatedPools + }, [rawOperatedPools, account.chainId]) - const cachedOperatedPools = cachedPoolsRef.current ?? rawOperatedPools const cachedUserIsOperator = useMemo(() => Boolean(cachedOperatedPools && cachedOperatedPools.length > 0), [cachedOperatedPools] diff --git a/apps/web/src/state/webReducer.ts b/apps/web/src/state/webReducer.ts index a27ad14f350..6a87c9d8965 100644 --- a/apps/web/src/state/webReducer.ts +++ b/apps/web/src/state/webReducer.ts @@ -43,6 +43,7 @@ export const interfacePersistedStateList: Array 'lists', 'poolsList', 'fiatOnRampTransactions', + 'logs', ] export type InterfaceState = ReturnType From e14048307b87cc357dadc78b339cbc5aa4679042 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 08:08:34 +0000 Subject: [PATCH 03/15] Fix typo: poolsAsCurrrencies -> poolsAsCurrencies Co-authored-by: gabririgo <12066256+gabririgo@users.noreply.github.com> --- apps/web/src/components/NavBar/PoolSelect/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/NavBar/PoolSelect/index.tsx b/apps/web/src/components/NavBar/PoolSelect/index.tsx index 1538c57d804..4ea7b825e6f 100644 --- a/apps/web/src/components/NavBar/PoolSelect/index.tsx +++ b/apps/web/src/components/NavBar/PoolSelect/index.tsx @@ -95,8 +95,8 @@ const PoolSelect: React.FC = ({ operatedPools }) => { } }, [activePoolExistsOnChain, activeSmartPool?.name, onPoolSelect, operatedPools, currentChainId]) - // Memoize poolsAsCurrrencies to prevent recreation on every render - const poolsAsCurrrencies = React.useMemo(() => + // Memoize poolsAsCurrencies to prevent recreation on every render + const poolsAsCurrencies = React.useMemo(() => operatedPools.map((pool: Token) => ({ currency: pool, currencyId: pool.address, @@ -134,7 +134,7 @@ const PoolSelect: React.FC = ({ operatedPools }) => { isOpen={showModal} onDismiss={() => setShowModal(false)} onCurrencySelect={handleSelectPool} - operatedPools={poolsAsCurrrencies} + operatedPools={poolsAsCurrencies} shouldDisplayPoolsOnly={true} /> From 0aad061482b929dfc9c300c2441079572f0b501a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 09:04:01 +0000 Subject: [PATCH 04/15] Improve caching to prevent vault disappearance during chain switch When switching to a new chain without cached pools, keep showing the last valid chain's pools instead of showing nothing. This prevents the PoolSelect and Pool tab from disappearing. - Track last chain with valid pools - Fall back to last valid chain's pools when current chain has no data yet - Prevents UI elements from disappearing during chain switch Co-authored-by: gabririgo <12066256+gabririgo@users.noreply.github.com> --- apps/web/src/components/NavBar/index.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/web/src/components/NavBar/index.tsx b/apps/web/src/components/NavBar/index.tsx index 659ec6cf11a..609b59ea778 100644 --- a/apps/web/src/components/NavBar/index.tsx +++ b/apps/web/src/components/NavBar/index.tsx @@ -144,17 +144,32 @@ export default function Navbar() { // Cache pools per chain to maintain display across chain switches const cachedPoolsByChainRef = useRef>(new Map()) + const lastValidChainIdRef = useRef(undefined) useEffect(() => { if (rawOperatedPools && rawOperatedPools.length > 0 && account.chainId) { cachedPoolsByChainRef.current.set(account.chainId, rawOperatedPools) + lastValidChainIdRef.current = account.chainId } }, [rawOperatedPools, account.chainId]) const cachedOperatedPools = useMemo(() => { + // Try to get pools for current chain if (account.chainId && cachedPoolsByChainRef.current.has(account.chainId)) { return cachedPoolsByChainRef.current.get(account.chainId) } + + // If we have fresh data for current chain, use it + if (rawOperatedPools && rawOperatedPools.length > 0) { + return rawOperatedPools + } + + // Otherwise, show the last chain's pools to avoid disappearing UI + // This handles the case when switching to a chain we haven't seen before + if (lastValidChainIdRef.current && cachedPoolsByChainRef.current.has(lastValidChainIdRef.current)) { + return cachedPoolsByChainRef.current.get(lastValidChainIdRef.current) + } + return rawOperatedPools }, [rawOperatedPools, account.chainId]) From 24cfb85a04b34eae214f01db21c14dfffbaea863 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Oct 2025 09:05:59 +0000 Subject: [PATCH 05/15] Fix: Keep Pool tab visible but only show current chain's pools Previous approach showed pools from wrong chain during switch, causing incorrect pool selection. New approach: - Track if user has ever had pools on any chain (hasEverHadPoolsRef) - Keep Pool tab visible based on this flag - But only show PoolSelect when pools exist for CURRENT chain - Prevents selecting pools from wrong chain Co-authored-by: gabririgo <12066256+gabririgo@users.noreply.github.com> --- apps/web/src/components/NavBar/index.tsx | 30 +++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/apps/web/src/components/NavBar/index.tsx b/apps/web/src/components/NavBar/index.tsx index 609b59ea778..e76abfda429 100644 --- a/apps/web/src/components/NavBar/index.tsx +++ b/apps/web/src/components/NavBar/index.tsx @@ -144,17 +144,18 @@ export default function Navbar() { // Cache pools per chain to maintain display across chain switches const cachedPoolsByChainRef = useRef>(new Map()) - const lastValidChainIdRef = useRef(undefined) + const hasEverHadPoolsRef = useRef(false) useEffect(() => { if (rawOperatedPools && rawOperatedPools.length > 0 && account.chainId) { cachedPoolsByChainRef.current.set(account.chainId, rawOperatedPools) - lastValidChainIdRef.current = account.chainId + hasEverHadPoolsRef.current = true } }, [rawOperatedPools, account.chainId]) + // Get pools for current chain only const cachedOperatedPools = useMemo(() => { - // Try to get pools for current chain + // Try to get cached pools for current chain if (account.chainId && cachedPoolsByChainRef.current.has(account.chainId)) { return cachedPoolsByChainRef.current.get(account.chainId) } @@ -164,19 +165,20 @@ export default function Navbar() { return rawOperatedPools } - // Otherwise, show the last chain's pools to avoid disappearing UI - // This handles the case when switching to a chain we haven't seen before - if (lastValidChainIdRef.current && cachedPoolsByChainRef.current.has(lastValidChainIdRef.current)) { - return cachedPoolsByChainRef.current.get(lastValidChainIdRef.current) - } - - return rawOperatedPools + // If no pools for current chain, return undefined (don't show wrong chain's pools) + return undefined }, [rawOperatedPools, account.chainId]) - const cachedUserIsOperator = useMemo(() => - Boolean(cachedOperatedPools && cachedOperatedPools.length > 0), - [cachedOperatedPools] - ) + // Keep userIsOperator true if user has ever had pools on any chain + // This prevents the Pool tab from disappearing during chain switches + const cachedUserIsOperator = useMemo(() => { + // If we have pools for current chain, use that + if (cachedOperatedPools && cachedOperatedPools.length > 0) { + return true + } + // Otherwise, keep showing operator UI if they've ever had pools + return hasEverHadPoolsRef.current + }, [cachedOperatedPools]) return (