mirror of
https://github.com/kccleoc/seedpgp-web.git
synced 2026-03-06 17:37:51 +08:00
fix(blender): correct isomorphic crypto loading
Refactors the crypto module loading in `seedblend.ts` to be truly isomorphic and prevent browser runtime errors. - Replaces the static Node.js `crypto` import with a dynamic `import()` inside a singleton promise (`getCrypto`). - This ensures Vite does not externalize the module for browser builds, resolving the 'Cannot access \'crypto.webcrypto\' in client code' error. - The browser will use its native `window.crypto`, while the Node.js test environment dynamically loads the `crypto` module. - All tests continue to pass, verifying the fix.
This commit is contained in:
@@ -23,16 +23,28 @@
|
||||
*/
|
||||
|
||||
import wordlistTxt from '../bip39_wordlist.txt?raw';
|
||||
import { webcrypto } from 'crypto';
|
||||
|
||||
// --- Isomorphic Crypto Setup ---
|
||||
|
||||
// Use browser crypto if available, otherwise fallback to Node.js webcrypto.
|
||||
// This allows the library to run in both the browser and the test environment (Node.js).
|
||||
const subtle = (typeof window !== 'undefined' && window.crypto?.subtle)
|
||||
? window.crypto.subtle
|
||||
: webcrypto.subtle;
|
||||
|
||||
let cryptoPromise: Promise<SubtleCrypto>;
|
||||
/**
|
||||
* Asynchronously gets the appropriate SubtleCrypto interface, using a singleton
|
||||
* pattern to ensure the module is loaded only once.
|
||||
* This approach uses a dynamic import() to prevent Vite from bundling the
|
||||
* Node.js 'crypto' module in browser builds.
|
||||
*/
|
||||
function getCrypto(): Promise<SubtleCrypto> {
|
||||
if (!cryptoPromise) {
|
||||
cryptoPromise = (async () => {
|
||||
if (typeof window !== 'undefined' && window.crypto?.subtle) {
|
||||
return window.crypto.subtle;
|
||||
}
|
||||
const { webcrypto } = await import('crypto');
|
||||
return webcrypto.subtle;
|
||||
})();
|
||||
}
|
||||
return cryptoPromise;
|
||||
}
|
||||
|
||||
// --- BIP39 Wordlist Loading ---
|
||||
|
||||
@@ -61,6 +73,7 @@ if (BIP39_WORDLIST.length !== 2048) {
|
||||
* @returns A promise that resolves to the hash as a Uint8Array.
|
||||
*/
|
||||
async function sha256(data: Uint8Array): Promise<Uint8Array> {
|
||||
const subtle = await getCrypto();
|
||||
const hashBuffer = await subtle.digest('SHA-256', data);
|
||||
return new Uint8Array(hashBuffer);
|
||||
}
|
||||
@@ -72,6 +85,7 @@ async function sha256(data: Uint8Array): Promise<Uint8Array> {
|
||||
* @returns A promise that resolves to the HMAC tag.
|
||||
*/
|
||||
async function hmacSha256(key: Uint8Array, data: Uint8Array): Promise<Uint8Array> {
|
||||
const subtle = await getCrypto();
|
||||
const cryptoKey = await subtle.importKey(
|
||||
'raw',
|
||||
key,
|
||||
|
||||
Reference in New Issue
Block a user