feat: eagerly connect outside of react lifecycle (#7334)
* feat: eagerly connect outside of react lifecycle * test: reflect selected wallet in localStorage * test: spy only on portfolio balances
This commit is contained in:
parent
0f6581bf47
commit
54880d201a
@ -53,7 +53,6 @@ Cypress.Commands.overwrite(
|
||||
|
||||
setInitialUserState(win, {
|
||||
...initialState,
|
||||
hideUniswapWalletBanner: true,
|
||||
...CONNECTED_WALLET_USER_STATE,
|
||||
...(options?.userState ?? {}),
|
||||
})
|
||||
|
@ -10,23 +10,25 @@ export const DISCONNECTED_WALLET_USER_STATE: Partial<UserState> = { selectedWall
|
||||
* Other persisted slices are not set, so they will be filled with their respective initial values
|
||||
* when the app runs.
|
||||
*/
|
||||
export function setInitialUserState(win: Cypress.AUTWindow, initialUserState: any) {
|
||||
export function setInitialUserState(win: Cypress.AUTWindow, state: UserState) {
|
||||
// Selected wallet should also be reflected in localStorage, so that eager connections work.
|
||||
if (state.selectedWallet) {
|
||||
win.localStorage.setItem('selected_wallet', state.selectedWallet)
|
||||
}
|
||||
|
||||
win.indexedDB.deleteDatabase('redux')
|
||||
|
||||
const dbRequest = win.indexedDB.open('redux')
|
||||
|
||||
dbRequest.onsuccess = function () {
|
||||
const db = dbRequest.result
|
||||
const transaction = db.transaction('keyvaluepairs', 'readwrite')
|
||||
const store = transaction.objectStore('keyvaluepairs')
|
||||
store.put(
|
||||
{
|
||||
user: initialUserState,
|
||||
user: state,
|
||||
},
|
||||
'persist:interface'
|
||||
)
|
||||
}
|
||||
|
||||
dbRequest.onupgradeneeded = function () {
|
||||
const db = dbRequest.result
|
||||
db.createObjectStore('keyvaluepairs')
|
||||
|
@ -5,7 +5,6 @@ import { Provider as EIP1193Provider } from '@web3-react/types'
|
||||
import { sendAnalyticsEvent, user } from 'analytics'
|
||||
import { connections, getConnection } from 'connection'
|
||||
import { Connection, ConnectionType } from 'connection/types'
|
||||
import useEagerlyConnect from 'hooks/useEagerlyConnect'
|
||||
import { Provider } from 'react-redux'
|
||||
import { HashRouter } from 'react-router-dom'
|
||||
import store from 'state'
|
||||
@ -33,7 +32,6 @@ jest.mock('connection', () => {
|
||||
|
||||
return { ConnectionType, getConnection: jest.fn(), connections: [mockConnection] }
|
||||
})
|
||||
jest.mock('hooks/useEagerlyConnect', () => jest.fn())
|
||||
|
||||
jest.unmock('@web3-react/core')
|
||||
|
||||
@ -59,7 +57,6 @@ describe('Web3Provider', () => {
|
||||
await act(async () => {
|
||||
await result
|
||||
})
|
||||
expect(useEagerlyConnect).toHaveBeenCalled()
|
||||
expect(result).toBeTruthy()
|
||||
})
|
||||
|
||||
|
@ -6,7 +6,6 @@ import { connections, getConnection } from 'connection'
|
||||
import { isSupportedChain } from 'constants/chains'
|
||||
import { RPC_PROVIDERS } from 'constants/providers'
|
||||
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
|
||||
import useEagerlyConnect from 'hooks/useEagerlyConnect'
|
||||
import usePrevious from 'hooks/usePrevious'
|
||||
import { ReactNode, useEffect } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
@ -15,7 +14,6 @@ import { getCurrentPageFromLocation } from 'utils/urlRoutes'
|
||||
import { getWalletMeta } from 'utils/walletMeta'
|
||||
|
||||
export default function Web3Provider({ children }: { children: ReactNode }) {
|
||||
useEagerlyConnect()
|
||||
const connectors = connections.map<[Connector, Web3ReactHooks]>(({ hooks, connector }) => [connector, hooks])
|
||||
|
||||
return (
|
||||
|
36
src/connection/eagerlyConnect.ts
Normal file
36
src/connection/eagerlyConnect.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { Connector } from '@web3-react/types'
|
||||
|
||||
import { getConnection, gnosisSafeConnection, networkConnection } from './index'
|
||||
import { ConnectionType, selectedWalletKey, toConnectionType } from './types'
|
||||
|
||||
async function connect(connector: Connector, type: ConnectionType) {
|
||||
performance.mark(`web3:connect:${type}:start`)
|
||||
try {
|
||||
if (connector.connectEagerly) {
|
||||
await connector.connectEagerly()
|
||||
} else {
|
||||
await connector.activate()
|
||||
}
|
||||
return true
|
||||
} catch (error) {
|
||||
console.debug(`web3-react eager connection error: ${error}`)
|
||||
return false
|
||||
} finally {
|
||||
performance.measure(`web3:connect:${type}`, `web3:connect:${type}:start`)
|
||||
}
|
||||
}
|
||||
|
||||
connect(gnosisSafeConnection.connector, ConnectionType.GNOSIS_SAFE)
|
||||
connect(networkConnection.connector, ConnectionType.NETWORK)
|
||||
const selectedWallet = toConnectionType(localStorage.getItem(selectedWalletKey) ?? undefined)
|
||||
if (selectedWallet) {
|
||||
const selectedConnection = getConnection(selectedWallet)
|
||||
if (selectedConnection) {
|
||||
connect(selectedConnection.connector, selectedWallet).then((connected) => {
|
||||
if (!connected) {
|
||||
// only clear the persisted wallet type if it failed to connect.
|
||||
localStorage.removeItem(selectedWalletKey)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ import { ChainId } from '@uniswap/sdk-core'
|
||||
import { Web3ReactHooks } from '@web3-react/core'
|
||||
import { Connector } from '@web3-react/types'
|
||||
|
||||
export const selectedWalletKey = 'selected_wallet'
|
||||
|
||||
export enum ConnectionType {
|
||||
UNISWAP_WALLET_V2 = 'UNISWAP_WALLET_V2',
|
||||
INJECTED = 'INJECTED',
|
||||
@ -11,6 +13,14 @@ export enum ConnectionType {
|
||||
GNOSIS_SAFE = 'GNOSIS_SAFE',
|
||||
}
|
||||
|
||||
export function toConnectionType(value = ''): ConnectionType | undefined {
|
||||
if (Object.keys(ConnectionType).includes(value)) {
|
||||
return value as ConnectionType
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
export interface Connection {
|
||||
getName(): string
|
||||
connector: Connector
|
||||
|
@ -1,47 +0,0 @@
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { gnosisSafeConnection, networkConnection } from 'connection'
|
||||
import { getConnection } from 'connection'
|
||||
import { useEffect } from 'react'
|
||||
import { useAppDispatch, useAppSelector } from 'state/hooks'
|
||||
import { updateSelectedWallet } from 'state/user/reducer'
|
||||
|
||||
import { useStateRehydrated } from './useStateRehydrated'
|
||||
|
||||
async function connect(connector: Connector) {
|
||||
try {
|
||||
if (connector.connectEagerly) {
|
||||
await connector.connectEagerly()
|
||||
} else {
|
||||
await connector.activate()
|
||||
}
|
||||
} catch (error) {
|
||||
console.debug(`web3-react eager connection error: ${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
export default function useEagerlyConnect() {
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
const selectedWallet = useAppSelector((state) => state.user.selectedWallet)
|
||||
const rehydrated = useStateRehydrated()
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
connect(gnosisSafeConnection.connector)
|
||||
connect(networkConnection.connector)
|
||||
|
||||
if (!selectedWallet) return
|
||||
const selectedConnection = getConnection(selectedWallet)
|
||||
|
||||
if (selectedConnection) {
|
||||
connect(selectedConnection.connector)
|
||||
}
|
||||
} catch {
|
||||
// only clear the persisted wallet type if it failed to connect.
|
||||
if (rehydrated) {
|
||||
dispatch(updateSelectedWallet({ wallet: undefined }))
|
||||
}
|
||||
return
|
||||
}
|
||||
}, [dispatch, rehydrated, selectedWallet])
|
||||
}
|
@ -2,6 +2,7 @@ import '@reach/dialog/styles.css'
|
||||
import 'inter-ui'
|
||||
import 'polyfills'
|
||||
import 'tracing'
|
||||
import 'connection/eagerlyConnect'
|
||||
|
||||
import { ApolloProvider } from '@apollo/client'
|
||||
import { FeatureFlagsProvider } from 'featureFlags'
|
||||
|
@ -1,11 +1,12 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
|
||||
import { ConnectionType } from '../../connection/types'
|
||||
import { ConnectionType, selectedWalletKey, toConnectionType } from '../../connection/types'
|
||||
import { SupportedLocale } from '../../constants/locales'
|
||||
import { DEFAULT_DEADLINE_FROM_NOW } from '../../constants/misc'
|
||||
import { RouterPreference } from '../../state/routing/types'
|
||||
import { SerializedPair, SerializedToken, SlippageTolerance } from './types'
|
||||
|
||||
const selectedWallet = toConnectionType(localStorage.getItem(selectedWalletKey) ?? undefined)
|
||||
const currentTimestamp = () => new Date().getTime()
|
||||
|
||||
export interface UserState {
|
||||
@ -56,7 +57,7 @@ function pairKey(token0Address: string, token1Address: string) {
|
||||
}
|
||||
|
||||
export const initialState: UserState = {
|
||||
selectedWallet: undefined,
|
||||
selectedWallet,
|
||||
userLocale: null,
|
||||
userRouterPreference: RouterPreference.API,
|
||||
userHideClosedPositions: false,
|
||||
@ -75,6 +76,7 @@ const userSlice = createSlice({
|
||||
initialState,
|
||||
reducers: {
|
||||
updateSelectedWallet(state, { payload: { wallet } }) {
|
||||
localStorage.setItem(selectedWalletKey, wallet)
|
||||
state.selectedWallet = wallet
|
||||
},
|
||||
updateUserLocale(state, action) {
|
||||
|
Loading…
Reference in New Issue
Block a user