add oracle provider to market details modals
This commit is contained in:
parent
9d37cf2007
commit
cf0a5e7e59
|
@ -3,6 +3,8 @@ import Modal from '../shared/Modal'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { PerpMarket } from '@blockworks-foundation/mango-v4'
|
||||
import Button from '@components/shared/Button'
|
||||
import useOracleProvider from 'hooks/useOracleProvider'
|
||||
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid'
|
||||
// import Tooltip from '@components/shared/Tooltip'
|
||||
|
||||
interface PerpMarketDetailsModalProps {
|
||||
|
@ -17,6 +19,9 @@ const PerpMarketDetailsModal = ({
|
|||
market,
|
||||
}: ModalCombinedProps) => {
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
const { oracleProvider, oracleLinkPath } = useOracleProvider()
|
||||
|
||||
console.log(oracleProvider, oracleLinkPath)
|
||||
|
||||
return market ? (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
|
@ -62,6 +67,22 @@ const PerpMarketDetailsModal = ({
|
|||
{(100 * market.maxFunding.toNumber()).toFixed(2)}%
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<p>{t('trade:oracle')}</p>
|
||||
{oracleLinkPath ? (
|
||||
<a
|
||||
className="flex items-center"
|
||||
href={oracleLinkPath}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span className="mr-1.5">{oracleProvider}</span>
|
||||
<ArrowTopRightOnSquareIcon className="h-4 w-4" />
|
||||
</a>
|
||||
) : (
|
||||
<p className="text-th-fgd-2">{oracleProvider}</p>
|
||||
)}
|
||||
</div>
|
||||
{/* Uncomment when insurance fund is ready */}
|
||||
{/* <div className="flex justify-between">
|
||||
<Tooltip
|
||||
|
|
|
@ -4,6 +4,8 @@ import { useTranslation } from 'next-i18next'
|
|||
import useSelectedMarket from 'hooks/useSelectedMarket'
|
||||
import { Serum3Market } from '@blockworks-foundation/mango-v4'
|
||||
import Button from '@components/shared/Button'
|
||||
import useOracleProvider from 'hooks/useOracleProvider'
|
||||
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid'
|
||||
// import useMangoGroup from 'hooks/useMangoGroup'
|
||||
// import { useMemo } from 'react'
|
||||
// import Tooltip from '@components/shared/Tooltip'
|
||||
|
@ -23,6 +25,7 @@ const SpotMarketDetailsModal = ({
|
|||
}: ModalCombinedProps) => {
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
const { serumOrPerpMarket } = useSelectedMarket()
|
||||
const { oracleProvider, oracleLinkPath } = useOracleProvider()
|
||||
// const { group } = useMangoGroup()
|
||||
|
||||
// const [baseBank, quoteBank] = useMemo(() => {
|
||||
|
@ -61,6 +64,22 @@ const SpotMarketDetailsModal = ({
|
|||
<p>{t('trade:max-leverage')}</p>
|
||||
<p className="font-mono text-th-fgd-2">5x</p>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<p>{t('trade:oracle')}</p>
|
||||
{oracleLinkPath ? (
|
||||
<a
|
||||
className="flex items-center"
|
||||
href={oracleLinkPath}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span className="mr-1.5">{oracleProvider}</span>
|
||||
<ArrowTopRightOnSquareIcon className="h-4 w-4" />
|
||||
</a>
|
||||
) : (
|
||||
<p className="text-th-fgd-2">{oracleProvider}</p>
|
||||
)}
|
||||
</div>
|
||||
{/* {baseMintInfo ? (
|
||||
<div className="flex justify-between">
|
||||
<Tooltip
|
||||
|
|
|
@ -7,11 +7,7 @@ import Tooltip from '@components/shared/Tooltip'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import { useEffect, useState } from 'react'
|
||||
import {
|
||||
PerpMarket,
|
||||
Bank,
|
||||
OracleProvider,
|
||||
} from '@blockworks-foundation/mango-v4'
|
||||
import { PerpMarket, Bank } from '@blockworks-foundation/mango-v4'
|
||||
import { BorshAccountsCoder } from '@coral-xyz/anchor'
|
||||
import {
|
||||
floorToDecimal,
|
||||
|
@ -21,6 +17,8 @@ import {
|
|||
import dayjs from 'dayjs'
|
||||
import duration from 'dayjs/plugin/duration'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import useOracleProvider from 'hooks/useOracleProvider'
|
||||
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid'
|
||||
|
||||
const OraclePrice = ({
|
||||
setChangePrice,
|
||||
|
@ -38,10 +36,10 @@ const OraclePrice = ({
|
|||
|
||||
const connection = mangoStore((s) => s.connection)
|
||||
const [price, setPrice] = useState(stalePrice)
|
||||
const [oracleProviderName, setOracleProviderName] = useState('Unknown')
|
||||
const [oracleLastUpdatedSlot, setOracleLastUpdatedSlot] = useState(0)
|
||||
const [highestSlot, setHighestSlot] = useState(0)
|
||||
const [isStale, setIsStale] = useState(false)
|
||||
const { oracleProvider, oracleLinkPath } = useOracleProvider()
|
||||
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
|
||||
|
@ -64,20 +62,6 @@ const OraclePrice = ({
|
|||
decimals = group.getMintDecimals(baseBank.mint)
|
||||
}
|
||||
|
||||
switch (marketOrBank.oracleProvider) {
|
||||
case OracleProvider.Pyth:
|
||||
setOracleProviderName('Pyth')
|
||||
break
|
||||
case OracleProvider.Switchboard:
|
||||
setOracleProviderName('Switchboard')
|
||||
break
|
||||
case OracleProvider.Stub:
|
||||
setOracleProviderName('Stub')
|
||||
break
|
||||
default:
|
||||
setOracleProviderName('Unknown')
|
||||
}
|
||||
|
||||
const coder = new BorshAccountsCoder(client.program.idl)
|
||||
const subId = connection.onAccountChange(
|
||||
marketOrBank.oracle,
|
||||
|
@ -147,8 +131,21 @@ const OraclePrice = ({
|
|||
placement="bottom"
|
||||
content={
|
||||
<>
|
||||
<div>
|
||||
{t('trade:price-provided-by')} {oracleProviderName}.
|
||||
<div className="flex">
|
||||
<span className="mr-1">{t('trade:price-provided-by')}</span>
|
||||
{oracleLinkPath ? (
|
||||
<a
|
||||
href={oracleLinkPath}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center"
|
||||
>
|
||||
<span className="mr-1">{oracleProvider}</span>
|
||||
<ArrowTopRightOnSquareIcon className="h-4 w-4" />
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-th-fgd-2">{oracleProvider}</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
{t('trade:last-updated')}{' '}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import {
|
||||
Bank,
|
||||
OracleProvider,
|
||||
PerpMarket,
|
||||
} from '@blockworks-foundation/mango-v4'
|
||||
import { useMemo } from 'react'
|
||||
import { formatTokenSymbol } from 'utils/tokens'
|
||||
import useMangoGroup from './useMangoGroup'
|
||||
import useSelectedMarket from './useSelectedMarket'
|
||||
|
||||
const useOracleProvider = () => {
|
||||
const { selectedMarket } = useSelectedMarket()
|
||||
const { group } = useMangoGroup()
|
||||
|
||||
const [oracleProvider, oracleLinkPath] = useMemo(() => {
|
||||
if (!group || !selectedMarket) return ['', '']
|
||||
let marketOrBank: PerpMarket | Bank
|
||||
let name: string
|
||||
if (selectedMarket instanceof PerpMarket) {
|
||||
marketOrBank = selectedMarket
|
||||
name = selectedMarket.name.split('-')[0]
|
||||
} else {
|
||||
const baseBank = group.getFirstBankByTokenIndex(
|
||||
selectedMarket.baseTokenIndex
|
||||
)
|
||||
marketOrBank = baseBank
|
||||
name = formatTokenSymbol(baseBank.name)
|
||||
}
|
||||
|
||||
switch (marketOrBank.oracleProvider) {
|
||||
case OracleProvider.Pyth:
|
||||
return [
|
||||
'Pyth',
|
||||
`https://pyth.network/price-feeds/crypto-${name.toLowerCase()}-usd`,
|
||||
]
|
||||
case OracleProvider.Switchboard:
|
||||
return [
|
||||
'Switchboard',
|
||||
`https://switchboard.xyz/explorer/3/${marketOrBank.oracle.toString()}`,
|
||||
]
|
||||
case OracleProvider.Stub:
|
||||
return ['Stub', '']
|
||||
default:
|
||||
return ['Unknown', '']
|
||||
}
|
||||
}, [group, selectedMarket])
|
||||
|
||||
return { oracleProvider, oracleLinkPath }
|
||||
}
|
||||
|
||||
export default useOracleProvider
|
|
@ -41,6 +41,7 @@
|
|||
"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",
|
||||
|
@ -54,7 +55,7 @@
|
|||
"post": "Post",
|
||||
"preview-sound": "Preview Sound",
|
||||
"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": "This price is provided by",
|
||||
"price-provided-by": "Oracle by",
|
||||
"quote": "Quote",
|
||||
"reduce-only": "Reduce Only",
|
||||
"sells": "Sells",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"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",
|
||||
|
@ -54,7 +55,7 @@
|
|||
"post": "Post",
|
||||
"preview-sound": "Preview Sound",
|
||||
"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": "This price is provided by",
|
||||
"price-provided-by": "Oracle by",
|
||||
"quote": "Quote",
|
||||
"reduce-only": "Reduce Only",
|
||||
"sells": "Sells",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"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",
|
||||
|
@ -54,7 +55,7 @@
|
|||
"post": "Post",
|
||||
"preview-sound": "Preview Sound",
|
||||
"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": "This price is provided by",
|
||||
"price-provided-by": "Oracle by",
|
||||
"quote": "Quote",
|
||||
"reduce-only": "Reduce Only",
|
||||
"sells": "Sells",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"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",
|
||||
|
@ -54,7 +55,7 @@
|
|||
"post": "Post",
|
||||
"preview-sound": "Preview Sound",
|
||||
"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": "This price is provided by",
|
||||
"price-provided-by": "Oracle by",
|
||||
"quote": "Quote",
|
||||
"reduce-only": "Reduce Only",
|
||||
"sells": "Sells",
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"notional": "合約面值",
|
||||
"notional-volume": "面值交易量($)",
|
||||
"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": "預言機價格",
|
||||
|
@ -54,7 +55,7 @@
|
|||
"post": "Post",
|
||||
"preview-sound": "聲音預覽",
|
||||
"price-expect": "您收到的價格可能與您預期有差異,並且無法保證完全執行。為了您的安全,最大滑點保持為 2.5%。超過 2.5%滑點的部分不會被平倉。",
|
||||
"price-provided-by": "This price is provided by",
|
||||
"price-provided-by": "Oracle by",
|
||||
"quote": "計價",
|
||||
"reduce-only": "限減少",
|
||||
"sells": "賣單",
|
||||
|
|
|
@ -142,8 +142,8 @@ export async function getNFTsByOwner(owner: PublicKey, connection: Connection) {
|
|||
|
||||
export const formatTokenSymbol = (symbol: string) => {
|
||||
if (symbol.toLowerCase().includes('portal')) {
|
||||
const truncSymbol = symbol.split(' ')[0]
|
||||
return truncSymbol === 'WBTC' ? 'wBTC' : truncSymbol
|
||||
const truncSymbol = symbol.split(' ')[0].toUpperCase()
|
||||
return truncSymbol === 'WBTC' ? 'BTC' : truncSymbol
|
||||
}
|
||||
return symbol === 'MSOL' ? 'mSOL' : symbol
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue