@@ -34,7 +34,7 @@ const writableIsSafeWalletAtom = isSafeWalletAtom as WritableAtom<boolean, [bool
3434
3535import type { WalletCapabilities } from './walletCapabilitiesAtom'
3636import type { WalletInfo } from '../types'
37- import type { EIP1193Provider } from 'viem'
37+ import type { EIP1193Provider , PublicClient } from 'viem'
3838import type { Connector } from 'wagmi'
3939
4040jest . mock ( '../../wagmi/state/walletMetadata.atoms' , ( ) => {
@@ -53,25 +53,22 @@ const MOCK_ACCOUNT = '0x1234567890123456789012345678901234567890' as const
5353const MOCK_CHAIN_ID = SupportedChainId . MAINNET
5454const MOCK_CONNECTOR = { type : 'injected' } as Connector
5555
56- const mockLogWalletWarn = jest . fn ( )
5756const mockGetCapabilities = jest . fn ( )
5857const mockWagmiConfigGetClient = jest . fn ( )
5958const mockGetIsWalletConnect = jest . fn ( )
6059const mockIsMobile = { value : false }
6160
62- jest . mock ( '@cowprotocol/common-utils' , ( ) => ( {
63- getCurrentChainIdFromUrl : ( ) => 1 ,
64- get isMobile ( ) {
65- return mockIsMobile . value
66- } ,
67- logWallet : {
68- warn : ( ...args : unknown [ ] ) => mockLogWalletWarn ( ...args ) ,
69- } ,
70- PromiseWithTimeout : < T > ( _ : number , handler : ( resolve : ( value : T ) => void ) => void ) : Promise < T > =>
71- new Promise < T > ( ( resolve ) => {
72- handler ( resolve )
73- } ) ,
74- } ) )
61+ jest . mock ( '@cowprotocol/common-utils' , ( ) => {
62+ const actual = jest . requireActual < typeof import ( '@cowprotocol/common-utils' ) > ( '@cowprotocol/common-utils' )
63+
64+ return {
65+ ...actual ,
66+ getCurrentChainIdFromUrl : ( ) => 1 ,
67+ get isMobile ( ) {
68+ return mockIsMobile . value
69+ } ,
70+ }
71+ } )
7572
7673jest . mock ( '../../wagmi/hooks/useIsWalletConnect' , ( ) => ( {
7774 getIsWalletConnect : ( ...args : unknown [ ] ) => mockGetIsWalletConnect ( ...args ) ,
@@ -101,7 +98,7 @@ function setWalletInfo(
10198 account : string
10299 chainId : SupportedChainId
103100 connector : Connector
104- provider : EIP1193Provider
101+ provider : EIP1193Provider | PublicClient
105102 } > = { } ,
106103) : void {
107104 store . set ( walletInfoAtom , {
@@ -303,21 +300,34 @@ describe('walletCapabilitiesAtom', () => {
303300 } )
304301 } )
305302
306- it ( 'returns empty object when getCapabilities does not settle before timeout' , async ( ) => {
303+ it ( 'returns null when getCapabilities fails and provider does not support EIP-1193 requests' , async ( ) => {
304+ const error = new Error ( 'viem error' )
305+ mockGetCapabilities . mockRejectedValue ( error )
306+
307+ const store = createStore ( )
308+ setWalletInfo ( store , { provider : { } as PublicClient } )
309+
310+ const result = await store . get ( walletCapabilitiesAtom )
311+
312+ expect ( result ) . toBeNull ( )
313+ } )
314+
315+ it ( 'returns null when getCapabilities times out and provider does not support EIP-1193 requests' , async ( ) => {
307316 jest . useFakeTimers ( )
308317 mockGetCapabilities . mockImplementation ( ( ) => new Promise ( ( ) => undefined ) )
309318
310319 const store = createStore ( )
311- setWalletInfo ( store )
312-
313- const resultPromise = store . get ( walletCapabilitiesAtom )
314- await jest . advanceTimersByTimeAsync ( 5_000 )
315- const result = await resultPromise
320+ setWalletInfo ( store , { provider : { } as PublicClient } )
316321
317- expect ( result ) . toEqual ( { } )
318- expect ( mockLogWalletWarn ) . toHaveBeenCalledWith ( expect . stringContaining ( 'Wallet capabilities loading timed out' ) )
322+ try {
323+ const resultPromise = store . get ( walletCapabilitiesAtom )
324+ await jest . advanceTimersByTimeAsync ( 5_000 )
325+ const result = await resultPromise
319326
320- jest . useRealTimers ( )
327+ expect ( result ) . toBeNull ( )
328+ } finally {
329+ jest . useRealTimers ( )
330+ }
321331 } )
322332 } )
323333
@@ -347,6 +357,49 @@ describe('walletCapabilitiesAtom', () => {
347357
348358 expect ( result ) . toEqual ( capabilities )
349359 } )
360+
361+ it ( 'uses legacy fallback when getCapabilities times out' , async ( ) => {
362+ jest . useFakeTimers ( )
363+ const capabilities : WalletCapabilities = { atomic : { status : 'supported' } }
364+ mockGetCapabilities . mockImplementation ( ( ) => new Promise ( ( ) => undefined ) )
365+ const mockRequest = jest . fn ( ) . mockResolvedValue ( { '0x1' : capabilities } )
366+
367+ const store = createStore ( )
368+ setWalletInfo ( store , { provider : createMockEip1193Provider ( mockRequest ) } )
369+
370+ try {
371+ const resultPromise = store . get ( walletCapabilitiesAtom )
372+ await jest . advanceTimersByTimeAsync ( 5_000 )
373+ const result = await resultPromise
374+
375+ expect ( result ) . toEqual ( capabilities )
376+ expect ( mockRequest ) . toHaveBeenCalledWith ( {
377+ method : 'wallet_getCapabilities' ,
378+ params : [ MOCK_ACCOUNT ] ,
379+ } )
380+ } finally {
381+ jest . useRealTimers ( )
382+ }
383+ } )
384+
385+ it ( 'returns null when legacy fallback times out' , async ( ) => {
386+ jest . useFakeTimers ( )
387+ mockGetCapabilities . mockRejectedValue ( new Error ( 'viem error' ) )
388+ const mockRequest = jest . fn ( ) . mockImplementation ( ( ) => new Promise ( ( ) => undefined ) )
389+
390+ const store = createStore ( )
391+ setWalletInfo ( store , { provider : createMockEip1193Provider ( mockRequest ) } )
392+
393+ try {
394+ const resultPromise = store . get ( walletCapabilitiesAtom )
395+ await jest . advanceTimersByTimeAsync ( 5_000 )
396+ const result = await resultPromise
397+
398+ expect ( result ) . toBeNull ( )
399+ } finally {
400+ jest . useRealTimers ( )
401+ }
402+ } )
350403 } )
351404} )
352405
0 commit comments