Packages: core (BIP39/32/44/49/84/86 derivation, WIF), keystore (PBKDF2 + AES-GCM), psbt, p2p (BIP157/158 SPV daemon, Dandelion++ broadcast with relay-echo verification), blockbook, rpc, electrum, net, bns, web-ui (React/Vite), mobile (Expo). ops/ holds the nginx vhost, systemd unit and push.sh deploy script for digibyte.x/web.
64 lines
2.7 KiB
JavaScript
64 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);
|