feat: integrate relay (#4320)
* setup relay compiler * refactored to use polling interval, fixed PR comments * fixes, readded uninitialized state for liquidity chart * updated cypress test * reorganized graphql files into src/graphql
This commit is contained in:
parent
d6d0a98afe
commit
91f4892b0c
@ -18,7 +18,6 @@
|
|||||||
"src/abis/types",
|
"src/abis/types",
|
||||||
"src/locales/**/*.js",
|
"src/locales/**/*.js",
|
||||||
"src/locales/**/en-US.po",
|
"src/locales/**/en-US.po",
|
||||||
"src/state/data/generated.ts",
|
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"coverage",
|
"coverage",
|
||||||
"build",
|
"build",
|
||||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,12 +1,16 @@
|
|||||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
|
||||||
# generated contract types
|
# generated contract types
|
||||||
/src/types/v3
|
/src/types/v3
|
||||||
/src/abis/types
|
/src/abis/types
|
||||||
/src/locales/**/*.js
|
/src/locales/**/*.js
|
||||||
/src/locales/**/en-US.po
|
/src/locales/**/en-US.po
|
||||||
/src/locales/**/pseudo.po
|
/src/locales/**/pseudo.po
|
||||||
/src/state/data/generated.ts
|
|
||||||
|
# generated graphql types
|
||||||
|
/src/graphql/schema/
|
||||||
|
__generated__/
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/node_modules
|
/node_modules
|
||||||
|
@ -1 +1 @@
|
|||||||
/src/state/data/generated.ts
|
/src/schema/schema.graphql
|
@ -2,10 +2,6 @@ overrideExisting: true
|
|||||||
schema: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3'
|
schema: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3'
|
||||||
documents: 'src/**/!(*.d).{ts,tsx}'
|
documents: 'src/**/!(*.d).{ts,tsx}'
|
||||||
generates:
|
generates:
|
||||||
./src/state/data/generated.ts:
|
./src/graphql/schema/schema.graphql:
|
||||||
plugins:
|
plugins:
|
||||||
- typescript
|
- schema-ast
|
||||||
- typescript-operations
|
|
||||||
- typescript-rtk-query:
|
|
||||||
importBaseApiFrom: './slice'
|
|
||||||
exportHooks: true
|
|
||||||
|
@ -37,8 +37,8 @@ describe('Add Liquidity', () => {
|
|||||||
it('loads fee tier distribution', () => {
|
it('loads fee tier distribution', () => {
|
||||||
cy.fixture('feeTierDistribution.json').then((feeTierDistribution) => {
|
cy.fixture('feeTierDistribution.json').then((feeTierDistribution) => {
|
||||||
cy.intercept('POST', '/subgraphs/name/uniswap/uniswap-v3', (req: CyHttpMessages.IncomingHttpRequest) => {
|
cy.intercept('POST', '/subgraphs/name/uniswap/uniswap-v3', (req: CyHttpMessages.IncomingHttpRequest) => {
|
||||||
if (hasQuery(req, 'feeTierDistribution')) {
|
if (hasQuery(req, 'FeeTierDistributionQuery')) {
|
||||||
req.alias = 'feeTierDistributionQuery'
|
req.alias = 'FeeTierDistributionQuery'
|
||||||
|
|
||||||
req.reply({
|
req.reply({
|
||||||
body: {
|
body: {
|
||||||
@ -55,7 +55,7 @@ describe('Add Liquidity', () => {
|
|||||||
|
|
||||||
cy.visit('/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85/0xc778417E063141139Fce010982780140Aa0cD5Ab')
|
cy.visit('/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85/0xc778417E063141139Fce010982780140Aa0cD5Ab')
|
||||||
|
|
||||||
cy.wait('@feeTierDistributionQuery')
|
cy.wait('@FeeTierDistributionQuery')
|
||||||
|
|
||||||
cy.get('#add-liquidity-selected-fee .selected-fee-label').should('contain.text', '0.3% fee tier')
|
cy.get('#add-liquidity-selected-fee .selected-fee-label').should('contain.text', '0.3% fee tier')
|
||||||
cy.get('#add-liquidity-selected-fee .selected-fee-percentage').should('contain.text', '40%')
|
cy.get('#add-liquidity-selected-fee .selected-fee-percentage').should('contain.text', '40%')
|
||||||
|
18
package.json
18
package.json
@ -8,7 +8,8 @@
|
|||||||
"contracts:compile:abi": "typechain --target ethers-v5 --out-dir src/abis/types \"./src/abis/**/*.json\"",
|
"contracts:compile:abi": "typechain --target ethers-v5 --out-dir src/abis/types \"./src/abis/**/*.json\"",
|
||||||
"contracts:compile:v3": "typechain --target ethers-v5 --out-dir src/types/v3 \"./node_modules/@uniswap/**/artifacts/contracts/**/*[!dbg].json\"",
|
"contracts:compile:v3": "typechain --target ethers-v5 --out-dir src/types/v3 \"./node_modules/@uniswap/**/artifacts/contracts/**/*[!dbg].json\"",
|
||||||
"contracts:compile": "yarn contracts:compile:abi && yarn contracts:compile:v3",
|
"contracts:compile": "yarn contracts:compile:abi && yarn contracts:compile:v3",
|
||||||
"graphql:generate": "graphql-codegen --config codegen.yml",
|
"relay": "relay-compiler",
|
||||||
|
"graphql:generate": "graphql-codegen --config codegen.yml && yarn relay",
|
||||||
"prei18n:extract": "node prei18n-extract.js",
|
"prei18n:extract": "node prei18n-extract.js",
|
||||||
"i18n:extract": "lingui extract --locale en-US",
|
"i18n:extract": "lingui extract --locale en-US",
|
||||||
"i18n:compile": "yarn i18n:extract && lingui compile",
|
"i18n:compile": "yarn i18n:extract && lingui compile",
|
||||||
@ -22,6 +23,11 @@
|
|||||||
"cypress:open": "cypress open --browser chrome --e2e",
|
"cypress:open": "cypress open --browser chrome --e2e",
|
||||||
"cypress:run": "cypress run --browser chrome --e2e"
|
"cypress:run": "cypress run --browser chrome --e2e"
|
||||||
},
|
},
|
||||||
|
"relay": {
|
||||||
|
"src": "./src",
|
||||||
|
"language": "typescript",
|
||||||
|
"schema": "./src/graphql/schema/schema.graphql"
|
||||||
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"collectCoverageFrom": [
|
"collectCoverageFrom": [
|
||||||
"src/components/**/*.ts*",
|
"src/components/**/*.ts*",
|
||||||
@ -58,8 +64,7 @@
|
|||||||
"@craco/craco": "6.4.3",
|
"@craco/craco": "6.4.3",
|
||||||
"@ethersproject/experimental": "^5.4.0",
|
"@ethersproject/experimental": "^5.4.0",
|
||||||
"@graphql-codegen/cli": "1.21.5",
|
"@graphql-codegen/cli": "1.21.5",
|
||||||
"@graphql-codegen/typescript": "1.22.3",
|
"@graphql-codegen/schema-ast": "^2.5.1",
|
||||||
"@graphql-codegen/typescript-operations": "^1.18.2",
|
|
||||||
"@graphql-codegen/typescript-rtk-query": "^1.1.1",
|
"@graphql-codegen/typescript-rtk-query": "^1.1.1",
|
||||||
"@lingui/cli": "^3.9.0",
|
"@lingui/cli": "^3.9.0",
|
||||||
"@testing-library/jest-dom": "^5.16.4",
|
"@testing-library/jest-dom": "^5.16.4",
|
||||||
@ -90,6 +95,7 @@
|
|||||||
"@types/wcag-contrast": "^3.0.0",
|
"@types/wcag-contrast": "^3.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4",
|
"@typescript-eslint/eslint-plugin": "^4",
|
||||||
"@typescript-eslint/parser": "^4",
|
"@typescript-eslint/parser": "^4",
|
||||||
|
"babel-plugin-relay": "^14.1.0",
|
||||||
"@vanilla-extract/babel-plugin": "^1.1.7",
|
"@vanilla-extract/babel-plugin": "^1.1.7",
|
||||||
"@vanilla-extract/webpack-plugin": "^2.1.11",
|
"@vanilla-extract/webpack-plugin": "^2.1.11",
|
||||||
"cypress": "^10.3.1",
|
"cypress": "^10.3.1",
|
||||||
@ -106,6 +112,7 @@
|
|||||||
"ms.macro": "^2.0.0",
|
"ms.macro": "^2.0.0",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"react-scripts": "^4.0.3",
|
"react-scripts": "^4.0.3",
|
||||||
|
"relay-compiler": "^14.1.0",
|
||||||
"serve": "^11.3.2",
|
"serve": "^11.3.2",
|
||||||
"typechain": "^5.0.0",
|
"typechain": "^5.0.0",
|
||||||
"typescript": "^4.4.3"
|
"typescript": "^4.4.3"
|
||||||
@ -126,6 +133,7 @@
|
|||||||
"@reach/portal": "^0.10.3",
|
"@reach/portal": "^0.10.3",
|
||||||
"@react-hook/window-scroll": "^1.3.0",
|
"@react-hook/window-scroll": "^1.3.0",
|
||||||
"@reduxjs/toolkit": "^1.6.1",
|
"@reduxjs/toolkit": "^1.6.1",
|
||||||
|
"@types/react-relay": "^13.0.2",
|
||||||
"@uniswap/governance": "^1.0.2",
|
"@uniswap/governance": "^1.0.2",
|
||||||
"@uniswap/liquidity-staker": "^1.0.2",
|
"@uniswap/liquidity-staker": "^1.0.2",
|
||||||
"@uniswap/merkle-distributor": "1.0.1",
|
"@uniswap/merkle-distributor": "1.0.1",
|
||||||
@ -174,7 +182,7 @@
|
|||||||
"firebase": "^9.1.3",
|
"firebase": "^9.1.3",
|
||||||
"focus-visible": "^5.2.0",
|
"focus-visible": "^5.2.0",
|
||||||
"fortmatic": "^2.4.0",
|
"fortmatic": "^2.4.0",
|
||||||
"graphql": "^15.5.0",
|
"graphql": "^16.5.0",
|
||||||
"graphql-request": "^3.4.0",
|
"graphql-request": "^3.4.0",
|
||||||
"immer": "^9.0.6",
|
"immer": "^9.0.6",
|
||||||
"inter-ui": "^3.13.1",
|
"inter-ui": "^3.13.1",
|
||||||
@ -199,6 +207,7 @@
|
|||||||
"react-popper": "^2.2.3",
|
"react-popper": "^2.2.3",
|
||||||
"react-query": "^3.39.1",
|
"react-query": "^3.39.1",
|
||||||
"react-redux": "^8.0.2",
|
"react-redux": "^8.0.2",
|
||||||
|
"react-relay": "^14.1.0",
|
||||||
"react-router-dom": "^6.3.0",
|
"react-router-dom": "^6.3.0",
|
||||||
"react-spring": "^8.0.27",
|
"react-spring": "^8.0.27",
|
||||||
"react-table": "^7.8.0",
|
"react-table": "^7.8.0",
|
||||||
@ -208,6 +217,7 @@
|
|||||||
"rebass": "^4.0.7",
|
"rebass": "^4.0.7",
|
||||||
"redux": "^4.1.2",
|
"redux": "^4.1.2",
|
||||||
"redux-localstorage-simple": "^2.3.1",
|
"redux-localstorage-simple": "^2.3.1",
|
||||||
|
"relay-hooks": "^7.1.0",
|
||||||
"setimmediate": "^1.0.5",
|
"setimmediate": "^1.0.5",
|
||||||
"styled-components": "^5.3.5",
|
"styled-components": "^5.3.5",
|
||||||
"tiny-invariant": "^1.2.0",
|
"tiny-invariant": "^1.2.0",
|
||||||
|
@ -14,7 +14,7 @@ export function useDensityChartData({
|
|||||||
currencyB: Currency | undefined
|
currencyB: Currency | undefined
|
||||||
feeAmount: FeeAmount | undefined
|
feeAmount: FeeAmount | undefined
|
||||||
}) {
|
}) {
|
||||||
const { isLoading, isUninitialized, isError, error, data } = usePoolActiveLiquidity(currencyA, currencyB, feeAmount)
|
const { isLoading, error, data } = usePoolActiveLiquidity(currencyA, currencyB, feeAmount)
|
||||||
|
|
||||||
const formatData = useCallback(() => {
|
const formatData = useCallback(() => {
|
||||||
if (!data?.length) {
|
if (!data?.length) {
|
||||||
@ -42,10 +42,8 @@ export function useDensityChartData({
|
|||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
isUninitialized,
|
|
||||||
isError,
|
|
||||||
error,
|
error,
|
||||||
formattedData: !isLoading && !isUninitialized ? formatData() : undefined,
|
formattedData: !isLoading ? formatData() : undefined,
|
||||||
}
|
}
|
||||||
}, [isLoading, isUninitialized, isError, error, formatData])
|
}, [isLoading, error, formatData])
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ export default function LiquidityChartRangeInput({
|
|||||||
|
|
||||||
const isSorted = currencyA && currencyB && currencyA?.wrapped.sortsBefore(currencyB?.wrapped)
|
const isSorted = currencyA && currencyB && currencyA?.wrapped.sortsBefore(currencyB?.wrapped)
|
||||||
|
|
||||||
const { isLoading, isUninitialized, isError, error, formattedData } = useDensityChartData({
|
const { isLoading, error, formattedData } = useDensityChartData({
|
||||||
currencyA,
|
currencyA,
|
||||||
currencyB,
|
currencyB,
|
||||||
feeAmount,
|
feeAmount,
|
||||||
@ -157,10 +157,12 @@ export default function LiquidityChartRangeInput({
|
|||||||
[isSorted, price, ticksAtLimit]
|
[isSorted, price, ticksAtLimit]
|
||||||
)
|
)
|
||||||
|
|
||||||
if (isError) {
|
if (error) {
|
||||||
sendEvent('exception', { description: error.toString(), fatal: false })
|
sendEvent('exception', { description: error.toString(), fatal: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isUninitialized = !currencyA || !currencyB || (formattedData === undefined && !isLoading)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AutoColumn gap="md" style={{ minHeight: '200px' }}>
|
<AutoColumn gap="md" style={{ minHeight: '200px' }}>
|
||||||
{isUninitialized ? (
|
{isUninitialized ? (
|
||||||
@ -170,7 +172,7 @@ export default function LiquidityChartRangeInput({
|
|||||||
/>
|
/>
|
||||||
) : isLoading ? (
|
) : isLoading ? (
|
||||||
<InfoBox icon={<Loader size="40px" stroke={theme.deprecated_text4} />} />
|
<InfoBox icon={<Loader size="40px" stroke={theme.deprecated_text4} />} />
|
||||||
) : isError ? (
|
) : error ? (
|
||||||
<InfoBox
|
<InfoBox
|
||||||
message={<Trans>Liquidity data not available.</Trans>}
|
message={<Trans>Liquidity data not available.</Trans>}
|
||||||
icon={<CloudOff size={56} stroke={theme.deprecated_text4} />}
|
icon={<CloudOff size={56} stroke={theme.deprecated_text4} />}
|
||||||
|
@ -44,7 +44,7 @@ export const ALL_SUPPORTED_CHAIN_IDS: SupportedChainId[] = Object.values(Support
|
|||||||
(id) => typeof id === 'number'
|
(id) => typeof id === 'number'
|
||||||
) as SupportedChainId[]
|
) as SupportedChainId[]
|
||||||
|
|
||||||
export function isSupportedChain(chainId: number | undefined): chainId is SupportedChainId {
|
export function isSupportedChain(chainId: number | null | undefined): chainId is SupportedChainId {
|
||||||
return !!chainId && !!SupportedChainId[chainId]
|
return !!chainId && !!SupportedChainId[chainId]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
53
src/graphql/AllV3TicksQuery.ts
Normal file
53
src/graphql/AllV3TicksQuery.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import graphql from 'babel-plugin-relay/macro'
|
||||||
|
import useInterval from 'lib/hooks/useInterval'
|
||||||
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
import { fetchQuery, useRelayEnvironment } from 'relay-hooks'
|
||||||
|
import { useAppSelector } from 'state/hooks'
|
||||||
|
|
||||||
|
import type {
|
||||||
|
AllV3TicksQuery as AllV3TicksQueryType,
|
||||||
|
AllV3TicksQuery$data,
|
||||||
|
} from './__generated__/AllV3TicksQuery.graphql'
|
||||||
|
|
||||||
|
const query = graphql`
|
||||||
|
query AllV3TicksQuery($poolAddress: String!, $skip: Int!) {
|
||||||
|
ticks(first: 1000, skip: $skip, where: { poolAddress: $poolAddress }, orderBy: tickIdx) {
|
||||||
|
tick: tickIdx
|
||||||
|
liquidityNet
|
||||||
|
price0
|
||||||
|
price1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export type Ticks = AllV3TicksQuery$data['ticks']
|
||||||
|
export type TickData = Ticks[number]
|
||||||
|
|
||||||
|
export default function useAllV3TicksQuery(poolAddress: string | undefined, skip: number, interval: number) {
|
||||||
|
const [data, setData] = useState<AllV3TicksQuery$data | null>(null)
|
||||||
|
const [error, setError] = useState<any>(null)
|
||||||
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
|
const chainId = useAppSelector((state) => state.application.chainId)
|
||||||
|
const environment = useRelayEnvironment()
|
||||||
|
|
||||||
|
const refreshData = useCallback(() => {
|
||||||
|
if (poolAddress && chainId) {
|
||||||
|
fetchQuery<AllV3TicksQueryType>(environment, query, {
|
||||||
|
poolAddress: poolAddress.toLowerCase(),
|
||||||
|
skip,
|
||||||
|
}).subscribe({
|
||||||
|
next: setData,
|
||||||
|
error: setError,
|
||||||
|
complete: () => setIsLoading(false),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setIsLoading(false)
|
||||||
|
}
|
||||||
|
}, [poolAddress, skip, chainId, environment])
|
||||||
|
|
||||||
|
// Trigger fetch on first load
|
||||||
|
useEffect(refreshData, [refreshData, poolAddress, skip])
|
||||||
|
|
||||||
|
useInterval(refreshData, interval, true)
|
||||||
|
return { error, isLoading, data }
|
||||||
|
}
|
69
src/graphql/FeeTierDistributionQuery.ts
Normal file
69
src/graphql/FeeTierDistributionQuery.ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import graphql from 'babel-plugin-relay/macro'
|
||||||
|
import useInterval from 'lib/hooks/useInterval'
|
||||||
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
import { fetchQuery, useRelayEnvironment } from 'relay-hooks'
|
||||||
|
import { useAppSelector } from 'state/hooks'
|
||||||
|
|
||||||
|
import type {
|
||||||
|
FeeTierDistributionQuery as FeeTierDistributionQueryType,
|
||||||
|
FeeTierDistributionQuery$data,
|
||||||
|
} from './__generated__/FeeTierDistributionQuery.graphql'
|
||||||
|
|
||||||
|
const query = graphql`
|
||||||
|
query FeeTierDistributionQuery($token0: String!, $token1: String!) {
|
||||||
|
_meta {
|
||||||
|
block {
|
||||||
|
number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asToken0: pools(
|
||||||
|
orderBy: totalValueLockedToken0
|
||||||
|
orderDirection: desc
|
||||||
|
where: { token0: $token0, token1: $token1 }
|
||||||
|
) {
|
||||||
|
feeTier
|
||||||
|
totalValueLockedToken0
|
||||||
|
totalValueLockedToken1
|
||||||
|
}
|
||||||
|
asToken1: pools(
|
||||||
|
orderBy: totalValueLockedToken0
|
||||||
|
orderDirection: desc
|
||||||
|
where: { token0: $token1, token1: $token0 }
|
||||||
|
) {
|
||||||
|
feeTier
|
||||||
|
totalValueLockedToken0
|
||||||
|
totalValueLockedToken1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default function useFeeTierDistributionQuery(
|
||||||
|
token0: string | undefined,
|
||||||
|
token1: string | undefined,
|
||||||
|
interval: number
|
||||||
|
) {
|
||||||
|
const [data, setData] = useState<FeeTierDistributionQuery$data | null>(null)
|
||||||
|
const [error, setError] = useState<any>(null)
|
||||||
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
|
const environment = useRelayEnvironment()
|
||||||
|
const chainId = useAppSelector((state) => state.application.chainId)
|
||||||
|
|
||||||
|
const refreshData = useCallback(() => {
|
||||||
|
if (token0 && token1 && chainId) {
|
||||||
|
fetchQuery<FeeTierDistributionQueryType>(environment, query, {
|
||||||
|
token0: token0.toLowerCase(),
|
||||||
|
token1: token1.toLowerCase(),
|
||||||
|
}).subscribe({
|
||||||
|
next: setData,
|
||||||
|
error: setError,
|
||||||
|
complete: () => setIsLoading(false),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [token0, token1, chainId, environment])
|
||||||
|
|
||||||
|
// Trigger fetch on first load
|
||||||
|
useEffect(refreshData, [refreshData, token0, token1])
|
||||||
|
|
||||||
|
useInterval(refreshData, interval, true)
|
||||||
|
return { error, isLoading, data }
|
||||||
|
}
|
9
src/graphql/RelayEnvironment.ts
Normal file
9
src/graphql/RelayEnvironment.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { Environment, Network, RecordSource, Store } from 'relay-runtime'
|
||||||
|
|
||||||
|
import fetchGraphQL from './fetchGraphQL'
|
||||||
|
|
||||||
|
// Export a singleton instance of Relay Environment configured with our network function:
|
||||||
|
export default new Environment({
|
||||||
|
network: Network.create(fetchGraphQL),
|
||||||
|
store: new Store(new RecordSource()),
|
||||||
|
})
|
53
src/graphql/fetchGraphQL.ts
Normal file
53
src/graphql/fetchGraphQL.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Helpful Resources
|
||||||
|
* https://github.com/sibelius/create-react-app-relay-modern/blob/master/src/relay/fetchQuery.js
|
||||||
|
* https://github.com/relay-tools/relay-compiler-language-typescript/blob/master/example/ts/app.tsx
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { SupportedChainId } from 'constants/chains'
|
||||||
|
import { Variables } from 'react-relay'
|
||||||
|
import { GraphQLResponse, ObservableFromValue, RequestParameters } from 'relay-runtime'
|
||||||
|
|
||||||
|
import store, { AppState } from '../state/index'
|
||||||
|
|
||||||
|
const CHAIN_SUBGRAPH_URL: Record<number, string> = {
|
||||||
|
[SupportedChainId.MAINNET]: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3',
|
||||||
|
[SupportedChainId.RINKEBY]: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3',
|
||||||
|
|
||||||
|
[SupportedChainId.ARBITRUM_ONE]: 'https://api.thegraph.com/subgraphs/name/ianlapham/arbitrum-minimal',
|
||||||
|
|
||||||
|
[SupportedChainId.OPTIMISM]: 'https://api.thegraph.com/subgraphs/name/ianlapham/optimism-post-regenesis',
|
||||||
|
|
||||||
|
[SupportedChainId.POLYGON]: 'https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v3-polygon',
|
||||||
|
|
||||||
|
[SupportedChainId.CELO]: 'https://api.thegraph.com/subgraphs/name/jesse-sawa/uniswap-celo',
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-type': 'application/json',
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define a function that fetches the results of a request (query/mutation/etc)
|
||||||
|
// and returns its results as a Promise:
|
||||||
|
const fetchQuery = (params: RequestParameters, variables: Variables): ObservableFromValue<GraphQLResponse> => {
|
||||||
|
const chainId = (store.getState() as AppState).application.chainId
|
||||||
|
|
||||||
|
const subgraphUrl =
|
||||||
|
chainId && CHAIN_SUBGRAPH_URL[chainId] ? CHAIN_SUBGRAPH_URL[chainId] : CHAIN_SUBGRAPH_URL[SupportedChainId.MAINNET]
|
||||||
|
|
||||||
|
const body = JSON.stringify({
|
||||||
|
query: params.text, // GraphQL text from input
|
||||||
|
variables,
|
||||||
|
})
|
||||||
|
|
||||||
|
const response = fetch(subgraphUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers,
|
||||||
|
body,
|
||||||
|
}).then((res) => res.json())
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
export default fetchQuery
|
@ -1,13 +1,11 @@
|
|||||||
import { skipToken } from '@reduxjs/toolkit/query/react'
|
|
||||||
import { Currency, Token } from '@uniswap/sdk-core'
|
import { Currency, Token } from '@uniswap/sdk-core'
|
||||||
import { FeeAmount } from '@uniswap/v3-sdk'
|
import { FeeAmount } from '@uniswap/v3-sdk'
|
||||||
import { sendEvent } from 'components/analytics'
|
import { sendEvent } from 'components/analytics'
|
||||||
import useBlockNumber from 'lib/hooks/useBlockNumber'
|
import useBlockNumber from 'lib/hooks/useBlockNumber'
|
||||||
import ms from 'ms.macro'
|
import ms from 'ms.macro'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { useFeeTierDistributionQuery } from 'state/data/enhanced'
|
|
||||||
import { FeeTierDistributionQuery } from 'state/data/generated'
|
|
||||||
|
|
||||||
|
import useFeeTierDistributionQuery from '../graphql/FeeTierDistributionQuery'
|
||||||
import { PoolState, usePool } from './usePools'
|
import { PoolState, usePool } from './usePools'
|
||||||
|
|
||||||
// maximum number of blocks past which we consider the data stale
|
// maximum number of blocks past which we consider the data stale
|
||||||
@ -26,10 +24,7 @@ export function useFeeTierDistribution(
|
|||||||
currencyA: Currency | undefined,
|
currencyA: Currency | undefined,
|
||||||
currencyB: Currency | undefined
|
currencyB: Currency | undefined
|
||||||
): FeeTierDistribution {
|
): FeeTierDistribution {
|
||||||
const { isFetching, isLoading, isUninitialized, isError, distributions } = usePoolTVL(
|
const { isLoading, error, distributions } = usePoolTVL(currencyA?.wrapped, currencyB?.wrapped)
|
||||||
currencyA?.wrapped,
|
|
||||||
currencyB?.wrapped
|
|
||||||
)
|
|
||||||
|
|
||||||
// fetch all pool states to determine pool state
|
// fetch all pool states to determine pool state
|
||||||
const [poolStateVeryLow] = usePool(currencyA, currencyB, FeeAmount.LOWEST)
|
const [poolStateVeryLow] = usePool(currencyA, currencyB, FeeAmount.LOWEST)
|
||||||
@ -38,10 +33,10 @@ export function useFeeTierDistribution(
|
|||||||
const [poolStateHigh] = usePool(currencyA, currencyB, FeeAmount.HIGH)
|
const [poolStateHigh] = usePool(currencyA, currencyB, FeeAmount.HIGH)
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (isLoading || isFetching || isUninitialized || isError || !distributions) {
|
if (isLoading || error || !distributions) {
|
||||||
return {
|
return {
|
||||||
isLoading: isLoading || isFetching || !isUninitialized,
|
isLoading,
|
||||||
isError,
|
isError: !!error,
|
||||||
distributions,
|
distributions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,7 +48,7 @@ export function useFeeTierDistribution(
|
|||||||
|
|
||||||
const percentages =
|
const percentages =
|
||||||
!isLoading &&
|
!isLoading &&
|
||||||
!isError &&
|
!error &&
|
||||||
distributions &&
|
distributions &&
|
||||||
poolStateVeryLow !== PoolState.LOADING &&
|
poolStateVeryLow !== PoolState.LOADING &&
|
||||||
poolStateLow !== PoolState.LOADING &&
|
poolStateLow !== PoolState.LOADING &&
|
||||||
@ -72,42 +67,24 @@ export function useFeeTierDistribution(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
isError,
|
isError: !!error,
|
||||||
distributions: percentages,
|
distributions: percentages,
|
||||||
largestUsageFeeTier: largestUsageFeeTier === -1 ? undefined : largestUsageFeeTier,
|
largestUsageFeeTier: largestUsageFeeTier === -1 ? undefined : largestUsageFeeTier,
|
||||||
}
|
}
|
||||||
}, [
|
}, [isLoading, error, distributions, poolStateVeryLow, poolStateLow, poolStateMedium, poolStateHigh])
|
||||||
isLoading,
|
|
||||||
isFetching,
|
|
||||||
isUninitialized,
|
|
||||||
isError,
|
|
||||||
distributions,
|
|
||||||
poolStateVeryLow,
|
|
||||||
poolStateLow,
|
|
||||||
poolStateMedium,
|
|
||||||
poolStateHigh,
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function usePoolTVL(token0: Token | undefined, token1: Token | undefined) {
|
function usePoolTVL(token0: Token | undefined, token1: Token | undefined) {
|
||||||
const latestBlock = useBlockNumber()
|
const latestBlock = useBlockNumber()
|
||||||
|
const { isLoading, error, data } = useFeeTierDistributionQuery(token0?.address, token1?.address, ms`30s`)
|
||||||
|
|
||||||
const { isLoading, isFetching, isUninitialized, isError, data } = useFeeTierDistributionQuery(
|
const { asToken0, asToken1, _meta } = data ?? {}
|
||||||
token0 && token1 ? { token0: token0.address.toLowerCase(), token1: token1.address.toLowerCase() } : skipToken,
|
|
||||||
{
|
|
||||||
pollingInterval: ms`30s`,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const { asToken0, asToken1, _meta } = (data as FeeTierDistributionQuery) ?? {}
|
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (!latestBlock || !_meta || !asToken0 || !asToken1) {
|
if (!latestBlock || !_meta || !asToken0 || !asToken1) {
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
isFetching,
|
error,
|
||||||
isUninitialized,
|
|
||||||
isError,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +93,7 @@ function usePoolTVL(token0: Token | undefined, token1: Token | undefined) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
isFetching,
|
error,
|
||||||
isUninitialized,
|
|
||||||
isError,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,10 +152,8 @@ function usePoolTVL(token0: Token | undefined, token1: Token | undefined) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
isFetching,
|
error,
|
||||||
isUninitialized,
|
|
||||||
isError,
|
|
||||||
distributions,
|
distributions,
|
||||||
}
|
}
|
||||||
}, [_meta, asToken0, asToken1, isLoading, isError, isFetching, isUninitialized, latestBlock])
|
}, [_meta, asToken0, asToken1, isLoading, error, latestBlock])
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import { skipToken } from '@reduxjs/toolkit/query/react'
|
|
||||||
import { Currency } from '@uniswap/sdk-core'
|
import { Currency } from '@uniswap/sdk-core'
|
||||||
import { FeeAmount, nearestUsableTick, Pool, TICK_SPACINGS, tickToPrice } from '@uniswap/v3-sdk'
|
import { FeeAmount, nearestUsableTick, Pool, TICK_SPACINGS, tickToPrice } from '@uniswap/v3-sdk'
|
||||||
import { useWeb3React } from '@web3-react/core'
|
import { useWeb3React } from '@web3-react/core'
|
||||||
import { SupportedChainId } from 'constants/chains'
|
import { SupportedChainId } from 'constants/chains'
|
||||||
import { ZERO_ADDRESS } from 'constants/misc'
|
import { ZERO_ADDRESS } from 'constants/misc'
|
||||||
|
import useAllV3TicksQuery, { TickData } from 'graphql/AllV3TicksQuery'
|
||||||
import JSBI from 'jsbi'
|
import JSBI from 'jsbi'
|
||||||
import { useSingleContractMultipleData } from 'lib/hooks/multicall'
|
import { useSingleContractMultipleData } from 'lib/hooks/multicall'
|
||||||
import ms from 'ms.macro'
|
import ms from 'ms.macro'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { useAllV3TicksQuery } from 'state/data/enhanced'
|
|
||||||
import computeSurroundingTicks from 'utils/computeSurroundingTicks'
|
import computeSurroundingTicks from 'utils/computeSurroundingTicks'
|
||||||
|
|
||||||
import { V3_CORE_FACTORY_ADDRESSES } from '../constants/addresses'
|
import { V3_CORE_FACTORY_ADDRESSES } from '../constants/addresses'
|
||||||
@ -18,12 +17,6 @@ import { PoolState, usePool } from './usePools'
|
|||||||
const PRICE_FIXED_DIGITS = 8
|
const PRICE_FIXED_DIGITS = 8
|
||||||
const CHAIN_IDS_MISSING_SUBGRAPH_DATA = [SupportedChainId.ARBITRUM_ONE, SupportedChainId.ARBITRUM_RINKEBY]
|
const CHAIN_IDS_MISSING_SUBGRAPH_DATA = [SupportedChainId.ARBITRUM_ONE, SupportedChainId.ARBITRUM_RINKEBY]
|
||||||
|
|
||||||
export interface TickData {
|
|
||||||
tick: number
|
|
||||||
liquidityNet: JSBI
|
|
||||||
liquidityGross: JSBI
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tick with fields parsed to JSBIs, and active liquidity computed.
|
// Tick with fields parsed to JSBIs, and active liquidity computed.
|
||||||
export interface TickProcessed {
|
export interface TickProcessed {
|
||||||
tick: number
|
tick: number
|
||||||
@ -118,7 +111,6 @@ function useTicksFromTickLens(
|
|||||||
return {
|
return {
|
||||||
tick: tickData.tick,
|
tick: tickData.tick,
|
||||||
liquidityNet: JSBI.BigInt(tickData.liquidityNet),
|
liquidityNet: JSBI.BigInt(tickData.liquidityNet),
|
||||||
liquidityGross: JSBI.BigInt(tickData.liquidityGross),
|
|
||||||
}
|
}
|
||||||
}) ?? []),
|
}) ?? []),
|
||||||
],
|
],
|
||||||
@ -162,9 +154,7 @@ function useTicksFromSubgraph(
|
|||||||
)
|
)
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
return useAllV3TicksQuery(poolAddress ? { poolAddress: poolAddress?.toLowerCase(), skip: 0 } : skipToken, {
|
return useAllV3TicksQuery(poolAddress, 0, ms`30s`)
|
||||||
pollingInterval: ms`30s`,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetches all ticks for a given pool
|
// Fetches all ticks for a given pool
|
||||||
@ -174,10 +164,8 @@ function useAllV3Ticks(
|
|||||||
feeAmount: FeeAmount | undefined
|
feeAmount: FeeAmount | undefined
|
||||||
): {
|
): {
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
isUninitialized: boolean
|
|
||||||
isError: boolean
|
|
||||||
error: unknown
|
error: unknown
|
||||||
ticks: TickData[] | undefined
|
ticks: readonly TickData[] | undefined
|
||||||
} {
|
} {
|
||||||
const useSubgraph = currencyA ? !CHAIN_IDS_MISSING_SUBGRAPH_DATA.includes(currencyA.chainId) : true
|
const useSubgraph = currencyA ? !CHAIN_IDS_MISSING_SUBGRAPH_DATA.includes(currencyA.chainId) : true
|
||||||
|
|
||||||
@ -186,8 +174,6 @@ function useAllV3Ticks(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
isLoading: useSubgraph ? subgraphTickData.isLoading : tickLensTickData.isLoading,
|
isLoading: useSubgraph ? subgraphTickData.isLoading : tickLensTickData.isLoading,
|
||||||
isUninitialized: useSubgraph ? subgraphTickData.isUninitialized : false,
|
|
||||||
isError: useSubgraph ? subgraphTickData.isError : tickLensTickData.isError,
|
|
||||||
error: useSubgraph ? subgraphTickData.error : tickLensTickData.isError,
|
error: useSubgraph ? subgraphTickData.error : tickLensTickData.isError,
|
||||||
ticks: useSubgraph ? subgraphTickData.data?.ticks : tickLensTickData.tickData,
|
ticks: useSubgraph ? subgraphTickData.data?.ticks : tickLensTickData.tickData,
|
||||||
}
|
}
|
||||||
@ -199,8 +185,6 @@ export function usePoolActiveLiquidity(
|
|||||||
feeAmount: FeeAmount | undefined
|
feeAmount: FeeAmount | undefined
|
||||||
): {
|
): {
|
||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
isUninitialized: boolean
|
|
||||||
isError: boolean
|
|
||||||
error: any
|
error: any
|
||||||
activeTick: number | undefined
|
activeTick: number | undefined
|
||||||
data: TickProcessed[] | undefined
|
data: TickProcessed[] | undefined
|
||||||
@ -210,7 +194,7 @@ export function usePoolActiveLiquidity(
|
|||||||
// Find nearest valid tick for pool in case tick is not initialized.
|
// Find nearest valid tick for pool in case tick is not initialized.
|
||||||
const activeTick = useMemo(() => getActiveTick(pool[1]?.tickCurrent, feeAmount), [pool, feeAmount])
|
const activeTick = useMemo(() => getActiveTick(pool[1]?.tickCurrent, feeAmount), [pool, feeAmount])
|
||||||
|
|
||||||
const { isLoading, isUninitialized, isError, error, ticks } = useAllV3Ticks(currencyA, currencyB, feeAmount)
|
const { isLoading, error, ticks } = useAllV3Ticks(currencyA, currencyB, feeAmount)
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (
|
if (
|
||||||
@ -220,13 +204,10 @@ export function usePoolActiveLiquidity(
|
|||||||
pool[0] !== PoolState.EXISTS ||
|
pool[0] !== PoolState.EXISTS ||
|
||||||
!ticks ||
|
!ticks ||
|
||||||
ticks.length === 0 ||
|
ticks.length === 0 ||
|
||||||
isLoading ||
|
isLoading
|
||||||
isUninitialized
|
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
isLoading: isLoading || pool[0] === PoolState.LOADING,
|
isLoading: isLoading || pool[0] === PoolState.LOADING,
|
||||||
isUninitialized,
|
|
||||||
isError,
|
|
||||||
error,
|
error,
|
||||||
activeTick,
|
activeTick,
|
||||||
data: undefined,
|
data: undefined,
|
||||||
@ -246,8 +227,6 @@ export function usePoolActiveLiquidity(
|
|||||||
console.error('TickData pivot not found')
|
console.error('TickData pivot not found')
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
isUninitialized,
|
|
||||||
isError,
|
|
||||||
error,
|
error,
|
||||||
activeTick,
|
activeTick,
|
||||||
data: undefined,
|
data: undefined,
|
||||||
@ -269,11 +248,9 @@ export function usePoolActiveLiquidity(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
isUninitialized,
|
|
||||||
isError,
|
|
||||||
error,
|
error,
|
||||||
activeTick,
|
activeTick,
|
||||||
data: ticksProcessed,
|
data: ticksProcessed,
|
||||||
}
|
}
|
||||||
}, [currencyA, currencyB, activeTick, pool, ticks, isLoading, isUninitialized, isError, error])
|
}, [currencyA, currencyB, activeTick, pool, ticks, isLoading, error])
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import 'polyfills'
|
|||||||
import 'components/analytics'
|
import 'components/analytics'
|
||||||
|
|
||||||
import { FeatureFlagsProvider } from 'featureFlags'
|
import { FeatureFlagsProvider } from 'featureFlags'
|
||||||
|
import RelayEnvironment from 'graphql/RelayEnvironment'
|
||||||
import { BlockNumberProvider } from 'lib/hooks/useBlockNumber'
|
import { BlockNumberProvider } from 'lib/hooks/useBlockNumber'
|
||||||
import { MulticallUpdater } from 'lib/state/multicall'
|
import { MulticallUpdater } from 'lib/state/multicall'
|
||||||
import { StrictMode } from 'react'
|
import { StrictMode } from 'react'
|
||||||
@ -11,6 +12,7 @@ import { createRoot } from 'react-dom/client'
|
|||||||
import { QueryClient, QueryClientProvider } from 'react-query'
|
import { QueryClient, QueryClientProvider } from 'react-query'
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
import { HashRouter } from 'react-router-dom'
|
import { HashRouter } from 'react-router-dom'
|
||||||
|
import { RelayEnvironmentProvider } from 'relay-hooks'
|
||||||
|
|
||||||
import Blocklist from './components/Blocklist'
|
import Blocklist from './components/Blocklist'
|
||||||
import Web3Provider from './components/Web3Provider'
|
import Web3Provider from './components/Web3Provider'
|
||||||
@ -56,6 +58,7 @@ createRoot(container).render(
|
|||||||
<HashRouter>
|
<HashRouter>
|
||||||
<LanguageProvider>
|
<LanguageProvider>
|
||||||
<Web3Provider>
|
<Web3Provider>
|
||||||
|
<RelayEnvironmentProvider environment={RelayEnvironment}>
|
||||||
<Blocklist>
|
<Blocklist>
|
||||||
<BlockNumberProvider>
|
<BlockNumberProvider>
|
||||||
<Updaters />
|
<Updaters />
|
||||||
@ -65,6 +68,7 @@ createRoot(container).render(
|
|||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</BlockNumberProvider>
|
</BlockNumberProvider>
|
||||||
</Blocklist>
|
</Blocklist>
|
||||||
|
</RelayEnvironmentProvider>
|
||||||
</Web3Provider>
|
</Web3Provider>
|
||||||
</LanguageProvider>
|
</LanguageProvider>
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
|
4
src/react-app-env.d.ts
vendored
4
src/react-app-env.d.ts
vendored
@ -31,3 +31,7 @@ declare module 'multihashes' {
|
|||||||
declare module 'd3-curve-circlecorners' {
|
declare module 'd3-curve-circlecorners' {
|
||||||
declare function radius(r: number): d3.CurveFactory
|
declare function radius(r: number): d3.CurveFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module 'babel-plugin-relay/macro' {
|
||||||
|
export { graphql as default } from 'react-relay'
|
||||||
|
}
|
||||||
|
@ -2,25 +2,11 @@ import { useWeb3React } from '@web3-react/core'
|
|||||||
import useDebounce from 'hooks/useDebounce'
|
import useDebounce from 'hooks/useDebounce'
|
||||||
import useIsWindowVisible from 'hooks/useIsWindowVisible'
|
import useIsWindowVisible from 'hooks/useIsWindowVisible'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { api, CHAIN_TAG } from 'state/data/enhanced'
|
import { useAppDispatch } from 'state/hooks'
|
||||||
import { useAppDispatch, useAppSelector } from 'state/hooks'
|
|
||||||
import { supportedChainId } from 'utils/supportedChainId'
|
import { supportedChainId } from 'utils/supportedChainId'
|
||||||
|
|
||||||
import { updateChainId } from './reducer'
|
import { updateChainId } from './reducer'
|
||||||
|
|
||||||
function useQueryCacheInvalidator() {
|
|
||||||
const dispatch = useAppDispatch()
|
|
||||||
|
|
||||||
// subscribe to `chainId` changes in the redux store rather than Web3
|
|
||||||
// this will ensure that when `invalidateTags` is called, the latest
|
|
||||||
// `chainId` is available in redux to build the subgraph url
|
|
||||||
const chainId = useAppSelector((state) => state.application.chainId)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch(api.util.invalidateTags([CHAIN_TAG]))
|
|
||||||
}, [chainId, dispatch])
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Updater(): null {
|
export default function Updater(): null {
|
||||||
const { chainId, provider } = useWeb3React()
|
const { chainId, provider } = useWeb3React()
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
@ -28,8 +14,6 @@ export default function Updater(): null {
|
|||||||
|
|
||||||
const [activeChainId, setActiveChainId] = useState(chainId)
|
const [activeChainId, setActiveChainId] = useState(chainId)
|
||||||
|
|
||||||
useQueryCacheInvalidator()
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (provider && chainId && windowVisible) {
|
if (provider && chainId && windowVisible) {
|
||||||
setActiveChainId(chainId)
|
setActiveChainId(chainId)
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import { api as generatedApi } from './generated'
|
|
||||||
|
|
||||||
// tag that should be applied to queries that need to be invalidated when the chain changes
|
|
||||||
export const CHAIN_TAG = 'Chain'
|
|
||||||
|
|
||||||
// enhanced api to provide/invalidate tags
|
|
||||||
export const api = generatedApi.enhanceEndpoints({
|
|
||||||
addTagTypes: [CHAIN_TAG],
|
|
||||||
endpoints: {
|
|
||||||
allV3Ticks: {
|
|
||||||
providesTags: [CHAIN_TAG],
|
|
||||||
},
|
|
||||||
feeTierDistribution: {
|
|
||||||
providesTags: [CHAIN_TAG],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
export const { useAllV3TicksQuery, useFeeTierDistributionQuery } = api
|
|
@ -1,114 +0,0 @@
|
|||||||
import { BaseQueryFn } from '@reduxjs/toolkit/query'
|
|
||||||
import { createApi } from '@reduxjs/toolkit/query/react'
|
|
||||||
import { SupportedChainId } from 'constants/chains'
|
|
||||||
import { DocumentNode } from 'graphql'
|
|
||||||
import { ClientError, gql, GraphQLClient } from 'graphql-request'
|
|
||||||
import { AppState } from 'state'
|
|
||||||
|
|
||||||
// List of supported subgraphs. Note that the app currently only support one active subgraph at a time
|
|
||||||
const CHAIN_SUBGRAPH_URL: Record<number, string> = {
|
|
||||||
[SupportedChainId.MAINNET]: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3',
|
|
||||||
[SupportedChainId.RINKEBY]: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3',
|
|
||||||
|
|
||||||
[SupportedChainId.ARBITRUM_ONE]: 'https://api.thegraph.com/subgraphs/name/ianlapham/arbitrum-minimal',
|
|
||||||
|
|
||||||
[SupportedChainId.OPTIMISM]: 'https://api.thegraph.com/subgraphs/name/ianlapham/optimism-post-regenesis',
|
|
||||||
|
|
||||||
[SupportedChainId.POLYGON]: 'https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v3-polygon',
|
|
||||||
|
|
||||||
[SupportedChainId.CELO]: 'https://api.thegraph.com/subgraphs/name/jesse-sawa/uniswap-celo',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const api = createApi({
|
|
||||||
reducerPath: 'dataApi',
|
|
||||||
baseQuery: graphqlRequestBaseQuery(),
|
|
||||||
endpoints: (builder) => ({
|
|
||||||
allV3Ticks: builder.query({
|
|
||||||
query: ({ poolAddress, skip = 0 }) => ({
|
|
||||||
document: gql`
|
|
||||||
query allV3Ticks($poolAddress: String!, $skip: Int!) {
|
|
||||||
ticks(first: 1000, skip: $skip, where: { poolAddress: $poolAddress }, orderBy: tickIdx) {
|
|
||||||
tick: tickIdx
|
|
||||||
liquidityNet
|
|
||||||
price0
|
|
||||||
price1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
variables: {
|
|
||||||
poolAddress,
|
|
||||||
skip,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
feeTierDistribution: builder.query({
|
|
||||||
query: ({ token0, token1 }) => ({
|
|
||||||
document: gql`
|
|
||||||
query feeTierDistribution($token0: String!, $token1: String!) {
|
|
||||||
_meta {
|
|
||||||
block {
|
|
||||||
number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
asToken0: pools(
|
|
||||||
orderBy: totalValueLockedToken0
|
|
||||||
orderDirection: desc
|
|
||||||
where: { token0: $token0, token1: $token1 }
|
|
||||||
) {
|
|
||||||
feeTier
|
|
||||||
totalValueLockedToken0
|
|
||||||
totalValueLockedToken1
|
|
||||||
}
|
|
||||||
asToken1: pools(
|
|
||||||
orderBy: totalValueLockedToken0
|
|
||||||
orderDirection: desc
|
|
||||||
where: { token0: $token1, token1: $token0 }
|
|
||||||
) {
|
|
||||||
feeTier
|
|
||||||
totalValueLockedToken0
|
|
||||||
totalValueLockedToken1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
variables: {
|
|
||||||
token0,
|
|
||||||
token1,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
|
|
||||||
// Graphql query client wrapper that builds a dynamic url based on chain id
|
|
||||||
function graphqlRequestBaseQuery(): BaseQueryFn<
|
|
||||||
{ document: string | DocumentNode; variables?: any },
|
|
||||||
unknown,
|
|
||||||
Pick<ClientError, 'name' | 'message' | 'stack'>,
|
|
||||||
Partial<Pick<ClientError, 'request' | 'response'>>
|
|
||||||
> {
|
|
||||||
return async ({ document, variables }, { getState }) => {
|
|
||||||
try {
|
|
||||||
const chainId = (getState() as AppState).application.chainId
|
|
||||||
|
|
||||||
const subgraphUrl = chainId ? CHAIN_SUBGRAPH_URL[chainId] : undefined
|
|
||||||
|
|
||||||
if (!subgraphUrl) {
|
|
||||||
return {
|
|
||||||
error: {
|
|
||||||
name: 'UnsupportedChainId',
|
|
||||||
message: `Subgraph queries against ChainId ${chainId} are not supported.`,
|
|
||||||
stack: '',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { data: await new GraphQLClient(subgraphUrl).request(document, variables), meta: {} }
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof ClientError) {
|
|
||||||
const { name, message, stack, request, response } = error
|
|
||||||
return { error: { name, message, stack }, meta: { request, response } }
|
|
||||||
}
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,7 +8,6 @@ import application from './application/reducer'
|
|||||||
import burn from './burn/reducer'
|
import burn from './burn/reducer'
|
||||||
import burnV3 from './burn/v3/reducer'
|
import burnV3 from './burn/v3/reducer'
|
||||||
import connection from './connection/reducer'
|
import connection from './connection/reducer'
|
||||||
import { api as dataApi } from './data/slice'
|
|
||||||
import { updateVersion } from './global/actions'
|
import { updateVersion } from './global/actions'
|
||||||
import lists from './lists/reducer'
|
import lists from './lists/reducer'
|
||||||
import logs from './logs/slice'
|
import logs from './logs/slice'
|
||||||
@ -37,12 +36,10 @@ const store = configureStore({
|
|||||||
multicall: multicall.reducer,
|
multicall: multicall.reducer,
|
||||||
lists,
|
lists,
|
||||||
logs,
|
logs,
|
||||||
[dataApi.reducerPath]: dataApi.reducer,
|
|
||||||
[routingApi.reducerPath]: routingApi.reducer,
|
[routingApi.reducerPath]: routingApi.reducer,
|
||||||
},
|
},
|
||||||
middleware: (getDefaultMiddleware) =>
|
middleware: (getDefaultMiddleware) =>
|
||||||
getDefaultMiddleware({ thunk: true })
|
getDefaultMiddleware({ thunk: true })
|
||||||
.concat(dataApi.middleware)
|
|
||||||
.concat(routingApi.middleware)
|
.concat(routingApi.middleware)
|
||||||
.concat(save({ states: PERSISTED_KEYS, debounce: 1000 })),
|
.concat(save({ states: PERSISTED_KEYS, debounce: 1000 })),
|
||||||
preloadedState: load({ states: PERSISTED_KEYS, disableWarnings: isTestEnv() }),
|
preloadedState: load({ states: PERSISTED_KEYS, disableWarnings: isTestEnv() }),
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { Token } from '@uniswap/sdk-core'
|
import { Token } from '@uniswap/sdk-core'
|
||||||
import { tickToPrice } from '@uniswap/v3-sdk'
|
import { tickToPrice } from '@uniswap/v3-sdk'
|
||||||
import { TickData, TickProcessed } from 'hooks/usePoolTickData'
|
import { TickProcessed } from 'hooks/usePoolTickData'
|
||||||
import JSBI from 'jsbi'
|
import JSBI from 'jsbi'
|
||||||
|
|
||||||
|
import { Ticks } from '../graphql/AllV3TicksQuery'
|
||||||
|
|
||||||
const PRICE_FIXED_DIGITS = 8
|
const PRICE_FIXED_DIGITS = 8
|
||||||
|
|
||||||
// Computes the numSurroundingTicks above or below the active tick.
|
// Computes the numSurroundingTicks above or below the active tick.
|
||||||
@ -10,7 +12,7 @@ export default function computeSurroundingTicks(
|
|||||||
token0: Token,
|
token0: Token,
|
||||||
token1: Token,
|
token1: Token,
|
||||||
activeTickProcessed: TickProcessed,
|
activeTickProcessed: TickProcessed,
|
||||||
sortedTickData: TickData[],
|
sortedTickData: Ticks,
|
||||||
pivot: number,
|
pivot: number,
|
||||||
ascending: boolean
|
ascending: boolean
|
||||||
): TickProcessed[] {
|
): TickProcessed[] {
|
||||||
|
171
yarn.lock
171
yarn.lock
@ -2195,16 +2195,26 @@
|
|||||||
lodash "~4.17.0"
|
lodash "~4.17.0"
|
||||||
tslib "~2.2.0"
|
tslib "~2.2.0"
|
||||||
|
|
||||||
"@graphql-codegen/typescript-operations@^1.18.2":
|
"@graphql-codegen/plugin-helpers@^2.6.2":
|
||||||
version "1.18.2"
|
version "2.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-operations/-/typescript-operations-1.18.2.tgz#c1cba14eaf7584a875a63035f97b07fb232bcbae"
|
resolved "https://registry.yarnpkg.com/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.6.2.tgz#3c65d89fc9b61914235fc7cb14f1d48492d27944"
|
||||||
integrity sha512-AF9OCNBq0HuW3C5nsO11+53fgFGE40lNUtjSIJocvMcstEKvHx4GrzYO0XIpZsjRPrnyds00Y5xTSynLqB0XxA==
|
integrity sha512-bt5PNix0MwzWP53UdaYm6URrVMWU8RlQhrTSLFjxQ8ShS5zoTlQtpZJGZc5ONqFgKa83qbUmzXUtP8oRVVn8zw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@graphql-codegen/plugin-helpers" "^1.18.7"
|
"@graphql-tools/utils" "^8.8.0"
|
||||||
"@graphql-codegen/typescript" "^1.22.3"
|
change-case-all "1.0.14"
|
||||||
"@graphql-codegen/visitor-plugin-common" "1.21.2"
|
common-tags "1.8.2"
|
||||||
auto-bind "~4.0.0"
|
import-from "4.0.0"
|
||||||
tslib "~2.3.0"
|
lodash "~4.17.0"
|
||||||
|
tslib "~2.4.0"
|
||||||
|
|
||||||
|
"@graphql-codegen/schema-ast@^2.5.1":
|
||||||
|
version "2.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@graphql-codegen/schema-ast/-/schema-ast-2.5.1.tgz#ce030ae6de5dacd745848009ba0ca18c9c30910c"
|
||||||
|
integrity sha512-tewa5DEKbglWn7kYyVBkh3J8YQ5ALqAMVmZwiVFIGOao5u66nd+e4HuFqp0u+Jpz4SJGGi0ap/oFrEvlqLjd2A==
|
||||||
|
dependencies:
|
||||||
|
"@graphql-codegen/plugin-helpers" "^2.6.2"
|
||||||
|
"@graphql-tools/utils" "^8.8.0"
|
||||||
|
tslib "~2.4.0"
|
||||||
|
|
||||||
"@graphql-codegen/typescript-rtk-query@^1.1.1":
|
"@graphql-codegen/typescript-rtk-query@^1.1.1":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
@ -2217,16 +2227,6 @@
|
|||||||
change-case-all "1.0.14"
|
change-case-all "1.0.14"
|
||||||
tslib "~2.2.0"
|
tslib "~2.2.0"
|
||||||
|
|
||||||
"@graphql-codegen/typescript@1.22.3", "@graphql-codegen/typescript@^1.22.3":
|
|
||||||
version "1.22.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-1.22.3.tgz#aaa85246974d74a9f544a950ae1611facabea7e6"
|
|
||||||
integrity sha512-qLSnVN2g/UxxzhRWHZcHw/Xkvx5wZh0RDzmg9MjAlPnDwAI89jg/ljKDwtTOfN+F6M8W4gQ9mjkWd6NxBQRgXw==
|
|
||||||
dependencies:
|
|
||||||
"@graphql-codegen/plugin-helpers" "^1.18.7"
|
|
||||||
"@graphql-codegen/visitor-plugin-common" "1.21.2"
|
|
||||||
auto-bind "~4.0.0"
|
|
||||||
tslib "~2.3.0"
|
|
||||||
|
|
||||||
"@graphql-codegen/visitor-plugin-common@1.21.2":
|
"@graphql-codegen/visitor-plugin-common@1.21.2":
|
||||||
version "1.21.2"
|
version "1.21.2"
|
||||||
resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.21.2.tgz#c72f1f47bee2ba03ceb48abf14e2cb82d9184b32"
|
resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-1.21.2.tgz#c72f1f47bee2ba03ceb48abf14e2cb82d9184b32"
|
||||||
@ -2449,6 +2449,13 @@
|
|||||||
camel-case "4.1.2"
|
camel-case "4.1.2"
|
||||||
tslib "~2.2.0"
|
tslib "~2.2.0"
|
||||||
|
|
||||||
|
"@graphql-tools/utils@^8.8.0":
|
||||||
|
version "8.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.9.0.tgz#c6aa5f651c9c99e1aca55510af21b56ec296cdb7"
|
||||||
|
integrity sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.4.0"
|
||||||
|
|
||||||
"@graphql-tools/wrap@^7.0.4":
|
"@graphql-tools/wrap@^7.0.4":
|
||||||
version "7.0.8"
|
version "7.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-7.0.8.tgz#ad41e487135ca3ea1ae0ea04bb3f596177fb4f50"
|
resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-7.0.8.tgz#ad41e487135ca3ea1ae0ea04bb3f596177fb4f50"
|
||||||
@ -3227,6 +3234,13 @@
|
|||||||
redux-thunk "^2.4.1"
|
redux-thunk "^2.4.1"
|
||||||
reselect "^4.1.5"
|
reselect "^4.1.5"
|
||||||
|
|
||||||
|
"@restart/hooks@^0.3.1":
|
||||||
|
version "0.3.27"
|
||||||
|
resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.3.27.tgz#91f356d66d4699a8cd8b3d008402708b6a9dc505"
|
||||||
|
integrity sha512-s984xV/EapUIfkjlf8wz9weP2O9TNKR96C68FfMEy2bE69+H4cNv3RD4Mf97lW7Htt7PjZrYTjSC8f3SB9VCXw==
|
||||||
|
dependencies:
|
||||||
|
dequal "^2.0.2"
|
||||||
|
|
||||||
"@rollup/plugin-node-resolve@^7.1.1":
|
"@rollup/plugin-node-resolve@^7.1.1":
|
||||||
version "7.1.3"
|
version "7.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca"
|
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca"
|
||||||
@ -4108,6 +4122,14 @@
|
|||||||
hoist-non-react-statics "^3.3.0"
|
hoist-non-react-statics "^3.3.0"
|
||||||
redux "^4.0.0"
|
redux "^4.0.0"
|
||||||
|
|
||||||
|
"@types/react-relay@^13.0.2":
|
||||||
|
version "13.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-relay/-/react-relay-13.0.2.tgz#85ac65b13b7a67f8c75fc32dd175160c28d3cc9b"
|
||||||
|
integrity sha512-QyPV/BVKyv5/3bZKILIJYa2dM1r2HOMYNe6vuFbs/4G1uWj9RCbJiTcWFK2OxH3y70p1k9/A5gPS3lFDm0CvHQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
"@types/relay-runtime" "*"
|
||||||
|
|
||||||
"@types/react-router-dom@^5.3.3":
|
"@types/react-router-dom@^5.3.3":
|
||||||
version "5.3.3"
|
version "5.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83"
|
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83"
|
||||||
@ -4158,6 +4180,11 @@
|
|||||||
"@types/styled-system" "*"
|
"@types/styled-system" "*"
|
||||||
"@types/styled-system__css" "*"
|
"@types/styled-system__css" "*"
|
||||||
|
|
||||||
|
"@types/relay-runtime@*":
|
||||||
|
version "13.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/relay-runtime/-/relay-runtime-13.0.3.tgz#0139a02d24fd527c844af3063e943692fd181854"
|
||||||
|
integrity sha512-LZr9fiWspAtiFIMDcj/6LarYFqxd3jh3ASXULtWL5Tl5CHoDe48Il2nIAF66XKLLCG3QvDgHR8yLX6ZVWKjkkw==
|
||||||
|
|
||||||
"@types/resolve@0.0.8":
|
"@types/resolve@0.0.8":
|
||||||
version "0.0.8"
|
version "0.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
|
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
|
||||||
@ -6045,6 +6072,15 @@ babel-plugin-named-asset-import@^0.3.7:
|
|||||||
resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz#156cd55d3f1228a5765774340937afc8398067dd"
|
resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz#156cd55d3f1228a5765774340937afc8398067dd"
|
||||||
integrity sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==
|
integrity sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==
|
||||||
|
|
||||||
|
babel-plugin-relay@^14.1.0:
|
||||||
|
version "14.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-plugin-relay/-/babel-plugin-relay-14.1.0.tgz#97128dd5f53f115c7d377d732c199a53eb48a1a7"
|
||||||
|
integrity sha512-1FTe0s07fGH/urhuVDWf9IPQd1UYcdvjCPPf5ixJJkK8+3cLAtseJ6dcyk1UnBSEDodRYwWLPhVOaGQIVvj3pw==
|
||||||
|
dependencies:
|
||||||
|
babel-plugin-macros "^2.0.0"
|
||||||
|
cosmiconfig "^5.0.5"
|
||||||
|
graphql "15.3.0"
|
||||||
|
|
||||||
"babel-plugin-styled-components@>= 1.12.0":
|
"babel-plugin-styled-components@>= 1.12.0":
|
||||||
version "1.13.1"
|
version "1.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.1.tgz#5ecd28b207627c2a26ef8d5da401e9644065095a"
|
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.1.tgz#5ecd28b207627c2a26ef8d5da401e9644065095a"
|
||||||
@ -7363,11 +7399,16 @@ commander@^6.1.0:
|
|||||||
resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz"
|
resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz"
|
||||||
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
|
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
|
||||||
|
|
||||||
common-tags@1.8.0, common-tags@^1.8.0:
|
common-tags@1.8.0:
|
||||||
version "1.8.0"
|
version "1.8.0"
|
||||||
resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz"
|
resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz"
|
||||||
integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==
|
integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==
|
||||||
|
|
||||||
|
common-tags@1.8.2, common-tags@^1.8.0:
|
||||||
|
version "1.8.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6"
|
||||||
|
integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==
|
||||||
|
|
||||||
commondir@^1.0.1:
|
commondir@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||||
@ -7579,7 +7620,7 @@ cosmiconfig@7.0.0:
|
|||||||
path-type "^4.0.0"
|
path-type "^4.0.0"
|
||||||
yaml "^1.10.0"
|
yaml "^1.10.0"
|
||||||
|
|
||||||
cosmiconfig@^5.0.0:
|
cosmiconfig@^5.0.0, cosmiconfig@^5.0.5:
|
||||||
version "5.2.1"
|
version "5.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
|
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
|
||||||
integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
|
integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
|
||||||
@ -7661,7 +7702,7 @@ cross-fetch@3.1.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
node-fetch "2.6.1"
|
node-fetch "2.6.1"
|
||||||
|
|
||||||
cross-fetch@^3.0.4, cross-fetch@^3.0.6, cross-fetch@^3.1.4, cross-fetch@^3.1.5:
|
cross-fetch@^3.0.6, cross-fetch@^3.1.4, cross-fetch@^3.1.5:
|
||||||
version "3.1.5"
|
version "3.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
|
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
|
||||||
integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
|
integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
|
||||||
@ -8583,6 +8624,11 @@ dependency-graph@^0.11.0:
|
|||||||
resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27"
|
resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27"
|
||||||
integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==
|
integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==
|
||||||
|
|
||||||
|
dequal@^2.0.2:
|
||||||
|
version "2.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
|
||||||
|
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
|
||||||
|
|
||||||
des.js@^1.0.0:
|
des.js@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
|
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
|
||||||
@ -9938,18 +9984,18 @@ fbjs-css-vars@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8"
|
resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8"
|
||||||
integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==
|
integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==
|
||||||
|
|
||||||
fbjs@^3.0.0:
|
fbjs@^3.0.0, fbjs@^3.0.2:
|
||||||
version "3.0.0"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.0.tgz#0907067fb3f57a78f45d95f1eacffcacd623c165"
|
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.4.tgz#e1871c6bd3083bac71ff2da868ad5067d37716c6"
|
||||||
integrity sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==
|
integrity sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-fetch "^3.0.4"
|
cross-fetch "^3.1.5"
|
||||||
fbjs-css-vars "^1.0.0"
|
fbjs-css-vars "^1.0.0"
|
||||||
loose-envify "^1.0.0"
|
loose-envify "^1.0.0"
|
||||||
object-assign "^4.1.0"
|
object-assign "^4.1.0"
|
||||||
promise "^7.1.1"
|
promise "^7.1.1"
|
||||||
setimmediate "^1.0.5"
|
setimmediate "^1.0.5"
|
||||||
ua-parser-js "^0.7.18"
|
ua-parser-js "^0.7.30"
|
||||||
|
|
||||||
fd-slicer@~1.1.0:
|
fd-slicer@~1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
@ -10630,11 +10676,21 @@ graphql-ws@^4.4.1:
|
|||||||
resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.9.0.tgz#5cfd8bb490b35e86583d8322f5d5d099c26e365c"
|
resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.9.0.tgz#5cfd8bb490b35e86583d8322f5d5d099c26e365c"
|
||||||
integrity sha512-sHkK9+lUm20/BGawNEWNtVAeJzhZeBg21VmvmLoT5NdGVeZWv5PdIhkcayQIAgjSyyQ17WMKmbDijIPG2On+Ag==
|
integrity sha512-sHkK9+lUm20/BGawNEWNtVAeJzhZeBg21VmvmLoT5NdGVeZWv5PdIhkcayQIAgjSyyQ17WMKmbDijIPG2On+Ag==
|
||||||
|
|
||||||
|
graphql@15.3.0:
|
||||||
|
version "15.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.3.0.tgz#3ad2b0caab0d110e3be4a5a9b2aa281e362b5278"
|
||||||
|
integrity sha512-GTCJtzJmkFLWRfFJuoo9RWWa/FfamUHgiFosxi/X1Ani4AVWbeyBenZTNX6dM+7WSbbFfTo/25eh0LLkwHMw2w==
|
||||||
|
|
||||||
graphql@^15.5.0:
|
graphql@^15.5.0:
|
||||||
version "15.5.0"
|
version "15.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.0.tgz#39d19494dbe69d1ea719915b578bf920344a69d5"
|
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.0.tgz#39d19494dbe69d1ea719915b578bf920344a69d5"
|
||||||
integrity sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==
|
integrity sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==
|
||||||
|
|
||||||
|
graphql@^16.5.0:
|
||||||
|
version "16.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.5.0.tgz#41b5c1182eaac7f3d47164fb247f61e4dfb69c85"
|
||||||
|
integrity sha512-qbHgh8Ix+j/qY+a/ZcJnFQ+j8ezakqPiHwPiZhV/3PgGlgf96QMBB5/f2rkiC9sgLoy/xvT6TSiaf2nTHJh5iA==
|
||||||
|
|
||||||
growly@^1.3.0:
|
growly@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||||
@ -11106,6 +11162,11 @@ import-from@3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
resolve-from "^5.0.0"
|
resolve-from "^5.0.0"
|
||||||
|
|
||||||
|
import-from@4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/import-from/-/import-from-4.0.0.tgz#2710b8d66817d232e16f4166e319248d3d5492e2"
|
||||||
|
integrity sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==
|
||||||
|
|
||||||
import-from@^2.1.0:
|
import-from@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1"
|
resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1"
|
||||||
@ -15822,6 +15883,17 @@ react-refresh@^0.8.3:
|
|||||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
||||||
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
|
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
|
||||||
|
|
||||||
|
react-relay@^14.1.0:
|
||||||
|
version "14.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-relay/-/react-relay-14.1.0.tgz#2a2349d33ca6558543340a12b363ee2de3db06a6"
|
||||||
|
integrity sha512-U4oHb5wn1LEi17x3AcZOy66MXs83tnYbsK7/YE1/3cQKCPrXhyVUQbEOC9L7jMX659jtS1NACae+7b03bryMCQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.0.0"
|
||||||
|
fbjs "^3.0.2"
|
||||||
|
invariant "^2.2.4"
|
||||||
|
nullthrows "^1.1.1"
|
||||||
|
relay-runtime "14.1.0"
|
||||||
|
|
||||||
react-remove-scroll-bar@^2.1.0:
|
react-remove-scroll-bar@^2.1.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.2.0.tgz"
|
resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.2.0.tgz"
|
||||||
@ -16261,6 +16333,19 @@ relay-compiler@10.1.0:
|
|||||||
signedsource "^1.0.0"
|
signedsource "^1.0.0"
|
||||||
yargs "^15.3.1"
|
yargs "^15.3.1"
|
||||||
|
|
||||||
|
relay-compiler@^14.1.0:
|
||||||
|
version "14.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/relay-compiler/-/relay-compiler-14.1.0.tgz#88e9c531eb14a6a31e6f14663982124d780bd1b6"
|
||||||
|
integrity sha512-P8+CXm+Hq96z5NNwYl7hyGo5GgvMZDs9mXBRv7txUbJO4Ql9mXio3+D9EX3VfevRWTuE4ahM37i3Ssx1H604vA==
|
||||||
|
|
||||||
|
relay-hooks@^7.1.0:
|
||||||
|
version "7.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/relay-hooks/-/relay-hooks-7.1.0.tgz#884ae7d62d03236edc8199d7b63bd38ca12d8959"
|
||||||
|
integrity sha512-FhpjjjKK24gQ/FXEfpQkHzwmI55LhaDflGc7BbMaBcIJK75ZVKz/TWO1Jws3szQo3v5PMCIxQ43776qwqDk9/Q==
|
||||||
|
dependencies:
|
||||||
|
"@restart/hooks" "^0.3.1"
|
||||||
|
fbjs "^3.0.0"
|
||||||
|
|
||||||
relay-runtime@10.1.0:
|
relay-runtime@10.1.0:
|
||||||
version "10.1.0"
|
version "10.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-10.1.0.tgz#4753bf36e95e8d862cef33608e3d98b4ed730d16"
|
resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-10.1.0.tgz#4753bf36e95e8d862cef33608e3d98b4ed730d16"
|
||||||
@ -16269,6 +16354,15 @@ relay-runtime@10.1.0:
|
|||||||
"@babel/runtime" "^7.0.0"
|
"@babel/runtime" "^7.0.0"
|
||||||
fbjs "^3.0.0"
|
fbjs "^3.0.0"
|
||||||
|
|
||||||
|
relay-runtime@14.1.0:
|
||||||
|
version "14.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-14.1.0.tgz#44b317101f560a16caea2eef8a52e254b03908fa"
|
||||||
|
integrity sha512-t2DR2hZviHrdEQrOvFqwmvRWvZ0SjI/r4bS5f3qvMyXt4g1kw3RTb2RNVmbKGg6zEQhf7Na/brdqE4roApmclQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.0.0"
|
||||||
|
fbjs "^3.0.2"
|
||||||
|
invariant "^2.2.4"
|
||||||
|
|
||||||
remark-parse@^5.0.0:
|
remark-parse@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz"
|
resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz"
|
||||||
@ -18105,10 +18199,10 @@ tslib@^1.0.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
|||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||||
|
|
||||||
tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@~2.3.0:
|
tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0, tslib@~2.4.0:
|
||||||
version "2.3.1"
|
version "2.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
|
||||||
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
|
||||||
|
|
||||||
tslib@~2.0.1:
|
tslib@~2.0.1:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
@ -18125,6 +18219,11 @@ tslib@~2.2.0:
|
|||||||
resolved "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz"
|
resolved "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz"
|
||||||
integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
|
integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
|
||||||
|
|
||||||
|
tslib@~2.3.0:
|
||||||
|
version "2.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
||||||
|
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
||||||
|
|
||||||
tsutils@^3.17.1, tsutils@^3.21.0:
|
tsutils@^3.17.1, tsutils@^3.21.0:
|
||||||
version "3.21.0"
|
version "3.21.0"
|
||||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
|
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
|
||||||
@ -18254,10 +18353,10 @@ typical@^2.6.0, typical@^2.6.1:
|
|||||||
resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d"
|
resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d"
|
||||||
integrity sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=
|
integrity sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=
|
||||||
|
|
||||||
ua-parser-js@^0.7.18, ua-parser-js@^0.7.28:
|
ua-parser-js@^0.7.28, ua-parser-js@^0.7.30:
|
||||||
version "0.7.28"
|
version "0.7.31"
|
||||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.28.tgz#8ba04e653f35ce210239c64661685bf9121dec31"
|
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6"
|
||||||
integrity sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==
|
integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==
|
||||||
|
|
||||||
uint8arrays@^2.1.3:
|
uint8arrays@^2.1.3:
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
|
Loading…
Reference in New Issue
Block a user