// 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; }