diff --git a/src/hooks/app-data-provider/useAppDataProvider.tsx b/src/hooks/app-data-provider/useAppDataProvider.tsx index 0572fce96d..b50504c01d 100644 --- a/src/hooks/app-data-provider/useAppDataProvider.tsx +++ b/src/hooks/app-data-provider/useAppDataProvider.tsx @@ -76,15 +76,16 @@ export const AppDataProvider: React.FC = ({ children }) => { const currentMarketData = useRootStore((state) => state.currentMarketData); const currentMarket = useRootStore((state) => state.currentMarket); - // pool hooks + // pool hooks const { data: reservesData, isLoading: reservesDataLoading } = usePoolReservesHumanized(currentMarketData); + const { data: formattedPoolReserves, isLoading: formattedPoolReservesLoading } = usePoolFormattedReserves(currentMarketData); const baseCurrencyData = reservesData?.baseCurrencyData; - // user hooks + // user hooks const eModes = reservesData?.reservesData ? formatEmodes(reservesData.reservesData) : {}; const { data: userReservesData, isLoading: userReservesDataLoading } = diff --git a/src/hooks/pool/usePoolFormattedReserves.ts b/src/hooks/pool/usePoolFormattedReserves.ts index 2f80cb0239..e6ae6bf424 100644 --- a/src/hooks/pool/usePoolFormattedReserves.ts +++ b/src/hooks/pool/usePoolFormattedReserves.ts @@ -6,6 +6,7 @@ import { import { formatReservesAndIncentives } from '@aave/math-utils'; import dayjs from 'dayjs'; import memoize from 'micro-memoize'; +import { UnderlyingAPYs } from 'src/services/UnderlyingYieldService'; import { reserveSortFn } from 'src/store/poolSelectors'; import { MarketDataType } from 'src/ui-config/marketsConfig'; import { fetchIconSymbolAndName, IconMapInterface } from 'src/ui-config/reservePatches'; @@ -14,6 +15,7 @@ import { getNetworkConfig, NetworkConfig } from 'src/utils/marketsAndNetworksCon import { selectBaseCurrencyData, selectReserves } from './selectors'; import { usePoolsReservesHumanized } from './usePoolReserves'; import { usePoolsReservesIncentivesHumanized } from './usePoolReservesIncentives'; +import { useUnderlyingYields } from './useUnderlyingYield'; import { combineQueries, SimplifiedUseQueryResult } from './utils'; export type FormattedReservesAndIncentives = ReturnType< @@ -22,13 +24,16 @@ export type FormattedReservesAndIncentives = ReturnType< IconMapInterface & { isEmodeEnabled: boolean; isWrappedBaseAsset: boolean; - } & ReserveDataHumanized; + } & ReserveDataHumanized & { + underlyingAPY: number | null; + }; const formatReserves = memoize( ( reservesData: ReservesDataHumanized, incentivesData: ReservesIncentiveDataHumanized[], - networkConfig: NetworkConfig + networkConfig: NetworkConfig, + underlyingAPYs: UnderlyingAPYs ) => { const reserves = selectReserves(reservesData); const baseCurrencyData = selectBaseCurrencyData(reservesData); @@ -45,6 +50,7 @@ const formatReserves = memoize( isEmodeEnabled: r.eModeCategoryId !== 0, isWrappedBaseAsset: r.symbol.toLowerCase() === networkConfig.wrappedBaseAssetSymbol?.toLowerCase(), + underlyingAPY: underlyingAPYs ? underlyingAPYs[r.symbol] : null, })) .sort(reserveSortFn); } @@ -55,6 +61,7 @@ export const usePoolsFormattedReserves = ( ): SimplifiedUseQueryResult[] => { const poolsReservesQueries = usePoolsReservesHumanized(marketsData); const poolsReservesIncentivesQueries = usePoolsReservesIncentivesHumanized(marketsData); + const underlyingAPYs = useUnderlyingYields(); return poolsReservesQueries.map((poolReservesQuery, index) => { const marketData = marketsData[index]; @@ -62,11 +69,15 @@ export const usePoolsFormattedReserves = ( const networkConfig = getNetworkConfig(marketData.chainId); const selector = ( reservesData: ReservesDataHumanized, - incentivesData: ReservesIncentiveDataHumanized[] + incentivesData: ReservesIncentiveDataHumanized[], + underlyingAPYs: UnderlyingAPYs ) => { - return formatReserves(reservesData, incentivesData, networkConfig); + return formatReserves(reservesData, incentivesData, networkConfig, underlyingAPYs); }; - return combineQueries([poolReservesQuery, poolReservesIncentivesQuery] as const, selector); + return combineQueries( + [poolReservesQuery, poolReservesIncentivesQuery, underlyingAPYs] as const, + selector + ); }); }; diff --git a/src/hooks/pool/useUnderlyingYield.ts b/src/hooks/pool/useUnderlyingYield.ts new file mode 100644 index 0000000000..4281086234 --- /dev/null +++ b/src/hooks/pool/useUnderlyingYield.ts @@ -0,0 +1,15 @@ +import { useQuery } from '@tanstack/react-query'; +import { UnderlyingAPYs } from 'src/services/UnderlyingYieldService'; +import { POLLING_INTERVAL, queryKeysFactory } from 'src/ui-config/queries'; +import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; + +import { SimplifiedUseQueryResult } from './utils'; + +export const useUnderlyingYields = (): SimplifiedUseQueryResult => { + const { underlyingYieldService } = useSharedDependencies(); + return useQuery({ + queryKey: queryKeysFactory.underlyingYields(), + queryFn: () => underlyingYieldService.getUnderlyingAPYs(), + refetchInterval: POLLING_INTERVAL, + }); +}; diff --git a/src/hooks/pool/useUserYield.ts b/src/hooks/pool/useUserYield.ts index f1d5dab8b4..f5082a9401 100644 --- a/src/hooks/pool/useUserYield.ts +++ b/src/hooks/pool/useUserYield.ts @@ -34,7 +34,7 @@ const formatUserYield = memoize( formattedGhoUserData: FormattedGhoUserData | undefined, user: FormatUserSummaryAndIncentivesResponse, currentMarket: string - ) => { + ): UserYield => { const proportions = user.userReservesData.reduce( (acc, value) => { const reserve = formattedPoolReserves.find( @@ -46,6 +46,12 @@ const formatUserYield = memoize( acc.positiveProportion = acc.positiveProportion.plus( new BigNumber(reserve.supplyAPY).multipliedBy(value.underlyingBalanceUSD) ); + + if (reserve.underlyingAPY) { + acc.positiveProportion = acc.positiveProportion.plus( + new BigNumber(reserve.underlyingAPY).multipliedBy(value.underlyingBalanceUSD) + ); + } if (reserve.aIncentivesData) { reserve.aIncentivesData.forEach((incentive) => { acc.positiveProportion = acc.positiveProportion.plus( diff --git a/src/locales/en/messages.po b/src/locales/en/messages.po index 1726c4dfa3..e5e5e1bd26 100644 --- a/src/locales/en/messages.po +++ b/src/locales/en/messages.po @@ -3471,6 +3471,7 @@ msgstr "withdrew" #: src/layouts/TopBarNotify.tsx #: src/layouts/TopBarNotify.tsx #: src/modules/dashboard/DashboardEModeButton.tsx +#: src/modules/dashboard/lists/ListAPYDetails.tsx #: src/modules/reserve-overview/ReserveTopDetailsWrapper.tsx #: src/modules/staking/GhoDiscountProgram.tsx msgid "{0}" diff --git a/src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsList.tsx b/src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsList.tsx index b5fde89f7f..ac1ed19c30 100644 --- a/src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsList.tsx +++ b/src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsList.tsx @@ -166,6 +166,7 @@ export const BorrowAssetsList = () => { 'asset', filteredReserves as unknown as DashboardReserve[] ); + const borrowDisabled = !sortedReserves.length && !ghoReserve; const RenderHeader: React.FC = () => { diff --git a/src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsListItem.tsx b/src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsListItem.tsx index 671e051ad7..420449ff98 100644 --- a/src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsListItem.tsx +++ b/src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsListItem.tsx @@ -11,6 +11,7 @@ import { CapsHint } from '../../../../components/caps/CapsHint'; import { CapType } from '../../../../components/caps/helper'; import { Link, ROUTES } from '../../../../components/primitives/Link'; import { ListAPRColumn } from '../ListAPRColumn'; +import { ListAPYDetails } from '../ListAPYDetails'; import { ListButtonsColumn } from '../ListButtonsColumn'; import { ListItemWrapper } from '../ListItemWrapper'; import { ListValueColumn } from '../ListValueColumn'; @@ -27,6 +28,7 @@ export const BorrowAssetsListItem = ({ vIncentivesData, underlyingAsset, isFreezed, + underlyingAPY, }: DashboardReserve) => { const { openBorrow } = useModalContext(); const { currentMarket } = useProtocolDataContext(); @@ -61,15 +63,21 @@ export const BorrowAssetsListItem = ({ } /> + ) : null + } incentives={vIncentivesData} symbol={symbol} /> - {/* */}