Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughReplaces multiple context/provider-based data sources with React Query hooks: adds a DataPrefetcher mounted in the app layout and introduces query hooks (useTokensQuery, useMerklCampaignsQuery, useOracleDataQuery) while removing TokenProvider, MerklCampaignsContext, and OracleDataContext; updates consumers to use the new hooks. Changes
Sequence DiagramsequenceDiagram
participant App as App Layout
participant Prefetch as DataPrefetcher
participant RQ as React Query layer
participant Consumers as Components / Hooks
App->>Prefetch: render (on mount)
activate Prefetch
Prefetch->>RQ: call useTokensQuery()
Prefetch->>RQ: call useMarketsQuery()
Prefetch->>RQ: call useMerklCampaignsQuery()
Prefetch->>RQ: call useOracleDataQuery()
note right of Prefetch: hooks trigger fetches and cache results
deactivate Prefetch
Consumers->>RQ: later calls use*Query()
RQ-->>Consumers: cached data (allTokens, campaigns, oracle data, etc.)
alt cache stale or refetch
RQ-->RQ: refetch per policy
RQ-->>Consumers: updated data
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/hooks/useVaultV2Data.ts (1)
39-54: Potential stale closure forfindTokenin queryFn.
findTokenis captured in the queryFn closure but isn't part of queryKey. If the tokens query resolves after the vault query, the vault data may display "--" for token symbol until the next refetch (30s staleTime).Options:
- Add a dependency that invalidates when tokens load (e.g., include
allTokens.lengthorisLoadingin queryKey).- Accept this as minor UX quirk since it self-corrects.
🧹 Nitpick comments (1)
src/hooks/queries/useTokensQuery.ts (1)
109-117: Optional: Inconsistent optional chaining.Line 103 uses
network.address?.toLowerCase()but line 114 doesn't. Both should probably match for consistency, though in practice tokenList items should always have addresses.Suggested fix
const getUniqueTokens = useCallback( (tokenList: { address: string; chainId: number }[]) => { return allTokens.filter((token) => { return tokenList.find((item) => token.networks.find( - (network) => network.address.toLowerCase() === item.address.toLowerCase() && network.chain.id === item.chainId, + (network) => network.address?.toLowerCase() === item.address.toLowerCase() && network.chain.id === item.chainId, ), ); }); }, [allTokens], );
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (15)
app/layout.tsxsrc/components/DataPrefetcher.tsxsrc/components/providers/ClientProviders.tsxsrc/components/shared/token-icon.tsxsrc/features/autovault/components/deployment/token-selection.tsxsrc/features/autovault/components/vault-detail/settings/EditCaps.tsxsrc/features/markets/components/markets-table-same-loan.tsxsrc/features/markets/markets-view.tsxsrc/features/positions/components/onboarding/market-selection-onboarding.tsxsrc/features/positions/components/user-vaults-table.tsxsrc/hooks/queries/useTokensQuery.tssrc/hooks/useFilteredMarkets.tssrc/hooks/usePortfolioValue.tssrc/hooks/useUserBalances.tssrc/hooks/useVaultV2Data.ts
🧰 Additional context used
🧠 Learnings (8)
📚 Learning: 2024-11-25T09:39:42.148Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 87
File: app/home/HomePage.tsx:17-39
Timestamp: 2024-11-25T09:39:42.148Z
Learning: In `app/home/HomePage.tsx`, the `useEffect` hook depends on `[showCustomized]` because changing `showCustomized` triggers updates to the yield and risk terms.
Applied to files:
src/hooks/usePortfolioValue.tssrc/features/positions/components/onboarding/market-selection-onboarding.tsxsrc/features/markets/components/markets-table-same-loan.tsxsrc/hooks/useFilteredMarkets.tssrc/features/markets/markets-view.tsx
📚 Learning: 2025-12-09T10:06:39.848Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 231
File: src/hooks/useDeployMorphoMarketV1Adapter.ts:3-3
Timestamp: 2025-12-09T10:06:39.848Z
Learning: In Wagmi v3, useConnection is the correct hook to obtain the connected wallet address, chainId, and connection status (isConnected). This replaces the useAccount hook from Wagmi v2. In your code under src/hooks, use: const { address, chainId, isConnected } = useConnection() from 'wagmi' to access the connected wallet information.
Applied to files:
src/hooks/usePortfolioValue.tssrc/hooks/useVaultV2Data.tssrc/hooks/useUserBalances.tssrc/hooks/useFilteredMarkets.tssrc/hooks/queries/useTokensQuery.ts
📚 Learning: 2025-11-13T20:32:48.908Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 183
File: app/positions/components/RebalanceModal.tsx:301-308
Timestamp: 2025-11-13T20:32:48.908Z
Learning: The TokenIcon component in the codebase accepts a `symbol` prop as part of its valid interface, in addition to `address`, `chainId`, `width`, `height`, and other props.
Applied to files:
src/components/shared/token-icon.tsx
📚 Learning: 2024-12-17T12:39:21.949Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 99
File: app/positions/components/onboarding/SuccessPage.tsx:17-17
Timestamp: 2024-12-17T12:39:21.949Z
Learning: Prefer using explicit network checks like `selectedToken?.network === SupportedNetworks.Base` over using array indexing like `config.agentSupportedNetworks[0]` for better maintainability.
Applied to files:
src/features/autovault/components/deployment/token-selection.tsxsrc/hooks/useUserBalances.tssrc/features/autovault/components/vault-detail/settings/EditCaps.tsx
📚 Learning: 2024-10-07T14:38:04.384Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 57
File: src/hooks/useRebalance.ts:112-114
Timestamp: 2024-10-07T14:38:04.384Z
Learning: In `src/hooks/useRebalance.ts`, adding a delay is necessary because Rabby wallet cannot handle sequential requests.
Applied to files:
src/hooks/useUserBalances.ts
📚 Learning: 2024-10-23T16:17:02.841Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 77
File: src/graphql/queries.ts:168-193
Timestamp: 2024-10-23T16:17:02.841Z
Learning: In `src/graphql/queries.ts`, handling only `MarketTransferTransactionData` is intentional at this time.
Applied to files:
src/features/positions/components/onboarding/market-selection-onboarding.tsxsrc/hooks/useFilteredMarkets.tssrc/features/markets/markets-view.tsx
📚 Learning: 2024-12-16T02:01:51.219Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 97
File: app/positions/components/onboarding/OnboardingContext.tsx:36-43
Timestamp: 2024-12-16T02:01:51.219Z
Learning: In `app/positions/components/onboarding/OnboardingContext.tsx`, the `defaultStep` variable is no longer needed and can be removed.
Applied to files:
src/features/positions/components/onboarding/market-selection-onboarding.tsx
📚 Learning: 2025-12-09T10:06:43.810Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 231
File: src/hooks/useDeployMorphoMarketV1Adapter.ts:3-3
Timestamp: 2025-12-09T10:06:43.810Z
Learning: In Wagmi v3, useConnection is the correct hook to obtain the connected wallet address, chainId, and connection status (isConnected). This replaces the useAccount hook from Wagmi v2. Usage: const { address, chainId, isConnected } = useConnection() from 'wagmi'.
Applied to files:
src/features/autovault/components/vault-detail/settings/EditCaps.tsx
🧬 Code graph analysis (14)
src/components/DataPrefetcher.tsx (2)
src/hooks/queries/useMarketsQuery.ts (1)
useMarketsQuery(27-96)src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/hooks/usePortfolioValue.ts (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/components/shared/token-icon.tsx (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/hooks/useVaultV2Data.ts (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/features/autovault/components/deployment/token-selection.tsx (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/hooks/useUserBalances.ts (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/features/positions/components/onboarding/market-selection-onboarding.tsx (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/features/positions/components/user-vaults-table.tsx (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/features/markets/components/markets-table-same-loan.tsx (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/hooks/useFilteredMarkets.ts (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/components/providers/ClientProviders.tsx (3)
src/contexts/OracleDataContext.tsx (1)
OracleDataProvider(33-180)src/contexts/MerklCampaignsContext.tsx (1)
MerklCampaignsProvider(20-75)src/features/positions/components/onboarding/onboarding-context.tsx (1)
OnboardingProvider(42-107)
app/layout.tsx (1)
src/components/DataPrefetcher.tsx (1)
DataPrefetcher(6-10)
src/features/autovault/components/vault-detail/settings/EditCaps.tsx (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
src/features/markets/markets-view.tsx (1)
src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)
🔇 Additional comments (14)
src/components/providers/ClientProviders.tsx (1)
16-20: Clean removal of TokenProvider.The migration to useTokensQuery is handled consistently across consuming components. No issues detected.
src/features/autovault/components/deployment/token-selection.tsx (1)
5-5: Straightforward migration to useTokensQuery.The hook provides the same API, and findToken is stable (wrapped in useCallback). No issues.
Also applies to: 51-51
app/layout.tsx (1)
11-11: DataPrefetcher placement is optimal.Mounting early in the layout triggers data fetching before components need it. React Query handles caching and deduping across the app.
Also applies to: 43-43
src/hooks/useFilteredMarkets.ts (1)
7-7: Migration looks good.Consistent with the pattern across other files. findToken is stable and correctly included in dependencies.
Also applies to: 42-42
src/features/positions/components/onboarding/market-selection-onboarding.tsx (1)
5-5: Clean migration to useTokensQuery.Uses getUniqueTokens for collateral token filtering. The function is stable and correctly included in dependencies.
Also applies to: 11-11
src/hooks/useUserBalances.ts (1)
3-3: Migration is correct.findToken usage remains the same, just sourced from useTokensQuery instead of TokenProvider.
Also applies to: 32-32
src/components/shared/token-icon.tsx (1)
5-5: Migration is correct.Token resolution logic unchanged, just using the new hook source.
Also applies to: 35-35
src/components/DataPrefetcher.tsx (1)
6-10: Standard prefetch pattern.Triggers queries early so data is cached before components need it. React Query dedupes requests and handles caching automatically.
src/features/autovault/components/vault-detail/settings/EditCaps.tsx (1)
7-7: LGTM!Clean migration to useTokensQuery. The findToken API is unchanged, and its memoization via useCallback in the hook ensures stable references for the dependency arrays in useMemo/useEffect.
Also applies to: 55-55
src/features/positions/components/user-vaults-table.tsx (1)
13-13: LGTM!Direct swap to useTokensQuery with no behavioral changes.
Also applies to: 34-34
src/features/markets/markets-view.tsx (1)
6-6: LGTM!Migration to useTokensQuery for allTokens access. The fallback to localTokensWithSource ensures tokens are available before the query resolves.
Also applies to: 42-42
src/hooks/usePortfolioValue.ts (1)
2-2: LGTM!Standard migration to useTokensQuery.
Also applies to: 23-23
src/features/markets/components/markets-table-same-loan.tsx (1)
12-12: LGTM!Migration to useTokensQuery with findToken used consistently in memoization dependencies.
Also applies to: 629-629
src/hooks/queries/useTokensQuery.ts (1)
54-131: LGTM!Solid React Query implementation:
- Fallback to localTokensWithSource ensures tokens are available before fetch completes
- Proper error re-throw for React Query error state
- Memoized utility functions
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/hooks/queries/useOracleDataQuery.ts (1)
28-75: Pagination and error handling work correctly.The pagination logic correctly fetches all oracle data across networks. Error handling allows partial success by continuing with other networks when one fails.
Consider adding logging for the silent breaks at lines 50 and 53 to aid debugging:
🔎 Optional improvement
if (!response.ok) { + console.warn(`HTTP ${response.status} fetching oracles for network ${network}, skip ${skip}`); break; } const result = (await response.json()) as OraclesQueryResponse; if (result.errors) { + console.warn(`GraphQL errors fetching oracles for network ${network}:`, result.errors); break; }src/hooks/queries/useMerklCampaignsQuery.ts (2)
5-28: Well-structured React Query implementation.The parallel fetching, caching strategy, and error handling are appropriate. The queryKey is correctly static since the hook has no parameters, allowing all consumers to share the cached data.
Optional: Consider handling partial data if one campaign type fails
Currently, if either campaign type fetch fails, the entire query fails and returns no campaigns. If the two campaign types are independent, you might want to return partial data:
queryFn: async () => { - const [supplyCampaigns, singleTokenCampaigns] = await Promise.all([ - fetchActiveCampaigns({ type: 'MORPHOSUPPLY' }), - fetchActiveCampaigns({ type: 'MORPHOSUPPLY_SINGLETOKEN' }), - ]); + const results = await Promise.allSettled([ + fetchActiveCampaigns({ type: 'MORPHOSUPPLY' }), + fetchActiveCampaigns({ type: 'MORPHOSUPPLY_SINGLETOKEN' }), + ]); + + const supplyCampaigns = results[0].status === 'fulfilled' ? results[0].value : []; + const singleTokenCampaigns = results[1].status === 'fulfilled' ? results[1].value : []; const allRawCampaigns = [...supplyCampaigns, ...singleTokenCampaigns]; return allRawCampaigns.map((campaign) => simplifyMerklCampaign(campaign)); },This is purely optional—the current all-or-nothing approach may be the correct business logic.
30-35: Good type definition.Exporting the return type is helpful for consumers. The type structure matches the implementation.
Minor nitpick:
refetchactually returns a Promise, so the type could be more precise:export type MerklCampaignsQueryReturn = { campaigns: SimplifiedCampaign[]; loading: boolean; error: string | null; - refetch: () => void; + refetch: () => Promise<unknown>; };This only matters if consumers need to await the refetch operation.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
docs/ARCHITECTURE.mdsrc/components/DataPrefetcher.tsxsrc/components/providers/ClientProviders.tsxsrc/contexts/MerklCampaignsContext.tsxsrc/contexts/OracleDataContext.tsxsrc/features/rewards/components/reward-table.tsxsrc/hooks/queries/useMerklCampaignsQuery.tssrc/hooks/queries/useOracleDataQuery.tssrc/hooks/useMarketCampaigns.tssrc/hooks/useMarketData.tssrc/hooks/useMerklCampaigns.tssrc/hooks/useProcessedMarkets.ts
💤 Files with no reviewable changes (3)
- src/contexts/MerklCampaignsContext.tsx
- src/contexts/OracleDataContext.tsx
- src/hooks/useMerklCampaigns.ts
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-12-09T10:06:39.848Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 231
File: src/hooks/useDeployMorphoMarketV1Adapter.ts:3-3
Timestamp: 2025-12-09T10:06:39.848Z
Learning: In Wagmi v3, useConnection is the correct hook to obtain the connected wallet address, chainId, and connection status (isConnected). This replaces the useAccount hook from Wagmi v2. In your code under src/hooks, use: const { address, chainId, isConnected } = useConnection() from 'wagmi' to access the connected wallet information.
Applied to files:
src/hooks/useMarketCampaigns.tssrc/hooks/queries/useMerklCampaignsQuery.tssrc/hooks/queries/useOracleDataQuery.tssrc/hooks/useProcessedMarkets.tssrc/hooks/useMarketData.ts
📚 Learning: 2024-10-12T09:23:16.495Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 63
File: app/markets/components/MarketRowDetail.tsx:49-52
Timestamp: 2024-10-12T09:23:16.495Z
Learning: When rendering oracle feeds in `ExpandedMarketDetail` (`app/markets/components/MarketRowDetail.tsx`), prefer explicit rendering over iterating keys when dealing with a small number of feeds.
Applied to files:
src/hooks/useProcessedMarkets.tssrc/hooks/useMarketData.ts
📚 Learning: 2024-10-23T16:17:02.841Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 77
File: src/graphql/queries.ts:168-193
Timestamp: 2024-10-23T16:17:02.841Z
Learning: In `src/graphql/queries.ts`, handling only `MarketTransferTransactionData` is intentional at this time.
Applied to files:
src/hooks/useProcessedMarkets.tssrc/hooks/useMarketData.ts
📚 Learning: 2025-12-09T10:06:43.810Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 231
File: src/hooks/useDeployMorphoMarketV1Adapter.ts:3-3
Timestamp: 2025-12-09T10:06:43.810Z
Learning: In Wagmi v3, useConnection is the correct hook to obtain the connected wallet address, chainId, and connection status (isConnected). This replaces the useAccount hook from Wagmi v2. Usage: const { address, chainId, isConnected } = useConnection() from 'wagmi'.
Applied to files:
src/features/rewards/components/reward-table.tsx
📚 Learning: 2024-12-16T02:01:51.219Z
Learnt from: antoncoding
Repo: antoncoding/monarch PR: 97
File: app/positions/components/onboarding/OnboardingContext.tsx:36-43
Timestamp: 2024-12-16T02:01:51.219Z
Learning: In `app/positions/components/onboarding/OnboardingContext.tsx`, the `defaultStep` variable is no longer needed and can be removed.
Applied to files:
src/components/providers/ClientProviders.tsx
🧬 Code graph analysis (8)
src/hooks/useMarketCampaigns.ts (1)
src/hooks/queries/useMerklCampaignsQuery.ts (1)
useMerklCampaignsQuery(5-28)
src/hooks/queries/useMerklCampaignsQuery.ts (2)
src/utils/merklApi.ts (2)
fetchActiveCampaigns(41-68)simplifyMerklCampaign(71-113)src/utils/merklTypes.ts (1)
SimplifiedCampaign(115-139)
src/components/DataPrefetcher.tsx (4)
src/hooks/queries/useMarketsQuery.ts (1)
useMarketsQuery(27-96)src/hooks/queries/useTokensQuery.ts (1)
useTokensQuery(55-131)src/hooks/queries/useMerklCampaignsQuery.ts (1)
useMerklCampaignsQuery(5-28)src/hooks/queries/useOracleDataQuery.ts (1)
useOracleDataQuery(77-110)
src/hooks/queries/useOracleDataQuery.ts (4)
src/utils/types.ts (2)
MorphoChainlinkOracleData(260-265)OraclesQueryResponse(277-290)src/utils/networks.ts (1)
ALL_SUPPORTED_NETWORKS(38-46)src/utils/urls.ts (1)
URLS(3-8)src/graphql/morpho-api-queries.ts (1)
oraclesQuery(18-66)
src/hooks/useProcessedMarkets.ts (1)
src/hooks/queries/useOracleDataQuery.ts (1)
useOracleDataQuery(77-110)
src/features/rewards/components/reward-table.tsx (1)
src/hooks/queries/useMerklCampaignsQuery.ts (1)
useMerklCampaignsQuery(5-28)
src/hooks/useMarketData.ts (1)
src/hooks/queries/useOracleDataQuery.ts (1)
useOracleDataQuery(77-110)
src/components/providers/ClientProviders.tsx (1)
src/features/positions/components/onboarding/onboarding-context.tsx (1)
OnboardingProvider(42-107)
🪛 LanguageTool
docs/ARCHITECTURE.md
[grammar] ~176-~176: Ensure spelling is correct
Context: ...ess) 3. Cache results with React Query (5min stale time) Display: Reward APRs s...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (9)
src/components/providers/ClientProviders.tsx (1)
11-16: LGTM!Clean removal of context providers as part of the migration to React Query hooks. The simplified provider tree with just OnboardingProvider is easier to maintain.
src/hooks/useMarketCampaigns.ts (1)
3-3: LGTM!Straightforward migration from context-based data access to the new React Query hook. The logic remains unchanged.
Also applies to: 22-22
src/hooks/useMarketData.ts (1)
5-5: LGTM!Clean migration to the new oracle data query hook. The enrichment logic at lines 102-117 remains intact.
Also applies to: 15-15
src/features/rewards/components/reward-table.tsx (1)
15-15: LGTM!Clean migration to the new campaigns query hook. The reward table logic and campaign matching remain unchanged.
Also applies to: 46-46
src/components/DataPrefetcher.tsx (1)
13-19: LGTM!Simple and effective prefetching pattern. Calling these hooks on mount ensures data is cached before users navigate to different pages.
docs/ARCHITECTURE.md (1)
22-23: LGTM!Documentation accurately reflects the migration from context providers to React Query hooks. The prefetching note and updated hook references are clear.
Also applies to: 152-157, 169-177
src/hooks/useProcessedMarkets.ts (1)
3-3: LGTM!Clean migration to the oracle data query hook. The blacklist filtering and enrichment logic remains intact.
Also applies to: 30-30
src/hooks/queries/useOracleDataQuery.ts (1)
77-110: LGTM!The hook correctly merges static cache with live data, giving precedence to API results. The memoized merged map and getOracleData callback ensure efficient lookups.
src/hooks/queries/useMerklCampaignsQuery.ts (1)
1-3: LGTM!Clean imports with everything properly typed.
Summary by CodeRabbit
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.