Merge branch 'main' into perp-market-details-modal

This commit is contained in:
tlrsssss 2023-04-03 21:43:58 -04:00 committed by GitHub
commit 5c03151a2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 377 additions and 220 deletions

View File

@ -1,3 +1,5 @@
import Decimal from 'decimal.js'
/* eslint-disable @typescript-eslint/no-explicit-any */
export const NEXT_PUBLIC_BIRDEYE_API_KEY =
process.env.NEXT_PUBLIC_BIRDEYE_API_KEY ||
@ -59,3 +61,80 @@ export function getNextBarTime(lastBar: any, resolution = '1D') {
return nextBarTime
}
export const SUBSCRIPT_NUMBER_MAP: Record<number, string> = {
4: '₄',
5: '₅',
6: '₆',
7: '₇',
8: '₈',
9: '₉',
10: '₁₀',
11: '₁₁',
12: '₁₂',
13: '₁₃',
14: '₁₄',
15: '₁₅',
}
export const calcPricePrecision = (num: number | string) => {
if (!num) return 8
switch (true) {
case Math.abs(+num) < 0.00000000001:
return 16
case Math.abs(+num) < 0.000000001:
return 14
case Math.abs(+num) < 0.0000001:
return 12
case Math.abs(+num) < 0.00001:
return 10
case Math.abs(+num) < 0.05:
return 6
case Math.abs(+num) < 1:
return 4
case Math.abs(+num) < 20:
return 3
default:
return 2
}
}
export const formatPrice = (
num: number,
precision?: number,
gr0 = true
): string => {
if (!num) {
return num.toString()
}
if (!precision) {
precision = calcPricePrecision(+num)
}
let formated: string = new Decimal(num).toFixed(precision)
if (formated.match(/^0\.[0]+$/g)) {
formated = formated.replace(/\.[0]+$/g, '')
}
if (gr0 && formated.match(/\.0{4,15}[1-9]+/g)) {
const match = formated.match(/\.0{4,15}/g)
if (!match) return ''
const matchString: string = match[0].slice(1)
formated = formated.replace(
/\.0{4,15}/g,
`.0${SUBSCRIPT_NUMBER_MAP[matchString.length]}`
)
}
return formated
}

View File

@ -69,6 +69,9 @@ export function subscribeOnStream(
}
if (!isOpen(socket)) {
console.warn('Socket Closed')
socket.addEventListener('open', (_event) => {
socket.send(JSON.stringify(msg))
})
return
}
console.warn('[subscribeBars birdeye]')

View File

@ -158,7 +158,7 @@ export const queryBirdeyeBars = async (
for (const bar of data.data.items) {
if (bar.unixTime >= from && bar.unixTime < to) {
const timestamp = bar.unixTime * 1000
if (bar.h > 22311) continue
if (bar.h >= 223111) continue
bars = [
...bars,
{
@ -223,7 +223,7 @@ export default {
session: '24x7',
timezone: 'Etc/UTC',
minmov: 1,
pricescale: 100,
pricescale: 10 ** 16,
has_intraday: true,
has_weekly_and_monthly: false,
has_empty_bars: true,

View File

@ -636,7 +636,7 @@ const AccountPage = () => {
{t('account:total-funding-earned')}
</p>
</Tooltip>
{Math.abs(fundingTotalValue) > 1 && mangoAccountAddress ? (
{mangoAccountAddress ? (
<Tooltip
className="hidden md:block"
content="Funding Chart"

View File

@ -1,5 +1,6 @@
import {
ArrowUpLeftIcon,
ChevronDownIcon,
QuestionMarkCircleIcon,
} from '@heroicons/react/20/solid'
import { useTranslation } from 'next-i18next'
@ -8,7 +9,7 @@ import { useCallback, useEffect, useState } from 'react'
import { useViewport } from '../../hooks/useViewport'
import { formatNumericValue } from '../../utils/numbers'
import { breakpoints } from '../../utils/theme'
import { IconButton } from '../shared/Button'
import Button, { IconButton } from '../shared/Button'
import Tooltip from '@components/shared/Tooltip'
import useJupiterMints from 'hooks/useJupiterMints'
import { Table, Td, Th, TrBody, TrHead } from '@components/shared/TableElements'
@ -18,6 +19,7 @@ import BorrowRepayModal from '@components/modals/BorrowRepayModal'
import BankAmountWithValue from '@components/shared/BankAmountWithValue'
import useBanksWithBalances from 'hooks/useBanksWithBalances'
import { getAvailableToBorrow } from './YourBorrowsTable'
import { Disclosure, Transition } from '@headlessui/react'
const AssetsBorrowsTable = () => {
const { t } = useTranslation(['common', 'token'])
@ -133,10 +135,10 @@ const AssetsBorrowsTable = () => {
</tbody>
</Table>
) : (
<div>
<div className="border-b border-th-bkg-3">
{banks.map((b) => {
const bank = b.bank
let logoURI
let logoURI: string | undefined
if (mangoTokens?.length) {
logoURI = mangoTokens.find(
(t) => t.address === bank.mint.toString()
@ -146,47 +148,75 @@ const AssetsBorrowsTable = () => {
const available = group ? getAvailableToBorrow(b, group) : 0
return (
<div
key={bank.name}
className="border-b border-th-bkg-3 px-6 py-4"
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
{logoURI ? (
<Image alt="" width="24" height="24" src={logoURI} />
) : (
<QuestionMarkCircleIcon className="h-7 w-7 text-th-fgd-3" />
)}
</div>
<p className="text-th-fgd-1">{bank.name}</p>
</div>
<div className="flex items-center space-x-4">
<div>
<p className="mb-0.5 text-right text-xs">
{t('available')}
</p>
<BankAmountWithValue
amount={available > 0 ? available : 0}
bank={bank}
/>
</div>
<div>
<p className="mb-0.5 text-right text-xs">{t('rate')}</p>
<p className="text-right text-th-down">
{formatNumericValue(bank.getBorrowRateUi(), 2)}%
</p>
</div>
<IconButton
disabled={b.maxBorrow === 0}
onClick={() => handleShowBorrowModal(bank.name)}
size="medium"
<Disclosure key={bank.name}>
{({ open }) => (
<>
<Disclosure.Button
className={`w-full border-t border-th-bkg-3 p-4 text-left first:border-t-0 focus:outline-none`}
>
<ArrowUpLeftIcon className="h-5 w-5" />
</IconButton>
</div>
</div>
</div>
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
{logoURI ? (
<Image
alt=""
width="24"
height="24"
src={logoURI}
/>
) : (
<QuestionMarkCircleIcon className="h-7 w-7 text-th-fgd-3" />
)}
</div>
<p className="text-th-fgd-1">{bank.name}</p>
</div>
<div className="flex items-center space-x-4">
<div>
<p className="mb-0.5 text-right text-xs">
{t('rate')}
</p>
<p className="text-right text-th-down">
{formatNumericValue(bank.getBorrowRateUi(), 2)}%
</p>
</div>
<ChevronDownIcon
className={`${
open ? 'rotate-180' : 'rotate-360'
} h-6 w-6 flex-shrink-0 text-th-fgd-3`}
/>
</div>
</div>
</Disclosure.Button>
<Transition
enter="transition ease-in duration-200"
enterFrom="opacity-0"
enterTo="opacity-100"
>
<Disclosure.Panel>
<div className="mx-4 grid grid-cols-2 gap-4 border-t border-th-bkg-3 pt-4 pb-4">
<div className="col-span-1">
<p className="text-xs text-th-fgd-3">
{t('available')}
</p>
<BankAmountWithValue
amount={available > 0 ? available : 0}
bank={bank}
/>
</div>
<Button
className="col-span-2 flex items-center justify-center"
onClick={() => handleShowBorrowModal(bank.name)}
secondary
>
<ArrowUpLeftIcon className="mr-2 h-5 w-5" />
{`${t('borrow')} ${bank.name.split(' ')[0]}`}
</Button>
</div>
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
)
})}
</div>

View File

@ -91,7 +91,7 @@ const BorrowPage = () => {
return (
<>
<div className="flex flex-col border-b border-th-bkg-3 px-6 py-4 lg:flex-row lg:items-center lg:justify-between">
<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:pr-6 md:pb-0">
<Tooltip

View File

@ -3,6 +3,7 @@ import useJupiterMints from 'hooks/useJupiterMints'
import {
ArrowDownRightIcon,
ArrowUpLeftIcon,
ChevronDownIcon,
NoSymbolIcon,
QuestionMarkCircleIcon,
} from '@heroicons/react/20/solid'
@ -17,12 +18,13 @@ import useMangoGroup from 'hooks/useMangoGroup'
import ConnectEmptyState from '../shared/ConnectEmptyState'
import { useWallet } from '@solana/wallet-adapter-react'
import Decimal from 'decimal.js'
import { IconButton } from '@components/shared/Button'
import Button, { IconButton } from '@components/shared/Button'
import { useCallback, useState } from 'react'
import BorrowRepayModal from '@components/modals/BorrowRepayModal'
import Tooltip from '@components/shared/Tooltip'
import BankAmountWithValue from '@components/shared/BankAmountWithValue'
import { BankWithBalance } from 'hooks/useBanksWithBalances'
import { Disclosure, Transition } from '@headlessui/react'
export const getAvailableToBorrow = (
bankWithBal: BankWithBalance,
@ -171,80 +173,120 @@ const YourBorrowsTable = ({ banks }: { banks: BankWithBalance[] }) => {
</tbody>
</Table>
) : (
banks.map((b) => {
const bank: Bank = b.bank
<div className="border-b border-th-bkg-3">
{banks.map((b) => {
const bank: Bank = b.bank
let logoURI
if (mangoTokens.length) {
logoURI = mangoTokens.find(
(t) => t.address === bank.mint.toString()
)?.logoURI
}
let logoURI: string | undefined
if (mangoTokens.length) {
logoURI = mangoTokens.find(
(t) => t.address === bank.mint.toString()
)?.logoURI
}
const available = group
? getAvailableToBorrow(b, group)
: new Decimal(0)
const available = group
? getAvailableToBorrow(b, group)
: new Decimal(0)
const borrowedAmount = mangoAccount
? Math.abs(mangoAccount.getTokenBalanceUi(bank))
: 0
const borrowedAmount = mangoAccount
? Math.abs(mangoAccount.getTokenBalanceUi(bank))
: 0
return (
<div
key={bank.name}
className="border-b border-th-bkg-3 px-6 py-4"
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
{logoURI ? (
<Image alt="" width="24" height="24" src={logoURI} />
) : (
<QuestionMarkCircleIcon className="h-7 w-7 text-th-fgd-3" />
)}
</div>
<p className="text-th-fgd-1">{bank.name}</p>
</div>
<div className="flex items-center space-x-4">
<div>
<p className="mb-0.5 text-right text-xs">
{t('borrow:borrowed-amount')}
</p>
<BankAmountWithValue
amount={borrowedAmount}
bank={bank}
/>
</div>
<div>
<p className="mb-0.5 text-right text-xs">{t('rate')}</p>
<p className="text-right text-th-down">
{formatNumericValue(bank.getBorrowRateUi(), 2)}%
</p>
</div>
<div className="flex space-x-2">
<IconButton
onClick={() =>
handleShowActionModals(bank.name, 'repay')
}
size="medium"
return (
<Disclosure key={bank.name}>
{({ open }) => (
<>
<Disclosure.Button
className={`w-full border-t border-th-bkg-3 p-4 text-left first:border-t-0 focus:outline-none`}
>
<ArrowDownRightIcon className="h-5 w-5" />
</IconButton>
<IconButton
disabled={available.eq(0)}
onClick={() =>
handleShowActionModals(bank.name, 'borrow')
}
size="medium"
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="mr-2.5 flex flex-shrink-0 items-center">
{logoURI ? (
<Image
alt=""
width="24"
height="24"
src={logoURI}
/>
) : (
<QuestionMarkCircleIcon className="h-7 w-7 text-th-fgd-3" />
)}
</div>
<p className="text-th-fgd-1">{bank.name}</p>
</div>
<div className="flex items-center space-x-4">
<div>
<p className="mb-0.5 text-right text-xs">
{t('borrow:borrowed-amount')}
</p>
<BankAmountWithValue
amount={borrowedAmount}
bank={bank}
/>
</div>
<ChevronDownIcon
className={`${
open ? 'rotate-180' : 'rotate-360'
} h-6 w-6 flex-shrink-0 text-th-fgd-3`}
/>
</div>
</div>
</Disclosure.Button>
<Transition
enter="transition ease-in duration-200"
enterFrom="opacity-0"
enterTo="opacity-100"
>
<ArrowUpLeftIcon className="h-5 w-5" />
</IconButton>
</div>
</div>
</div>
</div>
)
})
<Disclosure.Panel>
<div className="mx-4 grid grid-cols-2 gap-4 border-t border-th-bkg-3 pt-4 pb-4">
<div className="col-span-1">
<p className="text-xs text-th-fgd-3">
{t('rate')}
</p>
<p className="font-mono text-th-down">
{formatNumericValue(bank.getBorrowRateUi(), 2)}%
</p>
</div>
<div className="col-span-1">
<p className="text-xs text-th-fgd-3">
{t('available')}
</p>
<BankAmountWithValue
amount={available}
bank={bank}
/>
</div>
<Button
className="col-span-1 flex items-center justify-center"
disabled={!mangoAccount}
onClick={() =>
handleShowActionModals(bank.name, 'repay')
}
secondary
>
<ArrowDownRightIcon className="mr-2 h-5 w-5" />
{`${t('repay')} ${bank.name.split(' ')[0]}`}
</Button>
<Button
className="col-span-1 flex items-center justify-center"
onClick={() =>
handleShowActionModals(bank.name, 'borrow')
}
secondary
>
<ArrowUpLeftIcon className="mr-2 h-5 w-5" />
{`${t('borrow')} ${bank.name.split(' ')[0]}`}
</Button>
</div>
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
)
})}
</div>
)
) : mangoAccountAddress || connected ? (
<div className="border-b border-th-bkg-3">

View File

@ -28,6 +28,7 @@ const PerpMarketDetails = ({
const [priceDaysToShow, setPriceDaysToShow] = useState('30')
const [oiDaysToShow, setOiDaysToShow] = useState('30')
const [hourlyFundingeDaysToShow, setHourlyFundingDaysToShow] = useState('30')
const [instantFundingDaysToShow, setInstantFundingDaysToShow] = useState('30')
const rate = usePerpFundingRate()
const [marketStats, lastStat] = useMemo(() => {
@ -62,6 +63,16 @@ const PerpMarketDetails = ({
}
}, [marketStats, fundingRate])
const instantFundingRateStats = useMemo(() => {
if (marketStats) {
return marketStats.map((stat) => ({
...stat,
instantaneous_funding_rate: stat.instantaneous_funding_rate * 100,
}))
}
return []
}, [marketStats])
return (
<div className="grid grid-cols-2">
<div className="col-span-2 flex items-center border-b border-th-bkg-3 px-6 py-3">
@ -119,7 +130,7 @@ const PerpMarketDetails = ({
yKey={'open_interest'}
/>
</div>
<div className="col-span-2 border-b border-r border-th-bkg-3 py-4 px-6 md:col-span-1">
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1">
<DetailedAreaChart
data={perpHourlyStats ? perpHourlyStats : []}
daysToShow={hourlyFundingeDaysToShow}
@ -135,6 +146,22 @@ const PerpMarketDetails = ({
yDecimals={5}
/>
</div>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:pl-6">
<DetailedAreaChart
data={instantFundingRateStats}
daysToShow={instantFundingDaysToShow}
setDaysToShow={setInstantFundingDaysToShow}
heightClass="h-64"
loading={loadingPerpStats}
loaderHeightClass="h-[350px]"
suffix="%"
tickFormat={(x) => formatNumericValue(x, 4)}
title={t('trade:instantaneous-funding')}
xKey="date_hour"
yKey={'instantaneous_funding_rate'}
yDecimals={5}
/>
</div>
</>
) : null}
</div>

View File

@ -81,7 +81,6 @@ const SwapHistoryTable = () => {
signature,
swap_in_amount,
swap_in_loan_origination_fee,
swap_in_price_usd,
swap_in_symbol,
swap_out_amount,
loan,
@ -137,23 +136,15 @@ const SwapHistoryTable = () => {
src={baseLogoURI || ''}
/>
</div>
<div>
<p className="whitespace-nowrap">
<FormatNumericValue
value={swap_in_amount}
decimals={inDecimals}
/>{' '}
<span className="font-body text-th-fgd-3">
{inSymbol}
</span>
</p>
<p className="text-xs text-th-fgd-3">
<span className="font-body text-th-fgd-4">
{t('price')}:
</span>{' '}
<FormatNumericValue value={swap_in_price_usd} isUsd />
</p>
</div>
<p className="whitespace-nowrap">
<FormatNumericValue
value={swap_in_amount}
decimals={inDecimals}
/>{' '}
<span className="font-body text-th-fgd-3">
{inSymbol}
</span>
</p>
</div>
</Td>
<Td>
@ -166,24 +157,15 @@ const SwapHistoryTable = () => {
src={quoteLogoURI || ''}
/>
</div>
<div>
<p className="whitespace-nowrap">
<FormatNumericValue
value={swap_out_amount}
decimals={outDecimals}
/>{' '}
<span className="font-body text-th-fgd-3">
{outSymbol}
</span>
</p>
<p className="text-xs text-th-fgd-4">
<span className="font-body">{t('price')}:</span>{' '}
<FormatNumericValue
value={swap_out_price_usd}
isUsd
/>
</p>
</div>
<p className="whitespace-nowrap">
<FormatNumericValue
value={swap_out_amount}
decimals={outDecimals}
/>{' '}
<span className="font-body text-th-fgd-3">
{outSymbol}
</span>
</p>
</div>
</Td>
<Td>
@ -253,7 +235,6 @@ const SwapHistoryTable = () => {
signature,
swap_in_amount,
swap_in_loan_origination_fee,
swap_in_price_usd,
swap_in_symbol,
swap_out_amount,
loan,
@ -345,28 +326,6 @@ const SwapHistoryTable = () => {
/>
</p>
</div>
<div className="col-span-1">
<p className="text-xs text-th-fgd-3">
{`${swap_in_symbol} ${t('price')}`}
</p>
<p className="font-mono text-th-fgd-1">
<FormatNumericValue
value={swap_in_price_usd}
isUsd
/>
</p>
</div>
<div className="col-span-1">
<p className="text-xs text-th-fgd-3">
{`${swap_out_symbol} ${t('price')}`}
</p>
<p className="font-mono text-th-fgd-1">
<FormatNumericValue
value={swap_out_price_usd}
isUsd
/>
</p>
</div>
{borrowAmount ? (
<>
<div className="col-span-1">

View File

@ -11,7 +11,11 @@ import useSelectedMarket from 'hooks/useSelectedMarket'
import { useTranslation } from 'next-i18next'
import { useEffect, useMemo, useState } from 'react'
import { Token } from 'types/jupiter'
import { getDecimalCount, numberCompacter } from 'utils/numbers'
import {
formatCurrencyValue,
getDecimalCount,
numberCompacter,
} from 'utils/numbers'
import MarketSelectDropdown from './MarketSelectDropdown'
import PerpFundingRate from './PerpFundingRate'
import { BorshAccountsCoder } from '@coral-xyz/anchor'
@ -179,8 +183,9 @@ const AdvancedMarketHeader = ({
</div>
<div className="font-mono text-xs text-th-fgd-2">
{price ? (
`$${price.toFixed(
getDecimalCount(serumOrPerpMarket?.tickSize || 0.01) + 1
`${formatCurrencyValue(
price,
getDecimalCount(serumOrPerpMarket?.tickSize || 0.01)
)}`
) : (
<span className="text-th-fgd-4"></span>

View File

@ -115,7 +115,7 @@ const AdvancedTradeForm = () => {
s.tradeForm.baseSize = e.value
if (price && e.value !== '' && !Number.isNaN(Number(e.value))) {
s.tradeForm.quoteSize = (price * parseFloat(e.value)).toString()
s.tradeForm.quoteSize = new Decimal(price).mul(e.value).toFixed()
} else {
s.tradeForm.quoteSize = ''
}
@ -135,7 +135,7 @@ const AdvancedTradeForm = () => {
s.tradeForm.quoteSize = e.value
if (price && e.value !== '' && !Number.isNaN(Number(e.value))) {
s.tradeForm.baseSize = (parseFloat(e.value) / price).toString()
s.tradeForm.baseSize = new Decimal(e.value).div(price).toFixed()
} else {
s.tradeForm.baseSize = ''
}
@ -415,7 +415,7 @@ const AdvancedTradeForm = () => {
thousandSeparator=","
allowNegative={false}
isNumericString={true}
decimalScale={6}
decimalScale={tickDecimals}
name="price"
id="price"
className="ml-2 w-full bg-transparent font-mono focus:outline-none"

View File

@ -7,7 +7,7 @@ import useSelectedMarket from 'hooks/useSelectedMarket'
import useUnownedAccount from 'hooks/useUnownedAccount'
import { useTranslation } from 'next-i18next'
import { useCallback, useMemo } from 'react'
import { formatNumericValue } from 'utils/numbers'
import { floorToDecimal } from 'utils/numbers'
import { useSpotMarketMax } from './SpotSlider'
const MaxSizeButton = ({
@ -59,30 +59,33 @@ const MaxSizeButton = ({
const set = mangoStore.getState().set
set((state) => {
if (side === 'buy') {
state.tradeForm.quoteSize = formatNumericValue(max, tickDecimals)
state.tradeForm.quoteSize = floorToDecimal(max, tickDecimals).toFixed()
if (tradeType === 'Market' || !price) {
state.tradeForm.baseSize = formatNumericValue(
state.tradeForm.baseSize = floorToDecimal(
max / oraclePrice,
minOrderDecimals
)
).toFixed()
} else {
state.tradeForm.baseSize = formatNumericValue(
state.tradeForm.baseSize = floorToDecimal(
max / parseFloat(price),
minOrderDecimals
)
).toFixed()
}
} else {
state.tradeForm.baseSize = formatNumericValue(max, minOrderDecimals)
state.tradeForm.baseSize = floorToDecimal(
max,
minOrderDecimals
).toFixed()
if (tradeType === 'Market' || !price) {
state.tradeForm.quoteSize = formatNumericValue(
state.tradeForm.quoteSize = floorToDecimal(
max * oraclePrice,
minOrderDecimals
)
).toFixed()
} else {
state.tradeForm.quoteSize = formatNumericValue(
state.tradeForm.quoteSize = floorToDecimal(
max * parseFloat(price),
minOrderDecimals
)
).toFixed()
}
}
})

View File

@ -87,7 +87,7 @@ const RecentTrades = () => {
{
cacheTime: 1000 * 60 * 15,
staleTime: 0,
enabled: !!selectedMarketAddress,
enabled: !!selectedMarketAddress && market instanceof PerpMarket,
refetchOnWindowFocus: true,
refetchInterval: 1000 * 10,
}

View File

@ -1,12 +1,14 @@
import { PerpMarket, Serum3Market } from '@blockworks-foundation/mango-v4'
import useSelectedMarket from 'hooks/useSelectedMarket'
import Link from 'next/link'
import { useRouter } from 'next/router'
import MarketLogos from './MarketLogos'
const TableMarketName = ({ market }: { market: PerpMarket | Serum3Market }) => {
const { selectedMarket } = useSelectedMarket()
const { asPath } = useRouter()
return selectedMarket?.name === market.name ? (
return selectedMarket?.name === market.name && asPath.includes('/trade') ? (
<div className="flex items-center">
<MarketLogos market={market} size="large" />
<span className="whitespace-nowrap">{market.name}</span>

View File

@ -37,6 +37,7 @@ import Datafeed from 'apis/datafeed'
// import PerpDatafeed from 'apis/mngo/datafeed'
import useStablePrice from 'hooks/useStablePrice'
import { isMangoError } from 'types'
import { formatPrice } from 'apis/birdeye/helpers'
export interface ChartContainerProps {
container: ChartingLibraryWidgetOptions['container']
@ -724,6 +725,18 @@ const TradingViewChart = () => {
'header_symbol_search',
'popup_hints',
],
// eslint-disable-next-line
// @ts-ignore
custom_formatters: {
priceFormatterFactory: () => {
return {
format: (price) => {
// return the appropriate format
return formatPrice(price)
},
}
},
},
fullscreen: defaultProps.fullscreen,
autosize: defaultProps.autosize,
studies_overrides: defaultProps.studiesOverrides,

View File

@ -83,27 +83,26 @@ const UnsettledTrades = ({
setSettleMktAddress(market.publicKey.toString())
try {
const mangoAccounts = await client.getAllMangoAccounts(group)
const perpPosition = mangoAccount.getPerpPosition(market.perpMarketIndex)
const mangoAccountPnl = perpPosition?.getEquityUi(market)
if (mangoAccountPnl === undefined)
throw new Error('Unable to get account P&L')
const sign = Math.sign(mangoAccountPnl)
const filteredAccounts = mangoAccounts
.map((m) => ({
mangoAccount: m,
pnl:
m?.getPerpPosition(market.perpMarketIndex)?.getEquityUi(market) ||
0,
}))
.sort((a, b) => sign * (a.pnl - b.pnl))
console.log('mangoAccountPnl', mangoAccountPnl)
const settleCandidates = await market.getSettlePnlCandidates(
client,
group,
mangoAccountPnl < 0 ? 'positive' : 'negative',
2
)
console.log('settleCandidates', settleCandidates)
const profitableAccount =
mangoAccountPnl >= 0 ? mangoAccount : filteredAccounts[0].mangoAccount
mangoAccountPnl < 0 ? settleCandidates[0].account : mangoAccount
const unprofitableAccount =
mangoAccountPnl < 0 ? mangoAccount : filteredAccounts[0].mangoAccount
mangoAccountPnl > 0 ? settleCandidates[0].account : mangoAccount
const txid = await client.perpSettlePnl(
group,

View File

@ -34,7 +34,7 @@ const ConnectedMenu = () => {
const onConnectFetchAccountData = async (wallet: Wallet) => {
if (!wallet.adapter.publicKey) return
await actions.fetchMangoAccounts(wallet.adapter.publicKey)
actions.fetchTourSettings(wallet.adapter.publicKey?.toString() as string)
// actions.fetchTourSettings(wallet.adapter.publicKey?.toString() as string)
actions.fetchWalletTokens(wallet.adapter.publicKey)
}

View File

@ -18,7 +18,7 @@
"postinstall": "tar -xzC public -f vendor/charting_library.tgz;tar -xzC public -f vendor/datafeeds.tgz"
},
"dependencies": {
"@blockworks-foundation/mango-v4": "^0.9.9",
"@blockworks-foundation/mango-v4": "^0.9.13",
"@headlessui/react": "1.6.6",
"@heroicons/react": "2.0.10",
"@project-serum/anchor": "0.25.0",

View File

@ -18,7 +18,7 @@
"grouping": "Grouping",
"hide-asks": "Hide Asks",
"hide-bids": "Hide Bids",
"hourly-funding": "Hourly Funding",
"hourly-funding": "Average Hourly Funding",
"in-orders": "In Orders",
"init-leverage": "Init Leverage",
"instantaneous-funding": "Instantaneous Funding",

View File

@ -712,10 +712,7 @@ const mangoStore = create<MangoStore>()(
)
}
if (
mangoAccount.serum3Active().length &&
Object.keys(openOrders).length
) {
if (mangoAccount.serum3Active().length) {
serumOpenOrderAccounts = Array.from(
mangoAccount.serum3OosMapByMarketIndex.values()
)
@ -914,7 +911,6 @@ const mangoStore = create<MangoStore>()(
state.profile.loadDetails = false
})
} catch (e) {
notify({ type: 'error', title: 'Failed to load profile details' })
console.error(e)
set((state) => {
state.profile.loadDetails = false
@ -936,7 +932,6 @@ const mangoStore = create<MangoStore>()(
state.settings.loading = false
})
} catch (e) {
notify({ type: 'error', title: 'Failed to load profile details' })
console.error(e)
set((state) => {
state.settings.loading = false

View File

@ -14,10 +14,10 @@
dependencies:
regenerator-runtime "^0.13.11"
"@blockworks-foundation/mango-v4@^0.9.9":
version "0.9.10"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.9.10.tgz#af6de3f552904e8f028912c908c7d145e01331c9"
integrity sha512-4eea9qpKN2Y7v8/HMabnTfueVkQtvnVxoi/mAGAumvnQJZ3KK74133KhTwdhWXgJUJfD72lLKhjj1uLKzzwg/g==
"@blockworks-foundation/mango-v4@^0.9.13":
version "0.9.13"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.9.13.tgz#4869bf461a31d7a32da676f8c41217a07ba77fe8"
integrity sha512-2fkwB2Ogpox6LtFTxAG/J6PqE//LYbYYt2M1zNEZSiqXoNjEOg6qeA6xDo6CWK1HTE66su7PqDmluje7yEl4dA==
dependencies:
"@coral-xyz/anchor" "^0.26.0"
"@project-serum/serum" "0.13.65"