74 lines
3.4 KiB
JavaScript
74 lines
3.4 KiB
JavaScript
// Generated, do not edit. sha256:1acae16b8266effbdb3fb96f020db0a5b6e3d06834851544c79f37653dbed396
|
|
import { eventsNetByAccount } from './data/events.js';
|
|
import { syncTxProposals } from './data/proposals.js';
|
|
import { createScanLog } from './data/scan-logs.js';
|
|
import { syncAddressLinks, onchainAsset } from './data/tx-links.js';
|
|
import { listWalletAddresses, upsertWalletAddresses, accountOnchainBalance } from './data/wallet-addresses.js';
|
|
import { upsertWalletTxs } from './data/wallet-txs.js';
|
|
import { t } from './i18n/index.js';
|
|
import { addressInfo } from './price/btc-explorer.js';
|
|
import { ENUMS } from '../shared/config.js';
|
|
|
|
const nowIso = () => new Date().toISOString();
|
|
|
|
export const isOnchainSource = (source) => ENUMS.ONCHAIN_SOURCE_KIND.includes(source && source.kind);
|
|
|
|
export async function scanSource(source, report = () => {}) {
|
|
let addrRows;
|
|
let failed = 0;
|
|
if (!isOnchainSource(source)) {
|
|
throw new Error(`A source of kind '${source && source.kind}' is not scanned through the chain; `
|
|
+ `only ${ENUMS.ONCHAIN_SOURCE_KIND.join(' and ')} can be.`);
|
|
}
|
|
if (source.kind === 'address') {
|
|
const info = await addressInfo(source.value);
|
|
addrRows = [{
|
|
accountId: source.accountId, sourceId: source.id, address: source.value,
|
|
chainIndex: null, derivationIndex: null, automaticLabel: null,
|
|
balanceSats: info.balanceSats, transactionCount: info.transactionCount, lastScannedAt: nowIso(),
|
|
}];
|
|
} else {
|
|
const { scanWallet } = await import('./price/wallet-scanner.js?v=8');
|
|
const res = await scanWallet(source.value, source.scriptType, p => {
|
|
if (p.fase === 'scan') report(`${t('tracking.scanning')} ${p.chain} #${p.index}`);
|
|
});
|
|
addrRows = res.alleAdressen.map(a => ({
|
|
accountId: source.accountId, sourceId: source.id, address: a.adres,
|
|
chainIndex: a.chain, derivationIndex: a.index, automaticLabel: a.chainLabel,
|
|
balanceSats: a.saldo_satoshi, transactionCount: a.tx_aantal, lastScannedAt: nowIso(),
|
|
}));
|
|
}
|
|
await upsertWalletAddresses(addrRows);
|
|
|
|
const actief = addrRows.filter(a => (a.transactionCount || 0) > 0).map(a => a.address);
|
|
if (actief.length) {
|
|
report(t('tracking.scanningTx'));
|
|
const { scanMovements } = await import('./price/wallet-scanner.js?v=8');
|
|
const rekening = (await listWalletAddresses(source.accountId))
|
|
.filter(a => (a.transactionCount || 0) > 0).map(a => a.address);
|
|
const res = await scanMovements(actief, source.accountId, source.id, p => {
|
|
if (p.fase === 'tx') report(`${t('tracking.scanningTx')} ${p.index + 1}/${p.total}`);
|
|
}, { ownAddresses: rekening });
|
|
await upsertWalletTxs(res.rows);
|
|
await syncAddressLinks();
|
|
failed = res.failed.length;
|
|
}
|
|
const proposals = await reconcileAccount(source.accountId);
|
|
return { count: addrRows.length, failed, proposals };
|
|
}
|
|
|
|
export async function reconcileAccount(accountId) {
|
|
const onchain = await accountOnchainBalance(accountId);
|
|
const asset = await onchainAsset();
|
|
if (!asset) return 0;
|
|
const net = await eventsNetByAccount(accountId, asset.id);
|
|
const created = await syncTxProposals(accountId, asset.id);
|
|
await createScanLog({
|
|
accountId: accountId, scannedAt: nowIso(), status: 'success',
|
|
addressesFound: (await listWalletAddresses(accountId)).length,
|
|
balanceFound: onchain, proposalsCreated: created,
|
|
rawData: { onchain, events_net: net, gap: onchain - net },
|
|
});
|
|
return created;
|
|
}
|