From 05f2684d17166d3f721de8b487926e14a366daba Mon Sep 17 00:00:00 2001 From: Wonhee Lee <2wheeh@gmail.com> Date: Mon, 22 Dec 2025 17:10:23 +0900 Subject: [PATCH 1/3] fix: set currentWalletName, currentChainName correctly --- .../__tests__/chain-wallet-store.test.ts | 48 +++++++++++++++++++ .../src/wallet-manager/chain-wallet-store.ts | 4 ++ 2 files changed, 52 insertions(+) diff --git a/packages/store/__tests__/chain-wallet-store.test.ts b/packages/store/__tests__/chain-wallet-store.test.ts index c506a5a6d..8e08178f1 100644 --- a/packages/store/__tests__/chain-wallet-store.test.ts +++ b/packages/store/__tests__/chain-wallet-store.test.ts @@ -208,6 +208,33 @@ describe('ChainWalletStore', () => { ); }); + it('should set currentWalletName and currentChainName on successful connect', async () => { + const mockAccount: WalletAccount = { + address: 'cosmos1abc123', + pubkey: new Uint8Array([1, 2, 3]), + isNanoLedger: false, + algo: 'secp256k1' as Algo, + }; + + (mockWallet.connect as jest.Mock).mockResolvedValue(undefined); + (mockWallet.getAccount as jest.Mock).mockResolvedValue(mockAccount); + + await chainWalletStore.connect(); + + expect(mockInterchainStore.setCurrentWalletName).toHaveBeenCalledWith('keplr'); + expect(mockInterchainStore.setCurrentChainName).toHaveBeenCalledWith('cosmoshub'); + }); + + it('should not set current values on connection error', async () => { + const error = new Error('Connection failed'); + (mockWallet.connect as jest.Mock).mockRejectedValue(error); + + await chainWalletStore.connect(); + + expect(mockInterchainStore.setCurrentWalletName).not.toHaveBeenCalled(); + expect(mockInterchainStore.setCurrentChainName).not.toHaveBeenCalled(); + }); + it('should handle connection errors', async () => { const error = new Error('Connection failed'); (mockWallet.connect as jest.Mock).mockRejectedValue(error); @@ -264,6 +291,27 @@ describe('ChainWalletStore', () => { ); }); + it('should reset currentWalletName and currentChainName on successful disconnect', async () => { + (mockWallet.disconnect as jest.Mock).mockResolvedValue(undefined); + + await chainWalletStore.disconnect(); + + expect(mockInterchainStore.setCurrentWalletName).toHaveBeenCalledWith(''); + expect(mockInterchainStore.setCurrentChainName).toHaveBeenCalledWith(''); + }); + + it('should not reset current values on disconnection error', async () => { + const consoleSpy = jest.spyOn(console, 'error').mockImplementation(); + const error = new Error('Disconnection failed'); + (mockWallet.disconnect as jest.Mock).mockRejectedValue(error); + + await chainWalletStore.disconnect(); + + expect(mockInterchainStore.setCurrentWalletName).not.toHaveBeenCalled(); + expect(mockInterchainStore.setCurrentChainName).not.toHaveBeenCalled(); + consoleSpy.mockRestore(); + }); + it('should handle disconnection errors', async () => { const consoleSpy = jest.spyOn(console, 'error').mockImplementation(); const error = new Error('Disconnection failed'); diff --git a/packages/store/src/wallet-manager/chain-wallet-store.ts b/packages/store/src/wallet-manager/chain-wallet-store.ts index a41bd06c1..16aac7f67 100644 --- a/packages/store/src/wallet-manager/chain-wallet-store.ts +++ b/packages/store/src/wallet-manager/chain-wallet-store.ts @@ -56,6 +56,8 @@ export class ChainWalletStore extends BaseWallet { await this.wallet.connect(this.chain.chainId); const account = await this.getAccount(); this.store.updateChainWalletState(this.wallet.info.name, this.chain.chainName, { walletState: WalletState.Connected, account }); + this.store.setCurrentWalletName(this.wallet.info.name); + this.store.setCurrentChainName(this.chain.chainName); } catch (error) { this.store.updateChainWalletState(this.wallet.info.name, this.chain.chainName, { walletState: WalletState.Disconnected, errorMessage: (error as any).message }); } @@ -71,6 +73,8 @@ export class ChainWalletStore extends BaseWallet { try { await this.wallet.disconnect(this.chain.chainId); this.store.updateChainWalletState(this.wallet.info.name, this.chain.chainName, { walletState: WalletState.Disconnected, account: undefined, errorMessage: '' }); + this.store.setCurrentWalletName(''); + this.store.setCurrentChainName(''); } catch (error) { console.error(error); } From 0a4e41e3e0329ed241102e03c2e049b287c3d2d9 Mon Sep 17 00:00:00 2001 From: Wonhee Lee <2wheeh@gmail.com> Date: Mon, 22 Dec 2025 17:36:41 +0900 Subject: [PATCH 2/3] refactor: encapsulate current wallet/chain state sync in InterchainStore --- .../__tests__/chain-wallet-store.test.ts | 48 ------------------- packages/store/src/store/index.ts | 15 ++++++ .../src/wallet-manager/chain-wallet-store.ts | 4 -- 3 files changed, 15 insertions(+), 52 deletions(-) diff --git a/packages/store/__tests__/chain-wallet-store.test.ts b/packages/store/__tests__/chain-wallet-store.test.ts index 8e08178f1..c506a5a6d 100644 --- a/packages/store/__tests__/chain-wallet-store.test.ts +++ b/packages/store/__tests__/chain-wallet-store.test.ts @@ -208,33 +208,6 @@ describe('ChainWalletStore', () => { ); }); - it('should set currentWalletName and currentChainName on successful connect', async () => { - const mockAccount: WalletAccount = { - address: 'cosmos1abc123', - pubkey: new Uint8Array([1, 2, 3]), - isNanoLedger: false, - algo: 'secp256k1' as Algo, - }; - - (mockWallet.connect as jest.Mock).mockResolvedValue(undefined); - (mockWallet.getAccount as jest.Mock).mockResolvedValue(mockAccount); - - await chainWalletStore.connect(); - - expect(mockInterchainStore.setCurrentWalletName).toHaveBeenCalledWith('keplr'); - expect(mockInterchainStore.setCurrentChainName).toHaveBeenCalledWith('cosmoshub'); - }); - - it('should not set current values on connection error', async () => { - const error = new Error('Connection failed'); - (mockWallet.connect as jest.Mock).mockRejectedValue(error); - - await chainWalletStore.connect(); - - expect(mockInterchainStore.setCurrentWalletName).not.toHaveBeenCalled(); - expect(mockInterchainStore.setCurrentChainName).not.toHaveBeenCalled(); - }); - it('should handle connection errors', async () => { const error = new Error('Connection failed'); (mockWallet.connect as jest.Mock).mockRejectedValue(error); @@ -291,27 +264,6 @@ describe('ChainWalletStore', () => { ); }); - it('should reset currentWalletName and currentChainName on successful disconnect', async () => { - (mockWallet.disconnect as jest.Mock).mockResolvedValue(undefined); - - await chainWalletStore.disconnect(); - - expect(mockInterchainStore.setCurrentWalletName).toHaveBeenCalledWith(''); - expect(mockInterchainStore.setCurrentChainName).toHaveBeenCalledWith(''); - }); - - it('should not reset current values on disconnection error', async () => { - const consoleSpy = jest.spyOn(console, 'error').mockImplementation(); - const error = new Error('Disconnection failed'); - (mockWallet.disconnect as jest.Mock).mockRejectedValue(error); - - await chainWalletStore.disconnect(); - - expect(mockInterchainStore.setCurrentWalletName).not.toHaveBeenCalled(); - expect(mockInterchainStore.setCurrentChainName).not.toHaveBeenCalled(); - consoleSpy.mockRestore(); - }); - it('should handle disconnection errors', async () => { const consoleSpy = jest.spyOn(console, 'error').mockImplementation(); const error = new Error('Disconnection failed'); diff --git a/packages/store/src/store/index.ts b/packages/store/src/store/index.ts index 14ede0c3a..192e5b35f 100644 --- a/packages/store/src/store/index.ts +++ b/packages/store/src/store/index.ts @@ -78,6 +78,21 @@ export class InterchainStore { } else { this.addChainWalletState(walletName, chainName, state); } + + switch (state.walletState) { + case WalletState.Connected: + this.setCurrentWalletName(walletName); + this.setCurrentChainName(chainName); + break; + case WalletState.Disconnected: + if (this.state.currentWalletName === walletName && this.state.currentChainName === chainName) { + // TODO: for supporting multiple wallet connections, + // we should set these to the previous instead of clearing + this.setCurrentWalletName(''); + this.setCurrentChainName(''); + } + break; + } } // 添加新的 chain wallet state diff --git a/packages/store/src/wallet-manager/chain-wallet-store.ts b/packages/store/src/wallet-manager/chain-wallet-store.ts index 16aac7f67..a41bd06c1 100644 --- a/packages/store/src/wallet-manager/chain-wallet-store.ts +++ b/packages/store/src/wallet-manager/chain-wallet-store.ts @@ -56,8 +56,6 @@ export class ChainWalletStore extends BaseWallet { await this.wallet.connect(this.chain.chainId); const account = await this.getAccount(); this.store.updateChainWalletState(this.wallet.info.name, this.chain.chainName, { walletState: WalletState.Connected, account }); - this.store.setCurrentWalletName(this.wallet.info.name); - this.store.setCurrentChainName(this.chain.chainName); } catch (error) { this.store.updateChainWalletState(this.wallet.info.name, this.chain.chainName, { walletState: WalletState.Disconnected, errorMessage: (error as any).message }); } @@ -73,8 +71,6 @@ export class ChainWalletStore extends BaseWallet { try { await this.wallet.disconnect(this.chain.chainId); this.store.updateChainWalletState(this.wallet.info.name, this.chain.chainName, { walletState: WalletState.Disconnected, account: undefined, errorMessage: '' }); - this.store.setCurrentWalletName(''); - this.store.setCurrentChainName(''); } catch (error) { console.error(error); } From 44ebea9b42da3aa8a3da6f0a6457eeb1b9593a0e Mon Sep 17 00:00:00 2001 From: Wonhee Lee <2wheeh@gmail.com> Date: Mon, 22 Dec 2025 17:46:28 +0900 Subject: [PATCH 3/3] test: for wallet/chain state sync --- .../store/__tests__/interchain-store.test.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/store/__tests__/interchain-store.test.ts b/packages/store/__tests__/interchain-store.test.ts index f7d88b871..7c9ed642c 100644 --- a/packages/store/__tests__/interchain-store.test.ts +++ b/packages/store/__tests__/interchain-store.test.ts @@ -238,4 +238,30 @@ describe('InterchainStore', () => { expect(osmosisKeplr).toBeUndefined(); }); }); + + describe('Current Wallet/Chain Auto-Sync', () => { + it('should set currentWalletName and currentChainName when connected', () => { + store.updateChainWalletState('keplr', 'cosmoshub', { + walletState: WalletState.Connected, + }); + + const state = store.getState(); + expect(state.currentWalletName).toBe('keplr'); + expect(state.currentChainName).toBe('cosmoshub'); + }); + + it('should clear current when disconnecting the current wallet/chain', () => { + store.updateChainWalletState('keplr', 'cosmoshub', { + walletState: WalletState.Connected, + }); + + store.updateChainWalletState('keplr', 'cosmoshub', { + walletState: WalletState.Disconnected, + }); + + const state = store.getState(); + expect(state.currentWalletName).toBe(''); + expect(state.currentChainName).toBe(''); + }); + }); });