merge main
This commit is contained in:
commit
034ab5071e
|
@ -49,7 +49,9 @@ const OnBoarding = ({ minVotes }: { minVotes?: BN }) => {
|
|||
</a>
|
||||
</>
|
||||
}
|
||||
desc={t('on-boarding-deposit-info')}
|
||||
desc={`${t('on-boarding-deposit-info')} ${t(
|
||||
'on-boarding-description-1'
|
||||
)}`}
|
||||
/>
|
||||
</div>
|
||||
) : null
|
||||
|
|
|
@ -7,6 +7,7 @@ import { useScreenshot } from 'hooks/useScreenshot'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { createRef, useEffect, useMemo, useState } from 'react'
|
||||
import { ModalProps } from 'types/modal'
|
||||
import { ttCommons, ttCommonsExpanded, ttCommonsMono } from 'utils/fonts'
|
||||
import { formatNumericValue, getDecimalCount } from 'utils/numbers'
|
||||
|
||||
interface SharePositionModalProps {
|
||||
|
@ -86,7 +87,9 @@ const SharePositionModal = ({
|
|||
aria-hidden="true"
|
||||
/>
|
||||
<div className="fixed inset-0 flex flex-col items-center justify-center text-center">
|
||||
<Dialog.Panel className="relative flex flex-col items-center">
|
||||
<Dialog.Panel
|
||||
className={`relative flex flex-col items-center ${ttCommons.variable} ${ttCommonsExpanded.variable} ${ttCommonsMono.variable}`}
|
||||
>
|
||||
<div
|
||||
className="relative h-[338px] w-[600px] overflow-hidden border border-slate-700 bg-gradient-to-b from-slate-900 to-black pt-6"
|
||||
ref={ref}
|
||||
|
|
|
@ -117,7 +117,7 @@ const RpcSettings = () => {
|
|||
<h2 className="mb-4 text-base">{t('rpc')}</h2>
|
||||
<div className="flex flex-col border-t border-th-bkg-3 py-4 md:flex-row md:items-center md:justify-between md:px-4">
|
||||
<p className="mb-2 md:mb-0">{t('rpc-provider')}</p>
|
||||
<div className="w-full min-w-[160px] md:w-auto">
|
||||
<div className="w-full min-w-[400px] md:w-auto">
|
||||
<ButtonGroup
|
||||
activeValue={rpcEndpoint.label}
|
||||
onChange={(v) => handleSetEndpointProvider(v)}
|
||||
|
@ -138,7 +138,6 @@ const RpcSettings = () => {
|
|||
}
|
||||
/>
|
||||
<Button
|
||||
className="h-12"
|
||||
disabled={!customUrl}
|
||||
onClick={handleSaveCustomEndpoint}
|
||||
>
|
||||
|
|
|
@ -33,12 +33,16 @@ const HealthImpact = ({
|
|||
</Tooltip>
|
||||
{currentMaintHealth ? (
|
||||
<div className="flex items-center space-x-1.5 font-mono">
|
||||
<p className={`text-th-fgd-2 ${small ? 'text-xs' : 'text-sm'}`}>
|
||||
<p
|
||||
className={`font-mono text-th-fgd-2 ${
|
||||
small ? 'text-xs' : 'text-sm'
|
||||
}`}
|
||||
>
|
||||
{currentMaintHealth}%
|
||||
</p>
|
||||
<ArrowRightIcon className="h-4 w-4 text-th-fgd-4" />
|
||||
<p
|
||||
className={`${
|
||||
className={`font-mono ${
|
||||
maintProjectedHealth < 50 && maintProjectedHealth > 15
|
||||
? 'text-th-warning'
|
||||
: maintProjectedHealth <= 15
|
||||
|
@ -48,16 +52,6 @@ const HealthImpact = ({
|
|||
>
|
||||
{maintProjectedHealth}%
|
||||
</p>
|
||||
{/* <span
|
||||
className={`text-xs ${
|
||||
maintProjectedHealth >= currentMaintHealth!
|
||||
? 'text-th-up'
|
||||
: 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
({maintProjectedHealth >= currentMaintHealth! ? '+' : ''}
|
||||
{maintProjectedHealth - currentMaintHealth!}%)
|
||||
</span> */}
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-xs text-th-fgd-2">–</span>
|
||||
|
|
|
@ -19,29 +19,28 @@ const MarketLogos = ({
|
|||
const logos = useMemo(() => {
|
||||
if (!group || !mangoTokens.length || !market)
|
||||
return { baseLogoURI: '', quoteLogoURI: '' }
|
||||
|
||||
let jupiterBaseToken, jupiterQuoteToken
|
||||
const marketName = market.name.split('-')[0].toLowerCase()
|
||||
let baseLogoURI, quoteLogoURI
|
||||
if (market instanceof Serum3Market) {
|
||||
const baseBank = group.getFirstBankByTokenIndex(market.baseTokenIndex)
|
||||
const quoteBank = group.getFirstBankByTokenIndex(market.quoteTokenIndex)
|
||||
|
||||
jupiterBaseToken = mangoTokens.find(
|
||||
const jupiterBaseToken = mangoTokens.find(
|
||||
(t) => t.address === baseBank.mint.toString()
|
||||
)
|
||||
jupiterQuoteToken = mangoTokens.find(
|
||||
const jupiterQuoteToken = mangoTokens.find(
|
||||
(t) => t.address === quoteBank.mint.toString()
|
||||
)
|
||||
|
||||
baseLogoURI = jupiterBaseToken?.logoURI
|
||||
quoteLogoURI = jupiterQuoteToken?.logoURI
|
||||
} else {
|
||||
jupiterBaseToken =
|
||||
mangoTokens.find(
|
||||
(t) => t.symbol.toUpperCase() === market.name.split('-')[0]
|
||||
) ||
|
||||
mangoTokens.find((t) =>
|
||||
t.symbol.toUpperCase()?.includes(market.name.split('-')[0])
|
||||
)
|
||||
const jupiterBaseToken =
|
||||
mangoTokens.find((t) => t.symbol.toLowerCase() === marketName) ||
|
||||
mangoTokens.find((t) => t.symbol.toLowerCase()?.includes(marketName))
|
||||
|
||||
baseLogoURI = `/icons/${marketName}.svg` || jupiterBaseToken?.logoURI
|
||||
}
|
||||
const baseLogoURI = jupiterBaseToken ? jupiterBaseToken.logoURI : ''
|
||||
const quoteLogoURI = jupiterQuoteToken ? jupiterQuoteToken.logoURI : ''
|
||||
return {
|
||||
baseLogoURI,
|
||||
quoteLogoURI,
|
||||
|
@ -76,7 +75,7 @@ const MarketLogos = ({
|
|||
<div className="absolute left-0 top-0 z-10">
|
||||
<LogoWithFallback
|
||||
alt=""
|
||||
className="flex-shrink-0 drop-shadow-md"
|
||||
className="flex-shrink-0"
|
||||
width={pxSize}
|
||||
height={pxSize}
|
||||
src={logos.baseLogoURI || `/icons/${logos?.name?.toLowerCase()}.svg`}
|
||||
|
|
|
@ -445,12 +445,10 @@ const OpenOrders = () => {
|
|||
>
|
||||
<div>
|
||||
{modifyOrderId !== o.orderId.toString() ? (
|
||||
<div className="flex items-start">
|
||||
<div className="mt-0.5">
|
||||
<MarketLogos market={market} size="large" />
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<MarketLogos market={market} size="large" />
|
||||
<div>
|
||||
<div className="mb-1 flex space-x-1 leading-none text-th-fgd-2">
|
||||
<div className="flex space-x-1 text-th-fgd-2">
|
||||
{selectedMarket?.name === market.name ? (
|
||||
<span className="whitespace-nowrap">
|
||||
{market.name}
|
||||
|
@ -472,15 +470,15 @@ const OpenOrders = () => {
|
|||
<SideBadge side={o.side} />
|
||||
)}
|
||||
</div>
|
||||
<p className="leading-none text-th-fgd-4">
|
||||
<span className="font-mono text-th-fgd-3">
|
||||
<p className="text-th-fgd-4">
|
||||
<span className="font-mono text-th-fgd-2">
|
||||
<FormatNumericValue
|
||||
value={o.size}
|
||||
decimals={getDecimalCount(minOrderSize)}
|
||||
/>
|
||||
</span>
|
||||
{' at '}
|
||||
<span className="font-mono text-th-fgd-3">
|
||||
<span className="font-mono text-th-fgd-2">
|
||||
<FormatNumericValue
|
||||
value={o.price}
|
||||
decimals={getDecimalCount(tickSize)}
|
||||
|
|
|
@ -5,12 +5,7 @@ import Button, { IconButton, LinkButton } from '@components/shared/Button'
|
|||
import ConnectEmptyState from '@components/shared/ConnectEmptyState'
|
||||
import FormatNumericValue from '@components/shared/FormatNumericValue'
|
||||
import { Table, Td, Th, TrBody, TrHead } from '@components/shared/TableElements'
|
||||
import {
|
||||
ArrowTrendingDownIcon,
|
||||
ArrowTrendingUpIcon,
|
||||
ChevronDownIcon,
|
||||
NoSymbolIcon,
|
||||
} from '@heroicons/react/20/solid'
|
||||
import { ChevronDownIcon, NoSymbolIcon } from '@heroicons/react/20/solid'
|
||||
import { useWallet } from '@solana/wallet-adapter-react'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import useMangoAccount from 'hooks/useMangoAccount'
|
||||
|
@ -30,6 +25,7 @@ import Tooltip from '@components/shared/Tooltip'
|
|||
import { Disclosure, Transition } from '@headlessui/react'
|
||||
import useOpenPerpPositions from 'hooks/useOpenPerpPositions'
|
||||
import PnlTooltipContent from '@components/shared/PnlTooltipContent'
|
||||
import PerpSideBadge from './PerpSideBadge'
|
||||
|
||||
const PerpPositions = () => {
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
|
@ -98,218 +94,203 @@ const PerpPositions = () => {
|
|||
<>
|
||||
{mangoAccount && openPerpPositions.length ? (
|
||||
showTableView ? (
|
||||
<>
|
||||
<div className="thin-scroll overflow-x-auto">
|
||||
<Table>
|
||||
<thead>
|
||||
<TrHead>
|
||||
<Th className="text-left">{t('market')}</Th>
|
||||
<Th className="text-right">{t('trade:size')}</Th>
|
||||
<Th className="text-right">{t('trade:avg-entry-price')}</Th>
|
||||
<Th>
|
||||
<div className="flex justify-end">
|
||||
<Tooltip content={t('trade:tooltip-est-liq-price')}>
|
||||
<span className="tooltip-underline">
|
||||
{t('trade:est-liq-price')}
|
||||
</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</Th>
|
||||
<Th className="text-right">{t('trade:unrealized-pnl')}</Th>
|
||||
{!isUnownedAccount ? <Th /> : null}
|
||||
</TrHead>
|
||||
</thead>
|
||||
<tbody>
|
||||
{openPerpPositions.map((position, index) => {
|
||||
const market = group.getPerpMarketByMarketIndex(
|
||||
position.marketIndex
|
||||
)
|
||||
const basePosition = position.getBasePositionUi(market)
|
||||
const floorBasePosition = floorToDecimal(
|
||||
basePosition,
|
||||
getDecimalCount(market.minOrderSize)
|
||||
).toNumber()
|
||||
const isSelectedMarket =
|
||||
selectedMarket instanceof PerpMarket &&
|
||||
selectedMarket.perpMarketIndex === position.marketIndex
|
||||
<div className="thin-scroll overflow-x-auto">
|
||||
<Table>
|
||||
<thead>
|
||||
<TrHead>
|
||||
<Th className="text-left">{t('market')}</Th>
|
||||
<Th className="text-right">{t('trade:size')}</Th>
|
||||
<Th className="text-right">{t('trade:avg-entry-price')}</Th>
|
||||
<Th>
|
||||
<div className="flex justify-end">
|
||||
<Tooltip content={t('trade:tooltip-est-liq-price')}>
|
||||
<span className="tooltip-underline">
|
||||
{t('trade:est-liq-price')}
|
||||
</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</Th>
|
||||
<Th className="text-right">{t('trade:unrealized-pnl')}</Th>
|
||||
{!isUnownedAccount ? <Th /> : null}
|
||||
</TrHead>
|
||||
</thead>
|
||||
<tbody>
|
||||
{openPerpPositions.map((position, index) => {
|
||||
const market = group.getPerpMarketByMarketIndex(
|
||||
position.marketIndex
|
||||
)
|
||||
const basePosition = position.getBasePositionUi(market)
|
||||
const floorBasePosition = floorToDecimal(
|
||||
basePosition,
|
||||
getDecimalCount(market.minOrderSize)
|
||||
).toNumber()
|
||||
const isSelectedMarket =
|
||||
selectedMarket instanceof PerpMarket &&
|
||||
selectedMarket.perpMarketIndex === position.marketIndex
|
||||
|
||||
if (!basePosition) return null
|
||||
if (!basePosition) return null
|
||||
|
||||
const isLong = basePosition > 0
|
||||
const avgEntryPrice =
|
||||
position.getAverageEntryPriceUi(market)
|
||||
const unsettledPnl = position.getUnsettledPnlUi(market)
|
||||
const totalPnl =
|
||||
position.cumulativePnlOverPositionLifetimeUi(market)
|
||||
const unrealizedPnl = position.getUnRealizedPnlUi(market)
|
||||
const realizedPnl = position.getRealizedPnlUi()
|
||||
const roe =
|
||||
(unrealizedPnl /
|
||||
(Math.abs(basePosition) * avgEntryPrice)) *
|
||||
100
|
||||
const estLiqPrice = position.getLiquidationPriceUi(
|
||||
group,
|
||||
mangoAccount
|
||||
)
|
||||
const isLong = basePosition > 0
|
||||
const avgEntryPrice = position.getAverageEntryPriceUi(market)
|
||||
const unsettledPnl = position.getUnsettledPnlUi(market)
|
||||
const totalPnl =
|
||||
position.cumulativePnlOverPositionLifetimeUi(market)
|
||||
const unrealizedPnl = position.getUnRealizedPnlUi(market)
|
||||
const realizedPnl = position.getRealizedPnlUi()
|
||||
const roe =
|
||||
(unrealizedPnl / (Math.abs(basePosition) * avgEntryPrice)) *
|
||||
100
|
||||
const estLiqPrice = position.getLiquidationPriceUi(
|
||||
group,
|
||||
mangoAccount
|
||||
)
|
||||
|
||||
return (
|
||||
<TrBody
|
||||
key={`${position.marketIndex}`}
|
||||
className="my-1 p-2"
|
||||
>
|
||||
<Td>
|
||||
<TableMarketName
|
||||
market={market}
|
||||
side={isLong ? 'long' : 'short'}
|
||||
/>
|
||||
</Td>
|
||||
<Td className="text-right font-mono">
|
||||
{isSelectedMarket ? (
|
||||
<div className="flex flex-col items-end space-y-0.5">
|
||||
<LinkButton
|
||||
className="font-normal underline underline-offset-2 md:underline-offset-4 md:hover:no-underline"
|
||||
onClick={() =>
|
||||
handlePositionClick(floorBasePosition, market)
|
||||
}
|
||||
>
|
||||
<FormatNumericValue
|
||||
value={Math.abs(basePosition)}
|
||||
decimals={getDecimalCount(
|
||||
market.minOrderSize
|
||||
)}
|
||||
/>
|
||||
</LinkButton>
|
||||
<FormatNumericValue
|
||||
classNames="text-xs text-th-fgd-3"
|
||||
value={
|
||||
Math.abs(floorBasePosition) * market._uiPrice
|
||||
}
|
||||
isUsd
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col items-end space-y-0.5">
|
||||
return (
|
||||
<TrBody
|
||||
key={`${position.marketIndex}`}
|
||||
className="my-1 p-2"
|
||||
>
|
||||
<Td>
|
||||
<TableMarketName
|
||||
market={market}
|
||||
side={isLong ? 'long' : 'short'}
|
||||
/>
|
||||
</Td>
|
||||
<Td className="text-right font-mono">
|
||||
{isSelectedMarket ? (
|
||||
<div className="flex flex-col items-end space-y-0.5">
|
||||
<LinkButton
|
||||
className="font-normal underline underline-offset-2 md:underline-offset-4 md:hover:no-underline"
|
||||
onClick={() =>
|
||||
handlePositionClick(floorBasePosition, market)
|
||||
}
|
||||
>
|
||||
<FormatNumericValue
|
||||
value={Math.abs(basePosition)}
|
||||
decimals={getDecimalCount(market.minOrderSize)}
|
||||
/>
|
||||
<FormatNumericValue
|
||||
classNames="text-xs text-th-fgd-3"
|
||||
value={
|
||||
Math.abs(floorBasePosition) * market._uiPrice
|
||||
}
|
||||
isUsd
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Td>
|
||||
<Td className="font-mono">
|
||||
</LinkButton>
|
||||
<FormatNumericValue
|
||||
classNames="text-xs text-th-fgd-3"
|
||||
value={
|
||||
Math.abs(floorBasePosition) * market._uiPrice
|
||||
}
|
||||
isUsd
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col items-end space-y-0.5">
|
||||
<FormatNumericValue
|
||||
value={avgEntryPrice}
|
||||
decimals={getDecimalCount(market.tickSize)}
|
||||
isUsd
|
||||
value={Math.abs(basePosition)}
|
||||
decimals={getDecimalCount(market.minOrderSize)}
|
||||
/>
|
||||
<FormatNumericValue
|
||||
classNames="text-xs text-th-fgd-3"
|
||||
value={market.uiPrice}
|
||||
decimals={getDecimalCount(market.tickSize)}
|
||||
value={
|
||||
Math.abs(floorBasePosition) * market._uiPrice
|
||||
}
|
||||
isUsd
|
||||
/>
|
||||
</div>
|
||||
</Td>
|
||||
<Td className="text-right font-mono">
|
||||
{estLiqPrice ? (
|
||||
<FormatNumericValue
|
||||
value={estLiqPrice}
|
||||
decimals={getDecimalCount(market.tickSize)}
|
||||
isUsd
|
||||
/>
|
||||
) : (
|
||||
'–'
|
||||
)}
|
||||
</Td>
|
||||
<Td className="text-right font-mono">
|
||||
<div className="flex flex-col items-end ">
|
||||
<Tooltip
|
||||
content={
|
||||
<PnlTooltipContent
|
||||
unrealizedPnl={unrealizedPnl}
|
||||
realizedPnl={realizedPnl}
|
||||
totalPnl={totalPnl}
|
||||
unsettledPnl={unsettledPnl}
|
||||
/>
|
||||
}
|
||||
delay={100}
|
||||
>
|
||||
<span
|
||||
className={`tooltip-underline ${
|
||||
unrealizedPnl >= 0
|
||||
? 'text-th-up'
|
||||
: 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
<FormatNumericValue
|
||||
value={unrealizedPnl}
|
||||
isUsd
|
||||
decimals={2}
|
||||
/>
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Td>
|
||||
<Td className="font-mono">
|
||||
<div className="flex flex-col items-end space-y-0.5">
|
||||
<FormatNumericValue
|
||||
value={avgEntryPrice}
|
||||
decimals={getDecimalCount(market.tickSize)}
|
||||
isUsd
|
||||
/>
|
||||
<FormatNumericValue
|
||||
classNames="text-xs text-th-fgd-3"
|
||||
value={market.uiPrice}
|
||||
decimals={getDecimalCount(market.tickSize)}
|
||||
isUsd
|
||||
/>
|
||||
</div>
|
||||
</Td>
|
||||
<Td className="text-right font-mono">
|
||||
{estLiqPrice ? (
|
||||
<FormatNumericValue
|
||||
value={estLiqPrice}
|
||||
decimals={getDecimalCount(market.tickSize)}
|
||||
isUsd
|
||||
/>
|
||||
) : (
|
||||
'–'
|
||||
)}
|
||||
</Td>
|
||||
<Td className="text-right font-mono">
|
||||
<div className="flex flex-col items-end ">
|
||||
<Tooltip
|
||||
content={
|
||||
<PnlTooltipContent
|
||||
unrealizedPnl={unrealizedPnl}
|
||||
realizedPnl={realizedPnl}
|
||||
totalPnl={totalPnl}
|
||||
unsettledPnl={unsettledPnl}
|
||||
/>
|
||||
}
|
||||
delay={100}
|
||||
>
|
||||
<span
|
||||
className={
|
||||
roe >= 0 ? 'text-th-up' : 'text-th-down'
|
||||
}
|
||||
className={`tooltip-underline ${
|
||||
unrealizedPnl >= 0
|
||||
? 'text-th-up'
|
||||
: 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
<FormatNumericValue
|
||||
classNames="text-xs"
|
||||
value={roe}
|
||||
value={unrealizedPnl}
|
||||
isUsd
|
||||
decimals={2}
|
||||
/>
|
||||
%{' '}
|
||||
<span className="font-body text-xs text-th-fgd-3">
|
||||
(ROE)
|
||||
</span>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<span
|
||||
className={roe >= 0 ? 'text-th-up' : 'text-th-down'}
|
||||
>
|
||||
<FormatNumericValue
|
||||
classNames="text-xs"
|
||||
value={roe}
|
||||
decimals={2}
|
||||
/>
|
||||
%{' '}
|
||||
<span className="font-body text-xs text-th-fgd-3">
|
||||
(ROE)
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</Td>
|
||||
{!isUnownedAccount ? (
|
||||
<Td>
|
||||
<div className="flex items-center justify-end space-x-4">
|
||||
<Button
|
||||
className="text-xs"
|
||||
secondary
|
||||
size="small"
|
||||
onClick={() => showClosePositionModal(position)}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
<IconButton
|
||||
hideBg
|
||||
onClick={() =>
|
||||
handleShowShare(openPerpPositions[index])
|
||||
}
|
||||
disabled={!group || !basePosition}
|
||||
>
|
||||
<TwitterIcon className="h-4 w-4" />
|
||||
</IconButton>
|
||||
</div>
|
||||
</Td>
|
||||
{!isUnownedAccount ? (
|
||||
<Td>
|
||||
<div className="flex items-center justify-end space-x-4">
|
||||
<Button
|
||||
className="text-xs"
|
||||
secondary
|
||||
size="small"
|
||||
onClick={() => showClosePositionModal(position)}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
<IconButton
|
||||
hideBg
|
||||
onClick={() =>
|
||||
handleShowShare(openPerpPositions[index])
|
||||
}
|
||||
disabled={!group || !basePosition}
|
||||
>
|
||||
<TwitterIcon className="h-4 w-4" />
|
||||
</IconButton>
|
||||
</div>
|
||||
</Td>
|
||||
) : null}
|
||||
</TrBody>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</Table>
|
||||
</div>
|
||||
{showMarketCloseModal && positionToClose ? (
|
||||
<MarketCloseModal
|
||||
isOpen={showMarketCloseModal}
|
||||
onClose={hideClosePositionModal}
|
||||
position={positionToClose}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
) : null}
|
||||
</TrBody>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</Table>
|
||||
</div>
|
||||
) : (
|
||||
<div className="border-b border-th-bkg-3">
|
||||
{openPerpPositions.map((position, i) => {
|
||||
|
@ -349,50 +330,44 @@ const PerpPositions = () => {
|
|||
i === 0 ? 'border-t-0' : ''
|
||||
}`}
|
||||
>
|
||||
<div className="flex w-full flex-col sm:flex-row sm:items-center sm:justify-between">
|
||||
<div
|
||||
className={`flex items-center ${
|
||||
side === 'buy'
|
||||
? 'text-th-up'
|
||||
: side === 'sell'
|
||||
? 'text-th-down'
|
||||
: 'text-th-fgd-2'
|
||||
}`}
|
||||
>
|
||||
<MarketLogos market={market} size="large" />
|
||||
<span className="mr-1 whitespace-nowrap">
|
||||
{market.name}
|
||||
</span>
|
||||
{side === 'buy' ? (
|
||||
<ArrowTrendingUpIcon className="h-5 w-5" />
|
||||
) : side === 'sell' ? (
|
||||
<ArrowTrendingDownIcon className="h-5 w-5" />
|
||||
) : null}
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="font-mono">
|
||||
<FormatNumericValue
|
||||
value={Math.abs(basePosition)}
|
||||
decimals={getDecimalCount(market.minOrderSize)}
|
||||
/>{' '}
|
||||
<span className="font-body text-th-fgd-3">
|
||||
{market.name.split('-')[0]}
|
||||
<div className="flex items-center">
|
||||
<MarketLogos market={market} size="large" />
|
||||
<div>
|
||||
<div className="flex space-x-1 text-th-fgd-2">
|
||||
<span className="whitespace-nowrap">
|
||||
{market.name}
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-th-fgd-4">|</span>
|
||||
<span
|
||||
className={`font-mono ${
|
||||
unrealizedPnl > 0
|
||||
? 'text-th-up'
|
||||
: 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
<FormatNumericValue
|
||||
value={unrealizedPnl}
|
||||
isUsd
|
||||
decimals={2}
|
||||
<PerpSideBadge
|
||||
basePosition={side === 'buy' ? 1 : -1}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="font-mono">
|
||||
<FormatNumericValue
|
||||
value={Math.abs(basePosition)}
|
||||
decimals={getDecimalCount(
|
||||
market.minOrderSize
|
||||
)}
|
||||
/>{' '}
|
||||
<span className="font-body text-th-fgd-3">
|
||||
{market.name.split('-')[0]}
|
||||
</span>
|
||||
</span>
|
||||
<span className="text-th-fgd-4">|</span>
|
||||
<span
|
||||
className={`font-mono ${
|
||||
unrealizedPnl > 0
|
||||
? 'text-th-up'
|
||||
: 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
<FormatNumericValue
|
||||
value={unrealizedPnl}
|
||||
isUsd
|
||||
decimals={2}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ChevronDownIcon
|
||||
|
@ -568,7 +543,7 @@ const PerpPositions = () => {
|
|||
disabled={!group || !basePosition}
|
||||
>
|
||||
<div className="flex items-center justify-center">
|
||||
<TwitterIcon className="mr-2 h-4 w-4" />
|
||||
<TwitterIcon className="mr-2 h-4 w-4 flex-shrink-0" />
|
||||
{t('trade:tweet-position')}
|
||||
</div>
|
||||
</Button>
|
||||
|
@ -601,6 +576,13 @@ const PerpPositions = () => {
|
|||
position={positionToShare!}
|
||||
/>
|
||||
) : null}
|
||||
{showMarketCloseModal && positionToClose ? (
|
||||
<MarketCloseModal
|
||||
isOpen={showMarketCloseModal}
|
||||
onClose={hideClosePositionModal}
|
||||
position={positionToClose}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ const Slippage = () => {
|
|||
<p className="tooltip-underline mr-4">{t('trade:est-slippage')}</p>
|
||||
</Tooltip>
|
||||
<p
|
||||
className={`${
|
||||
className={`font-mono ${
|
||||
slippage <= 1
|
||||
? 'text-th-success'
|
||||
: slippage <= 3
|
||||
|
|
|
@ -153,7 +153,7 @@ const TradeSummary = ({
|
|||
<div className="space-y-2 px-3 md:px-4">
|
||||
<div className="flex justify-between text-xs">
|
||||
<p>{t('trade:order-value')}</p>
|
||||
<p className="text-th-fgd-2">
|
||||
<p className="font-mono text-th-fgd-2">
|
||||
{orderValue ? <FormatNumericValue value={orderValue} isUsd /> : '–'}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Group } from '@blockworks-foundation/mango-v4'
|
||||
import { WRAPPED_SOL_MINT } from '@project-serum/serum/lib/token-instructions'
|
||||
import { CLUSTER } from '@store/mangoStore'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import useMangoGroup from 'hooks/useMangoGroup'
|
||||
|
@ -41,17 +40,6 @@ const useJupiterMints = (): {
|
|||
}
|
||||
)
|
||||
|
||||
if (res?.data?.mangoTokens.length) {
|
||||
const findSol = res.data.mangoTokens.find(
|
||||
(t) => t.address === WRAPPED_SOL_MINT.toString()
|
||||
)
|
||||
if (findSol) {
|
||||
if (findSol.logoURI !== '/icons/sol.svg') {
|
||||
findSol.logoURI = '/icons/sol.svg'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
mangoTokens: res?.data?.mangoTokens || [],
|
||||
jupiterTokens: res?.data?.jupiterTokens || [],
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16 32C24.8366 32 32 24.8366 32 16C32 7.16344 24.8366 0 16 0C7.16344 0 0 7.16344 0 16C0 24.8366 7.16344 32 16 32Z" fill="#F7931A"/>
|
||||
<path d="M23.1892 14.02C23.5032 11.924 21.9062 10.797 19.7242 10.045L20.4322 7.205L18.7042 6.775L18.0142 9.54C17.5602 9.426 17.0942 9.32 16.6292 9.214L17.3242 6.431L15.5962 6L14.8882 8.839C14.5122 8.753 14.1422 8.669 13.7842 8.579L13.7862 8.57L11.4022 7.975L10.9422 9.821C10.9422 9.821 12.2252 10.115 12.1982 10.133C12.8982 10.308 13.0242 10.771 13.0032 11.139L12.1972 14.374C12.2452 14.386 12.3072 14.404 12.3772 14.431L12.1942 14.386L11.0642 18.918C10.9782 19.13 10.7612 19.449 10.2712 19.328C10.2892 19.353 9.01523 19.015 9.01523 19.015L8.15723 20.993L10.4072 21.554C10.8252 21.659 11.2352 21.769 11.6382 21.872L10.9232 24.744L12.6502 25.174L13.3582 22.334C13.8302 22.461 14.2882 22.579 14.7362 22.691L14.0302 25.519L15.7582 25.949L16.4732 23.083C19.4212 23.641 21.6372 23.416 22.5702 20.75C23.3222 18.604 22.5332 17.365 20.9822 16.558C22.1122 16.298 22.9622 15.555 23.1892 14.02V14.02ZM19.2392 19.558C18.7062 21.705 15.0912 20.544 13.9192 20.253L14.8692 16.448C16.0412 16.741 19.7982 17.32 19.2392 19.558ZM19.7742 13.989C19.2872 15.942 16.2792 14.949 15.3042 14.706L16.1642 11.256C17.1392 11.499 20.2822 11.952 19.7742 13.989Z" fill="white"/>
|
||||
<path d="M28.1127 12.8648C28.6164 9.50263 26.0546 7.69482 22.5545 6.48855L23.6902 1.93293L20.9183 1.24317L19.8115 5.67848C19.0833 5.49561 18.3358 5.32558 17.5899 5.15555L18.7047 0.691363L15.9328 0L14.7971 4.55401C14.194 4.41606 13.6005 4.28132 13.0262 4.13695L13.0294 4.12251L9.20527 3.16808L8.46739 6.12923C8.46739 6.12923 10.5254 6.60083 10.4821 6.62971C11.605 6.91042 11.8071 7.65312 11.7734 8.24342L10.4805 13.4327C10.5575 13.4519 10.657 13.4808 10.7693 13.5241L10.4757 13.4519L8.66309 20.7216C8.52514 21.0617 8.17705 21.5734 7.39105 21.3793C7.41992 21.4194 5.37631 20.8772 5.37631 20.8772L4 24.0501L7.6092 24.95C8.27971 25.1185 8.93739 25.2949 9.58384 25.4601L8.43692 30.0671L11.2072 30.7568L12.3429 26.2012C13.1 26.4049 13.8347 26.5942 14.5533 26.7739L13.4208 31.3102L16.1927 32L17.3396 27.4027C22.0685 28.2978 25.6231 27.9368 27.1198 23.6603C28.326 20.218 27.0604 18.2305 24.5725 16.936C26.3851 16.5189 27.7486 15.3271 28.1127 12.8648V12.8648ZM21.7765 21.7483C20.9216 25.1922 15.1228 23.3299 13.2428 22.8631L14.7667 16.7595C16.6467 17.2295 22.6732 18.1583 21.7765 21.7483ZM22.6347 12.8151C21.8535 15.9479 17.0284 14.355 15.4644 13.9652L16.844 8.4311C18.4079 8.82089 23.4496 9.54755 22.6347 12.8151Z" fill="#F7931A"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
@ -1,26 +1,19 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2582_2263)">
|
||||
<path d="M16 32C24.8366 32 32 24.8366 32 16C32 7.16345 24.8366 0 16 0C7.16345 0 0 7.16345 0 16C0 24.8366 7.16345 32 16 32Z" fill="black"/>
|
||||
<path d="M6.15479 12.2139H6.18078C6.17324 12.2168 6.16359 12.2168 6.15479 12.2139Z" fill="#308D8A"/>
|
||||
<path d="M9.24648 19.7458C9.36718 19.6251 9.53314 19.5547 9.70917 19.5547H25.6719C25.9636 19.5547 26.1095 19.9067 25.9033 20.1129L22.75 23.2663C22.6293 23.387 22.4633 23.4574 22.2873 23.4574H6.3245C6.0328 23.4574 5.88695 23.1053 6.09315 22.8991L9.24648 19.7458Z" fill="url(#paint0_linear_2582_2263)"/>
|
||||
<path d="M9.24648 7.97236C9.37221 7.85166 9.53817 7.78125 9.70917 7.78125H25.6719C25.9636 7.78125 26.1095 8.1333 25.9033 8.33949L22.75 11.4928C22.6293 11.6135 22.4633 11.6839 22.2873 11.6839H6.3245C6.0328 11.6839 5.88695 11.3319 6.09315 11.1257L9.24648 7.97236Z" fill="url(#paint1_linear_2582_2263)"/>
|
||||
<path d="M22.75 13.8215C22.6293 13.7008 22.4633 13.6304 22.2873 13.6304H6.3245C6.0328 13.6304 5.88695 13.9824 6.09315 14.1886L9.24648 17.3419C9.36718 17.4626 9.53314 17.533 9.70917 17.533H25.6719C25.9636 17.533 26.1095 17.181 25.9033 16.9748L22.75 13.8215Z" fill="url(#paint2_linear_2582_2263)"/>
|
||||
</g>
|
||||
<path d="M5.97554 22.3175C6.16033 22.1327 6.41442 22.0249 6.68391 22.0249H31.1227C31.5693 22.0249 31.7926 22.5639 31.4769 22.8796L26.6492 27.7073C26.4644 27.8921 26.2103 27.9999 25.9408 27.9999H1.50203C1.05545 27.9999 0.832159 27.4609 1.14785 27.1452L5.97554 22.3175Z" fill="url(#paint0_linear_1184_2703)"/>
|
||||
<path d="M5.97554 4.29259C6.16803 4.1078 6.42212 4 6.68391 4H31.1227C31.5693 4 31.7926 4.53898 31.4769 4.85466L26.6492 9.68235C26.4644 9.86715 26.2103 9.97494 25.9408 9.97494H1.50203C1.05545 9.97494 0.832159 9.43596 1.14785 9.12028L5.97554 4.29259Z" fill="url(#paint1_linear_1184_2703)"/>
|
||||
<path d="M26.6492 13.2472C26.4644 13.0624 26.2103 12.9546 25.9408 12.9546H1.50203C1.05545 12.9546 0.832159 13.4936 1.14785 13.8093L5.97554 18.6369C6.16033 18.8217 6.41442 18.9295 6.68391 18.9295H31.1227C31.5693 18.9295 31.7926 18.3906 31.4769 18.0749L26.6492 13.2472Z" fill="url(#paint2_linear_1184_2703)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_2582_2263" x1="24.147" y1="5.8975" x2="13.0995" y2="27.058" gradientUnits="userSpaceOnUse">
|
||||
<linearGradient id="paint0_linear_1184_2703" x1="28.7881" y1="1.11595" x2="11.8744" y2="33.5123" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3"/>
|
||||
<stop offset="1" stop-color="#DC1FFF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_2582_2263" x1="19.3165" y1="3.37558" x2="8.26896" y2="24.536" gradientUnits="userSpaceOnUse">
|
||||
<linearGradient id="paint1_linear_1184_2703" x1="21.3925" y1="-2.74502" x2="4.47898" y2="29.6513" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3"/>
|
||||
<stop offset="1" stop-color="#DC1FFF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_2582_2263" x1="21.7164" y1="4.62866" x2="10.6689" y2="25.7891" gradientUnits="userSpaceOnUse">
|
||||
<linearGradient id="paint2_linear_1184_2703" x1="25.0668" y1="-0.826886" x2="8.15321" y2="31.5694" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3"/>
|
||||
<stop offset="1" stop-color="#DC1FFF"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_2582_2263">
|
||||
<rect width="32" height="32" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.6 KiB |
|
@ -107,5 +107,6 @@
|
|||
"create-switch-oracle": "Create switchboard oracle for",
|
||||
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
|
||||
"create-oracle": "Create oracle",
|
||||
"tier": "Tier"
|
||||
"tier": "Tier",
|
||||
"on-boarding-description-1": "If you want to use delegated tokens go to vote view and select wallet in top right corner."
|
||||
}
|
|
@ -92,7 +92,7 @@
|
|||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"tweet-position": "Tweet",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
|
|
|
@ -107,5 +107,6 @@
|
|||
"create-switch-oracle": "Create switchboard oracle for",
|
||||
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
|
||||
"create-oracle": "Create oracle",
|
||||
"tier": "Tier"
|
||||
"tier": "Tier",
|
||||
"on-boarding-description-1": "If you want to use delegated tokens go to vote view and select wallet in top right corner."
|
||||
}
|
|
@ -92,7 +92,7 @@
|
|||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"tweet-position": "Tweet",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
|
|
|
@ -107,5 +107,6 @@
|
|||
"create-switch-oracle": "Create switchboard oracle for",
|
||||
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
|
||||
"create-oracle": "Create oracle",
|
||||
"tier": "Tier"
|
||||
"tier": "Tier",
|
||||
"on-boarding-description-1": "If you want to use delegated tokens go to vote view and select wallet in top right corner."
|
||||
}
|
|
@ -92,7 +92,7 @@
|
|||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"tweet-position": "Tweet",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
|
|
|
@ -107,5 +107,6 @@
|
|||
"create-switch-oracle": "Create switchboard oracle for",
|
||||
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
|
||||
"create-oracle": "Create oracle",
|
||||
"tier": "Tier"
|
||||
"tier": "Tier",
|
||||
"on-boarding-description-1": "If you want to use delegated tokens go to vote view and select wallet in top right corner."
|
||||
}
|
|
@ -92,7 +92,7 @@
|
|||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"tweet-position": "Tweet",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
|
|
|
@ -107,5 +107,6 @@
|
|||
"create-switch-oracle": "Create switchboard oracle for",
|
||||
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
|
||||
"create-oracle": "Create oracle",
|
||||
"tier": "Tier"
|
||||
"tier": "Tier",
|
||||
"on-boarding-description-1": "If you want to use delegated tokens go to vote view and select wallet in top right corner."
|
||||
}
|
|
@ -92,7 +92,7 @@
|
|||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"tweet-position": "Tweet",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
|
|
|
@ -279,7 +279,7 @@ const mangoStore = create<MangoStore>()(
|
|||
if (typeof window !== 'undefined' && CLUSTER === 'mainnet-beta') {
|
||||
const urlFromLocalStorage = localStorage.getItem(RPC_PROVIDER_KEY)
|
||||
rpcUrl = urlFromLocalStorage
|
||||
? JSON.parse(urlFromLocalStorage).value
|
||||
? JSON.parse(urlFromLocalStorage)
|
||||
: ENDPOINT.url
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue