Compare commits

...

23 Commits

Author SHA1 Message Date
zer0cache 204871235f
Merge 43d0f312ca into 56eb12dc69 2024-05-09 12:39:49 -04:00
saml33 56eb12dc69
show tooltip against banks with collateral fees (#414)
* show tooltip against banks with collateral fees

* copy update

---------

Co-authored-by: Adrian Brzeziński <a.brzezinski94@gmail.com>
2024-05-09 13:02:19 +02:00
Finn Casey Fierro 4b54fe33c6
fix to ratings (#421) 2024-05-09 12:59:13 +02:00
Finn Casey Fierro 09a4113bd2
new tab (#420)
* new tab

* remove console log
2024-05-08 17:25:32 +02:00
Adrian Brzeziński 59719cc810 Merge branch 'main' of github.com:blockworks-foundation/mango-v4-ui 2024-05-08 14:57:31 +02:00
Adrian Brzeziński 3ed3684d40 suggested modal fix 2024-05-08 14:57:04 +02:00
saml33 6215d3bb03 fix rate curve chart 2024-05-08 15:12:45 +10:00
saml33 951b3fc796 funding table asset styling 2024-05-08 15:04:35 +10:00
saml33 40670f3cfb modal overflow 2024-05-08 14:50:10 +10:00
saml33 d8967dcd71 add funding table empty states 2024-05-08 10:42:03 +10:00
Adrian Brzeziński 3e30fe0eb1 lint fix 2024-05-08 00:30:00 +02:00
Adrian Brzeziński e1f791b5e8 update settings libs 2024-05-08 00:24:08 +02:00
Finn fb23b86b7c fix 2024-05-07 23:53:38 +02:00
saml33 bdfd9ff466 fix text alignment 2024-05-07 23:00:20 +10:00
Adrian Brzeziński 3d76a68f7b fix prospective api 2024-05-07 12:40:52 +02:00
saml33 1dfda6cd2b
Merge pull request #418 from blockworks-foundation/saml33/show-token-leverage
show token leverage
2024-05-07 09:49:28 +10:00
saml33 6d86a6f607
Merge pull request #415 from blockworks-foundation/chinese-localization
Update Chinese localization
2024-05-07 09:41:25 +10:00
saml33 2ae3675bfe show token leverage 2024-05-06 10:34:42 +10:00
saml33 5fecc0ad1d fix modal overflow 2024-05-05 21:58:41 +10:00
saml33 017fed46d3 merge main 2024-05-05 21:32:55 +10:00
rjpeterson fe9a27174d remove extra space 2024-04-22 18:08:30 -07:00
rjpeterson 945ca79bf3 update translations 2024-04-22 18:04:25 -07:00
zer0cache@protonmail.com 43d0f312ca Make Jupiter v6 quote API configurable 2024-02-26 16:32:00 -05:00
33 changed files with 430 additions and 84 deletions

View File

@ -2,6 +2,7 @@ import { Bank } from '@blockworks-foundation/mango-v4'
import { Disclosure, Popover, Transition } from '@headlessui/react'
import {
ChevronDownIcon,
CurrencyDollarIcon,
EllipsisHorizontalIcon,
XMarkIcon,
} from '@heroicons/react/20/solid'
@ -51,6 +52,10 @@ import SheenLoader from './shared/SheenLoader'
import useAccountInterest from 'hooks/useAccountInterest'
import { handleGoToTradePage } from 'utils/markets'
import TableRatesDisplay from './shared/TableRatesDisplay'
import useCollateralFeePopupConditions from 'hooks/useCollateralFeePositions'
import { LinkButton } from './shared/Button'
import CollateralFeeWarningModal from './modals/CollateralFeeWarningModal'
import InlineNotification from './shared/InlineNotification'
export const handleOpenCloseBorrowModal = (borrowBank: Bank) => {
const group = mangoStore.getState().group
@ -118,8 +123,9 @@ type TableData = {
const set = mangoStore.getState().set
const TokenList = () => {
const { t } = useTranslation(['common', 'token', 'trade'])
const { t } = useTranslation(['common', 'account', 'token', 'trade'])
const [showCloseBorrowModal, setCloseBorrowModal] = useState(false)
const [showCollateralFeeModal, setShowCollateralFeeModal] = useState(false)
const [closeBorrowBank, setCloseBorrowBank] = useState<Bank | undefined>()
const [showZeroBalances, setShowZeroBalances] = useLocalStorageState(
SHOW_ZERO_BALANCES_KEY,
@ -131,6 +137,7 @@ const TokenList = () => {
const { width } = useViewport()
const showTableView = width ? width > breakpoints.md : false
const banks = useBanksWithBalances('balance')
const { isCharged, collateralFeeBanks } = useCollateralFeePopupConditions()
const {
data: totalInterestData,
@ -361,7 +368,33 @@ const TokenList = () => {
return (
<TrBody key={symbol}>
<Td>
<TableTokenName bank={bank} symbol={symbol} />
<div className="flex items-center">
<TableTokenName bank={bank} symbol={symbol} />
{isCharged &&
collateralFeeBanks.find(
(b) => b.bank.name === bank.name,
) ? (
<Tooltip
content={
<>
<span>
{t('account:tooltip-collateral-fees-charged')}
</span>
<LinkButton
className="mt-2"
onClick={() =>
setShowCollateralFeeModal(true)
}
>
{t('view-fees')}
</LinkButton>
</>
}
>
<CurrencyDollarIcon className="ml-2 h-4 w-4 cursor-help text-th-down" />
</Tooltip>
) : null}
</div>
</Td>
<Td className="text-right">
<BankAmountWithValue
@ -453,7 +486,13 @@ const TokenList = () => {
) : (
<div className="border-b border-th-bkg-3">
{tableData.map((data) => {
return <MobileTokenListItem key={data.bank.name} data={data} />
return (
<MobileTokenListItem
key={data.bank.name}
data={data}
setShowCollateralFeeModal={setShowCollateralFeeModal}
/>
)
})}
</div>
)}
@ -464,15 +503,28 @@ const TokenList = () => {
onClose={closeBorrowModal}
/>
) : null}
{showCollateralFeeModal ? (
<CollateralFeeWarningModal
isOpen={showCollateralFeeModal}
onClose={() => setShowCollateralFeeModal(false)}
/>
) : null}
</ContentBox>
)
}
export default TokenList
const MobileTokenListItem = ({ data }: { data: TableData }) => {
const MobileTokenListItem = ({
data,
setShowCollateralFeeModal,
}: {
data: TableData
setShowCollateralFeeModal: (show: boolean) => void
}) => {
const { t } = useTranslation(['common', 'token'])
const { mangoAccount } = useMangoAccount()
const { isCharged, collateralFeeBanks } = useCollateralFeePopupConditions()
const {
bank,
balance,
@ -530,6 +582,26 @@ const MobileTokenListItem = ({ data }: { data: TableData }) => {
>
<Disclosure.Panel>
<div className="mx-4 grid grid-cols-2 gap-4 border-t border-th-bkg-3 py-4">
{isCharged &&
collateralFeeBanks.find((b) => b.bank.name === bank.name) ? (
<div className="col-span-2">
<InlineNotification
desc={
<>
<span>
{t('account:tooltip-collateral-fees-charged')}
</span>
<LinkButton
onClick={() => setShowCollateralFeeModal(true)}
>
{t('view-fees')}
</LinkButton>
</>
}
type="info"
/>
</div>
) : null}
<div className="col-span-1">
<Tooltip content={t('tooltip-collateral-value')}>
<p className="tooltip-underline text-xs text-th-fgd-3">

View File

@ -1,5 +1,6 @@
import { Bank, PerpMarket } from '@blockworks-foundation/mango-v4'
import { LinkButton } from '@components/shared/Button'
import ConnectEmptyState from '@components/shared/ConnectEmptyState'
import FormatNumericValue from '@components/shared/FormatNumericValue'
import SheenLoader from '@components/shared/SheenLoader'
import {
@ -14,6 +15,8 @@ import {
import TokenLogo from '@components/shared/TokenLogo'
import MarketLogos from '@components/trade/MarketLogos'
import { Disclosure, Transition } from '@headlessui/react'
import { NoSymbolIcon } from '@heroicons/react/20/solid'
import { useWallet } from '@solana/wallet-adapter-react'
import mangoStore from '@store/mangoStore'
import { useInfiniteQuery } from '@tanstack/react-query'
import useMangoAccount from 'hooks/useMangoAccount'
@ -62,6 +65,7 @@ export const fetchMarginFunding = async (
const FundingTable = () => {
const { t } = useTranslation(['common', 'account'])
const { mangoAccountAddress } = useMangoAccount()
const { connected } = useWallet()
const { width } = useViewport()
const showTableView = width ? width > breakpoints.md : false
@ -136,7 +140,8 @@ const FundingTable = () => {
sortConfig,
} = useSortableData(tableData)
return (
return mangoAccountAddress &&
(sortedTableData?.length || isLoading || isFetchingNextPage) ? (
<>
{showTableView ? (
<Table>
@ -194,9 +199,11 @@ const FundingTable = () => {
<div className="flex items-center justify-end">
{marketOrBank ? (
marketOrBank instanceof PerpMarket ? (
<MarketLogos market={marketOrBank} />
<MarketLogos market={marketOrBank} size="small" />
) : (
<TokenLogo bank={marketOrBank} />
<div className="mr-1.5">
<TokenLogo bank={marketOrBank} size={16} />
</div>
)
) : null}
<p className="font-body">{asset}</p>
@ -256,7 +263,9 @@ const FundingTable = () => {
marketOrBank instanceof PerpMarket ? (
<MarketLogos market={marketOrBank} size="small" />
) : (
<TokenLogo bank={marketOrBank} size={16} />
<div className="mr-1.5">
<TokenLogo bank={marketOrBank} size={16} />
</div>
)
) : null}
<p className="text-right">{asset}</p>
@ -324,6 +333,17 @@ const FundingTable = () => {
</LinkButton>
) : null}
</>
) : mangoAccountAddress || connected ? (
<div className="flex flex-1 flex-col items-center justify-center">
<div className="flex flex-col items-center p-8">
<NoSymbolIcon className="mb-2 h-6 w-6 text-th-fgd-4" />
<p>{t('account:no-funding')}</p>
</div>
</div>
) : (
<div className="flex flex-1 flex-col items-center justify-center p-8">
<ConnectEmptyState text={t('account:connect-funding')} />
</div>
)
}

View File

@ -282,6 +282,7 @@ const SpotTable = ({ tokens }: { tokens: BankWithMarketData[] }) => {
<TableTokenName
bank={baseBank}
symbol={tokenName}
showLeverage
/>
</div>
</Td>

View File

@ -11,9 +11,10 @@ import FormatNumericValue from '@components/shared/FormatNumericValue'
type WarningProps = {
isOpen: boolean
onClose?: () => void
}
const CollateralFeeWarningModal = ({ isOpen }: WarningProps) => {
const CollateralFeeWarningModal = ({ isOpen, onClose }: WarningProps) => {
const { t } = useTranslation(['account'])
const { setWasModalOpen, collateralFeeBanks, ltvRatio } =
useCollateralFeePopupConditions()
@ -31,13 +32,15 @@ const CollateralFeeWarningModal = ({ isOpen }: WarningProps) => {
return Math.round(timeUntilChargeInHours * 100) / 100
}, [lastCharge, collateralFeeInterval])
const handleClose = () => {
setWasModalOpen(true)
if (onClose) {
onClose()
}
}
return (
<Modal
isOpen={isOpen}
onClose={() => setWasModalOpen(true)}
disableOutsideClose
hideClose
>
<Modal isOpen={isOpen} onClose={handleClose} disableOutsideClose hideClose>
<h2 className="mb-2 text-center">
{t('collateral-funding-modal-heading', {
remaining_hours: hoursTillNextCharge,
@ -55,7 +58,7 @@ const CollateralFeeWarningModal = ({ isOpen }: WarningProps) => {
<thead>
<TrHead>
<Th className="text-left">{t('collateral')}</Th>
<Th className="text-right">{t('funding-rate')} (APR)</Th>
<Th className="text-right">{t('funding-rate')} Per Day</Th>
<Th>
<div className="flex justify-end">{t('daily-fee')}</div>
</Th>
@ -72,17 +75,13 @@ const CollateralFeeWarningModal = ({ isOpen }: WarningProps) => {
</Td>
<Td>
<p className="text-right">
{(ltvRatio * bank.collateralFeePerDay * 365 * 100).toFixed(
2,
)}
%
{(ltvRatio * bank.collateralFeePerDay * 100).toFixed(4)}%
</p>
</Td>
<Td>
<div className="flex flex-col items-end">
<p>
<p className="text-right">
<FormatNumericValue value={dailyFee} />
<span className="font-body"> {bank.name}</span>
</p>
<span className="font-mono text-th-fgd-4">
$<FormatNumericValue value={dailyFee * bank.uiPrice} />
@ -97,7 +96,7 @@ const CollateralFeeWarningModal = ({ isOpen }: WarningProps) => {
<Button
className="mt-6 w-full"
onClick={() => {
setWasModalOpen(true)
handleClose()
}}
>
{t('okay-got-it')}

View File

@ -260,7 +260,7 @@ const UserSetupModal = ({
return (
<Modal isOpen={isOpen} onClose={onClose} fullScreen disableOutsideClose>
<div className="grid h-screen overflow-auto bg-th-bkg-1 text-left lg:grid-cols-2">
<div className="grid h-screen overflow-hidden bg-th-bkg-1 text-left lg:grid-cols-2">
<ColorBlur
width="66%"
height="300px"

View File

@ -33,7 +33,7 @@ function Modal({
}, [isOpen])
const handleClose = () => {
if (disableOutsideClose) return
if (disableOutsideClose && !fullScreen) return
onClose()
}
@ -59,10 +59,10 @@ function Modal({
themeData.fonts.display.variable
} ${
themeData.fonts.mono.variable
} thin-scroll w-full overflow-auto bg-th-bkg-1 font-body ${
} h-full w-full bg-th-bkg-1 font-body ${
fullScreen
? 'h-full'
: 'max-h-[calc(100vh-5%)] p-4 sm:max-w-md sm:rounded-lg sm:border sm:border-th-bkg-3 sm:p-6'
? ''
: 'thin-scroll max-h-[calc(100vh-48px)] overflow-y-auto p-4 sm:h-auto sm:max-w-md sm:rounded-lg sm:border sm:border-th-bkg-3 sm:p-6'
} relative ${panelClassNames}`}
>
<div>{children}</div>

View File

@ -5,28 +5,47 @@ import { useVaultLimits } from '@components/swap/useVaultLimits'
import { ExclamationTriangleIcon } from '@heroicons/react/20/solid'
import Tooltip from './Tooltip'
import { useTranslation } from 'react-i18next'
import { floorToDecimal } from 'utils/numbers'
import { LeverageBadge } from '@components/trade/MarketSelectDropdown'
const TableTokenName = ({ bank, symbol }: { bank: Bank; symbol: string }) => {
const { t } = useTranslation('common')
const TableTokenName = ({
bank,
symbol,
showLeverage,
}: {
bank: Bank
symbol: string
showLeverage?: boolean
}) => {
const { t } = useTranslation(['common', 'trade'])
const { vaultFull } = useVaultLimits(bank)
const weight = bank.scaledInitAssetWeight(bank.price)
const leverageFactor = 1 / (1 - weight.toNumber())
const leverageMax = floorToDecimal(leverageFactor, 1).toNumber()
return (
<div className="flex items-center">
<div className="mr-2.5 flex shrink-0 items-center">
<TokenLogo bank={bank} showRewardsLogo />
</div>
<Tooltip
content={
vaultFull ? t('warning-deposits-full', { token: bank.name }) : ''
}
>
<div>
<div className="flex items-center">
<p className="font-body leading-none text-th-fgd-2">{symbol}</p>
{showLeverage && leverageMax > 1 && leverageMax < Infinity ? (
<div className="ml-1">
<Tooltip content={t('trade:max-leverage')}>
<LeverageBadge leverage={leverageMax} />
</Tooltip>
</div>
) : null}
{vaultFull ? (
<ExclamationTriangleIcon className="ml-1 h-4 w-4 text-th-warning" />
<Tooltip content={t('warning-deposits-full', { token: bank.name })}>
<ExclamationTriangleIcon className="ml-1 h-4 w-4 text-th-warning" />
</Tooltip>
) : null}
</div>
<TokenReduceOnlyDesc bank={bank} />
</Tooltip>
</div>
</div>
)
}

View File

@ -213,7 +213,11 @@ const TokenDetailsTable = () => {
onClick={() => goToTokenPage(symbol.split(' ')[0], router)}
>
<Td>
<TableTokenName bank={bank} symbol={symbol} />
<TableTokenName
bank={bank}
symbol={symbol}
showLeverage
/>
</Td>
<Td>
<div className="flex justify-end space-x-1.5 text-right font-mono">
@ -275,7 +279,11 @@ const TokenDetailsTable = () => {
}`}
>
<div className="flex items-center justify-between">
<TableTokenName bank={bank} symbol={bank.name} />
<TableTokenName
bank={bank}
symbol={bank.name}
showLeverage
/>
<ChevronDownIcon
className={`${
open ? 'rotate-180' : 'rotate-0'

View File

@ -209,7 +209,11 @@ const TokenOverviewTable = () => {
}
>
<Td>
<TableTokenName bank={bank} symbol={symbol} />
<TableTokenName
bank={bank}
symbol={symbol}
showLeverage
/>
</Td>
<Td>
<div className="flex flex-col text-right">
@ -300,7 +304,11 @@ const TokenOverviewTable = () => {
}`}
>
<div className="flex items-center justify-between">
<TableTokenName bank={bank} symbol={symbol} />
<TableTokenName
bank={bank}
symbol={symbol}
showLeverage
/>
<ChevronDownIcon
className={`${
open ? 'rotate-180' : 'rotate-0'

View File

@ -58,7 +58,7 @@ const RateCurveChart = ({ bank }: { bank: Bank | undefined }) => {
const rateCurveChartData = useMemo(() => {
if (!bank) return []
const defaults = [
{ util: 0, rate: 0 },
{ util: 0, rate: bank.loanFeeRate.toNumber() * 100 },
{
util: bank.util0.toNumber() * 100,
rate:

View File

@ -524,10 +524,10 @@ const MarketSelectDropdown = () => {
export default MarketSelectDropdown
const LeverageBadge = ({ leverage }: { leverage: number }) => {
export const LeverageBadge = ({ leverage }: { leverage: number }) => {
return (
<div className="rounded border border-th-fgd-4 px-1 py-0.5 text-xxs leading-none text-th-fgd-4">
<span>{leverage < 1 ? leverage.toFixed(1) : leverage.toFixed()}x</span>
<div className="rounded bg-th-bkg-3 px-1 py-0.5 font-mono text-xxs leading-none text-th-fgd-2">
<span>{leverage < 2 ? leverage.toFixed(1) : leverage.toFixed()}x</span>
</div>
)
}

View File

@ -2,6 +2,7 @@ import { COLLATERAL_FEE_KEY } from 'utils/constants'
import useBanksWithBalances from './useBanksWithBalances'
import useLocalStorageState from './useLocalStorageState'
import { useMemo } from 'react'
import useMangoAccount from './useMangoAccount'
const useCollateralFeePopupConditions = () => {
const [wasModalOpen, setWasModalOpen] = useLocalStorageState(
@ -9,7 +10,7 @@ const useCollateralFeePopupConditions = () => {
false,
)
const banks = useBanksWithBalances('balance')
//check if there is at least 100$ active margin position and bank has collateral fee active
const marginPositionBalanceWithBanks = banks.filter(
(x) => x.balance < 0 && Math.abs(x.balance) * x.bank.uiPrice >= 100,
)
@ -47,12 +48,16 @@ const useCollateralFeePopupConditions = () => {
!!collateralFeeBanks.length &&
!wasModalOpen
const isCharged =
!!marginPositionBalanceWithBanks.length && !!collateralFeeBanks.length
return {
showCollateralFeeWarning,
setWasModalOpen,
marginPositionBalanceWithBanks,
collateralFeeBanks,
ltvRatio,
isCharged,
}
}

View File

@ -24,7 +24,7 @@
"@blockworks-foundation/mango-feeds": "0.1.7",
"@blockworks-foundation/mango-mints-redemption": "^0.0.10",
"@blockworks-foundation/mango-v4": "0.24.0",
"@blockworks-foundation/mango-v4-settings": "0.14.21",
"@blockworks-foundation/mango-v4-settings": "0.14.22",
"@blockworks-foundation/mangolana": "0.0.16",
"@headlessui/react": "1.6.6",
"@heroicons/react": "2.0.18",

View File

@ -22,8 +22,8 @@ export default async function handler(
`https://public-api.birdeye.so/defi/tokenlist?sort_by=v24hUSD&sort_type=desc&offset=${offset}&limit=50`,
options,
)
const tokenListResponse = await response.json()
const tokenListResponse = await response.json()
const tokenList = tokenListResponse['data']['tokens']
const filteredTokens = []
@ -35,7 +35,7 @@ export default async function handler(
const nowInSeconds = Math.floor(now.getTime() / 1000)
const pastDate = new Date()
pastDate.setDate(pastDate.getDate() - 4)
pastDate.setMonth(pastDate.getMonth() - 1)
pastDate.setMonth(pastDate.getMonth() - 1.5)
const pastDateInSeconds = Math.floor(pastDate.getTime() / 1000)
// Fetch history for the token
@ -44,7 +44,6 @@ export default async function handler(
options,
)
const historyData = await historyResponse.json()
if (historyData['data']['items']?.length >= 35) {
const detailResponse = await fetch(
`https://public-api.birdeye.so/defi/token_overview?address=${address}`,
@ -61,7 +60,6 @@ export default async function handler(
}
}
}
// Return the filtered list of tokens
res.status(200).json(filteredTokens)
} catch (error) {

View File

@ -64,15 +64,28 @@ const getSuggestedAndCurrentTier = (
bank: Bank,
midPriceImp: MidPriceImpact[],
) => {
const currentTier = Object.values(LISTING_PRESETS).find((x) => {
return x.initLiabWeight.toFixed(1) === '1.8'
? x.initLiabWeight.toFixed(1) ===
bank?.initLiabWeight.toNumber().toFixed(1) &&
x.reduceOnly === bank.reduceOnly
: x.initLiabWeight.toFixed(1) ===
bank?.initLiabWeight.toNumber().toFixed(1)
const epsilon = 1e-8
let currentTier = Object.values(LISTING_PRESETS).find((x) => {
if (bank?.name == 'USDC' || bank?.name == 'USDT') return true
if (bank?.depositWeightScaleStartQuote != 20000000000) {
if (
x.depositWeightScaleStartQuote === bank?.depositWeightScaleStartQuote
) {
return true
}
} else {
return (
Math.abs(
x.loanOriginationFeeRate - bank?.loanOriginationFeeRate.toNumber(),
) < epsilon
)
}
})
if (currentTier == undefined) {
currentTier = LISTING_PRESETS['asset_5000']
}
const filteredResp = midPriceImp
.filter((x) => x.avg_price_impact_percent < 1)
.reduce((acc: { [key: string]: MidPriceImpact }, val: MidPriceImpact) => {
@ -1393,6 +1406,19 @@ export const DashboardNavbar = () => {
</h4>
</Link>
</div>
<div>
<Link href={'/dashboard/marketing'} shallow={true}>
<h4
className={`${
asPath.includes('/dashboard/marketing')
? 'bg-th-bkg-2 text-th-active'
: ''
} cursor-pointer border-r border-th-bkg-3 px-6 py-4`}
>
Marketing
</h4>
</Link>
</div>
<div>
<Link
href={

View File

@ -0,0 +1,132 @@
import type { NextPage } from 'next'
import { DashboardNavbar } from '.'
import { Table, Td, Th, TrBody, TrHead } from '@components/shared/TableElements'
import useBanks from 'hooks/useBanks'
import { Bank } from '@blockworks-foundation/mango-v4'
import { formatCurrencyValue } from 'utils/numbers'
import { toUiDecimalsForQuote } from '@blockworks-foundation/mango-v4'
import { useRouter } from 'next/router' // Import the useRouter hook
const Marketing: NextPage = () => {
const banks = useBanks()['banks']
const router = useRouter()
const getColorForPercent = (percent: number) => {
// Use a smoother gradient of colors from red to green based on the percentage
if (percent < 10) return '#ff073a' // Deep red
else if (percent < 20) return '#ff6347' // Tomato
else if (percent < 30) return '#ff7f50' // Coral
else if (percent < 40) return '#ffa500' // Orange
else if (percent < 50) return '#ffd700' // Gold
else if (percent < 60) return '#ffff00' // Yellow
else if (percent < 70) return '#adff2f' // Green Yellow
else if (percent < 80) return '#7fff00' // Chartreuse
else if (percent < 90) return '#32cd32' // Lime Green
return '#00ff00' // Green
}
const handleRowClick = (tokenName: string) => {
router.push(`/stats?token=${tokenName}`)
}
return (
<div className="col-span-12 w-full lg:col-span-8 lg:col-start-3">
<DashboardNavbar />
<div className="mt-4">
<div className="mx-20 mb-4">
<p className="flex items-center space-x-4 text-th-fgd-4">
<span>Fullness of Token Deposits</span>
</p>
</div>
<div className="w-full overflow-scroll" style={{ maxHeight: '70vh' }}>
<Table className="h-full">
<thead>
<TrHead
style={{ boxShadow: '1px -5px 1px rgba(0,0,0,1)', zIndex: 19 }}
className="sticky top-0 border-t bg-th-bkg-2"
>
<Th
className="text-left"
style={{ borderLeft: '1px solid #ccc' }}
>
{'Symbol'}
</Th>
<Th className="text-left">{'Leverage'}</Th>
<Th className="text-left">{'Deposits'}</Th>
<Th className="text-left">{'Limit'}</Th>
<Th className="text-left">{'Percent'}</Th>
</TrHead>
</thead>
<tbody>
{banks.map((bank: Bank, idx) => {
const deposits = bank?.uiDeposits() * bank?.uiPrice
const depositLimit = Number(
toUiDecimalsForQuote(bank.borrowWeightScaleStartQuote),
)
const percent = (100 * deposits) / depositLimit
if (
bank?.name !== 'USDC' &&
bank?.maintAssetWeight.toNumber() > 0
) {
return (
<TrBody
key={idx}
className="h-10 cursor-pointer text-xs md:hover:bg-th-bkg-2"
onClick={() => handleRowClick(bank.name)}
>
<Td className={`sticky left-0 z-10 !py-3`}>
{bank?.name}
</Td>
<Td className={`sticky left-0 z-10 !py-3`}>
{(1 / (1 - bank?.initAssetWeight.toNumber())).toFixed()}
x
</Td>
<Td className={`sticky left-0 z-10 !py-3`}>
$
{(bank?.uiDeposits() * bank?.uiPrice).toLocaleString(
undefined,
{
minimumFractionDigits: 0,
maximumFractionDigits: 0,
},
)}
</Td>
<Td className={`sticky left-0 z-10 !py-3`}>
{formatCurrencyValue(
toUiDecimalsForQuote(
bank.borrowWeightScaleStartQuote,
),
)}
</Td>
<Td className={`sticky left-0 z-10 !py-3`}>
<div className="relative h-full w-full">
<div className="absolute flex h-full w-full items-center justify-start">
<span className="absolute left-0 font-bold">
{percent.toFixed(2)}%
</span>
<div
style={{
width: `${percent}%`,
backgroundColor: getColorForPercent(percent),
minHeight: '1rem',
marginLeft: '50px', // Offset to the right to avoid overlap
}}
className="transition-all duration-300 ease-in-out"
/>
</div>
</div>
</Td>
</TrBody>
)
}
})}
</tbody>
</Table>
</div>
</div>
</div>
)
}
export default Marketing

View File

@ -74,6 +74,33 @@ const Prospective: NextPage = () => {
return []
}, [tokensList])
const downloadTokens = () => {
let csvContent = 'data:text/csv;charset=utf-8,'
const filteredTokens = tokensList.filter(
(token) => !bankNames.includes(token.symbol.toUpperCase()),
)
if (filteredTokens.length > 0) {
const headers = Object.keys(filteredTokens[0]).join(',')
const rows = filteredTokens.map((token) =>
Object.values(token)
.map(
(value) => `"${value?.toString().replace(/"/g, '""')}"`, // Handle quotes in data
)
.join(','),
)
csvContent += headers + '\n' + rows.join('\n')
}
const encodedUri = encodeURI(csvContent)
const link = document.createElement('a')
link.setAttribute('href', encodedUri)
link.setAttribute('download', 'non_bank_tokens.csv')
document.body.appendChild(link) // Required for FF
link.click()
document.body.removeChild(link)
}
return (
<div className="col-span-12 w-full lg:col-span-8 lg:col-start-3">
<DashboardNavbar />
@ -82,6 +109,12 @@ const Prospective: NextPage = () => {
<p className="flex items-center space-x-4 text-th-fgd-4">
<span>Hidden Gems to Prospect On</span>
</p>
<button
onClick={downloadTokens}
className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"
>
Download
</button>
</div>
<div className="w-full overflow-scroll" style={{ maxHeight: '70vh' }}>
<Table className="h-full">

View File

@ -8,9 +8,10 @@
"collateral": "Collateral",
"collateral-funding-modal-heading": "You'll be charged collateral fees in {{remaining_hours}} hours",
"collateral-value": "Collateral Value",
"connect-funding": "Connect to view your account funding",
"custom-account-options-saved": "Advanced options set",
"cumulative-interest-chart": "Cumulative Interest Chart",
"daily-fee": "Daily Fee",
"daily-fee": "Est. Daily Fee",
"daily-volume": "24h Volume",
"export": "Export {{dataType}}",
"find-accounts": "Find Accounts",
@ -18,6 +19,7 @@
"followed-accounts": "Followed Accounts",
"funding-chart": "Funding Chart",
"funding-rate": "Funding Rate",
"funding-type": "Funding Type",
"hide-announcements": "Hide Announcements",
"init-health": "Init Health",
"maint-health": "Maint Health",
@ -30,6 +32,7 @@
"maint-health-contributions": "Maint Health Contributions",
"more-account-stats": "More Account Stats",
"no-data": "No data to display",
"no-funding": "No funding earned or paid",
"no-pnl-history": "No PnL History",
"not-following-yet": "Your not following any accounts yet...",
"okay-got-it": "Okay, Got It",
@ -44,6 +47,7 @@
"token-slots-manage": "You can manage your account slots here:",
"token-slots-nearly-full": "You have one token slot left",
"token-slots-warning-desc": "Mango Accounts are limited in the number of tokens they can hold at one time. When you fully withdraw a token or fully repay a borrow, a slot will become available again.",
"tooltip-collateral-fees-charged": "Collateral funding fees are being charged",
"tooltip-collateral-value": "The amount of capital this token gives you to use for trades and loans.",
"tooltip-connect-to-follow": "Connect to follow accounts",
"tooltip-follow-account": "Follow account on your account page",

View File

@ -213,6 +213,7 @@
"updating-account-name": "Updating Account Name...",
"utilization": "Utilization",
"value": "Value",
"view-fees": "View Fees",
"view-transaction": "View Transaction",
"wallet": "Wallet",
"wallet-address": "Wallet Address",

View File

@ -8,9 +8,10 @@
"collateral": "Collateral",
"collateral-funding-modal-heading": "You'll be charged collateral fees in {{remaining_hours}} hours",
"collateral-value": "Collateral Value",
"connect-funding": "Connect to view your account funding",
"custom-account-options-saved": "Advanced options set",
"cumulative-interest-chart": "Cumulative Interest Chart",
"daily-fee": "Daily Fee",
"daily-fee": "Est. Daily Fee",
"daily-volume": "24h Volume",
"export": "Export {{dataType}}",
"find-accounts": "Find Accounts",
@ -30,6 +31,7 @@
"maint-health-contributions": "Maint Health Contributions",
"more-account-stats": "More Account Stats",
"no-data": "No data to display",
"no-funding": "No funding earned or paid",
"no-pnl-history": "No PnL History",
"not-following-yet": "Your not following any accounts yet...",
"okay-got-it": "Okay, Got It",
@ -44,6 +46,7 @@
"token-slots-manage": "You can manage your account slots here:",
"token-slots-nearly-full": "You have one token slot left",
"token-slots-warning-desc": "Mango Accounts are limited in the number of tokens they can hold at one time. When you fully withdraw a token or fully repay a borrow, a slot will become available again.",
"tooltip-collateral-fees-charged": "Collateral funding fees are being charged",
"tooltip-collateral-value": "The amount of capital this token gives you to use for trades and loans.",
"tooltip-connect-to-follow": "Connect to follow accounts",
"tooltip-follow-account": "Follow account on your account page",

View File

@ -213,6 +213,7 @@
"updating-account-name": "Updating Account Name...",
"utilization": "Utilization",
"value": "Value",
"view-fees": "View Fees",
"view-transaction": "View Transaction",
"wallet": "Wallet",
"wallet-address": "Wallet Address",

View File

@ -8,9 +8,10 @@
"collateral": "Collateral",
"collateral-funding-modal-heading": "You'll be charged collateral fees in {{remaining_hours}} hours",
"collateral-value": "Valor do Colateral",
"connect-funding": "Connect to view your account funding",
"custom-account-options-saved": "Opções avançadas definidas",
"cumulative-interest-chart": "Gráfico de Juros Acumulados",
"daily-fee": "Daily Fee",
"daily-fee": "Est. Daily Fee",
"daily-volume": "Volume de 24h",
"export": "Exportar {{dataType}}",
"find-accounts": "Encontrar Contas",
@ -30,6 +31,7 @@
"maint-health-contributions": "Contribuições para a Saúde de Manutenção",
"more-account-stats": "Mais Estatísticas da Conta",
"no-data": "Sem dados para exibir",
"no-funding": "No funding earned or paid",
"no-pnl-history": "Sem Histórico de PnL",
"not-following-yet": "Ainda não está seguindo nenhuma conta...",
"okay-got-it": "Okay, Got It",
@ -44,6 +46,7 @@
"token-slots-manage": "Você pode gerenciar seus slots de conta aqui:",
"token-slots-nearly-full": "Você tem apenas um slot de token restante",
"token-slots-warning-desc": "As contas Mango são limitadas no número de tokens que podem, conter de uma vez. Quando você saca totalmente um token ou paga totalmente um empréstimo, um slot ficará disponível novamente.",
"tooltip-collateral-fees-charged": "Collateral funding fees are being charged",
"tooltip-collateral-value": "A quantidade de capital que este token fornece para usar em negociações e empréstimos.",
"tooltip-connect-to-follow": "Conecte-se para seguir contas",
"tooltip-follow-account": "Siga a conta na sua página de conta",

View File

@ -213,6 +213,7 @@
"updating-account-name": "Atualizando Nome da Conta...",
"utilization": "Utilização",
"value": "Valor",
"view-fees": "View Fees",
"view-transaction": "Visualizar Transação",
"wallet": "Carteira",
"wallet-address": "Endereço da Carteira",

View File

@ -8,9 +8,10 @@
"collateral": "Collateral",
"collateral-funding-modal-heading": "You'll be charged collateral fees in {{remaining_hours}} hours",
"collateral-value": "Collateral Value",
"connect-funding": "Connect to view your account funding",
"custom-account-options-saved": "Advanced options set",
"cumulative-interest-chart": "Cumulative Interest Chart",
"daily-fee": "Daily Fee",
"daily-fee": "Est. Daily Fee",
"daily-volume": "24h Volume",
"export": "Export {{dataType}}",
"find-accounts": "Find Accounts",
@ -30,6 +31,7 @@
"maint-health-contributions": "Maint Health Contributions",
"more-account-stats": "More Account Stats",
"no-data": "No data to display",
"no-funding": "No funding earned or paid",
"no-pnl-history": "No PnL History",
"not-following-yet": "Your not following any accounts yet...",
"okay-got-it": "Okay, Got It",
@ -44,6 +46,7 @@
"token-slots-manage": "You can manage your account slots here:",
"token-slots-nearly-full": "You have one token slot left",
"token-slots-warning-desc": "Mango Accounts are limited in the number of tokens they can hold at one time. When you fully withdraw a token or fully repay a borrow, a slot will become available again.",
"tooltip-collateral-fees-charged": "Collateral funding fees are being charged",
"tooltip-collateral-value": "The amount of capital this token gives you to use for trades and loans.",
"tooltip-connect-to-follow": "Connect to follow accounts",
"tooltip-follow-account": "Follow account on your account page",

View File

@ -213,6 +213,7 @@
"updating-account-name": "Updating Account Name...",
"utilization": "Utilization",
"value": "Value",
"view-fees": "View Fees",
"view-transaction": "View Transaction",
"wallet": "Wallet",
"wallet-address": "Wallet Address",

View File

@ -5,20 +5,21 @@
"advanced-options-desc": "Mango帐户对帐户一次可以持有的币种数量和市场数量有限制。 这是Solana 帐户的特征之一。 使用滑杆为你的新帐户自订币种以市场位置。",
"assets": "资产",
"assets-liabilities": "资产和债务",
"collateral": "Collateral",
"collateral-funding-modal-heading": "You'll be charged collateral fees in {{remaining_hours}} hours",
"collateral": "质押品",
"collateral-funding-modal-heading": "{{remaining_hours}}小时之后Mango将收取你的质押品费",
"collateral-value": "质押品价值",
"connect-funding": "Connect to view your account funding",
"custom-account-options-saved": "已改高级设定",
"cumulative-interest-chart": "累积利息图表",
"daily-fee": "Daily Fee",
"daily-fee": "每日费用",
"daily-volume": "24小时交易量",
"export": "导出{{dataType}}",
"find-accounts": "寻找帐户",
"follow": "关注",
"followed-accounts": "你关注的帐户",
"funding-chart": "资金费图表",
"funding-type": "Funding Type",
"hide-announcements": "隐藏通知",
"funding-type": "资金费类别",
"hide-announcements": "隐藏通知",
"health-contributions": "健康度贡献",
"init-health": "初始健康度",
"init-health-contribution": "初始健康贡献",
@ -30,9 +31,10 @@
"maint-health-contributions": "维持健康度",
"more-account-stats": "更多帐户统计",
"no-data": "无数据可显示",
"no-funding": "No funding earned or paid",
"no-pnl-history": "无盈亏历史",
"not-following-yet": "你尚未关注任何帐户...",
"okay-got-it": "Okay, Got It",
"okay-got-it": "好,动了",
"open-settings": "打开设定",
"pnl-chart": "盈亏图表",
"pnl-history": "盈亏历史",
@ -44,6 +46,7 @@
"token-slots-manage": "你在此可以管理帐户币位:",
"token-slots-nearly-full": "你剩下一个币位",
"token-slots-warning-desc": "Mango帐户可以持有的币种数量是有限的。当你完全提取币种或完全偿还借贷时币位将再次可用。",
"tooltip-collateral-fees-charged": "Collateral funding fees are being charged",
"tooltip-collateral-value": "该币种为你提供用于交易与借贷的资本金额。",
"tooltip-connect-to-follow": "连接钱包以关注帐户",
"tooltip-follow-account": "在你帐户页可以关注此帐户",
@ -63,7 +66,7 @@
"volume-chart": "交易量图表",
"warning-uninsured": "{{token}}不受保证。",
"week-starting": "从{{week}}来算的一周",
"whats-this": "What's This?",
"whats-this": "这是什么?",
"zero-balances": "显示等于零的余额",
"zero-collateral": "无质押品"
}

View File

@ -21,7 +21,7 @@
"amount-owed": "欠款",
"announcements": "通知",
"asked-sign-transaction": "你会被要求签署交易",
"asset": "Asset",
"asset": "资产",
"asset-liability-weight": "资产/债务权重",
"asset-liability-weight-desc": "资产权重在账户健康计算中对质押品价值进行扣减。资产权重越低,资产对质押品的影响越小。债务权重恰恰相反(在健康计算中增加债务价值)。",
"asset-weight": "资产权重",
@ -212,6 +212,7 @@
"updating-account-name": "正载改帐户标签...",
"utilization": "利用率",
"value": "价值",
"view-fees": "View Fees",
"view-transaction": "查看交易",
"wallet": "钱包",
"wallet-address": "钱包地址",

View File

@ -1,7 +1,7 @@
{
"base-liquidation-fee": "基本清算费用",
"closest-to-liquidation": "最接近清算的持仓",
"collateral-funding-fee": "Collateral Funding Fee (Per Day)",
"collateral-funding-fee": "质押品资金费用",
"daily": "日",
"hourly": "小时",
"largest-perp-positions": "最大持仓",

View File

@ -5,19 +5,20 @@
"advanced-options-desc": "Mango帳戶對帳戶一次可以持有的幣種數量和市場數量有限制。 這是 Solana 帳戶的特徵之一。 使用滑桿為你的新帳戶自訂幣種以市場位置。",
"assets": "資產",
"assets-liabilities": "資產和債務",
"collateral": "Collateral",
"collateral-funding-modal-heading": "You'll be charged collateral fees in {{remaining_hours}} hours",
"collateral": "質押品",
"collateral-funding-modal-heading": "{{remaining_hours}}小時之後Mango將收取你的質押品費",
"collateral-value": "質押品價值",
"connect-funding": "Connect to view your account funding",
"custom-account-options-saved": "已改高級設定",
"cumulative-interest-chart": "累積利息圖表",
"daily-fee": "Daily Fee",
"daily-fee": "每日費用",
"daily-volume": "24小時交易量",
"export": "導出{{dataType}}",
"find-accounts": "尋找帳戶",
"follow": "關注",
"followed-accounts": "你關注的帳戶",
"funding-chart": "資金費圖表",
"funding-type": "Funding Type",
"funding-type": "資金費類別",
"hide-announcements": "隱藏通知",
"health-contributions": "健康度貢獻",
"init-health": "初始健康度",
@ -30,9 +31,10 @@
"maint-health-contributions": "維持健康度",
"more-account-stats": "更多帳戶統計",
"no-data": "無數據可顯示",
"no-funding": "No funding earned or paid",
"no-pnl-history": "無盈虧歷史",
"not-following-yet": "你尚未關注任何帳戶...",
"okay-got-it": "Okay, Got It",
"okay-got-it": "好,動了",
"open-settings": "打開設定",
"pnl-chart": "盈虧圖表",
"pnl-history": "盈虧歷史",
@ -44,6 +46,7 @@
"token-slots-manage": "你在此可以管理帳戶幣位:",
"token-slots-nearly-full": "你剩下一個幣位",
"token-slots-warning-desc": "Mango帳戶可以持有的幣種數量是有限的。當你完全提取幣種或完全償還借貸時幣位將再次可用。",
"tooltip-collateral-fees-charged": "Collateral funding fees are being charged",
"tooltip-collateral-value": "該幣種為你提供用於交易與借貸的資本金額。",
"tooltip-connect-to-follow": "連接錢包以關注帳戶",
"tooltip-follow-account": "在你帳戶頁可以關注此帳戶",
@ -63,7 +66,7 @@
"volume-chart": "交易量圖表",
"warning-uninsured": "{{token}}不受保證。",
"week-starting": "從{{week}}來算的一周",
"whats-this": "What's This?",
"whats-this": "這是甚麼?",
"zero-balances": "顯示等於零的餘額",
"zero-collateral": "無質押品"
}

View File

@ -21,7 +21,7 @@
"amount-owed": "欠款",
"announcements": "通知",
"asked-sign-transaction": "你會被要求簽署交易",
"asset": "Asset",
"asset": "資產",
"asset-liability-weight": "資產/債務權重",
"asset-liability-weight-desc": "資產權重在賬戶健康計算中對質押品價值進行扣減。資產權重越低,資產對質押品的影響越小。債務權重恰恰相反(在健康計算中增加債務價值)。",
"asset-weight": "資產權重",
@ -212,6 +212,7 @@
"updating-account-name": "正載改帳戶標籤...",
"utilization": "利用率",
"value": "價值",
"view-fees": "View Fees",
"view-transaction": "查看交易",
"wallet": "錢包",
"wallet-address": "錢包地址",

View File

@ -1,7 +1,7 @@
{
"base-liquidation-fee": "基本清算費用",
"closest-to-liquidation": "最接近清算的持倉",
"collateral-funding-fee": "Collateral Funding Fee (Per Day)",
"collateral-funding-fee": "質押品資金費用",
"daily": "日",
"hourly": "小時",
"largest-perp-positions": "最大持倉",

View File

@ -131,7 +131,7 @@ export const JUPITER_API_DEVNET = 'https://api.jup.ag/api/tokens/devnet'
export const JUPITER_PRICE_API_MAINNET = 'https://price.jup.ag/v4/' // V6 Does not yet support /price requests as of 16/10/2023
export const JUPITER_V6_QUOTE_API_MAINNET = 'https://quote-api.jup.ag/v6'
export const JUPITER_V6_QUOTE_API_MAINNET = process.env.NEXT_PUBLIC_JUPITER_V6_QUOTE_API_MAINNET || 'https://public.jupiterapi.com'
export const NOTIFICATION_API = 'https://notifications-api.herokuapp.com/'

View File

@ -350,10 +350,10 @@
bn.js "^5.2.1"
eslint-config-prettier "^9.0.0"
"@blockworks-foundation/mango-v4-settings@0.14.21":
version "0.14.21"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4-settings/-/mango-v4-settings-0.14.21.tgz#d7aeb3bc827acd7d558bfba5d8ec1b48c590a746"
integrity sha512-QbveR8YSH4DI7sskeYBpEBHREWF2bCh/rJ7WymSlqmsIYR1DOvsk+ZqUdrDCtGEjZZb+3jrP77jjc3XMe1jZig==
"@blockworks-foundation/mango-v4-settings@0.14.22":
version "0.14.22"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4-settings/-/mango-v4-settings-0.14.22.tgz#7d7c9759b73d2c8166cf5f0871969e3764ea4139"
integrity sha512-YSJrCgeI6aC/RsL8dRyJmpKYB2CkY9YaiZ9PVjNWrQOcgQkp/DNaaI1CBFpZshtg6VtpFraQh6IrOmXzaAvglA==
dependencies:
bn.js "^5.2.1"
eslint-config-prettier "^9.0.0"