fix: isolate infura (#3241)

* fix: rm infura urls from lib

* fix: use passed providers for client SOR

* fix: clean up supported chain ids

* nit: rename params with specificity

* fix: use public rpc urls for l2

* fix: special-case rpc urls
This commit is contained in:
Zach Pomerantz 2022-02-07 10:12:45 -08:00 committed by GitHub
parent 96a122d7b8
commit c595ba951b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 130 additions and 150 deletions

@ -264,9 +264,7 @@ export default function Header() {
const { const {
infoLink, infoLink,
addNetworkInfo: { nativeCurrency: { symbol: nativeCurrencySymbol },
nativeCurrency: { symbol: nativeCurrencySymbol },
},
} = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET] } = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
return ( return (

@ -2,7 +2,7 @@
import { t, Trans } from '@lingui/macro' import { t, Trans } from '@lingui/macro'
import { Percent } from '@uniswap/sdk-core' import { Percent } from '@uniswap/sdk-core'
import useActiveWeb3React from 'hooks/useActiveWeb3React' import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'lib/hooks/routing/clientSideSmartOrderRouter/constants' import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import { useContext, useRef, useState } from 'react' import { useContext, useRef, useState } from 'react'
import { Settings, X } from 'react-feather' import { Settings, X } from 'react-feather'
import ReactGA from 'react-ga' import ReactGA from 'react-ga'

@ -4,8 +4,8 @@ import { InjectedConnector } from '@web3-react/injected-connector'
import { PortisConnector } from '@web3-react/portis-connector' import { PortisConnector } from '@web3-react/portis-connector'
import { WalletConnectConnector } from '@web3-react/walletconnect-connector' import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
import { WalletLinkConnector } from '@web3-react/walletlink-connector' import { WalletLinkConnector } from '@web3-react/walletlink-connector'
import { INFURA_NETWORK_URLS } from 'constants/chainInfo'
import { ALL_SUPPORTED_CHAIN_IDS, SupportedChainId } from 'constants/chains' import { ALL_SUPPORTED_CHAIN_IDS, SupportedChainId } from 'constants/chains'
import { INFURA_NETWORK_URLS } from 'constants/infura'
import UNISWAP_LOGO_URL from '../assets/svg/logo.svg' import UNISWAP_LOGO_URL from '../assets/svg/logo.svg'
import getLibrary from '../utils/getLibrary' import getLibrary from '../utils/getLibrary'

@ -7,40 +7,6 @@ import polygonMaticLogo from '../assets/svg/polygon-matic-logo.svg'
import { SupportedChainId, SupportedL1ChainId, SupportedL2ChainId } from './chains' import { SupportedChainId, SupportedL1ChainId, SupportedL2ChainId } from './chains'
import { ARBITRUM_LIST, OPTIMISM_LIST } from './lists' import { ARBITRUM_LIST, OPTIMISM_LIST } from './lists'
const INFURA_KEY = process.env.REACT_APP_INFURA_KEY
if (typeof INFURA_KEY === 'undefined') {
throw new Error(`REACT_APP_INFURA_KEY must be a defined environment variable`)
}
/**
* These are the network URLs used by the interface when there is not another available source of chain data
*/
export const INFURA_NETWORK_URLS: { [key in SupportedChainId]: string } = {
[SupportedChainId.MAINNET]: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.RINKEBY]: `https://rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ROPSTEN]: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.GOERLI]: `https://goerli.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.KOVAN]: `https://kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.OPTIMISM]: `https://optimism-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.OPTIMISTIC_KOVAN]: `https://optimism-kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ARBITRUM_ONE]: `https://arbitrum-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ARBITRUM_RINKEBY]: `https://arbitrum-rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON]: `https://polygon-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON_MUMBAI]: `https://polygon-mumbai.infura.io/v3/${INFURA_KEY}`,
}
/**
* This is used to call the add network RPC
*/
interface AddNetworkInfo {
readonly rpcUrl: string
readonly nativeCurrency: {
name: string // e.g. 'Goerli ETH',
symbol: string // e.g. 'gorETH',
decimals: number // e.g. 18,
}
}
export enum NetworkType { export enum NetworkType {
L1, L1,
L2, L2,
@ -56,7 +22,11 @@ interface BaseChainInfo {
readonly logoUrl: string readonly logoUrl: string
readonly label: string readonly label: string
readonly helpCenterUrl?: string readonly helpCenterUrl?: string
readonly addNetworkInfo: AddNetworkInfo readonly nativeCurrency: {
name: string // e.g. 'Goerli ETH',
symbol: string // e.g. 'gorETH',
decimals: number // e.g. 18,
}
} }
export interface L1ChainInfo extends BaseChainInfo { export interface L1ChainInfo extends BaseChainInfo {
@ -83,10 +53,7 @@ export const CHAIN_INFO: ChainInfoMap = {
infoLink: 'https://info.uniswap.org/#/', infoLink: 'https://info.uniswap.org/#/',
label: 'Ethereum', label: 'Ethereum',
logoUrl: ethereumLogoUrl, logoUrl: ethereumLogoUrl,
addNetworkInfo: { nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.MAINNET],
},
}, },
[SupportedChainId.RINKEBY]: { [SupportedChainId.RINKEBY]: {
networkType: NetworkType.L1, networkType: NetworkType.L1,
@ -95,10 +62,7 @@ export const CHAIN_INFO: ChainInfoMap = {
infoLink: 'https://info.uniswap.org/#/', infoLink: 'https://info.uniswap.org/#/',
label: 'Rinkeby', label: 'Rinkeby',
logoUrl: ethereumLogoUrl, logoUrl: ethereumLogoUrl,
addNetworkInfo: { nativeCurrency: { name: 'Rinkeby Ether', symbol: 'rETH', decimals: 18 },
nativeCurrency: { name: 'Rinkeby Ether', symbol: 'rETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.RINKEBY],
},
}, },
[SupportedChainId.ROPSTEN]: { [SupportedChainId.ROPSTEN]: {
networkType: NetworkType.L1, networkType: NetworkType.L1,
@ -107,10 +71,7 @@ export const CHAIN_INFO: ChainInfoMap = {
infoLink: 'https://info.uniswap.org/#/', infoLink: 'https://info.uniswap.org/#/',
label: 'Ropsten', label: 'Ropsten',
logoUrl: ethereumLogoUrl, logoUrl: ethereumLogoUrl,
addNetworkInfo: { nativeCurrency: { name: 'Ropsten Ether', symbol: 'ropETH', decimals: 18 },
nativeCurrency: { name: 'Ropsten Ether', symbol: 'ropETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.ROPSTEN],
},
}, },
[SupportedChainId.KOVAN]: { [SupportedChainId.KOVAN]: {
networkType: NetworkType.L1, networkType: NetworkType.L1,
@ -119,10 +80,7 @@ export const CHAIN_INFO: ChainInfoMap = {
infoLink: 'https://info.uniswap.org/#/', infoLink: 'https://info.uniswap.org/#/',
label: 'Kovan', label: 'Kovan',
logoUrl: ethereumLogoUrl, logoUrl: ethereumLogoUrl,
addNetworkInfo: { nativeCurrency: { name: 'Kovan Ether', symbol: 'kovETH', decimals: 18 },
nativeCurrency: { name: 'Kovan Ether', symbol: 'kovETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.KOVAN],
},
}, },
[SupportedChainId.GOERLI]: { [SupportedChainId.GOERLI]: {
networkType: NetworkType.L1, networkType: NetworkType.L1,
@ -131,10 +89,7 @@ export const CHAIN_INFO: ChainInfoMap = {
infoLink: 'https://info.uniswap.org/#/', infoLink: 'https://info.uniswap.org/#/',
label: 'Görli', label: 'Görli',
logoUrl: ethereumLogoUrl, logoUrl: ethereumLogoUrl,
addNetworkInfo: { nativeCurrency: { name: 'Görli Ether', symbol: 'görETH', decimals: 18 },
nativeCurrency: { name: 'Görli Ether', symbol: 'görETH', decimals: 18 },
rpcUrl: INFURA_NETWORK_URLS[SupportedChainId.GOERLI],
},
}, },
[SupportedChainId.OPTIMISM]: { [SupportedChainId.OPTIMISM]: {
networkType: NetworkType.L2, networkType: NetworkType.L2,
@ -148,10 +103,7 @@ export const CHAIN_INFO: ChainInfoMap = {
logoUrl: optimismLogoUrl, logoUrl: optimismLogoUrl,
statusPage: 'https://optimism.io/status', statusPage: 'https://optimism.io/status',
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137778-uniswap-on-optimistic-ethereum-oξ', helpCenterUrl: 'https://help.uniswap.org/en/collections/3137778-uniswap-on-optimistic-ethereum-oξ',
addNetworkInfo: { nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrl: 'https://mainnet.optimism.io',
},
}, },
[SupportedChainId.OPTIMISTIC_KOVAN]: { [SupportedChainId.OPTIMISTIC_KOVAN]: {
networkType: NetworkType.L2, networkType: NetworkType.L2,
@ -165,10 +117,7 @@ export const CHAIN_INFO: ChainInfoMap = {
logoUrl: optimismLogoUrl, logoUrl: optimismLogoUrl,
statusPage: 'https://optimism.io/status', statusPage: 'https://optimism.io/status',
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137778-uniswap-on-optimistic-ethereum-oξ', helpCenterUrl: 'https://help.uniswap.org/en/collections/3137778-uniswap-on-optimistic-ethereum-oξ',
addNetworkInfo: { nativeCurrency: { name: 'Optimistic Kovan Ether', symbol: 'kovOpETH', decimals: 18 },
nativeCurrency: { name: 'Optimistic Kovan Ether', symbol: 'kovOpETH', decimals: 18 },
rpcUrl: 'https://kovan.optimism.io',
},
}, },
[SupportedChainId.ARBITRUM_ONE]: { [SupportedChainId.ARBITRUM_ONE]: {
networkType: NetworkType.L2, networkType: NetworkType.L2,
@ -181,10 +130,7 @@ export const CHAIN_INFO: ChainInfoMap = {
logoUrl: arbitrumLogoUrl, logoUrl: arbitrumLogoUrl,
defaultListUrl: ARBITRUM_LIST, defaultListUrl: ARBITRUM_LIST,
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137787-uniswap-on-arbitrum', helpCenterUrl: 'https://help.uniswap.org/en/collections/3137787-uniswap-on-arbitrum',
addNetworkInfo: { nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrl: 'https://arb1.arbitrum.io/rpc',
},
}, },
[SupportedChainId.ARBITRUM_RINKEBY]: { [SupportedChainId.ARBITRUM_RINKEBY]: {
networkType: NetworkType.L2, networkType: NetworkType.L2,
@ -197,10 +143,7 @@ export const CHAIN_INFO: ChainInfoMap = {
logoUrl: arbitrumLogoUrl, logoUrl: arbitrumLogoUrl,
defaultListUrl: ARBITRUM_LIST, defaultListUrl: ARBITRUM_LIST,
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137787-uniswap-on-arbitrum', helpCenterUrl: 'https://help.uniswap.org/en/collections/3137787-uniswap-on-arbitrum',
addNetworkInfo: { nativeCurrency: { name: 'Rinkeby Arbitrum Ether', symbol: 'rinkArbETH', decimals: 18 },
nativeCurrency: { name: 'Rinkeby Arbitrum Ether', symbol: 'rinkArbETH', decimals: 18 },
rpcUrl: 'https://rinkeby.arbitrum.io/rpc',
},
}, },
[SupportedChainId.POLYGON]: { [SupportedChainId.POLYGON]: {
networkType: NetworkType.L1, networkType: NetworkType.L1,
@ -211,10 +154,7 @@ export const CHAIN_INFO: ChainInfoMap = {
infoLink: 'https://info.uniswap.org/#/polygon/', infoLink: 'https://info.uniswap.org/#/polygon/',
label: 'Polygon', label: 'Polygon',
logoUrl: polygonMaticLogo, logoUrl: polygonMaticLogo,
addNetworkInfo: { nativeCurrency: { name: 'Polygon Matic', symbol: 'MATIC', decimals: 18 },
rpcUrl: 'https://polygon-rpc.com/',
nativeCurrency: { name: 'Polygon Matic', symbol: 'MATIC', decimals: 18 },
},
}, },
[SupportedChainId.POLYGON_MUMBAI]: { [SupportedChainId.POLYGON_MUMBAI]: {
networkType: NetworkType.L1, networkType: NetworkType.L1,
@ -225,9 +165,6 @@ export const CHAIN_INFO: ChainInfoMap = {
infoLink: 'https://info.uniswap.org/#/polygon/', infoLink: 'https://info.uniswap.org/#/polygon/',
label: 'Polygon Mumbai', label: 'Polygon Mumbai',
logoUrl: polygonMaticLogo, logoUrl: polygonMaticLogo,
addNetworkInfo: { nativeCurrency: { name: 'Polygon Mumbai Matic', symbol: 'mMATIC', decimals: 18 },
nativeCurrency: { name: 'Polygon Mumbai Matic', symbol: 'mMATIC', decimals: 18 },
rpcUrl: 'https://rpc-endpoints.superfluid.dev/mumbai',
},
}, },
} }

23
src/constants/infura.ts Normal file

@ -0,0 +1,23 @@
import { SupportedChainId } from './chains'
const INFURA_KEY = process.env.REACT_APP_INFURA_KEY
if (typeof INFURA_KEY === 'undefined') {
throw new Error(`REACT_APP_INFURA_KEY must be a defined environment variable`)
}
/**
* These are the network URLs used by the interface when there is not another available source of chain data
*/
export const INFURA_NETWORK_URLS: { [key in SupportedChainId]: string } = {
[SupportedChainId.MAINNET]: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.RINKEBY]: `https://rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ROPSTEN]: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.GOERLI]: `https://goerli.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.KOVAN]: `https://kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.OPTIMISM]: `https://optimism-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.OPTIMISTIC_KOVAN]: `https://optimism-kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ARBITRUM_ONE]: `https://arbitrum-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ARBITRUM_RINKEBY]: `https://arbitrum-rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON]: `https://polygon-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON_MUMBAI]: `https://polygon-mumbai.infura.io/v3/${INFURA_KEY}`,
}

@ -1,5 +1,5 @@
import useActiveWeb3React from 'hooks/useActiveWeb3React' import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'lib/hooks/routing/clientSideSmartOrderRouter/constants' import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'lib/hooks/routing/clientSideSmartOrderRouter'
export default function useAutoRouterSupported(): boolean { export default function useAutoRouterSupported(): boolean {
const { chainId } = useActiveWeb3React() const { chainId } = useActiveWeb3React()

@ -73,4 +73,4 @@ ReactDOM.render(
if (process.env.REACT_APP_SERVICE_WORKER !== 'false') { if (process.env.REACT_APP_SERVICE_WORKER !== 'false') {
serviceWorkerRegistration.register() serviceWorkerRegistration.register()
} }
export { INFURA_NETWORK_URLS } from 'constants/chainInfo' export { INFURA_NETWORK_URLS } from 'constants/infura'

@ -1,7 +1,7 @@
import { initializeConnector } from '@widgets/web3-react/core' import { initializeConnector } from '@widgets/web3-react/core'
import { MetaMask } from '@widgets/web3-react/metamask' import { MetaMask } from '@widgets/web3-react/metamask'
import { INFURA_NETWORK_URLS } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains' import { SupportedChainId } from 'constants/chains'
import { INFURA_NETWORK_URLS } from 'constants/infura'
import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from 'constants/locales' import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from 'constants/locales'
import Widget from 'lib/components/Widget' import Widget from 'lib/components/Widget'
import { darkTheme, defaultTheme, lightTheme } from 'lib/theme' import { darkTheme, defaultTheme, lightTheme } from 'lib/theme'

@ -1,13 +1,10 @@
import { Protocol } from '@uniswap/router-sdk'
import { BigintIsh, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core' import { BigintIsh, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core'
import { AlphaRouter, AlphaRouterConfig, ChainId } from '@uniswap/smart-order-router' import { AlphaRouter, AlphaRouterConfig, AlphaRouterParams, ChainId } from '@uniswap/smart-order-router'
import JSBI from 'jsbi' import JSBI from 'jsbi'
import { GetQuoteResult } from 'state/routing/types' import { GetQuoteResult } from 'state/routing/types'
import { transformSwapRouteToGetQuoteResult } from 'utils/transformSwapRouteToGetQuoteResult' import { transformSwapRouteToGetQuoteResult } from 'utils/transformSwapRouteToGetQuoteResult'
import { buildDependencies } from './dependencies' export const AUTO_ROUTER_SUPPORTED_CHAINS: ChainId[] = Object.values(ChainId) as number[]
const routerParamsByChain = buildDependencies()
async function getQuote( async function getQuote(
{ {
@ -23,14 +20,10 @@ async function getQuote(
tokenOut: { address: string; chainId: number; decimals: number; symbol?: string } tokenOut: { address: string; chainId: number; decimals: number; symbol?: string }
amount: BigintIsh amount: BigintIsh
}, },
alphaRouterConfig: Partial<AlphaRouterConfig> routerParams: AlphaRouterParams,
routerConfig: Partial<AlphaRouterConfig>
): Promise<{ data: GetQuoteResult; error?: unknown }> { ): Promise<{ data: GetQuoteResult; error?: unknown }> {
const params = routerParamsByChain[chainId] const router = new AlphaRouter(routerParams)
if (!params) {
throw new Error('Router dependencies not initialized.')
}
const router = new AlphaRouter(params)
const currencyIn = new Token(tokenIn.chainId, tokenIn.address, tokenIn.decimals, tokenIn.symbol) const currencyIn = new Token(tokenIn.chainId, tokenIn.address, tokenIn.decimals, tokenIn.symbol)
const currencyOut = new Token(tokenOut.chainId, tokenOut.address, tokenOut.decimals, tokenOut.symbol) const currencyOut = new Token(tokenOut.chainId, tokenOut.address, tokenOut.decimals, tokenOut.symbol)
@ -44,7 +37,7 @@ async function getQuote(
quoteCurrency, quoteCurrency,
type === 'exactIn' ? TradeType.EXACT_INPUT : TradeType.EXACT_OUTPUT, type === 'exactIn' ? TradeType.EXACT_INPUT : TradeType.EXACT_OUTPUT,
/*swapConfig=*/ undefined, /*swapConfig=*/ undefined,
alphaRouterConfig routerConfig
) )
if (!swapRoute) throw new Error('Failed to generate client side quote') if (!swapRoute) throw new Error('Failed to generate client side quote')
@ -52,8 +45,6 @@ async function getQuote(
return { data: transformSwapRouteToGetQuoteResult(type, amount, swapRoute) } return { data: transformSwapRouteToGetQuoteResult(type, amount, swapRoute) }
} }
const protocols: Protocol[] = [Protocol.V2, Protocol.V3]
interface QuoteArguments { interface QuoteArguments {
tokenInAddress: string tokenInAddress: string
tokenInChainId: ChainId tokenInChainId: ChainId
@ -67,18 +58,22 @@ interface QuoteArguments {
type: 'exactIn' | 'exactOut' type: 'exactIn' | 'exactOut'
} }
export async function getClientSideQuote({ export async function getClientSideQuote(
tokenInAddress, {
tokenInChainId, tokenInAddress,
tokenInDecimals, tokenInChainId,
tokenInSymbol, tokenInDecimals,
tokenOutAddress, tokenInSymbol,
tokenOutChainId, tokenOutAddress,
tokenOutDecimals, tokenOutChainId,
tokenOutSymbol, tokenOutDecimals,
amount, tokenOutSymbol,
type, amount,
}: QuoteArguments) { type,
}: QuoteArguments,
routerParams: AlphaRouterParams,
routerConfig: Partial<AlphaRouterConfig>
) {
return getQuote( return getQuote(
{ {
type, type,
@ -97,6 +92,7 @@ export async function getClientSideQuote({
}, },
amount, amount,
}, },
{ protocols } routerParams,
routerConfig
) )
} }

@ -1,3 +0,0 @@
import { ChainId } from '@uniswap/smart-order-router'
export const AUTO_ROUTER_SUPPORTED_CHAINS: ChainId[] = Object.values(ChainId) as number[]

@ -1,25 +0,0 @@
import { JsonRpcProvider } from '@ethersproject/providers'
import { AlphaRouterParams } from '@uniswap/smart-order-router'
import { INFURA_NETWORK_URLS } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import { AUTO_ROUTER_SUPPORTED_CHAINS } from './constants'
export type Dependencies = {
[chainId in SupportedChainId]?: AlphaRouterParams
}
/** Minimal set of dependencies for the router to work locally. */
export function buildDependencies(): Dependencies {
const dependenciesByChain: Dependencies = {}
for (const chainId of AUTO_ROUTER_SUPPORTED_CHAINS) {
const provider = new JsonRpcProvider(INFURA_NETWORK_URLS[chainId])
dependenciesByChain[chainId] = {
chainId,
provider,
}
}
return dependenciesByChain
}

@ -1,12 +1,17 @@
import { Protocol } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { useStablecoinAmountFromFiatValue } from 'hooks/useUSDCPrice' import { useStablecoinAmountFromFiatValue } from 'hooks/useUSDCPrice'
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import { GetQuoteResult, InterfaceTrade, TradeState } from 'state/routing/types' import { GetQuoteResult, InterfaceTrade, TradeState } from 'state/routing/types'
import { computeRoutes, transformRoutesToTrade } from 'state/routing/utils' import { computeRoutes, transformRoutesToTrade } from 'state/routing/utils'
import useActiveWeb3React from '../useActiveWeb3React'
import { getClientSideQuote } from './clientSideSmartOrderRouter' import { getClientSideQuote } from './clientSideSmartOrderRouter'
import { useRoutingAPIArguments } from './useRoutingAPIArguments' import { useRoutingAPIArguments } from './useRoutingAPIArguments'
const protocols: Protocol[] = [Protocol.V2, Protocol.V3]
const config = { protocols }
export default function useClientSideSmartOrderRouterTrade<TTradeType extends TradeType>( export default function useClientSideSmartOrderRouterTrade<TTradeType extends TradeType>(
tradeType: TTradeType, tradeType: TTradeType,
amountSpecified?: CurrencyAmount<Currency>, amountSpecified?: CurrencyAmount<Currency>,
@ -15,6 +20,9 @@ export default function useClientSideSmartOrderRouterTrade<TTradeType extends Tr
state: TradeState state: TradeState
trade: InterfaceTrade<Currency, Currency, TTradeType> | undefined trade: InterfaceTrade<Currency, Currency, TTradeType> | undefined
} { } {
const chainId = amountSpecified?.currency.chainId
const { library } = useActiveWeb3React()
const [currencyIn, currencyOut]: [Currency | undefined, Currency | undefined] = useMemo( const [currencyIn, currencyOut]: [Currency | undefined, Currency | undefined] = useMemo(
() => () =>
tradeType === TradeType.EXACT_INPUT tradeType === TradeType.EXACT_INPUT
@ -30,6 +38,7 @@ export default function useClientSideSmartOrderRouterTrade<TTradeType extends Tr
tradeType, tradeType,
useClientSideRouter: true, useClientSideRouter: true,
}) })
const params = useMemo(() => chainId && library && { chainId, provider: library }, [chainId, library])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [{ quoteResult, error }, setFetchedResult] = useState<{ const [{ quoteResult, error }, setFetchedResult] = useState<{
@ -47,8 +56,8 @@ export default function useClientSideSmartOrderRouterTrade<TTradeType extends Tr
async function fetchQuote() { async function fetchQuote() {
try { try {
if (queryArgs) { if (queryArgs && params) {
const result = await getClientSideQuote(queryArgs) const result = await getClientSideQuote(queryArgs, params, config)
setFetchedResult({ setFetchedResult({
quoteResult: result.data, quoteResult: result.data,
error: result.error, error: result.error,
@ -63,7 +72,7 @@ export default function useClientSideSmartOrderRouterTrade<TTradeType extends Tr
setLoading(false) setLoading(false)
} }
} }
}, [queryArgs]) }, [queryArgs, params])
const route = useMemo( const route = useMemo(
() => computeRoutes(currencyIn, currencyOut, tradeType, quoteResult), () => computeRoutes(currencyIn, currencyOut, tradeType, quoteResult),

@ -1,12 +1,27 @@
import { JsonRpcProvider } from '@ethersproject/providers'
import { createApi, fetchBaseQuery, FetchBaseQueryError } from '@reduxjs/toolkit/query/react' import { createApi, fetchBaseQuery, FetchBaseQueryError } from '@reduxjs/toolkit/query/react'
import { Protocol } from '@uniswap/router-sdk' import { Protocol } from '@uniswap/router-sdk'
import { ChainId } from '@uniswap/smart-order-router' import { ChainId } from '@uniswap/smart-order-router'
import { getClientSideQuote } from 'lib/hooks/routing/clientSideSmartOrderRouter' import { AlphaRouterParams } from '@uniswap/smart-order-router'
import { SupportedChainId } from 'constants/chains'
import { INFURA_NETWORK_URLS } from 'constants/infura'
import { AUTO_ROUTER_SUPPORTED_CHAINS, getClientSideQuote } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import ms from 'ms.macro' import ms from 'ms.macro'
import qs from 'qs' import qs from 'qs'
import { GetQuoteResult } from './types' import { GetQuoteResult } from './types'
const routerParams = AUTO_ROUTER_SUPPORTED_CHAINS.reduce<{ [chainId in SupportedChainId]?: AlphaRouterParams }>(
(params, chainId) => ({
...params,
[chainId]: {
chainId,
provider: new JsonRpcProvider(INFURA_NETWORK_URLS[chainId]),
},
}),
{}
)
const protocols: Protocol[] = [Protocol.V2, Protocol.V3] const protocols: Protocol[] = [Protocol.V2, Protocol.V3]
const DEFAULT_QUERY_PARAMS = { const DEFAULT_QUERY_PARAMS = {
@ -46,7 +61,10 @@ export const routingApi = createApi({
try { try {
if (useClientSideRouter) { if (useClientSideRouter) {
result = await getClientSideQuote(args) const chainId = args.tokenInChainId
const params = routerParams[chainId]
if (!params) throw new Error(`Router does not support this chain (chainId: ${chainId}).`)
result = await getClientSideQuote(args, params, { protocols })
} else { } else {
const query = qs.stringify({ const query = qs.stringify({
...DEFAULT_QUERY_PARAMS, ...DEFAULT_QUERY_PARAMS,

@ -3,12 +3,39 @@ import { hexStripZeros } from '@ethersproject/bytes'
import { Web3Provider } from '@ethersproject/providers' import { Web3Provider } from '@ethersproject/providers'
import { CHAIN_INFO } from 'constants/chainInfo' import { CHAIN_INFO } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains' import { SupportedChainId } from 'constants/chains'
import { INFURA_NETWORK_URLS } from 'constants/infura'
interface SwitchNetworkArguments { interface SwitchNetworkArguments {
library: Web3Provider library: Web3Provider
chainId: SupportedChainId chainId: SupportedChainId
} }
function getRpcUrls(chainId: SupportedChainId): [string] {
switch (chainId) {
case SupportedChainId.MAINNET:
case SupportedChainId.RINKEBY:
case SupportedChainId.ROPSTEN:
case SupportedChainId.KOVAN:
case SupportedChainId.GOERLI:
return [INFURA_NETWORK_URLS[chainId]]
case SupportedChainId.OPTIMISM:
return ['https://mainnet.optimism.io']
case SupportedChainId.OPTIMISTIC_KOVAN:
return ['https://kovan.optimism.io']
case SupportedChainId.ARBITRUM_ONE:
return ['https://arb1.arbitrum.io/rpc']
case SupportedChainId.ARBITRUM_RINKEBY:
return ['https://rinkeby.arbitrum.io/rpc']
case SupportedChainId.POLYGON:
return ['https://polygon-rpc.com/']
case SupportedChainId.POLYGON_MUMBAI:
return ['https://rpc-endpoints.superfluid.dev/mumbai']
default:
}
// Our API-keyed URLs will fail security checks when used with external wallets.
throw new Error('RPC URLs must use public endpoints')
}
// provider.request returns Promise<any>, but wallet_switchEthereumChain must return null or throw // provider.request returns Promise<any>, but wallet_switchEthereumChain must return null or throw
// see https://github.com/rekmarks/EIPs/blob/3326-create/EIPS/eip-3326.md for more info on wallet_switchEthereumChain // see https://github.com/rekmarks/EIPs/blob/3326-create/EIPS/eip-3326.md for more info on wallet_switchEthereumChain
export async function switchToNetwork({ library, chainId }: SwitchNetworkArguments): Promise<null | void> { export async function switchToNetwork({ library, chainId }: SwitchNetworkArguments): Promise<null | void> {
@ -32,8 +59,8 @@ export async function switchToNetwork({ library, chainId }: SwitchNetworkArgumen
{ {
chainId: formattedChainId, chainId: formattedChainId,
chainName: info.label, chainName: info.label,
rpcUrls: [info.addNetworkInfo.rpcUrl], rpcUrls: getRpcUrls(chainId),
nativeCurrency: info.addNetworkInfo.nativeCurrency, nativeCurrency: info.nativeCurrency,
blockExplorerUrls: [info.explorer], blockExplorerUrls: [info.explorer],
}, },
], ],