Skip to content

Commit 0b71643

Browse files
refactor: remove wallet capabilities fallback
1 parent 0eb7628 commit 0b71643

6 files changed

Lines changed: 35 additions & 305 deletions

File tree

libs/wallet/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
"@cowprotocol/iframe-transport": "workspace:*",
4242
"@cowprotocol/types": "workspace:*",
4343
"@cowprotocol/ui": "workspace:*",
44-
"@cowprotocol/wallet-provider": "workspace:*",
4544
"@ethereumjs/util": "10.1.0",
4645
"@metamask/jazzicon": "2.0.0",
4746
"@metamask/sdk": "0.31.4",

libs/wallet/src/api/state/walletCapabilitiesAtom.test.ts

Lines changed: 17 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { createStore, type WritableAtom } from 'jotai'
22

3-
import type { EIP1193Provider, PublicClient } from 'viem'
43
import type { Connector } from 'wagmi'
54

65
import { SupportedChainId } from '@cowprotocol/cow-sdk'
@@ -9,7 +8,6 @@ import {
98
isAtomicBatchSupportedAtom,
109
isAtomicBatchSupportedAsyncAtom,
1110
isAtomicBatchSupportedLoadableAtom,
12-
resolveCapabilitiesForChain,
1311
walletCapabilitiesAtom,
1412
} from './walletCapabilitiesAtom'
1513

@@ -37,79 +35,34 @@ const MOCK_CHAIN_ID = SupportedChainId.MAINNET
3735
const MOCK_CONNECTOR = { type: 'injected' } as Connector
3836

3937
const mockGetCapabilities = jest.fn()
40-
const mockWagmiConfigGetClient = jest.fn()
4138

42-
jest.mock('viem/actions', () => ({
39+
jest.mock('wagmi/actions', () => ({
4340
getCapabilities: (...args: unknown[]) => mockGetCapabilities(...args),
4441
}))
4542

4643
jest.mock('../../wagmi/config', () => ({
47-
wagmiConfig: {
48-
getClient: (...args: unknown[]) => mockWagmiConfigGetClient(...args),
49-
},
44+
wagmiConfig: {},
5045
}))
5146

52-
function createMockEip1193Provider(request = jest.fn()): EIP1193Provider {
53-
return {
54-
request,
55-
on: jest.fn(),
56-
removeListener: jest.fn(),
57-
} as unknown as EIP1193Provider
58-
}
59-
6047
function setWalletInfo(
6148
store: ReturnType<typeof createStore>,
6249
overrides: Partial<{
6350
account: string
6451
chainId: SupportedChainId
6552
connector: Connector
66-
provider: NonNullable<WalletInfo['provider']>
6753
}> = {},
6854
): void {
6955
store.set(walletInfoAtom, {
7056
chainId: overrides.chainId ?? MOCK_CHAIN_ID,
7157
account: overrides.account ?? MOCK_ACCOUNT,
7258
connector: overrides.connector ?? MOCK_CONNECTOR,
73-
provider: overrides.provider ?? createMockEip1193Provider(),
7459
})
7560
}
7661

77-
describe('resolveCapabilitiesForChain', () => {
78-
const capabilities: WalletCapabilities = { atomic: { status: 'supported' } }
79-
80-
it('matches numeric chain id key', () => {
81-
expect(resolveCapabilitiesForChain({ [MOCK_CHAIN_ID]: capabilities }, MOCK_CHAIN_ID)).toEqual(capabilities)
82-
})
83-
84-
it('matches hex chain id key', () => {
85-
expect(resolveCapabilitiesForChain({ '0x1': capabilities }, MOCK_CHAIN_ID)).toEqual(capabilities)
86-
})
87-
88-
it('returns null when no chain key matches', () => {
89-
expect(resolveCapabilitiesForChain({ '0x64': capabilities }, MOCK_CHAIN_ID)).toBeNull()
90-
})
91-
92-
it('returns null for empty capabilities', () => {
93-
expect(resolveCapabilitiesForChain({}, MOCK_CHAIN_ID)).toBeNull()
94-
})
95-
})
96-
9762
describe('walletCapabilitiesAtom', () => {
9863
beforeEach(() => {
9964
jest.clearAllMocks()
10065
mockGetCapabilities.mockResolvedValue({})
101-
mockWagmiConfigGetClient.mockReturnValue({ chainId: MOCK_CHAIN_ID })
102-
})
103-
104-
it('returns null when isSafeViaWc is still loading', async () => {
105-
const store = createStore()
106-
store.set(writableIsSafeViaWcAtom, null)
107-
setWalletInfo(store)
108-
109-
const result = await store.get(walletCapabilitiesAtom)
110-
111-
expect(result).toBeNull()
112-
expect(mockGetCapabilities).not.toHaveBeenCalled()
11366
})
11467

11568
describe('walletInfoAtom state: missing required fields', () => {
@@ -118,7 +71,6 @@ describe('walletCapabilitiesAtom', () => {
11871
store.set(walletInfoAtom, {
11972
chainId: MOCK_CHAIN_ID,
12073
connector: MOCK_CONNECTOR,
121-
provider: createMockEip1193Provider(),
12274
})
12375

12476
const result = await store.get(walletCapabilitiesAtom)
@@ -132,7 +84,6 @@ describe('walletCapabilitiesAtom', () => {
13284
store.set(walletInfoAtom, {
13385
account: MOCK_ACCOUNT,
13486
connector: MOCK_CONNECTOR,
135-
provider: createMockEip1193Provider(),
13687
} as WalletInfo)
13788

13889
const result = await store.get(walletCapabilitiesAtom)
@@ -146,21 +97,6 @@ describe('walletCapabilitiesAtom', () => {
14697
store.set(walletInfoAtom, {
14798
chainId: MOCK_CHAIN_ID,
14899
account: MOCK_ACCOUNT,
149-
provider: createMockEip1193Provider(),
150-
})
151-
152-
const result = await store.get(walletCapabilitiesAtom)
153-
154-
expect(result).toBeNull()
155-
expect(mockGetCapabilities).not.toHaveBeenCalled()
156-
})
157-
158-
it('returns null when provider is missing', async () => {
159-
const store = createStore()
160-
store.set(walletInfoAtom, {
161-
chainId: MOCK_CHAIN_ID,
162-
account: MOCK_ACCOUNT,
163-
connector: MOCK_CONNECTOR,
164100
})
165101

166102
const result = await store.get(walletCapabilitiesAtom)
@@ -170,7 +106,7 @@ describe('walletCapabilitiesAtom', () => {
170106
})
171107
})
172108

173-
describe('getCapabilities (viem)', () => {
109+
describe('getCapabilities (wagmi)', () => {
174110
it('returns capabilities when getCapabilities resolves for the current chain', async () => {
175111
const capabilities: WalletCapabilities = { atomic: { status: 'supported' } }
176112
mockGetCapabilities.mockResolvedValue(capabilities)
@@ -181,8 +117,14 @@ describe('walletCapabilitiesAtom', () => {
181117
const result = await store.get(walletCapabilitiesAtom)
182118

183119
expect(result).toEqual(capabilities)
184-
expect(mockGetCapabilities).toHaveBeenCalled()
185-
expect(mockWagmiConfigGetClient).toHaveBeenCalledWith({ chainId: MOCK_CHAIN_ID })
120+
expect(mockGetCapabilities).toHaveBeenCalledWith(
121+
expect.anything(),
122+
expect.objectContaining({
123+
account: MOCK_ACCOUNT,
124+
chainId: MOCK_CHAIN_ID,
125+
connector: MOCK_CONNECTOR,
126+
}),
127+
)
186128
})
187129

188130
it('returns empty capabilities object when getCapabilities resolves with no fields', async () => {
@@ -196,111 +138,23 @@ describe('walletCapabilitiesAtom', () => {
196138
expect(result).toEqual({})
197139
})
198140

199-
it('returns null when getCapabilities and wallet_getCapabilities both fail', async () => {
200-
mockGetCapabilities.mockRejectedValue(new Error('viem error'))
201-
const mockRequest = jest.fn().mockRejectedValue(new Error('legacy error'))
202-
203-
const store = createStore()
204-
setWalletInfo(store, { provider: createMockEip1193Provider(mockRequest) })
205-
206-
const result = await store.get(walletCapabilitiesAtom)
207-
208-
expect(result).toBeNull()
209-
expect(mockRequest).toHaveBeenCalledWith({
210-
method: 'wallet_getCapabilities',
211-
params: [MOCK_ACCOUNT],
212-
})
213-
})
214-
215-
it('returns null when getCapabilities fails and provider does not support EIP-1193 requests', async () => {
216-
const error = new Error('viem error')
217-
mockGetCapabilities.mockRejectedValue(error)
141+
it('returns null when getCapabilities fails', async () => {
142+
mockGetCapabilities.mockRejectedValue(new Error('wagmi error'))
218143

219144
const store = createStore()
220-
setWalletInfo(store, { provider: {} as PublicClient })
221-
222-
const result = await store.get(walletCapabilitiesAtom)
223-
224-
expect(result).toBeNull()
225-
})
226-
227-
it('returns null when getCapabilities times out and provider does not support EIP-1193 requests', async () => {
228-
jest.useFakeTimers()
229-
mockGetCapabilities.mockImplementation(() => new Promise(() => undefined))
230-
231-
const store = createStore()
232-
setWalletInfo(store, { provider: {} as PublicClient })
233-
234-
try {
235-
const resultPromise = store.get(walletCapabilitiesAtom)
236-
await jest.advanceTimersByTimeAsync(5_000)
237-
const result = await resultPromise
238-
239-
expect(result).toBeNull()
240-
} finally {
241-
jest.useRealTimers()
242-
}
243-
})
244-
})
245-
246-
describe('wallet_getCapabilities legacy fallback', () => {
247-
it('returns capabilities resolved from hex chain id key when viem throws', async () => {
248-
const capabilities: WalletCapabilities = { atomic: { status: 'supported' } }
249-
mockGetCapabilities.mockRejectedValue(new Error('viem error'))
250-
const mockRequest = jest.fn().mockResolvedValue({ '0x1': capabilities })
251-
252-
const store = createStore()
253-
setWalletInfo(store, { provider: createMockEip1193Provider(mockRequest) })
254-
255-
const result = await store.get(walletCapabilitiesAtom)
256-
257-
expect(result).toEqual(capabilities)
258-
})
259-
260-
it('returns null when the current chain capability is missing', async () => {
261-
const capabilities: WalletCapabilities = { atomic: { status: 'supported' } }
262-
mockGetCapabilities.mockRejectedValue(new Error('viem error'))
263-
const mockRequest = jest.fn().mockResolvedValue({ '0x64': capabilities })
264-
265-
const store = createStore()
266-
setWalletInfo(store, { provider: createMockEip1193Provider(mockRequest) })
145+
setWalletInfo(store)
267146

268147
const result = await store.get(walletCapabilitiesAtom)
269148

270149
expect(result).toBeNull()
271150
})
272151

273-
it('uses legacy fallback when getCapabilities times out', async () => {
152+
it('returns null when getCapabilities times out', async () => {
274153
jest.useFakeTimers()
275-
const capabilities: WalletCapabilities = { atomic: { status: 'supported' } }
276154
mockGetCapabilities.mockImplementation(() => new Promise(() => undefined))
277-
const mockRequest = jest.fn().mockResolvedValue({ '0x1': capabilities })
278155

279156
const store = createStore()
280-
setWalletInfo(store, { provider: createMockEip1193Provider(mockRequest) })
281-
282-
try {
283-
const resultPromise = store.get(walletCapabilitiesAtom)
284-
await jest.advanceTimersByTimeAsync(5_000)
285-
const result = await resultPromise
286-
287-
expect(result).toEqual(capabilities)
288-
expect(mockRequest).toHaveBeenCalledWith({
289-
method: 'wallet_getCapabilities',
290-
params: [MOCK_ACCOUNT],
291-
})
292-
} finally {
293-
jest.useRealTimers()
294-
}
295-
})
296-
297-
it('returns null when legacy fallback times out', async () => {
298-
jest.useFakeTimers()
299-
mockGetCapabilities.mockRejectedValue(new Error('viem error'))
300-
const mockRequest = jest.fn().mockImplementation(() => new Promise(() => undefined))
301-
302-
const store = createStore()
303-
setWalletInfo(store, { provider: createMockEip1193Provider(mockRequest) })
157+
setWalletInfo(store)
304158

305159
try {
306160
const resultPromise = store.get(walletCapabilitiesAtom)
@@ -319,7 +173,6 @@ describe('isAtomicBatchSupportedAsyncAtom', () => {
319173
beforeEach(() => {
320174
jest.clearAllMocks()
321175
mockGetCapabilities.mockResolvedValue({})
322-
mockWagmiConfigGetClient.mockReturnValue({ chainId: MOCK_CHAIN_ID })
323176
})
324177

325178
it('returns false when walletInfoAtom yields no capabilities (disconnected)', async () => {
@@ -411,7 +264,6 @@ describe('isAtomicBatchSupportedLoadableAtom and isAtomicBatchSupportedAtom', ()
411264
beforeEach(() => {
412265
jest.clearAllMocks()
413266
mockGetCapabilities.mockResolvedValue({})
414-
mockWagmiConfigGetClient.mockReturnValue({ chainId: MOCK_CHAIN_ID })
415267
})
416268

417269
it('isAtomicBatchSupportedAtom returns null while loading', async () => {
@@ -438,9 +290,7 @@ describe('isAtomicBatchSupportedLoadableAtom and isAtomicBatchSupportedAtom', ()
438290
store.set(writableIsSafeViaWcAtom, false)
439291
store.set(writableIsSafeAppAtom, false)
440292
mockGetCapabilities.mockRejectedValue(new Error('network error'))
441-
setWalletInfo(store, {
442-
provider: createMockEip1193Provider(jest.fn().mockRejectedValue(new Error('legacy error'))),
443-
})
293+
setWalletInfo(store)
444294

445295
store.get(isAtomicBatchSupportedLoadableAtom)
446296
const asyncResult = await store.get(isAtomicBatchSupportedAsyncAtom)

0 commit comments

Comments
 (0)