Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 5 additions & 15 deletions src/components/AccountDetails/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import CopyHelper from 'components/AccountDetails/Copy'
import { coinbaseWalletConnection, injectedConnection } from 'connection'
import { getConnection } from 'connection/utils'
import { coinbaseWalletConnection } from 'connection'
import { getConnection, getConnectionName, getIsCoinbaseWallet, getIsMetaMask } from 'connection/utils'
import { useCallback, useContext } from 'react'
import { ExternalLink as LinkIcon } from 'react-feather'
import { useAppDispatch } from 'state/hooks'
Expand All @@ -11,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 { SUPPORTED_WALLETS } from '../../constants/wallet'
import { clearAllTransactions } from '../../state/transactions/reducer'
import { ExternalLink, LinkStyledButton, ThemedText } from '../../theme'
import { shortenAddress } from '../../utils'
Expand Down Expand Up @@ -210,23 +209,14 @@ export default function AccountDetails({
const theme = useContext(ThemeContext)
const dispatch = useAppDispatch()

const isMetaMask = !!window.ethereum?.isMetaMask
const isCoinbaseWallet = !!window.ethereum?.isCoinbaseWallet
const isMetaMask = getIsMetaMask()
const isCoinbaseWallet = getIsCoinbaseWallet()
const isInjectedMobileBrowser = (isMetaMask || isCoinbaseWallet) && isMobile

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 (
<WalletName>
<Trans>Connected with {name}</Trans>
<Trans>Connected with</Trans> {getConnectionName(connectionType, isMetaMask)}
</WalletName>
)
}
Expand Down
36 changes: 36 additions & 0 deletions src/components/WalletModal/CoinbaseWalletOption.tsx
Original file line number Diff line number Diff line change
@@ -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 }) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eventually i wanna make tryActivation a hook

const isActive = coinbaseWalletConnection.hooks.useIsActive()
return (
<Option
{...BASE_PROPS}
isActive={isActive}
onClick={() => tryActivation(coinbaseWalletConnection.connector)}
header={getConnectionName(ConnectionType.COINBASE_WALLET)}
/>
)
}
24 changes: 24 additions & 0 deletions src/components/WalletModal/FortmaticOption.tsx
Original file line number Diff line number Diff line change
@@ -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 changes: 48 additions & 0 deletions src/components/WalletModal/InjectedOption.tsx
Original file line number Diff line number Diff line change
@@ -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)}
/>
)
}
4 changes: 2 additions & 2 deletions src/components/WalletModal/Option.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export default function Option({
onClick = null,
color,
header,
subheader = null,
subheader,
icon,
isActive = false,
id,
Expand All @@ -106,7 +106,7 @@ export default function Option({
onClick?: null | (() => void)
color: string
header: React.ReactNode
subheader: React.ReactNode | null
subheader?: React.ReactNode
icon: string
isActive?: boolean
id: string
Expand Down
24 changes: 24 additions & 0 deletions src/components/WalletModal/WalletConnectOption.tsx
Original file line number Diff line number Diff line change
@@ -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)}
/>
)
}
41 changes: 32 additions & 9 deletions src/components/WalletModal/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import * as connectionUtils from 'connection/utils'
import { ApplicationModal } from 'state/application/reducer'

import { render, screen } from '../../test-utils'
import WalletModal from './index'

beforeEach(() => {
delete global.window.ethereum
})

afterAll(() => {
delete global.window.ethereum
afterEach(() => {
jest.clearAllMocks()
jest.resetModules()
})

const UserAgentMock = jest.requireMock('utils/userAgent')
Expand Down Expand Up @@ -47,8 +45,23 @@ it('loads Wallet Modal on desktop', async () => {
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 () => {
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={[]} />)
expect(screen.getByText('MetaMask')).toBeInTheDocument()
Expand All @@ -61,6 +74,10 @@ it('loads Wallet Modal on desktop with MetaMask installed', async () => {
it('loads Wallet Modal on mobile', async () => {
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={[]} />)
expect(screen.getByText('Open in Coinbase Wallet')).toBeInTheDocument()
expect(screen.getByText('WalletConnect')).toBeInTheDocument()
Expand All @@ -70,7 +87,10 @@ it('loads Wallet Modal on mobile', async () => {

it('loads Wallet Modal on MetaMask browser', async () => {
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={[]} />)
expect(screen.getByText('MetaMask')).toBeInTheDocument()
Expand All @@ -79,7 +99,10 @@ it('loads Wallet Modal on MetaMask browser', async () => {

it('loads Wallet Modal on Coinbase Wallet browser', async () => {
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={[]} />)
expect(screen.getByText('Coinbase Wallet')).toBeInTheDocument()
Expand Down
Loading