show token reduce state and hide non-borrow tokens from borrow

This commit is contained in:
saml33 2023-10-11 12:28:27 +11:00
parent b0d4b442ad
commit 8d15820b44
19 changed files with 131 additions and 112 deletions

View File

@ -16,6 +16,7 @@ import mangoStore from '@store/mangoStore'
import {
ACCOUNT_ACTION_MODAL_INNER_HEIGHT,
INPUT_TOKEN_DEFAULT,
TOKEN_REDUCE_ONLY_OPTIONS,
} from './../utils/constants'
import { notify } from './../utils/notifications'
import ActionTokenList from './account/ActionTokenList'
@ -65,6 +66,13 @@ function BorrowForm({ onSuccess, token }: BorrowFormProps) {
const { connected, publicKey } = useWallet()
const banks = useBanksWithBalances('maxBorrow')
const borrowBanks = useMemo(() => {
if (!banks || !banks.length) return []
return banks.filter(
(b) => b.bank.reduceOnly === TOKEN_REDUCE_ONLY_OPTIONS.DISABLED,
)
}, [banks])
const bank = useMemo(() => {
const group = mangoStore.getState().group
return group?.banksMapByName.get(selectedToken)?.[0]
@ -184,7 +192,7 @@ function BorrowForm({ onSuccess, token }: BorrowFormProps) {
</div>
</div>
<ActionTokenList
banks={banks}
banks={borrowBanks}
onSelect={handleSelectToken}
showBorrowRates
valueKey="maxBorrow"

View File

@ -28,7 +28,11 @@ import {
import DepositWithdrawModal from './modals/DepositWithdrawModal'
import BorrowRepayModal from './modals/BorrowRepayModal'
import { WRAPPED_SOL_MINT } from '@project-serum/serum/lib/token-instructions'
import { SHOW_ZERO_BALANCES_KEY, USDC_MINT } from 'utils/constants'
import {
SHOW_ZERO_BALANCES_KEY,
TOKEN_REDUCE_ONLY_OPTIONS,
USDC_MINT,
} from 'utils/constants'
import { PublicKey } from '@solana/web3.js'
import ActionsLinkButton from './account/ActionsLinkButton'
import FormatNumericValue from './shared/FormatNumericValue'
@ -41,6 +45,7 @@ import useLocalStorageState from 'hooks/useLocalStorageState'
import TokenLogo from './shared/TokenLogo'
import useHealthContributions from 'hooks/useHealthContributions'
import { useSortableData } from 'hooks/useSortableData'
import TableTokenName from './shared/TableTokenName'
type TableData = {
bank: Bank
@ -273,12 +278,7 @@ const TokenList = () => {
return (
<TrBody key={symbol}>
<Td>
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<p className="font-body">{symbol}</p>
</div>
<TableTokenName bank={bank} symbol={symbol} />
</Td>
<Td className="text-right">
<BankAmountWithValue
@ -394,14 +394,7 @@ const MobileTokenListItem = ({ data }: { data: TableData }) => {
className={`w-full border-t border-th-bkg-3 p-4 text-left first:border-t-0 focus:outline-none`}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="mr-2.5">
<TokenLogo bank={bank} />
</div>
<div>
<p className="mb-0.5 leading-none text-th-fgd-1">{symbol}</p>
</div>
</div>
<TableTokenName bank={bank} symbol={symbol} />
<div className="flex items-center space-x-2">
<div className="text-right">
<p className="font-mono text-sm text-th-fgd-2">
@ -643,11 +636,15 @@ export const ActionsMenu = ({
</p>
</div>
) : null}
<ActionsLinkButton
onClick={() => handleShowActionModals(bank.name, 'deposit')}
>
{t('deposit')}
</ActionsLinkButton>
{bank.reduceOnly !== TOKEN_REDUCE_ONLY_OPTIONS.ENABLED ? (
<ActionsLinkButton
onClick={() =>
handleShowActionModals(bank.name, 'deposit')
}
>
{t('deposit')}
</ActionsLinkButton>
) : null}
{balance < 0 ? (
<ActionsLinkButton
onClick={() => handleShowActionModals(bank.name, 'repay')}
@ -664,11 +661,15 @@ export const ActionsMenu = ({
{t('withdraw')}
</ActionsLinkButton>
) : null}
<ActionsLinkButton
onClick={() => handleShowActionModals(bank.name, 'borrow')}
>
{t('borrow')}
</ActionsLinkButton>
{bank.reduceOnly === TOKEN_REDUCE_ONLY_OPTIONS.DISABLED ? (
<ActionsLinkButton
onClick={() =>
handleShowActionModals(bank.name, 'borrow')
}
>
{t('borrow')}
</ActionsLinkButton>
) : null}
<ActionsLinkButton onClick={handleSwap}>
{t('swap')}
</ActionsLinkButton>

View File

@ -1,6 +1,6 @@
import { ArrowUpLeftIcon, ChevronDownIcon } from '@heroicons/react/20/solid'
import { useTranslation } from 'next-i18next'
import { useCallback, useState } from 'react'
import { useCallback, useMemo, useState } from 'react'
import { useViewport } from '../../hooks/useViewport'
import { formatNumericValue } from '../../utils/numbers'
import { breakpoints } from '../../utils/theme'
@ -13,7 +13,8 @@ import BankAmountWithValue from '@components/shared/BankAmountWithValue'
import useBanksWithBalances from 'hooks/useBanksWithBalances'
import { getAvailableToBorrow } from './YourBorrowsTable'
import { Disclosure, Transition } from '@headlessui/react'
import TokenLogo from '@components/shared/TokenLogo'
import { TOKEN_REDUCE_ONLY_OPTIONS } from 'utils/constants'
import TableTokenName from '@components/shared/TableTokenName'
const AssetsBorrowsTable = () => {
const { t } = useTranslation(['common', 'token'])
@ -24,6 +25,13 @@ const AssetsBorrowsTable = () => {
const showTableView = width ? width > breakpoints.md : false
const banks = useBanksWithBalances()
const banksToShow = useMemo(() => {
if (!banks || !banks.length) return []
return banks.filter(
(b) => b.bank.reduceOnly === TOKEN_REDUCE_ONLY_OPTIONS.DISABLED,
)
}, [banks])
const handleShowBorrowModal = useCallback((token: string) => {
setSelectedToken(token)
setShowBorrowModal(true)
@ -51,7 +59,7 @@ const AssetsBorrowsTable = () => {
</TrHead>
</thead>
<tbody>
{banks.map((b) => {
{banksToShow.map((b) => {
const bank = b.bank
const borrows = bank.uiBorrows()
@ -63,12 +71,7 @@ const AssetsBorrowsTable = () => {
return (
<TrBody key={bank.name}>
<Td>
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<p className="font-body">{bank.name}</p>
</div>
<TableTokenName bank={bank} symbol={bank.name} />
</Td>
<Td>
<div className="flex flex-col text-right">
@ -113,7 +116,7 @@ const AssetsBorrowsTable = () => {
</Table>
) : (
<div className="border-b border-th-bkg-3">
{banks.map((b) => {
{banksToShow.map((b) => {
const bank = b.bank
const available = group
@ -128,12 +131,7 @@ const AssetsBorrowsTable = () => {
className={`w-full border-t border-th-bkg-3 p-4 text-left first:border-t-0 focus:outline-none`}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<p className="text-th-fgd-1">{bank.name}</p>
</div>
<TableTokenName bank={bank} symbol={bank.name} />
<div className="flex items-center space-x-4">
<div>
<p className="mb-0.5 text-right text-xs">

View File

@ -89,7 +89,7 @@ const BorrowPage = () => {
}, [borrowValue, mangoAccount, group])
return (
<>
<div className="md:pb-[27px]">
<div className="flex flex-col border-b border-th-bkg-3 px-4 py-4 md:px-6 lg:flex-row lg:items-center lg:justify-between">
<div className="flex flex-col md:flex-row">
<div className="pb-4 md:pb-0 md:pr-6">
@ -202,7 +202,7 @@ const BorrowPage = () => {
onClose={() => setShowCreateAccountModal(false)}
/>
) : null}
</>
</div>
)
}

View File

@ -22,7 +22,7 @@ import Tooltip from '@components/shared/Tooltip'
import BankAmountWithValue from '@components/shared/BankAmountWithValue'
import { BankWithBalance } from 'hooks/useBanksWithBalances'
import { Disclosure, Transition } from '@headlessui/react'
import TokenLogo from '@components/shared/TokenLogo'
import TableTokenName from '@components/shared/TableTokenName'
export const getAvailableToBorrow = (
bankWithBal: BankWithBalance,
@ -99,12 +99,7 @@ const YourBorrowsTable = ({ banks }: { banks: BankWithBalance[] }) => {
return (
<TrBody key={bank.name} className="text-sm">
<Td>
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<span>{bank.name}</span>
</div>
<TableTokenName bank={bank} symbol={bank.name} />
</Td>
<Td className="text-right">
<BankAmountWithValue
@ -174,12 +169,7 @@ const YourBorrowsTable = ({ banks }: { banks: BankWithBalance[] }) => {
className={`w-full border-t border-th-bkg-3 p-4 text-left first:border-t-0 focus:outline-none`}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<p className="text-th-fgd-1">{bank.name}</p>
</div>
<TableTokenName bank={bank} symbol={bank.name} />
<div className="flex items-center space-x-4">
<div>
<p className="mb-0.5 text-right text-xs">

View File

@ -15,6 +15,7 @@ import SimpleAreaChart from '@components/shared/SimpleAreaChart'
import { COLORS } from 'styles/colors'
import useThemeWrapper from 'hooks/useThemeWrapper'
import dayjs from 'dayjs'
import TokenReduceOnlyDesc from '@components/shared/TokenReduceOnlyDesc'
const SpotCards = ({ tokens }: { tokens: BankWithMarketData[] }) => {
const { t } = useTranslation(['common', 'explore', 'trade'])
@ -59,7 +60,12 @@ const SpotCards = ({ tokens }: { tokens: BankWithMarketData[] }) => {
<div className="flex items-center space-x-3">
<TokenLogo bank={bank} size={32} />
<div>
<h3 className="mb-1 text-base leading-none">{bank.name}</h3>
<h3 className="mb-1 text-base leading-none">
{bank.name}
<span className="ml-1.5">
<TokenReduceOnlyDesc bank={bank} />
</span>
</h3>
<div className="flex items-center space-x-3">
<span className="font-mono">
<FormatNumericValue value={bank.uiPrice} isUsd />

View File

@ -31,6 +31,7 @@ import { BankWithMarketData } from './Spot'
import { SerumMarketWithMarketData } from 'hooks/useListedMarketsWithMarketData'
import Tooltip from '@components/shared/Tooltip'
import dayjs from 'dayjs'
import TableTokenName from '@components/shared/TableTokenName'
type TableData = {
assetWeight: string
@ -244,10 +245,7 @@ const SpotTable = ({ tokens }: { tokens: BankWithMarketData[] }) => {
onClick={() => goToTokenPage(tokenName.split(' ')[0], router)}
>
<Td>
<div className="flex items-center">
<TokenLogo bank={baseBank} />
<p className="ml-3 font-body">{tokenName}</p>
</div>
<TableTokenName bank={baseBank} symbol={tokenName} />
</Td>
<Td>
<div className="flex flex-col text-right">

View File

@ -28,13 +28,13 @@ import useBanksWithBalances, {
} from 'hooks/useBanksWithBalances'
import useUnownedAccount from 'hooks/useUnownedAccount'
import { Disclosure, Transition } from '@headlessui/react'
import TokenLogo from './TokenLogo'
import useHealthContributions from 'hooks/useHealthContributions'
import Tooltip from './Tooltip'
import { PublicKey } from '@solana/web3.js'
import { USDC_MINT } from 'utils/constants'
import { WRAPPED_SOL_MINT } from '@project-serum/serum/lib/token-instructions'
import { useSortableData } from 'hooks/useSortableData'
import TableTokenName from './TableTokenName'
const BalancesTable = () => {
const { t } = useTranslation(['common', 'account', 'trade'])
@ -175,12 +175,7 @@ const BalancesTable = () => {
return (
<TrBody key={bank.name} className="text-sm">
<Td>
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<span>{symbol}</span>
</div>
<TableTokenName bank={bank} symbol={symbol} />
</Td>
<Td className="text-right">
<Balance bank={bankWithBalance} />
@ -247,12 +242,7 @@ const BalancesTable = () => {
}`}
>
<div className="flex items-center justify-between">
<div className="flex items-start">
<div className="mr-2.5">
<TokenLogo bank={bank} />
</div>
<p className="text-th-fgd-2">{symbol}</p>
</div>
<TableTokenName bank={bank} symbol={symbol} />
<div className="flex items-center space-x-2">
<div className="text-right">
<Balance bank={bankWithBalance} />

View File

@ -0,0 +1,19 @@
import { Bank } from '@blockworks-foundation/mango-v4'
import TokenLogo from './TokenLogo'
import TokenReduceOnlyDesc from './TokenReduceOnlyDesc'
const TableTokenName = ({ bank, symbol }: { bank: Bank; symbol: string }) => {
return (
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<div>
<p className="font-body leading-none text-th-fgd-2">{symbol}</p>
<TokenReduceOnlyDesc bank={bank} />
</div>
</div>
)
}
export default TableTokenName

View File

@ -0,0 +1,19 @@
import { Bank } from '@blockworks-foundation/mango-v4'
import { useTranslation } from 'react-i18next'
import { TOKEN_REDUCE_ONLY_OPTIONS } from 'utils/constants'
const TokenReduceOnlyDesc = ({ bank }: { bank: Bank | undefined }) => {
const { t } = useTranslation('trade')
const tokenReduceState = bank?.reduceOnly
return tokenReduceState === TOKEN_REDUCE_ONLY_OPTIONS.DISABLED ? null : (
<span className="text-xxs">
{tokenReduceState === TOKEN_REDUCE_ONLY_OPTIONS.ENABLED ? (
<span className="text-th-warning">{t('reduce-only')}</span>
) : (
<span className="text-th-fgd-4">{t('no-borrows')}</span>
)}
</span>
)
}
export default TokenReduceOnlyDesc

View File

@ -24,9 +24,9 @@ import { getOracleProvider } from 'hooks/useOracleProvider'
import { useRouter } from 'next/router'
import { goToTokenPage } from './TokenOverviewTable'
import { LinkButton } from '@components/shared/Button'
import TokenLogo from '@components/shared/TokenLogo'
import { useCallback } from 'react'
import { useSortableData } from 'hooks/useSortableData'
import TableTokenName from '@components/shared/TableTokenName'
const TokenDetailsTable = () => {
const { t } = useTranslation(['common', 'activity', 'token', 'trade'])
@ -190,12 +190,7 @@ const TokenDetailsTable = () => {
onClick={() => goToTokenPage(symbol.split(' ')[0], router)}
>
<Td>
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<p className="font-body">{symbol}</p>
</div>
<TableTokenName bank={bank} symbol={symbol} />
</Td>
<Td>
<div className="flex justify-end space-x-1.5 text-right">
@ -259,12 +254,7 @@ const TokenDetailsTable = () => {
}`}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<p className="text-th-fgd-1">{bank.name}</p>
</div>
<TableTokenName bank={bank} symbol={bank.name} />
<ChevronDownIcon
className={`${
open ? 'rotate-180' : 'rotate-360'

View File

@ -21,9 +21,9 @@ import FormatNumericValue from '@components/shared/FormatNumericValue'
import BankAmountWithValue from '@components/shared/BankAmountWithValue'
import useBanksWithBalances from 'hooks/useBanksWithBalances'
import Decimal from 'decimal.js'
import TokenLogo from '@components/shared/TokenLogo'
import { useCallback } from 'react'
import { useSortableData } from 'hooks/useSortableData'
import TableTokenName from '@components/shared/TableTokenName'
export const goToTokenPage = (token: string, router: NextRouter) => {
const query = { ...router.query, ['token']: token }
@ -208,12 +208,7 @@ const TokenOverviewTable = () => {
}
>
<Td>
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<p className="font-body">{symbol}</p>
</div>
<TableTokenName bank={bank} symbol={symbol} />
</Td>
<Td>
<div className="flex flex-col text-right">
@ -312,12 +307,7 @@ const TokenOverviewTable = () => {
}`}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
<TokenLogo bank={bank} />
</div>
<p className="text-th-fgd-1">{symbol}</p>
</div>
<TableTokenName bank={bank} symbol={symbol} />
<ChevronDownIcon
className={`${
open ? 'rotate-180' : 'rotate-360'

View File

@ -16,6 +16,7 @@ import TokenLogo from '@components/shared/TokenLogo'
import Input from '@components/forms/Input'
import { getInputTokenBalance } from './TriggerSwapForm'
import { walletBalanceForToken } from '@components/DepositForm'
import TokenReduceOnlyDesc from '@components/shared/TokenReduceOnlyDesc'
export type SwapFormTokenListType =
| 'input'
@ -82,12 +83,12 @@ const TokenItem = ({
return group.getFirstBankByMint(new PublicKey(address))
}, [address, type])
const isReduceOnly = useMemo(() => {
if (!bank) return false
const borrowsReduceOnly = bank.areBorrowsReduceOnly()
const depositsReduceOnly = bank.areDepositsReduceOnly()
return borrowsReduceOnly && depositsReduceOnly
}, [bank])
// const isReduceOnly = useMemo(() => {
// if (!bank) return false
// const borrowsReduceOnly = bank.areBorrowsReduceOnly()
// const depositsReduceOnly = bank.areDepositsReduceOnly()
// return borrowsReduceOnly && depositsReduceOnly
// }, [bank])
return (
<div>
@ -110,11 +111,9 @@ const TokenItem = ({
{t(`trade:${token.amount.gt(0) ? 'long' : 'short'}`)}
</span>
) : null}
{isReduceOnly ? (
<span className="ml-1 text-xxs text-th-warning">
{t('reduce-only')}
</span>
) : null}
<span className="ml-1">
<TokenReduceOnlyDesc bank={bank} />
</span>
</p>
<p className="text-left text-xs text-th-fgd-4">

View File

@ -53,6 +53,7 @@
"min-order-size-error": "Min order size is {{minSize}} {{symbol}}",
"more-details": "More Details",
"no-balances": "No balances",
"no-borrows": "No Borrows",
"no-markets-found": "No markets found...",
"no-orders": "No open orders",
"no-positions": "No perp positions",

View File

@ -53,6 +53,7 @@
"min-order-size-error": "Min order size is {{minSize}} {{symbol}}",
"more-details": "More Details",
"no-balances": "No balances",
"no-borrows": "No Borrows",
"no-markets-found": "No markets found...",
"no-orders": "No open orders",
"no-positions": "No perp positions",

View File

@ -53,6 +53,7 @@
"min-order-size-error": "Min order size is {{minSize}} {{symbol}}",
"more-details": "More Details",
"no-balances": "No balances",
"no-borrows": "No Borrows",
"no-markets-found": "No markets found...",
"no-orders": "No open orders",
"no-positions": "No perp positions",

View File

@ -53,6 +53,7 @@
"min-order-size-error": "订单的最小数量是 {{minSize}} {{symbol}}",
"more-details": "看细节",
"no-balances": "无余额",
"no-borrows": "No Borrows",
"no-markets-found": "No markets found...",
"no-orders": "无订单",
"no-positions": "无持仓",

View File

@ -53,6 +53,7 @@
"min-order-size-error": "訂單的最小數量是 {{minSize}} {{symbol}}",
"more-details": "看細節",
"no-balances": "無餘額",
"no-borrows": "No Borrows",
"no-markets-found": "No markets found...",
"no-orders": "無訂單",
"no-positions": "無持倉",

View File

@ -175,3 +175,9 @@ export const MAX_ACCOUNTS = {
perpOpenOrders: '64',
tcsOrders: '64',
}
export enum TOKEN_REDUCE_ONLY_OPTIONS {
DISABLED,
ENABLED,
NO_BORROWS,
}