diff --git a/jest.config.cjs b/jest.config.cjs index 0c2b7e2b4f..2ba19a6f88 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -25,5 +25,5 @@ const customJestConfig = { // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async module.exports = async () => ({ ...(await createJestConfig(customJestConfig)()), - transformIgnorePatterns: ['node_modules/(?!(uint8arrays)/)'], + transformIgnorePatterns: ['node_modules/(?!(uint8arrays|multiformats)/)'], }) diff --git a/src/components/walletconnect/ConnectionForm/index.tsx b/src/components/walletconnect/ConnectionForm/index.tsx index cc75a85b56..af3969e697 100644 --- a/src/components/walletconnect/ConnectionForm/index.tsx +++ b/src/components/walletconnect/ConnectionForm/index.tsx @@ -1,6 +1,6 @@ import useLocalStorage from '@/services/local-storage/useLocalStorage' import { Grid, Typography, Divider, SvgIcon, IconButton, Tooltip } from '@mui/material' -import { useCallback, useContext, useEffect, useState } from 'react' +import { useCallback, useContext, useEffect } from 'react' import type { ReactElement } from 'react' import type { SessionTypes } from '@walletconnect/types' @@ -25,17 +25,15 @@ export const ConnectionForm = ({ uri: string }): ReactElement => { const { walletConnect } = useContext(WalletConnectContext) - const [dismissedHints = false, setDismissedHints] = useLocalStorage(WC_HINTS_KEY) - const [showHints, setShowHints] = useState(!dismissedHints) + const [showHints = false, setShowHints] = useLocalStorage(WC_HINTS_KEY) const onToggle = () => { setShowHints((prev) => !prev) } const onHide = useCallback(() => { - setDismissedHints(true) setShowHints(false) - }, [setDismissedHints]) + }, [setShowHints]) useEffect(() => { if (!walletConnect) { @@ -49,8 +47,7 @@ export const ConnectionForm = ({ - {(!dismissedHints || showHints) && ( + {showHints && ( <> diff --git a/src/components/walletconnect/ProposalForm/useCompatibilityWarning.ts b/src/components/walletconnect/ProposalForm/useCompatibilityWarning.ts index 3b1e68bb35..eb399f0f49 100644 --- a/src/components/walletconnect/ProposalForm/useCompatibilityWarning.ts +++ b/src/components/walletconnect/ProposalForm/useCompatibilityWarning.ts @@ -40,9 +40,9 @@ export const useCompatibilityWarning = ( const { proposer } = proposal.params let { message, severity } = isStrictAddressBridge(origin) - ? Warnings.DANGEROUS_BRIDGE + ? Warnings.BLOCKED_BRIDGE : isDefaultAddressBridge(origin) - ? Warnings.RISKY_BRIDGE + ? Warnings.WARNED_BRIDGE : isUnsupportedChain ? Warnings.UNSUPPORTED_CHAIN : Warnings.WRONG_CHAIN diff --git a/src/services/walletconnect/__tests__/WalletConnectContext.test.tsx b/src/services/walletconnect/__tests__/WalletConnectContext.test.tsx index f4638fca92..38a1fe01a6 100644 --- a/src/services/walletconnect/__tests__/WalletConnectContext.test.tsx +++ b/src/services/walletconnect/__tests__/WalletConnectContext.test.tsx @@ -10,7 +10,6 @@ import WalletConnectWallet from '../WalletConnectWallet' import { safeInfoSlice } from '@/store/safeInfoSlice' import { useAppDispatch } from '@/store' import * as useSafeWalletProvider from '@/services/safe-wallet-provider/useSafeWalletProvider' -import * as useWalletConnectSearchParamUri from '../useWalletConnectSearchParamUri' jest.mock('../WalletConnectWallet') jest.mock('@/services/safe-wallet-provider/useSafeWalletProvider') @@ -89,55 +88,6 @@ describe('WalletConnectProvider', () => { }) }) - it('connects to the session present in the URL', async () => { - jest.spyOn(WalletConnectWallet.prototype, 'init').mockImplementation(() => Promise.resolve()) - jest.spyOn(WalletConnectWallet.prototype, 'updateSessions').mockImplementation(() => Promise.resolve()) - jest.spyOn(WalletConnectWallet.prototype, 'connect').mockImplementation(() => Promise.resolve()) - jest.spyOn(WalletConnectWallet.prototype, 'onSessionAdd').mockImplementation(jest.fn()) - - const mockSetWcUri = jest.fn() - jest - .spyOn(useWalletConnectSearchParamUri, 'useWalletConnectSearchParamUri') - .mockImplementation(() => ['wc:123', mockSetWcUri]) - - const { getByText } = render( - - - , - { - initialReduxState: { - safeInfo: { - loading: false, - data: { - address: { - value: hexZeroPad('0x123', 20), - }, - chainId: '5', - } as SafeInfo, - }, - }, - routerProps: { - query: { - wc: 'wc:123', - }, - }, - }, - ) - - await waitFor(() => { - expect(getByText('WalletConnect initialized')).toBeInTheDocument() - expect(WalletConnectWallet.prototype.connect).toHaveBeenCalledWith('wc:123') - expect(WalletConnectWallet.prototype.onSessionAdd).toHaveBeenCalled() - }) - - // Manually assert that handler will remove the search param - const onSessionAddHandler = (WalletConnectWallet.prototype.onSessionAdd as jest.Mock).mock.calls[0][0] - - expect(mockSetWcUri).not.toHaveBeenCalled() - onSessionAddHandler() - expect(mockSetWcUri).toHaveBeenCalledWith(null) - }) - describe('updateSessions', () => { const getUpdateSafeInfoComponent = (safeInfo: SafeInfo) => { // eslint-disable-next-line react/display-name diff --git a/src/services/walletconnect/__tests__/WalletConnectWallet.test.ts b/src/services/walletconnect/__tests__/WalletConnectWallet.test.ts index 807e6cd184..5298b76360 100644 --- a/src/services/walletconnect/__tests__/WalletConnectWallet.test.ts +++ b/src/services/walletconnect/__tests__/WalletConnectWallet.test.ts @@ -219,16 +219,8 @@ describe('WalletConnectWallet', () => { hexZeroPad('0x123', 20), ) - expect(emitSessionEventSpy).toHaveBeenCalledTimes(2) + expect(emitSessionEventSpy).toHaveBeenCalledTimes(1) expect(emitSessionEventSpy).toHaveBeenNthCalledWith(1, { - topic: 'topic', - event: { - name: 'accountsChanged', - data: [hexZeroPad('0x123', 20)], - }, - chainId: 'eip155:1', - }) - expect(emitSessionEventSpy).toHaveBeenNthCalledWith(2, { topic: 'topic', event: { data: 1, name: 'chainChanged' }, chainId: 'eip155:1', @@ -264,11 +256,40 @@ describe('WalletConnectWallet', () => { hexZeroPad('0x123', 20), ) - expect(emitSpy).toHaveBeenCalledWith('session_add') + expect(emitSpy).toHaveBeenCalledWith('session_add', { namespaces: { eip155: {} }, topic: 'topic' }) }) }) describe('updateSession', () => { + it('should disconnect unsupported chains', async () => { + const disconnectSessionSpy = jest.spyOn((wallet as any).web3Wallet as IWeb3Wallet, 'disconnectSession') + const emitSpy = jest.spyOn(((wallet as any).web3Wallet as IWeb3Wallet).events, 'emit') + + const session = { + topic: 'topic1', + namespaces: { + eip155: { + chains: ['eip155:1'], + accounts: [`eip155:1:${hexZeroPad('0x123', 20)}`], + events: ['chainChanged', 'accountsChanged'], + methods: [], + }, + }, + } as unknown as SessionTypes.Struct + + await (wallet as any).updateSession(session, '69420', hexZeroPad('0x123', 20)) + + expect(disconnectSessionSpy).toHaveBeenCalledWith({ + reason: { + code: 6000, + message: 'User disconnected.', + }, + topic: 'topic1', + }) + + expect(emitSpy).toHaveBeenCalledWith('session_delete', session) + }) + it('should update the session with the correct namespace', async () => { const updateSessionSpy = jest.spyOn((wallet as any).web3Wallet as IWeb3Wallet, 'updateSession') const emitSessionEventSpy = jest.spyOn((wallet as any).web3Wallet as IWeb3Wallet, 'emitSessionEvent') @@ -285,14 +306,14 @@ describe('WalletConnectWallet', () => { }, } as unknown as SessionTypes.Struct - await (wallet as any).updateSession(session, '69420', hexZeroPad('0x123', 20)) + await (wallet as any).updateSession(session, '1', hexZeroPad('0x456', 20)) expect(updateSessionSpy).toHaveBeenCalledWith({ topic: 'topic1', namespaces: { eip155: { - chains: ['eip155:69420', 'eip155:1'], - accounts: [`eip155:69420:${hexZeroPad('0x123', 20)}`, `eip155:1:${hexZeroPad('0x123', 20)}`], + chains: ['eip155:1'], + accounts: [`eip155:1:${hexZeroPad('0x456', 20)}`, `eip155:1:${hexZeroPad('0x123', 20)}`], events: ['chainChanged', 'accountsChanged'], methods: [], }, @@ -326,30 +347,32 @@ describe('WalletConnectWallet', () => { it('should call emitSessionEvent with the correct parameters', async () => { const emitSessionEventSpy = jest.spyOn((wallet as any).web3Wallet as IWeb3Wallet, 'emitSessionEvent') - await (wallet as any).updateSession( - { - topic: 'topic1', - namespaces: {}, - } as SessionTypes.Struct, - '1', - hexZeroPad('0x123', 20), - ) + const session = { + topic: 'topic', + namespaces: { + eip155: { + chains: ['eip155:1'], + accounts: [`eip155:1:${hexZeroPad('0x123', 20)}`], + }, + }, + } as unknown as SessionTypes.Struct - expect(emitSessionEventSpy).toHaveBeenCalledWith({ - topic: 'topic1', + await (wallet as any).updateSession(session, '1', hexZeroPad('0x456', 20)) + + expect(emitSessionEventSpy).toHaveBeenCalledTimes(2) + + expect(emitSessionEventSpy).toHaveBeenNthCalledWith(1, { + topic: 'topic', event: { name: 'accountsChanged', - data: [hexZeroPad('0x123', 20)], + data: [hexZeroPad('0x456', 20)], }, chainId: 'eip155:1', }) - expect(emitSessionEventSpy).toHaveBeenCalledWith({ - topic: 'topic1', - event: { - name: 'chainChanged', - data: 1, - }, + expect(emitSessionEventSpy).toHaveBeenNthCalledWith(2, { + topic: 'topic', + event: { data: 1, name: 'chainChanged' }, chainId: 'eip155:1', }) })