uniswap-interface-uncensored/src/hooks/useAllV3Routes.ts

78 lines
2.4 KiB
TypeScript
Raw Normal View History

2021-05-20 19:21:40 +03:00
import { Currency } from '@uniswap/sdk-core'
2021-04-25 01:43:57 +03:00
import { Pool, Route } from '@uniswap/v3-sdk'
import { useMemo } from 'react'
import { useUserSingleHopOnly } from '../state/user/hooks'
import { useActiveWeb3React } from './web3'
2021-04-25 01:43:57 +03:00
import { useV3SwapPools } from './useV3SwapPools'
/**
* Returns true if poolA is equivalent to poolB
* @param poolA one of the two pools
* @param poolB the other pool
*/
function poolEquals(poolA: Pool, poolB: Pool): boolean {
return (
poolA === poolB ||
(poolA.token0.equals(poolB.token0) && poolA.token1.equals(poolB.token1) && poolA.fee === poolB.fee)
)
}
2021-04-25 01:43:57 +03:00
function computeAllRoutes(
currencyIn: Currency,
currencyOut: Currency,
pools: Pool[],
2021-05-20 19:21:40 +03:00
chainId: number,
2021-04-25 01:43:57 +03:00
currentPath: Pool[] = [],
allPaths: Route<Currency, Currency>[] = [],
2021-04-25 01:43:57 +03:00
startCurrencyIn: Currency = currencyIn,
maxHops = 2
): Route<Currency, Currency>[] {
2021-05-20 19:21:40 +03:00
const tokenIn = currencyIn?.wrapped
const tokenOut = currencyOut?.wrapped
if (!tokenIn || !tokenOut) throw new Error('Missing tokenIn/tokenOut')
2021-04-25 01:43:57 +03:00
for (const pool of pools) {
if (!pool.involvesToken(tokenIn) || currentPath.find((pathPool) => poolEquals(pool, pathPool))) continue
2021-04-25 01:43:57 +03:00
const outputToken = pool.token0.equals(tokenIn) ? pool.token1 : pool.token0
if (outputToken.equals(tokenOut)) {
allPaths.push(new Route([...currentPath, pool], startCurrencyIn, currencyOut))
} else if (maxHops > 1) {
computeAllRoutes(
outputToken,
currencyOut,
pools,
chainId,
[...currentPath, pool],
allPaths,
startCurrencyIn,
maxHops - 1
)
}
}
return allPaths
}
/**
* Returns all the routes from an input currency to an output currency
* @param currencyIn the input currency
* @param currencyOut the output currency
*/
export function useAllV3Routes(
currencyIn?: Currency,
currencyOut?: Currency
): { loading: boolean; routes: Route<Currency, Currency>[] } {
2021-04-25 01:43:57 +03:00
const { chainId } = useActiveWeb3React()
2021-04-26 20:17:37 +03:00
const { pools, loading: poolsLoading } = useV3SwapPools(currencyIn, currencyOut)
2021-04-25 01:43:57 +03:00
const [singleHopOnly] = useUserSingleHopOnly()
2021-04-25 01:43:57 +03:00
return useMemo(() => {
2021-04-26 20:17:37 +03:00
if (poolsLoading || !chainId || !pools || !currencyIn || !currencyOut) return { loading: true, routes: [] }
2021-04-25 01:43:57 +03:00
const routes = computeAllRoutes(currencyIn, currencyOut, pools, chainId, [], [], currencyIn, singleHopOnly ? 1 : 2)
2021-04-26 20:17:37 +03:00
return { loading: false, routes }
}, [chainId, currencyIn, currencyOut, pools, poolsLoading, singleHopOnly])
2021-04-25 01:43:57 +03:00
}