Fix wallet reconnection state loss (Closes #136)#156
Open
giftexceed wants to merge 2 commits into
Open
Conversation
Users occasionally lost their session after reconnecting their wallet. Three root causes in the reconnection flow: - restoreWalletSession() erased the persisted wallet id on ANY refresh failure, so a transient RPC blip / extension-not-ready / locked-account error permanently dropped the saved session. It now keeps the session and surfaces a recoverable error instead. - The STATE_UPDATED handler honoured transient null-address updates the kit emits mid-reconnect, flipping the UI back to "disconnected". Only an explicit DISCONNECT event now tears a live session down. - StrictMode double-invoked the restore effect with no guard, letting two concurrent restores race. Concurrent calls now share one in-flight promise. Also: persist the resolved address so the connected UI is restored optimistically on reload; add an isReconnecting state with a "Reconnecting…" affordance; clear errors when starting a connect; and make disconnect always clear local state without throwing. Adds integration tests (wallet service + WalletConnectButton) covering successful reconnect, transient-failure persistence, transient-null guarding, disconnect teardown, and concurrent-restore coalescing.
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes intermittent loss of application/session state after a wallet reconnect. Investigation traced it to three issues in the dashboard's reconnection flow (
dashboard/src/services/wallet.ts+walletStore.ts):restoreWalletSession()cleared the persisted wallet id on anyfetchAddress()failure. A temporary RPC blip, a wallet extension still loading, or a locked account permanently deleted the user's saved wallet, so on the next load they appeared disconnected. The persisted session is now treated as the source of truth — a failed refresh surfaces a recoverable error but keeps the session.STATE_UPDATEDevents with no address mid-reconnect; honouring them flipped the UI back to "Connect Wallet". Only the dedicatedDISCONNECTevent now tears a session down.Additional improvements
isReconnectingstate with a "Reconnecting…" button affordance.disconnectWalletalways clears local state without throwing.Tests
Added integration tests (kit mocked via Jest
moduleNameMapper):src/services/wallet.test.tsx— successful reconnect, transient-failure keeps session, transient-null guard, disconnect teardown, concurrent-restore coalescing, no-op when no wallet saved.src/components/WalletConnectButton.test.tsx— restored-session UI + connected UI surviving a reconnection blip.import.meta.envwas isolated intosrc/config/stellarNetwork.ts(mapped to a test stub) so the existing Jest runner — which executes modules as CommonJS — keeps working without enabling native ESM (which breaks the jest-axe suites).Verification
jest: 31 passed (was 22; +9 new) ✅tsc --noEmit: clean ✅eslint --max-warnings=0: clean ✅vite build: succeeds ✅Acceptance criteria
Closes #136