diff --git a/packages/use-wallet/src/__tests__/wallets/pera.test.ts b/packages/use-wallet/src/__tests__/wallets/pera.test.ts index 75c56026..e6e1d6cf 100644 --- a/packages/use-wallet/src/__tests__/wallets/pera.test.ts +++ b/packages/use-wallet/src/__tests__/wallets/pera.test.ts @@ -451,6 +451,79 @@ describe('PeraWallet', () => { expect(store.state.wallets[WalletId.PERA]).toBeUndefined() expect(wallet.isConnected).toBe(false) }) + + describe('auto-connect in Pera browser', () => { + let mockUserAgent: string + + beforeEach(() => { + mockUserAgent = '' + vi.clearAllMocks() + + vi.stubGlobal('window', { + navigator: { + get userAgent() { + return mockUserAgent + } + } + }) + }) + + afterEach(() => { + vi.unstubAllGlobals() + }) + + it('should attempt auto-connect in Pera browser when no session exists and no active wallet', async () => { + mockUserAgent = 'pera/1.0.0' + mockPeraWallet.connect.mockResolvedValueOnce([account1.address]) + + await wallet.resumeSession() + + expect(mockPeraWallet.connect).toHaveBeenCalled() + expect(store.state.wallets[WalletId.PERA]).toBeDefined() + expect(mockLogger.info).toHaveBeenCalledWith('Auto-connect successful') + }) + + it('should not attempt auto-connect if another wallet is active', async () => { + mockUserAgent = 'pera/1.0.0' + + // Set up another active wallet + store.setState((state) => ({ + ...state, + activeWallet: WalletId.DEFLY, + wallets: { + [WalletId.DEFLY]: { + accounts: [account2], + activeAccount: account2 + } + } + })) + + await wallet.resumeSession() + + expect(mockPeraWallet.connect).not.toHaveBeenCalled() + expect(mockLogger.info).toHaveBeenCalledWith('No session to resume') + }) + + it('should not attempt auto-connect in other browsers', async () => { + mockUserAgent = 'chrome/1.0.0' + + await wallet.resumeSession() + + expect(mockPeraWallet.connect).not.toHaveBeenCalled() + expect(mockLogger.info).toHaveBeenCalledWith('No session to resume') + }) + + it('should handle auto-connect failure gracefully', async () => { + mockUserAgent = 'pera/1.0.0' + mockPeraWallet.connect.mockRejectedValueOnce(new Error('Connect failed')) + + await wallet.resumeSession() + + expect(mockPeraWallet.connect).toHaveBeenCalled() + expect(mockLogger.warn).toHaveBeenCalledWith('Auto-connect failed:', 'Connect failed') + expect(store.state.wallets[WalletId.PERA]).toBeUndefined() + }) + }) }) describe('setActive', () => { diff --git a/packages/use-wallet/src/__tests__/wallets/pera2.test.ts b/packages/use-wallet/src/__tests__/wallets/pera2.test.ts index 15cfff06..67a2a526 100644 --- a/packages/use-wallet/src/__tests__/wallets/pera2.test.ts +++ b/packages/use-wallet/src/__tests__/wallets/pera2.test.ts @@ -332,6 +332,79 @@ describe('PeraWallet', () => { expect(store.state.wallets[WalletId.PERA2]).toBeUndefined() expect(wallet.isConnected).toBe(false) }) + + describe('auto-connect in Pera browser', () => { + let mockUserAgent: string + + beforeEach(() => { + mockUserAgent = '' + vi.clearAllMocks() + + vi.stubGlobal('window', { + navigator: { + get userAgent() { + return mockUserAgent + } + } + }) + }) + + afterEach(() => { + vi.unstubAllGlobals() + }) + + it('should attempt auto-connect in Pera browser when no session exists and no active wallet', async () => { + mockUserAgent = 'pera/1.0.0' + mockPeraWallet.connect.mockResolvedValueOnce([account1.address]) + + await wallet.resumeSession() + + expect(mockPeraWallet.connect).toHaveBeenCalled() + expect(store.state.wallets[WalletId.PERA2]).toBeDefined() + expect(mockLogger.info).toHaveBeenCalledWith('Auto-connect successful') + }) + + it('should not attempt auto-connect if another wallet is active', async () => { + mockUserAgent = 'pera/1.0.0' + + // Set up another active wallet + store.setState((state) => ({ + ...state, + activeWallet: WalletId.DEFLY, + wallets: { + [WalletId.DEFLY]: { + accounts: [account2], + activeAccount: account2 + } + } + })) + + await wallet.resumeSession() + + expect(mockPeraWallet.connect).not.toHaveBeenCalled() + expect(mockLogger.info).toHaveBeenCalledWith('No session to resume') + }) + + it('should not attempt auto-connect in other browsers', async () => { + mockUserAgent = 'chrome/1.0.0' + + await wallet.resumeSession() + + expect(mockPeraWallet.connect).not.toHaveBeenCalled() + expect(mockLogger.info).toHaveBeenCalledWith('No session to resume') + }) + + it('should handle auto-connect failure gracefully', async () => { + mockUserAgent = 'pera/1.0.0' + mockPeraWallet.connect.mockRejectedValueOnce(new Error('Connect failed')) + + await wallet.resumeSession() + + expect(mockPeraWallet.connect).toHaveBeenCalled() + expect(mockLogger.warn).toHaveBeenCalledWith('Auto-connect failed:', 'Connect failed') + expect(store.state.wallets[WalletId.PERA2]).toBeUndefined() + }) + }) }) describe('signing transactions', () => { diff --git a/packages/use-wallet/src/wallets/pera.ts b/packages/use-wallet/src/wallets/pera.ts index f83f0fd2..b1322896 100644 --- a/packages/use-wallet/src/wallets/pera.ts +++ b/packages/use-wallet/src/wallets/pera.ts @@ -137,6 +137,21 @@ export class PeraWallet extends BaseWallet { const state = this.store.state const walletState = state.wallets[this.id] + // Check for Pera Discover browser and auto-connect if no other wallet is active + if (typeof window !== 'undefined' && window.navigator) { + const isPeraDiscover = window.navigator.userAgent.includes('pera') + if (isPeraDiscover && !walletState && !state.activeWallet) { + this.logger.info('Pera Discover browser detected, attempting auto-connect...') + try { + await this.connect() + this.logger.info('Auto-connect successful') + return + } catch (error: any) { + this.logger.warn('Auto-connect failed:', error.message) + } + } + } + // No session to resume if (!walletState) { this.logger.info('No session to resume') diff --git a/packages/use-wallet/src/wallets/pera2.ts b/packages/use-wallet/src/wallets/pera2.ts index a28335e0..9e7a94d3 100644 --- a/packages/use-wallet/src/wallets/pera2.ts +++ b/packages/use-wallet/src/wallets/pera2.ts @@ -119,6 +119,21 @@ export class PeraWallet extends BaseWallet { const state = this.store.state const walletState = state.wallets[this.id] + // Check for Pera Discover browser and auto-connect if no other wallet is active + if (typeof window !== 'undefined' && window.navigator) { + const isPeraDiscover = window.navigator.userAgent.includes('pera') + if (isPeraDiscover && !walletState && !state.activeWallet) { + this.logger.info('Pera Discover browser detected, attempting auto-connect...') + try { + await this.connect() + this.logger.info('Auto-connect successful') + return + } catch (error: any) { + this.logger.warn('Auto-connect failed:', error.message) + } + } + } + // No session to resume if (!walletState) { this.logger.info('No session to resume')