Skip to content

### [FRONTEND-11] Implement Persistent Wallet Session with useLocalStorage and Auto-Reconnect #438

Description

@orunganiekan

Points: 200
Labels: frontend, hooks, ux, freighter, session
Background: useWallet.ts stores publicKey in component state — it is lost on every page refresh. Every session requires the user to click "Connect Wallet" again and wait for Freighter to respond. useLocalStorage.ts already exists but is not used by useWallet. The useFreighterAvailable hook confirms Freighter is present, and Freighter's isConnected() can silently verify a persisted session. On reconnect, if the stored public key no longer matches the connected Freighter account (user switched accounts), the stale key must be cleared rather than used silently — this is a security concern since all contract reads and transaction builds use the public key as the sourcePublicKey.

Task: Update useWallet.ts to persist publicKey via useLocalStorage('wallet_public_key', null). On mount, if a stored key exists: call freighterService.isConnected() and freighterService.getPublicKey() silently — if the returned key matches the stored key, auto-restore the session without a user prompt. If the keys differ (account switch), clear storage and set publicKey = null. Expose sessionRestored: boolean in the return value so App.tsx can skip rendering the ConnectWallet screen during the auto-restore check. Add a connecting state that covers both manual connect and auto-restore.

Key files: - frontend/src/hooks/useWallet.ts — integrate useLocalStorage; add auto-reconnect logic; expose sessionRestored

  • frontend/src/hooks/useLocalStorage.ts — verify it handles null serialization correctly (currently may not — audit)
  • frontend/src/App.tsx — consume sessionRestored to show a loading state instead of ConnectWallet during restore
  • frontend/src/__tests__/useFreighterAvailable.test.tsx — add test: stored key matching Freighter key restores session; mismatched key clears storage

Acceptance criteria: - [ ] publicKey persisted to localStorage under key 'wallet_public_key'

  • On mount with a stored key, auto-reconnect attempt is made silently (no user prompt)
  • Mismatched key (user switched Freighter account externally) clears storage and sets publicKey = null
  • sessionRestored: boolean is false during check, true after check completes (regardless of outcome)
  • App.tsx renders a loading indicator instead of ConnectWallet while !sessionRestored
  • Test: stored key matches → publicKey restored; stored key mismatches → publicKey null
  • npm run typecheck passes

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions