refactor: extract Web3Provider hooks, create internal Connection representation (#4040)
* refactor: separate hooks file for Web3Provider * move utils * rename + comments * rename Wallet enum to ConnectionType * more wallet -> connectiontype * more wallet -> connectiontype * move hooks * use Connection everywhere * connector -> connection * generic getConnection * rename injected -> injectedConnection * check connectionType * rm unused
This commit is contained in:
parent
48a962a750
commit
4e462ddbef
@ -1,7 +1,8 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
import { Connector } from '@web3-react/types'
|
||||
import CopyHelper from 'components/AccountDetails/Copy'
|
||||
import { coinbaseWalletConnection, injectedConnection } from 'connection'
|
||||
import { getConnection } from 'connection/utils'
|
||||
import { useCallback, useContext } from 'react'
|
||||
import { ExternalLink as LinkIcon } from 'react-feather'
|
||||
import { useAppDispatch } from 'state/hooks'
|
||||
@ -10,7 +11,6 @@ import styled, { ThemeContext } from 'styled-components/macro'
|
||||
import { isMobile } from 'utils/userAgent'
|
||||
|
||||
import { ReactComponent as Close } from '../../assets/images/x.svg'
|
||||
import { coinbaseWallet, injected } from '../../connectors'
|
||||
import { SUPPORTED_WALLETS } from '../../constants/wallet'
|
||||
import { clearAllTransactions } from '../../state/transactions/reducer'
|
||||
import { ExternalLink, LinkStyledButton, ThemedText } from '../../theme'
|
||||
@ -163,29 +163,6 @@ const WalletName = styled.div`
|
||||
color: ${({ theme }) => theme.text3};
|
||||
`
|
||||
|
||||
const IconWrapper = styled.div<{ size?: number }>`
|
||||
${({ theme }) => theme.flexColumnNoWrap};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 8px;
|
||||
& > img,
|
||||
span {
|
||||
height: ${({ size }) => (size ? size + 'px' : '32px')};
|
||||
width: ${({ size }) => (size ? size + 'px' : '32px')};
|
||||
}
|
||||
${({ theme }) => theme.mediaWidth.upToMedium`
|
||||
align-items: flex-end;
|
||||
`};
|
||||
`
|
||||
|
||||
function WrappedStatusIcon({ connector }: { connector: Connector }) {
|
||||
return (
|
||||
<IconWrapper size={16}>
|
||||
<StatusIcon connector={connector} />
|
||||
</IconWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
const TransactionListWrapper = styled.div`
|
||||
${({ theme }) => theme.flexColumnNoWrap};
|
||||
`
|
||||
@ -228,6 +205,8 @@ export default function AccountDetails({
|
||||
openOptions,
|
||||
}: AccountDetailsProps) {
|
||||
const { chainId, account, connector } = useWeb3React()
|
||||
const connectionType = getConnection(connector).type
|
||||
|
||||
const theme = useContext(ThemeContext)
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
@ -241,7 +220,8 @@ export default function AccountDetails({
|
||||
const name = Object.keys(SUPPORTED_WALLETS)
|
||||
.filter(
|
||||
(k) =>
|
||||
SUPPORTED_WALLETS[k].connector === connector && (connector !== injected || isMetaMask === (k === 'METAMASK'))
|
||||
SUPPORTED_WALLETS[k].connector === connector &&
|
||||
(connector !== injectedConnection.connector || isMetaMask === (k === 'METAMASK'))
|
||||
)
|
||||
.map((k) => SUPPORTED_WALLETS[k].name)[0]
|
||||
return (
|
||||
@ -281,7 +261,7 @@ export default function AccountDetails({
|
||||
// Coinbase Wallet SDK does not emit a disconnect event to the provider,
|
||||
// which is what web3-react uses to reset state. As a workaround we manually
|
||||
// reset state.
|
||||
if (connector === coinbaseWallet) {
|
||||
if (connector === coinbaseWalletConnection.connector) {
|
||||
connector.resetState()
|
||||
}
|
||||
} else {
|
||||
@ -308,21 +288,10 @@ export default function AccountDetails({
|
||||
</AccountGroupingRow>
|
||||
<AccountGroupingRow data-testid="web3-account-identifier-row">
|
||||
<AccountControl>
|
||||
{ENSName ? (
|
||||
<>
|
||||
<div>
|
||||
{connector && <WrappedStatusIcon connector={connector} />}
|
||||
<p> {ENSName}</p>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div>
|
||||
{connector && <WrappedStatusIcon connector={connector} />}
|
||||
<p> {account && shortenAddress(account)}</p>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div>
|
||||
<StatusIcon connectionType={connectionType} />
|
||||
<p>{ENSName ? ENSName : account && shortenAddress(account)}</p>
|
||||
</div>
|
||||
</AccountControl>
|
||||
</AccountGroupingRow>
|
||||
<AccountGroupingRow>
|
||||
|
@ -12,7 +12,7 @@ import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
|
||||
|
||||
import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
|
||||
import useTheme from '../../hooks/useTheme'
|
||||
import { useCurrencyBalance } from '../../state/wallet/hooks'
|
||||
import { useCurrencyBalance } from '../../state/connection/hooks'
|
||||
import { ThemedText } from '../../theme'
|
||||
import { ButtonGray } from '../Button'
|
||||
import CurrencyLogo from '../CurrencyLogo'
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
import { getWalletForConnector } from 'connectors'
|
||||
import { getConnection } from 'connection/utils'
|
||||
import { CHAIN_INFO } from 'constants/chainInfo'
|
||||
import { CHAIN_IDS_TO_NAMES, SupportedChainId } from 'constants/chains'
|
||||
import { useOnClickOutside } from 'hooks/useOnClickOutside'
|
||||
@ -12,8 +12,8 @@ import { ArrowDownCircle, ChevronDown } from 'react-feather'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import { useModalOpen, useToggleModal } from 'state/application/hooks'
|
||||
import { addPopup, ApplicationModal } from 'state/application/reducer'
|
||||
import { updateConnectionError } from 'state/connection/reducer'
|
||||
import { useAppDispatch } from 'state/hooks'
|
||||
import { updateWalletError } from 'state/wallet/reducer'
|
||||
import styled from 'styled-components/macro'
|
||||
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
|
||||
import { replaceURLParam } from 'utils/routes'
|
||||
@ -285,15 +285,15 @@ export default function NetworkSelector() {
|
||||
async (targetChain: number, skipToggle?: boolean) => {
|
||||
if (!connector) return
|
||||
|
||||
const wallet = getWalletForConnector(connector)
|
||||
const connectionType = getConnection(connector).type
|
||||
|
||||
try {
|
||||
dispatch(updateWalletError({ wallet, error: undefined }))
|
||||
dispatch(updateConnectionError({ connectionType, error: undefined }))
|
||||
await switchChain(connector, targetChain)
|
||||
} catch (error) {
|
||||
console.error('Failed to switch networks', error)
|
||||
|
||||
dispatch(updateWalletError({ wallet, error: error.message }))
|
||||
dispatch(updateConnectionError({ connectionType, error: error.message }))
|
||||
dispatch(addPopup({ content: { failedSwitchNetwork: targetChain }, key: `failed-network-switch` }))
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,9 @@ import { NavLink } from 'react-router-dom'
|
||||
import { Text } from 'rebass'
|
||||
import { useShowClaimPopup, useToggleSelfClaimModal } from 'state/application/hooks'
|
||||
import { useUserHasAvailableClaim } from 'state/claim/hooks'
|
||||
import { useNativeCurrencyBalances } from 'state/connection/hooks'
|
||||
import { useUserHasSubmittedClaim } from 'state/transactions/hooks'
|
||||
import { useDarkModeManager } from 'state/user/hooks'
|
||||
import { useNativeCurrencyBalances } from 'state/wallet/hooks'
|
||||
import styled from 'styled-components/macro'
|
||||
import { isChainAllowed } from 'utils/switchChain'
|
||||
|
||||
|
@ -1,22 +1,42 @@
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { ConnectionType } from 'connection'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg'
|
||||
import FortmaticIcon from '../../assets/images/fortmaticIcon.png'
|
||||
import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg'
|
||||
import { coinbaseWallet, fortmatic, injected, walletConnect } from '../../connectors'
|
||||
import Identicon from '../Identicon'
|
||||
|
||||
export default function StatusIcon({ connector }: { connector: Connector }) {
|
||||
switch (connector) {
|
||||
case injected:
|
||||
return <Identicon />
|
||||
case walletConnect:
|
||||
return <img src={WalletConnectIcon} alt="WalletConnect" />
|
||||
case coinbaseWallet:
|
||||
return <img src={CoinbaseWalletIcon} alt="Coinbase Wallet" />
|
||||
case fortmatic:
|
||||
return <img src={FortmaticIcon} alt="Fortmatic" />
|
||||
default:
|
||||
return null
|
||||
const IconWrapper = styled.div<{ size?: number }>`
|
||||
${({ theme }) => theme.flexColumnNoWrap};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 8px;
|
||||
& > img,
|
||||
span {
|
||||
height: ${({ size }) => (size ? size + 'px' : '32px')};
|
||||
width: ${({ size }) => (size ? size + 'px' : '32px')};
|
||||
}
|
||||
${({ theme }) => theme.mediaWidth.upToMedium`
|
||||
align-items: flex-end;
|
||||
`};
|
||||
`
|
||||
|
||||
export default function StatusIcon({ connectionType }: { connectionType: ConnectionType }) {
|
||||
let image
|
||||
switch (connectionType) {
|
||||
case ConnectionType.INJECTED:
|
||||
image = <Identicon />
|
||||
break
|
||||
case ConnectionType.WALLET_CONNECT:
|
||||
image = <img src={WalletConnectIcon} alt="WalletConnect" />
|
||||
break
|
||||
case ConnectionType.COINBASE_WALLET:
|
||||
image = <img src={CoinbaseWalletIcon} alt="Coinbase Wallet" />
|
||||
break
|
||||
case ConnectionType.FORTMATIC:
|
||||
image = <img src={FortmaticIcon} alt="Fortmatic" />
|
||||
break
|
||||
}
|
||||
|
||||
return <IconWrapper size={16}>{image}</IconWrapper>
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import styled from 'styled-components/macro'
|
||||
import { BIG_INT_ZERO } from '../../constants/misc'
|
||||
import { useColor } from '../../hooks/useColor'
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { useTokenBalance } from '../../state/connection/hooks'
|
||||
import { currencyId } from '../../utils/currencyId'
|
||||
import { unwrappedToken } from '../../utils/unwrappedToken'
|
||||
import { ButtonEmpty, ButtonPrimary, ButtonSecondary } from '../Button'
|
||||
|
@ -13,7 +13,7 @@ import styled from 'styled-components/macro'
|
||||
import { BIG_INT_ZERO } from '../../constants/misc'
|
||||
import { useColor } from '../../hooks/useColor'
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { useTokenBalance } from '../../state/connection/hooks'
|
||||
import { ExternalLink, ThemedText } from '../../theme'
|
||||
import { currencyId } from '../../utils/currencyId'
|
||||
import { unwrappedToken } from '../../utils/unwrappedToken'
|
||||
|
@ -33,7 +33,7 @@ jest.mock('@web3-react/core', () => {
|
||||
}
|
||||
})
|
||||
|
||||
jest.mock('../../../state/wallet/hooks', () => {
|
||||
jest.mock('../../../state/connection/hooks', () => {
|
||||
return {
|
||||
useCurrencyBalance: (currency: Currency) => {
|
||||
return mockCurrencyAmt[(currency as mockToken)?.address]
|
||||
|
@ -11,9 +11,9 @@ import styled from 'styled-components/macro'
|
||||
|
||||
import TokenListLogo from '../../../assets/svg/tokenlist.svg'
|
||||
import { useIsUserAddedToken } from '../../../hooks/Tokens'
|
||||
import { useCurrencyBalance } from '../../../state/connection/hooks'
|
||||
import { useCombinedActiveList } from '../../../state/lists/hooks'
|
||||
import { WrappedTokenInfo } from '../../../state/lists/wrappedTokenInfo'
|
||||
import { useCurrencyBalance } from '../../../state/wallet/hooks'
|
||||
import { ThemedText } from '../../../theme'
|
||||
import { isTokenOnList } from '../../../utils'
|
||||
import Column from '../../Column'
|
||||
|
@ -15,7 +15,7 @@ import { Edit } from 'react-feather'
|
||||
import AutoSizer from 'react-virtualized-auto-sizer'
|
||||
import { FixedSizeList } from 'react-window'
|
||||
import { Text } from 'rebass'
|
||||
import { useAllTokenBalances } from 'state/wallet/hooks'
|
||||
import { useAllTokenBalances } from 'state/connection/hooks'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { useAllTokens, useIsUserAddedToken, useSearchInactiveTokenLists, useToken } from '../../hooks/Tokens'
|
||||
|
@ -4,16 +4,17 @@ import { Connector } from '@web3-react/types'
|
||||
import { sendEvent } from 'components/analytics'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import { AutoRow } from 'components/Row'
|
||||
import { ConnectionType, injectedConnection } from 'connection'
|
||||
import { getConnection } from 'connection/utils'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { ArrowLeft } from 'react-feather'
|
||||
import { updateConnectionError } from 'state/connection/reducer'
|
||||
import { useAppDispatch, useAppSelector } from 'state/hooks'
|
||||
import { updateSelectedWallet } from 'state/user/reducer'
|
||||
import { updateWalletError } from 'state/wallet/reducer'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import MetamaskIcon from '../../assets/images/metamask.png'
|
||||
import { ReactComponent as Close } from '../../assets/images/x.svg'
|
||||
import { fortmatic, getWalletForConnector, injected } from '../../connectors'
|
||||
import { SUPPORTED_WALLETS } from '../../constants/wallet'
|
||||
import { useModalOpen, useWalletModalToggle } from '../../state/application/hooks'
|
||||
import { ApplicationModal } from '../../state/application/reducer'
|
||||
@ -125,7 +126,7 @@ export default function WalletModal({
|
||||
|
||||
const [pendingConnector, setPendingConnector] = useState<Connector | undefined>()
|
||||
const pendingError = useAppSelector((state) =>
|
||||
pendingConnector ? state.wallet.errorByWallet[getWalletForConnector(pendingConnector)] : undefined
|
||||
pendingConnector ? state.connection.errorByConnectionType[getConnection(pendingConnector).type] : undefined
|
||||
)
|
||||
|
||||
const walletModalOpen = useModalOpen(ApplicationModal.WALLET)
|
||||
@ -143,39 +144,39 @@ export default function WalletModal({
|
||||
|
||||
useEffect(() => {
|
||||
if (pendingConnector && walletView !== WALLET_VIEWS.PENDING) {
|
||||
updateWalletError({ wallet: getWalletForConnector(pendingConnector), error: undefined })
|
||||
updateConnectionError({ connectionType: getConnection(pendingConnector).type, error: undefined })
|
||||
setPendingConnector(undefined)
|
||||
}
|
||||
}, [pendingConnector, walletView])
|
||||
|
||||
const tryActivation = useCallback(
|
||||
async (connector: Connector) => {
|
||||
const wallet = getWalletForConnector(connector)
|
||||
const connectionType = getConnection(connector).type
|
||||
|
||||
// log selected wallet
|
||||
sendEvent({
|
||||
category: 'Wallet',
|
||||
action: 'Change Wallet',
|
||||
label: wallet,
|
||||
label: connectionType,
|
||||
})
|
||||
|
||||
try {
|
||||
// Fortmatic opens it's own modal on activation to log in. This modal has a tabIndex
|
||||
// collision into the WalletModal, so we special case by closing the modal.
|
||||
if (connector === fortmatic) {
|
||||
if (connectionType === ConnectionType.FORTMATIC) {
|
||||
toggleWalletModal()
|
||||
}
|
||||
|
||||
setPendingConnector(connector)
|
||||
setWalletView(WALLET_VIEWS.PENDING)
|
||||
dispatch(updateWalletError({ wallet, error: undefined }))
|
||||
dispatch(updateConnectionError({ connectionType, error: undefined }))
|
||||
|
||||
await connector.activate()
|
||||
|
||||
dispatch(updateSelectedWallet({ wallet }))
|
||||
dispatch(updateSelectedWallet({ wallet: connectionType }))
|
||||
} catch (error) {
|
||||
console.debug(`web3-react connection error: ${error}`)
|
||||
dispatch(updateWalletError({ wallet, error: error.message }))
|
||||
dispatch(updateConnectionError({ connectionType, error: error.message }))
|
||||
}
|
||||
},
|
||||
[dispatch, toggleWalletModal]
|
||||
@ -221,7 +222,7 @@ export default function WalletModal({
|
||||
}
|
||||
|
||||
// overwrite injected when needed
|
||||
if (option.connector === injected) {
|
||||
if (option.connector === injectedConnection.connector) {
|
||||
// don't show injected if there's no injected provider
|
||||
if (!(window.web3 || window.ethereum)) {
|
||||
if (option.name === 'MetaMask') {
|
||||
|
@ -1,44 +1,11 @@
|
||||
import { Web3ReactProvider } from '@web3-react/core'
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { BACKFILLABLE_WALLETS, getConnectorForWallet, gnosisSafe, injected, network, useConnectors } from 'connectors'
|
||||
import { ReactNode, useEffect } from 'react'
|
||||
import { useAppSelector } from 'state/hooks'
|
||||
|
||||
import { isMobile } from '../../utils/userAgent'
|
||||
|
||||
const connect = async (connector: Connector) => {
|
||||
try {
|
||||
if (connector.connectEagerly) {
|
||||
await connector.connectEagerly()
|
||||
} else {
|
||||
await connector.activate()
|
||||
}
|
||||
} catch (error) {
|
||||
console.debug(`web3-react eager connection error: ${error}`)
|
||||
}
|
||||
}
|
||||
import useConnectors from 'hooks/useConnectors'
|
||||
import useEagerlyConnect from 'hooks/useEagerlyConnect'
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
export default function Web3Provider({ children }: { children: ReactNode }) {
|
||||
const selectedWalletBackfilled = useAppSelector((state) => state.user.selectedWalletBackfilled)
|
||||
const selectedWallet = useAppSelector((state) => state.user.selectedWallet)
|
||||
|
||||
const connectors = useConnectors(selectedWallet)
|
||||
|
||||
const isMetaMask = !!window.ethereum?.isMetaMask
|
||||
|
||||
useEffect(() => {
|
||||
connect(gnosisSafe)
|
||||
connect(network)
|
||||
|
||||
if (isMobile && isMetaMask) {
|
||||
injected.activate()
|
||||
} else if (selectedWallet) {
|
||||
connect(getConnectorForWallet(selectedWallet))
|
||||
} else if (!selectedWalletBackfilled) {
|
||||
BACKFILLABLE_WALLETS.map(getConnectorForWallet).forEach(connect)
|
||||
}
|
||||
// The dependency list is empty so this is only run once on mount
|
||||
}, []) // eslint-disable-line react-hooks/exhaustive-deps
|
||||
useEagerlyConnect()
|
||||
const connectors = useConnectors()
|
||||
|
||||
return <Web3ReactProvider connectors={connectors}>{children}</Web3ReactProvider>
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { t, Trans } from '@lingui/macro'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { getWalletForConnector } from 'connectors'
|
||||
import { getConnection } from 'connection/utils'
|
||||
import { darken } from 'polished'
|
||||
import { useMemo } from 'react'
|
||||
import { Activity } from 'react-feather'
|
||||
@ -21,16 +20,6 @@ import Loader from '../Loader'
|
||||
import { RowBetween } from '../Row'
|
||||
import WalletModal from '../WalletModal'
|
||||
|
||||
const IconWrapper = styled.div<{ size?: number }>`
|
||||
${({ theme }) => theme.flexColumnNoWrap};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
& > * {
|
||||
height: ${({ size }) => (size ? size + 'px' : '32px')};
|
||||
width: ${({ size }) => (size ? size + 'px' : '32px')};
|
||||
}
|
||||
`
|
||||
|
||||
const Web3StatusGeneric = styled(ButtonSecondary)`
|
||||
${({ theme }) => theme.flexRowNoWrap}
|
||||
width: 100%;
|
||||
@ -131,18 +120,11 @@ function Sock() {
|
||||
)
|
||||
}
|
||||
|
||||
function WrappedStatusIcon({ connector }: { connector: Connector }) {
|
||||
return (
|
||||
<IconWrapper size={16}>
|
||||
<StatusIcon connector={connector} />
|
||||
</IconWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
function Web3StatusInner() {
|
||||
const { account, connector, chainId, ENSName } = useWeb3React()
|
||||
const connectionType = getConnection(connector).type
|
||||
|
||||
const error = useAppSelector((state) => state.wallet.errorByWallet[getWalletForConnector(connector)])
|
||||
const error = useAppSelector((state) => state.connection.errorByConnectionType[getConnection(connector).type])
|
||||
|
||||
const chainAllowed = chainId && isChainAllowed(connector, chainId)
|
||||
|
||||
@ -199,7 +181,7 @@ function Web3StatusInner() {
|
||||
<Text>{ENSName || shortenAddress(account)}</Text>
|
||||
</>
|
||||
)}
|
||||
{!hasPendingTransactions && connector && <WrappedStatusIcon connector={connector} />}
|
||||
{!hasPendingTransactions && <StatusIcon connectionType={connectionType} />}
|
||||
</Web3StatusConnected>
|
||||
)
|
||||
} else {
|
||||
|
@ -8,8 +8,8 @@ import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
|
||||
|
||||
import { UNI } from '../../constants/tokens'
|
||||
import useENS from '../../hooks/useENS'
|
||||
import { useTokenBalance } from '../../state/connection/hooks'
|
||||
import { useDelegateCallback } from '../../state/governance/hooks'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { ThemedText } from '../../theme'
|
||||
import AddressInputPanel from '../AddressInputPanel'
|
||||
import { ButtonPrimary } from '../Button'
|
||||
|
100
src/connection/index.ts
Normal file
100
src/connection/index.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { CoinbaseWallet } from '@web3-react/coinbase-wallet'
|
||||
import { initializeConnector, Web3ReactHooks } from '@web3-react/core'
|
||||
import { EIP1193 } from '@web3-react/eip1193'
|
||||
import { GnosisSafe } from '@web3-react/gnosis-safe'
|
||||
import { MetaMask } from '@web3-react/metamask'
|
||||
import { Network } from '@web3-react/network'
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { WalletConnect } from '@web3-react/walletconnect'
|
||||
import { SupportedChainId } from 'constants/chains'
|
||||
import { INFURA_NETWORK_URLS } from 'constants/infura'
|
||||
import Fortmatic from 'fortmatic'
|
||||
|
||||
import UNISWAP_LOGO_URL from '../assets/svg/logo.svg'
|
||||
|
||||
export enum ConnectionType {
|
||||
INJECTED = 'INJECTED',
|
||||
COINBASE_WALLET = 'COINBASE_WALLET',
|
||||
WALLET_CONNECT = 'WALLET_CONNECT',
|
||||
FORTMATIC = 'FORTMATIC',
|
||||
NETWORK = 'NETWORK',
|
||||
GNOSIS_SAFE = 'GNOSIS_SAFE',
|
||||
}
|
||||
|
||||
export interface Connection {
|
||||
connector: Connector
|
||||
hooks: Web3ReactHooks
|
||||
type: ConnectionType
|
||||
}
|
||||
|
||||
function onError(error: Error) {
|
||||
console.debug(`web3-react error: ${error}`)
|
||||
}
|
||||
|
||||
const [web3Network, web3NetworkHooks] = initializeConnector<Network>(
|
||||
(actions) => new Network({ actions, urlMap: INFURA_NETWORK_URLS, defaultChainId: 1 })
|
||||
)
|
||||
export const networkConnection: Connection = {
|
||||
connector: web3Network,
|
||||
hooks: web3NetworkHooks,
|
||||
type: ConnectionType.NETWORK,
|
||||
}
|
||||
|
||||
const [web3Injected, web3InjectedHooks] = initializeConnector<MetaMask>((actions) => new MetaMask({ actions, onError }))
|
||||
export const injectedConnection: Connection = {
|
||||
connector: web3Injected,
|
||||
hooks: web3InjectedHooks,
|
||||
type: ConnectionType.INJECTED,
|
||||
}
|
||||
|
||||
const [web3GnosisSafe, web3GnosisSafeHooks] = initializeConnector<GnosisSafe>((actions) => new GnosisSafe({ actions }))
|
||||
export const gnosisSafeConnection: Connection = {
|
||||
connector: web3GnosisSafe,
|
||||
hooks: web3GnosisSafeHooks,
|
||||
type: ConnectionType.GNOSIS_SAFE,
|
||||
}
|
||||
|
||||
const [web3WalletConnect, web3WalletConnectHooks] = initializeConnector<WalletConnect>(
|
||||
(actions) =>
|
||||
new WalletConnect({
|
||||
actions,
|
||||
options: {
|
||||
rpc: INFURA_NETWORK_URLS,
|
||||
qrcode: true,
|
||||
},
|
||||
onError,
|
||||
})
|
||||
)
|
||||
export const walletConnectConnection: Connection = {
|
||||
connector: web3WalletConnect,
|
||||
hooks: web3WalletConnectHooks,
|
||||
type: ConnectionType.WALLET_CONNECT,
|
||||
}
|
||||
|
||||
const [web3Fortmatic, web3FortmaticHooks] = initializeConnector<EIP1193>(
|
||||
(actions) => new EIP1193({ actions, provider: new Fortmatic(process.env.REACT_APP_FORTMATIC_KEY).getProvider() })
|
||||
)
|
||||
export const fortmaticConnection: Connection = {
|
||||
connector: web3Fortmatic,
|
||||
hooks: web3FortmaticHooks,
|
||||
type: ConnectionType.FORTMATIC,
|
||||
}
|
||||
|
||||
const [web3CoinbaseWallet, web3CoinbaseWalletHooks] = initializeConnector<CoinbaseWallet>(
|
||||
(actions) =>
|
||||
new CoinbaseWallet({
|
||||
actions,
|
||||
options: {
|
||||
url: INFURA_NETWORK_URLS[SupportedChainId.MAINNET],
|
||||
appName: 'Uniswap',
|
||||
appLogoUrl: UNISWAP_LOGO_URL,
|
||||
reloadOnDisconnect: false,
|
||||
},
|
||||
onError,
|
||||
})
|
||||
)
|
||||
export const coinbaseWalletConnection: Connection = {
|
||||
connector: web3CoinbaseWallet,
|
||||
hooks: web3CoinbaseWalletHooks,
|
||||
type: ConnectionType.COINBASE_WALLET,
|
||||
}
|
44
src/connection/utils.ts
Normal file
44
src/connection/utils.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Connector } from '@web3-react/types'
|
||||
import {
|
||||
coinbaseWalletConnection,
|
||||
ConnectionType,
|
||||
fortmaticConnection,
|
||||
gnosisSafeConnection,
|
||||
injectedConnection,
|
||||
networkConnection,
|
||||
walletConnectConnection,
|
||||
} from 'connection'
|
||||
|
||||
const CONNECTIONS = [
|
||||
coinbaseWalletConnection,
|
||||
fortmaticConnection,
|
||||
injectedConnection,
|
||||
networkConnection,
|
||||
walletConnectConnection,
|
||||
gnosisSafeConnection,
|
||||
]
|
||||
|
||||
export function getConnection(c: Connector | ConnectionType) {
|
||||
if (c instanceof Connector) {
|
||||
const connection = CONNECTIONS.find((connection) => connection.connector === c)
|
||||
if (!connection) {
|
||||
throw Error('unsupported connector')
|
||||
}
|
||||
return connection
|
||||
} else {
|
||||
switch (c) {
|
||||
case ConnectionType.INJECTED:
|
||||
return injectedConnection
|
||||
case ConnectionType.COINBASE_WALLET:
|
||||
return coinbaseWalletConnection
|
||||
case ConnectionType.WALLET_CONNECT:
|
||||
return walletConnectConnection
|
||||
case ConnectionType.FORTMATIC:
|
||||
return fortmaticConnection
|
||||
case ConnectionType.NETWORK:
|
||||
return networkConnection
|
||||
case ConnectionType.GNOSIS_SAFE:
|
||||
return gnosisSafeConnection
|
||||
}
|
||||
}
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
import { CoinbaseWallet } from '@web3-react/coinbase-wallet'
|
||||
import { initializeConnector, Web3ReactHooks } from '@web3-react/core'
|
||||
import { EIP1193 } from '@web3-react/eip1193'
|
||||
import { GnosisSafe } from '@web3-react/gnosis-safe'
|
||||
import { MetaMask } from '@web3-react/metamask'
|
||||
import { Network } from '@web3-react/network'
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { WalletConnect } from '@web3-react/walletconnect'
|
||||
import { SupportedChainId } from 'constants/chains'
|
||||
import { INFURA_NETWORK_URLS } from 'constants/infura'
|
||||
import Fortmatic from 'fortmatic'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import UNISWAP_LOGO_URL from '../assets/svg/logo.svg'
|
||||
|
||||
export enum Wallet {
|
||||
INJECTED = 'INJECTED',
|
||||
COINBASE_WALLET = 'COINBASE_WALLET',
|
||||
WALLET_CONNECT = 'WALLET_CONNECT',
|
||||
FORTMATIC = 'FORTMATIC',
|
||||
NETWORK = 'NETWORK',
|
||||
GNOSIS_SAFE = 'GNOSIS_SAFE',
|
||||
}
|
||||
|
||||
export const BACKFILLABLE_WALLETS = [Wallet.COINBASE_WALLET, Wallet.WALLET_CONNECT, Wallet.INJECTED]
|
||||
export const SELECTABLE_WALLETS = [...BACKFILLABLE_WALLETS, Wallet.FORTMATIC]
|
||||
|
||||
function onError(error: Error) {
|
||||
console.debug(`web3-react error: ${error}`)
|
||||
}
|
||||
|
||||
export function getWalletForConnector(connector: Connector) {
|
||||
switch (connector) {
|
||||
case injected:
|
||||
return Wallet.INJECTED
|
||||
case coinbaseWallet:
|
||||
return Wallet.COINBASE_WALLET
|
||||
case walletConnect:
|
||||
return Wallet.WALLET_CONNECT
|
||||
case fortmatic:
|
||||
return Wallet.FORTMATIC
|
||||
case network:
|
||||
return Wallet.NETWORK
|
||||
case gnosisSafe:
|
||||
return Wallet.GNOSIS_SAFE
|
||||
default:
|
||||
throw Error('unsupported connector')
|
||||
}
|
||||
}
|
||||
|
||||
export function getConnectorForWallet(wallet: Wallet) {
|
||||
switch (wallet) {
|
||||
case Wallet.INJECTED:
|
||||
return injected
|
||||
case Wallet.COINBASE_WALLET:
|
||||
return coinbaseWallet
|
||||
case Wallet.WALLET_CONNECT:
|
||||
return walletConnect
|
||||
case Wallet.FORTMATIC:
|
||||
return fortmatic
|
||||
case Wallet.NETWORK:
|
||||
return network
|
||||
case Wallet.GNOSIS_SAFE:
|
||||
return gnosisSafe
|
||||
}
|
||||
}
|
||||
|
||||
function getHooksForWallet(wallet: Wallet) {
|
||||
switch (wallet) {
|
||||
case Wallet.INJECTED:
|
||||
return injectedHooks
|
||||
case Wallet.COINBASE_WALLET:
|
||||
return coinbaseWalletHooks
|
||||
case Wallet.WALLET_CONNECT:
|
||||
return walletConnectHooks
|
||||
case Wallet.FORTMATIC:
|
||||
return fortmaticHooks
|
||||
case Wallet.NETWORK:
|
||||
return networkHooks
|
||||
case Wallet.GNOSIS_SAFE:
|
||||
return gnosisSafeHooks
|
||||
}
|
||||
}
|
||||
|
||||
export const [network, networkHooks] = initializeConnector<Network>(
|
||||
(actions) => new Network({ actions, urlMap: INFURA_NETWORK_URLS, defaultChainId: 1 })
|
||||
)
|
||||
|
||||
export const [injected, injectedHooks] = initializeConnector<MetaMask>((actions) => new MetaMask({ actions, onError }))
|
||||
|
||||
export const [gnosisSafe, gnosisSafeHooks] = initializeConnector<GnosisSafe>((actions) => new GnosisSafe({ actions }))
|
||||
|
||||
export const [walletConnect, walletConnectHooks] = initializeConnector<WalletConnect>(
|
||||
(actions) =>
|
||||
new WalletConnect({
|
||||
actions,
|
||||
options: {
|
||||
rpc: INFURA_NETWORK_URLS,
|
||||
qrcode: true,
|
||||
},
|
||||
onError,
|
||||
})
|
||||
)
|
||||
|
||||
export const [fortmatic, fortmaticHooks] = initializeConnector<EIP1193>(
|
||||
(actions) => new EIP1193({ actions, provider: new Fortmatic(process.env.REACT_APP_FORTMATIC_KEY).getProvider() })
|
||||
)
|
||||
|
||||
export const [coinbaseWallet, coinbaseWalletHooks] = initializeConnector<CoinbaseWallet>(
|
||||
(actions) =>
|
||||
new CoinbaseWallet({
|
||||
actions,
|
||||
options: {
|
||||
url: INFURA_NETWORK_URLS[SupportedChainId.MAINNET],
|
||||
appName: 'Uniswap',
|
||||
appLogoUrl: UNISWAP_LOGO_URL,
|
||||
reloadOnDisconnect: false,
|
||||
},
|
||||
onError,
|
||||
})
|
||||
)
|
||||
|
||||
interface ConnectorListItem {
|
||||
connector: Connector
|
||||
hooks: Web3ReactHooks
|
||||
}
|
||||
|
||||
function getConnectorListItemForWallet(wallet: Wallet) {
|
||||
return {
|
||||
connector: getConnectorForWallet(wallet),
|
||||
hooks: getHooksForWallet(wallet),
|
||||
}
|
||||
}
|
||||
|
||||
export function useConnectors(selectedWallet: Wallet | undefined) {
|
||||
return useMemo(() => {
|
||||
const connectors: ConnectorListItem[] = [{ connector: gnosisSafe, hooks: gnosisSafeHooks }]
|
||||
if (selectedWallet) {
|
||||
connectors.push(getConnectorListItemForWallet(selectedWallet))
|
||||
}
|
||||
connectors.push(
|
||||
...SELECTABLE_WALLETS.filter((wallet) => wallet !== selectedWallet).map(getConnectorListItemForWallet)
|
||||
)
|
||||
connectors.push({ connector: network, hooks: networkHooks })
|
||||
const web3ReactConnectors: [Connector, Web3ReactHooks][] = connectors.map(({ connector, hooks }) => [
|
||||
connector,
|
||||
hooks,
|
||||
])
|
||||
return web3ReactConnectors
|
||||
}, [selectedWallet])
|
||||
}
|
@ -1,15 +1,21 @@
|
||||
import { Connector } from '@web3-react/types'
|
||||
import {
|
||||
coinbaseWalletConnection,
|
||||
ConnectionType,
|
||||
fortmaticConnection,
|
||||
injectedConnection,
|
||||
walletConnectConnection,
|
||||
} from 'connection'
|
||||
|
||||
import INJECTED_ICON_URL from '../assets/images/arrow-right.svg'
|
||||
import COINBASE_ICON_URL from '../assets/images/coinbaseWalletIcon.svg'
|
||||
import FORTMATIC_ICON_URL from '../assets/images/fortmaticIcon.png'
|
||||
import METAMASK_ICON_URL from '../assets/images/metamask.png'
|
||||
import WALLETCONNECT_ICON_URL from '../assets/images/walletConnectIcon.svg'
|
||||
import { coinbaseWallet, fortmatic, injected, Wallet, walletConnect } from '../connectors'
|
||||
|
||||
interface WalletInfo {
|
||||
connector?: Connector
|
||||
wallet?: Wallet
|
||||
connectionType?: ConnectionType
|
||||
name: string
|
||||
iconURL: string
|
||||
description: string
|
||||
@ -22,8 +28,8 @@ interface WalletInfo {
|
||||
|
||||
export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
|
||||
INJECTED: {
|
||||
connector: injected,
|
||||
wallet: Wallet.INJECTED,
|
||||
connector: injectedConnection.connector,
|
||||
connectionType: ConnectionType.INJECTED,
|
||||
name: 'Injected',
|
||||
iconURL: INJECTED_ICON_URL,
|
||||
description: 'Injected web3 provider.',
|
||||
@ -32,8 +38,8 @@ export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
|
||||
primary: true,
|
||||
},
|
||||
METAMASK: {
|
||||
connector: injected,
|
||||
wallet: Wallet.INJECTED,
|
||||
connector: injectedConnection.connector,
|
||||
connectionType: ConnectionType.INJECTED,
|
||||
name: 'MetaMask',
|
||||
iconURL: METAMASK_ICON_URL,
|
||||
description: 'Easy-to-use browser extension.',
|
||||
@ -41,8 +47,8 @@ export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
|
||||
color: '#E8831D',
|
||||
},
|
||||
WALLET_CONNECT: {
|
||||
connector: walletConnect,
|
||||
wallet: Wallet.WALLET_CONNECT,
|
||||
connector: walletConnectConnection.connector,
|
||||
connectionType: ConnectionType.WALLET_CONNECT,
|
||||
name: 'WalletConnect',
|
||||
iconURL: WALLETCONNECT_ICON_URL,
|
||||
description: 'Connect to Trust Wallet, Rainbow Wallet and more...',
|
||||
@ -51,8 +57,8 @@ export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
|
||||
mobile: true,
|
||||
},
|
||||
COINBASE_WALLET: {
|
||||
connector: coinbaseWallet,
|
||||
wallet: Wallet.COINBASE_WALLET,
|
||||
connector: coinbaseWalletConnection.connector,
|
||||
connectionType: ConnectionType.COINBASE_WALLET,
|
||||
name: 'Coinbase Wallet',
|
||||
iconURL: COINBASE_ICON_URL,
|
||||
description: 'Use Coinbase Wallet app on mobile device',
|
||||
@ -69,8 +75,8 @@ export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
|
||||
mobileOnly: true,
|
||||
},
|
||||
FORTMATIC: {
|
||||
connector: fortmatic,
|
||||
wallet: Wallet.FORTMATIC,
|
||||
connector: fortmaticConnection.connector,
|
||||
connectionType: ConnectionType.FORTMATIC,
|
||||
name: 'Fortmatic',
|
||||
iconURL: FORTMATIC_ICON_URL,
|
||||
description: 'Login using Fortmatic hosted wallet',
|
||||
|
34
src/hooks/useConnectors.ts
Normal file
34
src/hooks/useConnectors.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { Web3ReactHooks } from '@web3-react/core'
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { ConnectionType } from 'connection'
|
||||
import { getConnection } from 'connection/utils'
|
||||
import { useMemo } from 'react'
|
||||
import { BACKFILLABLE_WALLETS } from 'state/connection/constants'
|
||||
import { useAppSelector } from 'state/hooks'
|
||||
|
||||
const SELECTABLE_WALLETS = [...BACKFILLABLE_WALLETS, ConnectionType.FORTMATIC]
|
||||
|
||||
export default function useConnectors() {
|
||||
const selectedWallet = useAppSelector((state) => state.user.selectedWallet)
|
||||
return useMemo(() => {
|
||||
const orderedConnectionTypes: ConnectionType[] = []
|
||||
|
||||
// Always attempt to use to Gnosis Safe first, as we can't know if we're in a SafeContext.
|
||||
orderedConnectionTypes.push(ConnectionType.GNOSIS_SAFE)
|
||||
|
||||
// Add the `selectedWallet` to the top so it's prioritized, then add the other selectable wallets.
|
||||
if (selectedWallet) {
|
||||
orderedConnectionTypes.push(selectedWallet)
|
||||
}
|
||||
orderedConnectionTypes.push(...SELECTABLE_WALLETS.filter((wallet) => wallet !== selectedWallet))
|
||||
|
||||
// Add network connection last as it should be the fallback.
|
||||
orderedConnectionTypes.push(ConnectionType.NETWORK)
|
||||
|
||||
// Convert to web3-react's representation of connectors.
|
||||
const web3Connectors: [Connector, Web3ReactHooks][] = orderedConnectionTypes
|
||||
.map(getConnection)
|
||||
.map(({ connector, hooks }) => [connector, hooks])
|
||||
return web3Connectors
|
||||
}, [selectedWallet])
|
||||
}
|
42
src/hooks/useEagerlyConnect.ts
Normal file
42
src/hooks/useEagerlyConnect.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { gnosisSafeConnection, injectedConnection, networkConnection } from 'connection'
|
||||
import { getConnection } from 'connection/utils'
|
||||
import { useEffect } from 'react'
|
||||
import { BACKFILLABLE_WALLETS } from 'state/connection/constants'
|
||||
import { useAppSelector } from 'state/hooks'
|
||||
import { isMobile } from 'utils/userAgent'
|
||||
|
||||
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 selectedWalletBackfilled = useAppSelector((state) => state.user.selectedWalletBackfilled)
|
||||
const selectedWallet = useAppSelector((state) => state.user.selectedWallet)
|
||||
|
||||
const isMetaMask = !!window.ethereum?.isMetaMask
|
||||
|
||||
useEffect(() => {
|
||||
connect(gnosisSafeConnection.connector)
|
||||
connect(networkConnection.connector)
|
||||
|
||||
if (isMobile && isMetaMask) {
|
||||
injectedConnection.connector.activate()
|
||||
} else if (selectedWallet) {
|
||||
connect(getConnection(selectedWallet).connector)
|
||||
} else if (!selectedWalletBackfilled) {
|
||||
BACKFILLABLE_WALLETS.map(getConnection)
|
||||
.map((connection) => connection.connector)
|
||||
.forEach(connect)
|
||||
}
|
||||
// The dependency list is empty so this is only run once on mount
|
||||
}, []) // eslint-disable-line react-hooks/exhaustive-deps
|
||||
}
|
@ -3,7 +3,7 @@ import { useWeb3React } from '@web3-react/core'
|
||||
import { SOCKS_CONTROLLER_ADDRESSES } from 'constants/addresses'
|
||||
import { SupportedChainId } from 'constants/chains'
|
||||
import { useMemo } from 'react'
|
||||
import { useTokenBalance } from 'state/wallet/hooks'
|
||||
import { useTokenBalance } from 'state/connection/hooks'
|
||||
|
||||
// technically a 721, not an ERC20, but suffices for our purposes
|
||||
const SOCKS = new Token(SupportedChainId.MAINNET, SOCKS_CONTROLLER_ADDRESSES[SupportedChainId.MAINNET], 0)
|
||||
|
@ -6,9 +6,9 @@ import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { WRAPPED_NATIVE_CURRENCY } from '../constants/tokens'
|
||||
import { useCurrencyBalance } from '../state/connection/hooks'
|
||||
import { useTransactionAdder } from '../state/transactions/hooks'
|
||||
import { TransactionType } from '../state/transactions/types'
|
||||
import { useCurrencyBalance } from '../state/wallet/hooks'
|
||||
import { useWETHContract } from './useContract'
|
||||
|
||||
export enum WrapType {
|
||||
|
@ -24,8 +24,8 @@ import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
import useUSDCPrice from '../../hooks/useUSDCPrice'
|
||||
import { useV2Pair } from '../../hooks/useV2Pairs'
|
||||
import { useWalletModalToggle } from '../../state/application/hooks'
|
||||
import { useTokenBalance } from '../../state/connection/hooks'
|
||||
import { useStakingInfo } from '../../state/stake/hooks'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { ThemedText } from '../../theme'
|
||||
import { currencyId } from '../../utils/currencyId'
|
||||
|
||||
|
@ -44,8 +44,8 @@ import { useToken } from '../../hooks/Tokens'
|
||||
import { usePairContract, useV2MigratorContract } from '../../hooks/useContract'
|
||||
import useIsArgentWallet from '../../hooks/useIsArgentWallet'
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
import { useTokenBalance } from '../../state/connection/hooks'
|
||||
import { TransactionType } from '../../state/transactions/types'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { BackArrow, ExternalLink, ThemedText } from '../../theme'
|
||||
import { isAddress } from '../../utils'
|
||||
import { calculateGasMargin } from '../../utils/calculateGasMargin'
|
||||
|
@ -18,8 +18,8 @@ import QuestionHelper from '../../components/QuestionHelper'
|
||||
import { AutoRow } from '../../components/Row'
|
||||
import { Dots } from '../../components/swap/styleds'
|
||||
import { V2_FACTORY_ADDRESSES } from '../../constants/addresses'
|
||||
import { useTokenBalancesWithLoadingIndicator } from '../../state/connection/hooks'
|
||||
import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks'
|
||||
import { useTokenBalancesWithLoadingIndicator } from '../../state/wallet/hooks'
|
||||
import { BackArrow, StyledInternalLink, ThemedText } from '../../theme'
|
||||
import { BodyWrapper } from '../AppBody'
|
||||
|
||||
|
@ -20,9 +20,9 @@ import { Dots } from '../../components/swap/styleds'
|
||||
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
|
||||
import { BIG_INT_ZERO } from '../../constants/misc'
|
||||
import { useV2Pairs } from '../../hooks/useV2Pairs'
|
||||
import { useTokenBalancesWithLoadingIndicator } from '../../state/connection/hooks'
|
||||
import { useStakingInfo } from '../../state/stake/hooks'
|
||||
import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks'
|
||||
import { useTokenBalancesWithLoadingIndicator } from '../../state/wallet/hooks'
|
||||
import { ExternalLink, HideSmall, ThemedText } from '../../theme'
|
||||
|
||||
const PageWrapper = styled(AutoColumn)`
|
||||
|
@ -19,8 +19,8 @@ import CurrencySearchModal from '../../components/SearchModal/CurrencySearchModa
|
||||
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
|
||||
import { nativeOnChain } from '../../constants/tokens'
|
||||
import { PairState, useV2Pair } from '../../hooks/useV2Pairs'
|
||||
import { useTokenBalance } from '../../state/connection/hooks'
|
||||
import { usePairAdder } from '../../state/user/hooks'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { StyledInternalLink } from '../../theme'
|
||||
import { ThemedText } from '../../theme'
|
||||
import { currencyId } from '../../utils/currencyId'
|
||||
|
@ -18,9 +18,9 @@ import { Link } from 'react-router-dom'
|
||||
import { Button } from 'rebass/styled-components'
|
||||
import { useModalOpen, useToggleDelegateModal } from 'state/application/hooks'
|
||||
import { ApplicationModal } from 'state/application/reducer'
|
||||
import { useTokenBalance } from 'state/connection/hooks'
|
||||
import { ProposalData, ProposalState } from 'state/governance/hooks'
|
||||
import { useAllProposalData, useUserDelegatee, useUserVotes } from 'state/governance/hooks'
|
||||
import { useTokenBalance } from 'state/wallet/hooks'
|
||||
import styled from 'styled-components/macro'
|
||||
import { ExternalLink, ThemedText } from 'theme'
|
||||
import { shortenAddress } from 'utils'
|
||||
|
@ -38,6 +38,7 @@ import {
|
||||
useToggleVoteModal,
|
||||
} from '../../state/application/hooks'
|
||||
import { ApplicationModal } from '../../state/application/reducer'
|
||||
import { useTokenBalance } from '../../state/connection/hooks'
|
||||
import {
|
||||
ProposalData,
|
||||
ProposalState,
|
||||
@ -47,7 +48,6 @@ import {
|
||||
useUserVotesAsOfBlock,
|
||||
} from '../../state/governance/hooks'
|
||||
import { VoteOption } from '../../state/governance/types'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { ExternalLink, StyledInternalLink, ThemedText } from '../../theme'
|
||||
import { isAddress } from '../../utils'
|
||||
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
|
||||
|
@ -9,8 +9,8 @@ import { useAppDispatch, useAppSelector } from 'state/hooks'
|
||||
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
import { useV2Pair } from '../../hooks/useV2Pairs'
|
||||
import { useTokenBalances } from '../connection/hooks'
|
||||
import { AppState } from '../index'
|
||||
import { useTokenBalances } from '../wallet/hooks'
|
||||
import { Field, typeInput } from './actions'
|
||||
|
||||
export function useBurnState(): AppState['burn'] {
|
||||
|
7
src/state/connection/constants.ts
Normal file
7
src/state/connection/constants.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { ConnectionType } from 'connection'
|
||||
|
||||
export const BACKFILLABLE_WALLETS = [
|
||||
ConnectionType.COINBASE_WALLET,
|
||||
ConnectionType.WALLET_CONNECT,
|
||||
ConnectionType.INJECTED,
|
||||
]
|
33
src/state/connection/reducer.ts
Normal file
33
src/state/connection/reducer.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
import { ConnectionType } from 'connection'
|
||||
|
||||
export interface ConnectionState {
|
||||
errorByConnectionType: Record<ConnectionType, string | undefined>
|
||||
}
|
||||
|
||||
export const initialState: ConnectionState = {
|
||||
errorByConnectionType: {
|
||||
[ConnectionType.INJECTED]: undefined,
|
||||
[ConnectionType.FORTMATIC]: undefined,
|
||||
[ConnectionType.WALLET_CONNECT]: undefined,
|
||||
[ConnectionType.COINBASE_WALLET]: undefined,
|
||||
[ConnectionType.NETWORK]: undefined,
|
||||
[ConnectionType.GNOSIS_SAFE]: undefined,
|
||||
},
|
||||
}
|
||||
|
||||
const connectionSlice = createSlice({
|
||||
name: 'connection',
|
||||
initialState,
|
||||
reducers: {
|
||||
updateConnectionError(
|
||||
state,
|
||||
{ payload: { connectionType, error } }: { payload: { connectionType: ConnectionType; error: string | undefined } }
|
||||
) {
|
||||
state.errorByConnectionType[connectionType] = error
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { updateConnectionError } = connectionSlice.actions
|
||||
export default connectionSlice.reducer
|
@ -6,6 +6,7 @@ import { load, save } from 'redux-localstorage-simple'
|
||||
import application from './application/reducer'
|
||||
import burn from './burn/reducer'
|
||||
import burnV3 from './burn/v3/reducer'
|
||||
import connection from './connection/reducer'
|
||||
import { api as dataApi } from './data/slice'
|
||||
import { updateVersion } from './global/actions'
|
||||
import lists from './lists/reducer'
|
||||
@ -16,7 +17,6 @@ import { routingApi } from './routing/slice'
|
||||
import swap from './swap/reducer'
|
||||
import transactions from './transactions/reducer'
|
||||
import user from './user/reducer'
|
||||
import wallet from './wallet/reducer'
|
||||
|
||||
const PERSISTED_KEYS: string[] = ['user', 'transactions', 'lists']
|
||||
|
||||
@ -24,7 +24,7 @@ const store = configureStore({
|
||||
reducer: {
|
||||
application,
|
||||
user,
|
||||
wallet,
|
||||
connection,
|
||||
transactions,
|
||||
swap,
|
||||
mint,
|
||||
|
@ -9,8 +9,8 @@ import { useAppDispatch, useAppSelector } from 'state/hooks'
|
||||
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
import { PairState, useV2Pair } from '../../hooks/useV2Pairs'
|
||||
import { useCurrencyBalances } from '../connection/hooks'
|
||||
import { AppState } from '../index'
|
||||
import { useCurrencyBalances } from '../wallet/hooks'
|
||||
import { Field, typeInput } from './actions'
|
||||
|
||||
const ZERO = JSBI.BigInt(0)
|
||||
|
@ -23,8 +23,8 @@ import { replaceURLParam } from 'utils/routes'
|
||||
|
||||
import { BIG_INT_ZERO } from '../../../constants/misc'
|
||||
import { PoolState } from '../../../hooks/usePools'
|
||||
import { useCurrencyBalances } from '../../connection/hooks'
|
||||
import { AppState } from '../../index'
|
||||
import { useCurrencyBalances } from '../../wallet/hooks'
|
||||
import {
|
||||
Bound,
|
||||
Field,
|
||||
|
@ -15,8 +15,8 @@ import { useCurrency } from '../../hooks/Tokens'
|
||||
import useENS from '../../hooks/useENS'
|
||||
import useParsedQueryString from '../../hooks/useParsedQueryString'
|
||||
import { isAddress } from '../../utils'
|
||||
import { useCurrencyBalances } from '../connection/hooks'
|
||||
import { AppState } from '../index'
|
||||
import { useCurrencyBalances } from '../wallet/hooks'
|
||||
import { Field, replaceSwapState, selectCurrency, setRecipient, switchCurrencies, typeInput } from './actions'
|
||||
import { SwapState } from './reducer'
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
import { Wallet } from 'connectors'
|
||||
import { ConnectionType } from 'connection'
|
||||
import { SupportedLocale } from 'constants/locales'
|
||||
|
||||
import { DEFAULT_DEADLINE_FROM_NOW } from '../../constants/misc'
|
||||
@ -14,7 +14,7 @@ export interface UserState {
|
||||
// we want to handle that case by backfilling them manually. Once we backfill, we set the backfilled field to `true`.
|
||||
// After some period of time, our active users will have this property set so we can likely remove the backfilling logic.
|
||||
selectedWalletBackfilled: boolean
|
||||
selectedWallet?: Wallet
|
||||
selectedWallet?: ConnectionType
|
||||
|
||||
// the timestamp of the last updateVersion action
|
||||
lastUpdateVersionTimestamp?: number
|
||||
|
@ -1,33 +0,0 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
import { Wallet } from 'connectors'
|
||||
|
||||
export interface WalletState {
|
||||
errorByWallet: Record<Wallet, string | undefined>
|
||||
}
|
||||
|
||||
export const initialState: WalletState = {
|
||||
errorByWallet: {
|
||||
[Wallet.INJECTED]: undefined,
|
||||
[Wallet.FORTMATIC]: undefined,
|
||||
[Wallet.WALLET_CONNECT]: undefined,
|
||||
[Wallet.COINBASE_WALLET]: undefined,
|
||||
[Wallet.NETWORK]: undefined,
|
||||
[Wallet.GNOSIS_SAFE]: undefined,
|
||||
},
|
||||
}
|
||||
|
||||
const walletSlice = createSlice({
|
||||
name: 'wallet',
|
||||
initialState,
|
||||
reducers: {
|
||||
updateWalletError(
|
||||
state,
|
||||
{ payload: { wallet, error } }: { payload: { wallet: Wallet; error: string | undefined } }
|
||||
) {
|
||||
state.errorByWallet[wallet] = error
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { updateWalletError } = walletSlice.actions
|
||||
export default walletSlice.reducer
|
@ -1,5 +1,12 @@
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { coinbaseWallet, fortmatic, gnosisSafe, injected, network, walletConnect } from 'connectors'
|
||||
import {
|
||||
coinbaseWalletConnection,
|
||||
fortmaticConnection,
|
||||
gnosisSafeConnection,
|
||||
injectedConnection,
|
||||
networkConnection,
|
||||
walletConnectConnection,
|
||||
} from 'connection'
|
||||
import { CHAIN_INFO } from 'constants/chainInfo'
|
||||
import { ALL_SUPPORTED_CHAIN_IDS, SupportedChainId } from 'constants/chains'
|
||||
import { INFURA_NETWORK_URLS } from 'constants/infura'
|
||||
@ -32,13 +39,13 @@ function getRpcUrls(chainId: SupportedChainId): [string] {
|
||||
|
||||
export function isChainAllowed(connector: Connector, chainId: number) {
|
||||
switch (connector) {
|
||||
case fortmatic:
|
||||
case fortmaticConnection.connector:
|
||||
return chainId === SupportedChainId.MAINNET
|
||||
case injected:
|
||||
case coinbaseWallet:
|
||||
case walletConnect:
|
||||
case network:
|
||||
case gnosisSafe:
|
||||
case injectedConnection.connector:
|
||||
case coinbaseWalletConnection.connector:
|
||||
case walletConnectConnection.connector:
|
||||
case networkConnection.connector:
|
||||
case gnosisSafeConnection.connector:
|
||||
return ALL_SUPPORTED_CHAIN_IDS.includes(chainId)
|
||||
default:
|
||||
return false
|
||||
@ -48,7 +55,7 @@ export function isChainAllowed(connector: Connector, chainId: number) {
|
||||
export const switchChain = async (connector: Connector, chainId: number) => {
|
||||
if (!isChainAllowed(connector, chainId)) {
|
||||
throw new Error(`Chain ${chainId} not supported for connector (${typeof connector})`)
|
||||
} else if (connector === walletConnect || connector === network) {
|
||||
} else if (connector === walletConnectConnection.connector || connector === networkConnection.connector) {
|
||||
await connector.activate(chainId)
|
||||
} else {
|
||||
const info = CHAIN_INFO[chainId]
|
||||
|
Loading…
Reference in New Issue
Block a user