63 lines
3.0 KiB
JavaScript
63 lines
3.0 KiB
JavaScript
// Generated, do not edit. sha256:437d88ce2721c02e69b9a2fbd8a4429ac52560b575699f0f5ce5e41e7cc24369
|
|
import { normalizeMovements, normalizeNwcMovements, nodeBalance, channelTxids } from './lightning-tracker.js';
|
|
import { upsertWalletTxs, labelChannelTxs } from '../data/wallet-txs.js';
|
|
import { recordSourceBalance } from '../data/wallet-sources.js';
|
|
|
|
export const isLightningSource = s => s?.kind === 'lnd' || s?.kind === 'nwc';
|
|
|
|
export function walletTxRows(movements, source) {
|
|
const rows = [];
|
|
let skipped = 0;
|
|
for (const m of movements || []) {
|
|
const txid = m.hash || m.ref || null;
|
|
if (!txid || !m.at) { skipped++; continue; }
|
|
const direction = m.direction === 'out' ? 'out' : 'in';
|
|
rows.push({
|
|
accountId: source.accountId, sourceId: source.id, layer: 'lightning', txid, direction,
|
|
valueSats: Math.max(0, Math.round(Number(m.sats) || 0)),
|
|
feeSats: direction === 'out' ? Math.max(0, Math.round(Number(m.fee_sats) || 0)) : null,
|
|
blockTime: m.at, blockHeight: null, address: null, kind: m.self ? 'self' : null, memo: m.memo ?? null,
|
|
});
|
|
}
|
|
return { rows, skipped };
|
|
}
|
|
|
|
const msatToSats = msat => Math.max(0, Math.floor(Number(msat || 0) / 1000));
|
|
|
|
export async function scanLightningSource(source, { tracker = null, nwcClient = null } = {}) {
|
|
const tr = tracker || { normalizeMovements, normalizeNwcMovements, nodeBalance, channelTxids };
|
|
let movements, balanceSats, kanaalTxids = [];
|
|
if (source.kind === 'lnd') {
|
|
if (!source.connectionId) throw new Error('A LND source without a connection.');
|
|
movements = await tr.normalizeMovements(source.connectionId);
|
|
balanceSats = (await tr.nodeBalance(source.connectionId)).channelLocal;
|
|
kanaalTxids = [...await tr.channelTxids(source.connectionId)];
|
|
} else if (source.kind === 'nwc') {
|
|
movements = await tr.normalizeNwcMovements(source.id);
|
|
const nwc = nwcClient || await import('./nwc.js');
|
|
balanceSats = msatToSats((await nwc.getBalance(source.id))?.balance);
|
|
} else {
|
|
throw new Error(`Not a lightning source: '${source.kind}'.`);
|
|
}
|
|
const { rows, skipped } = walletTxRows(movements, source);
|
|
if (rows.length) await upsertWalletTxs(rows);
|
|
await recordSourceBalance(source.id, balanceSats);
|
|
const channelLabels = kanaalTxids.length ? await labelChannelTxs(source.accountId, kanaalTxids) : 0;
|
|
return { count: rows.length, skipped, balanceSats, channelLabels, channelTxids: kanaalTxids };
|
|
}
|
|
|
|
export function countMovements(txs, isLinked) {
|
|
const groups = new Map();
|
|
for (const tx of txs || []) {
|
|
const key = tx.layer === 'lightning' ? `ln:${tx.accountId}:${tx.txid}` : `id:${tx.id}`;
|
|
groups.set(key, groups.get(key) || isLinked(tx));
|
|
}
|
|
return { total: groups.size, linked: [...groups.values()].filter(Boolean).length };
|
|
}
|
|
|
|
export function lightningAccountSats(sources) {
|
|
const ln = (sources || []).filter(isLightningSource);
|
|
const heeftLnd = ln.some(s => s.kind === 'lnd');
|
|
return ln.filter(s => s.kind === 'lnd' || !heeftLnd).reduce((sum, s) => sum + (Number(s.balanceSats) || 0), 0);
|
|
}
|