deviant/scripts/test-wif-property.mjs
walerikus 35076606c7 chore: checkpoint in-flight work across shell, contracts, and docs
Snapshot of the shared working tree's outstanding changes (multiple
concurrent workstreams), excluding generated runtime state files
(.football-tote-state.json, .tote-platform-state.json, .usdm-historical-chart.html).

Spans: wallet shell (connect/, keystore MultiKeyStore+vault, screens,
currency picker, sign-message), verify artifacts, new Potidaea/DRA/tote
contracts + regtest suites, cross-chain/T6 + WalletConnect Parameters,
a telegram-orderbook subproject, design mockups, and docs. See
shells/app/WALLET-COORDINATION.md for the per-file ownership split.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 02:02:05 +02:00

97 lines
3.2 KiB
JavaScript

#!/usr/bin/env node
/**
* test-wif-property.mjs — smoke-test w.privateKeyWif on TestNetWallet.fromSeed()
*
* The sweep flow's deriveKeySet() and findKeyForAddress() read `w.privateKeyWif`
* after calling TestNetWallet.fromSeed(mnemonic, path). The property is verified
* on newRandom() wallets throughout the chipnet scripts, but fromSeed() is a
* different code path inside mainnet-js.
*
* This script confirms:
* 1. w.privateKeyWif is present and non-empty on a fromSeed() wallet
* 2. It matches the WIF regex (^[5KLc][1-9A-HJ-NP-Za-km-z]{50,51}$)
* 3. The fallback w.toWIF?.() either also works or is absent (either is fine)
* 4. A wallet loaded back with fromWIF(w.privateKeyWif) round-trips to the same cashaddr
*
* Run: rtk node scripts/test-wif-property.mjs
* No network calls; no funds needed.
*/
import { TestNetWallet } from 'mainnet-js';
// BIP-39 standard test vector — safe to use in scripts, never fund on mainnet.
const MNEMONIC = 'test test test test test test test test test test test junk';
const PATHS = [
"m/44'/145'/0'/0/0", // BCH canonical (Electron Cash)
"m/44'/145'/0'/0/1", // second index — same family
"m/44'/0'/0'/0/0", // legacy BTC coin-type
];
// Same regex used in sweep.ts looksLikeWif()
const WIF_RE = /^[5KLc][1-9A-HJ-NP-Za-km-z]{50,51}$/;
let passed = 0;
let failed = 0;
function ok(label, value) {
console.log(` ✓ ${label}: ${value}`);
passed++;
}
function fail(label, detail) {
console.error(` ✗ ${label}: ${detail}`);
failed++;
}
for (const path of PATHS) {
console.log(`\nPath: ${path}`);
const w = await TestNetWallet.fromSeed(MNEMONIC, path);
// 1. cashaddr present
if (w.cashaddr && w.cashaddr.startsWith('bchtest:')) {
ok('cashaddr', w.cashaddr);
} else {
fail('cashaddr', `unexpected value: ${w.cashaddr}`);
}
// 2. privateKeyWif present and valid
const wif = w.privateKeyWif;
if (typeof wif === 'string' && wif.length > 0) {
ok('privateKeyWif type', `string, length ${wif.length}`);
} else {
fail('privateKeyWif type', `got ${typeof wif} = ${wif}`);
}
if (WIF_RE.test(wif ?? '')) {
ok('privateKeyWif regex', wif);
} else {
fail('privateKeyWif regex', `"${wif}" does not match WIF pattern`);
}
// 3. toWIF() fallback — may or may not exist; log either way
const toWif = w.toWIF?.();
if (typeof toWif === 'string') {
if (toWif === wif) {
ok('toWIF() == privateKeyWif', 'same value — fallback redundant but safe');
} else {
fail('toWIF() != privateKeyWif', `${toWif} vs ${wif}`);
}
} else {
ok('toWIF()', 'not present — fallback will reach \'\' (expected for mainnet-js)');
}
// 4. round-trip: fromWIF(wif) → same cashaddr
const w2 = await TestNetWallet.fromWIF(wif);
if (w2.cashaddr === w.cashaddr) {
ok('round-trip fromWIF', 'cashaddr matches');
} else {
fail('round-trip fromWIF', `got ${w2.cashaddr}, expected ${w.cashaddr}`);
}
}
console.log(`\n── Result: ${passed} passed, ${failed} failed ──`);
if (failed > 0) {
console.error('FAIL — update the fallback chain in sweep.ts if w.privateKeyWif is absent');
process.exit(1);
}
console.log('PASS — w.privateKeyWif works on fromSeed() wallets; fallback chain is correct');