fix max numbers shown in modals and swap form

This commit is contained in:
tjs 2022-08-20 20:09:36 -04:00
parent 52064b7627
commit 501510eb43
16 changed files with 127 additions and 92 deletions

View File

@ -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>

View File

@ -40,7 +40,7 @@ const AccountNameModal = ({ isOpen, onClose }: ModalProps) => {
txid: e?.signature,
type: 'error',
})
console.log(e)
console.error(e)
}
}

View File

@ -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}

View File

@ -73,7 +73,7 @@ const CreateAccountModal = ({
txid: e?.signature,
type: 'error',
})
console.log(e)
console.error(e)
}
}

View File

@ -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>

View File

@ -91,7 +91,7 @@ const UserSetupModal = ({ isOpen, onClose }: ModalProps) => {
txid: e?.signature,
type: 'error',
})
console.log(e)
console.error(e)
}
}, [accountName, wallet, t])

View File

@ -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>

View File

@ -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">

View File

@ -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,

View File

@ -30,8 +30,6 @@ const SwapSettings = ({ onClose }: { onClose: () => void }) => {
})
}
console.log('slippage', slippage)
return (
<>
<h3 className="mb-3">{t('settings')}</h3>

View File

@ -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])

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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
})