Merge remote-tracking branch 'origin/main' into clarkeni/performance_per_token

This commit is contained in:
Nicholas Clarke 2022-05-16 12:52:07 -07:00
commit 701faa2afe
30 changed files with 318 additions and 153 deletions

View File

@ -465,8 +465,16 @@ const BalancesTable = ({
balance.borrows.toFormat(balance.decimals)
)}
</Td>
<Td>{balance.orders}</Td>
<Td>{balance.unsettled}</Td>
<Td>
{balance.orders?.toLocaleString(undefined, {
maximumFractionDigits: balance.decimals,
})}
</Td>
<Td>
{balance.unsettled?.toLocaleString(undefined, {
maximumFractionDigits: balance.decimals,
})}
</Td>
<Td>
{marketConfig.kind === 'spot' &&
marketConfig.name.includes(balance.symbol) &&

View File

@ -26,19 +26,16 @@ export const handleWalletConnect = (wallet: Wallet) => {
if (!wallet) {
return
}
if (wallet.readyState === WalletReadyState.NotDetected) {
window.open(wallet.adapter.url, '_blank')
} else {
wallet?.adapter?.connect().catch((e) => {
if (e.name.includes('WalletLoadError')) {
notify({
title: `${wallet.adapter.name} Error`,
type: 'error',
description: `Please install ${wallet.adapter.name} and then reload this page.`,
})
}
})
}
wallet?.adapter?.connect().catch((e) => {
if (e.name.includes('WalletLoadError')) {
notify({
title: `${wallet.adapter.name} Error`,
type: 'error',
description: `Please install ${wallet.adapter.name} and then reload this page.`,
})
}
})
}
export const ConnectWalletButton: React.FC = () => {

View File

@ -16,7 +16,7 @@ const getRecentPerformance = async (setShow, setTps) => {
const totalTransactions = sumBy(response, 'numTransactions')
const tps = totalTransactions / totalSecs
if (tps < 1500) {
if (tps < 1800) {
setShow(true)
setTps(tps)
} else {

View File

@ -552,7 +552,7 @@ const JupiterForm: FunctionComponent = () => {
setFormValue((val) => ({
...val,
amount: newValue,
amount: Number(newValue),
}))
}}
/>

View File

@ -5,7 +5,10 @@ import {
InformationCircleIcon,
XCircleIcon,
} from '@heroicons/react/outline'
import useMangoStore, { CLUSTER } from '../stores/useMangoStore'
import useMangoStore, {
CLIENT_TX_TIMEOUT,
CLUSTER,
} from '../stores/useMangoStore'
import { Notification, notify } from '../utils/notifications'
import { useTranslation } from 'next-i18next'
import Loading from './Loading'
@ -105,7 +108,9 @@ const Notification = ({ notification }: { notification: Notification }) => {
hideNotification()
}
},
parsedTitle || type === 'confirm' || type === 'error' ? 90000 : 8000
parsedTitle || type === 'confirm' || type === 'error'
? CLIENT_TX_TIMEOUT
: 8000
)
return () => {

View File

@ -14,6 +14,7 @@ import { useScreenshot } from '../hooks/useScreenshot'
import * as MonoIcons from './icons'
import { TwitterIcon } from './icons'
import QRCode from 'react-qr-code'
import { useTranslation } from 'next-i18next'
import useMangoAccount from '../hooks/useMangoAccount'
import {
mangoCacheSelector,
@ -35,7 +36,7 @@ const calculatePositionPercentage = (position, maxLeverage) => {
return returnsPercentage * maxLeverage
} else {
const returnsPercentage =
(position.avgEntryPrice / position.indexPrice - 1) * 100
(position.indexPrice / position.avgEntryPrice - 1) * -100
return returnsPercentage * maxLeverage
}
}
@ -57,6 +58,7 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
onClose,
position,
}) => {
const { t } = useTranslation(['common', 'share-modal'])
const ref = createRef()
const [copied, setCopied] = useState(false)
const [showButton, setShowButton] = useState(true)
@ -81,7 +83,7 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
const positionPercentage = calculatePositionPercentage(position, maxLeverage)
const side = position.basePosition > 0 ? 'LONG' : 'SHORT'
const side = position.basePosition > 0 ? 'long' : 'short'
async function copyToClipboard(image) {
try {
@ -163,7 +165,7 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
isOpen={isOpen}
onClose={onClose}
className={`-mt-40 ${
side === 'LONG'
side === 'long'
? isProfit
? 'bg-long-profit'
: 'bg-long-loss'
@ -212,7 +214,7 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
!showButton ? 'inline-block h-full align-top leading-none' : ''
}`}
>
{side}
{t(side).toLocaleUpperCase()}
</span>
</span>
</div>
@ -227,7 +229,7 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
<div className="w-1/2 space-y-1 pt-2 text-base text-th-fgd-1">
{showSize ? (
<div className="flex items-center justify-between">
<span className="text-th-fgd-2">Size</span>
<span className="text-th-fgd-2">{t('size')}</span>
<span className="font-bold">
{roundPerpSize(
position.basePosition,
@ -237,7 +239,7 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
</div>
) : null}
<div className="flex items-center justify-between">
<span className="text-th-fgd-2">Avg entry price</span>
<span className="text-th-fgd-2">{t('average-entry')}</span>
<span className="font-bold">
$
{position.avgEntryPrice.toLocaleString(undefined, {
@ -247,7 +249,7 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-th-fgd-2">Mark Price</span>
<span className="text-th-fgd-2">{t('share-modal:mark-price')}</span>
<span className="font-bold">
$
{position.indexPrice.toLocaleString(undefined, {
@ -256,10 +258,12 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
})}
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-th-fgd-2">Max Leverage</span>
{/* <div className="flex items-center justify-between">
<span className="text-th-fgd-2">
{t('share-modal:max-leverage')}
</span>
<span className="font-bold">{maxLeverage}x</span>
</div>
</div> */}
</div>
</div>
<div className="absolute left-1/2 mt-3 w-[600px] -translate-x-1/2 transform rounded-md bg-th-bkg-2 p-4">
@ -267,7 +271,9 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
{!copied ? (
<div className="flex space-x-4 pb-4">
<div className="flex items-center">
<label className="mr-1.5 text-th-fgd-2">Show Size</label>
<label className="mr-1.5 text-th-fgd-2">
{t('share-modal:show-size')}
</label>
<Switch
checked={showSize}
onChange={(checked) => setShowSize(checked)}
@ -276,7 +282,7 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
{hasRequiredMngo ? (
<div className="flex items-center">
<label className="mr-1.5 text-th-fgd-2">
Show Referral QR
{t('share-modal:show-referral-qr')}
</label>
<Switch
checked={showReferral}
@ -289,19 +295,21 @@ const ShareModal: FunctionComponent<ShareModalProps> = ({
{copied ? (
<a
className="block flex items-center justify-center rounded-full bg-th-bkg-button px-6 py-2 text-center font-bold text-th-fgd-1 hover:cursor-pointer hover:text-th-fgd-1 hover:brightness-[1.1]"
href={`https://twitter.com/intent/tweet?text=I'm ${side} %24${position.marketConfig.baseSymbol} perp on %40mangomarkets%0A[PASTE IMAGE HERE]`}
href={`https://twitter.com/intent/tweet?text=I'm ${side.toUpperCase()} %24${
position.marketConfig.baseSymbol
} perp on %40mangomarkets%0A[PASTE IMAGE HERE]`}
target="_blank"
rel="noreferrer"
>
<TwitterIcon className="mr-1.5 h-4 w-4" />
<div>Tweet Position</div>
<div>{t('share-modal:tweet-position')}</div>
</a>
) : (
<div>
<Button onClick={handleCopyToClipboard}>
<div className="flex items-center">
<TwitterIcon className="mr-1.5 h-4 w-4" />
Copy Image and Share
{t('share-modal:copy-and-share')}
</div>
</Button>
</div>

View File

@ -56,7 +56,7 @@ const TradeNavMenu = () => {
: activeMenuCategory === 'Spot'
? spotMarketsInfo
: marketsInfo.filter((mkt) => favoriteMarkets.includes(mkt.name)),
[activeMenuCategory, marketsInfo]
[activeMenuCategory, marketsInfo, favoriteMarkets]
)
const handleMenuCategoryChange = (categoryName) => {
@ -235,7 +235,7 @@ export const FavoriteMarketButton = ({ market }) => {
}
const removeFromFavorites = (mkt) => {
setFavoriteMarkets(favoriteMarkets.filter((m) => m.name !== mkt))
setFavoriteMarkets(favoriteMarkets.filter((m) => m !== mkt))
}
return favoriteMarkets.find((mkt) => mkt === market.name) ? (

View File

@ -1,4 +1,4 @@
import { useEffect, useMemo, useRef, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import { useTheme } from 'next-themes'
import {
widget,
@ -103,6 +103,35 @@ const TVChartContainer = () => {
}, [selectedMarketConfig.name, chartReady])
useEffect(() => {
const mainSeriesProperties = [
'candleStyle',
'hollowCandleStyle',
'haStyle',
'barStyle',
]
let chartStyleOverrides = {}
mainSeriesProperties.forEach((prop) => {
chartStyleOverrides = {
...chartStyleOverrides,
[`mainSeriesProperties.${prop}.barColorsOnPrevClose`]: true,
[`mainSeriesProperties.${prop}.drawWick`]: true,
[`mainSeriesProperties.${prop}.drawBorder`]: true,
[`mainSeriesProperties.${prop}.upColor`]:
theme === 'Mango' ? '#AFD803' : '#5EBF4D',
[`mainSeriesProperties.${prop}.downColor`]:
theme === 'Mango' ? '#E54033' : '#CC2929',
[`mainSeriesProperties.${prop}.borderColor`]:
theme === 'Mango' ? '#AFD803' : '#5EBF4D',
[`mainSeriesProperties.${prop}.borderUpColor`]:
theme === 'Mango' ? '#AFD803' : '#5EBF4D',
[`mainSeriesProperties.${prop}.borderDownColor`]:
theme === 'Mango' ? '#E54033' : '#CC2929',
[`mainSeriesProperties.${prop}.wickUpColor`]:
theme === 'Mango' ? '#AFD803' : '#5EBF4D',
[`mainSeriesProperties.${prop}.wickDownColor`]:
theme === 'Mango' ? '#E54033' : '#CC2929',
}
})
const widgetOptions: ChartingLibraryWidgetOptions = {
// debug: true,
symbol: selectedMarketConfig.name,
@ -126,7 +155,7 @@ const TVChartContainer = () => {
'show_logo_on_all_charts',
'caption_buttons_text_if_possible',
'header_settings',
'header_chart_type',
// 'header_chart_type',
'header_compare',
'compare_symbol',
'header_screenshot',
@ -154,23 +183,7 @@ const TVChartContainer = () => {
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
'paneProperties.background':
theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832',
'mainSeriesProperties.candleStyle.barColorsOnPrevClose': true,
'mainSeriesProperties.candleStyle.drawWick': true,
'mainSeriesProperties.candleStyle.drawBorder': true,
'mainSeriesProperties.candleStyle.upColor':
theme === 'Mango' ? '#AFD803' : '#5EBF4D',
'mainSeriesProperties.candleStyle.downColor':
theme === 'Mango' ? '#E54033' : '#CC2929',
'mainSeriesProperties.candleStyle.borderColor':
theme === 'Mango' ? '#AFD803' : '#5EBF4D',
'mainSeriesProperties.candleStyle.borderUpColor':
theme === 'Mango' ? '#AFD803' : '#5EBF4D',
'mainSeriesProperties.candleStyle.borderDownColor':
theme === 'Mango' ? '#E54033' : '#CC2929',
'mainSeriesProperties.candleStyle.wickUpColor':
theme === 'Mango' ? '#AFD803' : '#5EBF4D',
'mainSeriesProperties.candleStyle.wickDownColor':
theme === 'Mango' ? '#E54033' : '#CC2929',
...chartStyleOverrides,
},
}
@ -623,25 +636,7 @@ const TVChartContainer = () => {
}
}, [chartReady, openOrders, showOrderLines])
const attributionUrl = useMemo(
() =>
`https://tradingview.com/symbols/${defaultProps.symbol?.slice(0, -5)}USD`,
[defaultProps]
)
return (
<>
<div id={defaultProps.containerId} className="tradingview-chart" />
<a
className="default-transition tiny-text flex justify-end px-3 py-1 text-th-fgd-4 hover:text-th-fgd-3"
href={attributionUrl}
rel="noopener noreferrer"
target="_blank"
>
Chart by TradingView
</a>
</>
)
return <div id={defaultProps.containerId} className="tradingview-chart" />
}
export default TVChartContainer

View File

@ -93,6 +93,9 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
.add(maxWithoutBorrows)
.mul(I80F48.fromString('0.995')) // handle rounding errors when borrowing
if (withdrawTokenSymbol == 'LUNA') {
setIncludeBorrow(false)
}
// get max withdraw amount
let maxWithdraw = maxWithoutBorrows
if (includeBorrow) {
@ -356,28 +359,32 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
</Select.Option>
))}
</Select>
<div className="jusitfy-between mt-4 flex items-center rounded-md bg-th-bkg-3 p-2 text-th-fgd-1">
<div className="text-fgd-1 flex items-center pr-4">
<span>{t('borrow-funds')}</span>
<Tooltip content={t('tooltip-interest-charged')}>
<InformationCircleIcon
className={`ml-2 h-5 w-5 cursor-help text-th-primary`}
/>
</Tooltip>
{withdrawTokenSymbol != 'LUNA' ? (
<div className="jusitfy-between mt-4 flex items-center rounded-md bg-th-bkg-3 p-2 text-th-fgd-1">
<div className="text-fgd-1 flex items-center pr-4">
<span>{t('borrow-funds')}</span>
<Tooltip content={t('tooltip-interest-charged')}>
<InformationCircleIcon
className={`ml-2 h-5 w-5 cursor-help text-th-primary`}
/>
</Tooltip>
</div>
<Switch
checked={includeBorrow}
className="ml-auto"
onChange={(checked) => handleIncludeBorrowSwitch(checked)}
/>
</div>
<Switch
checked={includeBorrow}
className="ml-auto"
onChange={(checked) => handleIncludeBorrowSwitch(checked)}
/>
</div>
) : null}
<div className="flex justify-between pt-4">
<Label>{t('amount')}</Label>
<LinkButton
className="mb-1.5"
onClick={() => setInputAmount(maxAmount.toString())}
>
{includeBorrow ? t('max-with-borrow') : t('max')}
{includeBorrow && withdrawTokenSymbol != 'LUNA'
? t('max-with-borrow')
: t('max')}
</LinkButton>
</div>
<div className="flex">
@ -417,9 +424,7 @@ const WithdrawModal: FunctionComponent<WithdrawModalProps> = ({
<div className={`flex justify-center pt-6`}>
<Button
onClick={() => setShowSimulation(true)}
disabled={
Number(inputAmount) <= 0 || simulation?.initHealthRatio < 0
}
disabled={Number(inputAmount) <= 0}
className="w-full"
>
{t('next')}

View File

@ -247,7 +247,8 @@ const PerformanceChart = ({
activeValue={chartToShow}
className="pb-2 pt-2 text-sm"
onChange={(v) => setChartToShow(v)}
values={[t('value'), t('pnl')]}
values={['Value', 'PnL']}
names={[t('value'), t('pnl')]}
/>
</div>

View File

@ -6,6 +6,7 @@ import { breakpoints } from '../TradePageGrid'
import { Table, Td, Th, TrBody, TrHead } from '../TableElements'
import { ExpandableRow, Row } from '../TableElements'
import { useTranslation } from 'next-i18next'
import { useMemo } from 'react'
interface Values {
name: string
@ -60,38 +61,40 @@ export default function StatsTotals({ latestStats, stats }) {
const isMobile = width ? width < breakpoints.sm : false
// get deposit and borrow values from stats
const depositValues: Values[] = []
const borrowValues: Values[] = []
const [depositValues, borrowValues]: [Values[], Values[]] = useMemo(() => {
const depositValues: Values[] = []
const borrowValues: Values[] = []
for (let i = 0; i < stats.length; i++) {
const time = stats[i].hourly
const name = stats[i].name
const depositValue =
stats[i].name === 'USDC'
? stats[i].totalDeposits
: stats[i].totalDeposits * stats[i].baseOraclePrice
for (let i = 0; i < stats.length; i++) {
const time = stats[i].hourly
const name = stats[i].name
const depositValue =
stats[i].name === 'USDC'
? stats[i].totalDeposits
: stats[i].totalDeposits * stats[i].baseOraclePrice
const borrowValue =
stats[i].name === 'USDC'
? stats[i].totalBorrows
: stats[i].totalBorrows * stats[i].baseOraclePrice
const borrowValue =
stats[i].name === 'USDC'
? stats[i].totalBorrows
: stats[i].totalBorrows * stats[i].baseOraclePrice
if (typeof depositValue === 'number' && name && time) {
depositValues.push({
name,
value: depositValue,
time,
})
}
if (typeof depositValue === 'number' && name && time) {
depositValues.push({
name,
value: depositValue,
time,
})
if (typeof borrowValue === 'number' && name && time) {
borrowValues.push({
name,
value: borrowValue,
time,
})
}
}
if (typeof borrowValue === 'number' && name && time) {
borrowValues.push({
name,
value: borrowValue,
time,
})
}
}
return [depositValues, borrowValues]
}, [stats])
const formatValues = (values) => {
// get value for each symbol every hour

View File

@ -118,6 +118,7 @@ export default function AdvancedTradeForm({
const [postOnlySlide, setPostOnlySlide] = useState(false)
const [postOnly, setPostOnly] = useState(false)
const [ioc, setIoc] = useState(false)
const [isLuna, setIsLuna] = useState(false)
const orderBookRef = useRef(useMangoStore.getState().selectedMarket.orderBook)
const orderbook = orderBookRef.current
@ -167,6 +168,16 @@ export default function AdvancedTradeForm({
}
}, [tradeType, set])
useEffect(() => {
if (marketConfig.baseSymbol == 'LUNA') {
setIsLuna(true)
setReduceOnly(true)
} else {
setIsLuna(false)
setReduceOnly(false)
}
}, [marketConfig])
useEffect(() => {
let condition
switch (tradeType) {
@ -784,6 +795,18 @@ export default function AdvancedTradeForm({
<span className="ml-2 rounded border border-th-primary px-1 py-0.5 text-xs text-th-primary">
{initLeverage}x
</span>
{isLuna ? (
<Tooltip
content={
<div className="text-center">
LUNA is currently in reduce only mode. No new positions may be
entered.
</div>
}
>
<ExclamationIcon className="ml-2 h-5 w-5 text-th-primary" />
</Tooltip>
) : null}
</ElementTitle>
{insufficientSol ? (
<div className="mb-3 text-left">
@ -966,7 +989,7 @@ export default function AdvancedTradeForm({
auto updating the reduceOnly state when doing a market order:
&& showReduceOnly(perpAccount?.basePosition.toNumber())
*/}
{marketConfig.kind === 'perp' ? (
{marketConfig.kind === 'perp' || isLuna ? (
<div className="mr-4 mt-3">
<Tooltip
className="hidden md:block"
@ -977,7 +1000,7 @@ export default function AdvancedTradeForm({
<Checkbox
checked={reduceOnly}
onChange={(e) => reduceOnChange(e.target.checked)}
disabled={isTriggerOrder}
disabled={isTriggerOrder || isLuna}
>
Reduce Only
</Checkbox>

View File

@ -33,7 +33,9 @@ function decodeBookL2(market, accInfo: AccountInfo<Buffer>): number[][] {
// @ts-ignore
null,
market,
BookSideLayout.decode(accInfo.data)
BookSideLayout.decode(accInfo.data),
undefined,
100000
)
return book.getL2Ui(depth)
}
@ -50,8 +52,14 @@ export function decodeBook(
return SpotOrderBook.decode(market, accInfo.data)
} else if (market instanceof PerpMarket) {
// FIXME: Review the null being passed here
// @ts-ignore
return new BookSide(null, market, BookSideLayout.decode(accInfo.data))
return new BookSide(
// @ts-ignore
null,
market,
BookSideLayout.decode(accInfo.data),
undefined,
100000
)
}
}
}

View File

@ -71,7 +71,13 @@ function parsePerpOpenOrders(
const bidData = accountInfos[market.bids.toBase58()]?.data
bidOrderBook =
market && bidData
? new BookSide(market.bids, market, BookSideLayout.decode(bidData))
? new BookSide(
market.bids,
market,
BookSideLayout.decode(bidData),
undefined,
100000
)
: []
}
@ -79,7 +85,13 @@ function parsePerpOpenOrders(
const askData = accountInfos[market.asks.toBase58()]?.data
askOrderBook =
market && askData
? new BookSide(market.asks, market, BookSideLayout.decode(askData))
? new BookSide(
market.asks,
market,
BookSideLayout.decode(askData),
undefined,
100000
)
: []
}

View File

@ -17,7 +17,7 @@
"analyze": "ANALYZE=true yarn build"
},
"dependencies": {
"@blockworks-foundation/mango-client": "^3.4.4",
"@blockworks-foundation/mango-client": "^3.4.7",
"@headlessui/react": "^0.0.0-insiders.2dbc38c",
"@heroicons/react": "^1.0.0",
"@jup-ag/react-hook": "^1.0.0-beta.22",
@ -28,7 +28,7 @@
"@solana/wallet-adapter-base": "^0.9.5",
"@solana/wallet-adapter-huobi": "^0.1.0",
"@solana/wallet-adapter-react": "^0.15.4",
"@solana/wallet-adapter-wallets": "^0.16.0",
"@solana/wallet-adapter-wallets": "^0.16.1",
"@solana/web3.js": "^1.36.0",
"@solflare-wallet/pfp": "^0.0.6",
"@tippyjs/react": "^4.2.5",

View File

@ -32,6 +32,7 @@ import { BrowserTracing } from '@sentry/tracing'
import { WalletProvider, WalletListener } from 'components/WalletAdapter'
import {
ExodusWalletAdapter,
PhantomWalletAdapter,
SolflareWalletAdapter,
SolletWalletAdapter,
@ -142,11 +143,12 @@ function App({ Component, pageProps }) {
() => [
new PhantomWalletAdapter(),
new SolflareWalletAdapter(),
new ExodusWalletAdapter(),
new SolletWalletAdapter(),
new GlowWalletAdapter(),
new SlopeWalletAdapter(),
new BitpieWalletAdapter(),
new HuobiWalletAdapter(),
new GlowWalletAdapter(),
],
[]
)

View File

@ -65,6 +65,7 @@ export async function getStaticProps({ locale }) {
'delegate',
'alerts',
'account-performance',
'share-modal',
])),
// Will be passed to the page component as props
},

View File

@ -30,6 +30,7 @@ export async function getStaticProps({ locale }) {
'common',
'tv-chart',
'alerts',
'share-modal',
])),
// Will be passed to the page component as props
},

View File

@ -5,5 +5,5 @@
"info": "Grant control to another Solana account to use Mango on your behalf.",
"public-key": "Delegate Public Key",
"delegate-updated": "Delegate Updated",
"set-error": "Could not set Delegate",
}
"set-error": "Could not set Delegate"
}

View File

@ -0,0 +1,8 @@
{
"copy-and-share": "Copy Image and Share",
"mark-price": "Mark Price",
"max-leverage": "Max Leverage",
"show-referral-qr": "Show Referral QR",
"show-size": "Show Size",
"tweet-position": "Tweet Position"
}

View File

@ -0,0 +1,8 @@
{
"copy-and-share": "Copy Image and Share",
"mark-price": "Mark Price",
"max-leverage": "Max Leverage",
"show-referral-qr": "Show Referral QR",
"show-size": "Show Size",
"tweet-position": "Tweet Position"
}

View File

@ -9,5 +9,5 @@
"outside-range": "Order Price Outside Range",
"slippage-accept": "Please use the trade input form if you wish to accept the potential slippage.",
"slippage-warning": "Your order price ({{updatedOrderPrice}}) is greater than 5% {{aboveBelow}} the current market price ({{selectedMarketPrice}}) indicating you might incur significant slippage.",
"toggle-order-line": "Toggle order line visibility"
"toggle-order-line": "Toggle order line visibility"
}

View File

@ -1,5 +1,5 @@
{
"about-to-withdraw": "您正在款",
"about-to-withdraw": "您正在款",
"above": "高于",
"accept": "接受",
"accept-terms": "我明白并接受使用此平台的风险",
@ -323,7 +323,7 @@
"recent-trades": "最近成交",
"redeem-all": "现实所有盈亏",
"redeem-failure": "收获MNGO奖励出错了",
"redeem-pnl": "结清",
"redeem-pnl": "领取",
"redeem-positive": "现实正数",
"redeem-success": "已收获MNGO奖励了",
"referrals": "推荐",
@ -434,7 +434,7 @@
"type": "类型",
"unrealized-pnl": "未实现盈亏",
"unsettled": "未结清",
"unsettled-balance": "未实现盈亏",
"unsettled-balance": "可领取价值",
"unsettled-balances": "未结清余额",
"unsettled-positions": "未结清持仓",
"update-filters": "更新过滤",

View File

@ -0,0 +1,8 @@
{
"copy-and-share": "拷贝图片来分享",
"mark-price": "现价",
"max-leverage": "最多杠杆",
"show-referral-qr": "显示推荐QR",
"show-size": "显示数量",
"tweet-position": "推文当前持仓"
}

View File

@ -9,5 +9,5 @@
"outside-range": "订单价格在范围之外",
"slippage-accept": "若您接受潜在的下滑请使用交易表格进行。",
"slippage-warning": "您的订单价格({{updatedOrderPrice}})多余5%{{aboveBelow}}市场价格({{selectedMarketPrice}})表是您也许遭受可观的下滑。",
"toggle-order-line": "切换订单线可见性"
"toggle-order-line": "切换订单线可见性"
}

View File

@ -1,5 +1,5 @@
{
"about-to-withdraw": "您正在款",
"about-to-withdraw": "您正在款",
"above": "高於",
"accept": "接受",
"accept-terms": "我明白並接受使用此平台的風險",
@ -323,7 +323,7 @@
"recent-trades": "最近成交",
"redeem-all": "現實所有盈虧",
"redeem-failure": "收穫MNGO獎勵出錯了",
"redeem-pnl": "實現盈虧",
"redeem-pnl": "領取",
"redeem-positive": "現實正數",
"redeem-success": "已收穫MNGO獎勵了",
"referrals": "推薦",
@ -434,7 +434,7 @@
"type": "類型",
"unrealized-pnl": "未實現盈虧",
"unsettled": "未結清",
"unsettled-balance": "未實現盈虧",
"unsettled-balance": "可領取價值",
"unsettled-balances": "未結清餘額",
"unsettled-positions": "未結清持倉",
"update-filters": "更新過濾",

View File

@ -0,0 +1,8 @@
{
"copy-and-share": "拷貝圖片來分享",
"mark-price": "現價",
"max-leverage": "最多槓桿",
"show-referral-qr": "顯示推薦QR",
"show-size": "顯示數量",
"tweet-position": "推文當前持倉"
}

View File

@ -9,5 +9,5 @@
"outside-range": "訂單價格在範圍之外",
"slippage-accept": "若您接受潛在的下滑請使用交易表格進行。",
"slippage-warning": "您的訂單價格({{updatedOrderPrice}})多餘5%{{aboveBelow}}市場價格({{selectedMarketPrice}})表是您也許遭受可觀的下滑。",
"toggle-order-line": "切換訂單線可見性"
"toggle-order-line": "切換訂單線可見性"
}

View File

@ -135,7 +135,7 @@ button.transition-none {
}
.tradingview-chart {
height: calc(100% - 24px);
display: contents;
}
/* Grid */

View File

@ -1008,16 +1008,16 @@
"@babel/helper-validator-identifier" "^7.16.7"
to-fast-properties "^2.0.0"
"@blockworks-foundation/mango-client@^3.4.4":
version "3.4.4"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-client/-/mango-client-3.4.4.tgz#5ccf688432c54c88b513499edde0dcb9af945a8f"
integrity sha512-r4qBcPbxgtfpTWO8Z/ChIY8bQKXXEG+4Bzce+IjHWN32g+UP0tVydMvfYi6WNN9JNrKccR58MujUWvEo7HyniQ==
"@blockworks-foundation/mango-client@^3.4.7":
version "3.4.7"
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-client/-/mango-client-3.4.7.tgz#5411ca4aae738bc9a277d88c15f6aa162f47aaf0"
integrity sha512-TBbWn+adQdXu+6UUiZqWD+LmZsDy9DhRkSaaxKDwC0q1VDLvXbO6Sj9XpOmw6ZAp7bgC/9uKtn9macJotppn3Q==
dependencies:
"@project-serum/anchor" "^0.21.0"
"@project-serum/serum" "0.13.55"
"@project-serum/sol-wallet-adapter" "^0.2.0"
"@solana/spl-token" "^0.1.6"
"@solana/web3.js" "^1.31.0"
"@solana/web3.js" "^1.37.1"
big.js "^6.1.1"
bn.js "^5.1.0"
buffer-layout "^1.2.1"
@ -1700,6 +1700,16 @@
"@sentry/types" "6.19.2"
tslib "^1.9.3"
"@solana/buffer-layout-utils@^0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz#b45a6cab3293a2eb7597cceb474f229889d875ca"
integrity sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==
dependencies:
"@solana/buffer-layout" "^4.0.0"
"@solana/web3.js" "^1.32.0"
bigint-buffer "^1.1.5"
bignumber.js "^9.0.1"
"@solana/buffer-layout@3.0.0", "@solana/buffer-layout@^3.0.0", "@solana/buffer-layout@^4.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz#b9353caeb9a1589cb77a1b145bcb1a9a93114326"
@ -1777,6 +1787,13 @@
"@solana/wallet-adapter-base" "^0.9.3"
"@solana/web3.js" "^1.20.0"
"@solana/wallet-adapter-exodus@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@solana/wallet-adapter-exodus/-/wallet-adapter-exodus-0.1.0.tgz#8d1d375fa2f3e43499ab0d763d4e04298ede3d57"
integrity sha512-dfkiIDiPwPD+ueU3DXJOn2TY+s0/1IKUA6/8Vi2HvRaCeZ75Ol8YE8CG2tHe49Hiz6iy+Fd+Nl9voEhQeYML1g==
dependencies:
"@solana/wallet-adapter-base" "^0.9.4"
"@solana/wallet-adapter-glow@^0.1.0":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@solana/wallet-adapter-glow/-/wallet-adapter-glow-0.1.1.tgz#4db395b2ccf73eb2d6c1d9362e26cbfd260fc19f"
@ -1891,10 +1908,10 @@
process "^0.11.10"
stream-browserify "^3.0.0"
"@solana/wallet-adapter-wallets@^0.16.0":
version "0.16.0"
resolved "https://registry.yarnpkg.com/@solana/wallet-adapter-wallets/-/wallet-adapter-wallets-0.16.0.tgz#0a30eaac10b04ac3e8aa7f3e001d7fd69f92c22a"
integrity sha512-blg/0eGDvQlvPkfaLD24vgB3+RxbksjLoKPRVF/4/Dj+XTc0Yx8PxXUDwCQSC5Xic51Q7ZfLhMxj8caXN+RM/Q==
"@solana/wallet-adapter-wallets@^0.16.1":
version "0.16.1"
resolved "https://registry.yarnpkg.com/@solana/wallet-adapter-wallets/-/wallet-adapter-wallets-0.16.1.tgz#cf151debda130044a0a72c3c50e8632764d797ff"
integrity sha512-ztrR9ieXpMVKx95JrH4MOtvhz048UmbiVJvEM97MhdKL6zpP09DNeqAQ9uuGjvjKy1WVJQ8r5+TK7+lLCgMimw==
dependencies:
"@solana/wallet-adapter-base" "^0.9.4"
"@solana/wallet-adapter-bitkeep" "^0.3.2"
@ -1903,6 +1920,7 @@
"@solana/wallet-adapter-clover" "^0.4.2"
"@solana/wallet-adapter-coin98" "^0.5.2"
"@solana/wallet-adapter-coinhub" "^0.3.2"
"@solana/wallet-adapter-exodus" "^0.1.0"
"@solana/wallet-adapter-glow" "^0.1.0"
"@solana/wallet-adapter-huobi" "^0.1.0"
"@solana/wallet-adapter-ledger" "^0.9.8"
@ -1996,6 +2014,28 @@
superstruct "^0.14.2"
tweetnacl "^1.0.0"
"@solana/web3.js@^1.37.1":
version "1.42.0"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.42.0.tgz#296e4bbab1fbfc198b3e9c3d94016c3876eb6a2c"
integrity sha512-QqGh5DWzrgsWRx4sCPDQIm3390b7buPR16tZI61slQaQwJ2ymrSXPQCe4PPTJEIlzGjCV3dkn2vpT2R32BfK2Q==
dependencies:
"@babel/runtime" "^7.12.5"
"@ethersproject/sha2" "^5.5.0"
"@solana/buffer-layout" "^4.0.0"
"@solana/buffer-layout-utils" "^0.2.0"
bn.js "^5.0.0"
borsh "^0.7.0"
bs58 "^4.0.1"
buffer "6.0.1"
cross-fetch "^3.1.4"
fast-stable-stringify "^1.0.0"
jayson "^3.4.4"
js-sha3 "^0.8.0"
rpc-websockets "^7.4.2"
secp256k1 "^4.0.2"
superstruct "^0.14.2"
tweetnacl "^1.0.0"
"@solflare-wallet/pfp@^0.0.6":
version "0.0.6"
resolved "https://registry.yarnpkg.com/@solflare-wallet/pfp/-/pfp-0.0.6.tgz#0dc360e7ebb11029977f5cd5593b5dc5e6074bab"
@ -2801,7 +2841,14 @@ big.js@^6.1.1:
resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.1.1.tgz#63b35b19dc9775c94991ee5db7694880655d5537"
integrity sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==
bignumber.js@^9.0.2:
bigint-buffer@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/bigint-buffer/-/bigint-buffer-1.1.5.tgz#d038f31c8e4534c1f8d0015209bf34b4fa6dd442"
integrity sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==
dependencies:
bindings "^1.3.0"
bignumber.js@^9.0.1, bignumber.js@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673"
integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==
@ -2811,6 +2858,13 @@ binary-extensions@^2.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
bindings@^1.3.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
dependencies:
file-uri-to-path "1.0.0"
blakejs@^1.1.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814"
@ -3978,6 +4032,11 @@ fast-safe-stringify@^2.0.6, fast-safe-stringify@^2.1.1:
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
fast-stable-stringify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313"
integrity sha1-XFVDRisiru79NtBbNOUceMuG0xM=
fastq@^1.6.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
@ -3992,6 +4051,11 @@ file-entry-cache@^6.0.1:
dependencies:
flat-cache "^3.0.4"
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"