65 lines
2.7 KiB
JavaScript
65 lines
2.7 KiB
JavaScript
|
|
// End-to-end smoke test of Blockbook scan flow.
|
|||
|
|
// Derives all four purposes × 2 accounts × 2 changes × 20 gap from
|
|||
|
|
// the standard abandon seed, hits /utxo/{addr} for each in parallel,
|
|||
|
|
// aggregates. Also probes a known-live address to prove client works
|
|||
|
|
// against real balances.
|
|||
|
|
import {
|
|||
|
|
seedFromPhrase, rootFromSeed, accountNode, addressNode,
|
|||
|
|
p2pkhAddress, p2shP2wpkhAddress, p2wpkhAddress, p2trAddress,
|
|||
|
|
} from '@dgb-wallet/core';
|
|||
|
|
import { BlockbookClient } from '../dist/index.js';
|
|||
|
|
|
|||
|
|
const bb = new BlockbookClient();
|
|||
|
|
|
|||
|
|
console.log('=== status ===');
|
|||
|
|
const s = await bb.status();
|
|||
|
|
console.log(` coin=${s.coin} tip=${s.tip.toLocaleString()} inSync=${s.inSync} v=${s.version}`);
|
|||
|
|
|
|||
|
|
console.log('\n=== known-live address (DGB mining pool) ===');
|
|||
|
|
const known = await bb.utxos('DLgDJd61zTsAhNN6xMja4z9ZNxy6Yb9Mrn');
|
|||
|
|
console.log(` utxo count=${known.length} first=${JSON.stringify({txid: known[0]?.txid.slice(0,12)+'…', value: known[0]?.value.toString()})}`);
|
|||
|
|
|
|||
|
|
console.log('\n=== abandon seed all-paths scan ===');
|
|||
|
|
const t0 = Date.now();
|
|||
|
|
const seed = await seedFromPhrase('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about');
|
|||
|
|
const root = rootFromSeed(seed);
|
|||
|
|
const addrs = [];
|
|||
|
|
for (const purpose of [44, 49, 84, 86]) {
|
|||
|
|
for (let a = 0; a < 2; a++) {
|
|||
|
|
const acct = accountNode(root, purpose, a);
|
|||
|
|
for (const change of [0, 1]) {
|
|||
|
|
for (let i = 0; i < 20; i++) {
|
|||
|
|
const node = addressNode(acct, change, i);
|
|||
|
|
const address =
|
|||
|
|
purpose === 44 ? p2pkhAddress(node) :
|
|||
|
|
purpose === 49 ? p2shP2wpkhAddress(node) :
|
|||
|
|
purpose === 84 ? p2wpkhAddress(node) :
|
|||
|
|
p2trAddress(node);
|
|||
|
|
addrs.push({ address, purpose, account: a, change, index: i });
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
console.log(` derived ${addrs.length} addresses in ${Date.now() - t0}ms`);
|
|||
|
|
|
|||
|
|
const t1 = Date.now();
|
|||
|
|
let cursor = 0;
|
|||
|
|
let totalSats = 0n;
|
|||
|
|
let hitCount = 0;
|
|||
|
|
const workers = Array.from({ length: 8 }, async () => {
|
|||
|
|
while (cursor < addrs.length) {
|
|||
|
|
const item = addrs[cursor++];
|
|||
|
|
const list = await bb.utxos(item.address).catch(() => []);
|
|||
|
|
if (list.length > 0) {
|
|||
|
|
hitCount++;
|
|||
|
|
for (const u of list) totalSats += u.value;
|
|||
|
|
console.log(` hit: ${item.address} m/${item.purpose}'/20'/${item.account}'/${item.change}/${item.index} utxos=${list.length} value=${Number(list.reduce((s,u)=>s+u.value, 0n))/1e8} DGB`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
await Promise.all(workers);
|
|||
|
|
const elapsed = Date.now() - t1;
|
|||
|
|
console.log(`\n scanned ${addrs.length} addresses in ${elapsed}ms hits=${hitCount} totalSats=${totalSats} totalDGB=${Number(totalSats)/1e8}`);
|
|||
|
|
console.log(` effective rate: ${(addrs.length / (elapsed/1000)).toFixed(0)} addr/s`);
|
|||
|
|
process.exit(0);
|