Commit 34a22ef9 authored by Charles Bachmeier's avatar Charles Bachmeier Committed by GitHub

fix: chain query parameter doesn't block you from switching chains (#6926)

* useSearchParams

* delete old param

* properly handle a connected wallet

* update chain query via network switcher

* updated tests

* working test

* comment typo

* don't overwrite current params

* change chain based on user wallet interaction

* one instance of set

* update chainIdRef on account load

* useeffect

* set chainIdRef when isActive

* remove logging

* update comment

* make condition else if
parent 5e86cf7b
......@@ -111,6 +111,7 @@ describe('network switching', () => {
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Polygon')
cy.get(getTestSelector('web3-status-connected'))
cy.url().should('contain', 'chain=polygon')
// Verify that the input/output fields were reset
cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
......@@ -127,4 +128,17 @@ describe('network switching from URL param', () => {
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Polygon')
})
it('should be able to switch network after loading from URL param', () => {
cy.visit('/swap?chain=polygon', { ethereum: 'hardhat' })
cy.get(getTestSelector('web3-status-connected'))
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Polygon')
// switching to another chain clears query param
switchChain('Ethereum')
cy.wait('@wallet_switchEthereumChain')
waitsForActiveChain('Ethereum')
cy.url().should('not.contain', 'chain=polygon')
})
})
......@@ -2,7 +2,9 @@ import { ChainId } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { getConnection } from 'connection'
import { didUserReject } from 'connection/utils'
import { CHAIN_IDS_TO_NAMES, isSupportedChain } from 'constants/chains'
import { useCallback } from 'react'
import { useSearchParams } from 'react-router-dom'
import { addPopup, PopupType } from 'state/application/reducer'
import { useAppDispatch } from 'state/hooks'
......@@ -12,6 +14,7 @@ export default function useSelectChain() {
const dispatch = useAppDispatch()
const { connector } = useWeb3React()
const switchChain = useSwitchChain()
const [searchParams, setSearchParams] = useSearchParams()
return useCallback(
async (targetChain: ChainId) => {
......@@ -21,6 +24,10 @@ export default function useSelectChain() {
try {
await switchChain(connector, targetChain)
if (isSupportedChain(targetChain)) {
searchParams.set('chain', CHAIN_IDS_TO_NAMES[targetChain])
setSearchParams(searchParams)
}
} catch (error) {
if (!didUserReject(connection, error) && error.code !== -32002 /* request already pending */) {
console.error('Failed to switch networks', error)
......@@ -33,6 +40,6 @@ export default function useSelectChain() {
}
}
},
[connector, dispatch, switchChain]
[connector, dispatch, searchParams, setSearchParams, switchChain]
)
}
import { useWeb3React } from '@web3-react/core'
import { CHAIN_IDS_TO_NAMES } from 'constants/chains'
import { CHAIN_IDS_TO_NAMES, isSupportedChain } from 'constants/chains'
import { ParsedQs } from 'qs'
import { useEffect } from 'react'
import { useEffect, useRef } from 'react'
import { useSearchParams } from 'react-router-dom'
import useParsedQueryString from './useParsedQueryString'
......@@ -21,8 +21,18 @@ function getParsedChainId(parsedQs?: ParsedQs) {
}
export default function useSyncChainQuery() {
const { chainId, isActive } = useWeb3React()
const { chainId, isActive, account } = useWeb3React()
const parsedQs = useParsedQueryString()
const chainIdRef = useRef(chainId)
const accountRef = useRef(account)
useEffect(() => {
// Update chainIdRef when the account is retrieved from Web3React
if (account && account !== accountRef.current) {
chainIdRef.current = chainId
accountRef.current = account
}
}, [account, chainId])
const urlChainId = getParsedChainId(parsedQs)
......@@ -31,8 +41,22 @@ export default function useSyncChainQuery() {
const [searchParams, setSearchParams] = useSearchParams()
useEffect(() => {
if (isActive && urlChainId && chainId !== urlChainId) {
// Change a user's chain on pageload if the connected chainId does not match the query param chain
if (isActive && urlChainId && chainIdRef.current === chainId && chainId !== urlChainId) {
selectChain(urlChainId)
}
}, [urlChainId, selectChain, searchParams, setSearchParams, isActive, chainId])
// If a user has a connected wallet and has manually changed their chain, update the query parameter if it's supported
else if (account && chainIdRef.current !== chainId && chainId !== urlChainId) {
if (isSupportedChain(chainId)) {
searchParams.set('chain', CHAIN_IDS_TO_NAMES[chainId])
} else {
searchParams.delete('chain')
}
setSearchParams(searchParams)
}
// If a user has a connected wallet and the chainId matches the query param chain, update the chainIdRef
else if (isActive && chainId === urlChainId) {
chainIdRef.current = urlChainId
}
}, [urlChainId, selectChain, searchParams, isActive, chainId, account, setSearchParams])
}
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