fix max numbers shown in modals and swap form
This commit is contained in:
parent
52064b7627
commit
501510eb43
|
@ -32,11 +32,11 @@ const ActionTokenItem = ({
|
|||
|
||||
return (
|
||||
<button
|
||||
className="default-transition flex w-full rounded-md border border-th-bkg-4 px-4 py-3 disabled:cursor-not-allowed disabled:opacity-60 md:hover:border-th-fgd-4 md:disabled:hover:border-th-bkg-4"
|
||||
className="default-transition grid w-full auto-cols-fr grid-flow-col rounded-md border border-th-bkg-4 px-4 py-3 disabled:cursor-not-allowed disabled:opacity-60 md:hover:border-th-fgd-4 md:disabled:hover:border-th-bkg-4"
|
||||
onClick={() => onSelect(name)}
|
||||
disabled={customValue <= 0}
|
||||
>
|
||||
<div className="flex w-1/5 items-center">
|
||||
<div className="flex items-center">
|
||||
<div className="mr-2.5 flex flex-shrink-0 items-center">
|
||||
<Image
|
||||
alt=""
|
||||
|
@ -48,20 +48,20 @@ const ActionTokenItem = ({
|
|||
<p className="text-th-fgd-1">{name}</p>
|
||||
</div>
|
||||
{showDepositRates ? (
|
||||
<div className="w-2/5 text-right">
|
||||
<div className="text-right">
|
||||
<p className="text-th-green">
|
||||
{formatDecimal(bank.getDepositRate().toNumber(), 2)}%
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
{showBorrowRates ? (
|
||||
<div className="w-2/5 text-right">
|
||||
<div className="text-right">
|
||||
<p className="text-th-red">
|
||||
{formatDecimal(bank.getBorrowRate().toNumber(), 2)}%
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="w-2/5 text-right">
|
||||
<div className="text-right">
|
||||
<p className="text-th-fgd-1">{formatDecimal(customValue)}</p>
|
||||
</div>
|
||||
</button>
|
||||
|
|
|
@ -40,7 +40,7 @@ const AccountNameModal = ({ isOpen, onClose }: ModalProps) => {
|
|||
txid: e?.signature,
|
||||
type: 'error',
|
||||
})
|
||||
console.log(e)
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { toUiDecimals } from '@blockworks-foundation/mango-v4'
|
||||
import {
|
||||
Bank,
|
||||
Group,
|
||||
MangoAccount,
|
||||
toUiDecimals,
|
||||
} from '@blockworks-foundation/mango-v4'
|
||||
import { ChevronDownIcon } from '@heroicons/react/solid'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Image from 'next/image'
|
||||
|
@ -7,7 +12,7 @@ import mangoStore from '../../store/mangoStore'
|
|||
import { ModalProps } from '../../types/modal'
|
||||
import { INPUT_TOKEN_DEFAULT } from '../../utils/constants'
|
||||
import { notify } from '../../utils/notifications'
|
||||
import { formatFixedDecimals } from '../../utils/numbers'
|
||||
import { floorToDecimal, formatFixedDecimals } from '../../utils/numbers'
|
||||
import ActionTokenList from '../account/ActionTokenList'
|
||||
import ButtonGroup from '../forms/ButtonGroup'
|
||||
import Input from '../forms/Input'
|
||||
|
@ -17,7 +22,30 @@ import HealthImpact from '../shared/HealthImpact'
|
|||
import Loading from '../shared/Loading'
|
||||
import Modal from '../shared/Modal'
|
||||
import { EnterBottomExitBottom, FadeInFadeOut } from '../shared/Transitions'
|
||||
import { BorrowLeverageSlider } from '../swap/LeverageSlider'
|
||||
// import { BorrowLeverageSlider } from '../swap/LeverageSlider'
|
||||
|
||||
const getMaxBorrowForToken = (
|
||||
group: Group,
|
||||
mangoAccount: MangoAccount,
|
||||
bank: Bank
|
||||
) => {
|
||||
const vaultBalance = floorToDecimal(
|
||||
bank.uiDeposits() - bank.uiBorrows(),
|
||||
bank.mintDecimals
|
||||
)
|
||||
const currentBalance = mangoAccount?.getTokenBalanceUi(bank) || 0
|
||||
const maxBorrow = toUiDecimals(
|
||||
mangoAccount?.getMaxWithdrawWithBorrowForToken(group, bank.mint).toNumber(),
|
||||
bank.mintDecimals
|
||||
)
|
||||
const maxBorrowWithBalance =
|
||||
currentBalance > 0 ? maxBorrow + currentBalance : maxBorrow
|
||||
|
||||
return Math.min(
|
||||
vaultBalance,
|
||||
floorToDecimal(maxBorrowWithBalance, bank.mintDecimals)
|
||||
)
|
||||
}
|
||||
|
||||
interface BorrowModalProps {
|
||||
token?: string
|
||||
|
@ -56,12 +84,9 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
|
||||
const tokenMax = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
if (!group || !bank) return 0
|
||||
const amount = mangoAccount
|
||||
?.getMaxWithdrawWithBorrowForToken(group, bank.mint)
|
||||
.toNumber()
|
||||
return amount && amount > 0 ? toUiDecimals(amount, bank.mintDecimals) : 0
|
||||
}, [mangoAccount, bank, selectedToken])
|
||||
if (!group || !bank || !mangoAccount) return 0
|
||||
return getMaxBorrowForToken(group, mangoAccount, bank)
|
||||
}, [mangoAccount, bank])
|
||||
|
||||
const setMax = useCallback(() => {
|
||||
setInputAmount(tokenMax.toString())
|
||||
|
@ -69,11 +94,12 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
|
||||
const handleSizePercentage = useCallback(
|
||||
(percentage: string) => {
|
||||
if (!bank) return
|
||||
setSizePercentage(percentage)
|
||||
const amount = (Number(percentage) / 100) * (tokenMax || 0)
|
||||
setInputAmount(amount.toString())
|
||||
setInputAmount(floorToDecimal(amount, bank.mintDecimals).toString())
|
||||
},
|
||||
[tokenMax]
|
||||
[tokenMax, bank]
|
||||
)
|
||||
|
||||
const handleSelectToken = (token: string) => {
|
||||
|
@ -103,8 +129,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
})
|
||||
actions.reloadAccount()
|
||||
} catch (e: any) {
|
||||
console.log(e)
|
||||
|
||||
console.error(e)
|
||||
notify({
|
||||
title: 'Transaction failed',
|
||||
description: e.message,
|
||||
|
@ -122,17 +147,8 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
return group?.banksMapByName
|
||||
? Array.from(group?.banksMapByName, ([key, value]) => {
|
||||
const bank = value[0]
|
||||
const amount = mangoAccount
|
||||
?.getMaxWithdrawWithBorrowForToken(group, bank.mint)
|
||||
.toNumber()
|
||||
return {
|
||||
key,
|
||||
value,
|
||||
maxAmount:
|
||||
amount && amount > 0
|
||||
? toUiDecimals(amount, bank.mintDecimals)
|
||||
: 0,
|
||||
}
|
||||
const maxAmount = getMaxBorrowForToken(group, mangoAccount, bank)
|
||||
return { key, value, maxAmount }
|
||||
})
|
||||
: []
|
||||
}
|
||||
|
@ -146,14 +162,14 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
show={showTokenList}
|
||||
>
|
||||
<h2 className="mb-4 text-center">{t('select-token')}</h2>
|
||||
<div className="flex px-4 pb-2">
|
||||
<div className="w-1/5">
|
||||
<div className="grid auto-cols-fr grid-flow-col px-4 pb-2">
|
||||
<div className="">
|
||||
<p className="text-xs">{t('token')}</p>
|
||||
</div>
|
||||
<div className="w-2/5 text-right">
|
||||
<div className="text-right">
|
||||
<p className="text-xs">{t('borrow-rate')}</p>
|
||||
</div>
|
||||
<div className="w-2/5 text-right">
|
||||
<div className="text-right">
|
||||
<p className="whitespace-nowrap text-xs">{t('max-borrow')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -177,9 +193,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
<span className="mr-1 font-normal text-th-fgd-3">
|
||||
{t('max')}:
|
||||
</span>
|
||||
<span className="mx-1 text-th-fgd-1 underline">
|
||||
{formatFixedDecimals(tokenMax)}
|
||||
</span>
|
||||
<span className="mx-1 text-th-fgd-1 underline">{tokenMax}</span>
|
||||
</LinkButton>
|
||||
</div>
|
||||
<div className="col-span-1 rounded-lg rounded-r-none border border-r-0 border-th-bkg-4 bg-th-bkg-1">
|
||||
|
@ -222,7 +236,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
unit="%"
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-2 mt-4">
|
||||
{/* <div className="col-span-2 mt-4">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<p className="text-th-fgd-3">{t('leverage')}</p>
|
||||
<p className="text-th-fgd-3">0.00x</p>
|
||||
|
@ -232,7 +246,7 @@ function BorrowModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
tokenMax={tokenMax}
|
||||
onChange={(x) => setInputAmount(x)}
|
||||
/>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
<HealthImpact
|
||||
mintPk={bank!.mint}
|
||||
|
|
|
@ -73,7 +73,7 @@ const CreateAccountModal = ({
|
|||
txid: e?.signature,
|
||||
type: 'error',
|
||||
})
|
||||
console.log(e)
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,6 @@ function DepositModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
|
||||
const bank = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
console.log('1: ', selectedToken)
|
||||
|
||||
return group?.banksMapByName.get(selectedToken)![0]
|
||||
}, [selectedToken])
|
||||
|
||||
|
@ -145,7 +143,7 @@ function DepositModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
}
|
||||
|
||||
const banks = useMemo(() => {
|
||||
return group?.banksMapByName
|
||||
const banks = group?.banksMapByName
|
||||
? Array.from(group?.banksMapByName, ([key, value]) => {
|
||||
const walletBalance = walletBalanceForToken(walletTokens, key)
|
||||
return {
|
||||
|
@ -158,6 +156,7 @@ function DepositModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
}
|
||||
})
|
||||
: []
|
||||
return banks.filter((b) => b.walletBalance > 0)
|
||||
}, [group?.banksMapByName, walletTokens])
|
||||
|
||||
return (
|
||||
|
@ -168,14 +167,14 @@ function DepositModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
show={showTokenList}
|
||||
>
|
||||
<h2 className="mb-4 text-center">{t('select-token')}</h2>
|
||||
<div className="flex px-4 pb-2">
|
||||
<div className="w-1/5">
|
||||
<div className="grid auto-cols-fr grid-flow-col px-4 pb-2">
|
||||
<div className="">
|
||||
<p className="text-xs">{t('token')}</p>
|
||||
</div>
|
||||
<div className="w-2/5 text-right">
|
||||
<div className="text-right">
|
||||
<p className="text-xs">{t('deposit-rate')}</p>
|
||||
</div>
|
||||
<div className="w-2/5 text-right">
|
||||
<div className="text-right">
|
||||
<p className="whitespace-nowrap text-xs">{t('wallet-balance')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -91,7 +91,7 @@ const UserSetupModal = ({ isOpen, onClose }: ModalProps) => {
|
|||
txid: e?.signature,
|
||||
type: 'error',
|
||||
})
|
||||
console.log(e)
|
||||
console.error(e)
|
||||
}
|
||||
}, [accountName, wallet, t])
|
||||
|
||||
|
|
|
@ -91,8 +91,7 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
})
|
||||
actions.reloadAccount()
|
||||
} catch (e: any) {
|
||||
console.log(e)
|
||||
|
||||
console.error(e)
|
||||
notify({
|
||||
title: 'Transaction failed',
|
||||
description: e.message,
|
||||
|
@ -110,9 +109,9 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
setShowTokenList(false)
|
||||
}
|
||||
|
||||
const banks = useMemo(() => {
|
||||
const withdrawBank = useMemo(() => {
|
||||
if (mangoAccount) {
|
||||
return group?.banksMapByName
|
||||
const banks = group?.banksMapByName
|
||||
? Array.from(group?.banksMapByName, ([key, value]) => {
|
||||
const accountBalance = mangoAccount?.getTokenBalanceUi(value[0])
|
||||
return {
|
||||
|
@ -122,6 +121,7 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
}
|
||||
})
|
||||
: []
|
||||
return banks.filter((b) => b.accountBalance > 0)
|
||||
}
|
||||
return []
|
||||
}, [mangoAccount, group?.banksMapByName])
|
||||
|
@ -134,16 +134,16 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
show={showTokenList}
|
||||
>
|
||||
<h2 className="mb-4 text-center">{t('select-token')}</h2>
|
||||
<div className="grid grid-cols-2 px-4 pb-2">
|
||||
<div className="col-span-1">
|
||||
<div className="grid auto-cols-fr grid-flow-col px-4 pb-2">
|
||||
<div className="">
|
||||
<p className="text-xs">{t('token')}</p>
|
||||
</div>
|
||||
<div className="col-span-1 flex justify-end">
|
||||
<div className="flex justify-end">
|
||||
<p className="text-xs">Account Balance</p>
|
||||
</div>
|
||||
</div>
|
||||
<ActionTokenList
|
||||
banks={banks}
|
||||
banks={withdrawBank}
|
||||
onSelect={handleSelectToken}
|
||||
sortByKey="accountBalance"
|
||||
/>
|
||||
|
@ -162,7 +162,7 @@ function WithdrawModal({ isOpen, onClose, token }: ModalCombinedProps) {
|
|||
onClick={() => handleSizePercentage('100')}
|
||||
>
|
||||
<span className="mr-1 font-normal text-th-fgd-3">
|
||||
{t('available-balance')}
|
||||
{t('account-balance')}
|
||||
</span>
|
||||
<span className="text-th-fgd-1 underline">{tokenMax}</span>
|
||||
</LinkButton>
|
||||
|
|
|
@ -6,7 +6,11 @@ import React, {
|
|||
useState,
|
||||
} from 'react'
|
||||
import { TransactionInstruction, PublicKey } from '@solana/web3.js'
|
||||
import { toNativeDecimals, toUiDecimals } from '@blockworks-foundation/mango-v4'
|
||||
import {
|
||||
HealthType,
|
||||
toNativeDecimals,
|
||||
toUiDecimals,
|
||||
} from '@blockworks-foundation/mango-v4'
|
||||
import { Jupiter, RouteInfo, TransactionFeeInfo } from '@jup-ag/core'
|
||||
import JSBI from 'jsbi'
|
||||
import Decimal from 'decimal.js'
|
||||
|
@ -117,27 +121,29 @@ const JupiterRouteInfo = ({
|
|||
return 'Unknown'
|
||||
|
||||
const simulatedHealthRatio = mangoAccount
|
||||
.simHealthRatioWithTokenPositionChanges(group, [
|
||||
{
|
||||
mintPk: new PublicKey(inputTokenInfo.address),
|
||||
tokenAmount:
|
||||
toNativeDecimals(
|
||||
amountIn.toNumber(),
|
||||
inputTokenInfo.decimals
|
||||
).toNumber() * -1,
|
||||
},
|
||||
{
|
||||
mintPk: new PublicKey(outputTokenInfo.address),
|
||||
tokenAmount: toNativeDecimals(
|
||||
amountOut,
|
||||
outputTokenInfo.decimals
|
||||
).toNumber(),
|
||||
},
|
||||
])
|
||||
.simHealthRatioWithTokenPositionChanges(
|
||||
group,
|
||||
[
|
||||
{
|
||||
mintPk: new PublicKey(inputTokenInfo.address),
|
||||
tokenAmount:
|
||||
toNativeDecimals(
|
||||
amountIn.toNumber(),
|
||||
inputTokenInfo.decimals
|
||||
).toNumber() * -1,
|
||||
},
|
||||
{
|
||||
mintPk: new PublicKey(outputTokenInfo.address),
|
||||
tokenAmount: toNativeDecimals(
|
||||
amountOut,
|
||||
outputTokenInfo.decimals
|
||||
).toNumber(),
|
||||
},
|
||||
],
|
||||
HealthType.maint
|
||||
)
|
||||
.toNumber()
|
||||
|
||||
// console.log('simulatedHealthRatio', simulatedHealthRatio)
|
||||
return simulatedHealthRatio > 100 ? 100 : simulatedHealthRatio
|
||||
return simulatedHealthRatio > 100 ? 100 : simulatedHealthRatio.toFixed(2)
|
||||
}, [mangoAccount, inputTokenInfo, outputTokenInfo, amountIn, amountOut])
|
||||
|
||||
const onSwap = async () => {
|
||||
|
@ -177,7 +183,7 @@ const JupiterRouteInfo = ({
|
|||
})
|
||||
await actions.reloadAccount()
|
||||
} catch (e: any) {
|
||||
console.log('Error swapping:', e)
|
||||
console.error('onSwap error: ', e)
|
||||
notify({
|
||||
title: 'Transaction failed',
|
||||
description: e.message,
|
||||
|
@ -218,7 +224,7 @@ const JupiterRouteInfo = ({
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mb-0.5 text-lg font-bold text-th-fgd-1">{`${amountIn} ${
|
||||
<p className="mb-0.5 text-lg text-th-fgd-1">{`${amountIn} ${
|
||||
inputTokenInfo!.name
|
||||
} for ${amountOut} ${outputTokenInfo.symbol}`}</p>
|
||||
<div className="flex items-center justify-end">
|
||||
|
|
|
@ -308,8 +308,15 @@ export const useTokenMax = () => {
|
|||
if (!group || !inputBank || !mangoAccount || !outputBank)
|
||||
return { amount: 0.0, decimals: 6, amountWithBorrow: 0.0 }
|
||||
|
||||
const amount = mangoAccount.getTokenBalanceUi(inputBank)
|
||||
const amountWithBorrow = mangoAccount
|
||||
const inputBankLiquidity = floorToDecimal(
|
||||
inputBank.uiDeposits() - inputBank.uiBorrows(),
|
||||
inputBank.mintDecimals
|
||||
)
|
||||
const maxWithdrawableAmount = Math.min(
|
||||
mangoAccount.getTokenBalanceUi(inputBank),
|
||||
inputBankLiquidity
|
||||
)
|
||||
const maxNativeAmountWithBorrow = mangoAccount
|
||||
?.getMaxSourceForTokenSwap(
|
||||
group,
|
||||
inputBank.mint,
|
||||
|
@ -317,14 +324,21 @@ export const useTokenMax = () => {
|
|||
0.98 - slippage / 10
|
||||
)
|
||||
.toNumber()
|
||||
const maxUiAmountWithBorrow = toUiDecimals(
|
||||
maxNativeAmountWithBorrow,
|
||||
inputBank.mintDecimals
|
||||
)
|
||||
|
||||
return {
|
||||
amount: amount > 0 ? floorToDecimal(amount, inputBank.mintDecimals) : 0,
|
||||
amount:
|
||||
maxWithdrawableAmount > 0
|
||||
? floorToDecimal(maxWithdrawableAmount, inputBank.mintDecimals)
|
||||
: 0,
|
||||
amountWithBorrow:
|
||||
amountWithBorrow > 0
|
||||
? floorToDecimal(
|
||||
toUiDecimals(amountWithBorrow, inputBank.mintDecimals),
|
||||
inputBank.mintDecimals
|
||||
maxUiAmountWithBorrow > 0
|
||||
? Math.min(
|
||||
floorToDecimal(maxUiAmountWithBorrow, inputBank.mintDecimals),
|
||||
inputBankLiquidity
|
||||
)
|
||||
: 0,
|
||||
decimals: inputBank.mintDecimals,
|
||||
|
|
|
@ -30,8 +30,6 @@ const SwapSettings = ({ onClose }: { onClose: () => void }) => {
|
|||
})
|
||||
}
|
||||
|
||||
console.log('slippage', slippage)
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3 className="mb-3">{t('settings')}</h3>
|
||||
|
|
|
@ -129,7 +129,7 @@ const SwapTokenChart: FunctionComponent<SwapTokenChartProps> = ({
|
|||
setChartData(chartData)
|
||||
setLoadChartData(false)
|
||||
} catch (e) {
|
||||
console.log('Unable to load chart data')
|
||||
console.warn('Unable to load chart data')
|
||||
}
|
||||
}, [baseTokenId, quoteTokenId, daysToShow])
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"account-closed": "Account Closed 👋",
|
||||
"account-balance": "Account Balance",
|
||||
"account-name": "Account Name",
|
||||
"account-name-desc": "Organize your accounts by giving them useful names",
|
||||
"account-update-failed": "Failed to update account",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"account-balance": "Account Balance",
|
||||
"account-closed": "Account Closed 👋",
|
||||
"account-name": "Account Name",
|
||||
"account-name-desc": "Organize your accounts by giving them useful names",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"account-balance": "Account Balance",
|
||||
"account-closed": "Account Closed 👋",
|
||||
"account-name": "Account Name",
|
||||
"account-name-desc": "Organize your accounts by giving them useful names",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"account-balance": "Account Balance",
|
||||
"account-closed": "Account Closed 👋",
|
||||
"account-name": "Account Name",
|
||||
"account-name-desc": "Organize your accounts by giving them useful names",
|
||||
|
|
|
@ -305,7 +305,7 @@ const mangoStore = create<MangoStore>(
|
|||
state.coingeckoPrices.loading = false
|
||||
})
|
||||
} catch (e) {
|
||||
console.log('ERORR: Unable to load Coingecko prices')
|
||||
console.warn('Unable to load Coingecko prices')
|
||||
set((state) => {
|
||||
state.coingeckoPrices.loading = false
|
||||
})
|
||||
|
@ -583,7 +583,7 @@ const mangoStore = create<MangoStore>(
|
|||
state.wallet.loadProfilePic = false
|
||||
})
|
||||
} catch (e) {
|
||||
console.log('Could not get profile picture', e)
|
||||
console.error('Could not get profile picture', e)
|
||||
set((state) => {
|
||||
state.wallet.loadProfilePic = false
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue