Context & Impact
The StellarWalletProvider.tsx restores wallet address and wallet ID from localStorage on every page load with no expiration check. If a user connected their wallet a week ago and the wallet's permissions have changed, or the Freighter session has expired, the app displays a stale "connected" state. Any transaction attempt will then fail with a confusing wallet error instead of prompting the user to reconnect.
Why this matters: Stale wallet sessions create a false sense of connection. Users see their address displayed and assume they're ready to transact, but the underlying wallet session may have expired. The first transaction attempt fails, and the error message doesn't indicate that reconnecting would fix it.
Scope
- Store a timestamp alongside the wallet address in localStorage
- Check the timestamp on restore — if older than a configurable TTL (e.g., 24 hours), clear the session
- Add a "session expired" state that prompts the user to reconnect
- Verify the wallet is actually accessible (ping
kit.getAddress()) on session restore
- Show a subtle UI indicator when the session was auto-restored vs. freshly connected
Implementation Guidelines
- Store
stellar_wallet_timestamp alongside existing stellar_wallet_address and stellar_wallet_id
- On restore, compare
Date.now() - savedTimestamp > TTL — if expired, clear all wallet data
- Default TTL: 24 hours (configurable via a constant)
- After restoring from localStorage, verify the wallet is still accessible with a lightweight check
- If verification fails, clear the session and show a "Please reconnect your wallet" prompt
- Update the timestamp on every successful transaction to keep active sessions alive
Acceptance Criteria
Getting Started
- Read
src/providers/StellarWalletProvider.tsx — focus on the localStorage restore logic (lines 71-90)
- Add
stellar_wallet_timestamp to the save/restore flow
- Create a
SESSION_TTL constant (default: 24 hours in milliseconds)
- Add timestamp check in the restore
useEffect
- Add a lightweight verification call after restore (
kit.getAddress() in a try-catch)
- If expired or verification fails, clear storage and set state to disconnected
- Test by manually setting an old timestamp in localStorage and refreshing
PR Submission Guide
This section applies to every PR for this issue. Follow it exactly.
Before You Start
While Working
Before Submitting the PR
PR Requirements
PRs without a screen recording or without a linked issue will not be reviewed. Failure to meet PR requirements may lead to PR rejection.
Context & Impact
The
StellarWalletProvider.tsxrestores wallet address and wallet ID from localStorage on every page load with no expiration check. If a user connected their wallet a week ago and the wallet's permissions have changed, or the Freighter session has expired, the app displays a stale "connected" state. Any transaction attempt will then fail with a confusing wallet error instead of prompting the user to reconnect.Why this matters: Stale wallet sessions create a false sense of connection. Users see their address displayed and assume they're ready to transact, but the underlying wallet session may have expired. The first transaction attempt fails, and the error message doesn't indicate that reconnecting would fix it.
Scope
kit.getAddress()) on session restoreImplementation Guidelines
stellar_wallet_timestampalongside existingstellar_wallet_addressandstellar_wallet_idDate.now() - savedTimestamp > TTL— if expired, clear all wallet dataAcceptance Criteria
Getting Started
src/providers/StellarWalletProvider.tsx— focus on the localStorage restore logic (lines 71-90)stellar_wallet_timestampto the save/restore flowSESSION_TTLconstant (default: 24 hours in milliseconds)useEffectkit.getAddress()in a try-catch)PR Submission Guide
Before You Start
mainbranch:git checkout main && git pull origin mainmain:git checkout -b feat/<issue-number>-wallet-session-expiryWhile Working
feat(scope): description,fix(scope): descriptiongit pull origin main --rebaseregularlyBefore Submitting the PR
mainand rebase:git checkout main && git pull origin main && git checkout <your-branch> && git rebase mainpnpm buildpnpm lintPR Requirements
Closes #<issue-number>PRs without a screen recording or without a linked issue will not be reviewed. Failure to meet PR requirements may lead to PR rejection.