Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2d00edcb01 | ||
|
590247b725 | ||
|
51b6c7a957 |
CODEOWNERS
cypress
patches
src
components
connection
hooks
index.tsxlocales
af-ZA.poar-SA.poca-ES.pocs-CZ.poda-DK.pode-DE.poel-GR.poes-ES.pofi-FI.pofr-FR.pohe-IL.pohu-HU.poid-ID.poit-IT.poja-JP.poko-KR.ponl-NL.pono-NO.popl-PL.popt-BR.popt-PT.poro-RO.poru-RU.posl-SI.posr-SP.posv-SE.posw-TZ.poth-TH.potr-TR.pouk-UA.povi-VN.pozh-CN.pozh-TW.po
pages/Swap
setupTests.tsstate
1
CODEOWNERS
Normal file
1
CODEOWNERS
Normal file
@ -0,0 +1 @@
|
|||||||
|
* @uniswap/web-admins
|
@ -53,6 +53,7 @@ Cypress.Commands.overwrite(
|
|||||||
|
|
||||||
setInitialUserState(win, {
|
setInitialUserState(win, {
|
||||||
...initialState,
|
...initialState,
|
||||||
|
hideUniswapWalletBanner: true,
|
||||||
...CONNECTED_WALLET_USER_STATE,
|
...CONNECTED_WALLET_USER_STATE,
|
||||||
...(options?.userState ?? {}),
|
...(options?.userState ?? {}),
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { connectionMetaKey } from '../../src/connection/meta'
|
|
||||||
import { ConnectionType } from '../../src/connection/types'
|
import { ConnectionType } from '../../src/connection/types'
|
||||||
import { UserState } from '../../src/state/user/reducer'
|
import { UserState } from '../../src/state/user/reducer'
|
||||||
|
|
||||||
@ -11,30 +10,23 @@ 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
|
* Other persisted slices are not set, so they will be filled with their respective initial values
|
||||||
* when the app runs.
|
* when the app runs.
|
||||||
*/
|
*/
|
||||||
export function setInitialUserState(win: Cypress.AUTWindow, state: UserState) {
|
export function setInitialUserState(win: Cypress.AUTWindow, initialUserState: any) {
|
||||||
// Selected wallet should also be reflected in localStorage, so that eager connections work.
|
|
||||||
if (state.selectedWallet) {
|
|
||||||
win.localStorage.setItem(
|
|
||||||
connectionMetaKey,
|
|
||||||
JSON.stringify({
|
|
||||||
type: state.selectedWallet,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
win.indexedDB.deleteDatabase('redux')
|
win.indexedDB.deleteDatabase('redux')
|
||||||
|
|
||||||
const dbRequest = win.indexedDB.open('redux')
|
const dbRequest = win.indexedDB.open('redux')
|
||||||
|
|
||||||
dbRequest.onsuccess = function () {
|
dbRequest.onsuccess = function () {
|
||||||
const db = dbRequest.result
|
const db = dbRequest.result
|
||||||
const transaction = db.transaction('keyvaluepairs', 'readwrite')
|
const transaction = db.transaction('keyvaluepairs', 'readwrite')
|
||||||
const store = transaction.objectStore('keyvaluepairs')
|
const store = transaction.objectStore('keyvaluepairs')
|
||||||
store.put(
|
store.put(
|
||||||
{
|
{
|
||||||
user: state,
|
user: initialUserState,
|
||||||
},
|
},
|
||||||
'persist:interface'
|
'persist:interface'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
dbRequest.onupgradeneeded = function () {
|
dbRequest.onupgradeneeded = function () {
|
||||||
const db = dbRequest.result
|
const db = dbRequest.result
|
||||||
db.createObjectStore('keyvaluepairs')
|
db.createObjectStore('keyvaluepairs')
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
diff --git a/node_modules/@web3-react/gnosis-safe/dist/index.js b/node_modules/@web3-react/gnosis-safe/dist/index.js
|
|
||||||
index 015a33c..4cd7cde 100644
|
|
||||||
--- a/node_modules/@web3-react/gnosis-safe/dist/index.js
|
|
||||||
+++ b/node_modules/@web3-react/gnosis-safe/dist/index.js
|
|
||||||
@@ -68,8 +68,8 @@ class GnosisSafe extends types_1.Connector {
|
|
||||||
if (this.eagerConnection)
|
|
||||||
return;
|
|
||||||
// kick off import early to minimize waterfalls
|
|
||||||
- const SafeAppProviderPromise = Promise.resolve().then(() => __importStar(require('@safe-global/safe-apps-provider'))).then(({ SafeAppProvider }) => SafeAppProvider);
|
|
||||||
- yield (this.eagerConnection = Promise.resolve().then(() => __importStar(require('@safe-global/safe-apps-sdk'))).then((m) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
+ const SafeAppProviderPromise = Promise.resolve().then(async () => __importStar(await import('@safe-global/safe-apps-provider'))).then(({ SafeAppProvider }) => SafeAppProvider);
|
|
||||||
+ yield (this.eagerConnection = Promise.resolve().then(async () => __importStar(await import('@safe-global/safe-apps-sdk'))).then((m) => __awaiter(this, void 0, void 0, function* () {
|
|
||||||
this.sdk = new m.default(this.options);
|
|
||||||
const safe = yield Promise.race([
|
|
||||||
this.sdk.safe.getInfo(),
|
|
@ -5,6 +5,7 @@ import { Provider as EIP1193Provider } from '@web3-react/types'
|
|||||||
import { sendAnalyticsEvent, user } from 'analytics'
|
import { sendAnalyticsEvent, user } from 'analytics'
|
||||||
import { connections, getConnection } from 'connection'
|
import { connections, getConnection } from 'connection'
|
||||||
import { Connection, ConnectionType } from 'connection/types'
|
import { Connection, ConnectionType } from 'connection/types'
|
||||||
|
import useEagerlyConnect from 'hooks/useEagerlyConnect'
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
import { HashRouter } from 'react-router-dom'
|
import { HashRouter } from 'react-router-dom'
|
||||||
import store from 'state'
|
import store from 'state'
|
||||||
@ -33,6 +34,7 @@ jest.mock('connection', () => {
|
|||||||
|
|
||||||
return { ConnectionType, getConnection: jest.fn(), connections: [mockConnection] }
|
return { ConnectionType, getConnection: jest.fn(), connections: [mockConnection] }
|
||||||
})
|
})
|
||||||
|
jest.mock('hooks/useEagerlyConnect', () => jest.fn())
|
||||||
|
|
||||||
jest.unmock('@web3-react/core')
|
jest.unmock('@web3-react/core')
|
||||||
|
|
||||||
@ -58,6 +60,7 @@ describe('Web3Provider', () => {
|
|||||||
await act(async () => {
|
await act(async () => {
|
||||||
await result
|
await result
|
||||||
})
|
})
|
||||||
|
expect(useEagerlyConnect).toHaveBeenCalled()
|
||||||
expect(result).toBeTruthy()
|
expect(result).toBeTruthy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import { connections, getConnection } from 'connection'
|
|||||||
import { isSupportedChain } from 'constants/chains'
|
import { isSupportedChain } from 'constants/chains'
|
||||||
import { RPC_PROVIDERS } from 'constants/providers'
|
import { RPC_PROVIDERS } from 'constants/providers'
|
||||||
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
|
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
|
||||||
|
import useEagerlyConnect from 'hooks/useEagerlyConnect'
|
||||||
import usePrevious from 'hooks/usePrevious'
|
import usePrevious from 'hooks/usePrevious'
|
||||||
import { ReactNode, useEffect } from 'react'
|
import { ReactNode, useEffect } from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
@ -14,6 +15,7 @@ import { getCurrentPageFromLocation } from 'utils/urlRoutes'
|
|||||||
import { getWalletMeta } from 'utils/walletMeta'
|
import { getWalletMeta } from 'utils/walletMeta'
|
||||||
|
|
||||||
export default function Web3Provider({ children }: { children: ReactNode }) {
|
export default function Web3Provider({ children }: { children: ReactNode }) {
|
||||||
|
useEagerlyConnect()
|
||||||
const connectors = connections.map<[Connector, Web3ReactHooks]>(({ hooks, connector }) => [connector, hooks])
|
const connectors = connections.map<[Connector, Web3ReactHooks]>(({ hooks, connector }) => [connector, hooks])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -4,19 +4,17 @@ import { useWeb3React } from '@web3-react/core'
|
|||||||
import { sendAnalyticsEvent, TraceEvent } from 'analytics'
|
import { sendAnalyticsEvent, TraceEvent } from 'analytics'
|
||||||
import PortfolioDrawer, { useAccountDrawer } from 'components/AccountDrawer'
|
import PortfolioDrawer, { useAccountDrawer } from 'components/AccountDrawer'
|
||||||
import { usePendingActivity } from 'components/AccountDrawer/MiniPortfolio/Activity/hooks'
|
import { usePendingActivity } from 'components/AccountDrawer/MiniPortfolio/Activity/hooks'
|
||||||
import Loader, { LoaderV3 } from 'components/Icons/LoadingSpinner'
|
import Loader from 'components/Icons/LoadingSpinner'
|
||||||
import { IconWrapper } from 'components/Identicon/StatusIcon'
|
import { IconWrapper } from 'components/Identicon/StatusIcon'
|
||||||
import PrefetchBalancesWrapper from 'components/PrefetchBalancesWrapper/PrefetchBalancesWrapper'
|
import PrefetchBalancesWrapper from 'components/PrefetchBalancesWrapper/PrefetchBalancesWrapper'
|
||||||
import { getConnection } from 'connection'
|
import { getConnection } from 'connection'
|
||||||
import { useConnectionReady } from 'connection/eagerlyConnect'
|
|
||||||
import { ConnectionMeta, getPersistedConnectionMeta, setPersistedConnectionMeta } from 'connection/meta'
|
|
||||||
import useENSName from 'hooks/useENSName'
|
import useENSName from 'hooks/useENSName'
|
||||||
import useLast from 'hooks/useLast'
|
import useLast from 'hooks/useLast'
|
||||||
import { navSearchInputVisibleSize } from 'hooks/useScreenSize'
|
import { navSearchInputVisibleSize } from 'hooks/useScreenSize'
|
||||||
import { Portal } from 'nft/components/common/Portal'
|
import { Portal } from 'nft/components/common/Portal'
|
||||||
import { useIsNftClaimAvailable } from 'nft/hooks/useIsNftClaimAvailable'
|
import { useIsNftClaimAvailable } from 'nft/hooks/useIsNftClaimAvailable'
|
||||||
import { darken } from 'polished'
|
import { darken } from 'polished'
|
||||||
import { useCallback, useEffect, useMemo, useRef } from 'react'
|
import { useCallback } from 'react'
|
||||||
import { useAppSelector } from 'state/hooks'
|
import { useAppSelector } from 'state/hooks'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { colors } from 'theme/colors'
|
import { colors } from 'theme/colors'
|
||||||
@ -96,15 +94,8 @@ const Web3StatusConnected = styled(Web3StatusGeneric)<{
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const Web3StatusConnecting = styled(Web3StatusConnected)`
|
const AddressAndChevronContainer = styled.div`
|
||||||
&:disabled {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const AddressAndChevronContainer = styled.div<{ loading?: boolean }>`
|
|
||||||
display: flex;
|
display: flex;
|
||||||
opacity: ${({ loading, theme }) => loading && theme.opacity.disabled};
|
|
||||||
|
|
||||||
@media only screen and (max-width: ${navSearchInputVisibleSize}px) {
|
@media only screen and (max-width: ${navSearchInputVisibleSize}px) {
|
||||||
display: none;
|
display: none;
|
||||||
@ -137,11 +128,8 @@ const StyledConnectButton = styled.button`
|
|||||||
function Web3StatusInner() {
|
function Web3StatusInner() {
|
||||||
const switchingChain = useAppSelector((state) => state.wallets.switchingChain)
|
const switchingChain = useAppSelector((state) => state.wallets.switchingChain)
|
||||||
const ignoreWhileSwitchingChain = useCallback(() => !switchingChain, [switchingChain])
|
const ignoreWhileSwitchingChain = useCallback(() => !switchingChain, [switchingChain])
|
||||||
const connectionReady = useConnectionReady()
|
const { account, connector } = useLast(useWeb3React(), ignoreWhileSwitchingChain)
|
||||||
const activeWeb3 = useWeb3React()
|
const { ENSName } = useENSName(account)
|
||||||
const lastWeb3 = useLast(useWeb3React(), ignoreWhileSwitchingChain)
|
|
||||||
const { account, connector } = useMemo(() => (activeWeb3.account ? activeWeb3 : lastWeb3), [activeWeb3, lastWeb3])
|
|
||||||
const { ENSName, loading: ENSLoading } = useENSName(account)
|
|
||||||
const connection = getConnection(connector)
|
const connection = getConnection(connector)
|
||||||
|
|
||||||
const [, toggleAccountDrawer] = useAccountDrawer()
|
const [, toggleAccountDrawer] = useAccountDrawer()
|
||||||
@ -153,48 +141,6 @@ function Web3StatusInner() {
|
|||||||
|
|
||||||
const { hasPendingActivity, pendingActivityCount } = usePendingActivity()
|
const { hasPendingActivity, pendingActivityCount } = usePendingActivity()
|
||||||
|
|
||||||
// Display a loading state while initializing the connection, based on the last session's persisted connection.
|
|
||||||
// The connection will go through three states:
|
|
||||||
// - startup: connection is not ready
|
|
||||||
// - initializing: account is available, but ENS (if preset on the persisted initialMeta) is still loading
|
|
||||||
// - initialized: account and ENS are available
|
|
||||||
// Subsequent connections are always considered initialized, and will not display startup/initializing states.
|
|
||||||
const initialConnection = useRef(getPersistedConnectionMeta())
|
|
||||||
const isConnectionInitializing = Boolean(
|
|
||||||
initialConnection.current?.address === account && initialConnection.current?.ENSName && ENSLoading
|
|
||||||
)
|
|
||||||
const isConnectionInitialized = connectionReady && !isConnectionInitializing
|
|
||||||
// Clear the initial connection once initialized so it does not interfere with subsequent connections.
|
|
||||||
useEffect(() => {
|
|
||||||
if (isConnectionInitialized) {
|
|
||||||
initialConnection.current = undefined
|
|
||||||
}
|
|
||||||
}, [isConnectionInitialized])
|
|
||||||
// Persist the connection if it changes, so it can be used to initialize the next session's connection.
|
|
||||||
useEffect(() => {
|
|
||||||
if (account || ENSName) {
|
|
||||||
const meta: ConnectionMeta = {
|
|
||||||
type: connection.type,
|
|
||||||
address: account,
|
|
||||||
ENSName: ENSName ?? undefined,
|
|
||||||
}
|
|
||||||
setPersistedConnectionMeta(meta)
|
|
||||||
}
|
|
||||||
}, [ENSName, account, connection.type])
|
|
||||||
|
|
||||||
if (!isConnectionInitialized) {
|
|
||||||
return (
|
|
||||||
<Web3StatusConnecting disabled={!isConnectionInitializing} onClick={handleWalletDropdownClick}>
|
|
||||||
<IconWrapper size={24}>
|
|
||||||
<LoaderV3 size="24px" />
|
|
||||||
</IconWrapper>
|
|
||||||
<AddressAndChevronContainer loading={true}>
|
|
||||||
<Text>{initialConnection.current?.ENSName ?? shortenAddress(initialConnection.current?.address)}</Text>
|
|
||||||
</AddressAndChevronContainer>
|
|
||||||
</Web3StatusConnecting>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (account) {
|
if (account) {
|
||||||
return (
|
return (
|
||||||
<TraceEvent
|
<TraceEvent
|
||||||
@ -221,7 +167,7 @@ function Web3StatusInner() {
|
|||||||
</RowBetween>
|
</RowBetween>
|
||||||
) : (
|
) : (
|
||||||
<AddressAndChevronContainer>
|
<AddressAndChevronContainer>
|
||||||
<Text>{ENSName ?? shortenAddress(account)}</Text>
|
<Text>{ENSName || shortenAddress(account)}</Text>
|
||||||
</AddressAndChevronContainer>
|
</AddressAndChevronContainer>
|
||||||
)}
|
)}
|
||||||
</Web3StatusConnected>
|
</Web3StatusConnected>
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
import { Connector } from '@web3-react/types'
|
|
||||||
import { useSyncExternalStore } from 'react'
|
|
||||||
|
|
||||||
import { getConnection, gnosisSafeConnection, networkConnection } from './index'
|
|
||||||
import { deletePersistedConnectionMeta, getPersistedConnectionMeta } from './meta'
|
|
||||||
import { ConnectionType } from './types'
|
|
||||||
|
|
||||||
class FailedToConnect extends Error {}
|
|
||||||
|
|
||||||
let connectionReady: Promise<void> | true = true
|
|
||||||
|
|
||||||
export function useConnectionReady() {
|
|
||||||
return useSyncExternalStore(
|
|
||||||
(onStoreChange) => {
|
|
||||||
if (connectionReady instanceof Promise) {
|
|
||||||
connectionReady.finally(onStoreChange)
|
|
||||||
}
|
|
||||||
return () => undefined
|
|
||||||
},
|
|
||||||
() => connectionReady === true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
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`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Safe connector will only work from safe.global, which iframes;
|
|
||||||
// it is only necessary to try (and to load all the deps) if we are in an iframe.
|
|
||||||
if (window !== window.parent) {
|
|
||||||
connect(gnosisSafeConnection.connector, ConnectionType.GNOSIS_SAFE)
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(networkConnection.connector, ConnectionType.NETWORK)
|
|
||||||
|
|
||||||
// Get the persisted wallet type from the last session.
|
|
||||||
const meta = getPersistedConnectionMeta()
|
|
||||||
if (meta?.type) {
|
|
||||||
const selectedConnection = getConnection(meta.type)
|
|
||||||
if (selectedConnection) {
|
|
||||||
connectionReady = connect(selectedConnection.connector, meta.type)
|
|
||||||
.then((connected) => {
|
|
||||||
if (!connected) throw new FailedToConnect()
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
// Clear the persisted wallet type if it failed to connect.
|
|
||||||
deletePersistedConnectionMeta()
|
|
||||||
// Log it if it threw an unknown error.
|
|
||||||
if (!(error instanceof FailedToConnect)) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
connectionReady = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
import { ConnectionType, toConnectionType } from './types'
|
|
||||||
|
|
||||||
export interface ConnectionMeta {
|
|
||||||
type: ConnectionType
|
|
||||||
address?: string
|
|
||||||
ENSName?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const connectionMetaKey = 'connection_meta'
|
|
||||||
|
|
||||||
export function getPersistedConnectionMeta(): ConnectionMeta | undefined {
|
|
||||||
try {
|
|
||||||
const value = localStorage.getItem(connectionMetaKey)
|
|
||||||
if (value) {
|
|
||||||
const raw = JSON.parse(value) as ConnectionMeta
|
|
||||||
const connectionType = toConnectionType(raw.type)
|
|
||||||
if (connectionType) {
|
|
||||||
return {
|
|
||||||
type: connectionType,
|
|
||||||
address: raw.address,
|
|
||||||
ENSName: raw.ENSName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(e)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setPersistedConnectionMeta(meta: ConnectionMeta) {
|
|
||||||
localStorage.setItem(connectionMetaKey, JSON.stringify(meta))
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deletePersistedConnectionMeta() {
|
|
||||||
localStorage.removeItem(connectionMetaKey)
|
|
||||||
}
|
|
@ -11,14 +11,6 @@ export enum ConnectionType {
|
|||||||
GNOSIS_SAFE = 'GNOSIS_SAFE',
|
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 {
|
export interface Connection {
|
||||||
getName(): string
|
getName(): string
|
||||||
connector: Connector
|
connector: Connector
|
||||||
|
@ -34,12 +34,11 @@ export default function useENSName(address?: string): { ENSName: string | null;
|
|||||||
const checkedName = address === fwdAddr?.address ? name : null
|
const checkedName = address === fwdAddr?.address ? name : null
|
||||||
|
|
||||||
const changed = debouncedAddress !== address
|
const changed = debouncedAddress !== address
|
||||||
const loading = changed || resolverAddress.loading || nameCallRes.loading || fwdAddr.loading
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
ENSName: changed ? null : checkedName,
|
ENSName: changed ? null : checkedName,
|
||||||
loading,
|
loading: changed || resolverAddress.loading || nameCallRes.loading,
|
||||||
}),
|
}),
|
||||||
[changed, checkedName, loading]
|
[changed, nameCallRes.loading, checkedName, resolverAddress.loading]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
47
src/hooks/useEagerlyConnect.ts
Normal file
47
src/hooks/useEagerlyConnect.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
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,7 +2,6 @@ import '@reach/dialog/styles.css'
|
|||||||
import 'inter-ui'
|
import 'inter-ui'
|
||||||
import 'polyfills'
|
import 'polyfills'
|
||||||
import 'tracing'
|
import 'tracing'
|
||||||
import 'connection/eagerlyConnect'
|
|
||||||
|
|
||||||
import { ApolloProvider } from '@apollo/client'
|
import { ApolloProvider } from '@apollo/client'
|
||||||
import { FeatureFlagsProvider } from 'featureFlags'
|
import { FeatureFlagsProvider } from 'featureFlags'
|
||||||
|
3645
src/locales/af-ZA.po
Normal file
3645
src/locales/af-ZA.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/ar-SA.po
Normal file
3645
src/locales/ar-SA.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/ca-ES.po
Normal file
3645
src/locales/ca-ES.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/cs-CZ.po
Normal file
3645
src/locales/cs-CZ.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/da-DK.po
Normal file
3645
src/locales/da-DK.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/de-DE.po
Normal file
3645
src/locales/de-DE.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/el-GR.po
Normal file
3645
src/locales/el-GR.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/es-ES.po
Normal file
3645
src/locales/es-ES.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/fi-FI.po
Normal file
3645
src/locales/fi-FI.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/fr-FR.po
Normal file
3645
src/locales/fr-FR.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/he-IL.po
Normal file
3645
src/locales/he-IL.po
Normal file
File diff suppressed because it is too large
Load Diff
3646
src/locales/hu-HU.po
Normal file
3646
src/locales/hu-HU.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/id-ID.po
Normal file
3645
src/locales/id-ID.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/it-IT.po
Normal file
3645
src/locales/it-IT.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/ja-JP.po
Normal file
3645
src/locales/ja-JP.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/ko-KR.po
Normal file
3645
src/locales/ko-KR.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/nl-NL.po
Normal file
3645
src/locales/nl-NL.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/no-NO.po
Normal file
3645
src/locales/no-NO.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/pl-PL.po
Normal file
3645
src/locales/pl-PL.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/pt-BR.po
Normal file
3645
src/locales/pt-BR.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/pt-PT.po
Normal file
3645
src/locales/pt-PT.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/ro-RO.po
Normal file
3645
src/locales/ro-RO.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/ru-RU.po
Normal file
3645
src/locales/ru-RU.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/sl-SI.po
Normal file
3645
src/locales/sl-SI.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/sr-SP.po
Normal file
3645
src/locales/sr-SP.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/sv-SE.po
Normal file
3645
src/locales/sv-SE.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/sw-TZ.po
Normal file
3645
src/locales/sw-TZ.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/th-TH.po
Normal file
3645
src/locales/th-TH.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/tr-TR.po
Normal file
3645
src/locales/tr-TR.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/uk-UA.po
Normal file
3645
src/locales/uk-UA.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/vi-VN.po
Normal file
3645
src/locales/vi-VN.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/zh-CN.po
Normal file
3645
src/locales/zh-CN.po
Normal file
File diff suppressed because it is too large
Load Diff
3645
src/locales/zh-TW.po
Normal file
3645
src/locales/zh-TW.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,6 @@ import SwapDetailsDropdown from 'components/swap/SwapDetailsDropdown'
|
|||||||
import SwapHeader from 'components/swap/SwapHeader'
|
import SwapHeader from 'components/swap/SwapHeader'
|
||||||
import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
|
import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
|
||||||
import TokenSafetyModal from 'components/TokenSafety/TokenSafetyModal'
|
import TokenSafetyModal from 'components/TokenSafety/TokenSafetyModal'
|
||||||
import { useConnectionReady } from 'connection/eagerlyConnect'
|
|
||||||
import { getChainInfo } from 'constants/chainInfo'
|
import { getChainInfo } from 'constants/chainInfo'
|
||||||
import { asSupportedChain, isSupportedChain } from 'constants/chains'
|
import { asSupportedChain, isSupportedChain } from 'constants/chains'
|
||||||
import { getSwapCurrencyId, TOKEN_SHORTHANDS } from 'constants/tokens'
|
import { getSwapCurrencyId, TOKEN_SHORTHANDS } from 'constants/tokens'
|
||||||
@ -184,7 +183,6 @@ export function Swap({
|
|||||||
onCurrencyChange?: (selected: Pick<SwapState, Field.INPUT | Field.OUTPUT>) => void
|
onCurrencyChange?: (selected: Pick<SwapState, Field.INPUT | Field.OUTPUT>) => void
|
||||||
disableTokenInputs?: boolean
|
disableTokenInputs?: boolean
|
||||||
}) {
|
}) {
|
||||||
const connectionReady = useConnectionReady()
|
|
||||||
const { account, chainId: connectedChainId, connector } = useWeb3React()
|
const { account, chainId: connectedChainId, connector } = useWeb3React()
|
||||||
const trace = useTrace()
|
const trace = useTrace()
|
||||||
|
|
||||||
@ -734,7 +732,7 @@ export function Swap({
|
|||||||
<ButtonPrimary $borderRadius="16px" disabled={true}>
|
<ButtonPrimary $borderRadius="16px" disabled={true}>
|
||||||
<Trans>Connecting to {getChainInfo(switchingChain)?.label}</Trans>
|
<Trans>Connecting to {getChainInfo(switchingChain)?.label}</Trans>
|
||||||
</ButtonPrimary>
|
</ButtonPrimary>
|
||||||
) : connectionReady && !account ? (
|
) : !account ? (
|
||||||
<TraceEvent
|
<TraceEvent
|
||||||
events={[BrowserEvent.onClick]}
|
events={[BrowserEvent.onClick]}
|
||||||
name={InterfaceEventName.CONNECT_WALLET_BUTTON_CLICKED}
|
name={InterfaceEventName.CONNECT_WALLET_BUTTON_CLICKED}
|
||||||
|
@ -74,12 +74,6 @@ jest.mock('@web3-react/core', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
jest.mock('connection/eagerlyConnect', () => {
|
|
||||||
return {
|
|
||||||
useConnectionReady: () => true,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
jest.mock('state/routing/slice', () => {
|
jest.mock('state/routing/slice', () => {
|
||||||
const routingSlice = jest.requireActual('state/routing/slice')
|
const routingSlice = jest.requireActual('state/routing/slice')
|
||||||
return {
|
return {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Trans } from '@lingui/macro'
|
import { Trans } from '@lingui/macro'
|
||||||
import { ChainId, Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
|
import { ChainId, Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
|
||||||
import { useWeb3React } from '@web3-react/core'
|
import { useWeb3React } from '@web3-react/core'
|
||||||
import { useConnectionReady } from 'connection/eagerlyConnect'
|
|
||||||
import { useFotAdjustmentsEnabled } from 'featureFlags/flags/fotAdjustments'
|
import { useFotAdjustmentsEnabled } from 'featureFlags/flags/fotAdjustments'
|
||||||
import useAutoSlippageTolerance from 'hooks/useAutoSlippageTolerance'
|
import useAutoSlippageTolerance from 'hooks/useAutoSlippageTolerance'
|
||||||
import { useDebouncedTrade } from 'hooks/useDebouncedTrade'
|
import { useDebouncedTrade } from 'hooks/useDebouncedTrade'
|
||||||
@ -169,12 +168,11 @@ export function useDerivedSwapInfo(state: SwapState, chainId: ChainId | undefine
|
|||||||
// slippage amount used to submit the trade
|
// slippage amount used to submit the trade
|
||||||
const allowedSlippage = uniswapXAutoSlippage ?? classicAllowedSlippage
|
const allowedSlippage = uniswapXAutoSlippage ?? classicAllowedSlippage
|
||||||
|
|
||||||
const connectionReady = useConnectionReady()
|
|
||||||
const inputError = useMemo(() => {
|
const inputError = useMemo(() => {
|
||||||
let inputError: ReactNode | undefined
|
let inputError: ReactNode | undefined
|
||||||
|
|
||||||
if (!account) {
|
if (!account) {
|
||||||
inputError = connectionReady ? <Trans>Connect Wallet</Trans> : <Trans>Connecting Wallet...</Trans>
|
inputError = <Trans>Connect Wallet</Trans>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!currencies[Field.INPUT] || !currencies[Field.OUTPUT]) {
|
if (!currencies[Field.INPUT] || !currencies[Field.OUTPUT]) {
|
||||||
@ -202,7 +200,7 @@ export function useDerivedSwapInfo(state: SwapState, chainId: ChainId | undefine
|
|||||||
}
|
}
|
||||||
|
|
||||||
return inputError
|
return inputError
|
||||||
}, [account, currencies, parsedAmount, to, currencyBalances, trade?.trade, allowedSlippage, connectionReady])
|
}, [account, currencies, parsedAmount, to, currencyBalances, trade.trade, allowedSlippage])
|
||||||
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { createSlice } from '@reduxjs/toolkit'
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
import { deletePersistedConnectionMeta, getPersistedConnectionMeta } from 'connection/meta'
|
|
||||||
|
|
||||||
import { ConnectionType } from '../../connection/types'
|
import { ConnectionType } from '../../connection/types'
|
||||||
import { SupportedLocale } from '../../constants/locales'
|
import { SupportedLocale } from '../../constants/locales'
|
||||||
@ -7,7 +6,6 @@ import { DEFAULT_DEADLINE_FROM_NOW } from '../../constants/misc'
|
|||||||
import { RouterPreference } from '../../state/routing/types'
|
import { RouterPreference } from '../../state/routing/types'
|
||||||
import { SerializedPair, SerializedToken, SlippageTolerance } from './types'
|
import { SerializedPair, SerializedToken, SlippageTolerance } from './types'
|
||||||
|
|
||||||
const selectedWallet = getPersistedConnectionMeta()?.type
|
|
||||||
const currentTimestamp = () => new Date().getTime()
|
const currentTimestamp = () => new Date().getTime()
|
||||||
|
|
||||||
export interface UserState {
|
export interface UserState {
|
||||||
@ -61,7 +59,7 @@ function pairKey(token0Address: string, token1Address: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const initialState: UserState = {
|
export const initialState: UserState = {
|
||||||
selectedWallet,
|
selectedWallet: undefined,
|
||||||
userLocale: null,
|
userLocale: null,
|
||||||
userRouterPreference: RouterPreference.API,
|
userRouterPreference: RouterPreference.API,
|
||||||
userHideClosedPositions: false,
|
userHideClosedPositions: false,
|
||||||
@ -80,9 +78,6 @@ const userSlice = createSlice({
|
|||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
updateSelectedWallet(state, { payload: { wallet } }) {
|
updateSelectedWallet(state, { payload: { wallet } }) {
|
||||||
if (!wallet) {
|
|
||||||
deletePersistedConnectionMeta()
|
|
||||||
}
|
|
||||||
state.selectedWallet = wallet
|
state.selectedWallet = wallet
|
||||||
},
|
},
|
||||||
updateUserLocale(state, action) {
|
updateUserLocale(state, action) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user