From 0960f84b588f316617eafb00a9c1aaeb2bc73eef Mon Sep 17 00:00:00 2001 From: Linkie Link Date: Thu, 11 Jan 2024 12:16:47 +0100 Subject: [PATCH] Pyth price fetching (#723) * env: remove testing library * fix: use pyth over oracle * fix: fix the endpoints * fix: fix build * tidy: refactor * fix: fixed account fetching * fix: made all queries chain agnostic * fix: fixed the chart position --- package.json | 1 - src/api/accounts/getAccount.ts | 2 +- src/api/params/getAssetParams.ts | 2 +- src/api/prices/getOraclePrices.ts | 2 +- src/api/prices/getPoolPrice.ts | 2 +- src/api/prices/getPrice.ts | 27 ++------ src/api/prices/getPriceData.ts | 11 ++- src/api/prices/getPrices.ts | 57 ++++++++-------- src/api/prices/getPythPriceData.ts | 5 +- src/api/prices/getPythPrices.ts | 19 +++++- src/api/vaults/getVaultAprs.ts | 9 ++- src/api/vaults/getVaultConfigs.ts | 2 +- src/api/wallets/getAccounts.ts | 1 - src/components/Trade/TradeChart/DataFeed.ts | 3 +- .../Trade/TradeChart/TVChartContainer.tsx | 2 +- src/components/Trade/TradeChart/index.tsx | 2 +- src/configs/chains/neutron/pion-1.ts | 2 - src/configs/chains/osmosis/osmosis-1.ts | 2 - src/constants/pyth.ts | 4 ++ src/hooks/usePriceData.tsx | 2 +- src/types/interfaces/chain.d.ts | 2 - src/utils/assets.ts | 11 +++ src/utils/resolvers.ts | 1 + yarn.lock | 67 ++----------------- 24 files changed, 94 insertions(+), 144 deletions(-) create mode 100644 src/constants/pyth.ts diff --git a/package.json b/package.json index 37d1b2e1..3739c769 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,6 @@ }, "devDependencies": { "@svgr/webpack": "^8.1.0", - "@testing-library/react": "^14.0.0", "@types/debounce-promise": "^3.1.9", "@types/lodash.debounce": "^4.0.9", "@types/lodash.throttle": "^4.1.8", diff --git a/src/api/accounts/getAccount.ts b/src/api/accounts/getAccount.ts index 8e16d54e..b1bdb98f 100644 --- a/src/api/accounts/getAccount.ts +++ b/src/api/accounts/getAccount.ts @@ -16,7 +16,7 @@ export default async function getAccount( const accountPosition: Positions = await cacheFn( () => creditManagerQueryClient.positions({ accountId: accountId }), positionsCache, - `account/${accountId}`, + `${chainConfig.id}/account/${accountId}`, ) const accountKind = await creditManagerQueryClient.accountKind({ accountId: accountId }) diff --git a/src/api/params/getAssetParams.ts b/src/api/params/getAssetParams.ts index 0be5c6d8..34e96071 100644 --- a/src/api/params/getAssetParams.ts +++ b/src/api/params/getAssetParams.ts @@ -13,7 +13,7 @@ export default async function getAssetParams( return iterateContractQuery(paramsQueryClient.allAssetParams) }, assetParamsCache, - 'assetParams', + `${chainConfig.id}/assetParams`, 600, ) } catch (ex) { diff --git a/src/api/prices/getOraclePrices.ts b/src/api/prices/getOraclePrices.ts index a927efb0..335ffb00 100644 --- a/src/api/prices/getOraclePrices.ts +++ b/src/api/prices/getOraclePrices.ts @@ -19,7 +19,7 @@ export default async function getOraclePrices( const priceResults = await cacheFn( () => iterateContractQuery(oracleQueryClient.prices), oraclePriceCache, - 'oraclePrices', + `${chainConfig.id}/oraclePrices`, 60, ) diff --git a/src/api/prices/getPoolPrice.ts b/src/api/prices/getPoolPrice.ts index 63d7f9ae..19058d30 100644 --- a/src/api/prices/getPoolPrice.ts +++ b/src/api/prices/getPoolPrice.ts @@ -38,7 +38,7 @@ const getAssetRate = async (chainConfig: ChainConfig, asset: Asset) => { const response = await cacheFn( () => fetch(url).then((res) => res.json()), poolPriceCache, - `poolPrices/${(asset.poolId || 0).toString()}`, + `${chainConfig.id}/poolPrices/${(asset.poolId || 0).toString()}`, 60, ) const pool = response.pool diff --git a/src/api/prices/getPrice.ts b/src/api/prices/getPrice.ts index 0c675993..519e32ed 100644 --- a/src/api/prices/getPrice.ts +++ b/src/api/prices/getPrice.ts @@ -1,10 +1,7 @@ import { cacheFn, priceCache } from 'api/cache' -import { getOracleQueryClient } from 'api/cosmwasm-client' -import getPoolPrice from 'api/prices/getPoolPrice' -import getPythPrice from 'api/prices/getPythPrices' -import { PRICE_ORACLE_DECIMALS } from 'constants/query' +import getPrices from 'api/prices/getPrices' +import { BN_ZERO } from 'constants/math' import { byDenom } from 'utils/array' -import { BN } from 'utils/helpers' export default async function getPrice( chainConfig: ChainConfig, @@ -15,25 +12,9 @@ export default async function getPrice( async function fetchPrice(chainConfig: ChainConfig, denom: string) { try { - const asset = chainConfig.assets.find(byDenom(denom)) as Asset + const prices = await getPrices(chainConfig) - if (asset.pythPriceFeedId) { - return (await getPythPrice(chainConfig, [asset.pythPriceFeedId]))[0] - } - - if (asset.hasOraclePrice) { - const oracleQueryClient = await getOracleQueryClient(chainConfig) - const priceResponse = await oracleQueryClient.price({ denom: asset.denom }) - const decimalDiff = asset.decimals - PRICE_ORACLE_DECIMALS - - return BN(priceResponse.price).shiftedBy(decimalDiff) - } - - if (asset.poolId) { - return await getPoolPrice(chainConfig, asset) - } - - throw `could not fetch the price info for the given denom: ${denom}` + return prices.find(byDenom(denom))?.amount ?? BN_ZERO } catch (ex) { throw ex } diff --git a/src/api/prices/getPriceData.ts b/src/api/prices/getPriceData.ts index 785aa292..46173d0c 100644 --- a/src/api/prices/getPriceData.ts +++ b/src/api/prices/getPriceData.ts @@ -1,21 +1,18 @@ import fetchPythPriceData from 'api/prices/getPythPriceData' -export default async function getPricesData( - chainConfig: ChainConfig, - assets: Asset[], -): Promise { +export default async function getPricesData(assets: Asset[]): Promise { try { const assetsWithPythPriceFeedId = assets.filter((asset) => !!asset.pythPriceFeedId) - return await requestPythPriceData(chainConfig, assetsWithPythPriceFeedId) + return await requestPythPriceData(assetsWithPythPriceFeedId) } catch (ex) { console.error(ex) throw ex } } -async function requestPythPriceData(chainConfig: ChainConfig, assets: Asset[]): Promise { +async function requestPythPriceData(assets: Asset[]): Promise { if (!assets.length) return [] const priceFeedIds = assets.map((a) => a.pythPriceFeedId) as string[] - return await fetchPythPriceData(chainConfig, priceFeedIds) + return await fetchPythPriceData(priceFeedIds) } diff --git a/src/api/prices/getPrices.ts b/src/api/prices/getPrices.ts index 073704f5..8984339f 100644 --- a/src/api/prices/getPrices.ts +++ b/src/api/prices/getPrices.ts @@ -1,32 +1,35 @@ import getOraclePrices from 'api/prices/getOraclePrices' import getPoolPrice from 'api/prices/getPoolPrice' import fetchPythPrices from 'api/prices/getPythPrices' +import chains from 'configs/chains' import useStore from 'store' import { BNCoin } from 'types/classes/BNCoin' import { partition } from 'utils/array' +import { getAllAssetsWithPythId } from 'utils/assets' export default async function getPrices(chainConfig: ChainConfig): Promise { const usdPrice = new BNCoin({ denom: 'usd', amount: '1' }) - try { - const assetsToFetchPrices = useStore - .getState() - .chainConfig.assets.filter( - (asset) => (asset.isEnabled && asset.isMarket) || asset.forceFetchPrice, - ) - const [assetsWithPythPriceFeedId, assetsWithOraclePrices, assetsWithPoolIds] = - separateAssetsByPriceSources(assetsToFetchPrices) - const pythAndOraclePrices = ( - await Promise.all([ - requestPythPrices(chainConfig, assetsWithPythPriceFeedId), - getOraclePrices(chainConfig, assetsWithOraclePrices), - ]) - ).flat() + const pythAndOraclePrices = [] + const assetsToFetchPrices = useStore + .getState() + .chainConfig.assets.filter( + (asset) => (asset.isEnabled && asset.isMarket) || asset.forceFetchPrice, + ) + + const assetsWithPythPriceFeedId = getAllAssetsWithPythId(chains) + const pythPrices = await requestPythPrices(assetsWithPythPriceFeedId) + pythAndOraclePrices.push(...pythPrices) + + try { + const [assetsWithOraclePrices, assetsWithPoolIds] = + separateAssetsByPriceSources(assetsToFetchPrices) + const oraclePrices = await getOraclePrices(chainConfig, assetsWithOraclePrices) const poolPrices = await requestPoolPrices(chainConfig, assetsWithPoolIds, pythAndOraclePrices) useStore.setState({ isOracleStale: false }) - return [...pythAndOraclePrices, ...poolPrices, usdPrice] + return [...pythAndOraclePrices, ...oraclePrices, ...poolPrices, usdPrice] } catch (ex) { console.error(ex) let message = 'Unknown Error' @@ -34,15 +37,17 @@ export default async function getPrices(chainConfig: ChainConfig): Promise { +async function requestPythPrices(assets: Asset[]): Promise { if (!assets.length) return [] - const priceFeedIds = assets.map((a) => a.pythPriceFeedId) as string[] - return await fetchPythPrices(chainConfig, priceFeedIds).then(mapResponseToBnCoin(assets)) + const priceFeedIds = assets + .map((a) => a.pythPriceFeedId) + .filter((priceFeedId, index, array) => array.indexOf(priceFeedId) === index) as string[] + return await fetchPythPrices(priceFeedIds, assets) } async function requestPoolPrices( @@ -55,24 +60,20 @@ async function requestPoolPrices( return await Promise.all(requests).then(mapResponseToBnCoin(assets)) } -const mapResponseToBnCoin = (assets: Asset[]) => (prices: BigNumber[]) => - prices.map((price: BigNumber, index: number) => +const mapResponseToBnCoin = (assets: Asset[]) => (prices: BigNumber[]) => { + return prices.map((price: BigNumber, index: number) => BNCoin.fromDenomAndBigNumber(assets[index].denom, price), ) +} function separateAssetsByPriceSources(assets: Asset[]) { - // Only fetch Pyth prices for mainnet - const [assetsWithPythPriceFeedId, assetsWithoutPythPriceFeedId] = partition( - assets, - (asset) => !!asset.pythPriceFeedId, - ) + const assetsWithoutPythPriceFeedId = assets.filter((asset) => !asset.pythPriceFeedId) - // Don't get oracle price if it's not mainnet and there is a poolId const [assetsWithOraclePrice, assetsWithoutOraclePrice] = partition( assetsWithoutPythPriceFeedId, (asset) => asset.hasOraclePrice || !asset.poolId, ) const assetsWithPoolId = assetsWithoutOraclePrice.filter((asset) => !!asset.poolId) - return [assetsWithPythPriceFeedId, assetsWithOraclePrice, assetsWithPoolId] + return [assetsWithOraclePrice, assetsWithPoolId] } diff --git a/src/api/prices/getPythPriceData.ts b/src/api/prices/getPythPriceData.ts index fbc28b66..b35e8666 100644 --- a/src/api/prices/getPythPriceData.ts +++ b/src/api/prices/getPythPriceData.ts @@ -1,8 +1,9 @@ import { cacheFn, pythPriceCache } from 'api/cache' +import { pythEndpoints } from 'constants/pyth' -export default async function fetchPythPriceData(chainConfig: ChainConfig, priceFeedIds: string[]) { +export default async function fetchPythPriceData(priceFeedIds: string[]) { try { - const pricesUrl = new URL(`${chainConfig.endpoints.pyth}/latest_vaas`) + const pricesUrl = new URL(`${pythEndpoints.api}/latest_vaas`) priceFeedIds.forEach((id) => pricesUrl.searchParams.append('ids[]', id)) const pythDataResponse: string[] = await cacheFn( diff --git a/src/api/prices/getPythPrices.ts b/src/api/prices/getPythPrices.ts index 4c748b18..8aa74d56 100644 --- a/src/api/prices/getPythPrices.ts +++ b/src/api/prices/getPythPrices.ts @@ -1,9 +1,11 @@ import { cacheFn, pythPriceCache } from 'api/cache' +import { pythEndpoints } from 'constants/pyth' +import { BNCoin } from 'types/classes/BNCoin' import { BN } from 'utils/helpers' -export default async function fetchPythPrices(chainConfig: ChainConfig, priceFeedIds: string[]) { +export default async function fetchPythPrices(priceFeedIds: string[], assets: Asset[]) { try { - const pricesUrl = new URL(`${chainConfig.endpoints.pyth}/latest_price_feeds`) + const pricesUrl = new URL(`${pythEndpoints.api}/latest_price_feeds`) priceFeedIds.forEach((id) => pricesUrl.searchParams.append('ids[]', id)) const pythResponse: PythPriceData[] = await cacheFn( @@ -13,7 +15,18 @@ export default async function fetchPythPrices(chainConfig: ChainConfig, priceFee 30, ) - return pythResponse.map(({ price }) => BN(price.price).shiftedBy(price.expo)) + const mappedPriceData = [] as BNCoin[] + + assets.forEach((asset) => { + const price = pythResponse.find((pythPrice) => asset.pythPriceFeedId === pythPrice.id)?.price + if (price) + mappedPriceData.push( + BNCoin.fromDenomAndBigNumber(asset.denom, BN(price.price).shiftedBy(price.expo)), + ) + return + }) + + return mappedPriceData } catch (ex) { throw ex } diff --git a/src/api/vaults/getVaultAprs.ts b/src/api/vaults/getVaultAprs.ts index d6a1eb3f..2308ef03 100644 --- a/src/api/vaults/getVaultAprs.ts +++ b/src/api/vaults/getVaultAprs.ts @@ -5,12 +5,17 @@ export default async function getAprs(chainConfig: ChainConfig) { const response = await cacheFn( () => fetch(chainConfig.endpoints.aprs.vaults), aprsCacheResponse, - 'aprsResponse', + `${chainConfig.id}/aprsResponse`, 60, ) if (response.ok) { - const data: AprResponse = await cacheFn(() => response.json(), aprsCache, 'aprs', 60) + const data: AprResponse = await cacheFn( + () => response.json(), + aprsCache, + `${chainConfig.id}/aprs`, + 60, + ) return data.vaults.map((aprData) => { const finalApr = aprData.apr.projected_apr * 100 diff --git a/src/api/vaults/getVaultConfigs.ts b/src/api/vaults/getVaultConfigs.ts index b7a8b83c..f8cb618c 100644 --- a/src/api/vaults/getVaultConfigs.ts +++ b/src/api/vaults/getVaultConfigs.ts @@ -11,7 +11,7 @@ export const getVaultConfigs = async ( return await cacheFn( () => iterateContractQuery(paramsQueryClient.allVaultConfigs, 'addr'), vaultConfigsCache, - 'vaultConfigs', + `${chainConfig.id}/vaultConfigs`, 600, ) } catch (ex) { diff --git a/src/api/wallets/getAccounts.ts b/src/api/wallets/getAccounts.ts index 9611cfae..7b13ed02 100644 --- a/src/api/wallets/getAccounts.ts +++ b/src/api/wallets/getAccounts.ts @@ -15,7 +15,6 @@ export default async function getAccounts( .map((account) => getAccount(chainConfig, account.id)) const accounts = await Promise.all($accounts).then((accounts) => accounts) - if (accounts) { return accounts.sort((a, b) => Number(a.id) - Number(b.id)) } diff --git a/src/components/Trade/TradeChart/DataFeed.ts b/src/components/Trade/TradeChart/DataFeed.ts index 2cc743c6..8762f309 100644 --- a/src/components/Trade/TradeChart/DataFeed.ts +++ b/src/components/Trade/TradeChart/DataFeed.ts @@ -1,5 +1,6 @@ import { defaultSymbolInfo } from 'components/Trade/TradeChart/constants' import { MILLISECONDS_PER_MINUTE } from 'constants/math' +import { pythEndpoints } from 'constants/pyth' import { byDenom } from 'utils/array' import { Bar, @@ -74,7 +75,7 @@ export class DataFeed implements IDatafeedChartApi { chainConfig: ChainConfig, ) { if (debug) console.log('Start charting library datafeed') - this.candlesEndpoint = chainConfig.endpoints.pythCandles + this.candlesEndpoint = pythEndpoints.candles this.candlesEndpointTheGraph = chainConfig.endpoints.graphCandles ?? '' this.assets = assets this.debug = debug diff --git a/src/components/Trade/TradeChart/TVChartContainer.tsx b/src/components/Trade/TradeChart/TVChartContainer.tsx index dc985bb4..3d60b96b 100644 --- a/src/components/Trade/TradeChart/TVChartContainer.tsx +++ b/src/components/Trade/TradeChart/TVChartContainer.tsx @@ -160,7 +160,7 @@ export const TVChartContainer = (props: Props) => { )} } - contentClassName='px-0.5 pb-0.5 h-full bg-chart' + contentClassName='px-0.5 pb-0.5 h-full bg-chart w-[calc(100%-2px)] ml-[1px]' className='h-[70dvh] max-h-[980px] min-h-[560px]' >
diff --git a/src/components/Trade/TradeChart/index.tsx b/src/components/Trade/TradeChart/index.tsx index 77ad2c0f..e52cc1ae 100644 --- a/src/components/Trade/TradeChart/index.tsx +++ b/src/components/Trade/TradeChart/index.tsx @@ -45,7 +45,7 @@ export default function TradeChart(props: Props) {
} - contentClassName='px-0.5 pb-0.5 h-full' + contentClassName='px-0.5 pb-0.5 h-full bg-chart w-[calc(100%-2px)] ml-[1px]' className='h-[70dvh] max-h-[980px] min-h-[560px]' >
diff --git a/src/configs/chains/neutron/pion-1.ts b/src/configs/chains/neutron/pion-1.ts index d3b9d392..b17fba0a 100644 --- a/src/configs/chains/neutron/pion-1.ts +++ b/src/configs/chains/neutron/pion-1.ts @@ -35,8 +35,6 @@ const Pion1: ChainConfig = { rest: 'https://rest-palvus.pion-1.ntrn.tech/', rpc: 'https://rpc-palvus.pion-1.ntrn.tech/', swap: 'https://testnet-neutron.astroport.fi/swap', - pyth: 'https://hermes.pyth.network/api', - pythCandles: 'https://benchmarks.pyth.network', pools: '', //TODO: ⛓️ Implement this explorer: 'https://testnet.mintscan.io/neutron-testnet', aprs: { diff --git a/src/configs/chains/osmosis/osmosis-1.ts b/src/configs/chains/osmosis/osmosis-1.ts index 0c8a510c..f5cb3db2 100644 --- a/src/configs/chains/osmosis/osmosis-1.ts +++ b/src/configs/chains/osmosis/osmosis-1.ts @@ -134,8 +134,6 @@ const Osmosis1: ChainConfig = { rpc: 'https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-rpc-front/', rest: 'https://osmosis-node.marsprotocol.io/GGSFGSFGFG34/osmosis-lcd-front/', swap: 'https://app.osmosis.zone', - pyth: 'https://hermes.pyth.network/api', - pythCandles: 'https://benchmarks.pyth.network', graphCandles: 'https://osmosis-candles.marsprotocol.io', explorer: 'https://www.mintscan.io/osmosis/transactions/', pools: diff --git a/src/constants/pyth.ts b/src/constants/pyth.ts new file mode 100644 index 00000000..b6dfea51 --- /dev/null +++ b/src/constants/pyth.ts @@ -0,0 +1,4 @@ +export const pythEndpoints = { + api: 'https://hermes.pyth.network/api', + candles: 'https://benchmarks.pyth.network', +} diff --git a/src/hooks/usePriceData.tsx b/src/hooks/usePriceData.tsx index 48e37600..a2a85e29 100644 --- a/src/hooks/usePriceData.tsx +++ b/src/hooks/usePriceData.tsx @@ -7,7 +7,7 @@ import useStore from 'store' export default function usePricesData() { const assets = useStore((s) => s.chainConfig.assets) const chainConfig = useChainConfig() - return useSWR(`chains/${chainConfig.id}/pricesData`, () => getPricesData(chainConfig, assets), { + return useSWR(`chains/${chainConfig.id}/pricesData`, () => getPricesData(assets), { fallbackData: [], refreshInterval: 30_000, revalidateOnFocus: false, diff --git a/src/types/interfaces/chain.d.ts b/src/types/interfaces/chain.d.ts index 546c871c..8a5a52ad 100644 --- a/src/types/interfaces/chain.d.ts +++ b/src/types/interfaces/chain.d.ts @@ -27,8 +27,6 @@ interface ChainConfig { rest: string rpc: string swap: string - pyth: string - pythCandles: string graphCandles?: string explorer: string pools: string diff --git a/src/utils/assets.ts b/src/utils/assets.ts index b2f89a9b..7313c25a 100644 --- a/src/utils/assets.ts +++ b/src/utils/assets.ts @@ -45,3 +45,14 @@ export function sortAssetsOrPairs( return bMarketValue - aMarketValue }) } + +export function getAllAssetsWithPythId(chains: { [key: string]: ChainConfig }) { + return Object.entries(chains) + .map(([_, chainConfig]) => chainConfig.assets) + .flatMap((assets) => assets) + .filter( + (item, index, array) => + index === array.findIndex((foundItem) => foundItem['denom'] === item['denom']), + ) + .filter((asset) => asset.pythPriceFeedId) +} diff --git a/src/utils/resolvers.ts b/src/utils/resolvers.ts index cced04ca..a4c6969a 100644 --- a/src/utils/resolvers.ts +++ b/src/utils/resolvers.ts @@ -78,6 +78,7 @@ export function resolveHLSStrategies( } export function resolvePerpsPositions(perpPositions: Positions['perps']): PerpsPosition[] { + if (!perpPositions) return [] return perpPositions.map((position) => { return { denom: position.denom, diff --git a/yarn.lock b/yarn.lock index fe509505..3cc54047 100644 --- a/yarn.lock +++ b/yarn.lock @@ -39,7 +39,7 @@ tslib "^2.3.0" zen-observable-ts "^1.2.5" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.21.4": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.21.4": version "7.21.4" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz" integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== @@ -1103,7 +1103,7 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4": version "7.21.5" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz" integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== @@ -3406,29 +3406,6 @@ long "^4.0.0" protobufjs "~6.11.2" -"@testing-library/dom@^9.0.0": - version "9.2.0" - resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-9.2.0.tgz" - integrity sha512-xTEnpUKiV/bMyEsE5bT4oYA0x0Z/colMtxzUY8bKyPXBNLn/e0V4ZjBZkEhms0xE4pv9QsPfSRu9AWS4y5wGvA== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^5.0.1" - aria-query "^5.0.0" - chalk "^4.1.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.5.0" - pretty-format "^27.0.2" - -"@testing-library/react@^14.0.0": - version "14.0.0" - resolved "https://registry.npmjs.org/@testing-library/react/-/react-14.0.0.tgz" - integrity sha512-S04gSNJbYE30TlIMLTzv6QCTzt9AqIF5y6s6SzVFILNcNvbV/jU96GeiTPillGQo+Ny64M/5PV7klNYYgv5Dfg== - dependencies: - "@babel/runtime" "^7.12.5" - "@testing-library/dom" "^9.0.0" - "@types/react-dom" "^18.0.0" - "@tippyjs/react@^4.2.6": version "4.2.6" resolved "https://registry.npmjs.org/@tippyjs/react/-/react-4.2.6.tgz" @@ -3441,11 +3418,6 @@ resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== -"@types/aria-query@^5.0.1": - version "5.0.1" - resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz" - integrity sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q== - "@types/bn.js@5.1.1", "@types/bn.js@^5.1.0": version "5.1.1" resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz" @@ -3581,7 +3553,7 @@ resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== -"@types/react-dom@18.2.15", "@types/react-dom@^18.0.0": +"@types/react-dom@18.2.15": version "18.2.15" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.15.tgz#921af67f9ee023ac37ea84b1bc0cc40b898ea522" integrity sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg== @@ -3958,11 +3930,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - ansi-styles@^6.0.0, ansi-styles@^6.2.1: version "6.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" @@ -3991,7 +3958,7 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^5.0.0, aria-query@^5.1.3: +aria-query@^5.1.3: version "5.1.3" resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== @@ -4429,7 +4396,7 @@ chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0: +chalk@^4.0.0: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -4968,11 +4935,6 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-accessibility-api@^0.5.9: - version "0.5.16" - resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz" - integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== - dom-helpers@^3.4.0: version "3.4.0" resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz" @@ -6887,11 +6849,6 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lz-string@^1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz" - integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== - magic-string@^0.27.0: version "0.27.0" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz" @@ -7516,15 +7473,6 @@ prettier@^3.0.3: resolved "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz" integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== -pretty-format@^27.0.2: - version "27.5.1" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz" - integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== - dependencies: - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^17.0.1" - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" @@ -7670,11 +7618,6 @@ react-is@^16.10.2, react-is@^16.13.1, react-is@^16.7.0: resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz"