fix: Incorrect passphrase on react-wallet#97
Conversation
…ssphrase" The catch-all in buildKeymaster showed "Incorrect passphrase" for every error, including unrelated failures during new wallet creation. Now only passphrase decryption errors show that message; other errors display their actual message. Also awaits async onSubmit in PassphraseModal so the spinner stays visible during wallet operations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ption Eliminates the Web Cryptography API secure-context requirement so wallet encryption works over plain HTTP (e.g. VPN access). Uses @noble/hashes for PBKDF2 key derivation and @noble/ciphers for AES-256-GCM, which are pure JS and already used elsewhere in the project. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR migrates cryptographic operations from the Web Crypto API to the @noble/ciphers and @noble/hashes libraries, which improves compatibility and error handling for incorrect passphrase detection. The change addresses issue #91 by ensuring that incorrect passphrase errors are properly detected across different runtime environments (Web Crypto API vs. @noble/ciphers).
Changes:
- Replaced Web Crypto API encryption/decryption with @noble/ciphers (AES-GCM) and @noble/hashes (PBKDF2-SHA512)
- Enhanced error detection to recognize both legacy Web Crypto "OperationError" and @noble/ciphers "invalid ghash tag" errors as incorrect passphrase indicators
- Improved React component error handling to differentiate between incorrect passphrase and other errors
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/keymaster/src/encryption.ts | Migrated from Web Crypto API to @noble libraries for mnemonic encryption/decryption |
| packages/keymaster/src/keymaster.ts | Added error detection for @noble/ciphers "invalid ghash tag" message alongside existing OperationError check |
| packages/keymaster/package.json | Added @noble/ciphers and @noble/hashes dependencies |
| tests/keymaster/wallet.test.ts | Removed WebCrypto availability tests (no longer needed with @noble) |
| tests/keymaster/testUtils.ts | Removed test utility for disabling crypto.subtle (no longer needed) |
| apps/react-wallet/src/modals/PassphraseModal.tsx | Updated onSubmit signature to support async handlers |
| apps/react-wallet/src/contexts/WalletProvider.tsx | Improved error handling to show specific error messages vs. generic incorrect passphrase |
| package.json | Added @rollup/rollup-linux-x64-gnu as direct dependency |
| package-lock.json | Updated lockfile with new dependencies and removed unused rollup platform binaries |
Comments suppressed due to low confidence (1)
package.json:20
- The @rollup/rollup-linux-x64-gnu package has been added as a direct dependency in the root package.json, but this is a platform-specific package intended for Linux x64 systems only. This will cause installation failures or warnings on other platforms (macOS, Windows, ARM, etc.). Platform-specific rollup binaries are typically installed automatically as optional dependencies by the main rollup package. Consider removing this explicit dependency and allowing rollup to manage its platform-specific binaries automatically, or if this is required for a specific CI/deployment environment, document why this is necessary.
"@rollup/rollup-linux-x64-gnu": "^4.57.1",
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Consolidates all cryptographic operations in the cipher package. Renames encMnemonic/decMnemonic to encryptWithPassphrase/decryptWithPassphrase and updates all consumers to import from @didcid/cipher/passphrase. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 19 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
packages/cipher/src/passphrase.ts:49
b64/ub64rely on a globalBuffer, but this module doesn’t import it. That will throw at runtime in browser consumers unless they remember to polyfillBufferglobally. Consider importingBufferfrom thebufferpackage (already a dependency) or switching to a browser-safe base64 implementation so@didcid/cipher/passphraseworks out-of-the-box across environments.
const b64 = (buf: Uint8Array) => {
return Buffer.from(buf).toString('base64');
}
const ub64 = (b64: string) => {
return new Uint8Array(Buffer.from(b64, 'base64'));
}
packages/keymaster/package.json:44
- The
./encryptionsubpath export was removed from@didcid/keymaster. If this package is consumed outside the monorepo, that’s a breaking API change for anyone importing@didcid/keymaster/encryption. Consider keeping a thin compatibility re-export (pointing to@didcid/cipher/passphrase) or coordinating this with a major version bump and migration notes.
"./client": {
"import": "./dist/esm/keymaster-client.js",
"require": "./dist/cjs/keymaster-client.cjs",
"types": "./dist/types/keymaster-client.d.ts"
},
"./wallet/json": {
"import": "./dist/esm/db/json.js",
"require": "./dist/cjs/db/json.cjs",
"types": "./dist/types/db/json.d.ts"
},
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Clean install resolves the native rollup binary correctly without needing @rollup/rollup-linux-x64-gnu as an explicit dependency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
No description provided.