From 60e1a2c4f4ad252c4bc6ac29fd7d59605ab61134 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Thu, 30 Jan 2025 10:22:44 +0000 Subject: [PATCH] Show latest loan debt (#795) --- .../src/comps/Positions/PositionCardLoan.tsx | 8 ++-- frontend/app/src/liquity-utils.ts | 42 ++++++++++++++++++- .../app/src/screens/LoanScreen/LoanScreen.tsx | 11 ++--- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/frontend/app/src/comps/Positions/PositionCardLoan.tsx b/frontend/app/src/comps/Positions/PositionCardLoan.tsx index cc1bd464c..6108d5993 100644 --- a/frontend/app/src/comps/Positions/PositionCardLoan.tsx +++ b/frontend/app/src/comps/Positions/PositionCardLoan.tsx @@ -1,7 +1,7 @@ import type { PositionLoanCommitted } from "@/src/types"; import { LoanStatusTag } from "@/src/comps/Tag/LoanStatusTag"; -import { getPrefixedTroveId } from "@/src/liquity-utils"; +import { getPrefixedTroveId, useLoan } from "@/src/liquity-utils"; import { useStoredState } from "@/src/services/StoredState"; import { PositionCardBorrow } from "./PositionCardBorrow"; import { PositionCardLeverage } from "./PositionCardLeverage"; @@ -21,10 +21,7 @@ export function PositionCardLoan( ) { const storedState = useStoredState(); - // only works for existing troves - if (!props.troveId) { - return null; - } + const loan = useLoan(props.collIndex, props.troveId); const prefixedTroveId = getPrefixedTroveId(props.collIndex, props.troveId); const loanMode = storedState.loanModes[prefixedTroveId] ?? props.type; @@ -34,6 +31,7 @@ export function PositionCardLoan( return ( : props.status === "redeemed" diff --git a/frontend/app/src/liquity-utils.ts b/frontend/app/src/liquity-utils.ts index db95317a5..5762141d5 100644 --- a/frontend/app/src/liquity-utils.ts +++ b/frontend/app/src/liquity-utils.ts @@ -6,14 +6,14 @@ import type { Config as WagmiConfig } from "wagmi"; import { DATA_REFRESH_INTERVAL, INTEREST_RATE_INCREMENT, INTEREST_RATE_MAX, INTEREST_RATE_MIN } from "@/src/constants"; import { getCollateralContract, getContracts, getProtocolContract } from "@/src/contracts"; -import { dnum18, jsonStringifyWithDnum } from "@/src/dnum-utils"; -import { dnumOrNull } from "@/src/dnum-utils"; +import { dnum18, dnumOrNull, jsonStringifyWithDnum } from "@/src/dnum-utils"; import { CHAIN_BLOCK_EXPLORER, LIQUITY_STATS_URL } from "@/src/env"; import { getCollGainFromSnapshots, useContinuousBoldGains } from "@/src/liquity-stability-pool"; import { useGovernanceStats, useGovernanceUser, useInterestRateBrackets, + useLoanById, useStabilityPool, useStabilityPoolDeposit, useStabilityPoolEpochScale, @@ -610,3 +610,41 @@ export function useLiquityStats() { enabled: Boolean(LIQUITY_STATS_URL), }); } + +export function useLatestTroveData(collIndex: CollIndex, troveId: TroveId) { + const TroveManager = getCollateralContract(collIndex, "TroveManager"); + if (!TroveManager) { + throw new Error(`Invalid collateral index: ${collIndex}`); + } + return useReadContract({ + ...TroveManager, + functionName: "getLatestTroveData", + args: [BigInt(troveId)], + query: { + refetchInterval: DATA_REFRESH_INTERVAL, + }, + }); +} + +export function useLoanLiveDebt(collIndex: CollIndex, troveId: TroveId) { + const latestTroveData = useLatestTroveData(collIndex, troveId); + return { + ...latestTroveData, + data: latestTroveData.data?.entireDebt ?? null, + }; +} + +export function useLoan(collIndex: CollIndex, troveId: TroveId) { + const liveDebt = useLoanLiveDebt(collIndex, troveId); + const loan = useLoanById(getPrefixedTroveId(collIndex, troveId)); + if (liveDebt.data && loan.data) { + return { + ...loan, + data: { + ...loan.data, + borrowed: dnum18(liveDebt.data), + }, + }; + } + return loan; +} diff --git a/frontend/app/src/screens/LoanScreen/LoanScreen.tsx b/frontend/app/src/screens/LoanScreen/LoanScreen.tsx index 0385a88b1..d10dcede0 100644 --- a/frontend/app/src/screens/LoanScreen/LoanScreen.tsx +++ b/frontend/app/src/screens/LoanScreen/LoanScreen.tsx @@ -8,12 +8,11 @@ import content from "@/src/content"; import { getCollateralContract } from "@/src/contracts"; import { dnum18 } from "@/src/dnum-utils"; import { fmtnum } from "@/src/formatting"; -import { getCollToken, getPrefixedTroveId, parsePrefixedTroveId } from "@/src/liquity-utils"; +import { getCollToken, getPrefixedTroveId, parsePrefixedTroveId, useLoan, useLoanLiveDebt } from "@/src/liquity-utils"; import { useAccount } from "@/src/services/Ethereum"; import { usePrice } from "@/src/services/Prices"; import { useStoredState } from "@/src/services/StoredState"; import { useTransactionFlow } from "@/src/services/TransactionFlow"; -import { useLoanById } from "@/src/subgraph-hooks"; import { isPrefixedtroveId } from "@/src/types"; import { css } from "@/styled-system/css"; import { Button, InfoTooltip, Tabs, TokenIcon } from "@liquity2/uikit"; @@ -50,15 +49,17 @@ export function LoanScreen() { if (!isPrefixedtroveId(paramPrefixedId)) { notFound(); } + const { troveId, collIndex } = parsePrefixedTroveId(paramPrefixedId); - const loan = useLoanById(paramPrefixedId); + const loan = useLoan(collIndex, troveId); const loanMode = storedState.loanModes[paramPrefixedId] ?? loan.data?.type ?? "borrow"; const collToken = getCollToken(loan.data?.collIndex ?? null); const collPriceUsd = usePrice(collToken?.symbol ?? null); - const { troveId } = parsePrefixedTroveId(paramPrefixedId); - const fullyRedeemed = loan.data && loan.data.status === "redeemed" && dn.eq(loan.data.borrowed, 0); + const fullyRedeemed = loan.data + && loan.data.status === "redeemed" + && dn.eq(loan.data.borrowed, 0); const loadingState = match([loan, collPriceUsd.data ?? null]) .returnType()