Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/controllers/src/utils/ConnectUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ export const ConnectUtil = {
*/
getWalletConnectWallets(wcAllWallets: WcWallet[], wcSearchWallets: WcWallet[]) {
if (wcSearchWallets.length > 0) {
return wcSearchWallets.map(w => this.mapWalletToWalletItem(w))
return WalletUtil.filterAndFlagWallets(wcSearchWallets).map(w =>
this.mapWalletToWalletItem(w)
)
}

return WalletUtil.getWalletConnectWallets(wcAllWallets).map(w => this.mapWalletToWalletItem(w))
Expand Down
11 changes: 8 additions & 3 deletions packages/controllers/src/utils/WalletUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ export const WalletUtil = {
return wallets.map((w, index) => ({ ...w, display_index: index }))
},

filterAndFlagWallets(wallets: WcWallet[]) {
const withInstalled = WalletUtil.markWalletsAsInstalled(wallets)
const filtered = WalletUtil.filterWalletsByWcSupport(withInstalled)

return WalletUtil.markWalletsWithDisplayIndex(filtered)
},

/**
* Filters wallets based on WalletConnect support and platform requirements.
*
Expand Down Expand Up @@ -218,9 +225,7 @@ export const WalletUtil = {
}

const uniqueWallets = CoreHelperUtil.uniqueBy(wallets, 'id')
const walletsWithInstalled = WalletUtil.markWalletsAsInstalled(uniqueWallets)
const walletsByWcSupport = WalletUtil.filterWalletsByWcSupport(walletsWithInstalled)

return WalletUtil.markWalletsWithDisplayIndex(walletsByWcSupport)
return WalletUtil.filterAndFlagWallets(uniqueWallets)
}
}
135 changes: 135 additions & 0 deletions packages/controllers/tests/utils/ConnectUtil.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'

import {
ConnectionController,
ConnectorController,
OptionsController
} from '../../exports/index.js'
import { AssetUtil } from '../../src/utils/AssetUtil.js'
import { ConnectUtil } from '../../src/utils/ConnectUtil.js'
import { CoreHelperUtil } from '../../src/utils/CoreHelperUtil.js'
import type { WcWallet } from '../../src/utils/TypeUtil.js'

// -- Helpers ------------------------------------------------------------------
function createMockWcWallet(overrides: Partial<WcWallet> = {}): WcWallet {
return {
id: 'wallet-id',
name: 'Test Wallet',
supports_wc: true,
mobile_link: 'testwalletapp://',
...overrides
}
}

// -- Tests --------------------------------------------------------------------
describe('ConnectUtil', () => {
describe('getWalletConnectWallets', () => {
beforeEach(() => {
vi.restoreAllMocks()
ConnectorController.state.connectors = []
OptionsController.state.featuredWalletIds = undefined
ConnectionController.state.wcBasic = false
vi.spyOn(AssetUtil, 'getWalletImageUrl').mockReturnValue('')
})

it('should filter out wallets without wc support from search results on mobile', () => {
vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(true)

const walletWithWc = createMockWcWallet({
id: 'wc-wallet',
name: 'WC Wallet',
supports_wc: true
})
const walletWithoutWc = createMockWcWallet({
id: 'no-wc-wallet',
name: 'No WC Wallet',
supports_wc: false,
mobile_link: 'noWcWalletapp://'
})

const result = ConnectUtil.getWalletConnectWallets([], [walletWithWc, walletWithoutWc])

expect(result.map(w => w.id)).toEqual(['wc-wallet'])
})

it('should include all search results on desktop when wcBasic is false', () => {
vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(false)
ConnectionController.state.wcBasic = false

const walletWithWc = createMockWcWallet({
id: 'wc-wallet',
name: 'WC Wallet',
supports_wc: true
})
const walletWithoutWc = createMockWcWallet({
id: 'no-wc-wallet',
name: 'No WC Wallet',
supports_wc: false
})

const result = ConnectUtil.getWalletConnectWallets([], [walletWithWc, walletWithoutWc])

expect(result.map(w => w.id)).toEqual(['wc-wallet', 'no-wc-wallet'])
})

it('should filter out wallets without wc support on desktop when wcBasic is true', () => {
vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(false)
ConnectionController.state.wcBasic = true

const walletWithWc = createMockWcWallet({
id: 'wc-wallet',
name: 'WC Wallet',
supports_wc: true
})
const walletWithoutWc = createMockWcWallet({
id: 'no-wc-wallet',
name: 'No WC Wallet',
supports_wc: false
})

const result = ConnectUtil.getWalletConnectWallets([], [walletWithWc, walletWithoutWc])

expect(result.map(w => w.id)).toEqual(['wc-wallet'])
})

it('should preserve order of search results when no installed or featured wallets', () => {
vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(false)

const wallets = [
createMockWcWallet({ id: 'wallet-0', name: 'Wallet 0' }),
createMockWcWallet({ id: 'wallet-1', name: 'Wallet 1' }),
createMockWcWallet({ id: 'wallet-2', name: 'Wallet 2' })
]

const result = ConnectUtil.getWalletConnectWallets([], wallets)

expect(result).toHaveLength(3)
expect(result[0]?.id).toBe('wallet-0')
expect(result[1]?.id).toBe('wallet-1')
expect(result[2]?.id).toBe('wallet-2')
})

it('should sort installed wallets first in search results', () => {
vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(false)
ConnectorController.state.connectors = [
{
id: 'wallet-2-connector',
name: 'Wallet 2',
type: 'ANNOUNCED',
chain: 'eip155',
info: { rdns: 'com.wallet2' }
}
] as any

const wallets = [
createMockWcWallet({ id: 'wallet-0', name: 'Wallet 0' }),
createMockWcWallet({ id: 'wallet-1', name: 'Wallet 1' }),
createMockWcWallet({ id: 'wallet-2', name: 'Wallet 2', rdns: 'com.wallet2' })
]

const result = ConnectUtil.getWalletConnectWallets([], wallets)

expect(result[0]?.id).toBe('wallet-2')
})
})
})
75 changes: 75 additions & 0 deletions packages/controllers/tests/utils/WalletUtil.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'

import {
ConnectionController,
ConnectorController,
OptionsController
} from '../../exports/index.js'
import { CoreHelperUtil } from '../../src/utils/CoreHelperUtil.js'
import type { WcWallet } from '../../src/utils/TypeUtil.js'
import { WalletUtil } from '../../src/utils/WalletUtil.js'

// -- Helpers ------------------------------------------------------------------
function createMockWcWallet(overrides: Partial<WcWallet> = {}): WcWallet {
return {
id: 'wallet-id',
name: 'Test Wallet',
supports_wc: true,
mobile_link: 'testwalletapp://',
...overrides
}
}

// -- Tests --------------------------------------------------------------------
describe('WalletUtil', () => {
describe('filterAndFlagWallets', () => {
beforeEach(() => {
vi.restoreAllMocks()
ConnectorController.state.connectors = []
OptionsController.state.featuredWalletIds = undefined
ConnectionController.state.wcBasic = false
})

it('should filter out wallets without wc support on mobile', () => {
vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(true)

const wallets = [
createMockWcWallet({ id: 'wc-wallet', supports_wc: true }),
createMockWcWallet({ id: 'no-wc-wallet', supports_wc: false })
]

const result = WalletUtil.filterAndFlagWallets(wallets)

expect(result.map(w => w.id)).toEqual(['wc-wallet'])
})

it('should pass through all wallets on desktop', () => {
Copy link
Copy Markdown
Contributor

@enesozturk enesozturk Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On desktop let's filter out the wallets which webapp_link is not valid? When they don't support WC and no webapp_link don't make sense to render them at all

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm but on desktop we can have injected wallets on those spots, and clicking on them should trigger those no?

vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(false)

const wallets = [
createMockWcWallet({ id: 'wc-wallet', supports_wc: true }),
createMockWcWallet({ id: 'no-wc-wallet', supports_wc: false })
]

const result = WalletUtil.filterAndFlagWallets(wallets)

expect(result.map(w => w.id)).toEqual(['wc-wallet', 'no-wc-wallet'])
})

it('should assign display_index to each wallet', () => {
vi.spyOn(CoreHelperUtil, 'isMobile').mockReturnValue(false)

const wallets = [
createMockWcWallet({ id: 'wallet-0' }),
createMockWcWallet({ id: 'wallet-1' }),
createMockWcWallet({ id: 'wallet-2' })
]

const result = WalletUtil.filterAndFlagWallets(wallets)

expect(result[0]?.display_index).toBe(0)
expect(result[1]?.display_index).toBe(1)
expect(result[2]?.display_index).toBe(2)
})
})
})
Loading