Commit 2d8f767d authored by Zach Pomerantz's avatar Zach Pomerantz Committed by GitHub

feat: upgrade web3-react (#3628)

* chore: upgrade web3-react

* feat: use a JsonRpcConnector

* chore: rm @ethersproject/experimental

* fix: assert Web3Provider in app

* fix: type providers more loosely

* chore: reinstall experimental for testing
parent 1303416e
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
"@babel/preset-env": "^7.16.11", "@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7", "@babel/preset-react": "^7.16.7",
"@babel/preset-typescript": "^7.16.7", "@babel/preset-typescript": "^7.16.7",
"@ethersproject/experimental": "^5.4.0",
"@gnosis.pm/safe-apps-web3-react": "^0.6.0", "@gnosis.pm/safe-apps-web3-react": "^0.6.0",
"@graphql-codegen/cli": "1.21.5", "@graphql-codegen/cli": "1.21.5",
"@graphql-codegen/typescript": "1.22.3", "@graphql-codegen/typescript": "1.22.3",
...@@ -89,8 +90,8 @@ ...@@ -89,8 +90,8 @@
"@uniswap/v2-periphery": "^1.1.0-beta.0", "@uniswap/v2-periphery": "^1.1.0-beta.0",
"@uniswap/v3-core": "1.0.0", "@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1", "@uniswap/v3-periphery": "^1.1.1",
"@web3-react/metamask": "8.0.13-beta.0", "@web3-react/metamask": "^8.0.18-beta.0",
"@web3-react/walletconnect": "8.0.18-beta.0", "@web3-react/walletconnect": "^8.0.25-beta.0",
"array.prototype.flat": "^1.2.4", "array.prototype.flat": "^1.2.4",
"array.prototype.flatmap": "^1.2.4", "array.prototype.flatmap": "^1.2.4",
"babel-plugin-macros": "^3.1.0", "babel-plugin-macros": "^3.1.0",
...@@ -193,7 +194,6 @@ ...@@ -193,7 +194,6 @@
"license": "GPL-3.0-or-later", "license": "GPL-3.0-or-later",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.17.0", "@babel/runtime": "^7.17.0",
"@ethersproject/experimental": "^5.4.0",
"@fontsource/ibm-plex-mono": "^4.5.1", "@fontsource/ibm-plex-mono": "^4.5.1",
"@fontsource/inter": "^4.5.1", "@fontsource/inter": "^4.5.1",
"@popperjs/core": "^2.4.4", "@popperjs/core": "^2.4.4",
...@@ -205,14 +205,14 @@ ...@@ -205,14 +205,14 @@
"@uniswap/token-lists": "^1.0.0-beta.27", "@uniswap/token-lists": "^1.0.0-beta.27",
"@uniswap/v2-sdk": "^3.0.1", "@uniswap/v2-sdk": "^3.0.1",
"@uniswap/v3-sdk": "^3.8.2", "@uniswap/v3-sdk": "^3.8.2",
"@web3-react/core": "8.0.17-beta.0", "@web3-react/core": "^8.0.22-beta.0",
"@web3-react/eip1193": "8.0.15-beta.0", "@web3-react/eip1193": "^8.0.17-beta.0",
"@web3-react/empty": "8.0.10-beta.0", "@web3-react/empty": "^8.0.11-beta.0",
"@web3-react/types": "8.0.10-beta.0", "@web3-react/types": "^8.0.11-beta.0",
"@web3-react/url": "8.0.12-beta.0", "@web3-react/url": "^8.0.16-beta.0",
"ajv": "^6.12.3", "ajv": "^6.12.3",
"cids": "^1.0.0", "cids": "^1.0.0",
"ethers": "^5.5.0", "ethers": "^5.1.4",
"immer": "^9.0.6", "immer": "^9.0.6",
"jotai": "^1.3.7", "jotai": "^1.3.7",
"jsbi": "^3.1.4", "jsbi": "^3.1.4",
......
...@@ -255,8 +255,8 @@ export default function NetworkSelector() { ...@@ -255,8 +255,8 @@ export default function NetworkSelector() {
const handleChainSwitch = useCallback( const handleChainSwitch = useCallback(
(targetChain: number, skipToggle?: boolean) => { (targetChain: number, skipToggle?: boolean) => {
if (!library) return if (!library?.provider) return
switchToNetwork({ library, chainId: targetChain }) switchToNetwork({ provider: library.provider, chainId: targetChain })
.then(() => { .then(() => {
if (!skipToggle) { if (!skipToggle) {
toggle() toggle()
......
...@@ -15,7 +15,7 @@ export default function useAddTokenToMetamask(currencyToAdd: Currency | undefine ...@@ -15,7 +15,7 @@ export default function useAddTokenToMetamask(currencyToAdd: Currency | undefine
const logoURL = useCurrencyLogoURIs(token)[0] const logoURL = useCurrencyLogoURIs(token)[0]
const addToken = useCallback(() => { const addToken = useCallback(() => {
if (library && library.provider.isMetaMask && library.provider.request && token) { if (library && library?.provider?.isMetaMask && library.provider.request && token) {
library.provider library.provider
.request({ .request({
method: 'wallet_watchAsset', method: 'wallet_watchAsset',
......
import { Provider as EthersProvider } from '@ethersproject/abstract-provider' import { JsonRpcProvider } from '@ethersproject/providers'
import { Provider as Eip1193Provider } from '@web3-react/types' import { Provider as Eip1193Provider } from '@web3-react/types'
import { DEFAULT_LOCALE, SupportedLocale } from 'constants/locales' import { DEFAULT_LOCALE, SupportedLocale } from 'constants/locales'
import { Provider as AtomProvider } from 'jotai' import { Provider as AtomProvider } from 'jotai'
import { TransactionsUpdater } from 'lib/hooks/transactions' import { TransactionsUpdater } from 'lib/hooks/transactions'
import { Web3Provider } from 'lib/hooks/useActiveWeb3React' import { ActiveWeb3Provider } from 'lib/hooks/useActiveWeb3React'
import { BlockUpdater } from 'lib/hooks/useBlockNumber' import { BlockUpdater } from 'lib/hooks/useBlockNumber'
import useEip1193Provider from 'lib/hooks/useEip1193Provider'
import { Provider as I18nProvider } from 'lib/i18n' import { Provider as I18nProvider } from 'lib/i18n'
import { MulticallUpdater, store as multicallStore } from 'lib/state/multicall' import { MulticallUpdater, store as multicallStore } from 'lib/state/multicall'
import styled, { keyframes, Theme, ThemeProvider } from 'lib/theme' import styled, { keyframes, Theme, ThemeProvider } from 'lib/theme'
...@@ -95,8 +94,8 @@ function Updaters() { ...@@ -95,8 +94,8 @@ function Updaters() {
export type WidgetProps = { export type WidgetProps = {
theme?: Theme theme?: Theme
locale?: SupportedLocale locale?: SupportedLocale
provider?: Eip1193Provider | EthersProvider provider?: Eip1193Provider | JsonRpcProvider
jsonRpcEndpoint?: string jsonRpcEndpoint?: string | JsonRpcProvider
width?: string | number width?: string | number
dialog?: HTMLElement | null dialog?: HTMLElement | null
className?: string className?: string
...@@ -115,7 +114,6 @@ export default function Widget(props: PropsWithChildren<WidgetProps>) { ...@@ -115,7 +114,6 @@ export default function Widget(props: PropsWithChildren<WidgetProps>) {
className, className,
onError, onError,
} = props } = props
const eip1193 = useEip1193Provider(provider)
const [dialog, setDialog] = useState<HTMLDivElement | null>(null) const [dialog, setDialog] = useState<HTMLDivElement | null>(null)
return ( return (
<StrictMode> <StrictMode>
...@@ -128,10 +126,10 @@ export default function Widget(props: PropsWithChildren<WidgetProps>) { ...@@ -128,10 +126,10 @@ export default function Widget(props: PropsWithChildren<WidgetProps>) {
<WidgetPropValidator {...props}> <WidgetPropValidator {...props}>
<ReduxProvider store={multicallStore}> <ReduxProvider store={multicallStore}>
<AtomProvider> <AtomProvider>
<Web3Provider provider={eip1193} jsonRpcEndpoint={jsonRpcEndpoint}> <ActiveWeb3Provider provider={provider} jsonRpcEndpoint={jsonRpcEndpoint}>
<Updaters /> <Updaters />
{children} {children}
</Web3Provider> </ActiveWeb3Provider>
</AtomProvider> </AtomProvider>
</ReduxProvider> </ReduxProvider>
</WidgetPropValidator> </WidgetPropValidator>
......
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { TransactionResponse, Web3Provider } from '@ethersproject/providers' import { JsonRpcProvider, TransactionResponse } from '@ethersproject/providers'
// eslint-disable-next-line no-restricted-imports // eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro' import { t, Trans } from '@lingui/macro'
import { Trade } from '@uniswap/router-sdk' import { Trade } from '@uniswap/router-sdk'
...@@ -40,7 +40,7 @@ interface FailedCall extends SwapCallEstimate { ...@@ -40,7 +40,7 @@ interface FailedCall extends SwapCallEstimate {
export default function useSendSwapTransaction( export default function useSendSwapTransaction(
account: string | null | undefined, account: string | null | undefined,
chainId: number | undefined, chainId: number | undefined,
library: Web3Provider | undefined, library: JsonRpcProvider | undefined,
trade: AnyTrade | undefined, // trade to execute, required trade: AnyTrade | undefined, // trade to execute, required
swapCalls: SwapCall[] swapCalls: SwapCall[]
): { callback: null | (() => Promise<TransactionResponse>) } { ): { callback: null | (() => Promise<TransactionResponse>) } {
......
import { getPriorityConnector, initializeConnector, Web3ReactHooks } from '@web3-react/core' import { ExternalProvider, JsonRpcProvider, Web3Provider } from '@ethersproject/providers'
import { initializeConnector, Web3ReactHooks } from '@web3-react/core'
import { EIP1193 } from '@web3-react/eip1193' import { EIP1193 } from '@web3-react/eip1193'
import { EMPTY } from '@web3-react/empty' import { EMPTY } from '@web3-react/empty'
import { Actions, Connector, Provider as Eip1193Provider } from '@web3-react/types' import { Actions, Connector, Provider as Eip1193Provider, Web3ReactStore } from '@web3-react/types'
import { Url } from '@web3-react/url' import { Url } from '@web3-react/url'
import { useAtom, WritableAtom } from 'jotai' import { useAtom, WritableAtom } from 'jotai'
import { useAtomValue } from 'jotai/utils' import { atom } from 'jotai'
import { atomWithDefault, RESET, useUpdateAtom } from 'jotai/utils' import JsonRpcConnector from 'lib/utils/JsonRpcConnector'
import { PropsWithChildren, useEffect } from 'react' import { createContext, PropsWithChildren, useContext, useEffect, useMemo } from 'react'
const [connector, hooks] = initializeConnector(() => EMPTY) type Web3ContextType = {
const EMPTY_CONNECTOR: [Connector, Web3ReactHooks] = [connector, hooks] connector: Connector
const urlConnectorAtom = atomWithDefault<[Connector, Web3ReactHooks]>(() => EMPTY_CONNECTOR) library?: (JsonRpcProvider & { provider?: ExternalProvider }) | Web3Provider
const injectedConnectorAtom = atomWithDefault<[Connector, Web3ReactHooks]>(() => EMPTY_CONNECTOR) chainId?: ReturnType<Web3ReactHooks['useChainId']>
const web3Atom = atomWithDefault<ReturnType<typeof hooks.useWeb3React>>(() => ({ accounts?: ReturnType<Web3ReactHooks['useAccounts']>
connector: EMPTY_CONNECTOR[0], account?: ReturnType<Web3ReactHooks['useAccount']>
library: undefined, active?: ReturnType<Web3ReactHooks['useIsActive']>
chainId: undefined, error?: ReturnType<Web3ReactHooks['useError']>
account: undefined, ensNames?: ReturnType<Web3ReactHooks['useENSNames']>
active: false, ensName?: ReturnType<Web3ReactHooks['useENSName']>
error: undefined, }
}))
const EMPTY_CONNECTOR = initializeConnector(() => EMPTY)
const EMPTY_CONTEXT: Web3ContextType = { connector: EMPTY }
const urlConnectorAtom = atom<[Connector, Web3ReactHooks, Web3ReactStore]>(EMPTY_CONNECTOR)
const injectedConnectorAtom = atom<[Connector, Web3ReactHooks, Web3ReactStore]>(EMPTY_CONNECTOR)
const Web3Context = createContext(EMPTY_CONTEXT)
export default function useActiveWeb3React() { export default function useActiveWeb3React() {
return useAtomValue(web3Atom) return useContext(Web3Context)
} }
function useConnector<T extends { new (actions: Actions, initializer: I): Connector }, I>( function useConnector<T extends { new (actions: Actions, initializer: I): Connector }, I>(
connectorAtom: WritableAtom<[Connector, Web3ReactHooks], typeof RESET | [Connector, Web3ReactHooks]>, connectorAtom: WritableAtom<[Connector, Web3ReactHooks, Web3ReactStore], [Connector, Web3ReactHooks, Web3ReactStore]>,
Connector: T, Connector: T,
initializer: I | undefined initializer: I | undefined
) { ) {
const [connector, setConnector] = useAtom(connectorAtom) const [connector, setConnector] = useAtom(connectorAtom)
useEffect(() => { useEffect(() => {
if (initializer) { if (initializer) {
const [connector, hooks] = initializeConnector((actions) => new Connector(actions, initializer)) const [connector, hooks, store] = initializeConnector((actions) => new Connector(actions, initializer))
connector.activate() connector.activate()
setConnector([connector, hooks]) setConnector([connector, hooks, store])
} else { } else {
setConnector(RESET) setConnector(EMPTY_CONNECTOR)
} }
}, [Connector, initializer, setConnector]) }, [Connector, initializer, setConnector])
return connector return connector
} }
interface Web3ProviderProps { interface ActiveWeb3ProviderProps {
provider?: Eip1193Provider provider?: Eip1193Provider | JsonRpcProvider
jsonRpcEndpoint?: string jsonRpcEndpoint?: string | JsonRpcProvider
} }
export function Web3Provider({ provider, jsonRpcEndpoint, children }: PropsWithChildren<Web3ProviderProps>) { export function ActiveWeb3Provider({
const injectedConnector = useConnector(injectedConnectorAtom, EIP1193, provider) provider,
jsonRpcEndpoint,
children,
}: PropsWithChildren<ActiveWeb3ProviderProps>) {
const Injected = useMemo(() => {
if (provider) {
if (JsonRpcProvider.isProvider(provider)) return JsonRpcConnector
if (JsonRpcProvider.isProvider((provider as any).provider)) {
throw new Error('Eip1193Bridge is experimental: pass your ethers Provider directly')
}
}
return EIP1193
}, [provider]) as { new (actions: Actions, initializer: typeof provider): Connector }
const injectedConnector = useConnector(injectedConnectorAtom, Injected, provider)
const urlConnector = useConnector(urlConnectorAtom, Url, jsonRpcEndpoint) const urlConnector = useConnector(urlConnectorAtom, Url, jsonRpcEndpoint)
const priorityConnector = getPriorityConnector(injectedConnector, urlConnector) const [connector, hooks] = injectedConnector[1].useIsActive() ? injectedConnector : urlConnector ?? EMPTY_CONNECTOR
const priorityProvider = priorityConnector.usePriorityProvider()
const priorityWeb3React = priorityConnector.usePriorityWeb3React(priorityProvider) const library = hooks.useProvider()
const setWeb3 = useUpdateAtom(web3Atom) const chainId = hooks.useChainId()
useEffect(() => { const accounts = hooks.useAccounts()
setWeb3(priorityWeb3React) const account = hooks.useAccount()
}, [priorityWeb3React, setWeb3]) const active = hooks.useIsActive()
const error = hooks.useError()
const ensNames = hooks.useENSNames()
const ensName = hooks.useENSName()
const web3 = useMemo(() => {
if (connector === EMPTY || !active) {
return EMPTY_CONTEXT
}
return { connector, library, chainId, accounts, account, active, error, ensNames, ensName }
}, [account, accounts, active, chainId, connector, ensName, ensNames, error, library])
// Log web3 errors to facilitate debugging. // Log web3 errors to facilitate debugging.
const error = priorityConnector.usePriorityError()
useEffect(() => { useEffect(() => {
if (error) { if (error) {
console.error('web3 error:', error) console.error('web3 error:', error)
} }
}, [error]) }, [error])
return <>{children}</> return <Web3Context.Provider value={web3}>{children}</Web3Context.Provider>
} }
import { Provider as EthersProvider } from '@ethersproject/abstract-provider'
import { VoidSigner } from '@ethersproject/abstract-signer'
import { Eip1193Bridge as ExperimentalEip1193Bridge } from '@ethersproject/experimental'
import { JsonRpcProvider, JsonRpcSigner } from '@ethersproject/providers'
import { Provider as Eip1193Provider } from '@web3-react/types'
import { ZERO_ADDRESS } from 'constants/misc'
import { useMemo } from 'react'
const voidSigner = new VoidSigner(ZERO_ADDRESS)
class Eip1193Bridge extends ExperimentalEip1193Bridge {
async send(method: string, params?: Array<any>): Promise<any> {
switch (method) {
case 'eth_chainId': {
// TODO(https://github.com/ethers-io/ethers.js/pull/2711): Returns eth_chainId as a hexadecimal.
const result = await this.provider.getNetwork()
return '0x' + result.chainId.toString(16)
}
case 'eth_sendTransaction': {
if (!this.signer) break
// TODO(zzmp): JsonRpcProvider filters from/gas fields from the params.
const req = JsonRpcProvider.hexlifyTransaction(params?.[0], { from: true, gas: true })
const tx = await this.signer.sendTransaction(req)
return tx.hash
}
default:
return super.send(method, params)
}
}
}
interface EthersSigningProvider extends EthersProvider {
getSigner(): JsonRpcSigner
}
export default function useEip1193Provider(
provider?: Eip1193Provider | EthersSigningProvider | EthersProvider
): Eip1193Provider | undefined {
return useMemo(() => {
if (provider) {
if (EthersProvider.isProvider(provider)) {
const signer = 'getSigner' in provider ? provider.getSigner() : null ?? voidSigner
return new Eip1193Bridge(signer, provider)
} else if (EthersProvider.isProvider((provider as ExperimentalEip1193Bridge).provider)) {
/*
* Direct users to use our own wrapper to avoid any pitfalls:
* - Eip1193Bridge is experimental
* - signer is not straightforward
* - bugs out if chainId>8
*/
throw new Error('Eip1193Bridge is experimental: pass your ethers Provider directly')
}
}
return provider
}, [provider])
}
import { JsonRpcProvider } from '@ethersproject/providers'
import { Actions, Connector, ProviderConnectInfo, ProviderRpcError } from '@web3-react/types'
function parseChainId(chainId: string) {
return Number.parseInt(chainId, 16)
}
export default class JsonRpcConnector extends Connector {
constructor(actions: Actions, public customProvider: JsonRpcProvider) {
super(actions)
customProvider
.on('connect', ({ chainId }: ProviderConnectInfo): void => {
this.actions.update({ chainId: parseChainId(chainId) })
})
.on('disconnect', (error: ProviderRpcError): void => {
this.actions.reportError(error)
})
.on('chainChanged', (chainId: string): void => {
this.actions.update({ chainId: parseChainId(chainId) })
})
.on('accountsChanged', (accounts: string[]): void => {
this.actions.update({ accounts })
})
}
async activate() {
this.actions.startActivation()
try {
const [{ chainId }, accounts] = await Promise.all([
this.customProvider.getNetwork(),
this.customProvider.listAccounts(),
])
this.actions.update({ chainId, accounts })
} catch (e) {
this.actions.reportError(e)
}
}
}
import { getAddress } from '@ethersproject/address' import { getAddress } from '@ethersproject/address'
import { AddressZero } from '@ethersproject/constants' import { AddressZero } from '@ethersproject/constants'
import { Contract } from '@ethersproject/contracts' import { Contract } from '@ethersproject/contracts'
import { JsonRpcSigner, Web3Provider } from '@ethersproject/providers' import { JsonRpcProvider, JsonRpcSigner } from '@ethersproject/providers'
import { Token } from '@uniswap/sdk-core' import { Token } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk' import { FeeAmount } from '@uniswap/v3-sdk'
import { ChainTokenMap } from 'lib/hooks/useTokenList/utils' import { ChainTokenMap } from 'lib/hooks/useTokenList/utils'
...@@ -25,17 +25,17 @@ export function shortenAddress(address: string, chars = 4): string { ...@@ -25,17 +25,17 @@ export function shortenAddress(address: string, chars = 4): string {
} }
// account is not optional // account is not optional
function getSigner(library: Web3Provider, account: string): JsonRpcSigner { function getSigner(library: JsonRpcProvider, account: string): JsonRpcSigner {
return library.getSigner(account).connectUnchecked() return library.getSigner(account).connectUnchecked()
} }
// account is optional // account is optional
function getProviderOrSigner(library: Web3Provider, account?: string): Web3Provider | JsonRpcSigner { function getProviderOrSigner(library: JsonRpcProvider, account?: string): JsonRpcProvider | JsonRpcSigner {
return account ? getSigner(library, account) : library return account ? getSigner(library, account) : library
} }
// account is optional // account is optional
export function getContract(address: string, ABI: any, library: Web3Provider, account?: string): Contract { export function getContract(address: string, ABI: any, library: JsonRpcProvider, account?: string): Contract {
if (!isAddress(address) || address === AddressZero) { if (!isAddress(address) || address === AddressZero) {
throw Error(`Invalid 'address' parameter '${address}'.`) throw Error(`Invalid 'address' parameter '${address}'.`)
} }
......
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { hexStripZeros } from '@ethersproject/bytes' import { hexStripZeros } from '@ethersproject/bytes'
import { Web3Provider } from '@ethersproject/providers' import { ExternalProvider } 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' import { INFURA_NETWORK_URLS } from 'constants/infura'
interface SwitchNetworkArguments { interface SwitchNetworkArguments {
library: Web3Provider provider: ExternalProvider
chainId: SupportedChainId chainId: SupportedChainId
} }
...@@ -38,13 +38,13 @@ function getRpcUrls(chainId: SupportedChainId): [string] { ...@@ -38,13 +38,13 @@ function getRpcUrls(chainId: SupportedChainId): [string] {
// 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({ provider, chainId }: SwitchNetworkArguments): Promise<null | void> {
if (!library?.provider?.request) { if (!provider.request) {
return return
} }
const formattedChainId = hexStripZeros(BigNumber.from(chainId).toHexString()) const formattedChainId = hexStripZeros(BigNumber.from(chainId).toHexString())
try { try {
await library.provider.request({ await provider.request({
method: 'wallet_switchEthereumChain', method: 'wallet_switchEthereumChain',
params: [{ chainId: formattedChainId }], params: [{ chainId: formattedChainId }],
}) })
...@@ -53,7 +53,7 @@ export async function switchToNetwork({ library, chainId }: SwitchNetworkArgumen ...@@ -53,7 +53,7 @@ export async function switchToNetwork({ library, chainId }: SwitchNetworkArgumen
if (error.code === 4902) { if (error.code === 4902) {
const info = CHAIN_INFO[chainId] const info = CHAIN_INFO[chainId]
await library.provider.request({ await provider.request({
method: 'wallet_addEthereumChain', method: 'wallet_addEthereumChain',
params: [ params: [
{ {
...@@ -69,7 +69,7 @@ export async function switchToNetwork({ library, chainId }: SwitchNetworkArgumen ...@@ -69,7 +69,7 @@ export async function switchToNetwork({ library, chainId }: SwitchNetworkArgumen
// the second call is done here because that behavior is not a part of the spec and cannot be relied upon in the future // the second call is done here because that behavior is not a part of the spec and cannot be relied upon in the future
// metamask's behavior when switching to the current network is just to return null (a no-op) // metamask's behavior when switching to the current network is just to return null (a no-op)
try { try {
await library.provider.request({ await provider.request({
method: 'wallet_switchEthereumChain', method: 'wallet_switchEthereumChain',
params: [{ chainId: formattedChainId }], params: [{ chainId: formattedChainId }],
}) })
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment