// node backfill-funding.js [--dry-run]: for every entry without `funding`, read the receive sources of its address // before received_at from the node and store them, so funded_by_operator_payee_before_entry can be answered for // entries recorded before 2026-09-15. Idempotent; never touches entries that already have funding. const path = require('path'); const L = require('./ladder'); const DATA = process.env.DATA_DIR || path.join(__dirname, 'data'); const ENTRIES = path.join(DATA, 'entries.json'); const RPC = process.env.NANO_RPC || 'http://127.0.0.1:7076'; const dry = process.argv.includes('--dry-run'); async function rpc(body) { const r = await fetch(RPC, { method: 'POST', body: JSON.stringify(body) }); return r.json(); } (async () => { const all = L.readJson(ENTRIES, {}); let n = 0; for (const [rid, byAddr] of Object.entries(all)) for (const [addr, e] of Object.entries(byAddr)) { if (e.funding) continue; e.funding = await L.fundingSources(rpc, addr, Date.parse(e.received_at)); n++; console.log('round', rid, addr.slice(0, 16), '->', e.funding.sources.length, 'source(s)', e.funding.sources.map(s => s.account.slice(0, 16) + ' ' + L.nanoStr(s.amount_raw)).join('; ')); } if (!dry && n) L.writeJsonAtomic(ENTRIES, all); console.log(dry ? 'dry run,' : 'wrote', n, 'entries'); })();