Merge branch 'main' into kierangillen/wallet-updates

This commit is contained in:
tjshipe 2022-03-28 13:55:44 -04:00 committed by GitHub
commit f771e3bb7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 353 additions and 189 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
NEXT_PUBLIC_GROUP=devnet.2

View File

@ -9,7 +9,7 @@ import { SHOW_TOUR_KEY } from './IntroTips'
import { useViewport } from '../hooks/useViewport'
import { breakpoints } from './TradePageGrid'
import { useRouter } from 'next/router'
import { LANGS } from './LanguageSwitch'
import { LANGS } from './SettingsModal'
import { RadioGroup } from '@headlessui/react'
export const ALPHA_MODAL_KEY = 'mangoAlphaAccepted-3.06'

View File

@ -147,6 +147,24 @@ const BalancesTable = ({
const unsettledBalances = balances.filter((bal) => bal.unsettled > 0)
const trimDecimals = useCallback((num: string) => {
if (parseFloat(num) === 0) {
return '0'
}
// Trim the decimals depending on the length of the whole number
const splitNum = num.split('.')
if (splitNum.length > 1) {
const wholeNum = splitNum[0]
const decimals = splitNum[1]
if (wholeNum.length > 8) {
return `${wholeNum}.${decimals.substring(0, 2)}`
} else if (wholeNum.length > 3) {
return `${wholeNum}.${decimals.substring(0, 3)}`
}
}
return num
}, [])
return (
<div className={`flex flex-col pb-2 sm:pb-4`}>
{unsettledBalances.length > 0 ? (
@ -360,7 +378,6 @@ const BalancesTable = ({
</thead>
<tbody>
{items.map((balance, index) => {
console.log('balance', balance)
if (!balance) {
return null
}
@ -396,8 +413,16 @@ const BalancesTable = ({
)}
</div>
</Td>
<Td>{balance.deposits.toFormat(balance.decimals)}</Td>
<Td>{balance.borrows.toFormat(balance.decimals)}</Td>
<Td>
{trimDecimals(
balance.deposits.toFormat(balance.decimals)
)}
</Td>
<Td>
{trimDecimals(
balance.borrows.toFormat(balance.decimals)
)}
</Td>
<Td>{balance.orders}</Td>
<Td>{balance.unsettled}</Td>
<Td>
@ -415,10 +440,12 @@ const BalancesTable = ({
handleSizeClick(balance.net, balance.symbol)
}
>
{balance.net.toFormat(balance.decimals)}
{trimDecimals(
balance.net.toFormat(balance.decimals)
)}
</span>
) : (
balance.net.toFormat(balance.decimals)
trimDecimals(balance.net.toFormat(balance.decimals))
)}
</Td>
<Td>{formatUsdValue(balance.value.toNumber())}</Td>

View File

@ -5,7 +5,7 @@ interface ButtonGroupProps {
className?: string
onChange: (x) => void
unit?: string
values: Array<string>
values: Array<any>
names?: Array<string>
}

View File

@ -71,7 +71,7 @@ const DelegateModal: FunctionComponent<DelegateModalProps> = ({
if (isKeyValid()) {
setInvalidKeyMessage('')
} else {
setInvalidKeyMessage(t('delegate:invalid-key'))
setInvalidKeyMessage(t('invalid-address'))
}
}

View File

@ -52,30 +52,6 @@ class IntroTips extends Component<Props, State> {
highlightClass: 'intro-highlight',
disableInteraction: true,
},
{
element: '#themes-tip',
intro: (
<div>
<h4>{this.props.t('themes-tip-title')}</h4>
<p>{this.props.t('themes-tip-desc')}</p>
</div>
),
tooltipClass: 'intro-tooltip',
highlightClass: 'intro-highlight',
disableInteraction: true,
},
{
element: '#languages-tip',
intro: (
<div>
<h4>{this.props.t('languages-tip-title')}</h4>
<p>{this.props.t('languages-tip-desc')}</p>
</div>
),
tooltipClass: 'intro-tooltip',
highlightClass: 'intro-highlight',
disableInteraction: true,
},
{
element: '#data-refresh-tip',
intro: (

View File

@ -1,59 +0,0 @@
import { useEffect, useState } from 'react'
import { TranslateIcon } from '@heroicons/react/outline'
import DropMenu from './DropMenu'
import { useRouter } from 'next/router'
import dayjs from 'dayjs'
import useLocalStorageState from '../hooks/useLocalStorageState'
require('dayjs/locale/en')
require('dayjs/locale/es')
require('dayjs/locale/zh')
require('dayjs/locale/zh-tw')
export const LANGS = [
{ locale: 'en', name: 'english', description: 'english' },
{ locale: 'es', name: 'spanish', description: 'spanish' },
{
locale: 'zh_tw',
name: 'chinese-traditional',
description: 'traditional chinese',
},
{ locale: 'zh', name: 'chinese', description: 'simplified chinese' },
]
const LanguageSwitch = () => {
const router = useRouter()
const { pathname, asPath, query } = router
const [mounted, setMounted] = useState(false)
const [savedLanguage, setSavedLanguage] = useLocalStorageState('language', '')
// When mounted on client, now we can show the UI
useEffect(() => setMounted(true), [])
const handleLangChange = (e) => {
setSavedLanguage(e)
router.push({ pathname, query }, asPath, { locale: e })
dayjs.locale(e == 'zh_tw' ? 'zh-tw' : e)
}
return (
<div id="languages-tip">
{mounted ? (
<DropMenu
button={
<div className="default-transition flex h-8 w-8 items-center justify-center rounded-full bg-th-bkg-4 text-th-fgd-1 hover:text-th-primary focus:outline-none">
<TranslateIcon className="h-4 w-4" />
</div>
}
value={savedLanguage}
onChange={(lang) => handleLangChange(lang)}
options={LANGS}
/>
) : (
<div className="h-8 w-8 rounded-full bg-th-bkg-3" />
)}
</div>
)
}
export default LanguageSwitch

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react'
import React, { useMemo, useState } from 'react'
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid'
import useMangoGroupConfig from '../hooks/useMangoGroupConfig'
import Modal from './Modal'
@ -11,6 +11,15 @@ import Select from './Select'
import { useTranslation } from 'next-i18next'
import Switch from './Switch'
import { MarketKind } from '@blockworks-foundation/mango-client'
import { useTheme } from 'next-themes'
import { useRouter } from 'next/router'
import ButtonGroup from './ButtonGroup'
import dayjs from 'dayjs'
require('dayjs/locale/en')
require('dayjs/locale/es')
require('dayjs/locale/zh')
require('dayjs/locale/zh-tw')
const NODE_URLS = [
{ label: 'Triton (RPC Pool)', value: 'https://mango.rpcpool.com' },
@ -18,9 +27,26 @@ const NODE_URLS = [
label: 'Genesys Go',
value: 'https://mango.genesysgo.net/',
},
{
label: 'Project Serum',
value: 'https://solana-api.projectserum.com/',
},
{ label: 'Custom', value: '' },
]
const THEMES = ['Light', 'Dark', 'Mango']
export const LANGS = [
{ locale: 'en', name: 'english', description: 'english' },
{ locale: 'es', name: 'spanish', description: 'spanish' },
{
locale: 'zh_tw',
name: 'chinese-traditional',
description: 'traditional chinese',
},
{ locale: 'zh', name: 'chinese', description: 'simplified chinese' },
]
const CUSTOM_NODE = NODE_URLS.find((n) => n.label === 'Custom')
export const NODE_URL_KEY = 'node-url-key-0.6'
@ -37,6 +63,8 @@ export const initialMarket = {
const SettingsModal = ({ isOpen, onClose }) => {
const { t } = useTranslation('common')
const [settingsView, setSettingsView] = useState('')
const { theme } = useTheme()
const [savedLanguage] = useLocalStorageState('language', '')
const [rpcEndpointUrl] = useLocalStorageState(
NODE_URL_KEY,
NODE_URLS[0].value
@ -58,6 +86,12 @@ const SettingsModal = ({ isOpen, onClose }) => {
const rpcEndpoint =
NODE_URLS.find((node) => node.value === rpcEndpointUrl) || CUSTOM_NODE
const savedLanguageName = useMemo(
() => LANGS.find((l) => l.locale === savedLanguage).name,
[savedLanguage]
)
return (
<Modal isOpen={isOpen} onClose={onClose}>
{settingsView !== '' ? (
@ -75,7 +109,7 @@ const SettingsModal = ({ isOpen, onClose }) => {
{!settingsView ? (
<div className="border-b border-th-bkg-4">
<button
className="default-transition flex w-full items-center justify-between border-t border-th-bkg-4 py-3 font-normal text-th-fgd-1 hover:text-th-primary focus:outline-none"
className="default-transition flex w-full items-center justify-between rounded-none border-t border-th-bkg-4 py-3 font-normal text-th-fgd-1 hover:text-th-primary focus:outline-none"
onClick={() => setSettingsView('Default Market')}
>
<span>{t('default-market')}</span>
@ -85,7 +119,27 @@ const SettingsModal = ({ isOpen, onClose }) => {
</div>
</button>
<button
className="default-transition flex w-full items-center justify-between border-t border-th-bkg-4 py-3 font-normal text-th-fgd-1 hover:text-th-primary focus:outline-none"
className="default-transition flex w-full items-center justify-between rounded-none border-t border-th-bkg-4 py-3 font-normal text-th-fgd-1 hover:text-th-primary focus:outline-none"
onClick={() => setSettingsView('Theme')}
>
<span>{t('theme')}</span>
<div className="flex items-center text-xs text-th-fgd-3">
{theme}
<ChevronRightIcon className="ml-1 h-5 w-5 text-th-fgd-1" />
</div>
</button>
<button
className="default-transition flex w-full items-center justify-between rounded-none border-t border-th-bkg-4 py-3 font-normal text-th-fgd-1 hover:text-th-primary focus:outline-none"
onClick={() => setSettingsView('Language')}
>
<span>{t('language')}</span>
<div className="flex items-center text-xs text-th-fgd-3">
{t(savedLanguageName)}
<ChevronRightIcon className="ml-1 h-5 w-5 text-th-fgd-1" />
</div>
</button>
<button
className="default-transition flex w-full items-center justify-between rounded-none border-t border-th-bkg-4 py-3 font-normal text-th-fgd-1 hover:text-th-primary focus:outline-none"
onClick={() => setSettingsView('RPC Endpoint')}
>
<span>{t('rpc-endpoint')}</span>
@ -132,6 +186,10 @@ const SettingsContent = ({ settingsView, setSettingsView }) => {
return <DefaultMarketSettings setSettingsView={setSettingsView} />
case 'RPC Endpoint':
return <RpcEndpointSettings setSettingsView={setSettingsView} />
case 'Theme':
return <ThemeSettings setSettingsView={setSettingsView} />
case 'Language':
return <LanguageSettings />
case '':
return null
}
@ -240,3 +298,49 @@ const RpcEndpointSettings = ({ setSettingsView }) => {
</div>
)
}
const ThemeSettings = ({ setSettingsView }) => {
const { theme, setTheme } = useTheme()
const { t } = useTranslation('common')
return (
<>
<Label>{t('theme')}</Label>
<ButtonGroup
activeValue={theme}
onChange={(t) => setTheme(t)}
values={THEMES}
/>
<Button onClick={() => setSettingsView('')} className="mt-6 w-full">
<div className={`flex items-center justify-center`}>{t('save')}</div>
</Button>
</>
)
}
const LanguageSettings = () => {
const [savedLanguage, setSavedLanguage] = useLocalStorageState('language', '')
const router = useRouter()
const { pathname, asPath, query } = router
const { t } = useTranslation('common')
const handleLangChange = () => {
router.push({ pathname, query }, asPath, { locale: savedLanguage })
dayjs.locale(savedLanguage == 'zh_tw' ? 'zh-tw' : savedLanguage)
}
return (
<>
<Label>{t('language')}</Label>
<ButtonGroup
activeValue={savedLanguage}
onChange={(l) => setSavedLanguage(l)}
values={LANGS.map((val) => val.locale)}
names={LANGS.map((val) => t(val.name))}
/>
<Button onClick={() => handleLangChange()} className="mt-6 w-full">
<div className={`flex items-center justify-center`}>{t('save')}</div>
</Button>
</>
)
}

View File

@ -1,40 +0,0 @@
import { useEffect, useState } from 'react'
import { useTheme } from 'next-themes'
import { MoonIcon, SunIcon } from '@heroicons/react/outline'
import DropMenu from './DropMenu'
import { MangoIcon } from './icons'
const THEMES = [
{ name: 'Light', icon: <SunIcon className="h-4 w-4" /> },
{ name: 'Dark', icon: <MoonIcon className="h-4 w-4" /> },
{ name: 'Mango', icon: <MangoIcon className="h-4 w-4 stroke-current" /> },
]
const ThemeSwitch = () => {
const [mounted, setMounted] = useState(false)
const { theme, setTheme } = useTheme()
// When mounted on client, now we can show the UI
useEffect(() => setMounted(true), [])
return (
<div id="themes-tip">
{mounted ? (
<DropMenu
button={
<div className="default-transition flex h-8 w-8 items-center justify-center rounded-full bg-th-bkg-4 text-th-fgd-1 hover:text-th-primary focus:outline-none">
{THEMES.find((t) => t.name === theme).icon}
</div>
}
value={theme}
onChange={(theme) => setTheme(theme)}
options={THEMES}
/>
) : (
<div className="h-8 w-8 rounded-full bg-th-bkg-3" />
)}
</div>
)
}
export default ThemeSwitch

View File

@ -3,12 +3,10 @@ import Link from 'next/link'
import { abbreviateAddress } from '../utils/index'
import useLocalStorageState from '../hooks/useLocalStorageState'
import MenuItem from './MenuItem'
import ThemeSwitch from './ThemeSwitch'
import useMangoStore from '../stores/useMangoStore'
import { ConnectWalletButton } from 'components'
import NavDropMenu from './NavDropMenu'
import AccountsModal from './AccountsModal'
import LanguageSwitch from './LanguageSwitch'
import { DEFAULT_MARKET_KEY, initialMarket } from './SettingsModal'
import { useTranslation } from 'next-i18next'
import Settings from './Settings'
@ -127,19 +125,12 @@ const TopBar = () => {
/>
</div>
</div>
<div className="flex items-center">
<div className={`pl-2`}>
<LanguageSwitch />
</div>
<div className={`pl-2`}>
<ThemeSwitch />
</div>
<div className="flex items-center space-x-2.5">
<div className="pl-2">
<Settings />
</div>
{mangoAccount &&
mangoAccount.owner.toBase58() === publicKey?.toBase58() ? (
<div className="pl-2">
mangoAccount.owner.toBase58() === publicKey?.toBase58() ? (
<button
className="rounded border border-th-bkg-4 py-1 px-2 text-xs hover:border-th-fgd-4 focus:outline-none"
onClick={() => setShowAccountsModal(true)}
@ -151,13 +142,8 @@ const TopBar = () => {
? mangoAccount.name
: abbreviateAddress(mangoAccount.publicKey)}
</button>
</div>
) : null}
<div className="flex">
<div className="pl-4">
<ConnectWalletButton />
</div>
</div>
<ConnectWalletButton />
</div>
</div>
</div>

View File

@ -1,8 +1,24 @@
import { ReactNode, useState } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { ChartBarIcon, CurrencyDollarIcon } from '@heroicons/react/solid'
import {
ChartBarIcon,
CurrencyDollarIcon,
MenuIcon,
XIcon,
} from '@heroicons/react/solid'
import { BtcMonoIcon, TradeIcon } from '../icons'
import { useTranslation } from 'next-i18next'
import { IconButton } from '../Button'
import {
CalculatorIcon,
CashIcon,
ChevronRightIcon,
CurrencyDollarIcon as FeesIcon,
LightBulbIcon,
SwitchHorizontalIcon,
UserAddIcon,
} from '@heroicons/react/outline'
const StyledBarItemLabel = ({ children, ...props }) => (
<div style={{ fontSize: '0.6rem', lineHeight: 1 }} {...props}>
@ -13,10 +29,11 @@ const StyledBarItemLabel = ({ children, ...props }) => (
const BottomBar = () => {
const { t } = useTranslation('common')
const { asPath } = useRouter()
const [showPanel, setShowPanel] = useState(false)
return (
<>
<div className="default-transition grid grid-cols-4 grid-rows-1 bg-th-bkg-3 py-2.5">
<div className="default-transition grid grid-cols-5 grid-rows-1 bg-th-bkg-3 py-2.5">
<Link
href={{
pathname: '/select',
@ -69,9 +86,114 @@ const BottomBar = () => {
<StyledBarItemLabel>{t('stats')}</StyledBarItemLabel>
</div>
</Link>
<div
className={`${
showPanel ? 'text-th-primary' : 'text-th-fgd-3'
} default-transition col-span-1 flex cursor-pointer flex-col items-center hover:text-th-primary`}
onClick={() => setShowPanel(!showPanel)}
>
<MenuIcon className="mb-1 h-4 w-4" />
<StyledBarItemLabel>{t('more')}</StyledBarItemLabel>
</div>
</div>
<MoreMenuPanel showPanel={showPanel} setShowPanel={setShowPanel} />
</>
)
}
export default BottomBar
const MoreMenuPanel = ({
showPanel,
setShowPanel,
}: {
showPanel: boolean
setShowPanel: (showPanel: boolean) => void
}) => {
const { t } = useTranslation('common')
return (
<div
className={`fixed bottom-0 z-30 h-96 w-full transform overflow-hidden bg-th-bkg-4 px-4 transition-all duration-700 ease-in-out ${
showPanel ? 'translate-y-0' : 'translate-y-full'
}`}
>
<div className="flex justify-end py-4">
<IconButton className="" onClick={() => setShowPanel(false)}>
<XIcon className="h-5 w-5" />
</IconButton>
</div>
<div
className="border-b border-th-fgd-4"
onClick={() => setShowPanel(false)}
>
<MoreMenuItem
title={t('borrow')}
path="/borrow"
icon={<CashIcon className="h-5 w-5" />}
/>
<MoreMenuItem
title={t('calculator')}
path="/risk-calculator"
icon={<CalculatorIcon className="h-5 w-5" />}
/>
<MoreMenuItem
title={t('swap')}
path="/swap"
icon={<SwitchHorizontalIcon className="h-5 w-5" />}
/>
<MoreMenuItem
title={t('referrals')}
path="/referral"
icon={<UserAddIcon className="h-5 w-5" />}
/>
<MoreMenuItem
title={t('fees')}
path="/fees"
icon={<FeesIcon className="h-5 w-5" />}
/>
<MoreMenuItem
title={t('learn')}
path="https://docs.mango.markets/"
icon={<LightBulbIcon className="h-5 w-5" />}
isExternal
/>
</div>
</div>
)
}
const MoreMenuItem = ({
title,
path,
icon,
isExternal,
}: {
title: string
path: string
icon: ReactNode
isExternal?: boolean
}) =>
isExternal ? (
<a
className="default-transition flex w-full items-center justify-between border-t border-th-fgd-4 px-2 py-3 text-th-fgd-2 hover:text-th-fgd-1"
href={path}
target="_blank"
rel="noopener noreferrer"
>
<div className="flex items-center">
{icon}
<span className="ml-1.5">{title}</span>
</div>
<ChevronRightIcon className="h-5 w-5" />
</a>
) : (
<Link href={path} shallow={true}>
<a className="default-transition flex w-full items-center justify-between border-t border-th-fgd-4 px-2 py-3 text-th-fgd-2 hover:text-th-fgd-1">
<div className="flex items-center">
{icon}
<span className="ml-1.5">{title}</span>
</div>
<ChevronRightIcon className="h-5 w-5" />
</a>
</Link>
)

View File

@ -114,10 +114,7 @@ export default function AdvancedTradeForm({
const isTriggerOrder = TRIGGER_ORDER_TYPES.includes(tradeType)
// TODO saml - create a tick box on the UI; Only available on perps
// eslint-disable-next-line
const [postOnlySlide, setPostOnlySlide] = useState(false)
const [postOnly, setPostOnly] = useState(false)
const [ioc, setIoc] = useState(false)
@ -406,8 +403,6 @@ export default function AdvancedTradeForm({
}
}
// TODO saml - use
// eslint-disable-next-line
const postOnlySlideOnChange = (checked) => {
if (checked) {
setIoc(false)
@ -415,7 +410,6 @@ export default function AdvancedTradeForm({
}
setPostOnlySlide(checked)
}
const postOnChange = (checked) => {
if (checked) {
setIoc(false)
@ -632,7 +626,9 @@ export default function AdvancedTradeForm({
let perpOrderPrice: number = orderPrice
if (isMarketOrder) {
if (tradeType === 'Market' && maxSlippage !== undefined) {
if (postOnlySlide) {
perpOrderType = 'postOnlySlide'
} else if (tradeType === 'Market' && maxSlippage !== undefined) {
perpOrderType = 'ioc'
if (side === 'buy') {
perpOrderPrice = markPrice * (1 + parseFloat(maxSlippage))
@ -793,15 +789,19 @@ export default function AdvancedTradeForm({
min="0"
step={tickSize}
onChange={(e) => onSetPrice(e.target.value)}
value={price}
disabled={isMarketOrder}
value={postOnlySlide ? '' : price}
disabled={isMarketOrder || postOnlySlide}
placeholder={tradeType === 'Market' ? markPrice : null}
prefix={
<img
src={`/assets/icons/${groupConfig.quoteSymbol.toLowerCase()}.svg`}
width="16"
height="16"
/>
<>
{!postOnlySlide && (
<img
src={`/assets/icons/${groupConfig.quoteSymbol.toLowerCase()}.svg`}
width="16"
height="16"
/>
)}
</>
}
/>
</>
@ -908,7 +908,7 @@ export default function AdvancedTradeForm({
</div>
) : null
) : null}
<div className="sm:flex">
<div className="flex-wrap sm:flex">
{isLimitOrder ? (
<div className="flex">
<div className="mr-4 mt-3">
@ -951,7 +951,7 @@ export default function AdvancedTradeForm({
&& showReduceOnly(perpAccount?.basePosition.toNumber())
*/}
{marketConfig.kind === 'perp' ? (
<div className="mt-3">
<div className="mr-4 mt-3">
<Tooltip
className="hidden md:block"
delay={250}
@ -968,6 +968,24 @@ export default function AdvancedTradeForm({
</Tooltip>
</div>
) : null}
{marketConfig.kind === 'perp' ? (
<div className="mt-3">
<Tooltip
className="hidden md:block"
delay={250}
placement="left"
content={t('tooltip-post-and-slide')}
>
<Checkbox
checked={postOnlySlide}
onChange={(e) => postOnlySlideOnChange(e.target.checked)}
disabled={isTriggerOrder}
>
Post & Slide
</Checkbox>
</Tooltip>
</div>
) : null}
{marketConfig.kind === 'spot' ? (
<div className="mt-3">
<Tooltip

View File

@ -180,6 +180,7 @@
"intro-feature-4": "Borrow against your assets for other DeFi activities",
"invalid-address": "The address is invalid",
"ioc": "IOC",
"language": "Language",
"languages-tip-desc": "Choose another language here. More coming soon...",
"languages-tip-title": "Multilingual?",
"layout-tip-desc": "Unlock to re-arrange and re-size the trading panels to your liking.",
@ -361,6 +362,7 @@
"taker": "Taker",
"taker-fee": "Taker Fee",
"target-period-length": "Target Period Length",
"theme": "Theme",
"themes-tip-desc": "Mango, Dark or Light (if you're that way inclined).",
"themes-tip-title": "Color Themes",
"time": "Time",
@ -382,6 +384,7 @@
"tooltip-lock-layout": "Lock Layout",
"tooltip-name-onchain": "Account names are stored on-chain",
"tooltip-post": "Post only orders are guaranteed to be the maker order or else it will be canceled.",
"tooltip-post-and-slide": "Post only slide is a type of limit order that will place your order one tick less than the opposite side of the book.",
"tooltip-projected-leverage": "Projected Leverage",
"tooltip-reduce": "Reduce only orders will only reduce your overall position.",
"tooltip-reset-layout": "Reset Layout",
@ -441,4 +444,4 @@
"your-assets": "Your Assets",
"your-borrows": "Your Borrows",
"zero-mngo-rewards": "0 MNGO Rewards"
}
}

View File

@ -6,5 +6,4 @@
"public-key": "Delegate Public Key",
"delegate-updated": "Delegate Updated",
"set-error": "Could not set Delegate",
"invalid-key": "Invalid public key"
}

View File

@ -23,6 +23,7 @@
"add-name": "Añadir nombre",
"alerts": "Alertas",
"all-assets": "Todos los activos",
"all-time": "All Time",
"amount": "Monto",
"approximate-time": "Tiempo aproximado",
"asset": "Activo",
@ -138,8 +139,8 @@
"favorite": "Favorito",
"favorites": "Favoritos",
"fee": "Tarifa",
"fees": "Fees",
"fee-discount": "Comisiones",
"fees": "Fees",
"first-deposit-desc": "Necesita 0.035 SOL para crear una cuenta de mango.",
"funding": "Fondos",
"funding-chart-title": "Fondos (últimos 30 días)",
@ -159,6 +160,8 @@
"if-referred": "{{fee}} if referred or 10k MNGO",
"if-referred-tooltip": "If you create your Mango Account from a referral link or have 10k MNGO in your Mango Account you get a 0.04% discount off futures fees.",
"in-orders": "En órdenes",
"include-perp": "Include Perp",
"include-spot": "Include Spot",
"includes-borrow": "Incluye el préstamo",
"init-error": "No se pudo realizar la operación de depósito y cuenta de margen inicial",
"init-health": "Salud inicial",
@ -175,7 +178,9 @@
"intro-feature-2": "Todos los activos cuentan como garantía para negociar o pedir prestado",
"intro-feature-3": "Deposite cualquier activo y gane intereses automáticamente",
"intro-feature-4": "Pida prestado contra sus activos para otras actividades de DeFi",
"invalid-address": "The address is invalid",
"ioc": "IOC",
"language": "Language",
"languages-tip-desc": "Elija otro idioma aquí. Más próximamente...",
"languages-tip-title": "Multilingüe?",
"layout-tip-desc": "Desbloquee para reorganizar y cambiar el tamaño de los paneles comerciales a su gusto.",
@ -202,6 +207,8 @@
"maker": "Maker",
"maker-fee": "Orden límite",
"mango": "Mango",
"mango-account-lookup-desc": "Enter a Mango account address to show account details",
"mango-account-lookup-title": "View a Mango Account",
"mango-accounts": "Cuentas Mango",
"margin": "Margen",
"margin-available": "Margen disponible",
@ -302,6 +309,7 @@
"redeem-all": "Redeem All",
"redeem-failure": "Error al canjear MNGO",
"redeem-pnl": "Resolver",
"redeem-positive": "Redeem positive",
"redeem-success": "MNGO canjeado con éxito",
"referrals": "Referencias",
"refresh": "Actualizar",
@ -354,6 +362,7 @@
"taker": "Receptor",
"taker-fee": "Tarifa del receptor",
"target-period-length": "Duración del período objetivo",
"theme": "Theme",
"themes-tip-desc": "Mango, Oscuro o Claro (si te gusta eso).",
"themes-tip-title": "Temas de color",
"time": "Tiempo",
@ -395,9 +404,9 @@
"total-srm": "SRM total en mango",
"totals": "Totales",
"trade": "Comercio",
"trade-export-disclaimer": "Due to the nature of how trades are processed, it is not possible to guarantee that all trades will be exported. However, a best effort approach has been taken, combining several independent sources to reduce the likelihood of missing trades.",
"trade-history": "Historial comercial",
"trades": "Trades",
"trade-export-disclaimer": "Due to the nature of how trades are processed, it is not possible to guarantee that all trades will be exported. However, a best effort approach has been taken, combining several independent sources to reduce the likelihood of missing trades.",
"trades-history": "Historial comercial",
"transaction-sent": "Transacción enviada",
"trigger-price": "Precio de activación",
@ -416,6 +425,7 @@
"v3-unaudited": "El protocolo V3 está en versión beta pública. Este es un software no auditado, utilícelo bajo su propio riesgo.",
"v3-welcome": "Bienvenido a Mango V3",
"value": "Valor",
"view": "View",
"view-all-trades": "Ver todas las operaciones en la página de la cuenta",
"view-counterparty": "Ver contraparte",
"view-transaction": "Ver transacción",

View File

@ -5,6 +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",
"invalid-key": "Invalid public key"
"set-error": "Could not set Delegate"
}

View File

@ -23,6 +23,7 @@
"add-name": "加标签",
"alerts": "警报",
"all-assets": "所有资产",
"all-time": "全历史",
"amount": "数量",
"approximate-time": "大概时间",
"asset": "资产",
@ -138,8 +139,8 @@
"favorite": "喜爱",
"favorites": "喜爱",
"fee": "费率",
"fees": "Fees",
"fee-discount": "费率折扣",
"fees": "费用",
"first-deposit-desc": "创建Mango帐户最少需要0.035 SOL。",
"funding": "资金费",
"funding-chart-title": "资金费 前30天(图表有点延迟)",
@ -156,9 +157,11 @@
"hourly-borrow-interest": "1小时借贷利息",
"hourly-deposit-interest": "1小时存款利息",
"hourly-funding": "1小时资金费",
"if-referred": "{{fee}} if referred or 10k MNGO",
"if-referred-tooltip": "If you create your Mango Account from a referral link or have 10k MNGO in your Mango Account you get a 0.04% discount off futures fees.",
"if-referred": "{{fee}}若被推荐或拥有10k MNGO",
"if-referred-tooltip": "若您以推荐码创建Mango账户或在您的Mango账户中有10k MNGO您将获得0.04%的合约费用折扣。",
"in-orders": "在掛单中",
"include-perp": "包含合约",
"include-spot": "包含现货",
"includes-borrow": "包括存入",
"init-error": "创建Mango帐户与存款出错了",
"init-health": "初始健康度",
@ -175,14 +178,16 @@
"intro-feature-2": "所有资产都可作为交易或借贷的质押品",
"intro-feature-3": "将任何资产存入来自动赚取利息",
"intro-feature-4": "为了把握其他DeFi操作机会而将您的资产质押借贷",
"invalid-address": "您输入的地址有问题",
"ioc": "IOC",
"language": "Language",
"languages-tip-desc": "在这里可选介面语言。更多选择将来...",
"languages-tip-title": "您会多种语言吗?",
"layout-tip-desc": "解锁并根据您的喜好重新排列和调整交易面板的大小。",
"layout-tip-title": "个人化页面布局",
"learn": "学习",
"learn-more": "学习",
"lend": "Lend",
"lend": "借出",
"lets-go": "前往",
"leverage": "杠杆",
"leverage-too-high": "杠杆太高。请减少取款数量",
@ -202,6 +207,8 @@
"maker": "挂单者",
"maker-fee": "挂单费率",
"mango": "Mango",
"mango-account-lookup-desc": "输入Mango帐户地址而查看帐户细节",
"mango-account-lookup-title": "查看Mango帐户",
"mango-accounts": "Mango帐户",
"margin": "杠杆",
"margin-available": "可用保证金",
@ -302,6 +309,7 @@
"redeem-all": "现实所有盈亏",
"redeem-failure": "收获MNGO奖励出错了",
"redeem-pnl": "结清",
"redeem-positive": "现实正数",
"redeem-success": "已收获MNGO奖励了",
"referrals": "推荐",
"refresh": "更新",
@ -354,6 +362,7 @@
"taker": "吃单者",
"taker-fee": "吃单费率",
"target-period-length": "目标期间长度",
"theme": "Theme",
"themes-tip-desc": "Mango黑暗或明亮看您偏向。",
"themes-tip-title": "颜色模式",
"time": "时间",
@ -395,9 +404,9 @@
"total-srm": "在Mango裡的SRM总量",
"totals": "总量",
"trade": "交易",
"trade-export-disclaimer": "Mango尽量以几个独立的来源结合成完整交易历史但由于交易处理方式Mango无法保证所有交易都会导出。",
"trade-history": "交易纪录",
"trades": "成交",
"trade-export-disclaimer": "Due to the nature of how trades are processed, it is not possible to guarantee that all trades will be exported. However, a best effort approach has been taken, combining several independent sources to reduce the likelihood of missing trades.",
"trades-history": "交易纪录",
"transaction-sent": "已下订单",
"trigger-price": "触发价格",
@ -416,6 +425,7 @@
"v3-unaudited": "Mango V3目前还是测试版。此软体未经过审计。风险自负。",
"v3-welcome": "欢迎到Mango V3",
"value": "价值",
"view": "查看",
"view-all-trades": "在帐户页面查看所以交易",
"view-counterparty": "查看交易对方",
"view-transaction": "查看交易",

View File

@ -5,6 +5,5 @@
"info": "将此帐户委托其他Solana帐户控制。",
"public-key": "受托钱包地址",
"delegate-updated": "已更换受托钱包",
"set-error": "设置委托钱包出错",
"invalid-key": "您输入的地址有问题"
"set-error": "设置委托钱包出错"
}

View File

@ -23,6 +23,7 @@
"add-name": "加標籤",
"alerts": "警報",
"all-assets": "所有資產",
"all-time": "全歷史",
"amount": "數量",
"approximate-time": "大概時間",
"asset": "資產",
@ -138,8 +139,8 @@
"favorite": "喜愛",
"favorites": "喜愛",
"fee": "費率",
"fees": "Fees",
"fee-discount": "費率折扣",
"fees": "費用",
"first-deposit-desc": "創建Mango帳戶最少需要0.035 SOL。",
"funding": "資金費",
"funding-chart-title": "資金費 前30天(圖表有點延遲)",
@ -156,9 +157,11 @@
"hourly-borrow-interest": "1小時借貸利息",
"hourly-deposit-interest": "1小時存款利息",
"hourly-funding": "1小時資金費",
"if-referred": "{{fee}} if referred or 10k MNGO",
"if-referred-tooltip": "If you create your Mango Account from a referral link or have 10k MNGO in your Mango Account you get a 0.04% discount off futures fees.",
"if-referred": "{{fee}}若被推薦或擁有10k MNGO",
"if-referred-tooltip": "若您以推薦碼創建Mango賬戶或在您的Mango賬戶中有10k MNGO您將獲得0.04%的合約費用折扣。",
"in-orders": "在掛單中",
"include-perp": "包含合約",
"include-spot": "包含現貨",
"includes-borrow": "包括存入",
"init-error": "創建Mango帳戶與存款出錯了",
"init-health": "初始健康度",
@ -175,14 +178,16 @@
"intro-feature-2": "所有資產都可作為交易或借貸的質押品",
"intro-feature-3": "將任何資產存入來自動賺取利息",
"intro-feature-4": "為了把握其他DeFi操作機會而將您的資產質押借貸",
"invalid-address": "您輸入的地址有問題",
"ioc": "IOC",
"language": "Language",
"languages-tip-desc": "在這裡可選介面語言。更多選擇將來...",
"languages-tip-title": "您會多種語言嗎?",
"layout-tip-desc": "解锁並根据您的喜好重新排列和调整交易面板的大小。",
"layout-tip-title": "個人化頁面佈局",
"learn": "學習",
"learn-more": "學習",
"lend": "Lend",
"lend": "借出",
"lets-go": "前往",
"leverage": "槓桿",
"leverage-too-high": "槓桿太高。請減少取款數量",
@ -202,6 +207,8 @@
"maker": "掛單者",
"maker-fee": "掛單費率",
"mango": "Mango",
"mango-account-lookup-desc": "輸入Mango帳戶地址而查看帳戶細節",
"mango-account-lookup-title": "查看Mango帳戶",
"mango-accounts": "Mango帳戶",
"margin": "槓桿",
"margin-available": "可用保證金",
@ -302,6 +309,7 @@
"redeem-all": "現實所有盈虧",
"redeem-failure": "收穫MNGO獎勵出錯了",
"redeem-pnl": "實現盈虧",
"redeem-positive": "現實正數",
"redeem-success": "已收穫MNGO獎勵了",
"referrals": "推薦",
"refresh": "更新",
@ -354,6 +362,7 @@
"taker": "吃單者",
"taker-fee": "吃單費率",
"target-period-length": "目標期間長度",
"theme": "Theme",
"themes-tip-desc": "Mango黑暗或明亮看您偏向。",
"themes-tip-title": "顏色模式",
"time": "時間",
@ -395,9 +404,9 @@
"total-srm": "在Mango裡的SRM總量",
"totals": "總量",
"trade": "交易",
"trade-export-disclaimer": "Mango儘量以幾個獨立的來源結合成完整交易歷史但由於交易處理方式Mango無法保證所有交易都會導出。",
"trade-history": "交易紀錄",
"trades": "成交",
"trade-export-disclaimer": "Due to the nature of how trades are processed, it is not possible to guarantee that all trades will be exported. However, a best effort approach has been taken, combining several independent sources to reduce the likelihood of missing trades.",
"trades-history": "交易紀錄",
"transaction-sent": "已下訂單",
"trigger-price": "觸發價格",
@ -416,6 +425,7 @@
"v3-unaudited": "Mango V3目前還是測試版。此軟體未經過審計。風險自負。",
"v3-welcome": "歡迎到Mango V3",
"value": "價值",
"view": "查看",
"view-all-trades": "在帳戶頁面查看所以交易",
"view-counterparty": "查看交易對方",
"view-transaction": "查看交易",

View File

@ -5,6 +5,5 @@
"info": "將此帳戶委託其他Solana帳戶控制。",
"public-key": "受託錢包地址",
"delegate-updated": "已更換受託錢包",
"set-error": "設置委託錢包出錯",
"invalid-key": "您輸入的地址有問題"
"set-error": "設置委託錢包出錯"
}