fix: replace static whatsapp-rust-bridge imports with lazy dynamic loading
The whatsapp-rust-bridge package contains a top-level await on an inline WASM binary, which propagates through the ESM graph and causes ERR_REQUIRE_ASYNC_MODULE when CJS consumers try to require() this package. Replace all static imports from whatsapp-rust-bridge with a lazy-loading bridge module (wasm-bridge.ts) that uses import().then() instead of top-level await, keeping the dependency out of the static ESM graph. https://claude.ai/code/session_01XaA7GwNaB6azTHFYQ8WEpB
This commit is contained in:
@@ -19,7 +19,7 @@ import {
|
|||||||
type MessageLabelAssociation
|
type MessageLabelAssociation
|
||||||
} from '../Types/LabelAssociation'
|
} from '../Types/LabelAssociation'
|
||||||
import { type BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidNormalizedUser } from '../WABinary'
|
import { type BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, isJidGroup, jidNormalizedUser } from '../WABinary'
|
||||||
import { expandAppStateKeys } from 'whatsapp-rust-bridge'
|
import { expandAppStateKeys } from './wasm-bridge'
|
||||||
import { aesDecrypt, aesEncrypt, hmacSign } from './crypto'
|
import { aesDecrypt, aesEncrypt, hmacSign } from './crypto'
|
||||||
import { toNumber } from './generics'
|
import { toNumber } from './generics'
|
||||||
import type { ILogger } from './logger'
|
import type { ILogger } from './logger'
|
||||||
@@ -102,7 +102,7 @@ const makeLtHashGenerator = ({ indexValueMap, hash }: Pick<LTHashState, 'hash' |
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
finish: () => {
|
finish: () => {
|
||||||
const result = LT_HASH_ANTI_TAMPERING.subtractThenAdd(new Uint8Array(hash), addBuffs, subBuffs)
|
const result = LT_HASH_ANTI_TAMPERING().subtractThenAdd(new Uint8Array(hash), addBuffs, subBuffs)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hash: Buffer.from(result),
|
hash: Buffer.from(result),
|
||||||
|
|||||||
+1
-1
@@ -118,7 +118,7 @@ export function sha256(buffer: Buffer) {
|
|||||||
return createHash('sha256').update(buffer).digest()
|
return createHash('sha256').update(buffer).digest()
|
||||||
}
|
}
|
||||||
|
|
||||||
export { hkdf, md5 } from 'whatsapp-rust-bridge'
|
export { hkdf, md5 } from './wasm-bridge'
|
||||||
|
|
||||||
export async function derivePairingCodeKey(pairingCode: string, salt: Buffer): Promise<Buffer> {
|
export async function derivePairingCodeKey(pairingCode: string, salt: Buffer): Promise<Buffer> {
|
||||||
// Convert inputs to formats Web Crypto API can work with
|
// Convert inputs to formats Web Crypto API can work with
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export * from './noise-handler'
|
|||||||
export * from './history'
|
export * from './history'
|
||||||
export * from './chat-utils'
|
export * from './chat-utils'
|
||||||
export * from './lt-hash'
|
export * from './lt-hash'
|
||||||
|
export { wasmBridgeReady } from './wasm-bridge'
|
||||||
export * from './auth-utils'
|
export * from './auth-utils'
|
||||||
export * from './use-multi-file-auth-state'
|
export * from './use-multi-file-auth-state'
|
||||||
export * from './link-preview'
|
export * from './link-preview'
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import { LTHashAntiTampering } from 'whatsapp-rust-bridge'
|
import { getLTHashAntiTampering } from './wasm-bridge'
|
||||||
|
|
||||||
export const LT_HASH_ANTI_TAMPERING = new LTHashAntiTampering()
|
export { getLTHashAntiTampering as LT_HASH_ANTI_TAMPERING }
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
type WasmBridgeModule = typeof import('whatsapp-rust-bridge')
|
||||||
|
|
||||||
|
let _bridge: WasmBridgeModule | undefined
|
||||||
|
|
||||||
|
// Start loading eagerly using .then() instead of top-level await.
|
||||||
|
// This prevents the whatsapp-rust-bridge top-level await from propagating
|
||||||
|
// through the ESM graph, which would break CJS require() consumers.
|
||||||
|
const _bridgeReady = import('whatsapp-rust-bridge').then(m => {
|
||||||
|
_bridge = m
|
||||||
|
return m
|
||||||
|
})
|
||||||
|
|
||||||
|
export { _bridgeReady as wasmBridgeReady }
|
||||||
|
|
||||||
|
function getBridge(): WasmBridgeModule {
|
||||||
|
if (!_bridge) {
|
||||||
|
throw new Error(
|
||||||
|
'whatsapp-rust-bridge not yet loaded. ' +
|
||||||
|
'Ensure async operations have started before calling crypto functions.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return _bridge
|
||||||
|
}
|
||||||
|
|
||||||
|
export const hkdf: WasmBridgeModule['hkdf'] = (...args) => getBridge().hkdf(...args)
|
||||||
|
|
||||||
|
export const md5: WasmBridgeModule['md5'] = (...args) => getBridge().md5(...args)
|
||||||
|
|
||||||
|
export const expandAppStateKeys: WasmBridgeModule['expandAppStateKeys'] = (...args) => getBridge().expandAppStateKeys(...args)
|
||||||
|
|
||||||
|
let _ltHash: InstanceType<WasmBridgeModule['LTHashAntiTampering']> | undefined
|
||||||
|
|
||||||
|
export function getLTHashAntiTampering(): InstanceType<WasmBridgeModule['LTHashAntiTampering']> {
|
||||||
|
if (!_ltHash) {
|
||||||
|
_ltHash = new (getBridge().LTHashAntiTampering)()
|
||||||
|
}
|
||||||
|
|
||||||
|
return _ltHash
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user