wallet-sdk PR5a: wallet handles + proof decryption#1123
Closed
orveth wants to merge 1 commit into
Closed
Conversation
Resolve PR4's deferred AccountHandleResolver with the REAL Slice-3 resolver (sub-slice 3a of cashu+spark): live account wallet handles + cashu proof decryption. The account repository/domain is unchanged — Sdk.create swaps the DeferredAccountHandleResolver for the new LiveAccountHandleResolver. Cashu (fully live): - getInitializedCashuWallet (internal/cashu-wallet.ts): builds an ExtendedCashuWallet, fetches mint info/keysets/keys via a framework-free per-mint 1h-TTL memo (MintMetadataCache, replacing master's QueryClient staleTime) + master's 10s NetworkError timeout, loads keys from cache; offline → keyless wallet + isOnline:false. - Proof decryption (internal/encryption.ts): re-housed ECIES decrypt + master's type-preserving (de)serialisation; key derived from OpenSecret at m/10111099'/0'; decryptCashuProofs ported into the resolver (batch decrypt amount/secret, re-parse dleq/witness via cashu-ts ProofSchema). Spark (live, lazy): - @agicash/breez-sdk-spark added (was absent from the lockfile). It is a native/WASM package, so its runtime is loaded via dynamic import() inside getInitializedSparkWallet (internal/spark-wallet.ts); only the TYPES are imported statically. Connect+getInfo balance, per-(mnemonic,network) memo, offline→throwing stub. No breezApiKey → labelled stub + offline (cashu-only). Placeholders resolved (types/dependencies.ts): ExtendedCashuWallet, BreezSdk, CashuProtocolProof, ProofDleq/ProofWitness now point at their real sources. OpenSecret (internal/open-secret.ts): added getEncryptionPrivateKeyHex / getCashuWalletSeed / getSparkWalletMnemonic (derivation paths match master). Tests (mock the networked/native bits — mint fetch, Breez runtime, ECIES): +22 tests covering MintMetadataCache memo/TTL, online/offline cashu init, spark connect/stub/memo, the live resolver, and getBalance over real decrypted proofs. Breez WASM is never loaded in unit tests or by a cashu-only Sdk.create. Full CI gate green locally: biome format + lint, tsc --noEmit, and both packages' tests (wallet-sdk 160 / web-wallet 133, 0 fail). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Contributor
Author
|
Superseded by the reactive design-B stack (SDK #1129-#1138 + lib-extract #1140-#1143). This no-cache stack was the reference substrate the reactive PRs were built from (~90% reused, reads adapted to Query); it was never reviewed/merged, so nothing is lost. Closing as superseded — branch retained for reference. |
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.
Sub-slice 3a of the heavy Slice 3 (cashu + spark), stacked on PR4 (#1122). It resolves PR4's deferred
AccountHandleResolverseam with the REAL resolver — the live accountwallethandles + cashu proof decryption that PR4 deferred. The accounts repository/domain is unchanged;Sdk.createsimply swapsDeferredAccountHandleResolver→LiveAccountHandleResolver.What's now LIVE
Cashu (fully live — the main win of this PR)
getInitializedCashuWallet(internal/cashu-wallet.ts) builds anExtendedCashuWallet(cashu-tsWalletsubclass + seed), fetches mint info / keysets / keys, and loads keys from cache. Master'sQueryClient1 hstaleTimememo → a framework-free per-mint-URLMintMetadataCache(1 h TTL, rejected fetches not cached); master's 10 s timeout → aPromise.racerejecting with a cashu-tsNetworkError. Offline / timeout → keyless wallet +isOnline: false, exactly as master.internal/encryption.ts): re-housed ECIES batch-decrypt + master's type-preserving (de)serialisation (Date / undefined / non-finite /Money), framework-free. The data-encryption key is derived from the OpenSecret enclave atm/10111099'/0'. Master'saccount-repository.decryptCashuProofsis ported into the resolver: batch-decrypt the interleavedamount/secretciphertext, re-parseamount→number /secret→string, and re-validatedleq/witnessvia cashu-tsProofSchema. Cashu accounts now get realproofs,isOnline, and a realgetBalance.Spark (live, but lazy-loaded)
getInitializedSparkWallet(internal/spark-wallet.ts): connects a BreezBreezSdk, reads balance fromgetInfo().balanceSats, memoised per(mnemonic, network); on any failure → a throwing stub +isOnline: false+nullbalance (master's behaviour). The singleinitLoggingguard is preserved.@agicash/breez-sdk-sparkneeded installing — it was a dep ofapps/web-walletbut absent from the lockfile /node_modules. Added it (pinned to master's0.13.5-1). It is a native/WASM package (loads WASM + auto-enables Node storage at module-eval), so its runtime is loaded via a dynamicimport()inside the init function; only the types are imported statically. Result: the WASM is never loaded in unit tests (which inject a mock runtime) or by a cashu-onlySdk.create. When nobreezApiKeyis configured, spark resolves to a labelled stub + offline — the SDK runs cashu-only without Breez.Placeholders resolved
types/dependencies.ts:ExtendedCashuWallet,BreezSdk,CashuProtocolProof,ProofDleq,ProofWitnessnow point at their real sources (app/lib/cashu/utils,@agicash/breez-sdk-spark,@cashu/cashu-tsProof).SparkNetworkwas already the real literal union.Still deferred (later sub-slices / slices)
executeQuoteorchestrator + mint-WS subscription managers (3b–3d / the rest of Slice 3).Sdk.destroy()now drops the live-handle memos; closing the actual Breezdisconnect()/ mint-WS subs lands when those connections open (Slice 5).Wiring
New SDK-internal re-export seams (single-source, matching PR4's
lib-*pattern):lib-cashu-wallet.ts,lib-ecies.ts,lib-account-cryptography.ts.OpenSecretClientgainsgetEncryptionPrivateKeyHex/getCashuWalletSeed/getSparkWalletMnemonic(derivation paths verbatim from master).Sdk.createconstructs theMintMetadataCache+SparkWalletCache(held on the connection bundle, dropped indestroy()) and theLiveAccountHandleResolver.Tests & mocking
+22tests, mocking every networked/native bit: the mint fetch (injectedMintfactory), the Breez runtime (injected mock — never imports WASM), and ECIES (mock.moduleof the decrypt primitive). Coverage:MintMetadataCachememo/TTL/reject-not-cached, online/offline cashu init, spark connect/stub/memo/retry, the live resolver (decrypted proofs incl.dleqparse, online/offline, no-key spark stub), andgetBalanceover the real decrypted proofs (sum = 42 sats).CI gate (green locally)
biome format --write+biome format(check) +biome lint+tsc --noEmitfor the package, and rootbun --filter='*' run test— wallet-sdk 160 pass / web-wallet 133 pass, 0 fail (both packages).bun install --frozen-lockfileverified (fresh CI install resolves the new deps).🤖 Generated with Claude Code