Environment
- SDK:
@mysten-incubation/memwal@0.1.7
- Node.js: v20+
- Network: Walrus Mainnet Relayer
Summary
When memwal.destroy() is called while an asynchronous request is in-flight (e.g. resolving compatibility metadata or SEAL session), this.privateKey.fill(0) zeros out the key bytes in-memory. Subsequent execution in signedRequest passes the zeroed Uint8Array to ed.signAsync(), generating a valid signature from the zero-key rather than throwing a clean instance-destroyed error.
Reproduction Steps
const memwal = MemWal.create({ key: process.env.MEMWAL_PRIVATE_KEY, accountId: process.env.MEMWAL_ACCOUNT_ID });
// Launch async operation and destroy before signing completes
const promise = memwal.recall({ query: "active query" });
memwal.destroy();
await promise;
// Fails with 401 Unauthorized from relayer due to zero-key signature
Root Cause
In dist/memwal.js (lines 154-157), destroy() wipes the private key buffer without setting a lifecycle flag. When signedRequest resumes, it signs the canonical message using the mutated [0x00, 0x00...] buffer instead of aborting cleanly.
Proposed Fix
Add an isDestroyed boolean flag and throw a clear Error("MemWal client instance has been destroyed") before calling ed.signAsync().
Environment
@mysten-incubation/memwal@0.1.7Summary
When
memwal.destroy()is called while an asynchronous request is in-flight (e.g. resolving compatibility metadata or SEAL session),this.privateKey.fill(0)zeros out the key bytes in-memory. Subsequent execution insignedRequestpasses the zeroed Uint8Array toed.signAsync(), generating a valid signature from the zero-key rather than throwing a clean instance-destroyed error.Reproduction Steps
Root Cause
In
dist/memwal.js(lines 154-157),destroy()wipes the private key buffer without setting a lifecycle flag. WhensignedRequestresumes, it signs the canonical message using the mutated[0x00, 0x00...]buffer instead of aborting cleanly.Proposed Fix
Add an
isDestroyedboolean flag and throw a clearError("MemWal client instance has been destroyed")before callinged.signAsync().