Commit 1c4a383a authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

feat: gate v1 retirement (#6845)

* Revert "feat(wallet-connect): retire v1 (#6820)"

This reverts commit d6759b86.

* gate v1/v2 switch with v2 fallback on wc entry

* fix tests

* add a second flag--isolate ... menu and default values from each other

* Update src/components/WalletModal/Option.tsx
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>

* Update src/featureFlags/flags/walletConnectPopover.ts
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>

* pr feedback

* pr feedback

* pr nit

---------
Co-authored-by: default avatarJordan Frankfurt <jordan@CORN-Jordan-949.frankfurt>
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>
parent 469a0060
...@@ -10,6 +10,8 @@ import useMultiChainPositions from './useMultiChainPositions' ...@@ -10,6 +10,8 @@ import useMultiChainPositions from './useMultiChainPositions'
jest.mock('./useMultiChainPositions') jest.mock('./useMultiChainPositions')
jest.spyOn(console, 'warn').mockImplementation()
const owner = '0xf5b6bb25f5beaea03dd014c6ef9fa9f3926bf36c' const owner = '0xf5b6bb25f5beaea03dd014c6ef9fa9f3926bf36c'
const pool = new Pool( const pool = new Pool(
......
...@@ -2,13 +2,16 @@ import { Trans } from '@lingui/macro' ...@@ -2,13 +2,16 @@ import { Trans } from '@lingui/macro'
import { sendAnalyticsEvent } from '@uniswap/analytics' import { sendAnalyticsEvent } from '@uniswap/analytics'
import { InterfaceElementName } from '@uniswap/analytics-events' import { InterfaceElementName } from '@uniswap/analytics-events'
import { WalletConnect } from '@web3-react/walletconnect' import { WalletConnect } from '@web3-react/walletconnect'
import { WalletConnect as WalletConnectv2 } from '@web3-react/walletconnect-v2'
import Column, { AutoColumn } from 'components/Column' import Column, { AutoColumn } from 'components/Column'
import Modal from 'components/Modal' import Modal from 'components/Modal'
import { RowBetween } from 'components/Row' import { RowBetween } from 'components/Row'
import { uniwalletConnectConnection } from 'connection' import { uniwalletConnectConnection, uniwalletWCV2ConnectConnection } from 'connection'
import { ActivationStatus, useActivationState } from 'connection/activate' import { ActivationStatus, useActivationState } from 'connection/activate'
import { ConnectionType } from 'connection/types' import { ConnectionType } from 'connection/types'
import { UniwalletConnect } from 'connection/WalletConnect' import { UniwalletConnect } from 'connection/WalletConnect'
import { UniwalletConnect as UniwalletConnectV2 } from 'connection/WalletConnectV2'
import { useWalletConnectV2AsDefault } from 'featureFlags/flags/walletConnectV2'
import { QRCodeSVG } from 'qrcode.react' import { QRCodeSVG } from 'qrcode.react'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import styled, { useTheme } from 'styled-components/macro' import styled, { useTheme } from 'styled-components/macro'
...@@ -42,19 +45,27 @@ export default function UniwalletModal() { ...@@ -42,19 +45,27 @@ export default function UniwalletModal() {
const [uri, setUri] = useState<string>() const [uri, setUri] = useState<string>()
// Displays the modal if a Uniswap Wallet Connection is pending & qrcode URI is available // Displays the modal if a Uniswap Wallet Connection is pending & qrcode URI is available
const uniswapWalletConnectors = [ConnectionType.UNISWAP_WALLET, ConnectionType.UNISWAP_WALLET_V2]
const open = const open =
activationState.status === ActivationStatus.PENDING && activationState.status === ActivationStatus.PENDING &&
activationState.connection.type === ConnectionType.UNISWAP_WALLET && uniswapWalletConnectors.includes(activationState.connection.type) &&
!!uri !!uri
const walletConnectV2AsDefault = useWalletConnectV2AsDefault()
useEffect(() => { useEffect(() => {
;(uniwalletConnectConnection.connector as WalletConnect).events.addListener( if (walletConnectV2AsDefault) {
UniwalletConnect.UNI_URI_AVAILABLE, const connectorV2 = uniwalletWCV2ConnectConnection.connector as WalletConnectv2
(uri) => { connectorV2.events.addListener(UniwalletConnectV2.UNI_URI_AVAILABLE, (uri: string) => {
uri && setUri(uri)
})
} else {
const connectorV1 = uniwalletConnectConnection.connector as WalletConnect
connectorV1.events.addListener(UniwalletConnect.UNI_URI_AVAILABLE, (uri: string) => {
uri && setUri(uri) uri && setUri(uri)
} })
) }
}, []) }, [walletConnectV2AsDefault])
useEffect(() => { useEffect(() => {
if (open) sendAnalyticsEvent('Uniswap wallet modal opened') if (open) sendAnalyticsEvent('Uniswap wallet modal opened')
......
...@@ -3,6 +3,7 @@ import { DetailsV2Variant, useDetailsV2Flag } from 'featureFlags/flags/nftDetail ...@@ -3,6 +3,7 @@ import { DetailsV2Variant, useDetailsV2Flag } from 'featureFlags/flags/nftDetail
import { useRoutingAPIForPriceFlag } from 'featureFlags/flags/priceRoutingApi' import { useRoutingAPIForPriceFlag } from 'featureFlags/flags/priceRoutingApi'
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc' import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
import { UnifiedRouterVariant, useRoutingAPIV2Flag } from 'featureFlags/flags/unifiedRouter' import { UnifiedRouterVariant, useRoutingAPIV2Flag } from 'featureFlags/flags/unifiedRouter'
import { useWalletConnectFallbackFlag } from 'featureFlags/flags/walletConnectPopover'
import { useWalletConnectV2Flag } from 'featureFlags/flags/walletConnectV2' import { useWalletConnectV2Flag } from 'featureFlags/flags/walletConnectV2'
import { useUpdateAtom } from 'jotai/utils' import { useUpdateAtom } from 'jotai/utils'
import { Children, PropsWithChildren, ReactElement, ReactNode, useCallback, useState } from 'react' import { Children, PropsWithChildren, ReactElement, ReactNode, useCallback, useState } from 'react'
...@@ -228,6 +229,12 @@ export default function FeatureFlagModal() { ...@@ -228,6 +229,12 @@ export default function FeatureFlagModal() {
featureFlag={FeatureFlag.walletConnectV2} featureFlag={FeatureFlag.walletConnectV2}
label="Uses WalletConnect V2 as default wallet connect connection" label="Uses WalletConnect V2 as default wallet connect connection"
/> />
<FeatureFlagOption
variant={BaseVariant}
value={useWalletConnectFallbackFlag()}
featureFlag={FeatureFlag.walletConnectFallback}
label="Adds a ... menu to the connection option"
/>
<FeatureFlagGroup name="Debug"> <FeatureFlagGroup name="Debug">
<FeatureFlagOption <FeatureFlagOption
variant={TraceJsonRpcVariant} variant={TraceJsonRpcVariant}
......
...@@ -15,14 +15,14 @@ describe('StatusIcon', () => { ...@@ -15,14 +15,14 @@ describe('StatusIcon', () => {
describe('with no account', () => { describe('with no account', () => {
it('renders children in correct order', () => { it('renders children in correct order', () => {
const supportedConnections = getConnections() const supportedConnections = getConnections()
const injectedConnection = supportedConnections[1] const injectedConnection = supportedConnections[2]
const component = render(<StatusIcon account={ACCOUNT} connection={injectedConnection} />) const component = render(<StatusIcon account={ACCOUNT} connection={injectedConnection} />)
expect(component.getByTestId('StatusIconRoot')).toMatchSnapshot() expect(component.getByTestId('StatusIconRoot')).toMatchSnapshot()
}) })
it('renders without mini icons', () => { it('renders without mini icons', () => {
const supportedConnections = getConnections() const supportedConnections = getConnections()
const injectedConnection = supportedConnections[1] const injectedConnection = supportedConnections[2]
const component = render(<StatusIcon account={ACCOUNT} connection={injectedConnection} showMiniIcons={false} />) const component = render(<StatusIcon account={ACCOUNT} connection={injectedConnection} showMiniIcons={false} />)
expect(component.getByTestId('StatusIconRoot').children.length).toEqual(0) expect(component.getByTestId('StatusIconRoot').children.length).toEqual(0)
}) })
...@@ -38,14 +38,14 @@ describe('StatusIcon', () => { ...@@ -38,14 +38,14 @@ describe('StatusIcon', () => {
it('renders children in correct order', () => { it('renders children in correct order', () => {
const supportedConnections = getConnections() const supportedConnections = getConnections()
const injectedConnection = supportedConnections[1] const injectedConnection = supportedConnections[2]
const component = render(<StatusIcon account={ACCOUNT} connection={injectedConnection} />) const component = render(<StatusIcon account={ACCOUNT} connection={injectedConnection} />)
expect(component.getByTestId('StatusIconRoot')).toMatchSnapshot() expect(component.getByTestId('StatusIconRoot')).toMatchSnapshot()
}) })
it('renders without mini icons', () => { it('renders without mini icons', () => {
const supportedConnections = getConnections() const supportedConnections = getConnections()
const injectedConnection = supportedConnections[1] const injectedConnection = supportedConnections[2]
const component = render(<StatusIcon account={ACCOUNT} connection={injectedConnection} showMiniIcons={false} />) const component = render(<StatusIcon account={ACCOUNT} connection={injectedConnection} showMiniIcons={false} />)
expect(component.getByTestId('StatusIconRoot').children.length).toEqual(0) expect(component.getByTestId('StatusIconRoot').children.length).toEqual(0)
}) })
......
...@@ -7,6 +7,7 @@ import Loader from 'components/Icons/LoadingSpinner' ...@@ -7,6 +7,7 @@ import Loader from 'components/Icons/LoadingSpinner'
import { walletConnectV1Connection, walletConnectV2Connection } from 'connection' import { walletConnectV1Connection, walletConnectV2Connection } from 'connection'
import { ActivationStatus, useActivationState } from 'connection/activate' import { ActivationStatus, useActivationState } from 'connection/activate'
import { Connection, ConnectionType } from 'connection/types' import { Connection, ConnectionType } from 'connection/types'
import { useWalletConnectFallback } from 'featureFlags/flags/walletConnectPopover'
import { useWalletConnectV2AsDefault } from 'featureFlags/flags/walletConnectV2' import { useWalletConnectV2AsDefault } from 'featureFlags/flags/walletConnectV2'
import { useOnClickOutside } from 'hooks/useOnClickOutside' import { useOnClickOutside } from 'hooks/useOnClickOutside'
import { MouseEvent, useEffect, useRef, useState } from 'react' import { MouseEvent, useEffect, useRef, useState } from 'react'
...@@ -65,7 +66,7 @@ const IconWrapper = styled.div` ...@@ -65,7 +66,7 @@ const IconWrapper = styled.div`
align-items: flex-end; align-items: flex-end;
`}; `};
` `
const WCv1PopoverContent = styled(ThemeButton)` const PopoverContent = styled(ThemeButton)`
background: ${({ theme }) => theme.backgroundSurface}; background: ${({ theme }) => theme.backgroundSurface};
border: 1px solid ${({ theme }) => theme.backgroundOutline}; border: 1px solid ${({ theme }) => theme.backgroundOutline};
border-radius: 12px; border-radius: 12px;
...@@ -79,7 +80,7 @@ const WCv1PopoverContent = styled(ThemeButton)` ...@@ -79,7 +80,7 @@ const WCv1PopoverContent = styled(ThemeButton)`
z-index: ${Z_INDEX.popover}; z-index: ${Z_INDEX.popover};
` `
const TOGGLE_SIZE = 24 const TOGGLE_SIZE = 24
const WCv1PopoverToggle = styled.button` const FallbackPopoverToggle = styled.button`
align-items: center; align-items: center;
background-color: transparent; background-color: transparent;
border: none; border: none;
...@@ -123,11 +124,11 @@ const WCv1Icon = styled.img` ...@@ -123,11 +124,11 @@ const WCv1Icon = styled.img`
height: 20px !important; height: 20px !important;
width: 20px !important; width: 20px !important;
` `
const WCv1BodyText = styled(ThemedText.BodyPrimary)` const PopoverBodyText = styled(ThemedText.BodyPrimary)`
margin-bottom: 4px !important; margin-bottom: 4px !important;
text-align: left; text-align: left;
` `
const WCv1Caption = styled(ThemedText.Caption)` const PopoverCaption = styled(ThemedText.Caption)`
text-align: left; text-align: left;
` `
...@@ -140,27 +141,28 @@ interface PopupButtonContentProps { ...@@ -140,27 +141,28 @@ interface PopupButtonContentProps {
} }
function PopupButtonContent({ connection, isDarkMode, show, onClick, onClose }: PopupButtonContentProps) { function PopupButtonContent({ connection, isDarkMode, show, onClick, onClose }: PopupButtonContentProps) {
const popoverElement = useRef<HTMLButtonElement>(null) const popoverElement = useRef<HTMLButtonElement>(null)
const walletConnectV2AsDefault = useWalletConnectV2AsDefault()
useOnClickOutside(popoverElement, onClose) useOnClickOutside(popoverElement, onClose)
const walletConnectV2AsDefault = useWalletConnectV2AsDefault()
if (!show) return null if (!show) return null
return ( return (
<WCv1PopoverContent onClick={onClick} ref={popoverElement} size={ButtonSize.small} emphasis={ButtonEmphasis.medium}> <PopoverContent onClick={onClick} ref={popoverElement} size={ButtonSize.small} emphasis={ButtonEmphasis.medium}>
<IconWrapper> <IconWrapper>
<WCv1Icon src={connection.getIcon?.(isDarkMode)} alt={connection.getName()} /> <WCv1Icon src={connection.getIcon?.(isDarkMode)} alt={connection.getName()} />
</IconWrapper> </IconWrapper>
<div> <div>
<WCv1BodyText> <PopoverBodyText>
<Trans>Connect with {walletConnectV2AsDefault ? t`v1` : t`v2`}</Trans> <Trans>Connect with {walletConnectV2AsDefault ? t`v1` : t`v2`}</Trans>
</WCv1BodyText> </PopoverBodyText>
<WCv1Caption color="textSecondary"> <PopoverCaption color="textSecondary">
{walletConnectV2AsDefault {walletConnectV2AsDefault
? t`Support for v1 will be discontinued June 28.` ? t`Support for v1 will be discontinued June 28.`
: t`Under development and unsupported by most wallets`} : t`Under development and unsupported by most wallets`}
</WCv1Caption> </PopoverCaption>
</div> </div>
</WCv1PopoverContent> </PopoverContent>
) )
} }
...@@ -169,12 +171,12 @@ interface OptionProps { ...@@ -169,12 +171,12 @@ interface OptionProps {
} }
export default function Option({ connection }: OptionProps) { export default function Option({ connection }: OptionProps) {
const { activationState, tryActivation } = useActivationState() const { activationState, tryActivation } = useActivationState()
const [WC1PromptOpen, setWC1PromptOpen] = useState(false) const [wCPopoverOpen, setWCPopoverOpen] = useState(false)
const [accountDrawerOpen, toggleAccountDrawerOpen] = useAccountDrawer() const [accountDrawerOpen, toggleAccountDrawerOpen] = useAccountDrawer()
const activate = () => tryActivation(connection, toggleAccountDrawerOpen) const activate = () => tryActivation(connection, toggleAccountDrawerOpen)
useEffect(() => { useEffect(() => {
if (!accountDrawerOpen) setWC1PromptOpen(false) if (!accountDrawerOpen) setWCPopoverOpen(false)
}, [accountDrawerOpen]) }, [accountDrawerOpen])
const isSomeOptionPending = activationState.status === ActivationStatus.PENDING const isSomeOptionPending = activationState.status === ActivationStatus.PENDING
...@@ -182,22 +184,25 @@ export default function Option({ connection }: OptionProps) { ...@@ -182,22 +184,25 @@ export default function Option({ connection }: OptionProps) {
const isDarkMode = useIsDarkMode() const isDarkMode = useIsDarkMode()
const walletConnectV2AsDefault = useWalletConnectV2AsDefault() const walletConnectV2AsDefault = useWalletConnectV2AsDefault()
const shouldUseWalletConnectFallback = useWalletConnectFallback()
const handleClickConnectViaPopover = (e: MouseEvent<HTMLButtonElement>) => {
const connector = walletConnectV2AsDefault ? walletConnectV1Connection : walletConnectV2Connection
const handleClickConnectViaWCv1 = (e: MouseEvent<HTMLButtonElement>) => {
e.stopPropagation() e.stopPropagation()
tryActivation(walletConnectV2AsDefault ? walletConnectV1Connection : walletConnectV2Connection, () => { tryActivation(connector, () => {
setWC1PromptOpen(false) setWCPopoverOpen(false)
toggleAccountDrawerOpen() toggleAccountDrawerOpen()
}) })
} }
const handleClickOpenWCv1Tooltip = (e: MouseEvent<HTMLButtonElement>) => { const handleClickOpenPopover = (e: MouseEvent<HTMLButtonElement>) => {
e.stopPropagation() e.stopPropagation()
setWC1PromptOpen(true) setWCPopoverOpen(true)
} }
const isWalletConnect = const isWalletConnect =
connection.type === ConnectionType.WALLET_CONNECT || connection.type === ConnectionType.WALLET_CONNECT_V2 connection.type === ConnectionType.WALLET_CONNECT || connection.type === ConnectionType.WALLET_CONNECT_V2
const showExtraMenuToggle = isWalletConnect && !isCurrentOptionPending const showExtraMenuToggle = isWalletConnect && !isCurrentOptionPending && shouldUseWalletConnectFallback
return ( return (
<Wrapper disabled={isSomeOptionPending}> <Wrapper disabled={isSomeOptionPending}>
...@@ -226,15 +231,15 @@ export default function Option({ connection }: OptionProps) { ...@@ -226,15 +231,15 @@ export default function Option({ connection }: OptionProps) {
{showExtraMenuToggle && ( {showExtraMenuToggle && (
<> <>
<WCv1PopoverToggle onClick={handleClickOpenWCv1Tooltip} onMouseDown={handleClickOpenWCv1Tooltip}> <FallbackPopoverToggle onClick={handleClickOpenPopover} onMouseDown={handleClickOpenPopover}>
<MoreHorizontal /> <MoreHorizontal />
</WCv1PopoverToggle> </FallbackPopoverToggle>
<PopupButtonContent <PopupButtonContent
connection={connection} connection={connection}
isDarkMode={isDarkMode} isDarkMode={isDarkMode}
show={WC1PromptOpen} show={wCPopoverOpen}
onClick={handleClickConnectViaWCv1} onClick={handleClickConnectViaPopover}
onClose={() => setWC1PromptOpen(false)} onClose={() => setWCPopoverOpen(false)}
/> />
</> </>
)} )}
......
...@@ -47,9 +47,10 @@ export default function WalletModal({ openSettings }: { openSettings: () => void ...@@ -47,9 +47,10 @@ export default function WalletModal({ openSettings }: { openSettings: () => void
const { activationState } = useActivationState() const { activationState } = useActivationState()
const walletConnectV2AsDefault = useWalletConnectV2AsDefault() const walletConnectV2AsDefault = useWalletConnectV2AsDefault()
const hiddenWalletConnectType = walletConnectV2AsDefault const hiddenWalletConnectTypes = [
? ConnectionType.WALLET_CONNECT walletConnectV2AsDefault ? ConnectionType.WALLET_CONNECT : ConnectionType.WALLET_CONNECT_V2,
: ConnectionType.WALLET_CONNECT_V2 walletConnectV2AsDefault ? ConnectionType.UNISWAP_WALLET : ConnectionType.UNISWAP_WALLET_V2,
]
// Keep the network connector in sync with any active user connector to prevent chain-switching on wallet disconnection. // Keep the network connector in sync with any active user connector to prevent chain-switching on wallet disconnection.
useEffect(() => { useEffect(() => {
...@@ -70,7 +71,7 @@ export default function WalletModal({ openSettings }: { openSettings: () => void ...@@ -70,7 +71,7 @@ export default function WalletModal({ openSettings }: { openSettings: () => void
<AutoColumn gap="16px"> <AutoColumn gap="16px">
<OptionGrid data-testid="option-grid"> <OptionGrid data-testid="option-grid">
{connections {connections
.filter((connection) => connection.shouldDisplay() && connection.type !== hiddenWalletConnectType) .filter((connection) => connection.shouldDisplay() && !hiddenWalletConnectTypes.includes(connection.type))
.map((connection) => ( .map((connection) => (
<Option key={connection.getName()} connection={connection} /> <Option key={connection.getName()} connection={connection} />
))} ))}
......
import { sendAnalyticsEvent } from '@uniswap/analytics' import { sendAnalyticsEvent } from '@uniswap/analytics'
import { WalletConnect, WalletConnectConstructorArgs } from '@web3-react/walletconnect-v2' import { URI_AVAILABLE, WalletConnect, WalletConnectConstructorArgs } from '@web3-react/walletconnect-v2'
import { L1_CHAIN_IDS, L2_CHAIN_IDS, SupportedChainId } from 'constants/chains' import { L1_CHAIN_IDS, L2_CHAIN_IDS, SupportedChainId } from 'constants/chains'
import { Z_INDEX } from 'theme/zIndex' import { Z_INDEX } from 'theme/zIndex'
import { isIOS } from 'utils/userAgent'
import { RPC_URLS } from '../constants/networks' import { RPC_URLS } from '../constants/networks'
...@@ -61,3 +62,37 @@ export class WalletConnectV2 extends WalletConnect { ...@@ -61,3 +62,37 @@ export class WalletConnectV2 extends WalletConnect {
return super.activate(chainId) return super.activate(chainId)
} }
} }
// Custom class for Uniswap Wallet specific functionality
export class UniwalletConnect extends WalletConnectV2 {
ANALYTICS_EVENT = 'Uniswap Wallet QR Scan'
static UNI_URI_AVAILABLE = 'uni_uri_available'
constructor({ actions, onError }: Omit<WalletConnectConstructorArgs, 'options'>) {
// disables walletconnect's proprietary qr code modal; instead UniwalletModal will listen for events to trigger our custom modal
super({ actions, qrcode: false, onError })
this.events.once(URI_AVAILABLE, () => {
this.provider?.events.on('disconnect', this.deactivate)
})
this.events.on(URI_AVAILABLE, (uri) => {
if (!uri) return
// Emits custom wallet connect code, parseable by the Uniswap Wallet
this.events.emit(UniwalletConnect.UNI_URI_AVAILABLE, `hello_uniwallet:${uri}`)
// Opens deeplink to Uniswap Wallet if on iOS
if (isIOS) {
const newTab = window.open(`https://uniswap.org/app/wc?uri=${encodeURIComponent(uri)}`)
// Fixes blank tab opening on mobile Chrome
newTab?.close()
}
})
}
deactivate() {
this.events.emit(URI_AVAILABLE)
return super.deactivate()
}
}
...@@ -39,7 +39,7 @@ describe('connection utility/metadata tests', () => { ...@@ -39,7 +39,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('Install MetaMask') expect(injected.getName()).toBe('Install MetaMask')
expect(injected.overrideActivate?.()).toBeTruthy() expect(injected.overrideActivate?.()).toBeTruthy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
it('MetaMask-Injected Desktop', async () => { it('MetaMask-Injected Desktop', async () => {
...@@ -49,7 +49,7 @@ describe('connection utility/metadata tests', () => { ...@@ -49,7 +49,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('MetaMask') expect(injected.getName()).toBe('MetaMask')
expect(injected.overrideActivate?.()).toBeFalsy() expect(injected.overrideActivate?.()).toBeFalsy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
it('Coinbase-Injected Desktop', async () => { it('Coinbase-Injected Desktop', async () => {
...@@ -60,7 +60,7 @@ describe('connection utility/metadata tests', () => { ...@@ -60,7 +60,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('Install MetaMask') expect(injected.getName()).toBe('Install MetaMask')
expect(injected.overrideActivate?.()).toBeTruthy() expect(injected.overrideActivate?.()).toBeTruthy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
it('Coinbase and MetaMask Injected Desktop', async () => { it('Coinbase and MetaMask Injected Desktop', async () => {
...@@ -71,7 +71,7 @@ describe('connection utility/metadata tests', () => { ...@@ -71,7 +71,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('MetaMask') expect(injected.getName()).toBe('MetaMask')
expect(injected.overrideActivate?.()).toBeFalsy() expect(injected.overrideActivate?.()).toBeFalsy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
it('Trust Wallet Injected Desktop', async () => { it('Trust Wallet Injected Desktop', async () => {
...@@ -81,7 +81,7 @@ describe('connection utility/metadata tests', () => { ...@@ -81,7 +81,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('Trust Wallet') expect(injected.getName()).toBe('Trust Wallet')
expect(injected.overrideActivate?.()).toBeFalsy() expect(injected.overrideActivate?.()).toBeFalsy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
it('Rabby Wallet Injected Desktop', async () => { it('Rabby Wallet Injected Desktop', async () => {
...@@ -91,7 +91,7 @@ describe('connection utility/metadata tests', () => { ...@@ -91,7 +91,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('Rabby') expect(injected.getName()).toBe('Rabby')
expect(injected.overrideActivate?.()).toBeFalsy() expect(injected.overrideActivate?.()).toBeFalsy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
it('LedgerConnect Wallet Injected Desktop', async () => { it('LedgerConnect Wallet Injected Desktop', async () => {
...@@ -101,7 +101,7 @@ describe('connection utility/metadata tests', () => { ...@@ -101,7 +101,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('Ledger') expect(injected.getName()).toBe('Ledger')
expect(injected.overrideActivate?.()).toBeFalsy() expect(injected.overrideActivate?.()).toBeFalsy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
it('Brave Browser Wallet Injected Desktop', async () => { it('Brave Browser Wallet Injected Desktop', async () => {
...@@ -111,7 +111,7 @@ describe('connection utility/metadata tests', () => { ...@@ -111,7 +111,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('Brave') expect(injected.getName()).toBe('Brave')
expect(injected.overrideActivate?.()).toBeFalsy() expect(injected.overrideActivate?.()).toBeFalsy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
it('Phantom Wallet Injected Desktop', async () => { it('Phantom Wallet Injected Desktop', async () => {
...@@ -122,7 +122,7 @@ describe('connection utility/metadata tests', () => { ...@@ -122,7 +122,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('Phantom') expect(injected.getName()).toBe('Phantom')
expect(injected.overrideActivate?.()).toBeFalsy() expect(injected.overrideActivate?.()).toBeFalsy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
const UNKNOWN_MM_INJECTOR = { isRandomWallet: true, isMetaMask: true } as Window['window']['ethereum'] const UNKNOWN_MM_INJECTOR = { isRandomWallet: true, isMetaMask: true } as Window['window']['ethereum']
...@@ -133,7 +133,7 @@ describe('connection utility/metadata tests', () => { ...@@ -133,7 +133,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getName()).toBe('MetaMask') expect(injected.getName()).toBe('MetaMask')
expect(injected.overrideActivate?.()).toBeFalsy() expect(injected.overrideActivate?.()).toBeFalsy()
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
const UNKNOWN_INJECTOR = { isRandomWallet: true } as Window['window']['ethereum'] const UNKNOWN_INJECTOR = { isRandomWallet: true } as Window['window']['ethereum']
...@@ -148,7 +148,7 @@ describe('connection utility/metadata tests', () => { ...@@ -148,7 +148,7 @@ describe('connection utility/metadata tests', () => {
expect(injected.getIcon?.(/* isDarkMode= */ true)).toBe(INJECTED_DARK_ICON) expect(injected.getIcon?.(/* isDarkMode= */ true)).toBe(INJECTED_DARK_ICON)
// Ensures we provide multiple connection options if in an unknown injected browser // Ensures we provide multiple connection options if in an unknown injected browser
expect(displayed.length).toEqual(4) expect(displayed.length).toEqual(5)
}) })
it('Generic Wallet Browser with delayed injection', async () => { it('Generic Wallet Browser with delayed injection', async () => {
...@@ -191,6 +191,6 @@ describe('connection utility/metadata tests', () => { ...@@ -191,6 +191,6 @@ describe('connection utility/metadata tests', () => {
// Expect coinbase option to launch coinbase app in a regular mobile browser // Expect coinbase option to launch coinbase app in a regular mobile browser
expect(coinbase.overrideActivate?.()).toBeTruthy() expect(coinbase.overrideActivate?.()).toBeTruthy()
expect(displayed.length).toEqual(3) expect(displayed.length).toEqual(4)
}) })
}) })
...@@ -17,7 +17,7 @@ import { RPC_PROVIDERS } from '../constants/providers' ...@@ -17,7 +17,7 @@ import { RPC_PROVIDERS } from '../constants/providers'
import { Connection, ConnectionType } from './types' import { Connection, ConnectionType } from './types'
import { getInjection, getIsCoinbaseWallet, getIsInjected, getIsMetaMaskWallet } from './utils' import { getInjection, getIsCoinbaseWallet, getIsInjected, getIsMetaMaskWallet } from './utils'
import { UniwalletConnect, WalletConnectV1 } from './WalletConnect' import { UniwalletConnect, WalletConnectV1 } from './WalletConnect'
import { WalletConnectV2 } from './WalletConnectV2' import { UniwalletConnect as UniwalletWCV2Connect, WalletConnectV2 } from './WalletConnectV2'
function onError(error: Error) { function onError(error: Error) {
console.debug(`web3-react error: ${error}`) console.debug(`web3-react error: ${error}`)
...@@ -107,6 +107,19 @@ export const uniwalletConnectConnection: Connection = { ...@@ -107,6 +107,19 @@ export const uniwalletConnectConnection: Connection = {
isNew: true, isNew: true,
} }
const [web3WCV2UniwalletConnect, web3WCV2UniwalletConnectHooks] = initializeConnector<UniwalletWCV2Connect>(
(actions) => new UniwalletWCV2Connect({ actions, onError })
)
export const uniwalletWCV2ConnectConnection: Connection = {
getName: () => 'Uniswap Wallet',
connector: web3WCV2UniwalletConnect,
hooks: web3WCV2UniwalletConnectHooks,
type: ConnectionType.UNISWAP_WALLET_V2,
getIcon: () => UNIWALLET_ICON,
shouldDisplay: () => Boolean(!getIsInjectedMobileBrowser() && !isNonIOSPhone),
isNew: true,
}
const [web3CoinbaseWallet, web3CoinbaseWalletHooks] = initializeConnector<CoinbaseWallet>( const [web3CoinbaseWallet, web3CoinbaseWalletHooks] = initializeConnector<CoinbaseWallet>(
(actions) => (actions) =>
new CoinbaseWallet({ new CoinbaseWallet({
...@@ -142,6 +155,7 @@ const coinbaseWalletConnection: Connection = { ...@@ -142,6 +155,7 @@ const coinbaseWalletConnection: Connection = {
export function getConnections() { export function getConnections() {
return [ return [
uniwalletConnectConnection, uniwalletConnectConnection,
uniwalletWCV2ConnectConnection,
injectedConnection, injectedConnection,
walletConnectV2Connection, walletConnectV2Connection,
walletConnectV1Connection, walletConnectV1Connection,
...@@ -171,6 +185,8 @@ export function getConnection(c: Connector | ConnectionType) { ...@@ -171,6 +185,8 @@ export function getConnection(c: Connector | ConnectionType) {
case ConnectionType.UNIWALLET: case ConnectionType.UNIWALLET:
case ConnectionType.UNISWAP_WALLET: case ConnectionType.UNISWAP_WALLET:
return uniwalletConnectConnection return uniwalletConnectConnection
case ConnectionType.UNISWAP_WALLET_V2:
return uniwalletWCV2ConnectConnection
case ConnectionType.NETWORK: case ConnectionType.NETWORK:
return networkConnection return networkConnection
case ConnectionType.GNOSIS_SAFE: case ConnectionType.GNOSIS_SAFE:
......
...@@ -3,6 +3,7 @@ import { Connector } from '@web3-react/types' ...@@ -3,6 +3,7 @@ import { Connector } from '@web3-react/types'
export enum ConnectionType { export enum ConnectionType {
UNISWAP_WALLET = 'UNISWAP_WALLET', UNISWAP_WALLET = 'UNISWAP_WALLET',
UNISWAP_WALLET_V2 = 'UNISWAP_WALLET_V2',
/** @deprecated - Use {@link UNISWAP_WALLET} instead. */ /** @deprecated - Use {@link UNISWAP_WALLET} instead. */
UNIWALLET = 'UNIWALLET', UNIWALLET = 'UNIWALLET',
INJECTED = 'INJECTED', INJECTED = 'INJECTED',
......
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
export function useWalletConnectFallbackFlag(): BaseVariant {
return useBaseFlag(FeatureFlag.walletConnectFallback)
}
export function useWalletConnectFallback(): boolean {
return useWalletConnectFallbackFlag() === BaseVariant.Enabled
}
...@@ -15,6 +15,7 @@ export enum FeatureFlag { ...@@ -15,6 +15,7 @@ export enum FeatureFlag {
nativeUsdcArbitrum = 'web_usdc_arbitrum', nativeUsdcArbitrum = 'web_usdc_arbitrum',
routingAPIPrice = 'routing_api_price', routingAPIPrice = 'routing_api_price',
walletConnectV2 = 'walletconnect_v2', walletConnectV2 = 'walletconnect_v2',
walletConnectFallback = 'walletconnect_fallback',
} }
interface FeatureFlagsContextType { interface FeatureFlagsContextType {
......
...@@ -2,6 +2,7 @@ import { Connector } from '@web3-react/types' ...@@ -2,6 +2,7 @@ import { Connector } from '@web3-react/types'
import { import {
networkConnection, networkConnection,
uniwalletConnectConnection, uniwalletConnectConnection,
uniwalletWCV2ConnectConnection,
walletConnectV1Connection, walletConnectV1Connection,
walletConnectV2Connection, walletConnectV2Connection,
} from 'connection' } from 'connection'
...@@ -41,6 +42,7 @@ export function useSwitchChain() { ...@@ -41,6 +42,7 @@ export function useSwitchChain() {
walletConnectV1Connection.connector, walletConnectV1Connection.connector,
walletConnectV2Connection.connector, walletConnectV2Connection.connector,
uniwalletConnectConnection.connector, uniwalletConnectConnection.connector,
uniwalletWCV2ConnectConnection.connector,
networkConnection.connector, networkConnection.connector,
].includes(connector) ].includes(connector)
) { ) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment