feat(all): migrate wallet to the Miden 0.15 protocol line - #277
Merged
Conversation
…-alpha) Phase A of the 0.15 migration — everything that compiles against @miden-sdk/miden-sdk@0.15.0-alpha.4. Four call sites still reference APIs that exist on web-sdk main but not yet in a published 0.15 alpha (useWorker, newCallbackProver, MidenClient.ready, BlockHeader.feeFaucetId); they are restored by the web-sdk main→next unification PR and the wallet build goes fully green against that branch (alpha.5). - deps: miden-sdk + react + resolutions → 0.15.0-alpha.4 (vite-plugin stays 0.14.11 — verified SDK-version-agnostic: name-based dedup + COOP/COEP headers + gRPC proxy only) - vault: drop account.isNetwork() (gone — networkness is now a component property) and the removed AccountType.RegularAccountImmutableCode builder step (faucet/regular moved off the account ID; storageMode() is the remaining visibility setter) - notes.import resolves a hex string (details-commitment for the wallet's details-only path) — dropped .toString() round-trips and documented the dApp-facing semantics change - InputNoteRecord.id() is now NoteId | undefined for partial (metadata-less) notes — consumable/claimable listings filter them until sync completes them (interface, dapp, sync-manager, claimable-notes) - storeIdentifier() became async — exportDb/importDb await it - metadata: faucets minted by pre-0.15 SDKs are not introspectable via BasicFungibleFaucetComponent.fromAccount — degrade to default metadata instead of session-blacklisting via NotFoundTokenMetadata - native-asset: nativeAssetId() → feeFaucetId() (protocol rename); discovery cache keys bumped to v2 (0.14 account IDs don't round-trip) - native-prover (Android rust-bridge): miden-client via git rev 733720a7 (the same rev the SDK WASM pins; 0.15 is unreleased on crates.io), concurrent now cascades from miden-client itself — direct miden-tx/miden-protocol deps dropped - e2e: miden-client-cli installable from a pinned git rev (midenClientCliGit in package.json, helpers/miden-cli.ts, and the 4 e2e-blockchain.yml install blocks); faucet creation uses the 0.15 CLI surface (--account-type public + -p basic-fungible-faucet, typed [fungible-faucet-metadata] init block, --storage-mode removed) - tests: mocks updated to the 0.15 surface (string import results, toHex, no isNetwork) + new coverage for every added guard branch; 1907 tests green, coverage 95.03% branches (gate: 95%)
… 0.15 (rev 733720a7) arm64-v8a + x86_64 .so binaries built via scripts/build-android.sh with the git-pinned miden-client (same rev the @miden-sdk/miden-sdk 0.15 WASM pins), so the TransactionInputs/ProvenTransaction wire format matches the SDK byte-for-byte. The iOS xcframework rebuild comes from web-sdk's crates/mobile-prover once the main→next unification PR lands.
First alpha cut from the unified web-sdk branch (web-sdk#177 + #178) — the four APIs the wallet was waiting on (useWorker, newCallbackProver, MidenClient.ready, BlockHeader.feeFaucetId) plus lastAuthError are in the published package, so the wallet now typechecks with zero errors against npm instead of a linked-PR build. alpha.5 also refines InputNoteRecord.nullifier() to string | undefined (a 0.15 nullifier folds in metadata, so a partial record cannot have one) — folded into the existing partial-note guards: a record without a nullifier is skipped from consumable/claimable listings alongside the id()-less case.
… prover, e2e green on devnet
Runtime issues found and fixed after the alpha.5 flip (full blockchain
e2e suite now 8/8 against devnet 0.15.0):
- front: gate SdkMidenProvider on ensureSdkWasmReady() — the /lazy
entries do no import-time WASM init, and mounting the SDK provider
before the module is up crashed the whole popup tree ('Something went
wrong while booting a wallet'). Root-caused to the SDK's MidenProvider
resolving its prover via WASM constructors at first render; SDK-side
fix in web-sdk#179, this gate is the wallet-side guarantee
- offscreen: WasmWebClient.proveTransactionWithProver →
proveTransaction (0.15 raw-surface rename; documented in the 0.15
migration guide, 0xMiden/docs#312)
- build: MIDEN_USE_OFFSCREEN_PROVING defaults to false on the 0.15
line — the 0.15 prover hangs under the MT WASM build (pool bring-up,
rayon dispatch, and the SW<->offscreen protocol all verified healthy
in isolation; single-threaded prove of the same tx completes).
Tracked in web-sdk#180; local proving runs single-threaded until then
- native-prover: iOS MidenMobileProver.xcframework rebuilt from
web-sdk crates/mobile-prover at the alpha.5 rev (both slices;
module.modulemap preserved; miden_prove_transaction symbol verified)
- e2e: the CLI helper retries 'new nonce N is less than old nonce M'
sync failures (transient while a deploy/mint is in flight —
miden-client#2243; matched wrap-tolerantly, miette folds the message);
send specs pin tokenSymbol 'TST' (fee-asset discovery now works on
0.15, so the native MIDEN row renders above the funded token and
first-row clicks pick the wrong asset)
- tests: provider tests await the readiness gate; partial-note mocks
carry nullifier() (alpha.5 types it string | undefined)
WiktorStarczewski
marked this pull request as ready for review
June 11, 2026 20:13
…ving on by default The offscreen doc constructed the SDK's worker-shim wrapper (exported as WasmWebClient) instead of the raw wasm-bindgen class (exported as WebClient). Consequences: the prove ran in the wrapper's method worker — a WASM instance whose rayon pool this document never initialized — and the wrapper's implicit worker INIT (createClient with an undefined rpcUrl) performs an eager genesis fetch against the default endpoint, whose failure leaves the wrapper's ready promise pending and every method call hanging forever. That was the wallet leg of 0xMiden/web-sdk#180. The raw class proves in this document's own WASM instance, on the pool init() brings up, with no implicit network round-trip. Proving on a bare client with an explicit prover requires the 0xMiden/web-sdk#182 fix (>= 0.15.0-alpha.6); older 0.15 builds fail the prove loudly with 'Client not initialized' instead of hanging. MIDEN_USE_OFFSCREEN_PROVING defaults to 'true' again on both configs.
…ile wipe The file-level wipe (rm Library/Documents/tmp in the app data container) never actually cleared the wallet's persisted state: UserDefaults is served through cfprefsd's cache and WebKit localStorage/IndexedDB through the per-device WebKit storage daemons, so a relaunched app read its old vault straight back from the daemons and booted to the unlock screen instead of onboarding. Every iOS test after the first failed at createNewWallet, deterministically. simctl uninstall purges app state through the OS and is the only reset that verifiably works.
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.
What
Migrates the wallet to the Miden 0.15 protocol line:
@miden-sdk/miden-sdk+@miden-sdk/react→ published0.15.0-alpha.7, native provers (Android.so+ iOS xcframework) rebuilt against the 0.15 client, E2E infrastructure on the 0.15 CLI surface. Devnet runs node 0.15.0; testnet is still 0.14 (expected-red under the e2e at-least-one-network gate until it upgrades).All web-sdk dependencies are released:
@miden-sdk/miden-sdk+@miden-sdk/reactpinned to published0.15.0-alpha.7(carries web-sdk#182 — the explicit-prover fix the offscreen path needs — and web-sdk#184 — the direct-path call serialization that unblocks mobile).Changes
TS migration (per the 0.15 migration guide, 0xMiden/docs#312 — which gained three sections from breaks this PR discovered):
account.isNetwork()dropped;AccountType.RegularAccountImmutableCodebuilder step removednotes.importresolves a hex string (details-commitment for the wallet's details-only dAppnoteBytespath —ImportPrivateNoteResponse.noteIdsemantics change, changelogged)id()andnullifier()are nowundefineduntil sync completes them — filtered from consumable/claimable listings (interface, dapp, sync-manager, claimable-notes)storeIdentifier()went async;WasmWebClient.proveTransactionWithProver→proveTransaction(offscreen prover doc)BasicFungibleFaucetComponent.fromAccount→ degrade to "Unknown" metadata instead of session-blacklistingBlockHeader.feeFaucetId(); discovery cache keyedv2Boot reliability:
SdkMidenProvidermounts only afterensureSdkWasmReady()— the/lazyentries do no import-time WASM init, and the SDK provider constructs WASM objects during setup (SDK-side fix: web-sdk#179; this gate is the wallet-side guarantee either way).Local proving: offscreen multi-threaded proving stays on (
MIDEN_USE_OFFSCREEN_PROVINGdefaults'true'). The "0.15 prover hang" decomposed into three stacked defects (full analysis: web-sdk#180 comment): the offscreen doc constructed the SDK's worker-shim wrapper (WasmWebClient) believing it was the raw class, the wrapper's implicit worker INIT fails on 0.15 (eager genesis fetch against the default endpoint → version-rejected by 0.14 testnet), and the SDK dropped the INIT error leavingreadypending — a silent forever-hang. The offscreen doc now proves on the raw prover-onlyWebClient(its own rayon pool, no implicit network), which needs web-sdk#182 (≥0.15.0-alpha.6): the explicit-proverproveTransactionfix. On older 0.15 builds the prove fails loudly withClient not initializedinstead of hanging.Native provers: Android JNI bridge + iOS xcframework rebuilt from miden-client rev
733720a7/ web-sdkcrates/mobile-proverat the alpha.5 rev — the exact rev the SDK WASM pins, so theTransactionInputs/ProvenTransactionwire format matches byte-for-byte.E2E/CI:
miden-client-cliinstalls from a pinned git rev (midenClientCliGit; 0.15 CLI unreleased on crates.io); 0.15 faucet surface (--account-type public+-p basic-fungible-faucet, typed[fungible-faucet-metadata]); the helper retries the transientnew nonce N is less than old nonce Msync failure (miden-client#2243); send specs pintokenSymbol: 'TST'(fee-asset discovery now works, so the native MIDEN row renders above the funded token).Store migration for existing users
0.14 stores don't round-trip; the SDK's IndexedDB store self-detects the version bump and re-creates itself — accounts re-register from the wallet seed and balances resync. Saved 0.14 store files can't be imported into a 0.15 build. Changelogged.
Verification
yarn ts0 errors against published alpha.5 ✅yarn lint✅ ·yarn test1907/1907 ✅ · coverage 95.04% branches ≥ 95% gate ✅ ·yarn test:smoke✅alpha.7(mint+balance, multi-account, multi-claim, private send via transport, public send, public send with forced local proving, wallet lifecycle ×2) against devnet node 0.15.0 — with offscreen MT proving on, built against the web-sdk#182 fix via the linked-PR mechanism; the forced-local-prove spec recordstx_completed prove_ms=5653(the prove that previously hung indefinitely), and the speculative pre-prove path works (via_speculation=true)alpha.7— first fully green mobile run on the 0.15 line (mint+claim+balance, multi-account, multi-claim, private send via transport, public send, lifecycle ×2). Two blockers root-caused on the way: the SDK's lost direct-path call serialization (web-sdk#184; wallet-creationRefCellpanic) and the e2e fixture's file-level sandbox wipe being defeated by cfprefsd/WebKit daemon caches (fixed: per-test uninstall+install).