Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,19 @@ export const CreateLoanForm = <ChainId extends IChainId>({
const network = networks[chainId]
const [preset, setPreset] = useBorrowPreset<BorrowPreset>(BorrowPreset.Safe)
const {
form,
values,
onSubmit,
params,
isPending,
onSubmit,
maxTokenValues,
params,
form,
collateralToken,
borrowToken,
collateralToken,
isCreated,
creationError,
txHash,
formErrors,
isApproved,
formErrors,
} = useCreateLoanForm({ market, network, preset, onCreated })
const setRange = useCallback(
(range: number) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { Token } from '@/llamalend/features/borrow/types'
import { useLoanToValueFromUserState } from '@/llamalend/features/manage-loan/hooks/useLoanToValueFromUserState'
import { useHealthQueries } from '@/llamalend/hooks/useHealthQueries'
import type { NetworkDict } from '@/llamalend/llamalend.types'
import { useMarketFutureRates } from '@/llamalend/queries/market-future-rates.query'
import { useMarketRates } from '@/llamalend/queries/market-rates'
import { useRepayBands } from '@/llamalend/queries/repay/repay-bands.query'
import { useRepayExpectedBorrowed } from '@/llamalend/queries/repay/repay-expected-borrowed.query'
import { useRepayEstimateGas } from '@/llamalend/queries/repay/repay-gas-estimate.query'
import { useRepayHealth } from '@/llamalend/queries/repay/repay-health.query'
import { useRepayPriceImpact } from '@/llamalend/queries/repay/repay-price-impact.query'
import { useRepayPrices } from '@/llamalend/queries/repay/repay-prices.query'
import { getUserHealthOptions } from '@/llamalend/queries/user-health.query'
import { useUserState } from '@/llamalend/queries/user-state.query'
import type { RepayParams } from '@/llamalend/queries/validation/manage-loan.types'
import type { RepayForm } from '@/llamalend/queries/validation/manage-loan.validation'
import { LoanInfoAccordion } from '@/llamalend/widgets/manage-loan/LoanInfoAccordion'
import type { IChainId } from '@curvefi/llamalend-api/lib/interfaces'
import { useSwitch } from '@ui-kit/hooks/useSwitch'
import { q } from '@ui-kit/types/util'
import { decimal, Decimal } from '@ui-kit/utils'

export function RepayLoanInfoAccordion<ChainId extends IChainId>({
params,
values: { slippage, userCollateral, userBorrowed },
collateralToken,
borrowToken,
networks,
onSlippageChange,
hasLeverage,
}: {
params: RepayParams<ChainId>
values: RepayForm
collateralToken: Token | undefined
borrowToken: Token | undefined
networks: NetworkDict<ChainId>
onSlippageChange: (newSlippage: Decimal) => void
hasLeverage: boolean | undefined
}) {
const [isOpen, , , toggle] = useSwitch(false)
const userState = q(useUserState(params, isOpen))
return (
<LoanInfoAccordion
isOpen={isOpen}
toggle={toggle}
bands={q(useRepayBands(params, isOpen))}
gas={useRepayEstimateGas(networks, params, isOpen)}
health={q(useRepayHealth(params, isOpen))}
prevHealth={useHealthQueries((isFull) => getUserHealthOptions({ ...params, isFull }))}
prevRates={q(useMarketRates(params, isOpen))}
rates={q(useMarketFutureRates(params, isOpen))}
debt={{
...userState,
data: userState?.data?.debt && decimal(+userState.data.debt - +(userBorrowed ?? 0)),
tokenSymbol: borrowToken?.symbol,
}}
prevDebt={{ ...userState, data: userState?.data?.debt }}
prices={q(useRepayPrices(params, isOpen))}
// routeImage={q(useRepayRouteImage(params, isOpen))}
loanToValue={useLoanToValueFromUserState(
{
chainId: params.chainId,
marketId: params.marketId,
userAddress: params.userAddress,
collateralToken,
borrowToken,
collateralDelta: userCollateral && `${-+userCollateral}`,
},
isOpen,
)}
leverage={{
enabled: !!hasLeverage,
expectedBorrowed: useRepayExpectedBorrowed(params, isOpen),
priceImpact: useRepayPriceImpact(params, isOpen),
slippage,
onSlippageChange,
collateralSymbol: collateralToken?.symbol,
}}
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,17 @@ export const AddCollateralForm = <ChainId extends IChainId>({
bands={bands}
prices={prices}
rates={marketRates}
loanToValue={useLoanToValueFromUserState({
chainId: params.chainId!,
marketId: params.marketId,
userAddress: params.userAddress,
collateralToken,
borrowToken,
enabled: isOpen,
collateralDelta: values.userCollateral,
})}
loanToValue={useLoanToValueFromUserState(
{
chainId: params.chainId,
marketId: params.marketId,
userAddress: params.userAddress,
collateralToken,
borrowToken,
collateralDelta: values.userCollateral,
},
isOpen,
)}
gas={gas}
/>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,20 @@ export const RemoveCollateralForm = <ChainId extends IChainId>({
bands={bands}
prices={prices}
rates={marketRates}
loanToValue={useLoanToValueFromUserState({
chainId: params.chainId!,
marketId: params.marketId,
userAddress: params.userAddress,
collateralToken,
borrowToken,
enabled: isOpen,
collateralDelta:
values.userCollateral != null
? (`-${values.userCollateral}` as unknown as import('@ui-kit/utils').Decimal)
: undefined,
})}
loanToValue={useLoanToValueFromUserState(
{
chainId: params.chainId,
marketId: params.marketId,
userAddress: params.userAddress,
collateralToken,
borrowToken,
collateralDelta:
values.userCollateral != null
? (`-${values.userCollateral}` as unknown as import('@ui-kit/utils').Decimal)
: undefined,
},
isOpen,
)}
gas={gas}
/>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { useLoanToValueFromUserState } from '@/llamalend/features/manage-loan/hooks/useLoanToValueFromUserState'
import { RepayLoanInfoAccordion } from '@/llamalend/features/borrow/components/RepayLoanInfoAccordion'
import { setValueOptions } from '@/llamalend/features/borrow/react-form.utils'
import { hasDeleverage, hasLeverage } from '@/llamalend/llama.utils'
import type { LlamaMarketTemplate, NetworkDict } from '@/llamalend/llamalend.types'
import type { RepayOptions } from '@/llamalend/mutations/repay.mutation'
import { useMarketRates } from '@/llamalend/queries/market-rates'
import { LoanFormAlerts } from '@/llamalend/widgets/manage-loan/LoanFormAlerts'
import { LoanFormTokenInput } from '@/llamalend/widgets/manage-loan/LoanFormTokenInput'
import { LoanFormWrapper } from '@/llamalend/widgets/manage-loan/LoanFormWrapper'
import { LoanInfoAccordion } from '@/llamalend/widgets/manage-loan/LoanInfoAccordion'
import type { IChainId } from '@curvefi/llamalend-api/lib/interfaces'
import { notFalsy } from '@curvefi/prices-api/objects.util'
import Button from '@mui/material/Button'
import Checkbox from '@mui/material/Checkbox'
import FormControlLabel from '@mui/material/FormControlLabel'
import Stack from '@mui/material/Stack'
import { useSwitch } from '@ui-kit/hooks/useSwitch'
import { t } from '@ui-kit/lib/i18n'
import { InputDivider } from '../../../widgets/InputDivider'
import { useRepayForm } from '../hooks/useRepayForm'
Expand All @@ -22,7 +24,7 @@ export const RepayForm = <ChainId extends IChainId>({
onRepaid,
fromCollateral,
fromWallet,
fromBorrowed,
fromBorrowed: showUserBorrowed,
}: {
market: LlamaMarketTemplate | undefined
networks: NetworkDict<ChainId>
Expand All @@ -34,65 +36,49 @@ export const RepayForm = <ChainId extends IChainId>({
fromBorrowed?: boolean
}) => {
const network = networks[chainId]
const [isOpen, , , toggle] = useSwitch(false)

const {
form,
values,
params,
isPending,
onSubmit,
action,
bands,
health,
prices,
gas,
isDisabled,
isFull,
formErrors,
collateralToken,
borrowToken,
params,
values,
collateralToken,
isRepaid,
repayError,
txHash,
expectedBorrowed,
routeImage,
priceImpact,
isApproved,
formErrors,
isFull,
} = useRepayForm({
market,
network,
networks,
enabled,
onRepaid,
})

const marketRates = useMarketRates(params, isOpen)

const { withdrawEnabled: withdrawEnabled } = values
const showStateCollateral = market && hasLeverage(market) && fromCollateral
const showUserCollateral = market && (hasLeverage(market) || hasDeleverage(market)) && fromWallet
return (
<LoanFormWrapper // todo: prevHealth, prevRates, debt, prevDebt
<LoanFormWrapper
{...form}
onSubmit={onSubmit}
infoAccordion={
<LoanInfoAccordion
isOpen={isOpen}
toggle={toggle}
health={health}
bands={bands}
prices={prices}
rates={marketRates}
loanToValue={useLoanToValueFromUserState({
chainId,
marketId: params.marketId,
userAddress: params.userAddress,
collateralToken,
borrowToken,
enabled: isOpen,
expectedBorrowed: expectedBorrowed.data?.totalBorrowed,
})}
gas={gas}
<RepayLoanInfoAccordion
params={params}
values={values}
collateralToken={collateralToken}
borrowToken={borrowToken}
networks={networks}
onSlippageChange={(value) => form.setValue('slippage', value, setValueOptions)}
hasLeverage={market && hasLeverage(market)}
/>
}
>
<Stack divider={<InputDivider />}>
{fromCollateral && (
<Stack divider={withdrawEnabled ? <InputDivider /> : undefined}>
{showStateCollateral && (
<LoanFormTokenInput
label={t`From collateral (position)`}
token={collateralToken}
Expand All @@ -103,7 +89,7 @@ export const RepayForm = <ChainId extends IChainId>({
network={network}
/>
)}
{fromWallet && (
{showUserCollateral && (
<LoanFormTokenInput
label={t`From collateral (wallet)`}
token={collateralToken}
Expand All @@ -114,7 +100,7 @@ export const RepayForm = <ChainId extends IChainId>({
network={network}
/>
)}
{fromBorrowed && (
{showUserBorrowed && (
<LoanFormTokenInput
label={t`From borrowed token`}
token={borrowToken}
Expand All @@ -127,17 +113,32 @@ export const RepayForm = <ChainId extends IChainId>({
)}
</Stack>

<FormControlLabel
control={
<Checkbox
checked={withdrawEnabled}
onChange={(e) => form.setValue('withdrawEnabled', e.target.checked, setValueOptions)}
/>
}
label={t`Repay & Withdraw`}
/>
<Button type="submit" loading={isPending || !market} disabled={isDisabled} data-testid="repay-submit-button">
{isPending ? t`Processing...` : isFull.data ? t`Repay full` : t`Repay`}
{isPending
? t`Processing...`
: notFalsy(isApproved?.data && t`Approve`, isFull.data ? t`Repay full` : t`Repay`).join(' & ')}
</Button>

<LoanFormAlerts
isSuccess={action.isSuccess}
error={action.error}
isSuccess={isRepaid}
error={repayError}
txHash={txHash}
formErrors={formErrors}
network={network}
handledErrors={['stateCollateral', 'userCollateral', 'userBorrowed']}
handledErrors={notFalsy(
showStateCollateral && 'stateCollateral',
showUserCollateral && 'userCollateral',
showUserBorrowed && 'userBorrowed',
)}
successTitle={t`Loan repaid`}
/>
</LoanFormWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import type { Decimal } from '@ui-kit/utils'
import type { Token } from '../../borrow/types'

type Params<ChainId extends IChainId> = {
chainId: ChainId
chainId: ChainId | null | undefined
marketId: string | null | undefined
userAddress: Address | null | undefined
collateralToken: Token | undefined
borrowToken: Token | undefined
enabled: boolean
/**
* Net change applied to on-chain collateral (positive = adding, negative = removing).
* TODO: use expectedCollateral from llamalend-js, currently being implemented by @0xPearce
Expand All @@ -29,16 +28,10 @@ type Params<ChainId extends IChainId> = {
* It uses the generic userState query so it can be reused across
* add-collateral, remove-collateral and repay flows.
*/
export const useLoanToValueFromUserState = <ChainId extends IChainId>({
chainId,
marketId,
userAddress,
collateralToken,
borrowToken,
enabled,
collateralDelta,
expectedBorrowed,
}: Params<ChainId>) => {
export const useLoanToValueFromUserState = <ChainId extends IChainId>(
{ chainId, marketId, userAddress, collateralToken, borrowToken, collateralDelta, expectedBorrowed }: Params<ChainId>,
enabled: boolean,
) => {
const {
data: userState,
isLoading: isUserLoading,
Expand Down
Loading
Loading