import_taddr decoded a WIF with bs58::decode(..).unwrap(), a [2..66]
slice of its hex and SecretKey::from_slice(..).unwrap(), all under the
wallet write guard that do_import_tk holds. A z-key, a typo or any short
string panicked there and poisoned the wallet until restart, and the
checksum was never verified, so a mistyped WIF that was still valid
base58 imported a different key.
A private key imported into an encrypted wallet was stored without an
enc_key. The import then failed in do_save's lock(), which had already
zeroed the seed while the wallet stayed "unlocked": seed export showed
the all-zero-entropy phrase.
- decode_taddr_wif replaces the old decode: Base58Check with the
checksum verified, version 0xBC (the config prefix) or 0x80, and the
0x01 compressed flag. It decodes into a buffer it owns and wipes it
with sodiumoxide::utils::memzero on every path, including a failed
checksum. Errors are fixed strings that never contain the key.
- import_taddr and add_imported_sk refuse while the wallet is encrypted,
as add_taddr and add_zaddr already do.
- do_import_tk and do_import_sk check is_encrypted() before the
"locked" check, so a locked wallet does not send the user to unlock
and retry.
Flagged behaviour changes:
- Base58Check, version 0xBC/0x80 and the compressed flag are required;
- uncompressed and foreign-network WIFs are rejected with fixed
messages (an uncompressed key used to import under the compressed
address, where its funds are not);
- no panic and no poisoned lock;
- private-key import (t and z) is refused while the wallet is
encrypted, with a reason that says to remove encryption, import, then
encrypt again; viewing keys still import;
- the key is never echoed.
No ABI, symbol or wallet format change.
Tests: garbage, z-keys, bad checksums, a transposed or flipped
character, a zero scalar, a wrong flag, uncompressed, 0x05 and 0xEF WIFs
are rejected with their message and leave tkeys usable; the wallet's own
export, a 0x80 WIF and the published key-1 vector still import; the
encrypted refusal in the wallet and the client, locked and unlocked,
leaves lock, save and seed export intact; a viewing key still imports
into an encrypted wallet; a bad timport leaves the wallet lock unpoisoned.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>