Merge branch 'main' into trade-hot-keys
This commit is contained in:
commit
ce13f685a3
|
@ -264,14 +264,6 @@ function DepositForm({ onSuccess, token }: DepositFormProps) {
|
|||
<p>{t('deposit-amount')}</p>
|
||||
<BankAmountWithValue amount={inputAmount} bank={bank} />
|
||||
</div>
|
||||
{/* <div className="flex justify-between">
|
||||
<div className="flex items-center">
|
||||
<Tooltip content={t('asset-weight-desc')}>
|
||||
<p className="tooltip-underline">{t('asset-weight')}</p>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<p className="font-mono">{bank!.initAssetWeight.toFixed(2)}x</p>
|
||||
</div> */}
|
||||
<div className="flex justify-between">
|
||||
<Tooltip content={t('tooltip-collateral-value')}>
|
||||
<p className="tooltip-underline">{t('collateral-value')}</p>
|
||||
|
@ -281,7 +273,7 @@ function DepositForm({ onSuccess, token }: DepositFormProps) {
|
|||
value={
|
||||
bank.uiPrice *
|
||||
Number(inputAmount) *
|
||||
Number(bank.initAssetWeight)
|
||||
Number(bank.scaledInitAssetWeight(bank.price))
|
||||
}
|
||||
isUsd
|
||||
/>
|
||||
|
|
|
@ -75,38 +75,52 @@ function WithdrawForm({ onSuccess, token }: WithdrawFormProps) {
|
|||
return logoURI
|
||||
}, [bank?.mint, mangoTokens])
|
||||
|
||||
const tokenMax = useMemo(() => {
|
||||
if (!bank || !mangoAccount || !group) return new Decimal(0)
|
||||
const amount = getMaxWithdrawForBank(group, bank, mangoAccount)
|
||||
|
||||
return amount
|
||||
const [adjustedTokenMax, tokenMax] = useMemo(() => {
|
||||
if (!bank || !mangoAccount || !group)
|
||||
return [new Decimal(0), new Decimal(0)]
|
||||
const tokenMax = getMaxWithdrawForBank(group, bank, mangoAccount).toNumber()
|
||||
let adjustedTokenMax = tokenMax
|
||||
const balance = mangoAccount.getTokenBalanceUi(bank)
|
||||
if (tokenMax < balance) {
|
||||
adjustedTokenMax = tokenMax * 0.998
|
||||
}
|
||||
return [new Decimal(adjustedTokenMax), new Decimal(tokenMax)]
|
||||
}, [mangoAccount, bank, group])
|
||||
|
||||
const handleSizePercentage = useCallback(
|
||||
(percentage: string) => {
|
||||
if (!bank) return
|
||||
setSizePercentage(percentage)
|
||||
const amount = floorToDecimal(
|
||||
new Decimal(tokenMax).mul(percentage).div(100),
|
||||
bank.mintDecimals
|
||||
)
|
||||
setInputAmount(amount.toFixed())
|
||||
let amount: Decimal
|
||||
if (percentage !== '100') {
|
||||
amount = floorToDecimal(
|
||||
new Decimal(adjustedTokenMax).mul(percentage).div(100),
|
||||
bank.mintDecimals
|
||||
)
|
||||
} else {
|
||||
amount = floorToDecimal(
|
||||
new Decimal(adjustedTokenMax),
|
||||
bank.mintDecimals
|
||||
)
|
||||
}
|
||||
setInputAmount(amount.toString())
|
||||
},
|
||||
[bank, tokenMax]
|
||||
[bank, adjustedTokenMax]
|
||||
)
|
||||
|
||||
const setMax = useCallback(() => {
|
||||
if (!bank) return
|
||||
const max = floorToDecimal(tokenMax, bank.mintDecimals)
|
||||
setInputAmount(max.toFixed())
|
||||
const max = floorToDecimal(adjustedTokenMax, bank.mintDecimals)
|
||||
setInputAmount(max.toString())
|
||||
setSizePercentage('100')
|
||||
}, [bank, tokenMax])
|
||||
}, [bank, adjustedTokenMax])
|
||||
|
||||
const handleWithdraw = useCallback(async () => {
|
||||
const client = mangoStore.getState().client
|
||||
const group = mangoStore.getState().group
|
||||
const mangoAccount = mangoStore.getState().mangoAccount.current
|
||||
const actions = mangoStore.getState().actions
|
||||
const withdrawAmount = parseFloat(inputAmount)
|
||||
if (!mangoAccount || !group || !bank) return
|
||||
setSubmitting(true)
|
||||
try {
|
||||
|
@ -114,7 +128,7 @@ function WithdrawForm({ onSuccess, token }: WithdrawFormProps) {
|
|||
group,
|
||||
mangoAccount,
|
||||
bank.mint,
|
||||
parseFloat(inputAmount),
|
||||
withdrawAmount,
|
||||
false
|
||||
)
|
||||
notify({
|
||||
|
@ -201,7 +215,7 @@ function WithdrawForm({ onSuccess, token }: WithdrawFormProps) {
|
|||
decimals={bank.mintDecimals}
|
||||
label={t('max')}
|
||||
onClick={setMax}
|
||||
value={tokenMax}
|
||||
value={adjustedTokenMax}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
|
|
|
@ -40,7 +40,8 @@ const AccountChart = ({
|
|||
if (chartToShow === 'cumulative-interest-value') {
|
||||
return data.map((d) => ({
|
||||
interest_value:
|
||||
d.borrow_interest_cumulative_usd + d.deposit_interest_cumulative_usd,
|
||||
d.borrow_interest_cumulative_usd * -1 +
|
||||
d.deposit_interest_cumulative_usd,
|
||||
time: d.time,
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -420,7 +420,7 @@ const AccountPage = () => {
|
|||
The lower your account health is the more likely you are to
|
||||
get liquidated when prices fluctuate.
|
||||
</p>
|
||||
{maintHealth < 100 ? (
|
||||
{maintHealth < 100 && mangoAccountAddress ? (
|
||||
<>
|
||||
<p className="text-xs font-bold text-th-fgd-1">
|
||||
Your account health is {maintHealth}%
|
||||
|
|
|
@ -62,7 +62,12 @@ const ActivityFilters = () => {
|
|||
let advancedParams = ''
|
||||
Object.entries(advancedFilters).map((entry) => {
|
||||
if (entry[1].length) {
|
||||
advancedParams = advancedParams + `&${entry[0]}=${entry[1]}`
|
||||
// ETH should be renamed to ETH (Portal) in the database
|
||||
const alignSymbolsToBackend = entry[1].map((e: string) =>
|
||||
e === 'ETH (Portal)' ? 'ETH' : e
|
||||
)
|
||||
advancedParams =
|
||||
advancedParams + `&${entry[0]}=${alignSymbolsToBackend}`
|
||||
}
|
||||
})
|
||||
return advancedParams
|
||||
|
|
|
@ -45,7 +45,11 @@ const fetchHourlyFunding = async (mangoAccountPk: string) => {
|
|||
const stats: HourlyFundingStatsData[] = entries.map(([key, value]) => {
|
||||
const marketEntries = Object.entries(value)
|
||||
const marketFunding = marketEntries.map(([key, value]) => {
|
||||
return { ...value, time: key }
|
||||
return {
|
||||
long_funding: value.long_funding * -1,
|
||||
short_funding: value.short_funding * -1,
|
||||
time: key,
|
||||
}
|
||||
})
|
||||
return { marketFunding, market: key }
|
||||
})
|
||||
|
|
|
@ -3,7 +3,13 @@ import GovernanceStore from '@store/governanceStore'
|
|||
import mangoStore from '@store/mangoStore'
|
||||
import { ReactNode, useEffect } from 'react'
|
||||
|
||||
const GovernancePageWrapper = ({ children }: { children: ReactNode }) => {
|
||||
const GovernancePageWrapper = ({
|
||||
children,
|
||||
noStyles,
|
||||
}: {
|
||||
children: ReactNode
|
||||
noStyles?: boolean
|
||||
}) => {
|
||||
const { publicKey } = useWallet()
|
||||
|
||||
const initConnection = GovernanceStore((s) => s.initConnection)
|
||||
|
@ -44,8 +50,12 @@ const GovernancePageWrapper = ({ children }: { children: ReactNode }) => {
|
|||
])
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-12">
|
||||
<div className="col-span-12 lg:col-span-8 lg:col-start-3">{children}</div>
|
||||
<div className={!noStyles ? 'grid grid-cols-12' : ''}>
|
||||
<div
|
||||
className={!noStyles ? 'col-span-12 lg:col-span-8 lg:col-start-3' : ''}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ import CreateOpenbookMarketModal from '@components/modals/CreateOpenbookMarketMo
|
|||
import { calculateTradingParameters } from 'utils/governance/listingTools'
|
||||
import useJupiterMints from 'hooks/useJupiterMints'
|
||||
import CreateSwitchboardOracleModal from '@components/modals/CreateSwitchboardOracleModal'
|
||||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
|
||||
type FormErrors = Partial<Record<keyof TokenListForm, string>>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import InlineNotification from '@components/shared/InlineNotification'
|
||||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
import { useWallet } from '@solana/wallet-adapter-react'
|
||||
import GovernanceStore from '@store/governanceStore'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
HandThumbDownIcon,
|
||||
HandThumbUpIcon,
|
||||
} from '@heroicons/react/20/solid'
|
||||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { MANGO_GOVERNANCE_PROGRAM } from 'utils/governance/constants'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
|
|
|
@ -8,7 +8,7 @@ import { MANGO_MINT } from 'utils/constants'
|
|||
import { PublicKey } from '@solana/web3.js'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { tryGetMint } from 'utils/governance/tools'
|
||||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import SheenLoader from '@components/shared/SheenLoader'
|
||||
import { NoSymbolIcon } from '@heroicons/react/20/solid'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Tooltip from '@components/shared/Tooltip'
|
||||
import { CheckCircleIcon } from '@heroicons/react/20/solid'
|
||||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
import { Governance, ProgramAccount, Proposal } from '@solana/spl-governance'
|
||||
import { RawMint } from '@solana/spl-token'
|
||||
import GovernanceStore from '@store/governanceStore'
|
||||
|
|
|
@ -3,7 +3,7 @@ import VoteResultsBar from './VoteResultBar'
|
|||
import { fmtTokenAmount } from 'utils/governance/tools'
|
||||
import { RawMint } from '@solana/spl-token'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
|
||||
type VoteResultsProps = {
|
||||
proposal: Proposal
|
||||
|
|
|
@ -17,7 +17,9 @@ import Tooltip from '@components/shared/Tooltip'
|
|||
const RPC_URLS = [
|
||||
{
|
||||
label: 'Triton',
|
||||
value: 'https://mango.rpcpool.com/0f9acc0d45173b51bf7d7e09c1e5',
|
||||
value:
|
||||
process.env.NEXT_PUBLIC_ENDPOINT ||
|
||||
'https://mango.rpcpool.com/946ef7337da3f5b8d3e4a34e7f88',
|
||||
},
|
||||
// {
|
||||
// label: 'Genesys Go',
|
||||
|
|
|
@ -141,9 +141,13 @@ const TokenDetailsTable = () => {
|
|||
</Td>
|
||||
<Td>
|
||||
<div className="flex justify-end space-x-1.5 text-right">
|
||||
<p>{bank.initAssetWeight.toFixed(2)}</p>
|
||||
<p>
|
||||
{bank.scaledInitAssetWeight(bank.price).toFixed(2)}
|
||||
</p>
|
||||
<span className="text-th-fgd-4">|</span>
|
||||
<p>{bank.initLiabWeight.toFixed(2)}</p>
|
||||
<p>
|
||||
{bank.scaledInitLiabWeight(bank.price).toFixed(2)}
|
||||
</p>
|
||||
</div>
|
||||
</Td>
|
||||
<Td>
|
||||
|
@ -254,11 +258,15 @@ const TokenDetailsTable = () => {
|
|||
</Tooltip>
|
||||
<div className="flex space-x-1.5 text-right font-mono">
|
||||
<p className="text-th-fgd-1">
|
||||
{bank.initAssetWeight.toFixed(2)}
|
||||
{bank
|
||||
.scaledInitAssetWeight(bank.price)
|
||||
.toFixed(2)}
|
||||
</p>
|
||||
<span className="text-th-fgd-4">|</span>
|
||||
<p className="text-th-fgd-1">
|
||||
{bank.initLiabWeight.toFixed(2)}
|
||||
{bank
|
||||
.scaledInitLiabWeight(bank.price)
|
||||
.toFixed(2)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
} from '@blockworks-foundation/mango-v4'
|
||||
import Tooltip from '@components/shared/Tooltip'
|
||||
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid'
|
||||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import { getOracleProvider } from 'hooks/useOracleProvider'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
@ -41,11 +41,11 @@ const TokenParams = ({ bank }: { bank: Bank }) => {
|
|||
</Tooltip>
|
||||
<div className="flex space-x-2">
|
||||
<p className="font-mono text-th-fgd-2">
|
||||
{bank.initAssetWeight.toFixed(2)}
|
||||
{bank.scaledInitAssetWeight(bank.price).toFixed(2)}
|
||||
</p>
|
||||
<span className="text-th-fgd-4">|</span>
|
||||
<p className="font-mono text-th-fgd-2">
|
||||
{bank.initLiabWeight.toFixed(2)}
|
||||
{bank.scaledInitLiabWeight(bank.price).toFixed(2)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
import MarketLogos from './MarketLogos'
|
||||
import SoonBadge from '@components/shared/SoonBadge'
|
||||
import TabButtons from '@components/shared/TabButtons'
|
||||
import { PerpMarket } from '@blockworks-foundation/mango-v4'
|
||||
|
||||
const MARKET_LINK_WRAPPER_CLASSES =
|
||||
'flex items-center justify-between px-4 md:pl-6 md:pr-4'
|
||||
|
@ -35,7 +36,9 @@ const MARKET_LINK_DISABLED_CLASSES =
|
|||
const MarketSelectDropdown = () => {
|
||||
const { t } = useTranslation('common')
|
||||
const { selectedMarket } = useSelectedMarket()
|
||||
const [spotOrPerp, setSpotOrPerp] = useState('perp')
|
||||
const [spotOrPerp, setSpotOrPerp] = useState(
|
||||
selectedMarket instanceof PerpMarket ? 'perp' : 'spot'
|
||||
)
|
||||
const serumMarkets = mangoStore((s) => s.serumMarkets)
|
||||
const allPerpMarkets = mangoStore((s) => s.perpMarkets)
|
||||
const perpStats = mangoStore((s) => s.perpStats.data)
|
||||
|
@ -130,9 +133,6 @@ const MarketSelectDropdown = () => {
|
|||
<div
|
||||
className={MARKET_LINK_WRAPPER_CLASSES}
|
||||
key={m.publicKey.toString()}
|
||||
onClick={() => {
|
||||
if (!isComingSoon) close()
|
||||
}}
|
||||
>
|
||||
{!isComingSoon ? (
|
||||
<>
|
||||
|
@ -142,6 +142,9 @@ const MarketSelectDropdown = () => {
|
|||
pathname: '/trade',
|
||||
query: { name: m.name },
|
||||
}}
|
||||
onClick={() => {
|
||||
close()
|
||||
}}
|
||||
shallow={true}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
|
@ -236,9 +239,6 @@ const MarketSelectDropdown = () => {
|
|||
<div
|
||||
className={MARKET_LINK_WRAPPER_CLASSES}
|
||||
key={m.publicKey.toString()}
|
||||
onClick={() => {
|
||||
close()
|
||||
}}
|
||||
>
|
||||
<Link
|
||||
className={MARKET_LINK_CLASSES}
|
||||
|
@ -246,6 +246,9 @@ const MarketSelectDropdown = () => {
|
|||
pathname: '/trade',
|
||||
query: { name: m.name },
|
||||
}}
|
||||
onClick={() => {
|
||||
close()
|
||||
}}
|
||||
shallow={true}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
BookSideType,
|
||||
MangoClient,
|
||||
PerpMarket,
|
||||
Serum3Market,
|
||||
} from '@blockworks-foundation/mango-v4'
|
||||
import useSelectedMarket from 'hooks/useSelectedMarket'
|
||||
import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettings'
|
||||
|
@ -425,7 +426,11 @@ const Orderbook = () => {
|
|||
const selectedMarket = mangoStore.getState().selectedMarket
|
||||
if (!useOrderbookFeed || !selectedMarket || !selectedMarket.current)
|
||||
return
|
||||
if (update.market != selectedMarket.current.publicKey.toBase58()) return
|
||||
const selectedMarketKey =
|
||||
selectedMarket.current instanceof Serum3Market
|
||||
? selectedMarket.current['serumMarketExternal']
|
||||
: selectedMarket.current.publicKey
|
||||
if (update.market != selectedMarketKey.toBase58()) return
|
||||
|
||||
// ensure updates are applied in the correct order by checking slot and writeVersion
|
||||
const lastSeenSlot =
|
||||
|
|
|
@ -17,13 +17,18 @@ import { useTranslation } from 'next-i18next'
|
|||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { floorToDecimal, getDecimalCount } from 'utils/numbers'
|
||||
import {
|
||||
floorToDecimal,
|
||||
formatCurrencyValue,
|
||||
getDecimalCount,
|
||||
} from 'utils/numbers'
|
||||
import { breakpoints } from 'utils/theme'
|
||||
import { calculateLimitPriceForMarketOrder } from 'utils/tradeForm'
|
||||
import MarketCloseModal from './MarketCloseModal'
|
||||
import MarketLogos from './MarketLogos'
|
||||
import PerpSideBadge from './PerpSideBadge'
|
||||
import TableMarketName from './TableMarketName'
|
||||
import Tooltip from '@components/shared/Tooltip'
|
||||
|
||||
const PerpPositions = () => {
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
|
@ -119,7 +124,7 @@ const PerpPositions = () => {
|
|||
<Th className="text-right">{`${t('trade:unsettled')} ${t(
|
||||
'pnl'
|
||||
)}`}</Th>
|
||||
<Th className="text-right">{t('pnl')}</Th>
|
||||
<Th className="text-right">{t('trade:unrealized-pnl')}</Th>
|
||||
{!isUnownedAccount ? <Th /> : null}
|
||||
</TrHead>
|
||||
</thead>
|
||||
|
@ -140,8 +145,10 @@ const PerpPositions = () => {
|
|||
if (!basePosition) return null
|
||||
|
||||
const unsettledPnl = position.getUnsettledPnlUi(market)
|
||||
const cummulativePnl =
|
||||
const totalPnl =
|
||||
position.cumulativePnlOverPositionLifetimeUi(market)
|
||||
const unrealizedPnl = position.getUnRealizedPnlUi(market)
|
||||
const realizedPnl = position.getRealizedPnlUi()
|
||||
|
||||
return (
|
||||
<TrBody
|
||||
|
@ -207,16 +214,31 @@ const PerpPositions = () => {
|
|||
decimals={2}
|
||||
/>
|
||||
</Td>
|
||||
<Td
|
||||
className={`text-right font-mono ${
|
||||
cummulativePnl > 0 ? 'text-th-up' : 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
<FormatNumericValue
|
||||
value={cummulativePnl}
|
||||
isUsd
|
||||
decimals={2}
|
||||
/>
|
||||
<Td className="text-right font-mono">
|
||||
<Tooltip
|
||||
content={
|
||||
<PnlTooltipContent
|
||||
unrealizedPnl={unrealizedPnl}
|
||||
realizedPnl={realizedPnl}
|
||||
totalPnl={totalPnl}
|
||||
/>
|
||||
}
|
||||
delay={100}
|
||||
>
|
||||
<span
|
||||
className={`tooltip-underline ${
|
||||
unrealizedPnl > 0
|
||||
? 'text-th-up'
|
||||
: 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
<FormatNumericValue
|
||||
value={unrealizedPnl}
|
||||
isUsd
|
||||
decimals={2}
|
||||
/>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Td>
|
||||
{!isUnownedAccount ? (
|
||||
<Td>
|
||||
|
@ -271,8 +293,10 @@ const PerpPositions = () => {
|
|||
selectedMarket.perpMarketIndex === position.marketIndex
|
||||
|
||||
if (!basePosition) return null
|
||||
const cummulativePnl =
|
||||
const totalPnl =
|
||||
position.cumulativePnlOverPositionLifetimeUi(market)
|
||||
const unrealizedPnl = position.getUnRealizedPnlUi(market)
|
||||
const realizedPnl = position.getRealizedPnlUi()
|
||||
return (
|
||||
<div
|
||||
className="flex items-center justify-between border-b border-th-bkg-3 p-4"
|
||||
|
@ -338,11 +362,24 @@ const PerpPositions = () => {
|
|||
<div className="flex items-center space-x-4">
|
||||
<div
|
||||
className={`text-right font-mono leading-none ${
|
||||
cummulativePnl > 0 ? 'text-th-up' : 'text-th-down'
|
||||
unrealizedPnl > 0 ? 'text-th-up' : 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
<p className="mb-1 text-th-fgd-4">PnL</p>
|
||||
<FormatNumericValue value={cummulativePnl} isUsd />
|
||||
<Tooltip
|
||||
content={
|
||||
<PnlTooltipContent
|
||||
unrealizedPnl={unrealizedPnl}
|
||||
realizedPnl={realizedPnl}
|
||||
totalPnl={totalPnl}
|
||||
/>
|
||||
}
|
||||
delay={100}
|
||||
>
|
||||
<p className="tooltip-underline mb-1 font-body text-th-fgd-4">
|
||||
{t('trade:unrealized-pnl')}
|
||||
</p>
|
||||
</Tooltip>
|
||||
<FormatNumericValue value={unrealizedPnl} isUsd />
|
||||
</div>
|
||||
{!isUnownedAccount ? (
|
||||
<Button
|
||||
|
@ -383,3 +420,46 @@ const PerpPositions = () => {
|
|||
}
|
||||
|
||||
export default PerpPositions
|
||||
|
||||
const PnlTooltipContent = ({
|
||||
unrealizedPnl,
|
||||
realizedPnl,
|
||||
totalPnl,
|
||||
}: {
|
||||
unrealizedPnl: number
|
||||
realizedPnl: number
|
||||
totalPnl: number
|
||||
}) => {
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
return (
|
||||
<>
|
||||
<div className="mb-3 space-y-1">
|
||||
<div className="flex justify-between">
|
||||
<p className="mr-3">{t('trade:unrealized-pnl')}</p>
|
||||
<span className="font-mono text-th-fgd-2">
|
||||
{formatCurrencyValue(unrealizedPnl, 2)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<p className="mr-3">{t('trade:realized-pnl')}</p>
|
||||
<span className="font-mono text-th-fgd-2">
|
||||
{formatCurrencyValue(realizedPnl, 2)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<p className="mr-3">{t('trade:total-pnl')}</p>
|
||||
<span className="font-mono text-th-fgd-2">
|
||||
{formatCurrencyValue(totalPnl, 2)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
href="https://docs.mango.markets/mango-markets/settle-pnl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{t('learn-more')}
|
||||
</a>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import { Order } from '@project-serum/serum/lib/market'
|
|||
import { PublicKey } from '@solana/web3.js'
|
||||
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||
import { formatNumericValue, getDecimalCount } from 'utils/numbers'
|
||||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
import Datafeed from 'apis/datafeed'
|
||||
// import PerpDatafeed from 'apis/mngo/datafeed'
|
||||
import { CombinedTradeHistory, isMangoError } from 'types'
|
||||
|
|
|
@ -50,9 +50,12 @@ export default function useBanksWithBalances(
|
|||
const maxBorrow = mangoAccount
|
||||
? getMaxWithdrawForBank(group, bank, mangoAccount, true).toNumber()
|
||||
: 0
|
||||
const maxWithdraw = mangoAccount
|
||||
let maxWithdraw = mangoAccount
|
||||
? getMaxWithdrawForBank(group, bank, mangoAccount).toNumber()
|
||||
: 0
|
||||
if (maxWithdraw < balance) {
|
||||
maxWithdraw = maxWithdraw * 0.998
|
||||
}
|
||||
const borrowedAmount = mangoAccount
|
||||
? floorToDecimal(
|
||||
mangoAccount.getTokenBorrowsUi(bank),
|
||||
|
|
|
@ -28,7 +28,7 @@ const fetchBirdeyePrices = async (
|
|||
if (responses?.length) {
|
||||
return responses.map((res) => ({
|
||||
data: res.data.items,
|
||||
mint: res.data.items[0].address,
|
||||
mint: res.data.items[0]?.address,
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,12 @@ const webpack = require('webpack')
|
|||
const nextConfig = {
|
||||
i18n,
|
||||
images: {
|
||||
domains: ['raw.githubusercontent.com', 'arweave.net', 'www.dual.finance'],
|
||||
domains: [
|
||||
'raw.githubusercontent.com',
|
||||
'arweave.net',
|
||||
'www.dual.finance',
|
||||
'storage.googleapis.com',
|
||||
],
|
||||
},
|
||||
reactStrictMode: true,
|
||||
//proxy for openserum api cors
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@blockworks-foundation/mango-feeds": "0.1.6",
|
||||
"@blockworks-foundation/mango-v4": "^0.15.13",
|
||||
"@blockworks-foundation/mango-v4": "^0.16.6",
|
||||
"@headlessui/react": "1.6.6",
|
||||
"@heroicons/react": "2.0.10",
|
||||
"@metaplex-foundation/js": "0.18.3",
|
||||
|
@ -104,6 +104,7 @@
|
|||
"typescript": "4.9.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"@coral-xyz/anchor": "^0.27.0",
|
||||
"eslint-config-next/eslint-import-resolver-typescript/tsconfig-paths/json5": "1.0.2"
|
||||
},
|
||||
"lavamoat": {
|
||||
|
|
|
@ -42,6 +42,10 @@ import { THEME_KEY } from 'utils/constants'
|
|||
// Create a client
|
||||
export const queryClient = new QueryClient()
|
||||
|
||||
const metaTitle = 'Mango Markets – Safer. Smarter. Faster.'
|
||||
const metaDescription =
|
||||
'A magical new way to interact with DeFi. Groundbreaking safety features designed to keep your funds secure. The easiest way to margin trade any token pair. All powered by flashloans.'
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
const network = WalletAdapterNetwork.Mainnet
|
||||
const endpoint = useMemo(() => clusterApiUrl(network), [network])
|
||||
|
@ -73,16 +77,9 @@ function MyApp({ Component, pageProps }: AppProps) {
|
|||
<Head>
|
||||
<title>Mango Markets</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta property="og:title" content="Mango Markets" />
|
||||
<meta property="og:title" content={metaTitle} />
|
||||
<meta name="description" content={metaDescription} />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta
|
||||
name="keywords"
|
||||
content="Mango Markets, Serum, SRM, Serum DEX, DEFI, Decentralized Finance, Decentralised Finance, Crypto, ERC20, Ethereum, Decentralize, Solana, SOL, SPL, Cross-Chain, Trading, Fastest, Fast, SerumBTC, SerumUSD, SRM Tokens, SPL Tokens"
|
||||
/>
|
||||
<meta
|
||||
name="description"
|
||||
content="A magical new way to interact with DeFi. Groundbreaking safety features designed to keep your funds secure."
|
||||
/>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="192x192"
|
||||
|
@ -91,11 +88,8 @@ function MyApp({ Component, pageProps }: AppProps) {
|
|||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="Mango Markets" />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content="A magical new way to interact with DeFi. Groundbreaking safety features designed to keep your funds secure."
|
||||
/>
|
||||
<meta name="twitter:title" content={metaTitle} />
|
||||
<meta name="twitter:description" content={metaDescription} />
|
||||
<meta
|
||||
name="twitter:image"
|
||||
content="https://app.mango.markets/images/1200x600-share.png?34567879"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,7 +12,7 @@ import {
|
|||
} from '@blockworks-foundation/mango-v4'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import { formatNumericValue } from 'utils/numbers'
|
||||
import { AnchorProvider, web3 } from '@project-serum/anchor'
|
||||
import { AnchorProvider, web3 } from '@coral-xyz/anchor'
|
||||
|
||||
export async function getStaticProps({ locale }: { locale: string }) {
|
||||
return {
|
||||
|
@ -51,7 +51,8 @@ const RiskDashboard: NextPage = () => {
|
|||
() => {
|
||||
const provider = new AnchorProvider(
|
||||
new web3.Connection(
|
||||
'https://mango.rpcpool.com/0f9acc0d45173b51bf7d7e09c1e5',
|
||||
process.env.NEXT_PUBLIC_ENDPOINT ||
|
||||
'https://mango.rpcpool.com/946ef7337da3f5b8d3e4a34e7f88',
|
||||
'processed'
|
||||
),
|
||||
emptyWallet,
|
||||
|
|
|
@ -0,0 +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_2784_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="url(#paint0_linear_2784_2263)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 16C1.5 7.99188 7.99188 1.5 16 1.5C24.0081 1.5 30.5 7.99188 30.5 16C30.5 24.0081 24.0081 30.5 16 30.5C7.99188 30.5 1.5 24.0081 1.5 16ZM16 2.5C8.54416 2.5 2.5 8.54416 2.5 16C2.5 23.4558 8.54416 29.5 16 29.5C23.4558 29.5 29.5 23.4558 29.5 16C29.5 8.54416 23.4558 2.5 16 2.5Z" fill="white"/>
|
||||
<path d="M6.15479 12.2139H6.18078C6.17324 12.2168 6.16359 12.2168 6.15479 12.2139Z" fill="#308D8A"/>
|
||||
<path d="M10.2963 19.1043C10.3983 19.0023 10.5384 18.9429 10.6871 18.9429H24.1678C24.4141 18.9429 24.5373 19.2402 24.3632 19.4143L21.7001 22.0773C21.5982 22.1793 21.4581 22.2387 21.3094 22.2387H7.82868C7.58234 22.2387 7.45917 21.9414 7.63331 21.7673L10.2963 19.1043Z" fill="white"/>
|
||||
<path d="M10.2963 9.16139C10.4025 9.05946 10.5427 9 10.6871 9H24.1678C24.4141 9 24.5373 9.29731 24.3632 9.47144L21.7001 12.1345C21.5982 12.2364 21.4581 12.2958 21.3094 12.2958H7.82868C7.58234 12.2958 7.45917 11.9985 7.63331 11.8244L10.2963 9.16139Z" fill="white"/>
|
||||
<path d="M21.7001 14.1008C21.5982 13.9989 21.4581 13.9395 21.3094 13.9395H7.82868C7.58234 13.9395 7.45917 14.2368 7.63331 14.4109L10.2963 17.0739C10.3983 17.1758 10.5384 17.2353 10.6871 17.2353H24.1678C24.4141 17.2353 24.5373 16.938 24.3632 16.7639L21.7001 14.1008Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_2784_2263" x1="32" y1="32" x2="0" y2="0" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#3D9B7F"/>
|
||||
<stop offset="1" stop-color="#87D58F"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_2784_2263">
|
||||
<rect width="32" height="32" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -89,6 +89,7 @@
|
|||
"interest-earned-paid": "Interest Earned",
|
||||
"leaderboard": "Leaderboard",
|
||||
"learn": "Learn",
|
||||
"learn-more": "Learn More",
|
||||
"leverage": "Leverage",
|
||||
"liability-weight": "Liability Weight",
|
||||
"liquidity": "Liquidity",
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
"price-expect": "The price you receive may be worse than you expect and full execution is not guaranteed. Max slippage is 2.5% for your safety. The part of your position with slippage beyond 2.5% will not be closed.",
|
||||
"price-provided-by": "Oracle by",
|
||||
"quote": "Quote",
|
||||
"realized-pnl": "Realized PnL",
|
||||
"reduce": "Reduce",
|
||||
"reduce-only": "Reduce Only",
|
||||
"sells": "Sells",
|
||||
|
@ -88,9 +89,11 @@
|
|||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
"interest-earned-paid": "Interest Earned",
|
||||
"leaderboard": "Leaderboard",
|
||||
"learn": "Learn",
|
||||
"learn-more": "Learn More",
|
||||
"leverage": "Leverage",
|
||||
"liability-weight": "Liability Weight",
|
||||
"liquidity": "Liquidity",
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
"price-expect": "The price you receive may be worse than you expect and full execution is not guaranteed. Max slippage is 2.5% for your safety. The part of your position with slippage beyond 2.5% will not be closed.",
|
||||
"price-provided-by": "Oracle by",
|
||||
"quote": "Quote",
|
||||
"realized-pnl": "Realized PnL",
|
||||
"reduce": "Reduce",
|
||||
"reduce-only": "Reduce Only",
|
||||
"sells": "Sells",
|
||||
|
@ -88,9 +89,11 @@
|
|||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
"interest-earned-paid": "Interest Earned",
|
||||
"leaderboard": "Leaderboard",
|
||||
"learn": "Learn",
|
||||
"learn-more": "Learn More",
|
||||
"leverage": "Leverage",
|
||||
"liability-weight": "Liability Weight",
|
||||
"liquidity": "Liquidity",
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
"price-expect": "The price you receive may be worse than you expect and full execution is not guaranteed. Max slippage is 2.5% for your safety. The part of your position with slippage beyond 2.5% will not be closed.",
|
||||
"price-provided-by": "Oracle by",
|
||||
"quote": "Quote",
|
||||
"realized-pnl": "Realized PnL",
|
||||
"reduce": "Reduce",
|
||||
"reduce-only": "Reduce Only",
|
||||
"sells": "Sells",
|
||||
|
@ -88,9 +89,11 @@
|
|||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
"interest-earned-paid": "获取利息",
|
||||
"leaderboard": "排行榜",
|
||||
"learn": "学",
|
||||
"learn-more": "Learn More",
|
||||
"leverage": "杠杆",
|
||||
"liability-weight": "债务权重",
|
||||
"liquidity": "流动性",
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
{
|
||||
"24h-volume": "24h Volume",
|
||||
"activate-volume-alert": "开启交易量警报",
|
||||
"amount": "数量",
|
||||
"activate-volume-alert": "Activate Volume Alert",
|
||||
"amount": "Amount",
|
||||
"average-funding": "Average {{interval}} Funding",
|
||||
"base": "基础",
|
||||
"book": "挂单薄",
|
||||
"buys": "买单",
|
||||
"cancel-order-error": "取消挂单出错",
|
||||
"close-confirm": "市场平仓您的{{config_name}}持仓",
|
||||
"close-position": "平仓",
|
||||
"connect-orders": "连接以查看您的订单",
|
||||
"connect-positions": "连接以查看您的持仓",
|
||||
"connect-trade-history": "连接以查看交易纪录",
|
||||
"connect-unsettled": "连接以查看未结清余额",
|
||||
"copy-and-share": "复制影像",
|
||||
"current-price": "目前价格",
|
||||
"base": "Base",
|
||||
"book": "Book",
|
||||
"buys": "Buys",
|
||||
"cancel-order-error": "Failed to cancel order",
|
||||
"close-confirm": "Market close your {{config_name}} position",
|
||||
"close-position": "Close Position",
|
||||
"connect-orders": "Connect to view your open orders",
|
||||
"connect-positions": "Connect to view your perp positions",
|
||||
"connect-trade-history": "Connect to view your trade history",
|
||||
"connect-unsettled": "Connect to view your unsettled funds",
|
||||
"copy-and-share": "Copy Image to Clipboard",
|
||||
"current-price": "Current Price",
|
||||
"edit-order": "Edit Order",
|
||||
"entry-price": "入场价",
|
||||
"est-slippage": "预计下滑",
|
||||
"funding-limits": "资金费限制",
|
||||
"funding-rate": "资金费率",
|
||||
"grouping": "分组",
|
||||
"hide-asks": "隐藏要价",
|
||||
"hide-bids": "隐藏出价",
|
||||
"in-orders": "在挂单中",
|
||||
"init-leverage": "初始杠杆",
|
||||
"instantaneous-funding": "瞬时资金费率",
|
||||
"insured": "被{{token}}保险",
|
||||
"interval-seconds": "间隔(秒)",
|
||||
"last-updated": "最近更新",
|
||||
"entry-price": "Entry Price",
|
||||
"est-slippage": "Est. Slippage",
|
||||
"funding-limits": "Funding Limits",
|
||||
"funding-rate": "1h Avg Funding Rate",
|
||||
"grouping": "Grouping",
|
||||
"hide-asks": "Hide Asks",
|
||||
"hide-bids": "Hide Bids",
|
||||
"in-orders": "In Orders",
|
||||
"init-leverage": "Init Leverage",
|
||||
"instantaneous-funding": "Instantaneous Funding Snapshot",
|
||||
"interval-seconds": "Interval (seconds)",
|
||||
"insured": "{{token}} Insured",
|
||||
"last-updated": "Last updated",
|
||||
"limit": "Limit",
|
||||
"limit-price": "限价价格",
|
||||
"long": "做多",
|
||||
|
@ -38,26 +38,27 @@
|
|||
"market-details": "{{market}}市场细节",
|
||||
"max-leverage": "最多杠杆",
|
||||
"min-order-size": "最小订单量",
|
||||
"maker-fee": "Maker Fee",
|
||||
"min-order-size-error": "Min order size is {{minSize}} {{symbol}}",
|
||||
"more-details": "More Details",
|
||||
"no-balances": "您没有余额",
|
||||
"no-orders": "您没有订单",
|
||||
"no-positions": "您没有持仓",
|
||||
"no-unsettled": "您没有未结清余额",
|
||||
"notional": "合约面值",
|
||||
"notional-volume": "面值交易量($)",
|
||||
"open-interest": "持仓量",
|
||||
"oracle": "预言机",
|
||||
"oracle-not-updated": "此预言机最近没有更新。",
|
||||
"oracle-not-updated-warning": "含有此币种的帐户无法进行活动。",
|
||||
"oracle-price": "预言机价格",
|
||||
"order-error": "下订单出错了",
|
||||
"order-type": "订单方式",
|
||||
"order-value": "订单价值",
|
||||
"orders": "订单",
|
||||
"place-order": "下{{side}}单",
|
||||
"placing-order": "正在下单",
|
||||
"positions": "当前持仓",
|
||||
"no-balances": "No balances",
|
||||
"no-orders": "No open orders",
|
||||
"no-positions": "No perp positions",
|
||||
"no-unsettled": "No unsettled funds",
|
||||
"notional": "Notional",
|
||||
"notional-volume": "Notional Volume ($)",
|
||||
"open-interest": "Open Interest",
|
||||
"oracle": "Oracle",
|
||||
"oracle-not-updated": "This oracle has not updated recently.",
|
||||
"oracle-not-updated-warning": "Actions will fail for accounts with a position in this token.",
|
||||
"oracle-price": "Oracle Price",
|
||||
"order-error": "Failed to place order",
|
||||
"order-type": "Order Type",
|
||||
"order-value": "Order Value",
|
||||
"orders": "Orders",
|
||||
"place-order": "Place {{side}} Order",
|
||||
"placing-order": "Placing Order",
|
||||
"positions": "Positions",
|
||||
"post": "Post",
|
||||
"preview-sound": "声音预览",
|
||||
"price-expect": "您收到的价格可能与您预期有差异,并且无法保证完全执行。为了您的安全,最大滑点保持为 2.5%。超过 2.5%滑点的部分不会被平仓。",
|
||||
|
@ -77,19 +78,22 @@
|
|||
"stable-price": "穩定價格",
|
||||
"taker": "吃單者",
|
||||
"tick-size": "波動單位",
|
||||
"taker-fee": "Taker Fee",
|
||||
"tooltip-borrow-balance": "You'll use your {{balance}} {{token}} balance and borrow {{borrowAmount}} {{token}} to execute this trade. The current {{token}} variable borrow rate is {{rate}}%",
|
||||
"tooltip-borrow-no-balance": "You'll borrow {{borrowAmount}} {{token}} to execute this trade. The current {{token}} variable borrow rate is {{rate}}%",
|
||||
"tooltip-enable-margin": "為此交易啟用保證金",
|
||||
"tooltip-ioc": "IOC交易若不吃單就會被取消。任何無法立刻成交的部分將被取消",
|
||||
"tooltip-insured": "如果發生破產,{{tokenOrMarket}}損失是否可以從保險基金中歸還",
|
||||
"tooltip-post": "Post交易若不掛單就會被取消。",
|
||||
"tooltip-slippage": "當前價格與您的交易將執行的價格之間的差值的估計",
|
||||
"tooltip-stable-price": "穩定價格用於一個安全機制。此機制可以限制用戶在預言機價格快速波動時下風險高的訂單",
|
||||
"tooltip-volume-alert": "交易量警報設定",
|
||||
"trade-sounds-tooltip": "為每筆新交易播放警報聲音",
|
||||
"trades": "交易",
|
||||
"tweet-position": "分享至Twitter",
|
||||
"unsettled": "未結清",
|
||||
"volume-alert": "交易量警報",
|
||||
"volume-alert-desc": "交易量超過警報設定時播放聲音"
|
||||
"tooltip-enable-margin": "Enable spot margin for this trade",
|
||||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
}
|
|
@ -89,6 +89,7 @@
|
|||
"interest-earned-paid": "獲取利息",
|
||||
"leaderboard": "排行榜",
|
||||
"learn": "學",
|
||||
"learn-more": "Learn More",
|
||||
"leverage": "槓桿",
|
||||
"liability-weight": "債務權重",
|
||||
"liquidity": "流動性",
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
{
|
||||
"24h-volume": "24h Volume",
|
||||
"activate-volume-alert": "開啟交易量警報",
|
||||
"amount": "數量",
|
||||
"activate-volume-alert": "Activate Volume Alert",
|
||||
"amount": "Amount",
|
||||
"average-funding": "Average {{interval}} Funding",
|
||||
"base": "基礎",
|
||||
"book": "掛單薄",
|
||||
"buys": "買單",
|
||||
"cancel-order-error": "取消掛單出錯",
|
||||
"close-confirm": "市場平倉您的{{config_name}}持倉",
|
||||
"close-position": "平倉",
|
||||
"connect-orders": "連接以查看您的訂單",
|
||||
"connect-positions": "連接以查看您的持倉",
|
||||
"connect-trade-history": "連接以查看交易紀錄",
|
||||
"connect-unsettled": "連接以查看未結清餘額",
|
||||
"copy-and-share": "複製影像",
|
||||
"current-price": "目前價格",
|
||||
"base": "Base",
|
||||
"book": "Book",
|
||||
"buys": "Buys",
|
||||
"cancel-order-error": "Failed to cancel order",
|
||||
"close-confirm": "Market close your {{config_name}} position",
|
||||
"close-position": "Close Position",
|
||||
"connect-orders": "Connect to view your open orders",
|
||||
"connect-positions": "Connect to view your perp positions",
|
||||
"connect-trade-history": "Connect to view your trade history",
|
||||
"connect-unsettled": "Connect to view your unsettled funds",
|
||||
"copy-and-share": "Copy Image to Clipboard",
|
||||
"current-price": "Current Price",
|
||||
"edit-order": "Edit Order",
|
||||
"entry-price": "入場價",
|
||||
"est-slippage": "預計下滑",
|
||||
"funding-limits": "資金費限制",
|
||||
"funding-rate": "資金費率",
|
||||
"grouping": "分組",
|
||||
"hide-asks": "隱藏要價",
|
||||
"hide-bids": "隱藏出價",
|
||||
"in-orders": "在掛單中",
|
||||
"init-leverage": "初始槓桿",
|
||||
"instantaneous-funding": "瞬時資金費率",
|
||||
"insured": "被{{token}}保險",
|
||||
"interval-seconds": "間隔(秒)",
|
||||
"last-updated": "最近更新",
|
||||
"entry-price": "Entry Price",
|
||||
"est-slippage": "Est. Slippage",
|
||||
"funding-limits": "Funding Limits",
|
||||
"funding-rate": "1h Avg Funding Rate",
|
||||
"grouping": "Grouping",
|
||||
"hide-asks": "Hide Asks",
|
||||
"hide-bids": "Hide Bids",
|
||||
"in-orders": "In Orders",
|
||||
"init-leverage": "Init Leverage",
|
||||
"instantaneous-funding": "Instantaneous Funding Snapshot",
|
||||
"interval-seconds": "Interval (seconds)",
|
||||
"insured": "{{token}} Insured",
|
||||
"last-updated": "Last updated",
|
||||
"limit": "Limit",
|
||||
"limit-price": "限價價格",
|
||||
"long": "做多",
|
||||
|
@ -41,24 +41,24 @@
|
|||
"min-order-size": "最小訂單量",
|
||||
"min-order-size-error": "Min order size is {{minSize}} {{symbol}}",
|
||||
"more-details": "More Details",
|
||||
"no-balances": "您沒有餘額",
|
||||
"no-orders": "您沒有訂單",
|
||||
"no-positions": "您沒有持倉",
|
||||
"no-unsettled": "您沒有未結清餘額",
|
||||
"notional": "合約面值",
|
||||
"notional-volume": "面值交易量($)",
|
||||
"open-interest": "持倉量",
|
||||
"oracle": "預言機",
|
||||
"oracle-not-updated": "此預言機最近沒有更新。",
|
||||
"oracle-not-updated-warning": "含有此幣種的帳戶無法進行活動。",
|
||||
"oracle-price": "預言機價格",
|
||||
"order-error": "下訂單出錯了",
|
||||
"order-type": "訂單方式",
|
||||
"order-value": "訂單價值",
|
||||
"orders": "訂單",
|
||||
"place-order": "下{{side}}單",
|
||||
"placing-order": "正在下單",
|
||||
"positions": "當前持倉",
|
||||
"no-balances": "No balances",
|
||||
"no-orders": "No open orders",
|
||||
"no-positions": "No perp positions",
|
||||
"no-unsettled": "No unsettled funds",
|
||||
"notional": "Notional",
|
||||
"notional-volume": "Notional Volume ($)",
|
||||
"open-interest": "Open Interest",
|
||||
"oracle": "Oracle",
|
||||
"oracle-not-updated": "This oracle has not updated recently.",
|
||||
"oracle-not-updated-warning": "Actions will fail for accounts with a position in this token.",
|
||||
"oracle-price": "Oracle Price",
|
||||
"order-error": "Failed to place order",
|
||||
"order-type": "Order Type",
|
||||
"order-value": "Order Value",
|
||||
"orders": "Orders",
|
||||
"place-order": "Place {{side}} Order",
|
||||
"placing-order": "Placing Order",
|
||||
"positions": "Positions",
|
||||
"post": "Post",
|
||||
"preview-sound": "聲音預覽",
|
||||
"price-expect": "您收到的價格可能與您預期有差異,並且無法保證完全執行。為了您的安全,最大滑點保持為 2.5%。超過 2.5%滑點的部分不會被平倉。",
|
||||
|
@ -79,19 +79,22 @@
|
|||
"taker": "吃單者",
|
||||
"taker-fee": "吃單者 Fee",
|
||||
"tick-size": "波動單位",
|
||||
"realized-pnl": "Realized PnL",
|
||||
"tooltip-borrow-balance": "You'll use your {{balance}} {{token}} balance and borrow {{borrowAmount}} {{token}} to execute this trade. The current {{token}} variable borrow rate is {{rate}}%",
|
||||
"tooltip-borrow-no-balance": "You'll borrow {{borrowAmount}} {{token}} to execute this trade. The current {{token}} variable borrow rate is {{rate}}%",
|
||||
"tooltip-enable-margin": "為此交易啟用保證金",
|
||||
"tooltip-ioc": "IOC交易若不吃單就會被取消。任何無法立刻成交的部分將被取消",
|
||||
"tooltip-insured": "如果發生破產,{{tokenOrMarket}}損失是否可以從保險基金中歸還",
|
||||
"tooltip-post": "Post交易若不掛單就會被取消。",
|
||||
"tooltip-slippage": "當前價格與您的交易將執行的價格之間的差值的估計",
|
||||
"tooltip-stable-price": "穩定價格用於一個安全機制。此機制可以限制用戶在預言機價格快速波動時下風險高的訂單",
|
||||
"tooltip-volume-alert": "交易量警報設定",
|
||||
"trade-sounds-tooltip": "為每筆新交易播放警報聲音",
|
||||
"trades": "交易",
|
||||
"tweet-position": "分享至Twitter",
|
||||
"unsettled": "未結清",
|
||||
"volume-alert": "交易量警報",
|
||||
"volume-alert-desc": "交易量超過警報設定時播放聲音"
|
||||
"tooltip-enable-margin": "Enable spot margin for this trade",
|
||||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||
"total-pnl": "Total PnL",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"trades": "Trades",
|
||||
"tweet-position": "Share to Twitter",
|
||||
"unrealized-pnl": "Unrealized PnL",
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { AnchorProvider, BN } from '@project-serum/anchor'
|
||||
import { AnchorProvider, BN } from '@coral-xyz/anchor'
|
||||
import {
|
||||
getAllProposals,
|
||||
getGovernanceAccounts,
|
||||
|
|
|
@ -2,7 +2,7 @@ import dayjs from 'dayjs'
|
|||
import produce from 'immer'
|
||||
import create from 'zustand'
|
||||
import { subscribeWithSelector } from 'zustand/middleware'
|
||||
import { AnchorProvider, BN, Wallet, web3 } from '@project-serum/anchor'
|
||||
import { AnchorProvider, BN, Wallet, web3 } from '@coral-xyz/anchor'
|
||||
import { Connection, Keypair, PublicKey } from '@solana/web3.js'
|
||||
import { OpenOrders, Order } from '@project-serum/serum/lib/market'
|
||||
import { Orderbook } from '@project-serum/serum'
|
||||
|
@ -75,10 +75,10 @@ const ENDPOINTS = [
|
|||
name: 'mainnet-beta',
|
||||
url:
|
||||
process.env.NEXT_PUBLIC_ENDPOINT ||
|
||||
'https://mango.rpcpool.com/0f9acc0d45173b51bf7d7e09c1e5',
|
||||
'https://mango.rpcpool.com/946ef7337da3f5b8d3e4a34e7f88',
|
||||
websocket:
|
||||
process.env.NEXT_PUBLIC_ENDPOINT ||
|
||||
'https://mango.rpcpool.com/0f9acc0d45173b51bf7d7e09c1e5',
|
||||
'https://mango.rpcpool.com/946ef7337da3f5b8d3e4a34e7f88',
|
||||
custom: false,
|
||||
},
|
||||
{
|
||||
|
@ -481,7 +481,15 @@ const mangoStore = create<MangoStore>()(
|
|||
|
||||
const latestFeed = entries
|
||||
.map(([key, value]) => {
|
||||
return { ...value, symbol: key }
|
||||
// ETH should be renamed to ETH (Portal) in the database
|
||||
let symbol = value.activity_details.symbol
|
||||
if (symbol === 'ETH') {
|
||||
value.activity_details.symbol = 'ETH (Portal)'
|
||||
}
|
||||
return {
|
||||
...value,
|
||||
symbol: key,
|
||||
}
|
||||
})
|
||||
.sort(
|
||||
(a, b) =>
|
||||
|
|
|
@ -610,7 +610,7 @@ input[type='range']::-webkit-slider-runnable-track {
|
|||
}
|
||||
|
||||
.tooltip-underline {
|
||||
@apply default-transition w-max border-b border-dashed border-th-fgd-4 leading-tight hover:cursor-help hover:border-transparent;
|
||||
@apply default-transition w-max border-b border-dashed border-current leading-tight hover:cursor-help hover:border-transparent;
|
||||
}
|
||||
|
||||
.radial-gradient-bg {
|
||||
|
|
|
@ -43,7 +43,7 @@ export const FAVORITE_MARKETS_KEY = 'favoriteMarkets-0.2'
|
|||
|
||||
export const THEME_KEY = 'theme-0.1'
|
||||
|
||||
export const RPC_PROVIDER_KEY = 'rpcProviderKey-0.4'
|
||||
export const RPC_PROVIDER_KEY = 'rpcProviderKey-0.5'
|
||||
|
||||
export const PRIORITY_FEE_KEY = 'priorityFeeKey-0.1'
|
||||
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
import { AnchorProvider, Program } from '@project-serum/anchor'
|
||||
import { AnchorProvider, Program } from '@coral-xyz/anchor'
|
||||
import { PythHttpClient } from '@pythnetwork/client'
|
||||
import { notify } from 'utils/notifications'
|
||||
import { MAINNET_PYTH_PROGRAM } from './constants'
|
||||
import { OPENBOOK_PROGRAM_ID, toNative } from '@blockworks-foundation/mango-v4'
|
||||
import {
|
||||
Bank,
|
||||
Group,
|
||||
I80F48,
|
||||
OPENBOOK_PROGRAM_ID,
|
||||
toNative,
|
||||
toUiDecimals,
|
||||
toUiDecimalsForQuote,
|
||||
} from '@blockworks-foundation/mango-v4'
|
||||
import { Market } from '@project-serum/serum'
|
||||
import { Connection, Keypair, PublicKey } from '@solana/web3.js'
|
||||
import EmptyWallet from 'utils/wallet'
|
||||
|
@ -307,8 +315,13 @@ const listingBase = {
|
|||
insuranceFound: true,
|
||||
borrowWeightScale: toNative(250000, 6).toNumber(),
|
||||
depositWeightScale: toNative(250000, 6).toNumber(),
|
||||
preset_key: 'PREMIUM',
|
||||
preset_name: 'Blue chip',
|
||||
target_amount: 100000,
|
||||
}
|
||||
|
||||
export type ListingPreset = typeof listingBase
|
||||
|
||||
export type LISTING_PRESETS_KEYS =
|
||||
| 'PREMIUM'
|
||||
| 'MID'
|
||||
|
@ -317,14 +330,11 @@ export type LISTING_PRESETS_KEYS =
|
|||
| 'UNTRUSTED'
|
||||
|
||||
export const LISTING_PRESETS: {
|
||||
[key in LISTING_PRESETS_KEYS]:
|
||||
| (typeof listingBase & { name: string })
|
||||
| Record<string, never>
|
||||
[key in LISTING_PRESETS_KEYS]: ListingPreset | Record<string, never>
|
||||
} = {
|
||||
//Price impact $100,000 < 1%
|
||||
PREMIUM: {
|
||||
...listingBase,
|
||||
name: 'Premium',
|
||||
},
|
||||
//Price impact $20,000 < 1%
|
||||
MID: {
|
||||
|
@ -335,10 +345,12 @@ export const LISTING_PRESETS: {
|
|||
initLiabWeight: 1.4,
|
||||
liquidationFee: 0.1,
|
||||
netBorrowLimitPerWindowQuote: toNative(20000, 6).toNumber(),
|
||||
name: 'Mid',
|
||||
borrowWeightScale: toNative(50000, 6).toNumber(),
|
||||
depositWeightScale: toNative(50000, 6).toNumber(),
|
||||
insuranceFound: false,
|
||||
preset_key: 'MID',
|
||||
preset_name: 'Midwit',
|
||||
target_amount: 20000,
|
||||
},
|
||||
//Price impact $5,000 < 1%
|
||||
MEME: {
|
||||
|
@ -354,7 +366,9 @@ export const LISTING_PRESETS: {
|
|||
borrowWeightScale: toNative(20000, 6).toNumber(),
|
||||
depositWeightScale: toNative(20000, 6).toNumber(),
|
||||
insuranceFound: false,
|
||||
name: 'Meme',
|
||||
preset_key: 'MEME',
|
||||
preset_name: 'Meme Coin',
|
||||
target_amount: 5000,
|
||||
},
|
||||
//Price impact $1,000 < 1%
|
||||
SHIT: {
|
||||
|
@ -370,7 +384,9 @@ export const LISTING_PRESETS: {
|
|||
borrowWeightScale: toNative(5000, 6).toNumber(),
|
||||
depositWeightScale: toNative(5000, 6).toNumber(),
|
||||
insuranceFound: false,
|
||||
name: 'Shit',
|
||||
preset_key: 'SHIT',
|
||||
preset_name: 'Shit Coin',
|
||||
target_amount: 1000,
|
||||
},
|
||||
UNTRUSTED: {},
|
||||
}
|
||||
|
@ -384,3 +400,128 @@ export const coinTiersToNames: {
|
|||
SHIT: 'Shit Coin',
|
||||
UNTRUSTED: 'Untrusted',
|
||||
}
|
||||
|
||||
export const formatSuggestedValues = (
|
||||
suggestedParams:
|
||||
| Record<string, never>
|
||||
| Omit<
|
||||
typeof listingBase,
|
||||
'name' | 'netBorrowLimitWindowSizeTs' | 'insuranceFound'
|
||||
>
|
||||
) => {
|
||||
return {
|
||||
maxStalenessSlots: suggestedParams.maxStalenessSlots,
|
||||
oracleConfFilter: (100 * suggestedParams.oracleConfFilter).toFixed(2),
|
||||
adjustmentFactor: (suggestedParams.adjustmentFactor * 100).toFixed(2),
|
||||
rate0: (100 * suggestedParams.rate0).toFixed(2),
|
||||
util0: (100 * suggestedParams.util0).toFixed(),
|
||||
rate1: (100 * suggestedParams.rate1).toFixed(2),
|
||||
util1: (100 * suggestedParams.util1).toFixed(),
|
||||
maxRate: (100 * suggestedParams.maxRate).toFixed(2),
|
||||
loanFeeRate: (10000 * suggestedParams.loanFeeRate).toFixed(2),
|
||||
loanOriginationFeeRate: (
|
||||
10000 * suggestedParams.loanOriginationFeeRate
|
||||
).toFixed(2),
|
||||
maintAssetWeight: suggestedParams.maintAssetWeight.toFixed(2),
|
||||
initAssetWeight: suggestedParams.initAssetWeight.toFixed(2),
|
||||
maintLiabWeight: suggestedParams.maintLiabWeight.toFixed(2),
|
||||
initLiabWeight: suggestedParams.initLiabWeight.toFixed(2),
|
||||
liquidationFee: (suggestedParams.liquidationFee * 100).toFixed(2),
|
||||
minVaultToDepositsRatio: suggestedParams.minVaultToDepositsRatio * 100,
|
||||
netBorrowLimitPerWindowQuote: toUiDecimals(
|
||||
suggestedParams.netBorrowLimitPerWindowQuote,
|
||||
6
|
||||
),
|
||||
borrowWeightScale: toUiDecimals(suggestedParams.borrowWeightScale, 6),
|
||||
depositWeightScale: toUiDecimals(suggestedParams.depositWeightScale, 6),
|
||||
}
|
||||
}
|
||||
|
||||
export const getFormattedBankValues = (group: Group, bank: Bank) => {
|
||||
return {
|
||||
...bank,
|
||||
publicKey: bank.publicKey.toBase58(),
|
||||
vault: bank.vault.toBase58(),
|
||||
oracle: bank.oracle.toBase58(),
|
||||
stablePrice: group.toUiPrice(
|
||||
I80F48.fromNumber(bank.stablePriceModel.stablePrice),
|
||||
bank.mintDecimals
|
||||
),
|
||||
maxStalenessSlots: bank.oracleConfig.maxStalenessSlots.toNumber(),
|
||||
lastStablePriceUpdated: new Date(
|
||||
1000 * bank.stablePriceModel.lastUpdateTimestamp.toNumber()
|
||||
).toUTCString(),
|
||||
stablePriceGrowthLimitsDelay: (
|
||||
100 * bank.stablePriceModel.delayGrowthLimit
|
||||
).toFixed(2),
|
||||
stablePriceGrowthLimitsStable: (
|
||||
100 * bank.stablePriceModel.stableGrowthLimit
|
||||
).toFixed(2),
|
||||
loanFeeRate: (10000 * bank.loanFeeRate.toNumber()).toFixed(2),
|
||||
loanOriginationFeeRate: (
|
||||
10000 * bank.loanOriginationFeeRate.toNumber()
|
||||
).toFixed(2),
|
||||
collectedFeesNative: toUiDecimals(
|
||||
bank.collectedFeesNative.toNumber(),
|
||||
bank.mintDecimals
|
||||
).toFixed(2),
|
||||
collectedFeesNativePrice: (
|
||||
toUiDecimals(bank.collectedFeesNative.toNumber(), bank.mintDecimals) *
|
||||
bank.uiPrice
|
||||
).toFixed(2),
|
||||
dust: bank.dust.toNumber(),
|
||||
deposits: toUiDecimals(
|
||||
bank.indexedDeposits.mul(bank.depositIndex).toNumber(),
|
||||
bank.mintDecimals
|
||||
),
|
||||
depositsPrice: (
|
||||
toUiDecimals(
|
||||
bank.indexedDeposits.mul(bank.depositIndex).toNumber(),
|
||||
bank.mintDecimals
|
||||
) * bank.uiPrice
|
||||
).toFixed(2),
|
||||
borrows: toUiDecimals(
|
||||
bank.indexedBorrows.mul(bank.borrowIndex).toNumber(),
|
||||
bank.mintDecimals
|
||||
),
|
||||
borrowsPrice: (
|
||||
toUiDecimals(
|
||||
bank.indexedBorrows.mul(bank.borrowIndex).toNumber(),
|
||||
bank.mintDecimals
|
||||
) * bank.uiPrice
|
||||
).toFixed(2),
|
||||
avgUtilization: bank.avgUtilization.toNumber() * 100,
|
||||
maintAssetWeight: bank.maintAssetWeight.toFixed(2),
|
||||
maintLiabWeight: bank.maintLiabWeight.toFixed(2),
|
||||
initAssetWeight: bank.initAssetWeight.toFixed(2),
|
||||
initLiabWeight: bank.initLiabWeight.toFixed(2),
|
||||
depositWeightScale: toUiDecimalsForQuote(bank.depositWeightScaleStartQuote),
|
||||
borrowWeightScale: toUiDecimalsForQuote(bank.borrowWeightScaleStartQuote),
|
||||
rate0: (100 * bank.rate0.toNumber()).toFixed(2),
|
||||
util0: (100 * bank.util0.toNumber()).toFixed(),
|
||||
rate1: (100 * bank.rate1.toNumber()).toFixed(2),
|
||||
util1: (100 * bank.util1.toNumber()).toFixed(),
|
||||
maxRate: (100 * bank.maxRate.toNumber()).toFixed(2),
|
||||
adjustmentFactor: (bank.adjustmentFactor.toNumber() * 100).toFixed(2),
|
||||
depositRate: bank.getDepositRateUi(),
|
||||
borrowRate: bank.getBorrowRateUi(),
|
||||
lastIndexUpdate: new Date(
|
||||
1000 * bank.indexLastUpdated.toNumber()
|
||||
).toUTCString(),
|
||||
lastRatesUpdate: new Date(
|
||||
1000 * bank.bankRateLastUpdated.toNumber()
|
||||
).toUTCString(),
|
||||
oracleConfFilter: (100 * bank.oracleConfig.confFilter.toNumber()).toFixed(
|
||||
2
|
||||
),
|
||||
minVaultToDepositsRatio: bank.minVaultToDepositsRatio * 100,
|
||||
netBorrowsInWindow: toUiDecimalsForQuote(
|
||||
I80F48.fromI64(bank.netBorrowsInWindow).mul(bank.price)
|
||||
).toFixed(2),
|
||||
netBorrowLimitPerWindowQuote: toUiDecimals(
|
||||
bank.netBorrowLimitPerWindowQuote,
|
||||
6
|
||||
),
|
||||
liquidationFee: (bank.liquidationFee.toNumber() * 100).toFixed(2),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
import {
|
||||
Governance,
|
||||
MintMaxVoteWeightSource,
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
import { Connection, PublicKey } from '@solana/web3.js'
|
||||
import { TokenProgramAccount } from './accounts/vsrAccounts'
|
||||
import { MintLayout, RawMint } from '@solana/spl-token'
|
||||
import { BN } from '@project-serum/anchor'
|
||||
import { BN } from '@coral-xyz/anchor'
|
||||
|
||||
export async function fetchRealm({
|
||||
connection,
|
||||
|
@ -139,3 +139,21 @@ export async function resolveProposalDescription(descriptionLink: string) {
|
|||
return descriptionLink
|
||||
}
|
||||
}
|
||||
|
||||
export const compareObjectsAndGetDifferentKeys = <T extends object>(
|
||||
object1: T,
|
||||
object2: T
|
||||
): (keyof T)[] => {
|
||||
const diffKeys: string[] = []
|
||||
|
||||
Object.keys(object1).forEach((key) => {
|
||||
if (
|
||||
object1[key as keyof typeof object1] !==
|
||||
object2[key as keyof typeof object2]
|
||||
) {
|
||||
diffKeys.push(key)
|
||||
}
|
||||
})
|
||||
|
||||
return diffKeys as (keyof T)[]
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Program, Provider, web3 } from '@coral-xyz/anchor'
|
||||
import { Idl } from '@project-serum/anchor'
|
||||
import { Idl } from '@coral-xyz/anchor'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
|
||||
export const DEFAULT_VSR_ID = new web3.PublicKey(
|
||||
|
|
|
@ -1,17 +1,34 @@
|
|||
import { Wallet } from '@project-serum/anchor'
|
||||
import { Keypair, PublicKey, Transaction } from '@solana/web3.js'
|
||||
import { Wallet } from '@coral-xyz/anchor'
|
||||
import { isVersionedTransaction } from '@solana/wallet-adapter-base'
|
||||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
Transaction,
|
||||
VersionedTransaction,
|
||||
} from '@solana/web3.js'
|
||||
|
||||
export default class EmptyWallet implements Wallet {
|
||||
constructor(readonly payer: Keypair) {}
|
||||
|
||||
async signTransaction(tx: Transaction): Promise<Transaction> {
|
||||
tx.partialSign(this.payer)
|
||||
async signTransaction<T extends Transaction | VersionedTransaction>(
|
||||
tx: T
|
||||
): Promise<T> {
|
||||
if (isVersionedTransaction(tx)) {
|
||||
tx.sign([this.payer])
|
||||
} else {
|
||||
tx.partialSign(this.payer)
|
||||
}
|
||||
return tx
|
||||
}
|
||||
|
||||
async signAllTransactions(txs: Transaction[]): Promise<Transaction[]> {
|
||||
async signAllTransactions<T extends Transaction | VersionedTransaction>(
|
||||
txs: T[]
|
||||
): Promise<T[]> {
|
||||
return txs.map((t) => {
|
||||
t.partialSign(this.payer)
|
||||
if (isVersionedTransaction(t)) {
|
||||
t.sign([this.payer])
|
||||
} else {
|
||||
t.partialSign(this.payer)
|
||||
}
|
||||
return t
|
||||
})
|
||||
}
|
||||
|
|
41
yarn.lock
41
yarn.lock
|
@ -21,12 +21,12 @@
|
|||
dependencies:
|
||||
ws "^8.13.0"
|
||||
|
||||
"@blockworks-foundation/mango-v4@^0.15.13":
|
||||
version "0.15.13"
|
||||
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.15.13.tgz#adbfb63a69fc94ddaed9a7d65733e881335d092d"
|
||||
integrity sha512-akqs0LYK7sjD5mqxwGWBaN7AaPIgDhdUswRWjFRCRXJy1B9la2pmJv9iWjXFU9DDWPORrpu5psFZ0NZ8hYKpnA==
|
||||
"@blockworks-foundation/mango-v4@^0.16.6":
|
||||
version "0.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.16.6.tgz#abd65dd70f4c81f6f9b08f6d735ea73b53d2a378"
|
||||
integrity sha512-QKsKiJSbqM0CXcNsrIYaW0TWOTGXktMm4ZQnF+XnO1WyMylq7M5pnA/UPhuGuk2X0KUI9iedVYhoHBO73wdFOA==
|
||||
dependencies:
|
||||
"@coral-xyz/anchor" "^0.26.0"
|
||||
"@coral-xyz/anchor" "^0.27.0"
|
||||
"@project-serum/serum" "0.13.65"
|
||||
"@pythnetwork/client" "~2.14.0"
|
||||
"@solana/spl-token" "0.3.7"
|
||||
|
@ -84,28 +84,7 @@
|
|||
eventemitter3 "^4.0.7"
|
||||
uuid "^8.3.2"
|
||||
|
||||
"@coral-xyz/anchor@^0.26.0":
|
||||
version "0.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.26.0.tgz#c8e4f7177e93441afd030f22d777d54d0194d7d1"
|
||||
integrity sha512-PxRl+wu5YyptWiR9F2MBHOLLibm87Z4IMUBPreX+DYBtPM+xggvcPi0KAN7+kIL4IrIhXI8ma5V0MCXxSN1pHg==
|
||||
dependencies:
|
||||
"@coral-xyz/borsh" "^0.26.0"
|
||||
"@solana/web3.js" "^1.68.0"
|
||||
base64-js "^1.5.1"
|
||||
bn.js "^5.1.2"
|
||||
bs58 "^4.0.1"
|
||||
buffer-layout "^1.2.2"
|
||||
camelcase "^6.3.0"
|
||||
cross-fetch "^3.1.5"
|
||||
crypto-hash "^1.3.0"
|
||||
eventemitter3 "^4.0.7"
|
||||
js-sha256 "^0.9.0"
|
||||
pako "^2.0.3"
|
||||
snake-case "^3.0.4"
|
||||
superstruct "^0.15.4"
|
||||
toml "^3.0.0"
|
||||
|
||||
"@coral-xyz/anchor@^0.27.0":
|
||||
"@coral-xyz/anchor@^0.26.0", "@coral-xyz/anchor@^0.27.0":
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.27.0.tgz#621e5ef123d05811b97e49973b4ed7ede27c705c"
|
||||
integrity sha512-+P/vPdORawvg3A9Wj02iquxb4T0C5m4P6aZBVYysKl4Amk+r6aMPZkUhilBkD6E4Nuxnoajv3CFykUfkGE0n5g==
|
||||
|
@ -126,14 +105,6 @@
|
|||
superstruct "^0.15.4"
|
||||
toml "^3.0.0"
|
||||
|
||||
"@coral-xyz/borsh@^0.26.0":
|
||||
version "0.26.0"
|
||||
resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.26.0.tgz#d054f64536d824634969e74138f9f7c52bbbc0d5"
|
||||
integrity sha512-uCZ0xus0CszQPHYfWAqKS5swS1UxvePu83oOF+TWpUkedsNlg6p2p4azxZNSSqwXb9uXMFgxhuMBX9r3Xoi0vQ==
|
||||
dependencies:
|
||||
bn.js "^5.1.2"
|
||||
buffer-layout "^1.2.0"
|
||||
|
||||
"@coral-xyz/borsh@^0.27.0":
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.27.0.tgz#700c647ea5262b1488957ac7fb4e8acf72c72b63"
|
||||
|
|
Loading…
Reference in New Issue