From ffd6141170e25d874c3c90aff2b56d07ab791955 Mon Sep 17 00:00:00 2001 From: Doug Richar Date: Wed, 18 Dec 2024 14:44:19 -0500 Subject: [PATCH] fix(wallets): prevent WalletConnect v1 session data collision Skip `reconnectSession` for inactive Pera/Defly wallets since wallet state is already managed by use-wallet. This prevents a bug where both wallets share the same WalletConnect v1 storage key, causing the inactive wallet to overwrite the active wallet's connected accounts on session resume. --- .../src/__tests__/wallets/defly.test.ts | 23 +++++++++++++++++++ .../src/__tests__/wallets/pera.test.ts | 23 +++++++++++++++++++ packages/use-wallet/src/wallets/defly.ts | 6 +++++ packages/use-wallet/src/wallets/pera.ts | 6 +++++ 4 files changed, 58 insertions(+) diff --git a/packages/use-wallet/src/__tests__/wallets/defly.test.ts b/packages/use-wallet/src/__tests__/wallets/defly.test.ts index c8f4cc64..3b4ea183 100644 --- a/packages/use-wallet/src/__tests__/wallets/defly.test.ts +++ b/packages/use-wallet/src/__tests__/wallets/defly.test.ts @@ -449,6 +449,29 @@ describe('DeflyWallet', () => { expect(store.state.wallets[WalletId.DEFLY]).toBeUndefined() expect(wallet.isConnected).toBe(false) }) + + it('should skip reconnectSession if Pera is active', async () => { + const walletState: WalletState = { + accounts: [account1], + activeAccount: account1 + } + + store = new Store({ + ...defaultState, + activeWallet: WalletId.PERA, + wallets: { + [WalletId.DEFLY]: walletState + } + }) + + wallet = createWalletWithStore(store) + + await wallet.resumeSession() + + expect(mockLogger.info).toHaveBeenCalledWith('Skipping reconnectSession for Defly (inactive)') + expect(mockDeflyWallet.reconnectSession).not.toHaveBeenCalled() + expect(store.state.wallets[WalletId.DEFLY]).toEqual(walletState) + }) }) describe('setActive', () => { diff --git a/packages/use-wallet/src/__tests__/wallets/pera.test.ts b/packages/use-wallet/src/__tests__/wallets/pera.test.ts index d5b290aa..3e0d05bd 100644 --- a/packages/use-wallet/src/__tests__/wallets/pera.test.ts +++ b/packages/use-wallet/src/__tests__/wallets/pera.test.ts @@ -449,6 +449,29 @@ describe('PeraWallet', () => { expect(store.state.wallets[WalletId.PERA]).toBeUndefined() expect(wallet.isConnected).toBe(false) }) + + it('should skip reconnectSession if Defly is active', async () => { + const walletState: WalletState = { + accounts: [account1], + activeAccount: account1 + } + + store = new Store({ + ...defaultState, + activeWallet: WalletId.DEFLY, + wallets: { + [WalletId.PERA]: walletState + } + }) + + wallet = createWalletWithStore(store) + + await wallet.resumeSession() + + expect(mockLogger.info).toHaveBeenCalledWith('Skipping reconnectSession for Pera (inactive)') + expect(mockPeraWallet.reconnectSession).not.toHaveBeenCalled() + expect(store.state.wallets[WalletId.PERA]).toEqual(walletState) + }) }) describe('setActive', () => { diff --git a/packages/use-wallet/src/wallets/defly.ts b/packages/use-wallet/src/wallets/defly.ts index 2128284f..230614df 100644 --- a/packages/use-wallet/src/wallets/defly.ts +++ b/packages/use-wallet/src/wallets/defly.ts @@ -137,6 +137,12 @@ export class DeflyWallet extends BaseWallet { return } + // If Pera is active, skip reconnectSession for Defly + if (state.activeWallet === WalletId.PERA) { + this.logger.info('Skipping reconnectSession for Defly (inactive)') + return + } + this.logger.info('Resuming session...') const client = this.client || (await this.initializeClient()) diff --git a/packages/use-wallet/src/wallets/pera.ts b/packages/use-wallet/src/wallets/pera.ts index 8a35bac6..0113be63 100644 --- a/packages/use-wallet/src/wallets/pera.ts +++ b/packages/use-wallet/src/wallets/pera.ts @@ -142,6 +142,12 @@ export class PeraWallet extends BaseWallet { return } + // If Defly is active, skip reconnectSession for Pera + if (state.activeWallet === WalletId.DEFLY) { + this.logger.info('Skipping reconnectSession for Pera (inactive)') + return + } + this.logger.info('Resuming session...') const client = this.client || (await this.initializeClient())