feat(web-client): opt-in passkey-based keystore#27
Open
WiktorStarczewski wants to merge 9 commits into
Open
Conversation
…NFLICTS) Migrated from 0xMiden/miden-client#1835 (author: WiktorStarczewski) as part of the web-sdk split. Original PR: 0xMiden/miden-client#1835 This commit contains 3-way merge conflict markers in: - crates/web-client/js/client.js - crates/web-client/js/index.js - crates/web-client/rollup.config.js The miden-client PR was opened against an older miden-client next, and web-sdk's next has drifted (e.g. via the PR #13 sync from miden-client next). The conflicts must be resolved manually before merge.
6 tasks
Resolves the committed <<<<<<<< / >>>>>>> conflict markers in:
- crates/web-client/js/client.js — keep both passkey resolution
(theirs) and rpcUrl/noteTransportUrl
extraction (ours), with passkey
resolution running first so it can
modify options.keystore before the
downstream branch reads it.
- crates/web-client/js/index.js — keep both export blocks.
- crates/web-client/rollup.config.js — keep new passkey-keystore build
block (theirs), then keep the
verbose classic-worker comment
(ours), drop the terse 'Build the
worker file' placeholder.
Note: this PR's CI will still be red — miden-client#1835 is built against
miden-protocol = '=0.14.0-alpha.1', which is too old to resolve against
web-sdk's current sources (23 compile errors when retargeting deps to
that branch). The original PR needs to be rebased onto current miden-client
next before this can be made green.
Now that miden-client#1835's wiktor-storekeys branch has been merged with miden-client@dab6cf7b (the same snapshot of next that web-sdk currently pins), the dep retarget that #23/#25/#26/#31 use works for this PR too. Local 'cargo check --workspace --target wasm32-unknown-unknown' is clean (was 23 errors before the upstream merge, due to the alpha-protocol mismatch the PR description mentions). Revert before merge — see PR description merge gate.
The new `passkey-keystore.js` module depends on browser-only WebAuthn PRF APIs (navigator.credentials, AuthenticatorAttachment, etc.) that aren't available in the node-test environment. Including it in the vitest coverage scope drops overall coverage to ~74%, well below the 95% threshold (the file is 610 lines, none reachable from node). It IS covered by Playwright integration tests (crates/web-client/test/passkey-keystore.test.ts), so excluding it from vitest follows the same pattern as `js/wasm.js`, `js/eager.js`, `js/index.js`, etc. — sources that depend on platform features the node test runner can't provide. Note: this PR didn't have vitest.config.js on its branch (the file was added on next after this PR was opened). Seeded with next's content verbatim plus the new exclusion.
…erage scope" This reverts commit b315863.
WiktorStarczewski
added a commit
that referenced
this pull request
Apr 30, 2026
Observed flake: probe returns HTTP 200 once on the first attempt that clears the connection-refused phase, exits, tests start, ALL tests fail with 'TypeError: Failed to fetch' to the gRPC backend. The single-probe gate isn't strict enough — a one-shot 200 (e.g. tonic-health responding before the rest of the dispatcher is fully wired) currently passes. Upgrade the readiness signal to N consecutive HTTP successes spaced PROBE_INTERVAL apart (defaults: 3 successes, 0.5s apart), so the probe only declares the server ready after ~1s of demonstrably-stable response. Any non-success in the streak resets it to zero and the slow-poll loop resumes — so a momentary blip during init doesn't get counted twice on either side. Tracked occurrences across recent PR runs: web-sdk PR #23 ci-shard-4, PR #29 ci-shard-1 + ci-shard-4, PR #27 multiple shards.
WiktorStarczewski
added a commit
that referenced
this pull request
Apr 30, 2026
Observed flake: probe returns HTTP 200 once on the first attempt that clears the connection-refused phase, exits, tests start, ALL tests fail with 'TypeError: Failed to fetch' to the gRPC backend. The single-probe gate isn't strict enough — a one-shot 200 (e.g. tonic-health responding before the rest of the dispatcher is fully wired) currently passes. Upgrade the readiness signal to N consecutive HTTP successes spaced PROBE_INTERVAL apart (defaults: 3 successes, 0.5s apart), so the probe only declares the server ready after ~1s of demonstrably-stable response. Any non-success in the streak resets it to zero and the slow-poll loop resumes — so a momentary blip during init doesn't get counted twice on either side. Tracked occurrences across recent PR runs: web-sdk PR #23 ci-shard-4, PR #29 ci-shard-1 + ci-shard-4, PR #27 multiple shards.
This was referenced Apr 30, 2026
WiktorStarczewski
added a commit
that referenced
this pull request
Apr 30, 2026
Observed flake: probe returns HTTP 200 once on the first attempt that clears the connection-refused phase, exits, tests start, ALL tests fail with 'TypeError: Failed to fetch' to the gRPC backend. The single-probe gate isn't strict enough — a one-shot 200 (e.g. tonic-health responding before the rest of the dispatcher is fully wired) currently passes. Upgrade the readiness signal to N consecutive HTTP successes spaced PROBE_INTERVAL apart (defaults: 3 successes, 0.5s apart), so the probe only declares the server ready after ~1s of demonstrably-stable response. Any non-success in the streak resets it to zero and the slow-poll loop resumes — so a momentary blip during init doesn't get counted twice on either side. Tracked occurrences across recent PR runs: web-sdk PR #23 ci-shard-4, PR #29 ci-shard-1 + ci-shard-4, PR #27 multiple shards.
WiktorStarczewski
added a commit
that referenced
this pull request
Apr 30, 2026
Observed flake: probe returns HTTP 200 once on the first attempt that clears the connection-refused phase, exits, tests start, ALL tests fail with 'TypeError: Failed to fetch' to the gRPC backend. The single-probe gate isn't strict enough — a one-shot 200 (e.g. tonic-health responding before the rest of the dispatcher is fully wired) currently passes. Upgrade the readiness signal to N consecutive HTTP successes spaced PROBE_INTERVAL apart (defaults: 3 successes, 0.5s apart), so the probe only declares the server ready after ~1s of demonstrably-stable response. Any non-success in the streak resets it to zero and the slow-poll loop resumes — so a momentary blip during init doesn't get counted twice on either side. Tracked occurrences across recent PR runs: web-sdk PR #23 ci-shard-4, PR #29 ci-shard-1 + ci-shard-4, PR #27 multiple shards.
…en configs
- vitest.config.js: exclude crates/web-client/js/passkey-keystore.js
from coverage scope. The new file depends on browser-only WebAuthn
PRF APIs that aren't reachable from node, so it can't be unit-tested
via vitest. It's covered end-to-end by
crates/web-client/test/passkey-keystore.test.ts under Playwright
instead. Without this exclusion, coverage was 73.67% (vs 95% gate).
- knip.jsonc: remove 'dexie' from ignoreDependencies. dexie was
previously only loaded transitively at test runtime (via rollup-bundled
page.evaluate scripts that knip's static scan can't see), but
passkey-keystore.js now imports it directly at the source level —
making the ignore unnecessary. Knip flagged this with 'Remove from
ignoreDependencies'.
- Pulls in scripts/wait-for-grpc.sh's stricter probe (#62 / #63), which
addresses the gRPC dispatch flake that previously hit several PRs'
integration shards.
cargo check --workspace --target wasm32-unknown-unknown is clean (build
artifact compiles against the dep retarget at miden-client wiktor-storekeys
that this PR carries on Cargo.toml). Test stage may surface additional
issues now that the build clears — particularly the 'webclient_new
undefined' WASM-symbol issue we saw on prior runs of this branch — but
those need to be diagnosed against a fresh CI run rather than guessed at.
…age.evaluate
The new test/passkey-keystore.test.ts at line 100 does:
await page.evaluate(async () => {
const { createPasskeyKeystore } = await import('./passkey-keystore.js');
...
});
The import inside page.evaluate() runs in the *browser* context (loaded
from http://localhost:8080) so it resolves to dist/passkey-keystore.js
that the dedicated passkey rollup build emits — NOT to a sibling of
the test file. Knip's static scan can't follow this and flags it as an
unresolved import.
Add './passkey-keystore.js' to the existing ignoreUnresolved allowlist
on the crates/web-client workspace, alongside './index.js' and
'./crates/miden_client_web' which have the same in-browser-eval shape.
This was referenced Apr 30, 2026
…manual dep retarget Cargo.toml + Cargo.lock match origin/next; the 'Client PR: #1835' marker on the PR description drives runtime dep injection. The miden-client wiktor-storekeys branch was previously merged with dab6cf7b (see earlier in this session) so it carries the storekeys work on top of the dab6cf7b-era Store trait that web-sdk's idxdb-store implements.
|
🔗 Linked client PR:
This run is testing against the linked PR's head. The published artifact will use the canonical Local-dev parity: |
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.
Client PR: #1835
Migrated from miden-client#1835 as part of the web-sdk split (web/WASM components moved out of miden-client into this dedicated repo — see miden-client #1992 / #2135).
Summary (per the original PR)
passkey-keystore.jsmodule +passkey-keystore.test.tstest coverage.passkeyEncryptionoption onWebClient.createClient, with a clear warning when bothpasskeyEncryptionand an explicitkeystoreare passed.The miden-client/Rust-side changes from the original PR (opt-in password-based encryption for
FilesystemKeyStore) stay on miden-client#1835.