diff --git a/.gitignore b/.gitignore index 45023cd4..0d4e5865 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ build dist .env .DS_Store +scripts \ No newline at end of file diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 50235cdc..57c885d2 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -34,6 +34,7 @@ "bignumber.js": "^9.1.1", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "dayjs": "^1.11.13", "encoding": "^0.1.13", "fuels": "0.96.1", "lucide-react": "^0.460.0", diff --git a/apps/frontend/src/components/DashboardView/AssetsTable/BorrowTable.tsx b/apps/frontend/src/components/DashboardView/AssetsTable/BorrowTable.tsx index 0b00f9f6..8b8646f7 100644 --- a/apps/frontend/src/components/DashboardView/AssetsTable/BorrowTable.tsx +++ b/apps/frontend/src/components/DashboardView/AssetsTable/BorrowTable.tsx @@ -1,6 +1,10 @@ import { InfoIcon } from '@/components/InfoIcon'; +import { Line } from '@/components/Line'; import { PointIcons } from '@/components/PointIcons'; -import { POINTS_BORROW } from '@/components/PointIcons/PointsTooltip'; +import { + POINTS_BORROW, + POINTS_LM, +} from '@/components/PointIcons/PointsTooltip'; import { Title } from '@/components/Title'; import { Button } from '@/components/ui/button'; import { @@ -20,12 +24,18 @@ import { TableHeader, TableRow, } from '@/components/ui/table'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from '@/components/ui/tooltip'; import { appConfig } from '@/configs'; import { USER_ROLE, + useApr, useBalance, useBorrowCapacity, - useBorrowRate, useMarketConfiguration, usePrice, useUserRole, @@ -40,12 +50,7 @@ import { selectChangeTokenAmount, useMarketStore, } from '@/stores'; -import { - SYMBOL_TO_ICON, - formatUnits, - getBorrowApr, - getFormattedNumber, -} from '@/utils'; +import { SYMBOL_TO_ICON, formatUnits, getFormattedNumber } from '@/utils'; import { useAccount, useIsConnected } from '@fuels/react'; import * as VisuallyHidden from '@radix-ui/react-visually-hidden'; import BigNumber from 'bignumber.js'; @@ -66,6 +71,12 @@ const SkeletonRow = ( + + + + + +
+
+
Borrow APY
+ +
+
+
Borrow APY
+ +
Supply Points
@@ -111,7 +130,6 @@ export const BorrowTable = () => { ); const changeInputDialogOpen = useMarketStore(selectChangeInputDialogOpen); - const { data: borrowRate, isPending: isBorrowRatePending } = useBorrowRate(); const { data: userSupplyBorrow } = useUserSupplyBorrow(); const { data: priceData } = usePrice(); const { data: marketConfiguration, isPending: isPendingMarketConfiguration } = @@ -125,6 +143,8 @@ export const BorrowTable = () => { changeInputDialogOpen(true); }; + const { data: aprData, isPending: isAprPending } = useApr(); + const { isConnected } = useIsConnected(); const { data: balance } = useBalance({ @@ -161,7 +181,7 @@ export const BorrowTable = () => { - +
Borrow Asset { />
- Borrow APY - Your Borrow Position - + Borrow APY + Your Borrow Position + +
+ Reward APY + +
+
+ +
+ Net APY + +
+
+
Borrow Points { />
- {} + {}
- {isPendingMarketConfiguration ? ( + {isPendingMarketConfiguration || isAprPending ? ( SkeletonRow ) : ( @@ -239,13 +279,74 @@ export const BorrowTable = () => { - {getBorrowApr(borrowRate)} + {aprData?.borrowBaseApr.times(100).toFixed(2)}% {borrowedBalance} + +
+ {aprData?.borrowRewardApr.times(100).toFixed(2)}% + +
+
+ + + + any }) => + e.preventDefault() + } + > +
{aprData?.netBorrowApr.times(100).toFixed(2)}%
+
+ any; + }) => e.preventDefault()} + > +
+
+ Net Borrow APY +
+
+
+
Borrow APY
+
+ {aprData?.borrowBaseApr.times(100).toFixed(2)}% +
+
+
+
Reward APY
+
+ {aprData?.borrowRewardApr.times(100).toFixed(2)}% +
+
+
+ +
+
Net Borrow APY
+
+ {aprData?.netBorrowApr.times(100).toFixed(2)}% +
+
+
+
+
+
+
@@ -307,7 +408,7 @@ export const BorrowTable = () => { Card Description - {isPendingMarketConfiguration ? ( + {isPendingMarketConfiguration || isAprPending ? ( SkeletonCardContent ) : ( @@ -365,10 +466,10 @@ export const BorrowTable = () => {
- {getBorrowApr(borrowRate)} + {aprData?.borrowBaseApr.times(100).toFixed(2)}%
@@ -377,6 +478,35 @@ export const BorrowTable = () => {
{borrowedBalance}
+
+
+ Reward APY +
+
+
+ {aprData?.borrowRewardApr.times(100).toFixed(2)}% + +
+
+
+
+
+ Net APY +
+
+ {aprData?.netBorrowApr.times(100).toFixed(2)}% +
+
Borrow Points diff --git a/apps/frontend/src/components/DashboardView/AssetsTable/CollateralTable.tsx b/apps/frontend/src/components/DashboardView/AssetsTable/CollateralTable.tsx index dfeaf28f..40f7c992 100644 --- a/apps/frontend/src/components/DashboardView/AssetsTable/CollateralTable.tsx +++ b/apps/frontend/src/components/DashboardView/AssetsTable/CollateralTable.tsx @@ -280,14 +280,7 @@ const CollateralTableRow = ({
- +
@@ -402,15 +395,7 @@ const CollateralCard = ({
Supply Points
- +
diff --git a/apps/frontend/src/components/DashboardView/AssetsTable/LendTable.tsx b/apps/frontend/src/components/DashboardView/AssetsTable/LendTable.tsx index 61b1bb1c..fdb2e64c 100644 --- a/apps/frontend/src/components/DashboardView/AssetsTable/LendTable.tsx +++ b/apps/frontend/src/components/DashboardView/AssetsTable/LendTable.tsx @@ -1,6 +1,7 @@ import { InfoIcon } from '@/components/InfoIcon'; +import { Line } from '@/components/Line'; import { PointIcons } from '@/components/PointIcons'; -import { POINTS_LEND } from '@/components/PointIcons/PointsTooltip'; +import { POINTS_LEND, POINTS_LM } from '@/components/PointIcons/PointsTooltip'; import { Title } from '@/components/Title'; import { Button } from '@/components/ui/button'; import { @@ -20,9 +21,16 @@ import { TableHeader, TableRow, } from '@/components/ui/table'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from '@/components/ui/tooltip'; import { appConfig } from '@/configs'; import { USER_ROLE, + useApr, useBalance, useMarketConfiguration, useSupplyRate, @@ -63,6 +71,12 @@ const SkeletonRow = ( + + + + + +
+
+
Reward APY
+ +
+
+
Net APY
+ +
Supply Points
@@ -108,7 +130,6 @@ export const LendTable = () => { ); const changeInputDialogOpen = useMarketStore(selectChangeInputDialogOpen); - const { data: supplyRate, isPending: isSupplyRatePending } = useSupplyRate(); const { data: userSupplyBorrow } = useUserSupplyBorrow(); const { data: marketConfiguration, isPending: isPendingMarketConfiguration } = useMarketConfiguration(); @@ -125,6 +146,8 @@ export const LendTable = () => { assetId: marketConfiguration?.baseToken.bits, }); + const { data: aprData, isPending: isAprPending } = useApr(); + const userRole = useUserRole(); return ( @@ -133,15 +156,35 @@ export const LendTable = () => {
- +
Earn Asset
- Supply APY - Your Supplied Assets - + Supply APY + Your Supplied Assets + +
+ Reward APY + +
+
+ +
+ Net APY + +
+
+
Earn Points { />
- {} + {}
- {isPendingMarketConfiguration ? ( + {isPendingMarketConfiguration || isAprPending ? ( SkeletonRow ) : ( @@ -205,11 +248,11 @@ export const LendTable = () => { - {getSupplyApr(supplyRate)} + {aprData?.supplyBaseApr.times(100).toFixed(2)}% {getFormattedNumber( @@ -220,6 +263,67 @@ export const LendTable = () => { )}{' '} {appConfig.assets[marketConfiguration?.baseToken.bits ?? '']} + +
+ {aprData?.supplyRewardApr.times(100).toFixed(2)}% + +
+
+ + + + any }) => + e.preventDefault() + } + > +
{aprData?.netSupplyApr.times(100).toFixed(2)}%
+
+ any; + }) => e.preventDefault()} + > +
+
+ Net Earn APY +
+
+
+
Supply APY
+
+ {aprData?.supplyBaseApr.times(100).toFixed(2)}% +
+
+
+
Reward APY
+
+ {aprData?.supplyRewardApr.times(100).toFixed(2)}% +
+
+
+ +
+
Net Supply APY
+
+ {aprData?.netSupplyApr.times(100).toFixed(2)}% +
+
+
+
+
+
+
@@ -279,7 +383,7 @@ export const LendTable = () => { Card Description - {isPendingMarketConfiguration ? ( + {isPendingMarketConfiguration || isAprPending ? ( SkeletonCardContent ) : ( @@ -331,10 +435,10 @@ export const LendTable = () => {
- {getSupplyApr(supplyRate)} + {aprData?.supplyBaseApr.times(100).toFixed(2)}%
@@ -355,6 +459,31 @@ export const LendTable = () => { }
+
+
Reward APY
+
+
+ {aprData?.supplyRewardApr.times(100).toFixed(2)}% + +
+
+
+
+
Net APY
+
+ {aprData?.netSupplyApr.times(100).toFixed(2)}% +
+
Supply Points diff --git a/apps/frontend/src/components/DashboardView/Stats/InfoBowl.tsx b/apps/frontend/src/components/DashboardView/Stats/InfoBowl.tsx index a1692bea..38827adb 100644 --- a/apps/frontend/src/components/DashboardView/Stats/InfoBowl.tsx +++ b/apps/frontend/src/components/DashboardView/Stats/InfoBowl.tsx @@ -5,16 +5,11 @@ import { TooltipProvider, TooltipTrigger, } from '@/components/ui/tooltip'; -import { - useBorrowRate, - useSupplyRate, - useUserCollateralAssets, - useUserSupplyBorrow, -} from '@/hooks'; +import { useUserCollateralAssets, useUserSupplyBorrow } from '@/hooks'; +import { useApr } from '@/hooks'; import { useUserCollateralUtilization } from '@/hooks/useUserCollateralUtilization'; import { cn } from '@/lib/utils'; import { selectMarketMode, useMarketStore } from '@/stores'; -import { getBorrowApr, getSupplyApr } from '@/utils'; import { useIsConnected } from '@fuels/react'; import { useMemo } from 'react'; import Wave from 'react-wavify'; @@ -38,8 +33,7 @@ const WAVE_COLORS = { export const InfoBowl = () => { const marketMode = useMarketStore(selectMarketMode); const { isConnected } = useIsConnected(); - const { data: borrowRate, isPending: isPendingBorrowRate } = useBorrowRate(); - const { data: supplyRate, isPending: isPendingSupplyRate } = useSupplyRate(); + const { data: userSupplyBorrow, isPending: isPendingUserSupplyBorrow } = useUserSupplyBorrow(); const { data: collateralUtilization } = useUserCollateralUtilization(); @@ -70,23 +64,12 @@ export const InfoBowl = () => { return WAVE_COLORS.danger; }, [collateralUtilization, collateralBalances]); - const borrowApr = useMemo(() => getBorrowApr(borrowRate), [borrowRate]); - - const supplyApr = useMemo(() => getSupplyApr(supplyRate), [supplyRate]); + const { data: aprData, isPending: isAprPending } = useApr(); const isLoading = useMemo(() => { - if (!isConnected) return isPendingBorrowRate || isPendingSupplyRate; - return [ - isPendingBorrowRate, - isPendingSupplyRate, - isPendingUserSupplyBorrow, - ].some((res) => res); - }, [ - isConnected, - isPendingBorrowRate, - isPendingSupplyRate, - isPendingUserSupplyBorrow, - ]); + if (!isConnected) return isAprPending; + return [isPendingUserSupplyBorrow, isAprPending].some((res) => res); + }, [isConnected, isAprPending, isPendingUserSupplyBorrow]); return ( @@ -165,17 +148,17 @@ export const InfoBowl = () => { )} {bowlMode === 1 && (
- Borrow APY + Net Borrow APY
- {borrowApr} + {aprData?.netBorrowApr.times(100).toFixed(2)}%
)} {bowlMode === 0 && (
- Supply APY + Net Supply APY
- {supplyApr} + {aprData?.netSupplyApr.times(100).toFixed(2)}%
)} diff --git a/apps/frontend/src/components/MarketsView/MarketOverview.tsx b/apps/frontend/src/components/MarketsView/MarketOverview.tsx index 336d8b1d..c28ab8fe 100644 --- a/apps/frontend/src/components/MarketsView/MarketOverview.tsx +++ b/apps/frontend/src/components/MarketsView/MarketOverview.tsx @@ -2,26 +2,23 @@ import { Card, CardContent, CardHeader } from '@/components/ui/card'; import { - useBorrowRate, + useApr, useCollateralConfigurations, useMarketBalanceOfBase, useMarketBasics, useMarketConfiguration, usePrice, - useSupplyRate, useTotalCollateral, useTotalReserves, } from '@/hooks'; -import { ChartData } from '@/lib/charts'; +import type { ChartData } from '@/lib/charts'; import { cn } from '@/lib/utils'; import { SYMBOL_TO_ICON, formatUnits, - getBorrowApr, getFormattedNumber, getFormattedPrice, - getSupplyApr, } from '@/utils'; import BigNumber from 'bignumber.js'; import { ChevronLeft } from 'lucide-react'; @@ -29,6 +26,13 @@ import Link from 'next/link'; import type React from 'react'; import { useMemo } from 'react'; import { IconPair } from '../IconPair'; +import { Line } from '../Line'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from '../ui/tooltip'; import { KinkChart } from './KinkChart'; import { MarketChart } from './MarketChart'; import { MarketCollateralsTable } from './MarketCollateralsTable'; @@ -44,15 +48,13 @@ export default function MarketOverview({ baseAsset, chartData, }: MarketOverviewProps) { - const { data: borrowRate } = useBorrowRate(baseAsset); - const { data: supplyRate } = useSupplyRate(baseAsset); const { data: totalReserves } = useTotalReserves(baseAsset); + const { data: aprData, isPending: isAprPending } = useApr(); + const { data: collateralConfigurations } = useCollateralConfigurations(baseAsset); const { data: marketConfiguration } = useMarketConfiguration(baseAsset); - const borrowApr = useMemo(() => getBorrowApr(borrowRate), [borrowRate]); - const supplyApr = useMemo(() => getSupplyApr(supplyRate), [supplyRate]); const { data: availableLiquidity } = useMarketBalanceOfBase(baseAsset); const { data: totalCollateral } = useTotalCollateral(baseAsset); @@ -261,15 +263,115 @@ export default function MarketOverview({
Net Borrow APR
-
- {borrowApr} +
+ + + any }) => + e.preventDefault() + } + > +
+ {aprData?.netBorrowApr.times(100).toFixed(2)}% +
+
+ any; + }) => e.preventDefault()} + > +
+
+ Net Borrow APY +
+
+
+
Borrow APY
+
+ {aprData?.borrowBaseApr.times(100).toFixed(2)}% +
+
+
+
Reward APY
+
+ {aprData?.borrowRewardApr.times(100).toFixed(2)} + % +
+
+
+ +
+
Net Borrow APY
+
+ {aprData?.netBorrowApr.times(100).toFixed(2)}% +
+
+
+
+
+
Net Earn APR
-
- {supplyApr} +
+ + + any }) => + e.preventDefault() + } + > +
+ {aprData?.netSupplyApr.times(100).toFixed(2)}% +
+
+ any; + }) => e.preventDefault()} + > +
+
+ Net Earn APY +
+
+
+
Supply APY
+
+ {aprData?.supplyBaseApr.times(100).toFixed(2)}% +
+
+
+
Reward APY
+
+ {aprData?.supplyRewardApr.times(100).toFixed(2)} + % +
+
+
+ +
+
Net Supply APY
+
+ {aprData?.netSupplyApr.times(100).toFixed(2)}% +
+
+
+
+
+
diff --git a/apps/frontend/src/components/MarketsView/MarketTableRow.tsx b/apps/frontend/src/components/MarketsView/MarketTableRow.tsx index d7881b2f..c7fa0677 100644 --- a/apps/frontend/src/components/MarketsView/MarketTableRow.tsx +++ b/apps/frontend/src/components/MarketsView/MarketTableRow.tsx @@ -2,12 +2,11 @@ import { TableCell, TableRow } from '@/components/ui/table'; import { - useBorrowRate, + useApr, useCollateralConfigurations, useMarketBasics, useMarketConfiguration, usePrice, - useSupplyRate, useTotalCollateral, useUtilization, } from '@/hooks'; @@ -15,21 +14,27 @@ import { SYMBOL_TO_ICON, SYMBOL_TO_NAME, formatUnits, - getBorrowApr, getFormattedPrice, - getSupplyApr, } from '@/utils'; import BigNumber from 'bignumber.js'; import Image from 'next/image'; import type React from 'react'; import { appConfig } from '@/configs'; +import { cn } from '@/lib/utils'; import { useRouter } from 'next/navigation'; import { useMemo } from 'react'; import SWAY from '/public/tokens/sway.svg?url'; import { CircularProgressBar } from '../CircularProgressBar'; import { type Collateral, CollateralIcons } from '../CollateralIcons'; +import { Line } from '../Line'; import { Skeleton } from '../ui/skeleton'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from '../ui/tooltip'; const SkeletonRow = ( @@ -69,10 +74,7 @@ export const MarketTableRow = ({ const { data: marketConfiguration } = useMarketConfiguration(); const { data: utilization } = useUtilization(marketName); - const { data: borrowRate } = useBorrowRate(marketName); - const { data: supplyRate } = useSupplyRate(marketName); - const borrowApr = useMemo(() => getBorrowApr(borrowRate), [borrowRate]); - const supplyApr = useMemo(() => getSupplyApr(supplyRate), [supplyRate]); + const { data: aprData, isPending: isAprPending } = useApr(); const { data: collateralConfigurations, @@ -159,11 +161,89 @@ export const MarketTableRow = ({ }
- -
{supplyApr}
+ + + + any }) => e.preventDefault()} + > +
{aprData?.netSupplyApr.times(100).toFixed(2)}%
+
+ any; + }) => e.preventDefault()} + > +
+
+ Net Earn APY +
+
+
+
Supply APY
+
{aprData?.supplyBaseApr.times(100).toFixed(2)}%
+
+
+
Reward APY
+
{aprData?.supplyRewardApr.times(100).toFixed(2)}%
+
+
+ +
+
Net Supply APY
+
{aprData?.netSupplyApr.times(100).toFixed(2)}%
+
+
+
+
+
- -
{borrowApr}
+ + + + any }) => e.preventDefault()} + > +
{aprData?.netBorrowApr.times(100).toFixed(2)}%
+
+ any; + }) => e.preventDefault()} + > +
+
+ Net Borrow APY +
+
+
+
Borrow APY
+
{aprData?.borrowBaseApr.times(100).toFixed(2)}%
+
+
+
Reward APY
+
{aprData?.borrowRewardApr.times(100).toFixed(2)}%
+
+
+ +
+
Net Borrow APY
+
{aprData?.netBorrowApr.times(100).toFixed(2)}%
+
+
+
+
+
{getFormattedPrice( diff --git a/apps/frontend/src/components/Navbar/Points.tsx b/apps/frontend/src/components/Navbar/Points.tsx index 2534443e..129db120 100644 --- a/apps/frontend/src/components/Navbar/Points.tsx +++ b/apps/frontend/src/components/Navbar/Points.tsx @@ -4,7 +4,6 @@ import { PopoverTrigger, } from '@/components/ui/popover'; import { useUser } from '@/hooks'; -import { useFuelPoints } from '@/hooks/useFuelPoints'; import { cn } from '@/lib/utils'; import { useIsConnected } from '@fuels/react'; import { Trophy } from 'lucide-react'; @@ -26,8 +25,6 @@ export const Points = () => { const { isConnected } = useIsConnected(); - const { data: fuelPoints } = useFuelPoints(); - return ( { {isConnected ? (user ? user.points : '0') : 'Connect Wallet'}
-
-
- Fuel Points - -
- - {isConnected ? fuelPoints : 'Connect Wallet'} - -