Skip to content

refactor: add backup data source #140

Merged
antoncoding merged 11 commits intomasterfrom
refactor/change-subgraph
Apr 20, 2025
Merged

refactor: add backup data source #140
antoncoding merged 11 commits intomasterfrom
refactor/change-subgraph

Conversation

@antoncoding
Copy link
Copy Markdown
Owner

@antoncoding antoncoding commented Apr 20, 2025

Summary by CodeRabbit

  • New Features

    • Added dynamic support for fetching market and historical data from Morpho API or subgraph sources based on network.
    • Introduced new hooks to retrieve market and historical data with flexible data source selection.
    • Added configuration for subgraph URLs and data source determination functions.
  • Improvements

    • Unified timeframe handling across charts and market content to use '1d', '7d', and '30d' options.
    • Enhanced chart components with improved empty data handling and consistent timeframe UI.
    • Improved loading states with spinner and styled feedback in market views.
  • Bug Fixes

    • Prevented errors in average calculations by handling empty data arrays explicitly.
  • Refactor

    • Simplified and consolidated state and prop management in chart components.
    • Removed unused reward and APY fields from types and GraphQL queries.
    • Reorganized data fetching logic, removing deprecated hooks and updating imports.
  • Chores

    • Added new GraphQL queries and fragments for Morpho subgraph integration.
    • Added detailed TypeScript types for subgraph data structures.
    • Cleaned up imports and removed deprecated utility functions.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 20, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
monarch ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 20, 2025 3:53pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 20, 2025

📝 Walkthrough

Walkthrough

This update introduces a new data sourcing system for market and historical data, supporting both Morpho API and subgraph endpoints. Several new modules fetch and transform data from these sources, with types and utilities for subgraph integration. The market and volume chart components are refactored to use unified timeframe handling and improved type safety. The main market content component is updated to use consolidated state and hooks for fetching data. Numerous imports are redirected to new query files, and some obsolete utility and hook files are removed. Types are updated to match the new data structure.

Changes

Files/Paths Change Summary
app/market/[chainId]/[marketid]/RateChart.tsx, VolumeChart.tsx Refactored props and logic for unified timeframe handling (`'1d'
app/market/[chainId]/[marketid]/content.tsx Unified timeframe state and data fetching for rates and volumes, improved loading UI, switched to new hooks for market data.
src/config/dataSources.ts New module to select data source (Morpho or subgraph) based on network.
src/contexts/MarketsContext.tsx, src/hooks/useLiquidations.ts Switched from using market IDs to unique keys for liquidation tracking; updated GraphQL query imports.
src/data-sources/morpho-api/fetchers.ts, historical.ts, market.ts New modules for fetching and processing market and historical data from Morpho API using GraphQL.
src/data-sources/subgraph/fetchers.ts, historical.ts, market.ts New modules for fetching and transforming market and historical data from subgraph endpoints; includes type-safe parsing and error handling.
src/graphql/morpho-api-queries.ts Updated GraphQL fragments: removed unused fields (oracle info, priceUsd, rewards, APY fields) for Morpho API queries.
src/graphql/morpho-subgraph-queries.ts New module defining GraphQL fragments and queries for subgraph data, including market and historical snapshot queries.
src/hooks/useMarketData.ts, useMarketHistoricalData.ts New hooks to fetch market and historical data from the appropriate source (Morpho or subgraph) based on network and parameters.
src/hooks/useMarket.ts Deleted old hook for fetching market and historical data, replaced by new data source–aware hooks.
src/hooks/useMarketBorrows.ts, useMarketLiquidations.ts, useMarketSupplies.ts Updated GraphQL query imports to new Morpho API queries.
src/hooks/useUserPosition.ts, useUserPositions.ts, useUserRebalancerInfo.ts, useUserTransactions.ts Updated GraphQL query imports to new Morpho API queries; minor logic tweak in user position state assignment.
src/services/statsService.ts Updated stats queries import path.
src/utils/morpho.ts Removed reward calculation utilities and their dependencies.
src/utils/subgraph-types.ts New types for subgraph data structures: tokens, oracles, interest rates, protocol info, markets, and responses.
src/utils/subgraph-urls.ts New module for managing subgraph URLs per network, using environment variable for API key.
src/utils/types.ts Updated types: removed unused fields (oracle info, priceUsd, rewards, APY fields), simplified intervals, renamed and simplified historical data types.

Sequence Diagram(s)

sequenceDiagram
    participant UI
    participant MarketContent
    participant useMarketData
    participant useMarketHistoricalData
    participant MorphoAPI
    participant Subgraph

    UI->>MarketContent: Render with selectedTimeframe
    MarketContent->>useMarketData: Fetch market (uniqueKey, network)
    useMarketData->>MorphoAPI: If source is Morpho, fetch market
    useMarketData->>Subgraph: If source is Subgraph, fetch market
    MarketContent->>useMarketHistoricalData: Fetch historical data (uniqueKey, network, options)
    useMarketHistoricalData->>MorphoAPI: If source is Morpho, fetch historical data
    useMarketHistoricalData->>Subgraph: If source is Subgraph, fetch historical data
    MarketContent->>UI: Render charts with fetched data
Loading

Possibly related PRs

Poem

Charts and hooks now work as one,
Data flows where it needs to run.
Morpho or Subgraph, pick your stream—
Unified types, a cleaner scheme.
Timeframes short and long align,
Loading spinners now look fine.
Code refactored, neat and tight—
Market data, day or night!

⏳📈

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
✨ Finishing Touches
  • 📝 Generate Docstrings

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🔭 Outside diff range comments (4)
src/hooks/useMarketBorrows.ts (1)

40-42: ⚠️ Potential issue

Fix comment vs. pagination limit
The comment says “Limit to 100” but first is set to 1000. Update the comment or the value to match the intended limit.

src/hooks/useMarketLiquidations.ts (1)

37-40: ⚠️ Potential issue

Add pagination to liquidations
Unlike borrows and supplies, this query lacks first/skip variables—consider adding them or confirming the default server behavior to avoid unbounded results.

src/hooks/useMarketSupplies.ts (1)

40-42: ⚠️ Potential issue

Fix comment vs. pagination limit
The inline note says “Limit to 100” but the code uses first: 1000. Align the comment or adjust the limit.

src/hooks/useUserRebalancerInfo.ts (1)

19-27: 🛠️ Refactor suggestion

Add response.ok check and error throw
You parse response.json() without verifying response.ok. Wrap the fetch in an if (!response.ok) throw new Error(...) to catch HTTP errors early.

🧹 Nitpick comments (26)
src/utils/subgraph-types.ts (4)

4-10: Check SubgraphToken types
The decimals field is typed as number, but subgraph decimals are often strings to preserve precision. Consider using a string alias for all numeric fields.


13-19: Validate SubgraphOracle.id type
You’ve typed the id as string, but if it’s always an on‑chain address you might use the same Address type for consistency.


30-34: Improve protocol network typing
network and protocol are raw strings—consider defining a literal union of known networks ('MAINNET'|'BASE'|…) and protocols for stronger type safety.


37-69: Extract numeric string aliases
You have many fields typed as string representing bigints or decimals. Introducing type aliases like type BigDecimal = string and type BigIntString = string can improve readability and catch copy‑paste errors.

src/hooks/useMarketBorrows.ts (1)

23-28: Consider consolidating fetch logic
This hook’s pattern repeats across borrows, supplies, and liquidations. Extract a generic useFetchTransactions hook to reduce duplication.

src/hooks/useMarketLiquidations.ts (1)

22-28: Consider consolidating fetch logic
Repeating fetch pattern across hooks can be abstracted into a reusable fetch hook with generics.

src/hooks/useMarketSupplies.ts (1)

23-28: Consider consolidating fetch logic
This hook shares structure with borrows and liquidations. A generic data‑fetch hook could DRY up the code.

src/data-sources/morpho-api/fetchers.ts (1)

20-29: Consider improving error handling with more details.

The error message "Unknown GraphQL error" is generic. Including specific error details in the message would help debugging.

-    throw new Error('Unknown GraphQL error from Morpho API');
+    throw new Error(`GraphQL error from Morpho API: ${(result as any).errors[0]?.message || 'Unknown error'}`);
src/hooks/useLiquidations.ts (2)

4-36: Move query to dedicated file.

The GraphQL query is defined directly in this file, while other queries are imported from central files.

Consider moving this query to the centralized query file:

+// In @/graphql/morpho-api-queries.ts
+export const liquidationsQuery = `
+  query getLiquidations($first: Int, $skip: Int) {
+    transactions(
+      where: { type_in: [MarketLiquidation] }
+      first: $first
+      skip: $skip
+    ) {
+      items {
+        id
+        type
+        data {
+          ... on MarketLiquidationTransactionData {
+            market {
+              id
+              uniqueKey
+            }
+            repaidAssets
+          }
+        }
+        hash
+        chain {
+          id
+        }
+      }
+      pageInfo {
+        countTotal
+        count
+        limit
+        skip
+      }
+    }
+  }
+`;

+// In this file
+import { liquidationsQuery } from '@/graphql/morpho-api-queries';
-const liquidationsQuery = `
-  query getLiquidations($first: Int, $skip: Int) {
-    transactions(
-      where: { type_in: [MarketLiquidation] }
-      first: $first
-      skip: $skip
-    ) {
-      items {
-        id
-        type
-        data {
-          ... on MarketLiquidationTransactionData {
-            market {
-              id
-              uniqueKey
-            }
-            repaidAssets
-          }
-        }
-        hash
-        chain {
-          id
-        }
-      }
-      pageInfo {
-        countTotal
-        count
-        limit
-        skip
-      }
-    }
-  }
-`;

88-109: Consider using morphoGraphqlFetcher.

This hook has direct fetch logic that duplicates the new morphoGraphqlFetcher functionality.

Replace this fetch implementation with the new fetcher:

do {
-  const response = await fetch(URLS.MORPHO_BLUE_API, {
-    method: 'POST',
-    headers: { 'Content-Type': 'application/json' },
-    body: JSON.stringify({
-      query: liquidationsQuery,
-      variables: { first: pageSize, skip },
-    }),
-  });
-  const result = (await response.json()) as QueryResult;
+  const result = await morphoGraphqlFetcher<QueryResult>(
+    liquidationsQuery,
+    { first: pageSize, skip }
+  );
  const liquidations = result.data.transactions.items;
  const pageInfo = result.data.transactions.pageInfo;
src/data-sources/subgraph/fetchers.ts (1)

1-5: Type inconsistency with morpho-api fetcher.

The generic type constraint is different from the morphoGraphqlFetcher, which uses Record<string, any>.

-export const subgraphGraphqlFetcher = async <T extends object>(
+export const subgraphGraphqlFetcher = async <T extends Record<string, any>>(
  apiUrl: string, // Subgraph URL can vary
  query: string,
  variables: Record<string, unknown>,
): Promise<T> => {
src/contexts/MarketsContext.tsx (1)

63-70: Direct API URL hardcoding.

The component makes API requests directly using a hardcoded URL instead of using the new fetcher.

-  const marketsResponse = await fetch('https://blue-api.morpho.org/graphql', {
-    method: 'POST',
-    headers: { 'Content-Type': 'application/json' },
-    body: JSON.stringify({
-      query: marketsQuery,
-      variables: { first: 1000, where: { whitelisted: true } },
-    }),
-  });
-
-  const marketsResult = (await marketsResponse.json()) as MarketResponse;
+  const marketsResult = await morphoGraphqlFetcher<MarketResponse>(
+    marketsQuery,
+    { first: 1000, where: { whitelisted: true } }
+  );

Also, import the required function:

+import { morphoGraphqlFetcher } from '@/data-sources/morpho-api/fetchers';
src/config/dataSources.ts (1)

16-25: Historical data source implementation is limited

Unlike getMarketDataSource function, there are no commented-out cases for specific networks. Consider applying the same pattern if subgraph support for historical data is planned.

export const getHistoricalDataSource = (network: SupportedNetworks): 'morpho' | 'subgraph' => {
  switch (network) {
+    // case SupportedNetworks.Mainnet:
+    // case SupportedNetworks.Base:
+    //   return 'subgraph';
    default:
      return 'morpho';
  }
};
src/utils/subgraph-urls.ts (1)

15-18: Remove outdated TODO comment

The TODO comment suggests replacing a placeholder ID, but the code already appears to have a valid subgraph ID.

-// TODO: Replace 'YOUR_MAINNET_SUBGRAPH_ID' with the actual Mainnet Subgraph ID
+// Mainnet subgraph endpoint
const mainnetSubgraphUrl = apiKey
  ? `https://gateway.thegraph.com/api/${apiKey}/subgraphs/id/8Lz789DP5VKLXumTMTgygjU2xtuzx8AhbaacgN5PYCAs`
  : undefined;
src/hooks/useMarketData.ts (2)

26-26: Remove or conditionalize debug log

Production code shouldn't include debug logging statements. Consider removing this or conditionalizing it based on environment.

-      console.log(`Fetching market data for ${uniqueKey} on ${network} via ${dataSource}`);
+      if (process.env.NODE_ENV === 'development') {
+        console.log(`Fetching market data for ${uniqueKey} on ${network} via ${dataSource}`);
+      }

29-35: Handle unknown data source within try block

The code has a fallback for unknown data sources after the try/catch, but it would be more consistent to handle this case within the try block.

      try {
        if (dataSource === 'morpho') {
          return await fetchMorphoMarket(uniqueKey, network);
        } else if (dataSource === 'subgraph') {
          // fetchSubgraphMarket already handles potential null return
          return await fetchSubgraphMarket(uniqueKey, network);
+        } else {
+          console.warn('Unknown market data source determined');
+          return null;
        }
      } catch (fetchError) {
        console.error(`Failed to fetch market data via ${dataSource}:`, fetchError);
        return null; // Return null on fetch error
      }

-      // Fallback if dataSource logic is somehow incorrect
-      console.warn('Unknown market data source determined');
-      return null;
src/data-sources/morpho-api/market.ts (2)

7-8: Remove implementation comments

These comments about removed or moved code should be removed before the final PR merge.

-// Removed historical types (MarketRates, MarketVolumes, etc.)
-// Moved HistoricalDataResult to historical.ts

27-39: Improve error message specificity

Add the unique key to the error message when market data is not found to make debugging easier.

  if (!response.data || !response.data.marketByUniqueKey) {
-    throw new Error('Market data not found in Morpho API response');
+    throw new Error(`Market data not found in Morpho API response for key: ${uniqueKey}`);
  }
src/hooks/useMarketHistoricalData.ts (2)

27-59: Remove console logs before production

The implementation logic looks solid, but there are several console.log statements that should be removed before deploying to production.

-        console.log('Historical data prerequisites not met or source unavailable.', {
-          uniqueKey,
-          network,
-          options,
-          dataSource,
-        });
+        // Prerequisites not met
-      console.log(`Fetching historical data for ${uniqueKey} on ${network} via ${dataSource}`);
+        // Fetching data
-        console.log('res morpho', res);
+        // Data fetched from Morpho
-        console.log('res', res);
+        // Data fetched from subgraph

61-68: Return object uses shorthand notation

Consider using object shorthand notation for cleaner code since property names match variable names.

-  return {
-    data: data,
-    isLoading: isLoading,
-    error: error,
-    refetch: refetch,
-    dataSource: dataSource,
-  };
+  return { data, isLoading, error, refetch, dataSource };
src/data-sources/subgraph/market.ts (1)

139-156: Consider retrying failed requests

The function doesn't include retry logic for failed network requests, which could be useful for intermittent failures.

Consider adding retry logic for transient network issues by wrapping the fetch call in a retry mechanism.

src/data-sources/morpho-api/historical.ts (1)

64-73: Too‑verbose console logs – gate behind DEBUG flag

Dumping the full GraphQL response on every request will flood the console and, in production builds, bloat bundle size.
Wrap these console.log calls in an env / debug guard or remove them.

-console.log('[fetchMorphoMarketHistoricalData] Raw API Response:', …)
-
+if (process.env.NEXT_PUBLIC_DEBUG === 'true') {
+  // eslint-disable-next-line no-console
+  console.debug('[Morpho‑historical] resp', response);
+}
app/market/[chainId]/[marketid]/content.tsx (1)

44-56: Redundant default clause

case '7d' falls straight through to the same block as default, making the latter useless (Biome warning).
Either remove the explicit '7d' case or drop default:

-    case '7d':
-    default:
+    default: // treat unknown or '7d' as 7‑day
🧰 Tools
🪛 Biome (1.9.4)

[error] 53-53: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

src/graphql/morpho-subgraph-queries.ts (1)

84-84: Remove or expand the TODO comment.

This comment doesn't provide actionable information. Either remove it or expand with specific queries that might be needed.

-// Add other queries as needed, e.g., for user positions based on subgraph schema
+// TODO: Add user position queries once we implement position tracking with the subgraph
app/market/[chainId]/[marketid]/VolumeChart.tsx (1)

92-94: Consider extracting the large number check to a constant.

The 100B threshold is hardcoded without explanation. Extract this to a named constant for better readability.

+const MAX_DISPLAY_USD_VALUE = 100_000_000_000; // 100B USD, filter out likely erroneous data points

 // Check if any timestamps has USD value exceeds 100B
-if (historicalData.supplyAssetsUsd[index].y >= 100_000_000_000) {
+if (historicalData.supplyAssetsUsd[index].y >= MAX_DISPLAY_USD_VALUE) {
   return null;
 }
app/market/[chainId]/[marketid]/RateChart.tsx (1)

176-182: Consider reusing the formatPercentage function in tooltip.

The tooltip formatter duplicates the percentage formatting logic already defined in formatPercentage. You should reuse this function for consistency.

 <Tooltip
   labelFormatter={(unixTime) => new Date(unixTime * 1000).toLocaleString()}
-  formatter={(value: number) => `${(value * 100).toFixed(2)}%`}
+  formatter={(value: number) => formatPercentage(value)}
   contentStyle={{
     backgroundColor: 'var(--color-background)',
   }}
 />
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75186c6 and a4439d1.

📒 Files selected for processing (29)
  • app/market/[chainId]/[marketid]/RateChart.tsx (5 hunks)
  • app/market/[chainId]/[marketid]/VolumeChart.tsx (8 hunks)
  • app/market/[chainId]/[marketid]/content.tsx (6 hunks)
  • src/config/dataSources.ts (1 hunks)
  • src/contexts/MarketsContext.tsx (4 hunks)
  • src/data-sources/morpho-api/fetchers.ts (1 hunks)
  • src/data-sources/morpho-api/historical.ts (1 hunks)
  • src/data-sources/morpho-api/market.ts (1 hunks)
  • src/data-sources/subgraph/fetchers.ts (1 hunks)
  • src/data-sources/subgraph/historical.ts (1 hunks)
  • src/data-sources/subgraph/market.ts (1 hunks)
  • src/graphql/morpho-api-queries.ts (1 hunks)
  • src/graphql/morpho-subgraph-queries.ts (1 hunks)
  • src/hooks/useLiquidations.ts (4 hunks)
  • src/hooks/useMarket.ts (0 hunks)
  • src/hooks/useMarketBorrows.ts (1 hunks)
  • src/hooks/useMarketData.ts (1 hunks)
  • src/hooks/useMarketHistoricalData.ts (1 hunks)
  • src/hooks/useMarketLiquidations.ts (1 hunks)
  • src/hooks/useMarketSupplies.ts (1 hunks)
  • src/hooks/useUserPosition.ts (2 hunks)
  • src/hooks/useUserPositions.ts (1 hunks)
  • src/hooks/useUserRebalancerInfo.ts (1 hunks)
  • src/hooks/useUserTransactions.ts (1 hunks)
  • src/services/statsService.ts (1 hunks)
  • src/utils/morpho.ts (0 hunks)
  • src/utils/subgraph-types.ts (1 hunks)
  • src/utils/subgraph-urls.ts (1 hunks)
  • src/utils/types.ts (3 hunks)
💤 Files with no reviewable changes (2)
  • src/utils/morpho.ts
  • src/hooks/useMarket.ts
🧰 Additional context used
🧬 Code Graph Analysis (10)
src/utils/subgraph-urls.ts (1)
src/utils/networks.ts (1)
  • SupportedNetworks (33-33)
src/hooks/useMarketData.ts (5)
src/utils/networks.ts (1)
  • SupportedNetworks (33-33)
src/config/dataSources.ts (1)
  • getMarketDataSource (6-14)
src/utils/types.ts (1)
  • Market (261-312)
src/data-sources/morpho-api/market.ts (1)
  • fetchMorphoMarket (27-39)
src/data-sources/subgraph/market.ts (1)
  • fetchSubgraphMarket (129-156)
src/data-sources/morpho-api/fetchers.ts (1)
src/utils/urls.ts (1)
  • URLS (1-5)
src/hooks/useMarketHistoricalData.ts (4)
src/utils/networks.ts (1)
  • SupportedNetworks (33-33)
src/data-sources/morpho-api/historical.ts (3)
  • TimeseriesOptions (8-8)
  • HistoricalDataSuccessResult (40-43)
  • fetchMorphoMarketHistoricalData (47-117)
src/config/dataSources.ts (1)
  • getHistoricalDataSource (20-25)
src/data-sources/subgraph/historical.ts (1)
  • fetchSubgraphMarketHistoricalData (104-151)
src/data-sources/morpho-api/market.ts (5)
src/utils/types.ts (1)
  • Market (261-312)
src/utils/warnings.ts (1)
  • getMarketWarningsWithDetail (95-131)
src/utils/networks.ts (1)
  • SupportedNetworks (33-33)
src/data-sources/morpho-api/fetchers.ts (1)
  • morphoGraphqlFetcher (4-32)
src/graphql/morpho-api-queries.ts (1)
  • marketDetailQuery (181-188)
src/data-sources/subgraph/market.ts (5)
src/utils/subgraph-types.ts (3)
  • SubgraphMarket (37-69)
  • SubgraphToken (4-10)
  • SubgraphMarketQueryResponse (80-85)
src/utils/networks.ts (1)
  • SupportedNetworks (33-33)
src/utils/types.ts (3)
  • Market (261-312)
  • MorphoChainlinkOracleData (253-258)
  • WarningWithDetail (80-85)
src/utils/subgraph-urls.ts (1)
  • getSubgraphUrl (27-29)
src/data-sources/subgraph/fetchers.ts (1)
  • subgraphGraphqlFetcher (1-31)
src/config/dataSources.ts (1)
src/utils/networks.ts (1)
  • SupportedNetworks (33-33)
app/market/[chainId]/[marketid]/content.tsx (4)
src/utils/types.ts (1)
  • TimeseriesOptions (319-323)
src/hooks/useMarketData.ts (1)
  • useMarketData (8-59)
src/hooks/useMarketHistoricalData.ts (1)
  • useMarketHistoricalData (11-68)
src/components/common/Spinner.tsx (1)
  • Spinner (24-57)
src/graphql/morpho-subgraph-queries.ts (1)
src/graphql/morpho-api-queries.ts (2)
  • marketFragment (17-119)
  • marketsQuery (121-138)
src/data-sources/subgraph/historical.ts (4)
src/data-sources/morpho-api/historical.ts (5)
  • HistoricalDataSuccessResult (40-43)
  • MarketRates (10-15)
  • TimeseriesDataPoint (8-8)
  • MarketVolumes (17-24)
  • TimeseriesOptions (8-8)
src/utils/subgraph-urls.ts (1)
  • getSubgraphUrl (27-29)
src/data-sources/subgraph/fetchers.ts (1)
  • subgraphGraphqlFetcher (1-31)
src/graphql/morpho-subgraph-queries.ts (1)
  • marketHourlySnapshotsQuery (129-146)
🪛 Biome (1.9.4)
app/market/[chainId]/[marketid]/content.tsx

[error] 53-53: Useless case clause.

because the default clause is present:

Unsafe fix: Remove the useless case.

(lint/complexity/noUselessSwitchCase)

🔇 Additional comments (65)
src/utils/subgraph-types.ts (2)

22-27: Confirm interest rate type union
The 'FIXED' option isn’t used in Morpho’s rate settings (only STABLE/VARIABLE). If the subgraph never returns FIXED, drop it to tighten the union.


72-77: Approve response wrapper types
The SubgraphMarketsQueryResponse and SubgraphMarketQueryResponse match the expected GraphQL structure. Good job including optional errors.

Also applies to: 80-85

src/hooks/useMarketBorrows.ts (1)

2-2: Approve updated import path
Switching to @/graphql/morpho-api-queries aligns with the new Morpho API module.

src/hooks/useMarketLiquidations.ts (1)

2-2: Approve updated import path
The @/graphql/morpho-api-queries import correctly syncs with the Morpho API queries.

src/hooks/useMarketSupplies.ts (1)

2-2: Approve updated import path
Consistent switch to @/graphql/morpho-api-queries is correct.

src/hooks/useUserRebalancerInfo.ts (1)

2-2: Approve updated import path
Switching to @/graphql/morpho-api-queries fits the overall query migration.

src/services/statsService.ts (1)

2-2: Import source updated for stats queries.

The import source for the GraphQL queries has been updated to use the Monarch-specific stats queries module.

src/hooks/useUserTransactions.ts (1)

2-2: Updated import to use Morpho API queries.

This change aligns with the migration to Morpho-specific API query modules across the codebase.

src/hooks/useUserPositions.ts (1)

6-6: Updated import to use Morpho API queries.

Import now points to the dedicated Morpho API queries module, consistent with other hook changes.

src/hooks/useUserPosition.ts (2)

3-3: Updated import to use Morpho API queries.

Import source updated to the Morpho-specific API queries module.


63-63: Simplified state assignment.

The position state assignment has been streamlined to directly use the currentSnapshot without additional processing.

src/data-sources/morpho-api/fetchers.ts (1)

1-32: Well-structured generic fetcher for GraphQL queries.

The implementation is clean and handles errors appropriately. The type safety with generics is good for ensuring correct data handling.

src/hooks/useLiquidations.ts (5)

73-73: Appropriate state variable rename.

Changing from IDs to unique keys is consistent with the broader refactoring.


83-83: Concise local set declaration.

Good naming that matches its usage.


103-103: Updated property access is correct.

Now using market.uniqueKey instead of market.id as identifier.


111-111: State updater renamed consistently.

Correctly using the new state variable name.


128-128: Updated returned property name.

Return value is updated to match new naming.

src/data-sources/subgraph/fetchers.ts (2)

1-31: Clean implementation of subgraph fetcher.

The fetcher correctly handles API interactions and error cases with appropriate error messages.


12-15: Better error logging than morpho-api fetcher.

This implementation includes status details in error logs, which is more helpful than the morpho-api version.

src/contexts/MarketsContext.tsx (4)

12-12: Updated import path is correct.

Changed to use the new location of marketsQuery.


47-52: Property name update is consistent.

Updated destructured property from useLiquidations to match the hook's changes.


84-84: Updated marker check logic.

Now correctly checking uniqueKey instead of id.


104-104: Updated dependency correctly.

The dependency array now references the renamed state variable.

src/hooks/useMarketData.ts (1)

17-50: Query implementation is thorough and robust

The query implementation handles errors gracefully, includes proper caching with staleTime, and enables the query only when all prerequisites are met. Good job!

src/hooks/useMarketHistoricalData.ts (3)

1-7: Clean imports organized by package and local modules

The imports are well organized, starting with external libraries and then local modules. This makes it easier to understand dependencies.


11-24: Query key structure ensures proper caching

The hook parameters are well-typed with undefined handling, and the query key includes all variables that could affect the result.


25-26: Straightforward data source selection

Data source determination is concise and follows the pattern of returning null when network is undefined.

src/data-sources/subgraph/market.ts (5)

1-8: Imports correctly structured

Imports are properly organized and all necessary dependencies are included.


9-26: Well-implemented safe parsing helpers

These utility functions properly handle null/undefined values and parsing errors, providing good fallbacks.


28-58: Handling nullable subgraph fields correctly

The function properly handles potentially missing fields by providing default values, which is essential when working with external APIs.


128-138: Good error handling for missing subgraph URL

The function properly checks for missing URL and throws a meaningful error message.


72-74: ⚠️ Potential issue

Verify rates array exists before accessing

The code assumes that subgraphMarket.rates is an array, but if it's undefined, the find operation will throw an error.

-  const supplyApy = Number(subgraphMarket.rates?.find((r) => r.side === 'LENDER')?.rate ?? 0);
-  const borrowApy = Number(subgraphMarket.rates?.find((r) => r.side === 'BORROWER')?.rate ?? 0);
+  const supplyApy = Number(subgraphMarket.rates ? subgraphMarket.rates.find((r) => r.side === 'LENDER')?.rate ?? 0 : 0);
+  const borrowApy = Number(subgraphMarket.rates ? subgraphMarket.rates.find((r) => r.side === 'BORROWER')?.rate ?? 0 : 0);

Likely an incorrect or invalid review comment.

src/graphql/morpho-api-queries.ts (3)

1-2: Helpful API reference comment

Adding the API reference URL is useful for developers who need to understand the API schema.


32-45: Clean and focused token fields selection

The removal of priceUsd aligns with the type changes in types.ts, maintaining consistency.


46-63: Streamlined state fields

The state fields now focus only on essential data, which helps reduce payload size.

src/utils/types.ts (3)

308-312: Oracle data structure improvement

The type structure is now cleaner and more focused, with correct nesting of oracle data.


322-322: Narrowed interval type increases type safety

Restricting the interval options to specific values improves type safety and prevents potential errors.


341-343: Renamed type reflects its purpose better

Renaming MarketDetail to HistoricalData better represents what the type contains.

src/data-sources/morpho-api/historical.ts (1)

75-82: “Essential data” check is brittle

Only supplyApy is treated as mandatory. If the API ever omits that field (e.g. empty array) the whole result becomes null, even though the remaining series could be useful.
Consider checking for any non‑empty timeseries instead of a single field, or let the caller decide what is “usable”.

src/graphql/morpho-subgraph-queries.ts (7)

1-9: Well-defined token fragment.

The TokenFields fragment captures essential token information, including price data.


11-19: Good structure for oracle fragment.

This fragment properly encapsulates oracle information needed for market data.


21-73: Market fragment provides comprehensive data schema.

The fragment includes all necessary market fields with proper nesting and fragment composition. Comments on lines 26 and 30 helpfully map fields to application terminology.


75-82: Markets query looks good.

This query properly reuses the market fragment and includes sorting by TVL, which is a sensible default.


86-93: Single market query looks correct.

The query properly takes an ID parameter and reuses the market fragment.


97-127: Good historical data fragment.

This fragment captures the time series data needed for charts, with helpful comments about limitations at lines 124-125.


129-146: Historical data query is well structured.

The query handles time ranges properly and includes the necessary fragments. The query limit is explicit with a comment explaining the subgraph constraint.

app/market/[chainId]/[marketid]/VolumeChart.tsx (9)

19-21: Updated imports to match new data structure.

The imports now reference the correct types from the new data sources.


23-32: Props updated for unified timeframe handling.

Props now accept standardized timeframe structures and delegate state management to parent components, improving consistency.


34-43: Component parameters aligned with new props structure.

Properly destructures the new props.


52-58: Time formatting now uses the range object.

Uses the provided timestamp range for formatting decisions rather than hardcoded values.


74-76: Improved type safety for data points.

Better handling of potentially undefined values in the data arrays.


141-142: Added type annotation to reduce accumulator.

Explicitly typing the accumulator improves code clarity and prevents potential type errors.


157-160: Standardized timeframe option values.

Changed to shorter format ('1d' instead of '1day') for consistency across components.


180-184: Updated ButtonGroup to use the new timeframe props.

Properly delegates timeframe state management to parent component.


331-332: Updated timeframe display reference.

Now correctly references the new selectedTimeframe prop.

app/market/[chainId]/[marketid]/RateChart.tsx (10)

19-20: Updated imports to match new data structure.

Imports now reference the correct types from the new data sources.


22-29: Props updated for unified timeframe handling.

Props now accept standardized timeframe structures and delegate state management to parent components.


31-38: Component parameters aligned with new props structure.

Properly destructures the new props.


66-69: Added null check to prevent errors with empty data.

Ensures the function handles empty arrays gracefully.


76-83: Improved safety for null data handling.

Better handling of potentially undefined or empty historicalData arrays.


90-97: Added null and empty array checks.

Similar safety improvements for utilization data.


99-105: Time formatting now uses the range object.

Uses the provided timestamp range for formatting decisions rather than hardcoded values.


107-111: Standardized timeframe option values.

Changed to shorter format ('1d' instead of '1day') for consistency.


117-124: Updated ButtonGroup to use the new timeframe props.

Properly delegates timeframe state management to parent component.


279-280: Updated timeframe display reference.

Now correctly references the new selectedTimeframe prop.

Comment thread src/config/dataSources.ts
Comment thread src/utils/subgraph-urls.ts
Comment thread src/data-sources/morpho-api/market.ts
Comment on lines +75 to +77
const liquidityAssets = (BigInt(supplyAssets) - BigInt(borrowAssets)).toString();
const liquidityAssetsUsd =
safeParseFloat(totalDepositBalanceUSD) - safeParseFloat(totalBorrowBalanceUSD);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure safe BigInt operations

Using BigInt directly on potentially undefined values can cause runtime errors.

-  const liquidityAssets = (BigInt(supplyAssets) - BigInt(borrowAssets)).toString();
+  const supplyAssetsBigInt = BigInt(supplyAssets || '0');
+  const borrowAssetsBigInt = BigInt(borrowAssets || '0');
+  const liquidityAssets = (supplyAssetsBigInt - borrowAssetsBigInt).toString();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const liquidityAssets = (BigInt(supplyAssets) - BigInt(borrowAssets)).toString();
const liquidityAssetsUsd =
safeParseFloat(totalDepositBalanceUSD) - safeParseFloat(totalBorrowBalanceUSD);
const supplyAssetsBigInt = BigInt(supplyAssets || '0');
const borrowAssetsBigInt = BigInt(borrowAssets || '0');
const liquidityAssets = (supplyAssetsBigInt - borrowAssetsBigInt).toString();
const liquidityAssetsUsd =
safeParseFloat(totalDepositBalanceUSD) - safeParseFloat(totalBorrowBalanceUSD);

utilization: utilization,
supplyApy: supplyApy,
borrowApy: borrowApy,
fee: safeParseFloat(fee) / 10000, // Subgraph fee is likely basis points (needs verification)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify fee conversion assumption

The comment indicates uncertainty about fee conversion. This should be verified to ensure correct calculations.


🌐 Web query:

What is the format of fee values in Morpho subgraph data? Are they in basis points?

💡 Result:

Format of Fee Values in Morpho Subgraph Data

The Morpho subgraph provides detailed protocol data via GraphQL, but the specific format for fee values is not explicitly described in the official documentation or open-source subgraph repositories included in the search results. However, some inferences and conventions in DeFi data formatting, as well as observed examples and related context, can clarify how fee values typically appear.

Interest Rates and Fee Representation

  • Interest rates in Morpho subgraphs are presented as decimal values representing annualized rates. For example, a borrow APY might be given as "rate": "0.205574598544752", which corresponds to a 20.56% annual rate[9].
  • There is no evidence in the documentation or code examples that Morpho subgraph data expresses fee values in basis points (where 1 basis point = 0.01% or 0.0001 as a decimal value).
  • Instead, rates and likely fee values are stored as a human-readable decimal fraction (e.g., 0.1 for 10%, 0.0015 for 0.15%) rather than an integer representing basis points[9].

Field Naming and Raw Values

  • Morpho subgraph entities sometimes include “internal” data fields, which may not be human-readable and are meant for internal calculations. These fields are usually prefixed with an underscore and may use different scaling or representations[3].
  • For user-facing or documented fields relating to rates and protocol fees, the prevailing pattern is to use decimal fractions, not basis points[9].

Example: Interest Rate Formatting

"rate": "0.19011573722135125872777079486656"
This value should be interpreted as a decimal fraction, where 0.19... represents a 19% annualized rate, not 1,900 basis points[9].

Points and Precision

  • In the context of "points" for Morpho Blue and MetaMorpho, precision is increased by adding decimals to represent partial shares, but this is a separate mechanism not directly related to fee value formatting[6].

Summary Table

Value Type Example Format Unit
Interest Rate 0.2055745985 Decimal fraction Annualized rate
Fee (inferred) 0.01 Decimal fraction Percentage (1%)
Basis Points not used

Conclusion

Fee values in Morpho subgraph data are expressed as decimal fractions (e.g., 0.01 for 1%) and not in basis points. This matches the pattern for other rate fields in Morpho subgraphs and follows standard DeFi GraphQL conventions[9].

If you require further confirmation for a specific fee-related field, checking the field's raw value or documentation for that subgraph entity is recommended. However, all available public evidence strongly indicates decimals, not basis points, are the default.

Citations:


Adjust fee parsing: remove basis‑points scaling

Web data shows Morpho fees are decimal fractions (e.g. 0.01 for 1%), not basis points. Dividing by 10 000 will understate the fee.

Please update:

• File: src/data-sources/subgraph/market.ts (around line 103)
• Replace:

- fee: safeParseFloat(fee) / 10000, // was treating as bps
+ fee: safeParseFloat(fee),        // fee is already a decimal fraction
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fee: safeParseFloat(fee) / 10000, // Subgraph fee is likely basis points (needs verification)
// was treating fee as bps, but subgraph already returns a decimal fraction
fee: safeParseFloat(fee), // fee is already a decimal fraction

Comment on lines 35 to +44
const NOW = Math.floor(Date.now() / 1000);
const WEEK_IN_SECONDS = 7 * 24 * 60 * 60;
const DAY_IN_SECONDS = 24 * 60 * 60;
const WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS;

// Helper to calculate time range based on timeframe string
const calculateTimeRange = (timeframe: '1d' | '7d' | '30d'): TimeseriesOptions => {
const endTimestamp = NOW;
let startTimestamp;
let interval: TimeseriesOptions['interval'] = 'HOUR';
switch (timeframe) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

NOW is static – data goes stale after first render

NOW is evaluated at module load, so every later timeframe change still uses the old timestamp.
Compute endTimestamp inside calculateTimeRange instead:

-const NOW = Math.floor(Date.now() / 1000);-const calculateTimeRange = (timeframe: '1d' | '7d' | '30d'): TimeseriesOptions => {
-  const endTimestamp = NOW;
+const calculateTimeRange = (timeframe: '1d' | '7d' | '30d'): TimeseriesOptions => {
+  const endTimestamp = Math.floor(Date.now() / 1000);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const NOW = Math.floor(Date.now() / 1000);
const WEEK_IN_SECONDS = 7 * 24 * 60 * 60;
const DAY_IN_SECONDS = 24 * 60 * 60;
const WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS;
// Helper to calculate time range based on timeframe string
const calculateTimeRange = (timeframe: '1d' | '7d' | '30d'): TimeseriesOptions => {
const endTimestamp = NOW;
let startTimestamp;
let interval: TimeseriesOptions['interval'] = 'HOUR';
switch (timeframe) {
const DAY_IN_SECONDS = 24 * 60 * 60;
const WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS;
// Helper to calculate time range based on timeframe string
const calculateTimeRange = (timeframe: '1d' | '7d' | '30d'): TimeseriesOptions => {
const endTimestamp = Math.floor(Date.now() / 1000);
let startTimestamp;
let interval: TimeseriesOptions['interval'] = 'HOUR';
switch (timeframe) {

Comment on lines +79 to +90
const supplyNative = BigInt(snapshot.inputTokenBalance ?? '0');
const borrowNative = BigInt(snapshot.variableBorrowedTokenBalance ?? '0');
const liquidityNative = supplyNative - borrowNative;

volumes.supplyAssetsUsd.push({ x: timestamp, y: 0 });
volumes.borrowAssetsUsd.push({ x: timestamp, y: 0 });
volumes.liquidityAssetsUsd.push({ x: timestamp, y: 0 });

volumes.supplyAssets.push({ x: timestamp, y: Number(supplyNative) });
volumes.borrowAssets.push({ x: timestamp, y: Number(borrowNative) });
volumes.liquidityAssets.push({ x: timestamp, y: Number(liquidityNative) });
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

BigInt → Number may overflow

Number(supplyNative) (and similar) loses precision once values exceed 2^53‑1. Large markets will hit this quickly.

- volumes.supplyAssets.push({ x: timestamp, y: Number(supplyNative) });
+ volumes.supplyAssets.push({ x: timestamp, y: parseFloat(supplyNative.toString()) });

Or keep the value as string/BigInt and convert only in the chart layer.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const supplyNative = BigInt(snapshot.inputTokenBalance ?? '0');
const borrowNative = BigInt(snapshot.variableBorrowedTokenBalance ?? '0');
const liquidityNative = supplyNative - borrowNative;
volumes.supplyAssetsUsd.push({ x: timestamp, y: 0 });
volumes.borrowAssetsUsd.push({ x: timestamp, y: 0 });
volumes.liquidityAssetsUsd.push({ x: timestamp, y: 0 });
volumes.supplyAssets.push({ x: timestamp, y: Number(supplyNative) });
volumes.borrowAssets.push({ x: timestamp, y: Number(borrowNative) });
volumes.liquidityAssets.push({ x: timestamp, y: Number(liquidityNative) });
});
const supplyNative = BigInt(snapshot.inputTokenBalance ?? '0');
const borrowNative = BigInt(snapshot.variableBorrowedTokenBalance ?? '0');
const liquidityNative = supplyNative - borrowNative;
volumes.supplyAssetsUsd.push({ x: timestamp, y: 0 });
volumes.borrowAssetsUsd.push({ x: timestamp, y: 0 });
volumes.liquidityAssetsUsd.push({ x: timestamp, y: 0 });
- volumes.supplyAssets.push({ x: timestamp, y: Number(supplyNative) });
+ volumes.supplyAssets.push({ x: timestamp, y: parseFloat(supplyNative.toString()) });
volumes.borrowAssets.push({ x: timestamp, y: Number(borrowNative) });
volumes.liquidityAssets.push({ x: timestamp, y: Number(liquidityNative) });
});

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
app/market/[chainId]/[marketid]/RateChart.tsx (2)

45-55: Consider memoizing chart data calculation.

The getChartData function rebuilds the chart data on every render. Consider using React's useMemo to cache this calculation and prevent unnecessary work.

-  const getChartData = () => {
+  const chartData = React.useMemo(() => {
     if (!historicalData) return [];
     const { supplyApy, borrowApy, rateAtUTarget } = historicalData;
 
     return supplyApy.map((point: TimeseriesDataPoint, index: number) => ({
       x: point.x,
       supplyApy: point.y,
       borrowApy: borrowApy[index]?.y || 0,
       rateAtUTarget: rateAtUTarget[index]?.y || 0,
     }));
-  };
+  }, [historicalData]);

107-111: Define timeframe values as constants.

Using magic strings for timeframe values ('1d', '7d', '30d') could lead to typos. Consider defining these as constants in a separate file.

+// In a constants file
+export const TIMEFRAMES = {
+  ONE_DAY: '1d',
+  ONE_WEEK: '7d',
+  ONE_MONTH: '30d',
+} as const;
+
+export type Timeframe = typeof TIMEFRAMES[keyof typeof TIMEFRAMES];

// Then in this file
const timeframeOptions = [
-  { key: '1d', label: '1D', value: '1d' },
-  { key: '7d', label: '7D', value: '7d' },
-  { key: '30d', label: '30D', value: '30d' },
+  { key: TIMEFRAMES.ONE_DAY, label: '1D', value: TIMEFRAMES.ONE_DAY },
+  { key: TIMEFRAMES.ONE_WEEK, label: '7D', value: TIMEFRAMES.ONE_WEEK },
+  { key: TIMEFRAMES.ONE_MONTH, label: '30D', value: TIMEFRAMES.ONE_MONTH },
];
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a4439d1 and ea1b8ba.

📒 Files selected for processing (6)
  • app/market/[chainId]/[marketid]/RateChart.tsx (5 hunks)
  • app/market/[chainId]/[marketid]/VolumeChart.tsx (8 hunks)
  • src/data-sources/morpho-api/historical.ts (1 hunks)
  • src/data-sources/morpho-api/market.ts (1 hunks)
  • src/data-sources/subgraph/historical.ts (1 hunks)
  • src/utils/types.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/data-sources/morpho-api/market.ts
  • src/data-sources/subgraph/historical.ts
  • src/data-sources/morpho-api/historical.ts
  • src/utils/types.ts
  • app/market/[chainId]/[marketid]/VolumeChart.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/market/[chainId]/[marketid]/RateChart.tsx (3)
src/utils/types.ts (4)
  • MarketRates (326-331)
  • Market (261-312)
  • TimeseriesOptions (319-323)
  • TimeseriesDataPoint (314-317)
src/data-sources/morpho-api/historical.ts (2)
  • TimeseriesOptions (14-14)
  • TimeseriesDataPoint (14-14)
src/components/ButtonGroup.tsx (1)
  • ButtonGroup (51-97)
🔇 Additional comments (10)
app/market/[chainId]/[marketid]/RateChart.tsx (10)

3-3: Simplified imports with better type specificity.

Updated imports now directly reference MarketRates type, which aligns with the new data source refactoring.

Also applies to: 19-20


22-29: Props interface improved for unified timeframe handling.

The component now uses a consistent timeframe format ('1d'|'7d'|'30d') and a single callback handler, which simplifies the API and aligns with other components.


31-38: Clean prop destructuring with updated parameter names.

Updated parameter names match the interface changes, maintaining code consistency.


63-69: Added null safety check for empty arrays.

Good defensive programming - checking for empty arrays before reduction prevents potential runtime errors.


75-83: Improved typesafety in rate calculation.

Added null check for empty data and explicitly typed reducer parameters for better type safety.


89-97: Enhanced null checking for utilization rate calculation.

Similar improvements to type safety with explicit null checking and typed reducer parameters.


99-105: Updated time formatting logic for consistency.

Now uses selectedTimeRange instead of the removed rateTimeRange for determining timestamp formatting.


107-111: Simplified timeframe options with shorter keys.

Updated timeframe option values from longer format ('1day') to shorter format ('1d'), improving consistency.


117-123: Streamlined timeframe selection handler.

The ButtonGroup now directly calls the passed handler with proper type casting, eliminating an unnecessary wrapper function.


276-280: Updated timeframe display in UI.

The historical averages section now correctly references the updated timeframe format.

@antoncoding antoncoding merged commit e006e23 into master Apr 20, 2025
4 checks passed
@antoncoding antoncoding deleted the refactor/change-subgraph branch April 20, 2025 15:56
@coderabbitai coderabbitai Bot mentioned this pull request Nov 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant