Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b3b637d23 | ||
|
|
1a488503a7 |
@@ -1,13 +1,7 @@
|
||||
import { getTestSelector } from '../utils'
|
||||
|
||||
describe('Universal search bar', () => {
|
||||
before(() => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/')
|
||||
cy.get('[data-cy="magnifying-icon"]')
|
||||
.parent()
|
||||
.then(($navIcon) => {
|
||||
$navIcon.click()
|
||||
})
|
||||
cy.get('[data-cy="magnifying-icon"]').parent().eq(1).click()
|
||||
})
|
||||
|
||||
it('should yield clickable result for regular token or nft collection search term', () => {
|
||||
@@ -19,20 +13,7 @@ describe('Universal search bar', () => {
|
||||
.and('contain.text', '$')
|
||||
.and('contain.text', '%')
|
||||
cy.get('[data-cy="searchbar-token-row-UNI"]').first().click()
|
||||
|
||||
cy.get('div').contains('Uniswap').should('exist')
|
||||
// Stats should have: TVL, 24H Volume, 52W low, 52W high.
|
||||
cy.get(getTestSelector('token-details-stats')).should('exist')
|
||||
cy.get(getTestSelector('token-details-stats')).within(() => {
|
||||
cy.get('[data-cy="tvl"]').should('include.text', '$')
|
||||
cy.get('[data-cy="volume-24h"]').should('include.text', '$')
|
||||
cy.get('[data-cy="52w-low"]').should('include.text', '$')
|
||||
cy.get('[data-cy="52w-high"]').should('include.text', '$')
|
||||
})
|
||||
|
||||
// About section should have description of token.
|
||||
cy.get(getTestSelector('token-details-about-section')).should('exist')
|
||||
cy.contains('UNI is the governance token for Uniswap').should('exist')
|
||||
cy.location('hash').should('equal', '#/tokens/ethereum/0x1f9840a85d5af5bf1d1762f925bdaddc4201f984')
|
||||
})
|
||||
|
||||
it.skip('should show recent tokens and popular tokens with empty search term', () => {
|
||||
|
||||
@@ -186,6 +186,7 @@
|
||||
"@visx/react-spring": "^2.12.2",
|
||||
"@visx/responsive": "^2.10.0",
|
||||
"@visx/shape": "^2.11.1",
|
||||
"@walletconnect/modal": "^2.5.4",
|
||||
"@web3-react/coinbase-wallet": "^8.2.0",
|
||||
"@web3-react/core": "^8.2.0",
|
||||
"@web3-react/eip1193": "^8.2.0",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { t, Trans } from '@lingui/macro'
|
||||
import { TraceEvent } from '@uniswap/analytics'
|
||||
import { BrowserEvent, InterfaceElementName, InterfaceEventName } from '@uniswap/analytics-events'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
import { useAccountDrawer } from 'components/AccountDrawer'
|
||||
import { ButtonEmphasis, ButtonSize, ThemeButton } from 'components/Button'
|
||||
import Loader from 'components/Icons/LoadingSpinner'
|
||||
@@ -173,7 +174,8 @@ export default function Option({ connection }: OptionProps) {
|
||||
const { activationState, tryActivation } = useActivationState()
|
||||
const [wCPopoverOpen, setWCPopoverOpen] = useState(false)
|
||||
const [accountDrawerOpen, toggleAccountDrawerOpen] = useAccountDrawer()
|
||||
const activate = () => tryActivation(connection, toggleAccountDrawerOpen)
|
||||
const { chainId } = useWeb3React()
|
||||
const activate = () => tryActivation(connection, toggleAccountDrawerOpen, chainId)
|
||||
|
||||
useEffect(() => {
|
||||
if (!accountDrawerOpen) setWCPopoverOpen(false)
|
||||
|
||||
@@ -10,7 +10,7 @@ import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/tra
|
||||
import useEagerlyConnect from 'hooks/useEagerlyConnect'
|
||||
import useOrderedConnections from 'hooks/useOrderedConnections'
|
||||
import usePrevious from 'hooks/usePrevious'
|
||||
import { ReactNode, useEffect, useMemo } from 'react'
|
||||
import { ReactNode, useEffect, useMemo, useState } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useConnectedWallets } from 'state/wallets/hooks'
|
||||
import { getCurrentPageFromLocation } from 'utils/urlRoutes'
|
||||
@@ -20,7 +20,13 @@ export default function Web3Provider({ children }: { children: ReactNode }) {
|
||||
const connections = useOrderedConnections()
|
||||
const connectors: [Connector, Web3ReactHooks][] = connections.map(({ hooks, connector }) => [connector, hooks])
|
||||
|
||||
const key = useMemo(() => connections.map((connection) => connection.getName()).join('-'), [connections])
|
||||
// Force a re-render when our connection state changes.
|
||||
const [index, setIndex] = useState(0)
|
||||
useEffect(() => setIndex((index) => index + 1), [connections])
|
||||
const key = useMemo(
|
||||
() => connections.map((connection) => connection.getName()).join('-') + index,
|
||||
[connections, index]
|
||||
)
|
||||
|
||||
return (
|
||||
<Web3ReactProvider connectors={connectors} key={key}>
|
||||
|
||||
@@ -15,22 +15,21 @@ const RPC_URLS_WITHOUT_FALLBACKS = Object.entries(RPC_URLS).reduce(
|
||||
}),
|
||||
{}
|
||||
)
|
||||
const optionalChains = [...L1_CHAIN_IDS, ...L2_CHAIN_IDS].filter((x) => x !== SupportedChainId.MAINNET)
|
||||
|
||||
export class WalletConnectV2 extends WalletConnect {
|
||||
ANALYTICS_EVENT = 'Wallet Connect QR Scan'
|
||||
constructor({
|
||||
actions,
|
||||
onError,
|
||||
defaultChainId,
|
||||
qrcode = true,
|
||||
}: Omit<WalletConnectConstructorArgs, 'options'> & { qrcode?: boolean }) {
|
||||
onError,
|
||||
}: Omit<WalletConnectConstructorArgs, 'options'> & { defaultChainId: number; qrcode?: boolean }) {
|
||||
const darkmode = Boolean(window.matchMedia('(prefers-color-scheme: dark)'))
|
||||
super({
|
||||
actions,
|
||||
options: {
|
||||
projectId: process.env.REACT_APP_WALLET_CONNECT_PROJECT_ID as string,
|
||||
optionalChains,
|
||||
chains: [SupportedChainId.MAINNET],
|
||||
chains: [defaultChainId],
|
||||
optionalChains: [...L1_CHAIN_IDS, ...L2_CHAIN_IDS],
|
||||
showQrModal: qrcode,
|
||||
rpcMap: RPC_URLS_WITHOUT_FALLBACKS,
|
||||
// as of 6/16/2023 there are no docs for `optionalMethods`
|
||||
@@ -47,8 +46,8 @@ export class WalletConnectV2 extends WalletConnect {
|
||||
termsOfServiceUrl: undefined,
|
||||
themeMode: darkmode ? 'dark' : 'light',
|
||||
themeVariables: {
|
||||
'--w3m-font-family': '"Inter custom", sans-serif',
|
||||
'--w3m-z-index': Z_INDEX.modal.toString(),
|
||||
'--wcm-font-family': '"Inter custom", sans-serif',
|
||||
'--wcm-z-index': Z_INDEX.modal.toString(),
|
||||
},
|
||||
walletImages: undefined,
|
||||
},
|
||||
@@ -70,7 +69,7 @@ export class UniwalletConnect extends WalletConnectV2 {
|
||||
|
||||
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 })
|
||||
super({ actions, defaultChainId: SupportedChainId.MAINNET, qrcode: false, onError })
|
||||
|
||||
this.events.once(URI_AVAILABLE, () => {
|
||||
this.provider?.events.on('disconnect', this.deactivate)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Web3ReactHooks } from '@web3-react/core'
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { SupportedChainId } from 'constants/chains'
|
||||
import { useAppDispatch, useAppSelector } from 'state/hooks'
|
||||
import { updateSelectedWallet } from 'state/user/reducer'
|
||||
import { createDeferredPromise } from 'test-utils/promise'
|
||||
|
||||
import { act, renderHook } from '../test-utils/render'
|
||||
@@ -35,6 +38,7 @@ function createMockConnection(
|
||||
hooks: {} as unknown as Web3ReactHooks,
|
||||
type,
|
||||
shouldDisplay: () => true,
|
||||
overrideActivate: jest.fn(),
|
||||
connector: new MockConnector(activate, deactivate),
|
||||
}
|
||||
}
|
||||
@@ -54,18 +58,25 @@ it('Should call activate function on a connection', async () => {
|
||||
const activationResponse = createDeferredPromise()
|
||||
const mockConnection = createMockConnection(jest.fn().mockImplementation(() => activationResponse.promise))
|
||||
|
||||
renderHook(() => useAppDispatch()(updateSelectedWallet({ wallet: ConnectionType.INJECTED })))
|
||||
const initialSelectedWallet = renderHook(() => useAppSelector((state) => state.user.selectedWallet))
|
||||
expect(initialSelectedWallet.result.current).toBeDefined()
|
||||
|
||||
const result = renderHook(useActivationState).result
|
||||
const onSuccess = jest.fn()
|
||||
|
||||
let activationCall: Promise<void> = new Promise(jest.fn())
|
||||
act(() => {
|
||||
activationCall = result.current.tryActivation(mockConnection, onSuccess)
|
||||
activationCall = result.current.tryActivation(mockConnection, onSuccess, SupportedChainId.OPTIMISM)
|
||||
})
|
||||
|
||||
expect(result.current.activationState).toEqual({ status: ActivationStatus.PENDING, connection: mockConnection })
|
||||
expect(mockConnection.overrideActivate).toHaveBeenCalledWith(SupportedChainId.OPTIMISM)
|
||||
expect(mockConnection.connector.activate).toHaveBeenCalledTimes(1)
|
||||
expect(console.debug).toHaveBeenLastCalledWith(`Connection activating: ${mockConnection.getName()}`)
|
||||
expect(onSuccess).toHaveBeenCalledTimes(0)
|
||||
const pendingSelectedWallet = renderHook(() => useAppSelector((state) => state.user.selectedWallet))
|
||||
expect(pendingSelectedWallet.result.current).toBeUndefined()
|
||||
|
||||
await act(async () => {
|
||||
activationResponse.resolve()
|
||||
@@ -77,6 +88,8 @@ it('Should call activate function on a connection', async () => {
|
||||
expect(console.debug).toHaveBeenLastCalledWith(`Connection activated: ${mockConnection.getName()}`)
|
||||
expect(console.debug).toHaveBeenCalledTimes(2)
|
||||
expect(onSuccess).toHaveBeenCalledTimes(1)
|
||||
const finalSelectedWallet = renderHook(() => useAppSelector((state) => state.user.selectedWallet))
|
||||
expect(finalSelectedWallet.result.current).toBeDefined()
|
||||
})
|
||||
|
||||
it('Should properly deactivate pending connection attempts', async () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { sendAnalyticsEvent } from '@uniswap/analytics'
|
||||
import { InterfaceEventName, WalletConnectionResult } from '@uniswap/analytics-events'
|
||||
import { Connection } from 'connection/types'
|
||||
import { SupportedChainId } from 'constants/chains'
|
||||
import { atom } from 'jotai'
|
||||
import { useAtomValue, useUpdateAtom } from 'jotai/utils'
|
||||
import { useCallback } from 'react'
|
||||
@@ -31,15 +32,16 @@ function useTryActivation() {
|
||||
const currentPage = getCurrentPageFromLocation(pathname)
|
||||
|
||||
return useCallback(
|
||||
async (connection: Connection, onSuccess: () => void) => {
|
||||
async (connection: Connection, onSuccess: () => void, chainId?: SupportedChainId) => {
|
||||
// Skips wallet connection if the connection should override the default
|
||||
// behavior, i.e. install MetaMask or launch Coinbase app
|
||||
if (connection.overrideActivate?.()) return
|
||||
if (connection.overrideActivate?.(chainId)) return
|
||||
|
||||
try {
|
||||
setActivationState({ status: ActivationStatus.PENDING, connection })
|
||||
|
||||
console.debug(`Connection activating: ${connection.getName()}`)
|
||||
dispatch(updateSelectedWallet({ wallet: undefined }))
|
||||
await connection.connector.activate()
|
||||
|
||||
console.debug(`Connection activated: ${connection.getName()}`)
|
||||
|
||||
@@ -3,7 +3,7 @@ import { initializeConnector } from '@web3-react/core'
|
||||
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 { Actions, Connector } from '@web3-react/types'
|
||||
import GNOSIS_ICON from 'assets/images/gnosis.png'
|
||||
import UNISWAP_LOGO from 'assets/svg/logo.svg'
|
||||
import COINBASE_ICON from 'assets/wallets/coinbase-icon.svg'
|
||||
@@ -82,17 +82,28 @@ export const walletConnectV1Connection: Connection = {
|
||||
shouldDisplay: () => !getIsInjectedMobileBrowser(),
|
||||
}
|
||||
|
||||
const [web3WalletConnectV2, web3WalletConnectV2Hooks] = initializeConnector<WalletConnectV2>(
|
||||
(actions) => new WalletConnectV2({ actions, onError })
|
||||
)
|
||||
export const walletConnectV2Connection: Connection = {
|
||||
getName: () => 'WalletConnect',
|
||||
connector: web3WalletConnectV2,
|
||||
hooks: web3WalletConnectV2Hooks,
|
||||
type: ConnectionType.WALLET_CONNECT_V2,
|
||||
getIcon: () => WALLET_CONNECT_ICON,
|
||||
shouldDisplay: () => !getIsInjectedMobileBrowser(),
|
||||
}
|
||||
export const walletConnectV2Connection: Connection = new (class implements Connection {
|
||||
private initializer = (actions: Actions, defaultChainId = SupportedChainId.MAINNET) =>
|
||||
new WalletConnectV2({ actions, defaultChainId, onError })
|
||||
|
||||
type = ConnectionType.WALLET_CONNECT_V2
|
||||
getName = () => 'WalletConnect'
|
||||
getIcon = () => WALLET_CONNECT_ICON
|
||||
shouldDisplay = () => !getIsInjectedMobileBrowser()
|
||||
|
||||
private _connector = initializeConnector<WalletConnectV2>(this.initializer)
|
||||
overrideActivate = (chainId?: SupportedChainId) => {
|
||||
// Always re-create the connector, so that the chainId is updated.
|
||||
this._connector = initializeConnector((actions) => this.initializer(actions, chainId))
|
||||
return false
|
||||
}
|
||||
get connector() {
|
||||
return this._connector[0]
|
||||
}
|
||||
get hooks() {
|
||||
return this._connector[1]
|
||||
}
|
||||
})()
|
||||
|
||||
const [web3UniwalletConnect, web3UniwalletConnectHooks] = initializeConnector<UniwalletConnect>(
|
||||
(actions) => new UniwalletConnect({ actions, onError })
|
||||
@@ -133,7 +144,6 @@ const [web3CoinbaseWallet, web3CoinbaseWalletHooks] = initializeConnector<Coinba
|
||||
onError,
|
||||
})
|
||||
)
|
||||
|
||||
const coinbaseWalletConnection: Connection = {
|
||||
getName: () => 'Coinbase Wallet',
|
||||
connector: web3CoinbaseWallet,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Web3ReactHooks } from '@web3-react/core'
|
||||
import { Connector } from '@web3-react/types'
|
||||
import { SupportedChainId } from 'constants/chains'
|
||||
|
||||
export enum ConnectionType {
|
||||
UNISWAP_WALLET = 'UNISWAP_WALLET',
|
||||
@@ -21,6 +22,6 @@ export interface Connection {
|
||||
type: ConnectionType
|
||||
getIcon?(isDarkMode: boolean): string
|
||||
shouldDisplay(): boolean
|
||||
overrideActivate?: () => boolean
|
||||
overrideActivate?: (chainId?: SupportedChainId) => boolean
|
||||
isNew?: boolean
|
||||
}
|
||||
|
||||
56
yarn.lock
56
yarn.lock
@@ -6337,13 +6337,31 @@
|
||||
resolved "https://registry.npmjs.org/@walletconnect/mobile-registry/-/mobile-registry-1.4.0.tgz"
|
||||
integrity sha512-ZtKRio4uCZ1JUF7LIdecmZt7FOLnX72RPSY7aUVu7mj7CSfxDwUn6gBuK6WGtH+NZCldBqDl5DenI5fFSvkKYw==
|
||||
|
||||
"@walletconnect/modal@^2.4.5":
|
||||
version "2.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@walletconnect/modal/-/modal-2.4.5.tgz#bfdf6110a7f09c709fc5af19e576a28e6bba1d6e"
|
||||
integrity sha512-t+sII7GIMsKDr0wvSJxzlpcbxw35WthuVpAqPlzMS7roSPmQZT18KO8Iu4ccLkNZF+ioptRTpBUKtk2eeuaqlQ==
|
||||
"@walletconnect/modal-core@2.5.4":
|
||||
version "2.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@walletconnect/modal-core/-/modal-core-2.5.4.tgz#7d739a90a9cf103067eea46507ea649e8dada436"
|
||||
integrity sha512-ISe4LqmEDFU7b6rLgonqaEtMXzG6ko13HA7S8Ty3d7GgfAEe29LM1dq3zo8ehEOghhofhj1PiiNfvaogZKzT1g==
|
||||
dependencies:
|
||||
"@web3modal/core" "2.4.5"
|
||||
"@web3modal/ui" "2.4.5"
|
||||
buffer "6.0.3"
|
||||
valtio "1.10.6"
|
||||
|
||||
"@walletconnect/modal-ui@2.5.4":
|
||||
version "2.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@walletconnect/modal-ui/-/modal-ui-2.5.4.tgz#0433fb0226dd47e17fede620c5a5ff332baed155"
|
||||
integrity sha512-5qLLjwbE3YC4AsCVhf8J87otklkApcQ5DCMykOcS0APPv8lKQ46JxpQhfWwRYaUkuIiHonI9h1YxFARDkoaI9g==
|
||||
dependencies:
|
||||
"@walletconnect/modal-core" "2.5.4"
|
||||
lit "2.7.5"
|
||||
motion "10.16.2"
|
||||
qrcode "1.5.3"
|
||||
|
||||
"@walletconnect/modal@^2.4.5", "@walletconnect/modal@^2.5.4":
|
||||
version "2.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@walletconnect/modal/-/modal-2.5.4.tgz#66659051f9c0f35c151d3a8d940f8c64d42fab74"
|
||||
integrity sha512-JAKMcCd4JQvSEr7pNitg3OBke4DN1JyaQ7bdi3x4T7oLgOr9Y88qdkeOXko/0aJonDHJsM88hZ10POQWmKfEMA==
|
||||
dependencies:
|
||||
"@walletconnect/modal-core" "2.5.4"
|
||||
"@walletconnect/modal-ui" "2.5.4"
|
||||
|
||||
"@walletconnect/qrcode-modal@^1.8.0":
|
||||
version "1.8.0"
|
||||
@@ -6634,24 +6652,6 @@
|
||||
"@web3-react/types" "^8.2.0"
|
||||
eventemitter3 "^4.0.7"
|
||||
|
||||
"@web3modal/core@2.4.5":
|
||||
version "2.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@web3modal/core/-/core-2.4.5.tgz#506161e37b8431fc8d605aed7a73d93e3f8ee7b4"
|
||||
integrity sha512-iulOIW2irVaq+xWTzzM2xbRI4TCR0yTnV2Yz+ifIFl+r3OF3ZOC1jsy4jJnKL7/6e7p4NmmKJk0/w951KzCF5g==
|
||||
dependencies:
|
||||
buffer "6.0.3"
|
||||
valtio "1.10.5"
|
||||
|
||||
"@web3modal/ui@2.4.5":
|
||||
version "2.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@web3modal/ui/-/ui-2.4.5.tgz#bd388faeafd9abf72abffc85613b3d7038adcf14"
|
||||
integrity sha512-LvGjGL7vyQrUrrQOtFAK0SyxJs1yozOnJjP7s7gWXJa7wFWCE+kVjrhE8VrKbwx7nHe78IFA1rs7V1ncCirqVQ==
|
||||
dependencies:
|
||||
"@web3modal/core" "2.4.5"
|
||||
lit "2.7.5"
|
||||
motion "10.16.2"
|
||||
qrcode "1.5.3"
|
||||
|
||||
"@webassemblyjs/ast@1.11.5", "@webassemblyjs/ast@^1.11.5":
|
||||
version "1.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.5.tgz#6e818036b94548c1fb53b754b5cae3c9b208281c"
|
||||
@@ -19117,10 +19117,10 @@ v8-to-istanbul@^8.1.0:
|
||||
convert-source-map "^1.6.0"
|
||||
source-map "^0.7.3"
|
||||
|
||||
valtio@1.10.5:
|
||||
version "1.10.5"
|
||||
resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.10.5.tgz#7852125e3b774b522827d96bd9c76d285c518678"
|
||||
integrity sha512-jTp0k63VXf4r5hPoaC6a6LCG4POkVSh629WLi1+d5PlajLsbynTMd7qAgEiOSPxzoX5iNvbN7iZ/k/g29wrNiQ==
|
||||
valtio@1.10.6:
|
||||
version "1.10.6"
|
||||
resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.10.6.tgz#80ed00198b949939863a0fa56ae687abb417fc4f"
|
||||
integrity sha512-SxN1bHUmdhW6V8qsQTpCgJEwp7uHbntuH0S9cdLQtiohuevwBksbpXjwj5uDMA7bLwg1WKyq9sEpZrx3TIMrkA==
|
||||
dependencies:
|
||||
proxy-compare "2.5.1"
|
||||
use-sync-external-store "1.2.0"
|
||||
|
||||
Reference in New Issue
Block a user