Skip to content

Persist the browser demo account and storage across reloads - #526

Open
Dzejkop wants to merge 2 commits into
codex/walletkit-web-workerfrom
codex/persistent-browser-demo
Open

Dzejkop wants to merge 2 commits into
codex/walletkit-web-workerfrom
codex/persistent-browser-demo

Conversation

@Dzejkop

@Dzejkop Dzejkop commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Reopen the same staging demo account and encrypted OPFS databases after a page reload. Previously every load generated a new database key, storage namespace, and seed, leaving the previous databases inaccessible.

  • Save a versioned demo profile containing the storage ID, database key, seed, and completed registration/issuance steps before initializing WalletKit.
  • Restore that profile on reload and offer explicit authenticator initialization to reopen stored credentials. Proof generation stays disabled until initialization completes.
  • Reject malformed profiles without replacing their keys, and retain the active identity if saving a newly derived seed fails.
  • Document that this staging demo stores raw keys in localStorage. Passkey PRF unlock remains separate work; use one tab per origin.

Validation: production Next.js build and TypeScript checks pass; four persistence tests pass. A Chrome smoke check verified reload key/identity retention, re-derived identity retention, restored-progress button gating, and corrupt-profile rejection. No staging registration or issuance calls were made.

Stacked above #523. This PR changes only the demo.


Note

Low Risk
Demo-only localStorage persistence and example/docs updates; no production WalletKit or auth path changes.

Overview
The Next.js examples/web demo no longer throws away identity on every reload: it persists a versioned demo profile in localStorage (storageId, databaseKey, seed, and registration/issuance flags) and passes the saved storageId and key into initializeWalletKit() so encrypted OPFS SQLite can be reopened after refresh.

demo-profile.ts validates stored JSON (version, key shapes, progress consistency) and fails closed on corrupt or unsupported profiles instead of silently rotating keys. page.tsx restores UI gating from saved progress, updates the profile when registering, issuing, or deriving a new seed, and requires authenticator initialization before proof generation. Four bun test cases cover persistence and error paths; docs and root README point at examples/web and call out staging-only raw key retention.

The example package is renamed to walletkit-web-example; changes are limited to the demo and documentation.

Reviewed by Cursor Bugbot for commit bc85fd2. Bugbot is set up for automated code reviews on this repo. Configure here.

@Dzejkop
Dzejkop force-pushed the codex/persistent-browser-demo branch 2 times, most recently from deb1ee9 to e1cdf67 Compare September 9, 2026 15:47
@Dzejkop
Dzejkop added this pull request to stack #529 September 10, 2026 09:20
@Dzejkop
Dzejkop force-pushed the codex/persistent-browser-demo branch from e1cdf67 to 19a9a8c Compare September 10, 2026 09:33
@Dzejkop
Dzejkop force-pushed the codex/persistent-browser-demo branch from 19a9a8c to aa77e1e Compare September 10, 2026 09:39
@Dzejkop
Dzejkop marked this pull request as ready for review September 10, 2026 12:22
@Dzejkop
Dzejkop force-pushed the codex/persistent-browser-demo branch from aa77e1e to 6e36f51 Compare September 10, 2026 12:28

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6e36f51. Configure here.

@@ -79,6 +111,8 @@ export default function Home() {
if (status.state === "finalized") break;
await new Promise((resolve) => setTimeout(resolve, 500));
}
saved.registered = true;
saveDemoProfile(saved);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Failed save leaves profile flags inconsistent

Low Severity

register and issue set saved.registered / saved.credentialIssued on the live profile.current object before saveDemoProfile returns. A failed write leaves memory marked complete while React state and localStorage stay incomplete, so Derive stays enabled and can persist a new seed as already registered.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6e36f51. Configure here.

piohei
piohei previously approved these changes Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants