UNPKG

0xtrails

Version:

SDK for Trails

159 lines (136 loc) 4.13 kB
import { useMemo, useEffect } from "react" import { useAavePools } from "./aave.js" import { useMorphoVaults } from "./morpho.js" import { logger } from "./logger.js" // Cache configuration const CACHE_DURATION = 5 * 60 * 1000 // 5 minutes in milliseconds // Global cache for pools data let poolsCache: { data: Pool[] timestamp: number aaveData: Pool[] | null morphoData: Pool[] | null } | null = null // Pool data interface (shared across all protocols) export interface Pool { id: string name: string protocol: string chainId: number apy: number tvl: number token: { symbol: string name: string address: string decimals: number logoUrl?: string } depositAddress: string isActive: boolean poolUrl?: string protocolUrl?: string wrappedTokenGatewayAddress?: string } export function usePools() { // Fetch pools from Aave const { data: aavePools, loading: aaveLoading, error: aaveError, } = useAavePools() // Fetch vaults from Morpho const { data: morphoPools, loading: morphoLoading, error: morphoError, } = useMorphoVaults() // Check if cache is valid const isCacheValid = useMemo(() => { if (!poolsCache) return false const now = Date.now() const isExpired = now - poolsCache.timestamp > CACHE_DURATION // Check if underlying data has changed const aaveDataChanged = JSON.stringify(poolsCache.aaveData) !== JSON.stringify(aavePools) const morphoDataChanged = JSON.stringify(poolsCache.morphoData) !== JSON.stringify(morphoPools) return !isExpired && !aaveDataChanged && !morphoDataChanged }, [aavePools, morphoPools]) // Combine and transform all pools with caching const allPools: Pool[] = useMemo(() => { // Return cached data if valid if (isCacheValid && poolsCache) { logger.console.log("[trails-sdk] Using cached pools data") return poolsCache.data } logger.console.log("[trails-sdk] Generating new pools data") const pools: Pool[] = [] // Add Aave pools if (aavePools) { pools.push(...aavePools) } // Add Morpho pools if (morphoPools) { pools.push(...morphoPools) } // Update cache poolsCache = { data: pools, timestamp: Date.now(), aaveData: aavePools, morphoData: morphoPools, } return pools }, [aavePools, morphoPools, isCacheValid]) // Determine overall loading and error states const loading = useMemo(() => { // Don't show loading if we have valid cached data if (isCacheValid && poolsCache) { return false } return aaveLoading || morphoLoading }, [aaveLoading, morphoLoading, isCacheValid]) const error = useMemo(() => { // Don't show error if we have valid cached data if (isCacheValid && poolsCache) { return null } return aaveError || morphoError }, [aaveError, morphoError, isCacheValid]) // Sort by APY descending with caching const sortedPools = useMemo(() => { return allPools.sort((a: Pool, b: Pool) => b.apy - a.apy) }, [allPools]) // Clear cache when there are errors useEffect(() => { if (aaveError || morphoError) { logger.console.log("[trails-sdk] Clearing cache due to errors") poolsCache = null } }, [aaveError, morphoError]) // logger.console.log("[trails-sdk] === COMBINED POOLS DEBUG ===") // logger.console.log("[trails-sdk] Cache valid:", isCacheValid) // logger.console.log("[trails-sdk] Aave pools count:", aavePools?.length || 0) // logger.console.log("[trails-sdk] Morpho pools count:", morphoPools?.length || 0) // logger.console.log("[trails-sdk] Total pools count:", sortedPools.length) // logger.console.log( // "[trails-sdk] Loading states - Aave:", // aaveLoading, // "Morpho:", // morphoLoading, // ) // logger.console.log( // "[trails-sdk] Error states - Aave:", // aaveError, // "Morpho:", // morphoError, // ) // logger.console.log("[trails-sdk] ==============================") return { data: sortedPools, loading, error, } } export default usePools