test: cover wallet.js key derivation and vault.js encryption — currently zero tests on the crypto core #159
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The two modules that hold user funds have no tests at all. The whole suite
is four files (
tests/constants.test.js,tests/etherscanLabels.test.js,tests/phishingDomains.test.js,tests/uniswap.test.js) and none of themrequire
wallet.jsorvault.js.src/shared/wallet.jsexports (wallet.js:73-82):generateMnemonic,deriveAddressFromXpub,hdWalletFromMnemonic,hdWalletFromXprv,isValidXprv,addressFromPrivateKey,getSignerForAddress,isValidMnemonic.src/shared/vault.js(62 lines) implements the Argon2id + XSalsa20-Poly1305encrypt/decrypt described in the README Key Decisions section.
This covers two of the three README TODO testing items (
README.md:888-889):"Tests for mnemonic generation and address derivation" and "Tests for xpub
derivation and child address generation".
Blocking caveat
wallet.js:7-13short-circuitsgenerateMnemonic()to the hardcodedDEBUG_MNEMONICwheneverDEBUGis true, andsrc/shared/constants.js:1isconst DEBUG = true. A naive test written today would assert on the fixeddebug phrase, pass, and leave the real entropy path untested. Issue #149
makes
DEBUGa build-time flag defaulting off; coordinate with it. If #149 hasnot landed, the tests here must explicitly exercise the non-debug path rather
than accepting whatever
DEBUGcurrently yields.Implementation requirements
self-referential. Use a published throwaway phrase; never a real one.
hdWalletFromMnemonicmust be pinned against known addresses for thedocumented path
m/44'/60'/0'/0/nfor at least indices 0, 1, and 2. TheREADME states compatibility with the standard derivation path, so these
vectors also serve as the compatibility guarantee.
hdWalletFromMnemonic:21usesBIP44_ETH_PATH = "m/44'/60'/0'/0"whilehdWalletFromXprv:32usesroot.derivePath("44'/60'/0'/0")— relative, without them/prefix. A testmust lock down what each actually produces. If they disagree in a way that
yields different addresses for the same key material, that is a bug: report
it in the PR rather than encoding the wrong behaviour into an assertion.
deriveAddressFromXpubmust be tested for correct child address generationand must be shown to agree with
hdWalletFromMnemonicfor the sameunderlying seed and index.
isValidMnemonic/isValidXprv: cover valid input, wrong-checksum input,wrong word count, and empty/garbage input.
addressFromPrivateKey: pin against a known key/address pair.vault.js: round-trip encrypt then decrypt returns the original plaintext;a wrong password fails and fails cleanly (no partial plaintext, no
unhandled rejection); a tampered ciphertext is rejected by the Poly1305 auth
tag; the stored blob has the documented
{ salt, nonce, ciphertext }shape;two encryptions of the same plaintext with the same password produce
different ciphertexts (fresh salt and nonce).
script/test:10.Argon2id is deliberately slow — if the default parameters make the round-trip
test too slow, do not weaken the production parameters. Use fewer
iterations of the test, or expose the cost parameters for the test only, and
say which in the PR.
Definition of done
tests/wallet.test.jsandtests/vault.test.jsexist and cover everybullet above.
wallet.jsandvault.jshas at least oneassertion against it.
the implementation currently returns.
m/-prefix asymmetry betweenhdWalletFromMnemonicandhdWalletFromXprvis either proven harmless by test, or reported as abug in the PR.
make teststill completes within the 30-second timeout.README.md:888-889are ticked.TODO.mdupdated in the same commit.make checkpasses.Manager note — sequencing constraint, recorded before this is dispatched so it
is not discovered the hard way.
tests/wallet.test.jsalready exists on PR #169's branch. That PR (issue#149, the DEBUG build-time flag) created it with six tests covering
generateMnemonicin both build modes, including the debug path and theruntime-toggle interaction.
So this issue is now extend, not create. Whoever picks it up must:
fix/issue-149-debug-build-flagif #169 has not merged, oron
mainafter it has. Do not branch from amainthat lacks that file andthen create a second
tests/wallet.test.js— that is a guaranteed conflicton a file where a bad merge resolution could silently drop the regression
tests protecting a funds-loss vulnerability.
reorganise them; they are the guard for #149 and were specifically validated
during review against five different broken-implementation shapes.
resolved: #169 makes
DEBUGdefault tofalseunder jest, sogenerateMnemonic()in a test context exercises the real entropy path.That removes the trap this issue warned about. The remaining scope is the
derivation and vault coverage —
hdWalletFromMnemonic,hdWalletFromXprv,deriveAddressFromXpub,isValidMnemonic,isValidXprv,addressFromPrivateKey, and all ofvault.js.m/prefix asymmetry betweenhdWalletFromMnemonic:21andhdWalletFromXprv:32remains unexamined and is still the most interestingthing in this issue. Pin it with known-answer vectors; if the two disagree
for the same key material, that is a bug to report rather than an assertion
to write.
Holding dispatch until #169 merges or until it is clear the branch base is
stable, to avoid a three-deep stack of unmerged PRs on the same file.
clawbot referenced this issue2026-08-11 15:15:13 +02:00