diff --git a/src/services/walletconnect/WalletConnectContext.test.tsx b/src/services/walletconnect/WalletConnectContext.test.tsx
deleted file mode 100644
index 2719b3eb21..0000000000
--- a/src/services/walletconnect/WalletConnectContext.test.tsx
+++ /dev/null
@@ -1,220 +0,0 @@
-import { hexZeroPad } from 'ethers/lib/utils'
-import { useContext } from 'react'
-import type { SafeInfo } from '@safe-global/safe-gateway-typescript-sdk'
-
-import { fireEvent, render, waitFor } from '@/tests/test-utils'
-import { WalletConnectContext, WalletConnectProvider } from './WalletConnectContext'
-import WalletConnectWallet from './WalletConnectWallet'
-import { safeInfoSlice } from '@/store/safeInfoSlice'
-import { useAppDispatch } from '@/store'
-
-jest.mock('./WalletConnectWallet')
-
-const TestComponent = () => {
- const { walletConnect, error } = useContext(WalletConnectContext)
- return (
- <>
- {walletConnect &&
WalletConnect initialized
}
- {error && {error.message}
}
- >
- )
-}
-
-describe('WalletConnectProvider', () => {
- it('sets the walletConnect state', async () => {
- jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
- jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
-
- const { getByText } = render(
-
-
- ,
- {
- initialReduxState: {
- safeInfo: {
- loading: false,
- data: {
- address: {
- value: hexZeroPad('0x123', 20),
- },
- chainId: '5',
- } as SafeInfo,
- },
- },
- },
- )
-
- await waitFor(() => {
- expect(getByText('WalletConnect initialized')).toBeInTheDocument()
- })
- })
-
- it('sets the error state', async () => {
- jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.reject(new Error('Test init failed')))
- jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
-
- const { getByText } = render(
-
-
- ,
- {
- initialReduxState: {
- safeInfo: {
- loading: false,
- data: {
- address: {
- value: hexZeroPad('0x123', 20),
- },
- chainId: '5',
- } as SafeInfo,
- },
- },
- },
- )
-
- await waitFor(() => {
- expect(getByText('Test init failed')).toBeInTheDocument()
- })
- })
-
- describe('updateSessions', () => {
- const getUpdateSafeInfoComponent = (safeInfo: SafeInfo) => {
- // eslint-disable-next-line react/display-name
- return () => {
- const dispatch = useAppDispatch()
- const updateSafeInfo = () => {
- dispatch(
- safeInfoSlice.actions.set({
- loading: false,
- data: safeInfo,
- }),
- )
- }
-
- return
- }
- }
-
- it('updates sessions when the chainId changes', async () => {
- jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
- jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
-
- const ChainUpdater = getUpdateSafeInfoComponent({
- address: { value: hexZeroPad('0x123', 20) },
- chainId: '1',
- } as SafeInfo)
-
- const { getByText } = render(
-
-
-
- ,
- {
- initialReduxState: {
- safeInfo: {
- loading: false,
- data: {
- address: {
- value: hexZeroPad('0x123', 20),
- },
- chainId: '5',
- } as SafeInfo,
- },
- },
- },
- )
-
- await waitFor(() => {
- expect(getByText('WalletConnect initialized')).toBeInTheDocument()
- expect(WalletConnectWallet.updateSessions).toHaveBeenCalledWith('5', hexZeroPad('0x123', 20))
- })
-
- fireEvent.click(getByText('update'))
-
- await waitFor(() => {
- expect(WalletConnectWallet.updateSessions).toHaveBeenCalledWith('1', hexZeroPad('0x123', 20))
- })
- })
-
- it('updates sessions when the safeAddress changes', async () => {
- jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
- jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
-
- const AddressUpdater = getUpdateSafeInfoComponent({
- address: { value: hexZeroPad('0x456', 20) },
- chainId: '5',
- } as SafeInfo)
-
- const { getByText } = render(
-
-
-
- ,
- {
- initialReduxState: {
- safeInfo: {
- loading: false,
- data: {
- address: {
- value: hexZeroPad('0x123', 20),
- },
- chainId: '5',
- } as SafeInfo,
- },
- },
- },
- )
-
- await waitFor(() => {
- expect(getByText('WalletConnect initialized')).toBeInTheDocument()
- expect(WalletConnectWallet.updateSessions).toHaveBeenCalledWith('5', hexZeroPad('0x123', 20))
- })
-
- fireEvent.click(getByText('update'))
-
- await waitFor(() => {
- expect(WalletConnectWallet.updateSessions).toHaveBeenCalledWith('5', hexZeroPad('0x456', 20))
- })
- })
-
- it('sets the error state', async () => {
- jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
- jest
- .spyOn(WalletConnectWallet, 'updateSessions')
- .mockImplementation(() => Promise.reject(new Error('Test updateSessions failed')))
-
- const { getByText } = render(
-
-
- ,
- {
- initialReduxState: {
- safeInfo: {
- loading: false,
- data: {
- address: {
- value: hexZeroPad('0x123', 20),
- },
- chainId: '5',
- } as SafeInfo,
- },
- },
- },
- )
-
- await waitFor(() => {
- expect(getByText('Test updateSessions failed')).toBeInTheDocument()
- })
- })
- })
-
- describe('onRequest', () => {
- it.todo('does not continue with the request if there is no matching topic')
-
- it.todo('does not continue with the request if there is no matching chainId')
-
- it.todo('passes the request onto the Safe Wallet Provider and sends the response to WalletConnect')
-
- it.todo('sets the error state if there is an error requesting the response from the Safe Wallet Provider')
- })
-})
diff --git a/src/services/walletconnect/WalletConnectContext.tsx b/src/services/walletconnect/WalletConnectContext.tsx
index ec95c6eb30..7848cc2cc7 100644
--- a/src/services/walletconnect/WalletConnectContext.tsx
+++ b/src/services/walletconnect/WalletConnectContext.tsx
@@ -60,6 +60,8 @@ export const WalletConnectProvider = ({ children }: { children: ReactNode }) =>
iconUrl: session.peer.metadata.icons[0],
})
+ console.log('============', response)
+
// Send response to WalletConnect
await walletConnect.sendSessionResponse(topic, response)
} catch (e) {
diff --git a/src/services/walletconnect/__tests__/WalletConnectContext.test.tsx b/src/services/walletconnect/__tests__/WalletConnectContext.test.tsx
new file mode 100644
index 0000000000..9a3e108c88
--- /dev/null
+++ b/src/services/walletconnect/__tests__/WalletConnectContext.test.tsx
@@ -0,0 +1,476 @@
+import { hexZeroPad } from 'ethers/lib/utils'
+import { useContext } from 'react'
+import type { SafeInfo } from '@safe-global/safe-gateway-typescript-sdk'
+import type { Web3WalletTypes } from '@walletconnect/web3wallet'
+import type { SessionTypes } from '@walletconnect/types'
+
+import { fireEvent, render, waitFor } from '@/tests/test-utils'
+import { WalletConnectContext, WalletConnectProvider } from '../WalletConnectContext'
+import WalletConnectWallet from '../WalletConnectWallet'
+import { safeInfoSlice } from '@/store/safeInfoSlice'
+import { useAppDispatch } from '@/store'
+import * as useSafeWalletProvider from '@/services/safe-wallet-provider/useSafeWalletProvider'
+
+jest.mock('../WalletConnectWallet')
+jest.mock('@/services/safe-wallet-provider/useSafeWalletProvider')
+
+const TestComponent = () => {
+ const { walletConnect, error } = useContext(WalletConnectContext)
+ return (
+ <>
+ {walletConnect && WalletConnect initialized
}
+ {error && {error.message}
}
+ >
+ )
+}
+
+describe('WalletConnectProvider', () => {
+ beforeEach(() => {
+ jest.resetAllMocks()
+ })
+
+ it('sets the walletConnect state', async () => {
+ jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
+
+ const { getByText } = render(
+
+
+ ,
+ {
+ initialReduxState: {
+ safeInfo: {
+ loading: false,
+ data: {
+ address: {
+ value: hexZeroPad('0x123', 20),
+ },
+ chainId: '5',
+ } as SafeInfo,
+ },
+ },
+ },
+ )
+
+ await waitFor(() => {
+ expect(getByText('WalletConnect initialized')).toBeInTheDocument()
+ })
+ })
+
+ it('sets the error state', async () => {
+ jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.reject(new Error('Test init failed')))
+ jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
+
+ const { getByText } = render(
+
+
+ ,
+ {
+ initialReduxState: {
+ safeInfo: {
+ loading: false,
+ data: {
+ address: {
+ value: hexZeroPad('0x123', 20),
+ },
+ chainId: '5',
+ } as SafeInfo,
+ },
+ },
+ },
+ )
+
+ await waitFor(() => {
+ expect(getByText('Test init failed')).toBeInTheDocument()
+ })
+ })
+
+ describe('updateSessions', () => {
+ const getUpdateSafeInfoComponent = (safeInfo: SafeInfo) => {
+ // eslint-disable-next-line react/display-name
+ return () => {
+ const dispatch = useAppDispatch()
+ const updateSafeInfo = () => {
+ dispatch(
+ safeInfoSlice.actions.set({
+ loading: false,
+ data: safeInfo,
+ }),
+ )
+ }
+
+ return
+ }
+ }
+
+ it('updates sessions when the chainId changes', async () => {
+ jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
+
+ const ChainUpdater = getUpdateSafeInfoComponent({
+ address: { value: hexZeroPad('0x123', 20) },
+ chainId: '1',
+ } as SafeInfo)
+
+ const { getByText } = render(
+
+
+
+ ,
+ {
+ initialReduxState: {
+ safeInfo: {
+ loading: false,
+ data: {
+ address: {
+ value: hexZeroPad('0x123', 20),
+ },
+ chainId: '5',
+ } as SafeInfo,
+ },
+ },
+ },
+ )
+
+ await waitFor(() => {
+ expect(getByText('WalletConnect initialized')).toBeInTheDocument()
+ expect(WalletConnectWallet.updateSessions).toHaveBeenCalledWith('5', hexZeroPad('0x123', 20))
+ })
+
+ fireEvent.click(getByText('update'))
+
+ await waitFor(() => {
+ expect(WalletConnectWallet.updateSessions).toHaveBeenCalledWith('1', hexZeroPad('0x123', 20))
+ })
+ })
+
+ it('updates sessions when the safeAddress changes', async () => {
+ jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
+
+ const AddressUpdater = getUpdateSafeInfoComponent({
+ address: { value: hexZeroPad('0x456', 20) },
+ chainId: '5',
+ } as SafeInfo)
+
+ const { getByText } = render(
+
+
+
+ ,
+ {
+ initialReduxState: {
+ safeInfo: {
+ loading: false,
+ data: {
+ address: {
+ value: hexZeroPad('0x123', 20),
+ },
+ chainId: '5',
+ } as SafeInfo,
+ },
+ },
+ },
+ )
+
+ await waitFor(() => {
+ expect(getByText('WalletConnect initialized')).toBeInTheDocument()
+ expect(WalletConnectWallet.updateSessions).toHaveBeenCalledWith('5', hexZeroPad('0x123', 20))
+ })
+
+ fireEvent.click(getByText('update'))
+
+ await waitFor(() => {
+ expect(WalletConnectWallet.updateSessions).toHaveBeenCalledWith('5', hexZeroPad('0x456', 20))
+ })
+ })
+
+ it('sets the error state', async () => {
+ jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
+ jest
+ .spyOn(WalletConnectWallet, 'updateSessions')
+ .mockImplementation(() => Promise.reject(new Error('Test updateSessions failed')))
+
+ const { getByText } = render(
+
+
+ ,
+ {
+ initialReduxState: {
+ safeInfo: {
+ loading: false,
+ data: {
+ address: {
+ value: hexZeroPad('0x123', 20),
+ },
+ chainId: '5',
+ } as SafeInfo,
+ },
+ },
+ },
+ )
+
+ await waitFor(() => {
+ expect(getByText('Test updateSessions failed')).toBeInTheDocument()
+ })
+ })
+ })
+
+ describe('onRequest', () => {
+ it('does not continue with the request if there is no matching topic', async () => {
+ jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'getActiveSessions').mockImplementation(() => [])
+
+ const onRequestSpy = jest.spyOn(WalletConnectWallet, 'onRequest')
+ const sendSessionResponseSpy = jest.spyOn(WalletConnectWallet, 'sendSessionResponse')
+
+ const mockRequest = jest.fn()
+ jest.spyOn(useSafeWalletProvider, 'default').mockImplementation(
+ () =>
+ ({
+ request: mockRequest,
+ } as unknown as ReturnType),
+ )
+
+ render(
+
+
+ ,
+ {
+ initialReduxState: {
+ safeInfo: {
+ loading: false,
+ data: {
+ address: {
+ value: hexZeroPad('0x123', 20),
+ },
+ chainId: '5',
+ } as SafeInfo,
+ },
+ },
+ },
+ )
+
+ await waitFor(() => {
+ expect(onRequestSpy).toHaveBeenCalled()
+ })
+
+ const onRequestHandler = onRequestSpy.mock.calls[0][0]
+
+ onRequestHandler({
+ id: 1,
+ topic: 'topic',
+ params: {
+ request: {},
+ chainId: 'eip155:5', // Goerli
+ },
+ } as unknown as Web3WalletTypes.SessionRequest)
+
+ expect(mockRequest).not.toHaveBeenCalled()
+ expect(sendSessionResponseSpy).not.toHaveBeenCalled()
+ })
+
+ it('does not continue with the request if there is no matching chainId', async () => {
+ jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
+ jest
+ .spyOn(WalletConnectWallet, 'getActiveSessions')
+ .mockImplementation(() => [{ topic: 'topic' } as unknown as SessionTypes.Struct])
+
+ const onRequestSpy = jest.spyOn(WalletConnectWallet, 'onRequest')
+ const sendSessionResponseSpy = jest.spyOn(WalletConnectWallet, 'sendSessionResponse')
+
+ const mockRequest = jest.fn()
+ jest.spyOn(useSafeWalletProvider, 'default').mockImplementation(
+ () =>
+ ({
+ request: mockRequest,
+ } as unknown as ReturnType),
+ )
+
+ render(
+
+
+ ,
+ {
+ initialReduxState: {
+ safeInfo: {
+ loading: false,
+ data: {
+ address: {
+ value: hexZeroPad('0x123', 20),
+ },
+ chainId: '5',
+ } as SafeInfo,
+ },
+ },
+ },
+ )
+
+ await waitFor(() => {
+ expect(onRequestSpy).toHaveBeenCalled()
+ })
+
+ const onRequestHandler = onRequestSpy.mock.calls[0][0]
+
+ onRequestHandler({
+ id: 1,
+ topic: 'topic',
+ params: {
+ request: {},
+ chainId: 'eip155:1', // Mainnet
+ },
+ } as unknown as Web3WalletTypes.SessionRequest)
+
+ expect(mockRequest).not.toHaveBeenCalled()
+ expect(sendSessionResponseSpy).not.toHaveBeenCalled()
+ })
+
+ it('passes the request onto the Safe Wallet Provider and sends the response to WalletConnect', async () => {
+ jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'getActiveSessions').mockImplementation(() => [
+ {
+ topic: 'topic',
+ peer: {
+ metadata: {
+ name: 'name',
+ description: 'description',
+ url: 'url',
+ icons: ['iconUrl'],
+ },
+ },
+ } as unknown as SessionTypes.Struct,
+ ])
+
+ const onRequestSpy = jest.spyOn(WalletConnectWallet, 'onRequest')
+ const sendSessionResponseSpy = jest.spyOn(WalletConnectWallet, 'sendSessionResponse')
+
+ const mockRequest = jest.fn().mockImplementation(() => Promise.resolve({}))
+ jest.spyOn(useSafeWalletProvider, 'default').mockImplementation(
+ () =>
+ ({
+ request: mockRequest,
+ } as unknown as ReturnType),
+ )
+
+ render(
+
+
+ ,
+ {
+ initialReduxState: {
+ safeInfo: {
+ loading: false,
+ data: {
+ address: {
+ value: hexZeroPad('0x123', 20),
+ },
+ chainId: '5',
+ } as SafeInfo,
+ },
+ },
+ },
+ )
+
+ await waitFor(() => {
+ expect(onRequestSpy).toHaveBeenCalled()
+ })
+
+ const onRequestHandler = onRequestSpy.mock.calls[0][0]
+
+ onRequestHandler({
+ id: 1,
+ topic: 'topic',
+ params: {
+ request: { method: 'fake', params: [] },
+ chainId: 'eip155:5', // Goerli
+ },
+ } as unknown as Web3WalletTypes.SessionRequest)
+
+ expect(mockRequest).toHaveBeenCalledWith(
+ 1,
+ { method: 'fake', params: [] },
+ {
+ name: 'name',
+ description: 'description',
+ url: 'url',
+ iconUrl: 'iconUrl',
+ },
+ )
+
+ await waitFor(() => {
+ expect(sendSessionResponseSpy).toHaveBeenCalledWith('topic', {})
+ })
+ })
+
+ it('sets the error state if there is an error requesting', async () => {
+ jest.spyOn(WalletConnectWallet, 'init').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'updateSessions').mockImplementation(() => Promise.resolve())
+ jest.spyOn(WalletConnectWallet, 'getActiveSessions').mockImplementation(() => [
+ {
+ topic: 'topic',
+ peer: {
+ metadata: {
+ name: 'name',
+ description: 'description',
+ url: 'url',
+ icons: ['iconUrl'],
+ },
+ },
+ } as unknown as SessionTypes.Struct,
+ ])
+
+ jest.spyOn(useSafeWalletProvider, 'default').mockImplementation(
+ () =>
+ ({
+ request: () => Promise.reject(new Error('Test request failed')),
+ } as unknown as ReturnType),
+ )
+
+ const onRequestSpy = jest.spyOn(WalletConnectWallet, 'onRequest')
+ const sendSessionResponseSpy = jest.spyOn(WalletConnectWallet, 'sendSessionResponse')
+
+ const { getByText } = render(
+
+
+ ,
+ {
+ initialReduxState: {
+ safeInfo: {
+ loading: false,
+ data: {
+ address: {
+ value: hexZeroPad('0x123', 20),
+ },
+ chainId: '5',
+ } as SafeInfo,
+ },
+ },
+ },
+ )
+
+ await waitFor(() => {
+ expect(onRequestSpy).toHaveBeenCalled()
+ })
+
+ const onRequestHandler = onRequestSpy.mock.calls[0][0]
+
+ onRequestHandler({
+ id: 1,
+ topic: 'topic',
+ params: {
+ request: {},
+ chainId: 'eip155:5', // Goerli
+ },
+ } as unknown as Web3WalletTypes.SessionRequest)
+
+ expect(sendSessionResponseSpy).not.toHaveBeenCalled()
+
+ await waitFor(() => {
+ expect(getByText('Test request failed')).toBeInTheDocument()
+ })
+ })
+ })
+})
diff --git a/src/services/walletconnect/WalletConnectWallet.test.ts b/src/services/walletconnect/__tests__/WalletConnectWallet.test.ts
similarity index 99%
rename from src/services/walletconnect/WalletConnectWallet.test.ts
rename to src/services/walletconnect/__tests__/WalletConnectWallet.test.ts
index 9655de631d..47e7203b29 100644
--- a/src/services/walletconnect/WalletConnectWallet.test.ts
+++ b/src/services/walletconnect/__tests__/WalletConnectWallet.test.ts
@@ -2,7 +2,7 @@ import { hexZeroPad } from 'ethers/lib/utils'
import type { ProposalTypes, SessionTypes, SignClientTypes, Verify } from '@walletconnect/types'
import type { IWeb3Wallet, Web3WalletTypes } from '@walletconnect/web3wallet'
-import type WalletConnectWallet from './WalletConnectWallet'
+import type WalletConnectWallet from '../WalletConnectWallet'
jest.mock('@walletconnect/core', () => ({
Core: jest.fn(),
@@ -49,7 +49,7 @@ describe('WalletConnectWallet', () => {
beforeEach(async () => {
// Reset import
- wallet = (await import('./WalletConnectWallet')).default
+ wallet = (await import('../WalletConnectWallet')).default
await wallet.init()
})
diff --git a/src/services/walletconnect/useWalletConnectSessions.test.tsx b/src/services/walletconnect/__tests__/useWalletConnectSessions.test.tsx
similarity index 96%
rename from src/services/walletconnect/useWalletConnectSessions.test.tsx
rename to src/services/walletconnect/__tests__/useWalletConnectSessions.test.tsx
index 8754bf36fa..aaf3d30aa6 100644
--- a/src/services/walletconnect/useWalletConnectSessions.test.tsx
+++ b/src/services/walletconnect/__tests__/useWalletConnectSessions.test.tsx
@@ -1,7 +1,7 @@
import { renderHook, waitFor } from '@/tests/test-utils'
import { WalletConnectContext } from '@/services/walletconnect/WalletConnectContext'
-import useWalletConnectSessions from './useWalletConnectSessions'
-import type WalletConnectWallet from './WalletConnectWallet'
+import useWalletConnectSessions from '../useWalletConnectSessions'
+import type WalletConnectWallet from '../WalletConnectWallet'
describe('useWalletConnectSessions', () => {
it('should return an array of active sessions', () => {