refactor: wallet specific Option components (#4065)
* refactor: wallet specific Option components * fix * fix * fix coinbase wallet logic * injected logic * remove wallet.ts * install metamask * move all into InjectedOption * fix mobile metamask * wip * more mocking * more test fixes * refactor * more special casing * isMetaMask * simplify components * fix imports * fix coinbase wallet * test fix * fix connectors changing * Revert "fix connectors changing" This reverts commit 2acfe645ca506048e599d515674a54b27d12144f. * more to typescript logic instead of jsx
This commit is contained in:
parent
817d808ec5
commit
869691d43f
@ -1,8 +1,8 @@
|
|||||||
import { Trans } from '@lingui/macro'
|
import { Trans } from '@lingui/macro'
|
||||||
import { useWeb3React } from '@web3-react/core'
|
import { useWeb3React } from '@web3-react/core'
|
||||||
import CopyHelper from 'components/AccountDetails/Copy'
|
import CopyHelper from 'components/AccountDetails/Copy'
|
||||||
import { coinbaseWalletConnection, injectedConnection } from 'connection'
|
import { coinbaseWalletConnection } from 'connection'
|
||||||
import { getConnection } from 'connection/utils'
|
import { getConnection, getConnectionName, getIsCoinbaseWallet, getIsMetaMask } from 'connection/utils'
|
||||||
import { useCallback, useContext } from 'react'
|
import { useCallback, useContext } from 'react'
|
||||||
import { ExternalLink as LinkIcon } from 'react-feather'
|
import { ExternalLink as LinkIcon } from 'react-feather'
|
||||||
import { useAppDispatch } from 'state/hooks'
|
import { useAppDispatch } from 'state/hooks'
|
||||||
@ -11,7 +11,6 @@ import styled, { ThemeContext } from 'styled-components/macro'
|
|||||||
import { isMobile } from 'utils/userAgent'
|
import { isMobile } from 'utils/userAgent'
|
||||||
|
|
||||||
import { ReactComponent as Close } from '../../assets/images/x.svg'
|
import { ReactComponent as Close } from '../../assets/images/x.svg'
|
||||||
import { SUPPORTED_WALLETS } from '../../constants/wallet'
|
|
||||||
import { clearAllTransactions } from '../../state/transactions/reducer'
|
import { clearAllTransactions } from '../../state/transactions/reducer'
|
||||||
import { ExternalLink, LinkStyledButton, ThemedText } from '../../theme'
|
import { ExternalLink, LinkStyledButton, ThemedText } from '../../theme'
|
||||||
import { shortenAddress } from '../../utils'
|
import { shortenAddress } from '../../utils'
|
||||||
@ -210,23 +209,14 @@ export default function AccountDetails({
|
|||||||
const theme = useContext(ThemeContext)
|
const theme = useContext(ThemeContext)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
const isMetaMask = !!window.ethereum?.isMetaMask
|
const isMetaMask = getIsMetaMask()
|
||||||
const isCoinbaseWallet = !!window.ethereum?.isCoinbaseWallet
|
const isCoinbaseWallet = getIsCoinbaseWallet()
|
||||||
const isInjectedMobileBrowser = (isMetaMask || isCoinbaseWallet) && isMobile
|
const isInjectedMobileBrowser = (isMetaMask || isCoinbaseWallet) && isMobile
|
||||||
|
|
||||||
function formatConnectorName() {
|
function formatConnectorName() {
|
||||||
const { ethereum } = window
|
|
||||||
const isMetaMask = !!(ethereum && ethereum.isMetaMask)
|
|
||||||
const name = Object.keys(SUPPORTED_WALLETS)
|
|
||||||
.filter(
|
|
||||||
(k) =>
|
|
||||||
SUPPORTED_WALLETS[k].connector === connector &&
|
|
||||||
(connector !== injectedConnection.connector || isMetaMask === (k === 'METAMASK'))
|
|
||||||
)
|
|
||||||
.map((k) => SUPPORTED_WALLETS[k].name)[0]
|
|
||||||
return (
|
return (
|
||||||
<WalletName>
|
<WalletName>
|
||||||
<Trans>Connected with {name}</Trans>
|
<Trans>Connected with</Trans> {getConnectionName(connectionType, isMetaMask)}
|
||||||
</WalletName>
|
</WalletName>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
36
src/components/WalletModal/CoinbaseWalletOption.tsx
Normal file
36
src/components/WalletModal/CoinbaseWalletOption.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { Connector } from '@web3-react/types'
|
||||||
|
import COINBASE_ICON_URL from 'assets/images/coinbaseWalletIcon.svg'
|
||||||
|
import { coinbaseWalletConnection, ConnectionType } from 'connection'
|
||||||
|
import { getConnectionName } from 'connection/utils'
|
||||||
|
|
||||||
|
import Option from './Option'
|
||||||
|
|
||||||
|
const BASE_PROPS = {
|
||||||
|
color: '#315CF5',
|
||||||
|
icon: COINBASE_ICON_URL,
|
||||||
|
id: 'coinbase-wallet',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function OpenCoinbaseWalletOption() {
|
||||||
|
const isActive = coinbaseWalletConnection.hooks.useIsActive()
|
||||||
|
return (
|
||||||
|
<Option
|
||||||
|
{...BASE_PROPS}
|
||||||
|
isActive={isActive}
|
||||||
|
link="https://go.cb-w.com/mtUDhEZPy1"
|
||||||
|
header="Open in Coinbase Wallet"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CoinbaseWalletOption({ tryActivation }: { tryActivation: (connector: Connector) => void }) {
|
||||||
|
const isActive = coinbaseWalletConnection.hooks.useIsActive()
|
||||||
|
return (
|
||||||
|
<Option
|
||||||
|
{...BASE_PROPS}
|
||||||
|
isActive={isActive}
|
||||||
|
onClick={() => tryActivation(coinbaseWalletConnection.connector)}
|
||||||
|
header={getConnectionName(ConnectionType.COINBASE_WALLET)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
24
src/components/WalletModal/FortmaticOption.tsx
Normal file
24
src/components/WalletModal/FortmaticOption.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { Connector } from '@web3-react/types'
|
||||||
|
import FORTMATIC_ICON_URL from 'assets/images/fortmaticIcon.png'
|
||||||
|
import { ConnectionType, fortmaticConnection } from 'connection'
|
||||||
|
import { getConnectionName } from 'connection/utils'
|
||||||
|
|
||||||
|
import Option from './Option'
|
||||||
|
|
||||||
|
const BASE_PROPS = {
|
||||||
|
color: '#6748FF',
|
||||||
|
icon: FORTMATIC_ICON_URL,
|
||||||
|
id: 'fortmatic',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FortmaticOption({ tryActivation }: { tryActivation: (connector: Connector) => void }) {
|
||||||
|
const isActive = fortmaticConnection.hooks.useIsActive()
|
||||||
|
return (
|
||||||
|
<Option
|
||||||
|
{...BASE_PROPS}
|
||||||
|
isActive={isActive}
|
||||||
|
onClick={() => tryActivation(fortmaticConnection.connector)}
|
||||||
|
header={getConnectionName(ConnectionType.FORTMATIC)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
48
src/components/WalletModal/InjectedOption.tsx
Normal file
48
src/components/WalletModal/InjectedOption.tsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { Trans } from '@lingui/macro'
|
||||||
|
import { Connector } from '@web3-react/types'
|
||||||
|
import INJECTED_ICON_URL from 'assets/images/arrow-right.svg'
|
||||||
|
import METAMASK_ICON_URL from 'assets/images/metamask.png'
|
||||||
|
import { ConnectionType, injectedConnection } from 'connection'
|
||||||
|
import { getConnectionName } from 'connection/utils'
|
||||||
|
|
||||||
|
import Option from './Option'
|
||||||
|
|
||||||
|
const INJECTED_PROPS = {
|
||||||
|
color: '#010101',
|
||||||
|
icon: INJECTED_ICON_URL,
|
||||||
|
id: 'injected',
|
||||||
|
}
|
||||||
|
|
||||||
|
const METAMASK_PROPS = {
|
||||||
|
color: '#E8831D',
|
||||||
|
icon: METAMASK_ICON_URL,
|
||||||
|
id: 'metamask',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function InstallMetaMaskOption() {
|
||||||
|
return <Option {...METAMASK_PROPS} header={<Trans>Install MetaMask</Trans>} link={'https://metamask.io/'} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MetaMaskOption({ tryActivation }: { tryActivation: (connector: Connector) => void }) {
|
||||||
|
const isActive = injectedConnection.hooks.useIsActive()
|
||||||
|
return (
|
||||||
|
<Option
|
||||||
|
{...METAMASK_PROPS}
|
||||||
|
isActive={isActive}
|
||||||
|
header={getConnectionName(ConnectionType.INJECTED, true)}
|
||||||
|
onClick={() => tryActivation(injectedConnection.connector)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function InjectedOption({ tryActivation }: { tryActivation: (connector: Connector) => void }) {
|
||||||
|
const isActive = injectedConnection.hooks.useIsActive()
|
||||||
|
return (
|
||||||
|
<Option
|
||||||
|
{...INJECTED_PROPS}
|
||||||
|
isActive={isActive}
|
||||||
|
header={getConnectionName(ConnectionType.INJECTED, false)}
|
||||||
|
onClick={() => tryActivation(injectedConnection.connector)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
@ -95,7 +95,7 @@ export default function Option({
|
|||||||
onClick = null,
|
onClick = null,
|
||||||
color,
|
color,
|
||||||
header,
|
header,
|
||||||
subheader = null,
|
subheader,
|
||||||
icon,
|
icon,
|
||||||
isActive = false,
|
isActive = false,
|
||||||
id,
|
id,
|
||||||
@ -106,7 +106,7 @@ export default function Option({
|
|||||||
onClick?: null | (() => void)
|
onClick?: null | (() => void)
|
||||||
color: string
|
color: string
|
||||||
header: React.ReactNode
|
header: React.ReactNode
|
||||||
subheader: React.ReactNode | null
|
subheader?: React.ReactNode
|
||||||
icon: string
|
icon: string
|
||||||
isActive?: boolean
|
isActive?: boolean
|
||||||
id: string
|
id: string
|
||||||
|
24
src/components/WalletModal/WalletConnectOption.tsx
Normal file
24
src/components/WalletModal/WalletConnectOption.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { Connector } from '@web3-react/types'
|
||||||
|
import WALLET_CONNECT_ICON_URL from 'assets/images/walletConnectIcon.svg'
|
||||||
|
import { ConnectionType, walletConnectConnection } from 'connection'
|
||||||
|
import { getConnectionName } from 'connection/utils'
|
||||||
|
|
||||||
|
import Option from './Option'
|
||||||
|
|
||||||
|
const BASE_PROPS = {
|
||||||
|
color: '#4196FC',
|
||||||
|
icon: WALLET_CONNECT_ICON_URL,
|
||||||
|
id: 'wallet-connect',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function WalletConnectOption({ tryActivation }: { tryActivation: (connector: Connector) => void }) {
|
||||||
|
const isActive = walletConnectConnection.hooks.useIsActive()
|
||||||
|
return (
|
||||||
|
<Option
|
||||||
|
{...BASE_PROPS}
|
||||||
|
isActive={isActive}
|
||||||
|
onClick={() => tryActivation(walletConnectConnection.connector)}
|
||||||
|
header={getConnectionName(ConnectionType.WALLET_CONNECT)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
@ -1,14 +1,12 @@
|
|||||||
|
import * as connectionUtils from 'connection/utils'
|
||||||
import { ApplicationModal } from 'state/application/reducer'
|
import { ApplicationModal } from 'state/application/reducer'
|
||||||
|
|
||||||
import { render, screen } from '../../test-utils'
|
import { render, screen } from '../../test-utils'
|
||||||
import WalletModal from './index'
|
import WalletModal from './index'
|
||||||
|
|
||||||
beforeEach(() => {
|
afterEach(() => {
|
||||||
delete global.window.ethereum
|
jest.clearAllMocks()
|
||||||
})
|
jest.resetModules()
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
delete global.window.ethereum
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const UserAgentMock = jest.requireMock('utils/userAgent')
|
const UserAgentMock = jest.requireMock('utils/userAgent')
|
||||||
@ -47,8 +45,23 @@ it('loads Wallet Modal on desktop', async () => {
|
|||||||
expect(screen.getAllByTestId('wallet-modal-option')).toHaveLength(4)
|
expect(screen.getAllByTestId('wallet-modal-option')).toHaveLength(4)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('loads Wallet Modal on desktop with generic Injected', async () => {
|
||||||
|
jest.spyOn(connectionUtils, 'getIsInjected').mockReturnValue(true)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsMetaMask').mockReturnValue(false)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsCoinbaseWallet').mockReturnValue(false)
|
||||||
|
|
||||||
|
render(<WalletModal pendingTransactions={[]} confirmedTransactions={[]} />)
|
||||||
|
expect(screen.getByText('Injected')).toBeInTheDocument()
|
||||||
|
expect(screen.getByText('Coinbase Wallet')).toBeInTheDocument()
|
||||||
|
expect(screen.getByText('WalletConnect')).toBeInTheDocument()
|
||||||
|
expect(screen.getByText('Fortmatic')).toBeInTheDocument()
|
||||||
|
expect(screen.getAllByTestId('wallet-modal-option')).toHaveLength(4)
|
||||||
|
})
|
||||||
|
|
||||||
it('loads Wallet Modal on desktop with MetaMask installed', async () => {
|
it('loads Wallet Modal on desktop with MetaMask installed', async () => {
|
||||||
global.window.ethereum = { isMetaMask: true }
|
jest.spyOn(connectionUtils, 'getIsInjected').mockReturnValue(true)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsMetaMask').mockReturnValue(true)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsCoinbaseWallet').mockReturnValue(false)
|
||||||
|
|
||||||
render(<WalletModal pendingTransactions={[]} confirmedTransactions={[]} />)
|
render(<WalletModal pendingTransactions={[]} confirmedTransactions={[]} />)
|
||||||
expect(screen.getByText('MetaMask')).toBeInTheDocument()
|
expect(screen.getByText('MetaMask')).toBeInTheDocument()
|
||||||
@ -61,6 +74,10 @@ it('loads Wallet Modal on desktop with MetaMask installed', async () => {
|
|||||||
it('loads Wallet Modal on mobile', async () => {
|
it('loads Wallet Modal on mobile', async () => {
|
||||||
UserAgentMock.isMobile = true
|
UserAgentMock.isMobile = true
|
||||||
|
|
||||||
|
jest.spyOn(connectionUtils, 'getIsInjected').mockReturnValue(false)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsMetaMask').mockReturnValue(false)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsCoinbaseWallet').mockReturnValue(false)
|
||||||
|
|
||||||
render(<WalletModal pendingTransactions={[]} confirmedTransactions={[]} />)
|
render(<WalletModal pendingTransactions={[]} confirmedTransactions={[]} />)
|
||||||
expect(screen.getByText('Open in Coinbase Wallet')).toBeInTheDocument()
|
expect(screen.getByText('Open in Coinbase Wallet')).toBeInTheDocument()
|
||||||
expect(screen.getByText('WalletConnect')).toBeInTheDocument()
|
expect(screen.getByText('WalletConnect')).toBeInTheDocument()
|
||||||
@ -70,7 +87,10 @@ it('loads Wallet Modal on mobile', async () => {
|
|||||||
|
|
||||||
it('loads Wallet Modal on MetaMask browser', async () => {
|
it('loads Wallet Modal on MetaMask browser', async () => {
|
||||||
UserAgentMock.isMobile = true
|
UserAgentMock.isMobile = true
|
||||||
global.window.ethereum = { isMetaMask: true }
|
|
||||||
|
jest.spyOn(connectionUtils, 'getIsInjected').mockReturnValue(true)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsMetaMask').mockReturnValue(true)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsCoinbaseWallet').mockReturnValue(false)
|
||||||
|
|
||||||
render(<WalletModal pendingTransactions={[]} confirmedTransactions={[]} />)
|
render(<WalletModal pendingTransactions={[]} confirmedTransactions={[]} />)
|
||||||
expect(screen.getByText('MetaMask')).toBeInTheDocument()
|
expect(screen.getByText('MetaMask')).toBeInTheDocument()
|
||||||
@ -79,7 +99,10 @@ it('loads Wallet Modal on MetaMask browser', async () => {
|
|||||||
|
|
||||||
it('loads Wallet Modal on Coinbase Wallet browser', async () => {
|
it('loads Wallet Modal on Coinbase Wallet browser', async () => {
|
||||||
UserAgentMock.isMobile = true
|
UserAgentMock.isMobile = true
|
||||||
global.window.ethereum = { isCoinbaseWallet: true }
|
|
||||||
|
jest.spyOn(connectionUtils, 'getIsInjected').mockReturnValue(true)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsMetaMask').mockReturnValue(false)
|
||||||
|
jest.spyOn(connectionUtils, 'getIsCoinbaseWallet').mockReturnValue(true)
|
||||||
|
|
||||||
render(<WalletModal pendingTransactions={[]} confirmedTransactions={[]} />)
|
render(<WalletModal pendingTransactions={[]} confirmedTransactions={[]} />)
|
||||||
expect(screen.getByText('Coinbase Wallet')).toBeInTheDocument()
|
expect(screen.getByText('Coinbase Wallet')).toBeInTheDocument()
|
||||||
|
@ -4,27 +4,28 @@ import { Connector } from '@web3-react/types'
|
|||||||
import { sendEvent } from 'components/analytics'
|
import { sendEvent } from 'components/analytics'
|
||||||
import { AutoColumn } from 'components/Column'
|
import { AutoColumn } from 'components/Column'
|
||||||
import { AutoRow } from 'components/Row'
|
import { AutoRow } from 'components/Row'
|
||||||
import { ConnectionType, injectedConnection } from 'connection'
|
import { ConnectionType } from 'connection'
|
||||||
import { getConnection } from 'connection/utils'
|
import { getConnection, getIsCoinbaseWallet, getIsInjected, getIsMetaMask } from 'connection/utils'
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { ArrowLeft } from 'react-feather'
|
import { ArrowLeft } from 'react-feather'
|
||||||
import { updateConnectionError } from 'state/connection/reducer'
|
import { updateConnectionError } from 'state/connection/reducer'
|
||||||
import { useAppDispatch, useAppSelector } from 'state/hooks'
|
import { useAppDispatch, useAppSelector } from 'state/hooks'
|
||||||
import { updateSelectedWallet } from 'state/user/reducer'
|
import { updateSelectedWallet } from 'state/user/reducer'
|
||||||
import styled from 'styled-components/macro'
|
import styled from 'styled-components/macro'
|
||||||
|
import { isMobile } from 'utils/userAgent'
|
||||||
|
|
||||||
import MetamaskIcon from '../../assets/images/metamask.png'
|
|
||||||
import { ReactComponent as Close } from '../../assets/images/x.svg'
|
import { ReactComponent as Close } from '../../assets/images/x.svg'
|
||||||
import { SUPPORTED_WALLETS } from '../../constants/wallet'
|
|
||||||
import { useModalIsOpen, useToggleWalletModal } from '../../state/application/hooks'
|
import { useModalIsOpen, useToggleWalletModal } from '../../state/application/hooks'
|
||||||
import { ApplicationModal } from '../../state/application/reducer'
|
import { ApplicationModal } from '../../state/application/reducer'
|
||||||
import { ExternalLink, ThemedText } from '../../theme'
|
import { ExternalLink, ThemedText } from '../../theme'
|
||||||
import { isMobile } from '../../utils/userAgent'
|
|
||||||
import AccountDetails from '../AccountDetails'
|
import AccountDetails from '../AccountDetails'
|
||||||
import { LightCard } from '../Card'
|
import { LightCard } from '../Card'
|
||||||
import Modal from '../Modal'
|
import Modal from '../Modal'
|
||||||
import Option from './Option'
|
import { CoinbaseWalletOption, OpenCoinbaseWalletOption } from './CoinbaseWalletOption'
|
||||||
|
import { FortmaticOption } from './FortmaticOption'
|
||||||
|
import { InjectedOption, InstallMetaMaskOption, MetaMaskOption } from './InjectedOption'
|
||||||
import PendingView from './PendingView'
|
import PendingView from './PendingView'
|
||||||
|
import { WalletConnectOption } from './WalletConnectOption'
|
||||||
|
|
||||||
const CloseIcon = styled.div`
|
const CloseIcon = styled.div`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -120,7 +121,7 @@ export default function WalletModal({
|
|||||||
ENSName?: string
|
ENSName?: string
|
||||||
}) {
|
}) {
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { connector, account } = useWeb3React()
|
const { account } = useWeb3React()
|
||||||
|
|
||||||
const [walletView, setWalletView] = useState(WALLET_VIEWS.ACCOUNT)
|
const [walletView, setWalletView] = useState(WALLET_VIEWS.ACCOUNT)
|
||||||
|
|
||||||
@ -182,91 +183,48 @@ export default function WalletModal({
|
|||||||
[dispatch, toggleWalletModal]
|
[dispatch, toggleWalletModal]
|
||||||
)
|
)
|
||||||
|
|
||||||
// get wallets user can switch too, depending on device/browser
|
|
||||||
function getOptions() {
|
function getOptions() {
|
||||||
const isMetaMask = !!window.ethereum?.isMetaMask
|
const isInjected = getIsInjected()
|
||||||
const isCoinbaseWallet = !!window.ethereum?.isCoinbaseWallet
|
const isMetaMask = getIsMetaMask()
|
||||||
return Object.keys(SUPPORTED_WALLETS).map((key) => {
|
const isCoinbaseWallet = getIsCoinbaseWallet()
|
||||||
const option = SUPPORTED_WALLETS[key]
|
|
||||||
|
|
||||||
const optionProps = {
|
const isCoinbaseWalletBrowser = isMobile && isCoinbaseWallet
|
||||||
isActive: option.connector === connector,
|
const isMetaMaskBrowser = isMobile && isMetaMask
|
||||||
id: `connect-${key}`,
|
const isInjectedMobileBrowser = isCoinbaseWalletBrowser || isMetaMaskBrowser
|
||||||
link: option.href,
|
|
||||||
header: option.name,
|
let injectedOption
|
||||||
color: option.color,
|
if (!isInjected) {
|
||||||
key,
|
if (!isMobile) {
|
||||||
icon: option.iconURL,
|
injectedOption = <InstallMetaMaskOption />
|
||||||
}
|
}
|
||||||
|
} else if (!isCoinbaseWallet) {
|
||||||
// check for mobile options
|
if (isMetaMask) {
|
||||||
if (isMobile) {
|
injectedOption = <MetaMaskOption tryActivation={tryActivation} />
|
||||||
if (
|
} else {
|
||||||
(!window.web3 && !window.ethereum && option.mobile) ||
|
injectedOption = <InjectedOption tryActivation={tryActivation} />
|
||||||
(isMetaMask && option.name === 'MetaMask') ||
|
|
||||||
(isCoinbaseWallet && option.name === 'Coinbase Wallet')
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<Option
|
|
||||||
{...optionProps}
|
|
||||||
onClick={() => {
|
|
||||||
if (!option.href && !!option.connector) {
|
|
||||||
tryActivation(option.connector)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
subheader={null}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// overwrite injected when needed
|
let coinbaseWalletOption
|
||||||
if (option.connector === injectedConnection.connector) {
|
if (isMobile && !isInjectedMobileBrowser) {
|
||||||
// don't show injected if there's no injected provider
|
coinbaseWalletOption = <OpenCoinbaseWalletOption />
|
||||||
if (!(window.web3 || window.ethereum)) {
|
} else if (!isMobile || isCoinbaseWalletBrowser) {
|
||||||
if (option.name === 'MetaMask') {
|
coinbaseWalletOption = <CoinbaseWalletOption tryActivation={tryActivation} />
|
||||||
return (
|
}
|
||||||
<Option
|
|
||||||
id={`connect-${key}`}
|
|
||||||
key={key}
|
|
||||||
color={'#E8831D'}
|
|
||||||
header={<Trans>Install MetaMask</Trans>}
|
|
||||||
subheader={null}
|
|
||||||
link={'https://metamask.io/'}
|
|
||||||
icon={MetamaskIcon}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return null //dont want to return install twice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// don't return metamask if injected provider isn't metamask
|
|
||||||
else if (option.name === 'MetaMask' && !isMetaMask) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
// likewise for generic
|
|
||||||
else if (option.name === 'Injected' && isMetaMask) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return rest of options
|
const walletConnectionOption =
|
||||||
return (
|
(!isInjectedMobileBrowser && <WalletConnectOption tryActivation={tryActivation} />) ?? null
|
||||||
!isMobile &&
|
|
||||||
!option.mobileOnly && (
|
const fortmaticOption = (!isInjectedMobileBrowser && <FortmaticOption tryActivation={tryActivation} />) ?? null
|
||||||
<Option
|
|
||||||
{...optionProps}
|
return (
|
||||||
onClick={() => {
|
<>
|
||||||
option.connector === connector
|
{injectedOption}
|
||||||
? setWalletView(WALLET_VIEWS.ACCOUNT)
|
{coinbaseWalletOption}
|
||||||
: !option.href && option.connector && tryActivation(option.connector)
|
{walletConnectionOption}
|
||||||
}}
|
{fortmaticOption}
|
||||||
subheader={null} //use option.descriptio to bring back multi-line
|
</>
|
||||||
/>
|
)
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getModalContent() {
|
function getModalContent() {
|
||||||
|
@ -18,6 +18,18 @@ const CONNECTIONS = [
|
|||||||
gnosisSafeConnection,
|
gnosisSafeConnection,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
export function getIsInjected(): boolean {
|
||||||
|
return Boolean(window.ethereum)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getIsMetaMask(): boolean {
|
||||||
|
return window.ethereum?.isMetaMask ?? false
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getIsCoinbaseWallet(): boolean {
|
||||||
|
return window.ethereum?.isCoinbaseWallet ?? false
|
||||||
|
}
|
||||||
|
|
||||||
export function getConnection(c: Connector | ConnectionType) {
|
export function getConnection(c: Connector | ConnectionType) {
|
||||||
if (c instanceof Connector) {
|
if (c instanceof Connector) {
|
||||||
const connection = CONNECTIONS.find((connection) => connection.connector === c)
|
const connection = CONNECTIONS.find((connection) => connection.connector === c)
|
||||||
@ -42,3 +54,20 @@ export function getConnection(c: Connector | ConnectionType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getConnectionName(connectionType: ConnectionType, isMetaMask?: boolean) {
|
||||||
|
switch (connectionType) {
|
||||||
|
case ConnectionType.INJECTED:
|
||||||
|
return isMetaMask ? 'MetaMask' : 'Injected'
|
||||||
|
case ConnectionType.COINBASE_WALLET:
|
||||||
|
return 'Coinbase Wallet'
|
||||||
|
case ConnectionType.WALLET_CONNECT:
|
||||||
|
return 'WalletConnect'
|
||||||
|
case ConnectionType.FORTMATIC:
|
||||||
|
return 'Fortmatic'
|
||||||
|
case ConnectionType.NETWORK:
|
||||||
|
return 'Network'
|
||||||
|
case ConnectionType.GNOSIS_SAFE:
|
||||||
|
return 'Gnosis Safe'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
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'
|
|
||||||
|
|
||||||
interface WalletInfo {
|
|
||||||
connector?: Connector
|
|
||||||
connectionType?: ConnectionType
|
|
||||||
name: string
|
|
||||||
iconURL: string
|
|
||||||
description: string
|
|
||||||
href: string | null
|
|
||||||
color: string
|
|
||||||
primary?: true
|
|
||||||
mobile?: true
|
|
||||||
mobileOnly?: true
|
|
||||||
}
|
|
||||||
|
|
||||||
export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
|
|
||||||
INJECTED: {
|
|
||||||
connector: injectedConnection.connector,
|
|
||||||
connectionType: ConnectionType.INJECTED,
|
|
||||||
name: 'Injected',
|
|
||||||
iconURL: INJECTED_ICON_URL,
|
|
||||||
description: 'Injected web3 provider.',
|
|
||||||
href: null,
|
|
||||||
color: '#010101',
|
|
||||||
primary: true,
|
|
||||||
},
|
|
||||||
METAMASK: {
|
|
||||||
connector: injectedConnection.connector,
|
|
||||||
connectionType: ConnectionType.INJECTED,
|
|
||||||
name: 'MetaMask',
|
|
||||||
iconURL: METAMASK_ICON_URL,
|
|
||||||
description: 'Easy-to-use browser extension.',
|
|
||||||
href: null,
|
|
||||||
color: '#E8831D',
|
|
||||||
},
|
|
||||||
WALLET_CONNECT: {
|
|
||||||
connector: walletConnectConnection.connector,
|
|
||||||
connectionType: ConnectionType.WALLET_CONNECT,
|
|
||||||
name: 'WalletConnect',
|
|
||||||
iconURL: WALLETCONNECT_ICON_URL,
|
|
||||||
description: 'Connect to Trust Wallet, Rainbow Wallet and more...',
|
|
||||||
href: null,
|
|
||||||
color: '#4196FC',
|
|
||||||
mobile: true,
|
|
||||||
},
|
|
||||||
COINBASE_WALLET: {
|
|
||||||
connector: coinbaseWalletConnection.connector,
|
|
||||||
connectionType: ConnectionType.COINBASE_WALLET,
|
|
||||||
name: 'Coinbase Wallet',
|
|
||||||
iconURL: COINBASE_ICON_URL,
|
|
||||||
description: 'Use Coinbase Wallet app on mobile device',
|
|
||||||
href: null,
|
|
||||||
color: '#315CF5',
|
|
||||||
},
|
|
||||||
COINBASE_LINK: {
|
|
||||||
name: 'Open in Coinbase Wallet',
|
|
||||||
iconURL: COINBASE_ICON_URL,
|
|
||||||
description: 'Open in Coinbase Wallet app.',
|
|
||||||
href: 'https://go.cb-w.com/mtUDhEZPy1',
|
|
||||||
color: '#315CF5',
|
|
||||||
mobile: true,
|
|
||||||
mobileOnly: true,
|
|
||||||
},
|
|
||||||
FORTMATIC: {
|
|
||||||
connector: fortmaticConnection.connector,
|
|
||||||
connectionType: ConnectionType.FORTMATIC,
|
|
||||||
name: 'Fortmatic',
|
|
||||||
iconURL: FORTMATIC_ICON_URL,
|
|
||||||
description: 'Login using Fortmatic hosted wallet',
|
|
||||||
href: null,
|
|
||||||
color: '#6748FF',
|
|
||||||
mobile: true,
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import { Connector } from '@web3-react/types'
|
import { Connector } from '@web3-react/types'
|
||||||
import { gnosisSafeConnection, injectedConnection, networkConnection } from 'connection'
|
import { gnosisSafeConnection, injectedConnection, networkConnection } from 'connection'
|
||||||
import { getConnection } from 'connection/utils'
|
import { getConnection, getIsMetaMask } from 'connection/utils'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { BACKFILLABLE_WALLETS } from 'state/connection/constants'
|
import { BACKFILLABLE_WALLETS } from 'state/connection/constants'
|
||||||
import { useAppSelector } from 'state/hooks'
|
import { useAppSelector } from 'state/hooks'
|
||||||
@ -22,7 +22,7 @@ export default function useEagerlyConnect() {
|
|||||||
const selectedWalletBackfilled = useAppSelector((state) => state.user.selectedWalletBackfilled)
|
const selectedWalletBackfilled = useAppSelector((state) => state.user.selectedWalletBackfilled)
|
||||||
const selectedWallet = useAppSelector((state) => state.user.selectedWallet)
|
const selectedWallet = useAppSelector((state) => state.user.selectedWallet)
|
||||||
|
|
||||||
const isMetaMask = !!window.ethereum?.isMetaMask
|
const isMetaMask = getIsMetaMask()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
connect(gnosisSafeConnection.connector)
|
connect(gnosisSafeConnection.connector)
|
||||||
|
Loading…
Reference in New Issue
Block a user