Skip to content

Commit

Permalink
refactor: filter out the duplicate wallets when there is both injecte…
Browse files Browse the repository at this point in the history
…d and recent (#3446)
  • Loading branch information
enesozturk authored Dec 12, 2024
1 parent fc0de2c commit c1a641f
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 5 deletions.
23 changes: 23 additions & 0 deletions .changeset/warm-ligers-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@reown/appkit-scaffold-ui': patch
'@apps/builder': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit': patch
'@reown/appkit-utils': patch
'@reown/appkit-cdn': patch
'@reown/appkit-cli': patch
'@reown/appkit-common': patch
'@reown/appkit-core': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
'@reown/appkit-wallet-button': patch
---

Filter out when there is duplicate wallet items in recents and injected wallets
Original file line number Diff line number Diff line change
@@ -1,28 +1,47 @@
import type { WcWallet } from '@reown/appkit-core'
import { AssetUtil, RouterController, StorageUtil } from '@reown/appkit-core'
import { AssetUtil, ConnectorController, RouterController, StorageUtil } from '@reown/appkit-core'
import { customElement } from '@reown/appkit-ui'
import { LitElement, html } from 'lit'
import { property } from 'lit/decorators.js'
import { property, state } from 'lit/decorators.js'
import { ifDefined } from 'lit/directives/if-defined.js'

@customElement('w3m-connect-recent-widget')
export class W3mConnectRecentWidget extends LitElement {
// -- Members ------------------------------------------- //
private unsubscribe: (() => void)[] = []

// -- State & Properties -------------------------------- //
@property() public tabIdx?: number = undefined

@state() private connectors = ConnectorController.state.connectors

// -- Lifecycle ----------------------------------------- //
public constructor() {
super()
this.unsubscribe.push(
ConnectorController.subscribeKey('connectors', val => (this.connectors = val))
)
}

// -- Render -------------------------------------------- //
public override render() {
const recent = StorageUtil.getRecentWallets()
const recentWallets = StorageUtil.getRecentWallets()
const filteredRecentWallets = recentWallets.filter(
wallet =>
!this.connectors.some(
connector => connector.id === wallet.id || connector.name === wallet.name
)
)

if (!recent?.length) {
if (!filteredRecentWallets.length) {
this.style.cssText = `display: none`

return null
}

return html`
<wui-flex flexDirection="column" gap="xs">
${recent.map(
${filteredRecentWallets.map(
wallet => html`
<wui-list-wallet
imageSrc=${ifDefined(AssetUtil.getWalletImage(wallet))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export class W3mConnectingWcView extends LitElement {
if (wcLinking) {
StorageUtil.setWalletConnectDeepLink(wcLinking)
}

if (recentWallet) {
StorageUtil.setAppKitRecent(recentWallet)
}
Expand Down
120 changes: 120 additions & 0 deletions packages/scaffold-ui/test/partials/w3m-connect-recent-widget.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { W3mConnectRecentWidget } from '../../src/partials/w3m-connect-recent-widget'
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { fixture } from '@open-wc/testing'
import { html } from 'lit'
import { ConnectorController, RouterController, StorageUtil } from '@reown/appkit-core'

describe('W3mConnectRecentWidget', () => {
const mockRecentWallets = [
{ id: 'recent1', name: 'Recent Wallet 1' },
{ id: 'recent2', name: 'Recent Wallet 2' }
]

const mockConnectors = [
{ id: 'connector1', name: 'Connector 1' },
{ id: 'recent1', name: 'Recent Wallet 1' } // Matching wallet
]

let subscribeCallback: (connectors: any) => void

beforeEach(() => {
subscribeCallback = vi.fn()

vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue(mockRecentWallets)

vi.spyOn(ConnectorController, 'state', 'get').mockReturnValue({
connectors: mockConnectors
} as any)

vi.spyOn(ConnectorController, 'subscribeKey').mockImplementation((_, callback) => {
subscribeCallback = callback
return () => undefined
})
})

afterEach(() => {
vi.clearAllMocks()
})

it('should render filtered recent wallets when there are matching connectors', async () => {
const element: W3mConnectRecentWidget = await fixture(
html`<w3m-connect-recent-widget></w3m-connect-recent-widget>`
)

const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet')
expect(walletElements?.length).toBe(1)

const walletName = walletElements?.[0]?.getAttribute('name')
expect(walletName).toBe('Recent Wallet 2')
})

it('should render all recent wallets when there are no matching connectors', async () => {
vi.spyOn(ConnectorController, 'state', 'get').mockReturnValue({
connectors: [{ id: 'connector1', name: 'Connector 1' }]
} as any)

const element: W3mConnectRecentWidget = await fixture(
html`<w3m-connect-recent-widget></w3m-connect-recent-widget>`
)

const walletElements = element.shadowRoot?.querySelectorAll('wui-list-wallet')
expect(walletElements?.length).toBe(2)

const walletNames = Array.from(walletElements || []).map(el => el.getAttribute('name'))
expect(walletNames).toContain('Recent Wallet 1')
expect(walletNames).toContain('Recent Wallet 2')
})

it('should not render widget when there are no recent wallets', async () => {
vi.spyOn(StorageUtil, 'getRecentWallets').mockReturnValue([])

const element: W3mConnectRecentWidget = await fixture(
html`<w3m-connect-recent-widget></w3m-connect-recent-widget>`
)

expect(element.style.display).toBe('none')
expect(element.shadowRoot?.querySelector('wui-flex')).toBeNull()
})

it('should handle wallet click and navigate to connecting view', async () => {
const routerSpy = vi.spyOn(RouterController, 'push')

const element: W3mConnectRecentWidget = await fixture(
html`<w3m-connect-recent-widget></w3m-connect-recent-widget>`
)

const walletElement = element.shadowRoot?.querySelector('wui-list-wallet')
walletElement?.click()

expect(routerSpy).toHaveBeenCalledWith('ConnectingWalletConnect', {
wallet: mockRecentWallets[1]
})
})

it('should respect tabIdx property', async () => {
const element: W3mConnectRecentWidget = await fixture(
html`<w3m-connect-recent-widget .tabIdx=${2}></w3m-connect-recent-widget>`
)

const walletElement = element.shadowRoot?.querySelector('wui-list-wallet')
expect(walletElement?.getAttribute('tabIdx')).toBe('2')
})

it('should update when connectors change', async () => {
const element: W3mConnectRecentWidget = await fixture(
html`<w3m-connect-recent-widget></w3m-connect-recent-widget>`
)

expect(element.shadowRoot?.querySelectorAll('wui-list-wallet').length).toBe(1)

vi.spyOn(ConnectorController, 'state', 'get').mockReturnValue({
connectors: [{ id: 'connector1', name: 'Connector 1' }]
} as any)

subscribeCallback([{ id: 'connector1', name: 'Connector 1' }])

await element.updateComplete

expect(element.shadowRoot?.querySelectorAll('wui-list-wallet').length).toBe(2)
})
})

0 comments on commit c1a641f

Please sign in to comment.