Operation ran today: swept every FT holding across A-H + gmx
(backed MBAs + non-state NBAs) back to BCH via implicit fungible-token
burn, consolidated into wallet H. 9 txs total, 51 covenant-state NFTs
preserved. H now at 2.6967 BCH (up from 1.86).
Also kept two new audit helpers from the operation:
scripts/scan-all-wallets-ft.mjs one-shot inventory across every
.chipnet-keys-*.json
scripts/inspect-h-utxos.mjs classifies H's UTXOs
(bch-only / ft / nft / hybrid)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
58 lines
2.2 KiB
JavaScript
58 lines
2.2 KiB
JavaScript
#!/usr/bin/env node
|
|
// Inventory FT holdings across every chipnet wallet (.chipnet-keys-*.json)
|
|
// Prints per-wallet BCH + per-category FT balances. Read-only.
|
|
import { readFileSync, readdirSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import { ElectrumNetworkProvider } from 'cashscript';
|
|
|
|
const ROOT = join(import.meta.dirname, '..');
|
|
const KEYS = readdirSync(ROOT).filter(f => /^\.chipnet-keys.*\.json$/.test(f)).sort();
|
|
|
|
const provider = new ElectrumNetworkProvider('chipnet');
|
|
|
|
const KNOWN = {};
|
|
try {
|
|
for (const p of ['ChipnetTests/.chipnet-asm-token.json',
|
|
'ChipnetTests/.chipnet-asm2-token.json',
|
|
'ChipnetTests/.chipnet-cap-token.json',
|
|
'ChipnetTests/.chipnet-t001-token.json']) {
|
|
const o = JSON.parse(readFileSync(join(ROOT, p), 'utf8'));
|
|
const cat = (o.tokenId || o.categoryId || '').toLowerCase();
|
|
if (cat) KNOWN[cat] = o.ticker || o.name || p.split('/').pop();
|
|
}
|
|
} catch {}
|
|
|
|
for (const k of KEYS) {
|
|
let j;
|
|
try { j = JSON.parse(readFileSync(join(ROOT, k), 'utf8')); } catch { continue; }
|
|
const addr = j.cashaddr || j.address || j.tokenaddr;
|
|
if (!addr) { console.log(`${k}: no address field`); continue; }
|
|
try {
|
|
const utxos = await provider.getUtxos(addr);
|
|
let bch = 0n;
|
|
const byCat = new Map();
|
|
for (const u of utxos) {
|
|
if (u.token) {
|
|
bch += BigInt(u.satoshis ?? 0);
|
|
const c = u.token.category.toLowerCase();
|
|
byCat.set(c, (byCat.get(c) ?? 0n) + BigInt(u.token.amount ?? 0));
|
|
} else {
|
|
bch += BigInt(u.satoshis ?? 0);
|
|
}
|
|
}
|
|
const bchStr = (Number(bch) / 1e8).toFixed(8);
|
|
const label = k.replace(/^\.chipnet-keys-?/, '').replace(/\.json$/, '') || '(default)';
|
|
console.log(`\n${label.padEnd(20)} ${addr.slice(0, 18)}...${addr.slice(-6)}`);
|
|
console.log(` BCH ${bchStr} (${utxos.length} UTXOs)`);
|
|
if (byCat.size === 0) {
|
|
console.log(` no FTs`);
|
|
} else {
|
|
for (const [cat, amt] of byCat) {
|
|
const name = KNOWN[cat] || cat.slice(0, 10) + '…';
|
|
console.log(` ${name.padEnd(14)} ${amt.toString()} units [${cat.slice(0, 12)}…]`);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.log(`${k}: ERROR ${e.message?.slice(0, 80)}`);
|
|
}
|
|
}
|