73 lines
3.0 KiB
TypeScript
73 lines
3.0 KiB
TypeScript
|
import { Currency, Token } from '@uniswap/sdk-core'
|
||
|
import { useMemo } from 'react'
|
||
|
|
||
|
import { ADDITIONAL_BASES, BASES_TO_CHECK_TRADES_AGAINST, CUSTOM_BASES } from '../constants/routing'
|
||
|
|
||
|
export function useAllCurrencyCombinations(currencyA?: Currency, currencyB?: Currency): [Token, Token][] {
|
||
|
const chainId = currencyA?.chainId
|
||
|
|
||
|
const [tokenA, tokenB] = chainId ? [currencyA?.wrapped, currencyB?.wrapped] : [undefined, undefined]
|
||
|
|
||
|
const bases: Token[] = useMemo(() => {
|
||
|
if (!chainId || chainId !== tokenB?.chainId) return []
|
||
|
|
||
|
const common = BASES_TO_CHECK_TRADES_AGAINST[chainId] ?? []
|
||
|
const additionalA = tokenA ? ADDITIONAL_BASES[chainId]?.[tokenA.address] ?? [] : []
|
||
|
const additionalB = tokenB ? ADDITIONAL_BASES[chainId]?.[tokenB.address] ?? [] : []
|
||
|
|
||
|
return [...common, ...additionalA, ...additionalB]
|
||
|
}, [chainId, tokenA, tokenB])
|
||
|
|
||
|
const basePairs: [Token, Token][] = useMemo(
|
||
|
() =>
|
||
|
bases
|
||
|
.flatMap((base): [Token, Token][] => bases.map((otherBase) => [base, otherBase]))
|
||
|
// though redundant with the first filter below, that expression runs more often, so this is probably worthwhile
|
||
|
.filter(([t0, t1]) => !t0.equals(t1)),
|
||
|
[bases]
|
||
|
)
|
||
|
|
||
|
return useMemo(
|
||
|
() =>
|
||
|
tokenA && tokenB
|
||
|
? [
|
||
|
// the direct pair
|
||
|
[tokenA, tokenB] as [Token, Token],
|
||
|
// token A against all bases
|
||
|
...bases.map((base): [Token, Token] => [tokenA, base]),
|
||
|
// token B against all bases
|
||
|
...bases.map((base): [Token, Token] => [tokenB, base]),
|
||
|
// each base against all bases
|
||
|
...basePairs,
|
||
|
]
|
||
|
// filter out invalid pairs comprised of the same asset (e.g. WETH<>WETH)
|
||
|
.filter(([t0, t1]) => !t0.equals(t1))
|
||
|
// filter out duplicate pairs
|
||
|
.filter(([t0, t1], i, otherPairs) => {
|
||
|
// find the first index in the array at which there are the same 2 tokens as the current
|
||
|
const firstIndexInOtherPairs = otherPairs.findIndex(([t0Other, t1Other]) => {
|
||
|
return (t0.equals(t0Other) && t1.equals(t1Other)) || (t0.equals(t1Other) && t1.equals(t0Other))
|
||
|
})
|
||
|
// only accept the first occurrence of the same 2 tokens
|
||
|
return firstIndexInOtherPairs === i
|
||
|
})
|
||
|
// optionally filter out some pairs for tokens with custom bases defined
|
||
|
.filter(([tokenA, tokenB]) => {
|
||
|
if (!chainId) return true
|
||
|
const customBases = CUSTOM_BASES[chainId]
|
||
|
|
||
|
const customBasesA: Token[] | undefined = customBases?.[tokenA.address]
|
||
|
const customBasesB: Token[] | undefined = customBases?.[tokenB.address]
|
||
|
|
||
|
if (!customBasesA && !customBasesB) return true
|
||
|
|
||
|
if (customBasesA && !customBasesA.find((base) => tokenB.equals(base))) return false
|
||
|
if (customBasesB && !customBasesB.find((base) => tokenA.equals(base))) return false
|
||
|
|
||
|
return true
|
||
|
})
|
||
|
: [],
|
||
|
[tokenA, tokenB, bases, basePairs, chainId]
|
||
|
)
|
||
|
}
|