e81e8a8f71
* Revert "Revert "Merge branch 'main' of https://github.com/Uniswap/interface" (#2912)" This reverts commit 7d343dcfbdf75a2f91d28cefce84e4b1bace7b87. * Revert "deleted files" This reverts commit 097b8361d4c09afd3cb681c4622145c555ced884.
136 lines
4.1 KiB
TypeScript
136 lines
4.1 KiB
TypeScript
import { skipToken } from '@reduxjs/toolkit/query/react'
|
|
import { Currency } from '@uniswap/sdk-core'
|
|
import { FeeAmount, Pool, TICK_SPACINGS, tickToPrice } from '@uniswap/v3-sdk'
|
|
import JSBI from 'jsbi'
|
|
import ms from 'ms.macro'
|
|
import { useMemo } from 'react'
|
|
import { useAllV3TicksQuery } from 'state/data/enhanced'
|
|
import { AllV3TicksQuery } from 'state/data/generated'
|
|
import computeSurroundingTicks from 'utils/computeSurroundingTicks'
|
|
|
|
import { PoolState, usePool } from './usePools'
|
|
|
|
const PRICE_FIXED_DIGITS = 8
|
|
|
|
// Tick with fields parsed to JSBIs, and active liquidity computed.
|
|
export interface TickProcessed {
|
|
tickIdx: number
|
|
liquidityActive: JSBI
|
|
liquidityNet: JSBI
|
|
price0: string
|
|
}
|
|
|
|
const getActiveTick = (tickCurrent: number | undefined, feeAmount: FeeAmount | undefined) =>
|
|
tickCurrent && feeAmount ? Math.floor(tickCurrent / TICK_SPACINGS[feeAmount]) * TICK_SPACINGS[feeAmount] : undefined
|
|
|
|
// Fetches all ticks for a given pool
|
|
export function useAllV3Ticks(
|
|
currencyA: Currency | undefined,
|
|
currencyB: Currency | undefined,
|
|
feeAmount: FeeAmount | undefined
|
|
) {
|
|
const poolAddress =
|
|
currencyA && currencyB && feeAmount ? Pool.getAddress(currencyA?.wrapped, currencyB?.wrapped, feeAmount) : undefined
|
|
|
|
const { isLoading, isError, error, isUninitialized, data } = useAllV3TicksQuery(
|
|
poolAddress ? { poolAddress: poolAddress?.toLowerCase(), skip: 0 } : skipToken,
|
|
{
|
|
pollingInterval: ms`30s`,
|
|
}
|
|
)
|
|
|
|
return {
|
|
isLoading,
|
|
isUninitialized,
|
|
isError,
|
|
error,
|
|
ticks: data?.ticks as AllV3TicksQuery['ticks'],
|
|
}
|
|
}
|
|
|
|
export function usePoolActiveLiquidity(
|
|
currencyA: Currency | undefined,
|
|
currencyB: Currency | undefined,
|
|
feeAmount: FeeAmount | undefined
|
|
): {
|
|
isLoading: boolean
|
|
isUninitialized: boolean
|
|
isError: boolean
|
|
error: any
|
|
activeTick: number | undefined
|
|
data: TickProcessed[] | undefined
|
|
} {
|
|
const pool = usePool(currencyA, currencyB, feeAmount)
|
|
|
|
// Find nearest valid tick for pool in case tick is not initialized.
|
|
const activeTick = useMemo(() => getActiveTick(pool[1]?.tickCurrent, feeAmount), [pool, feeAmount])
|
|
|
|
const { isLoading, isUninitialized, isError, error, ticks } = useAllV3Ticks(currencyA, currencyB, feeAmount)
|
|
|
|
return useMemo(() => {
|
|
if (
|
|
!currencyA ||
|
|
!currencyB ||
|
|
activeTick === undefined ||
|
|
pool[0] !== PoolState.EXISTS ||
|
|
!ticks ||
|
|
ticks.length === 0 ||
|
|
isLoading ||
|
|
isUninitialized
|
|
) {
|
|
return {
|
|
isLoading: isLoading || pool[0] === PoolState.LOADING,
|
|
isUninitialized,
|
|
isError,
|
|
error,
|
|
activeTick,
|
|
data: undefined,
|
|
}
|
|
}
|
|
|
|
const token0 = currencyA?.wrapped
|
|
const token1 = currencyB?.wrapped
|
|
|
|
// find where the active tick would be to partition the array
|
|
// if the active tick is initialized, the pivot will be an element
|
|
// if not, take the previous tick as pivot
|
|
const pivot = ticks.findIndex(({ tickIdx }) => tickIdx > activeTick) - 1
|
|
|
|
if (pivot < 0) {
|
|
// consider setting a local error
|
|
console.error('TickData pivot not found')
|
|
return {
|
|
isLoading,
|
|
isUninitialized,
|
|
isError,
|
|
error,
|
|
activeTick,
|
|
data: undefined,
|
|
}
|
|
}
|
|
|
|
const activeTickProcessed: TickProcessed = {
|
|
liquidityActive: JSBI.BigInt(pool[1]?.liquidity ?? 0),
|
|
tickIdx: activeTick,
|
|
liquidityNet:
|
|
Number(ticks[pivot].tickIdx) === activeTick ? JSBI.BigInt(ticks[pivot].liquidityNet) : JSBI.BigInt(0),
|
|
price0: tickToPrice(token0, token1, activeTick).toFixed(PRICE_FIXED_DIGITS),
|
|
}
|
|
|
|
const subsequentTicks = computeSurroundingTicks(token0, token1, activeTickProcessed, ticks, pivot, true)
|
|
|
|
const previousTicks = computeSurroundingTicks(token0, token1, activeTickProcessed, ticks, pivot, false)
|
|
|
|
const ticksProcessed = previousTicks.concat(activeTickProcessed).concat(subsequentTicks)
|
|
|
|
return {
|
|
isLoading,
|
|
isUninitialized,
|
|
isError,
|
|
error,
|
|
activeTick,
|
|
data: ticksProcessed,
|
|
}
|
|
}, [currencyA, currencyB, activeTick, pool, ticks, isLoading, isUninitialized, isError, error])
|
|
}
|