create switchboard oracle from ui (#162)

* wip create oracle

* wip

* wip

* wi[

* switchboard oracle wip

* switchboard oracle

* switchboard authority

* deduplicate

* fix cfg
This commit is contained in:
Adrian Brzeziński 2023-06-05 17:29:04 +02:00 committed by GitHub
parent d8b66e390e
commit 79b6fd6cc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 667 additions and 139 deletions

View File

@ -364,8 +364,10 @@ const ListMarket = ({ goBack }: { goBack: () => void }) => {
</div>
{createOpenbookMarketModal ? (
<CreateOpenbookMarketModal
quoteSymbol={quoteToken!}
baseSymbol={baseToken!}
quoteDecimals={quoteBank?.mintDecimals || 0}
quoteMint={quoteBank?.mint.toBase58() || ''}
baseDecimals={baseBank?.mintDecimals || 0}
baseMint={baseBank?.mint.toBase58() || ''}
isOpen={createOpenbookMarketModal}
onClose={closeCreateOpenBookMarketModal}
tradingParams={tradingParams}

View File

@ -1,18 +1,14 @@
import Input from '@components/forms/Input'
import Label from '@components/forms/Label'
import Button, { IconButton } from '@components/shared/Button'
import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react'
import { ChangeEvent, useCallback, useMemo, useState } from 'react'
import mangoStore, { CLUSTER } from '@store/mangoStore'
import { Token } from 'types/jupiter'
import { handleGetRoutes } from '@components/swap/useQuoteRoutes'
import {
JUPITER_API_DEVNET,
JUPITER_API_MAINNET,
USDC_MINT,
} from 'utils/constants'
import { JUPITER_PRICE_API_MAINNET, USDC_MINT } from 'utils/constants'
import { PublicKey, SYSVAR_RENT_PUBKEY } from '@solana/web3.js'
import { useWallet } from '@solana/wallet-adapter-react'
import { OPENBOOK_PROGRAM_ID } from '@blockworks-foundation/mango-v4'
import { OPENBOOK_PROGRAM_ID, RouteInfo } from '@blockworks-foundation/mango-v4'
import {
MANGO_DAO_WALLET,
MANGO_DAO_WALLET_GOVERNANCE,
@ -23,7 +19,6 @@ import {
ChevronDownIcon,
ExclamationCircleIcon,
} from '@heroicons/react/20/solid'
import BN from 'bn.js'
import { createProposal } from 'utils/governance/instructions/createProposal'
import GovernanceStore from '@store/governanceStore'
import { notify } from 'utils/notifications'
@ -40,6 +35,11 @@ import useMangoGroup from 'hooks/useMangoGroup'
import { getBestMarket, getOracle } from 'utils/governance/listingTools'
import { fmtTokenAmount, tryGetPubKey } from 'utils/governance/tools'
import OnBoarding from '../OnBoarding'
import CreateOpenbookMarketModal from '@components/modals/CreateOpenbookMarketModal'
import { calculateTradingParameters } from 'utils/governance/listingTools'
import useJupiterMints from 'hooks/useJupiterMints'
import CreateSwitchboardOracleModal from '@components/modals/CreateSwitchboardOracleModal'
import { BN } from '@project-serum/anchor'
type FormErrors = Partial<Record<keyof TokenListForm, string>>
@ -75,6 +75,7 @@ const defaultTokenListFormValues: TokenListForm = {
const ListToken = ({ goBack }: { goBack: () => void }) => {
const wallet = useWallet()
const { jupiterTokens } = useJupiterMints()
const connection = mangoStore((s) => s.connection)
const client = mangoStore((s) => s.client)
const { group } = useMangoGroup()
@ -93,15 +94,21 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
...defaultTokenListFormValues,
})
const [loadingListingParams, setLoadingListingParams] = useState(false)
const [tokenList, setTokenList] = useState<Token[]>([])
const [formErrors, setFormErrors] = useState<FormErrors>({})
const [priceImpact, setPriceImpact] = useState<number>(0)
const [currentTokenInfo, setCurrentTokenInfo] = useState<
Token | null | undefined
>(null)
const [baseTokenPrice, setBaseTokenPrice] = useState<number>(0)
const [proposalPk, setProposalPk] = useState<string | null>(null)
const [mint, setMint] = useState('')
const [creatingProposal, setCreatingProposal] = useState(false)
const [createOpenbookMarketModal, setCreateOpenbookMarket] = useState(false)
const [orcaPoolAddress, setOrcaPoolAddress] = useState('')
const [raydiumPoolAddress, setRaydiumPoolAddress] = useState('')
const [oracleModalOpen, setOracleModalOpen] = useState(false)
const quoteBank = group?.getFirstBankByMint(new PublicKey(USDC_MINT))
const minVoterWeight = useMemo(
() =>
governances
@ -109,55 +116,36 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
.minCommunityTokensToCreateProposal
: new BN(0),
[governances]
)
) as BN
const mintVoterWeightNumber = governances
? fmtTokenAmount(minVoterWeight, MANGO_MINT_DECIMALS)
: 0
const tradingParams = useMemo(() => {
if (quoteBank && currentTokenInfo) {
return calculateTradingParameters(
baseTokenPrice,
quoteBank.uiPrice,
currentTokenInfo.decimals,
quoteBank.mintDecimals
)
}
return {
baseLots: 0,
quoteLots: 0,
minOrderValue: 0,
baseLotExponent: 0,
quoteLotExponent: 0,
minOrderSize: 0,
priceIncrement: 0,
priceIncrementRelative: 0,
}
}, [quoteBank, currentTokenInfo, baseTokenPrice])
const handleSetAdvForm = (propertyName: string, value: string | number) => {
setFormErrors({})
setAdvForm({ ...advForm, [propertyName]: value })
}
const handleTokenFind = async () => {
cancel()
if (!tryGetPubKey(mint)) {
notify({
title: t('enter-valid-token-mint'),
type: 'error',
})
return
}
let currentTokenList: Token[] = tokenList
if (!tokenList.length) {
currentTokenList = await getTokenList()
setTokenList(currentTokenList)
}
const tokenInfo = currentTokenList.find((x) => x.address === mint)
setCurrentTokenInfo(tokenInfo)
if (tokenInfo) {
handleLiqudityCheck(new PublicKey(mint))
getListingParams(tokenInfo)
}
}
const getTokenList = useCallback(async () => {
try {
const url =
CLUSTER === 'devnet' ? JUPITER_API_DEVNET : JUPITER_API_MAINNET
const response = await fetch(url)
const data: Token[] = await response.json()
return data
} catch (e) {
notify({
title: t('cant-find-token-for-mint'),
description: `${e}`,
type: 'error',
})
return []
}
}, [t])
const getListingParams = useCallback(
async (tokenInfo: Token) => {
setLoadingListingParams(true)
@ -216,7 +204,7 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
const SLIPPAGE_BPS = 50
const MODE = 'ExactIn'
const FEE = 0
const { bestRoute } = await handleGetRoutes(
const { bestRoute, routes } = await handleGetRoutes(
USDC_MINT,
tokenMint.toBase58(),
USDC_AMOUNT,
@ -226,6 +214,7 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
wallet.publicKey ? wallet.publicKey?.toBase58() : emptyPk
)
setPriceImpact(bestRoute ? bestRoute.priceImpactPct * 100 : 100)
handleGetPoolParams(routes)
} catch (e) {
notify({
title: t('liquidity-check-error'),
@ -237,6 +226,35 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
[t, wallet.publicKey]
)
const handleGetPoolParams = (routes: never[] | RouteInfo[]) => {
const marketInfos = routes.flatMap((x) => x.marketInfos)
const orcaPool = marketInfos.find((x) => x.label === 'Orca')
const raydiumPool = marketInfos.find((x) => x.label === 'Raydium')
setOrcaPoolAddress(orcaPool?.id || '')
setRaydiumPoolAddress(raydiumPool?.id || '')
}
const handleTokenFind = useCallback(async () => {
cancel()
if (!tryGetPubKey(mint)) {
notify({
title: t('enter-valid-token-mint'),
type: 'error',
})
return
}
const tokenInfo = jupiterTokens.find((x) => x.address === mint)
const priceInfo = await (
await fetch(`${JUPITER_PRICE_API_MAINNET}/price?ids=${mint}`)
).json()
setBaseTokenPrice(priceInfo.data[mint]?.price || 0)
setCurrentTokenInfo(tokenInfo)
if (tokenInfo) {
handleLiqudityCheck(new PublicKey(mint))
getListingParams(tokenInfo)
}
}, [getListingParams, handleLiqudityCheck, jupiterTokens, mint, t])
const cancel = () => {
setCurrentTokenInfo(null)
setPriceImpact(0)
@ -372,9 +390,18 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
wallet,
])
useEffect(() => {
setTokenList([])
}, [])
const closeCreateOpenBookMarketModal = () => {
setCreateOpenbookMarket(false)
if (currentTokenInfo) {
getListingParams(currentTokenInfo)
}
}
const closeCreateOracleModal = () => {
setOracleModalOpen(false)
if (currentTokenInfo) {
getListingParams(currentTokenInfo)
}
}
return (
<div>
@ -681,33 +708,70 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
)}
</Disclosure>
</div>
{!advForm.oraclePk && !loadingListingParams ? (
<div className="my-4">
<InlineNotification
desc={t('cant-list-oracle-not-found')}
type="error"
/>
</div>
) : null}
{!advForm.openBookMarketExternalPk && !loadingListingParams ? (
<div className="mb-4">
<InlineNotification
desc={
<div>
<a
href="https://raydium.io/create-market"
rel="noopener noreferrer"
target="_blank"
className="underline"
>
{t('cant-list-no-openbook-market')}
</a>
</div>
}
type="error"
/>
</div>
) : null}
<ol className="list-decimal pl-4">
{!advForm.openBookMarketExternalPk && !loadingListingParams ? (
<li className="pl-2">
<div className="mb-4">
<InlineNotification
desc={
<div>
<a
onClick={() => setCreateOpenbookMarket(true)}
className="cursor-pointer underline"
>
{t('cant-list-no-openbook-market')}
</a>
</div>
}
type="error"
/>
</div>
{createOpenbookMarketModal ? (
<CreateOpenbookMarketModal
quoteMint={quoteBank?.mint.toBase58() || ''}
baseMint={currentTokenInfo?.address || ''}
baseDecimals={currentTokenInfo.decimals}
quoteDecimals={quoteBank?.mintDecimals || 0}
isOpen={createOpenbookMarketModal}
onClose={closeCreateOpenBookMarketModal}
tradingParams={tradingParams}
/>
) : null}
</li>
) : null}
{!advForm.oraclePk && !loadingListingParams ? (
<li
className={`my-4 pl-2 ${
!advForm.openBookMarketExternalPk
? 'disabled pointer-events-none opacity-60'
: ''
}`}
>
<InlineNotification
desc={
<div>
<a
onClick={() => setOracleModalOpen(true)}
className="cursor-pointer underline"
>
{t('cant-list-oracle-not-found')}
</a>
</div>
}
type="error"
/>
<CreateSwitchboardOracleModal
orcaPoolAddress={orcaPoolAddress}
raydiumPoolAddress={raydiumPoolAddress}
baseTokenName={currentTokenInfo.symbol}
baseTokenPk={currentTokenInfo.address}
openbookMarketPk={advForm.openBookMarketExternalPk}
isOpen={oracleModalOpen}
onClose={closeCreateOracleModal}
></CreateSwitchboardOracleModal>
</li>
) : null}
</ol>
<div className="mt-6 flex flex-col space-y-3 sm:flex-row sm:space-y-0 sm:space-x-4">
<Button secondary onClick={cancel} size="large">
{t('cancel')}

View File

@ -20,8 +20,11 @@ const OnBoarding = ({ minVotes }: { minVotes?: BN }) => {
const minVoterWeight = minVotes
? minVotes
: governances
? governances[MANGO_DAO_WALLET_GOVERNANCE.toBase58()].account.config
.minCommunityTokensToCreateProposal
? new BN(
governances[
MANGO_DAO_WALLET_GOVERNANCE.toBase58()
].account.config.minCommunityTokensToCreateProposal.toString()
)
: new BN(0)
const mintVoterWeightNumber = governances
? fmtTokenAmount(minVoterWeight, MANGO_MINT_DECIMALS)

View File

@ -44,9 +44,9 @@ export function VoteCountdown({
const now = dayjs().unix()
let timeToVoteEnd = proposal.isPreVotingState()
? governance.config.maxVotingTime
? governance.config.baseVotingTime
: (proposal.votingAt?.toNumber() ?? 0) +
governance.config.maxVotingTime -
governance.config.baseVotingTime -
now
if (timeToVoteEnd <= 0) {

View File

@ -1,5 +1,6 @@
import Tooltip from '@components/shared/Tooltip'
import { CheckCircleIcon } from '@heroicons/react/20/solid'
import { BN } from '@project-serum/anchor'
import { Governance, ProgramAccount, Proposal } from '@solana/spl-governance'
import { RawMint } from '@solana/spl-token'
import GovernanceStore from '@store/governanceStore'
@ -29,11 +30,11 @@ const QuorumProgress = ({ governance, proposal, communityMint }: Props) => {
)
const minimumYesVotes =
fmtTokenAmount(maxVoteWeight!, communityMint.decimals) *
fmtTokenAmount(new BN(maxVoteWeight!.toString()), communityMint.decimals) *
(voteThresholdPct / 100)
const yesVoteCount = fmtTokenAmount(
proposal.account.getYesVoteCount(),
new BN(proposal.account.getYesVoteCount().toString()),
communityMint.decimals
)

View File

@ -3,6 +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'
type VoteResultsProps = {
proposal: Proposal
@ -13,11 +14,11 @@ const VoteResults = ({ proposal, communityMint }: VoteResultsProps) => {
const { t } = useTranslation(['governance'])
const yesVoteCount = fmtTokenAmount(
proposal.getYesVoteCount(),
proposal.getYesVoteCount() as BN,
communityMint.decimals
)
const noVoteCount = fmtTokenAmount(
proposal.getNoVoteCount(),
proposal.getNoVoteCount() as BN,
communityMint.decimals
)
const totalVoteCount = yesVoteCount + noVoteCount

View File

@ -2,7 +2,6 @@ import mangoStore, { CLUSTER } from '@store/mangoStore'
import { ModalProps } from '../../types/modal'
import Modal from '../shared/Modal'
import { OPENBOOK_PROGRAM_ID } from '@blockworks-foundation/mango-v4'
import useMangoGroup from 'hooks/useMangoGroup'
import { ChangeEvent, useEffect, useState } from 'react'
import Label from '@components/forms/Label'
import Input from '@components/forms/Input'
@ -46,36 +45,32 @@ const defaultFormValues: CreateObMarketForm = {
}
type CreateOpenbookMarketModalProps = {
quoteSymbol: string
baseSymbol: string
baseMint: string
baseDecimals: number
quoteMint: string
quoteDecimals: number
tradingParams: TradingParams
}
const CreateOpenbookMarketModal = ({
isOpen,
onClose,
quoteSymbol,
baseSymbol,
baseMint,
baseDecimals,
quoteMint,
quoteDecimals,
tradingParams,
}: ModalProps & CreateOpenbookMarketModalProps) => {
const { t } = useTranslation(['governance'])
const connection = mangoStore((s) => s.connection)
const wallet = useWallet()
const { handleConnect } = useEnhancedWallet()
const { group } = useMangoGroup()
const [form, setForm] = useState({ ...defaultFormValues })
const [formErrors, setFormErrors] = useState<FormErrors>({})
const [creating, setCreating] = useState(false)
const [solNeededToCreateMarket, setSolNeededToCreateMarket] = useState(0)
const baseBank = group?.banksMapByName.get(baseSymbol)?.length
? group.banksMapByName.get(baseSymbol)![0]
: null
const quoteBank = group?.banksMapByName.get(quoteSymbol)?.length
? group.banksMapByName.get(quoteSymbol)![0]
: null
const handleSetAdvForm = (propertyName: string, value: string | number) => {
setFormErrors({})
setForm({ ...form, [propertyName]: value })
@ -92,12 +87,12 @@ const CreateOpenbookMarketModal = ({
connection,
wallet: wallet.publicKey!,
baseInfo: {
mint: baseBank!.mint,
decimals: baseBank!.mintDecimals,
mint: new PublicKey(baseMint),
decimals: baseDecimals,
},
quoteInfo: {
mint: quoteBank!.mint,
decimals: quoteBank!.mintDecimals,
mint: new PublicKey(quoteMint),
decimals: quoteDecimals,
},
lotSize: Number(form.minimumOrderSize),
tickSize: Number(form.minimumPriceTickSize),
@ -148,14 +143,14 @@ const CreateOpenbookMarketModal = ({
useEffect(() => {
setForm({
programId: OPENBOOK_PROGRAM_ID[CLUSTER].toBase58(),
baseMint: baseBank?.mint.toBase58() || '',
quoteMint: quoteBank?.mint.toBase58() || '',
baseMint: baseMint || '',
quoteMint: quoteMint || '',
minimumOrderSize: tradingParams.minOrderSize.toString(),
minimumPriceTickSize: tradingParams.priceIncrement.toString(),
})
}, [
baseBank?.mint,
quoteBank?.mint,
baseMint,
quoteMint,
tradingParams.minOrderSize,
tradingParams.priceIncrement,
])

View File

@ -0,0 +1,292 @@
import mangoStore, { CLUSTER } from '@store/mangoStore'
import { ModalProps } from '../../types/modal'
import Modal from '../shared/Modal'
import { useWallet } from '@solana/wallet-adapter-react'
import {
CrankAccount,
QueueAccount,
SwitchboardProgram,
} from '@switchboard-xyz/solana.js'
import { OracleJob } from '@switchboard-xyz/common'
import Button from '@components/shared/Button'
import { MANGO_DAO_WALLET } from 'utils/governance/constants'
import { USDC_MINT } from 'utils/constants'
import { Transaction } from '@solana/web3.js'
import { chunk } from 'lodash'
import { useTranslation } from 'next-i18next'
import { notify } from 'utils/notifications'
import { isMangoError } from 'types'
import { useCallback, useState } from 'react'
import Loading from '@components/shared/Loading'
const poolAddressError = 'no-pool-address-found'
const SWITCHBOARD_PERMISSIONLESS_QUE =
'5JYwqvKkqp35w8Nq3ba4z1WYUeJQ1rB36V8XvaGp6zn1'
const SWITCHBOARD_PERMISSIONLESS_CRANK =
'BKtF8yyQsj3Ft6jb2nkfpEKzARZVdGgdEPs6mFmZNmbA'
type BaseProps = ModalProps & {
openbookMarketPk: string
baseTokenPk: string
baseTokenName: string
}
type RaydiumProps = BaseProps & {
raydiumPoolAddress: string
orcaPoolAddress?: string
}
type OrcaProps = BaseProps & {
raydiumPoolAddress?: string
orcaPoolAddress: string
}
const CreateSwitchboardOracleModal = ({
isOpen,
onClose,
openbookMarketPk,
baseTokenPk,
baseTokenName,
raydiumPoolAddress,
orcaPoolAddress,
}: RaydiumProps | OrcaProps) => {
const { t } = useTranslation(['governance'])
const connection = mangoStore((s) => s.connection)
const wallet = useWallet()
const quoteTokenName = 'USDC'
const [creatingOracle, setCreatingOracle] = useState(false)
const create = useCallback(async () => {
try {
setCreatingOracle(true)
const payer = wallet!.publicKey!
if (!orcaPoolAddress && !raydiumPoolAddress) {
throw poolAddressError
}
const poolPropertyName = orcaPoolAddress
? 'orcaPoolAddress'
: 'raydiumPoolAddress'
const poolAddress = orcaPoolAddress ? orcaPoolAddress : raydiumPoolAddress
const program = await SwitchboardProgram.load(CLUSTER, connection)
const [[queueAccount], [crankAccount]] = await Promise.all([
QueueAccount.load(program, SWITCHBOARD_PERMISSIONLESS_QUE),
CrankAccount.load(program, SWITCHBOARD_PERMISSIONLESS_CRANK),
])
const [aggregatorAccount, txArray1] =
await queueAccount.createFeedInstructions(payer, {
name: `${baseTokenName}/${quoteTokenName}`,
batchSize: 6,
minRequiredOracleResults: 3,
minRequiredJobResults: 2,
minUpdateDelaySeconds: 300,
withdrawAuthority: MANGO_DAO_WALLET,
authority: MANGO_DAO_WALLET,
crankDataBuffer: crankAccount.dataBuffer?.publicKey,
crankPubkey: crankAccount.publicKey,
fundAmount: 2.6,
enable: true,
basePriorityFee: 0,
disableCrank: false,
maxPriorityFeeMultiplier: 0,
priorityFeeBump: 0,
priorityFeeBumpPeriod: 0,
jobs: [
{
weight: 1,
data: OracleJob.encodeDelimited(
OracleJob.fromObject({
tasks: [
{
conditionalTask: {
attempt: [
{
valueTask: {
big: '100',
},
},
{
divideTask: {
job: {
tasks: [
{
jupiterSwapTask: {
inTokenAddress: USDC_MINT,
outTokenAddress: baseTokenPk,
baseAmountString: '100',
},
},
],
},
},
},
],
onFailure: [
{
lpExchangeRateTask: {
[poolPropertyName]: poolAddress,
},
},
],
},
},
],
})
).finish(),
},
{
weight: 1,
data: OracleJob.encodeDelimited(
OracleJob.fromObject({
tasks: [
{
conditionalTask: {
attempt: [
{
cacheTask: {
cacheItems: [
{
variableName: 'IN_TOKEN_QTY',
job: {
tasks: [
{
valueTask: {
big: '100',
},
},
{
divideTask: {
job: {
tasks: [
{
serumSwapTask: {
serumPoolAddress:
openbookMarketPk,
},
},
],
},
},
},
],
},
},
],
},
},
{
jupiterSwapTask: {
inTokenAddress: baseTokenPk,
outTokenAddress: USDC_MINT,
baseAmountString: '${IN_TOKEN_QTY}',
},
},
{
divideTask: {
big: '${IN_TOKEN_QTY}',
},
},
],
onFailure: [
{
lpExchangeRateTask: {
[poolPropertyName]: poolAddress,
},
},
],
},
},
],
})
).finish(),
},
],
})
const lockTx = aggregatorAccount.lockInstruction(payer, {})
const txChunks = chunk([...txArray1, lockTx], 1)
const transactions: Transaction[] = []
const latestBlockhash = await connection.getLatestBlockhash('finalized')
for (const chunk of txChunks) {
const tx = new Transaction()
const singers = [...chunk.flatMap((x) => x.signers)]
tx.add(...chunk.flatMap((x) => x.ixns))
tx.lastValidBlockHeight = latestBlockhash.lastValidBlockHeight
tx.recentBlockhash = latestBlockhash.blockhash
tx.feePayer = payer
if (singers.length) {
tx.sign(...singers)
}
transactions.push(tx)
}
const signedTransactions = await wallet.signAllTransactions!(transactions)
for (const tx of signedTransactions) {
const rawTransaction = tx.serialize()
const address = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
})
await connection.confirmTransaction({
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
signature: address,
})
}
setCreatingOracle(false)
onClose()
} catch (e) {
setCreatingOracle(false)
if (e === poolAddressError) {
notify({
title: 'Transaction failed',
description: 'No orca or raydium pool found for oracle',
type: 'error',
})
} else {
if (!isMangoError(e)) return
notify({
title: 'Transaction failed',
description: e.message,
txid: e?.txid,
type: 'error',
})
}
}
}, [
baseTokenName,
baseTokenPk,
connection,
onClose,
openbookMarketPk,
orcaPoolAddress,
raydiumPoolAddress,
wallet,
])
return (
<Modal isOpen={isOpen} onClose={onClose}>
<div className="space-y-4 pb-4">
<p>
{t('create-switch-oracle')} {baseTokenName}/USDC
</p>
<p>{t('estimated-oracle-cost')}</p>
</div>
<div className="float-right">
<Button disabled={creatingOracle} onClick={create}>
{creatingOracle ? (
<Loading className="w-5"></Loading>
) : (
t('create-oracle')
)}
</Button>
</div>
</Modal>
)
}
export default CreateSwitchboardOracleModal

View File

@ -25,12 +25,13 @@
"@metaplex-foundation/js": "0.18.3",
"@project-serum/anchor": "0.25.0",
"@pythnetwork/client": "2.15.0",
"@solana/spl-governance": "0.3.25",
"@solana/spl-governance": "0.3.27",
"@solana/spl-token": "0.3.7",
"@solana/wallet-adapter-base": "0.9.20",
"@solana/wallet-adapter-react": "0.15.32",
"@solana/wallet-adapter-wallets": "0.19.11",
"@solflare-wallet/pfp": "0.0.6",
"@switchboard-xyz/solana.js": "2.2.0",
"@tanstack/react-query": "4.10.1",
"@tippyjs/react": "4.2.6",
"@types/howler": "2.2.7",
@ -113,6 +114,7 @@
"@solana/wallet-adapter-wallets>@solana/wallet-adapter-torus>@toruslabs/solana-embed>@toruslabs/openlogin-jrpc>@toruslabs/openlogin-utils>keccak": true,
"@metaplex-foundation/js>@bundlr-network/client>arbundles>secp256k1": true,
"@metaplex-foundation/js>@bundlr-network/client>arbundles>keccak": true,
"@switchboard-xyz/solana.js>@switchboard-xyz/common>protobufjs": true,
"@solana/web3.js>bigint-buffer": false,
"@solana/web3.js>rpc-websockets>bufferutil": true,
"@solana/web3.js>rpc-websockets>utf-8-validate": true,

View File

@ -95,5 +95,8 @@
"what-happens-next-3": "{{token}} will be listed on Mango automatically on execution.",
"yes": "Yes",
"yes-votes": "Yes Votes",
"your-votes": "Your Votes:"
"your-votes": "Your Votes:",
"create-switch-oracle": "Create switchboard oracle for",
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
"create-oracle": "Create oracle"
}

View File

@ -95,5 +95,8 @@
"what-happens-next-3": "{{token}} will be listed on Mango automatically on execution.",
"yes": "Yes",
"yes-votes": "Yes Votes",
"your-votes": "Your Votes:"
"your-votes": "Your Votes:",
"create-switch-oracle": "Create switchboard oracle for",
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
"create-oracle": "Create oracle"
}

View File

@ -95,5 +95,8 @@
"what-happens-next-3": "{{token}} will be listed on Mango automatically on execution.",
"yes": "Yes",
"yes-votes": "Yes Votes",
"your-votes": "Your Votes:"
"your-votes": "Your Votes:",
"create-switch-oracle": "Create switchboard oracle for",
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
"create-oracle": "Create oracle"
}

View File

@ -95,5 +95,8 @@
"what-happens-next-3": "{{token}} will be listed on Mango automatically on execution.",
"yes": "Yes",
"yes-votes": "Yes Votes",
"your-votes": "Your Votes:"
"your-votes": "Your Votes:",
"create-switch-oracle": "Create switchboard oracle for",
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
"create-oracle": "Create oracle"
}

View File

@ -95,5 +95,8 @@
"what-happens-next-3": "{{token}} will be listed on Mango automatically on execution.",
"yes": "Yes",
"yes-votes": "Yes Votes",
"your-votes": "Your Votes:"
"your-votes": "Your Votes:",
"create-switch-oracle": "Create switchboard oracle for",
"estimated-oracle-cost": "Estimated cost with funding oracle for ~6 months 2.8 SOL",
"create-oracle": "Create oracle"
}

View File

@ -64,7 +64,6 @@ import { PerpMarket } from '@blockworks-foundation/mango-v4/'
import perpPositionsUpdater from './perpPositionsUpdater'
import { DEFAULT_PRIORITY_FEE } from '@components/settings/RpcSettings'
import {
EntityId,
IExecutionLineAdapter,
IOrderLineAdapter,
} from '@public/charting_library/charting_library'

View File

@ -94,6 +94,11 @@ export const JUPITER_API_MAINNET = 'https://token.jup.ag/strict'
export const JUPITER_API_DEVNET = 'https://api.jup.ag/api/tokens/devnet'
export const JUPITER_PRICE_API_MAINNET = 'https://price.jup.ag/v4/'
export const NOTIFICATION_API = 'https://notifications-api.herokuapp.com/'
export const NOTIFICATION_API_WEBSOCKET =
'wss://notifications-api.herokuapp.com/ws'
export const SWITCHBOARD_PROGRAM_ID =
'SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f'

View File

@ -15,7 +15,7 @@ export const isInCoolOffTime = (
governance: Governance | undefined
) => {
const mainVotingEndedAt = proposal?.signingOffAt
?.addn(governance?.config.maxVotingTime || 0)
?.addn(governance?.config.baseVotingTime || 0)
.toNumber()
const votingCoolOffTime = governance?.config.votingCoolOffTime || 0

View File

@ -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 'bn.js'
import { BN } from '@project-serum/anchor'
export async function fetchRealm({
connection,

187
yarn.lock
View File

@ -105,6 +105,27 @@
superstruct "^0.15.4"
toml "^3.0.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==
dependencies:
"@coral-xyz/borsh" "^0.27.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/borsh@^0.26.0":
version "0.26.0"
resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.26.0.tgz#d054f64536d824634969e74138f9f7c52bbbc0d5"
@ -113,6 +134,14 @@
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"
integrity sha512-tJKzhLukghTWPLy+n8K8iJKgBq1yLT/AxaNd10yJrX8mI56ao5+OFAKAqW/h0i79KCvb4BK0VGO5ECmmolFz9A==
dependencies:
bn.js "^5.1.2"
buffer-layout "^1.2.0"
"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
@ -938,12 +967,19 @@
jsbi "^3.1.5"
sha.js "^2.4.11"
"@noble/curves@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932"
integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==
dependencies:
"@noble/hashes" "1.3.0"
"@noble/ed25519@^1.6.1", "@noble/ed25519@^1.7.0", "@noble/ed25519@^1.7.1":
version "1.7.3"
resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123"
integrity sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==
"@noble/hashes@^1.1.2", "@noble/hashes@^1.1.3":
"@noble/hashes@1.3.0", "@noble/hashes@^1.1.2", "@noble/hashes@^1.1.3", "@noble/hashes@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1"
integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==
@ -1117,6 +1153,59 @@
bs58 "^4.0.1"
eventemitter3 "^4.0.7"
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==
"@protobufjs/base64@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
"@protobufjs/codegen@^2.0.4":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
"@protobufjs/eventemitter@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==
"@protobufjs/fetch@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==
dependencies:
"@protobufjs/aspromise" "^1.1.1"
"@protobufjs/inquire" "^1.1.0"
"@protobufjs/float@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==
"@protobufjs/inquire@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==
"@protobufjs/path@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==
"@protobufjs/pool@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==
"@protobufjs/utf8@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
"@pythnetwork/client@2.15.0":
version "2.15.0"
resolved "https://registry.yarnpkg.com/@pythnetwork/client/-/client-2.15.0.tgz#e84a1e52e7b142acc7476940f94f6dffc2e94bc2"
@ -1203,10 +1292,10 @@
dependencies:
buffer "~6.0.3"
"@solana/spl-governance@0.3.25":
version "0.3.25"
resolved "https://registry.yarnpkg.com/@solana/spl-governance/-/spl-governance-0.3.25.tgz#57563003ebd4cf0bf778876035828196e34e29fd"
integrity sha512-+qepFswOvG0mHLoLnONw+6bwSuEKr7UhJyeAuM/nodjkR8Z5IfH4HQuOzl+TlPTjMStLFJ7Ja6AzTu+FkPGIUQ==
"@solana/spl-governance@0.3.27":
version "0.3.27"
resolved "https://registry.yarnpkg.com/@solana/spl-governance/-/spl-governance-0.3.27.tgz#54ab8310a142b3d581d8abc3df37e3511f02619c"
integrity sha512-5qAgaOWXNNbfOAiBeX5GqX+ZahMGzm1s/kLADAVRWtPYI/vpwc8ENI5jpPOEWG5bgTnnBP+wLT9mgxgwoS4e+A==
dependencies:
"@solana/web3.js" "^1.22.0"
axios "^1.1.3"
@ -1696,15 +1785,14 @@
"@wallet-standard/app" "^1.0.1"
"@wallet-standard/base" "^1.0.1"
"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.22.0", "@solana/web3.js@^1.31.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.44.3", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.63.1", "@solana/web3.js@^1.66.2", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.73.2":
version "1.75.0"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.75.0.tgz#824c6f78865007bca758ca18f268d6f7363b42e5"
integrity sha512-rHQgdo1EWfb+nPUpHe4O7i8qJPELHKNR5PAZRK+a7XxiykqOfbaAlPt5boDWAGPnYbSv0ziWZv5mq9DlFaQCxg==
"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.22.0", "@solana/web3.js@^1.31.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.44.3", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.63.1", "@solana/web3.js@^1.66.2", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.73.0", "@solana/web3.js@^1.73.2":
version "1.77.2"
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.77.2.tgz#4b4d71f07efb9aca1f7ab3ae8746c2e79389fe39"
integrity sha512-pKu9S21NGAi6Nsayz2KEdhqOlPUJIr3L911bgQvPg2Dbk/U4gJsk41XGdxyfsfnwKPEI/KbitcByterst4VQ3g==
dependencies:
"@babel/runtime" "^7.12.5"
"@noble/ed25519" "^1.7.0"
"@noble/hashes" "^1.1.2"
"@noble/secp256k1" "^1.6.3"
"@noble/curves" "^1.0.0"
"@noble/hashes" "^1.3.0"
"@solana/buffer-layout" "^4.0.0"
agentkeepalive "^4.2.1"
bigint-buffer "^1.1.5"
@ -1897,6 +1985,21 @@
dependencies:
tslib "^2.4.0"
"@switchboard-xyz/common@^2.2.3":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@switchboard-xyz/common/-/common-2.2.3.tgz#f4d39cea8cea9354ad369f749462fa37152c4ec9"
integrity sha512-E4NQf9aXdOiul+sySAbFPAW9k0qz4wRTfqrU7cEa8nRIvUkg6VIZ+5JfajHv/VfK9UOD+6ZfMBxq2+dHkiz9zw==
dependencies:
"@solana/web3.js" "^1.66.2"
"@types/big.js" "^6.1.6"
"@types/bn.js" "^5.1.1"
big.js "^6.2.1"
bn.js "^5.2.1"
bs58 "^5.0.0"
decimal.js "^10.4.3"
protobufjs "^7.2.3"
yaml "^2.2.1"
"@switchboard-xyz/sbv2-lite@^0.1.6":
version "0.1.6"
resolved "https://registry.yarnpkg.com/@switchboard-xyz/sbv2-lite/-/sbv2-lite-0.1.6.tgz#dc3fbb5b3b028dbd3c688b991bcc48a670131ddb"
@ -1905,6 +2008,19 @@
"@project-serum/anchor" "^0.24.2"
big.js "^6.1.1"
"@switchboard-xyz/solana.js@2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@switchboard-xyz/solana.js/-/solana.js-2.2.0.tgz#5108cfbbf0ca6e48297ae8c6e8c11f39e04ac32a"
integrity sha512-UzAyKDY1wq1UO50PsKc/6huF6xYX/3B5kA0lmEnZMb+5L6M3YtDckbxk6mD4kG7J0curvvX6Alu9cO6uGqnI3A==
dependencies:
"@coral-xyz/anchor" "^0.27.0"
"@coral-xyz/borsh" "^0.27.0"
"@solana/spl-token" "^0.3.6"
"@solana/web3.js" "^1.73.0"
"@switchboard-xyz/common" "^2.2.3"
dotenv "^16.0.3"
lodash "^4.17.21"
"@tanstack/query-core@4.10.1":
version "4.10.1"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.10.1.tgz#a587e39c28a905168bdf8a3906e36715c30ec083"
@ -2070,7 +2186,7 @@
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
"@types/big.js@6.1.6":
"@types/big.js@6.1.6", "@types/big.js@^6.1.6":
version "6.1.6"
resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.1.6.tgz#3d417e758483d55345a03a087f7e0c87137ca444"
integrity sha512-0r9J+Zz9rYm2hOTwiMAVkm3XFQ4u5uTK37xrQMhc9bysn/sf/okzovWMYYIBMFTn/yrEZ11pusgLEaoarTlQbA==
@ -2082,7 +2198,7 @@
dependencies:
"@types/node" "*"
"@types/bn.js@^5.1.0":
"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1":
version "5.1.1"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682"
integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==
@ -2199,10 +2315,10 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.185.tgz#c9843f5a40703a8f5edfd53358a58ae729816908"
integrity sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==
"@types/node@*":
version "18.16.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.0.tgz#4668bc392bb6938637b47e98b1f2ed5426f33316"
integrity sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ==
"@types/node@*", "@types/node@>=13.7.0":
version "20.2.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.5.tgz#26d295f3570323b2837d322180dfbf1ba156fefb"
integrity sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==
"@types/node@11.11.6":
version "11.11.6"
@ -3163,7 +3279,7 @@ bech32@1.1.4:
resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9"
integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==
big.js@6.2.1, big.js@^6.1.1:
big.js@6.2.1, big.js@^6.1.1, big.js@^6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f"
integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==
@ -4014,6 +4130,11 @@ decimal.js@10.4.0:
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.0.tgz#97a7448873b01e92e5ff9117d89a7bca8e63e0fe"
integrity sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg==
decimal.js@^10.4.3:
version "10.4.3"
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==
decode-uri-component@^0.2.0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
@ -6029,6 +6150,11 @@ loglevel@^1.8.0, loglevel@^1.8.1:
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4"
integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==
long@^5.0.0:
version "5.2.3"
resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1"
integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@ -6888,6 +7014,24 @@ prop-types@15.x, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, pro
object-assign "^4.1.1"
react-is "^16.13.1"
protobufjs@^7.2.3:
version "7.2.3"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.3.tgz#01af019e40d9c6133c49acbb3ff9e30f4f0f70b2"
integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==
dependencies:
"@protobufjs/aspromise" "^1.1.2"
"@protobufjs/base64" "^1.1.2"
"@protobufjs/codegen" "^2.0.4"
"@protobufjs/eventemitter" "^1.1.0"
"@protobufjs/fetch" "^1.1.0"
"@protobufjs/float" "^1.0.2"
"@protobufjs/inquire" "^1.1.0"
"@protobufjs/path" "^1.1.2"
"@protobufjs/pool" "^1.1.0"
"@protobufjs/utf8" "^1.1.0"
"@types/node" ">=13.7.0"
long "^5.0.0"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
@ -8775,6 +8919,11 @@ yaml@^1.10.2:
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yaml@^2.2.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b"
integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==
yargs-parser@20.2.4:
version "20.2.4"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"