import crypto from 'node:crypto'; import { mapToSortedObject } from './assets.mjs'; export function buildInventorySnapshot({ accountId, balances, recentDeposits, trackedWithdrawals, assetRegistry, observedAt = new Date().toISOString(), }) { const spendable = {}; for (const assetId of assetRegistry.keys()) { spendable[assetId] = String(balances[assetId] || '0'); } const pendingInbound = {}; const pendingOutbound = {}; const depositRecords = []; const withdrawalRecords = []; for (const [assetId] of assetRegistry) { pendingInbound[assetId] = '0'; pendingOutbound[assetId] = '0'; } for (const deposit of recentDeposits) { depositRecords.push(deposit); if (deposit.status === 'PENDING') { const assetId = deposit.asset_id; pendingInbound[assetId] = addStrings(pendingInbound[assetId], deposit.amount); } } for (const withdrawal of trackedWithdrawals) { withdrawalRecords.push(withdrawal); if (withdrawal.status && withdrawal.status !== 'COMPLETED' && withdrawal.asset_id) { pendingOutbound[withdrawal.asset_id] = addStrings( pendingOutbound[withdrawal.asset_id], withdrawal.amount || '0', ); } } return { inventory_id: crypto.randomUUID(), account_id: accountId, synced_at: observedAt, spendable: mapToSortedObject(spendable), pending_inbound: mapToSortedObject(pendingInbound), pending_outbound: mapToSortedObject(pendingOutbound), deposits: depositRecords, withdrawals: withdrawalRecords, reconciliation_status: hasPending(pendingInbound) || hasPending(pendingOutbound) ? 'pending_transfers' : 'ok', }; } function addStrings(left, right) { return (BigInt(left || '0') + BigInt(right || '0')).toString(); } function hasPending(values) { return Object.values(values).some((value) => BigInt(value || '0') > 0n); }