import test from 'node:test'; import assert from 'node:assert/strict'; import { buildFundingVisibility, correlateFundingObservation, hasFundingObservationChanged, } from '../src/core/funding-observations.mjs'; import { buildInventorySnapshot } from '../src/core/inventory.mjs'; import { routeHistoryRecord } from '../src/core/history-records.mjs'; test('pre-credit funding visibility remains non-spendable', () => { const observation = correlateFundingObservation({ accountId: 'solver.near', assetId: 'nep141:btc.omft.near', chain: 'btc:mainnet', fundingHandle: 'bc1qexample', source: 'btc_mempool_space', txHash: 'btc-tx-1', amount: '1500', confirmations: 0, observedAt: '2026-04-03T08:00:00.000Z', }); const inventory = buildInventorySnapshot({ accountId: 'solver.near', balances: { 'nep141:btc.omft.near': '1000', }, recentDeposits: [], trackedWithdrawals: [], assetRegistry: new Map([ ['nep141:btc.omft.near', { decimals: 8 }], ]), observedAt: '2026-04-03T08:01:00.000Z', }); const visibility = buildFundingVisibility([observation], { now: '2026-04-03T08:01:00.000Z', }); assert.equal(observation.status, 'SEEN_UNCONFIRMED'); assert.equal(inventory.spendable['nep141:btc.omft.near'], '1000'); assert.equal(visibility.pre_credit_inbound['nep141:btc.omft.near'], '1500'); assert.equal(visibility.by_handle.bc1qexample.observations[0].spendable, false); }); test('funding observation correlates to later credit without losing tx hash', () => { const seen = correlateFundingObservation({ accountId: 'solver.near', assetId: 'nep141:btc.omft.near', chain: 'btc:mainnet', fundingHandle: 'bc1qexample', source: 'btc_mempool_space', txHash: 'btc-tx-1', amount: '1500', confirmations: 2, observedAt: '2026-04-03T08:00:00.000Z', }); const credited = correlateFundingObservation({ existing: seen, accountId: 'solver.near', assetId: 'nep141:btc.omft.near', chain: 'btc:mainnet', fundingHandle: 'bc1qexample', source: 'btc_mempool_space', txHash: 'btc-tx-1', amount: '1500', confirmations: 3, observedAt: '2026-04-03T08:10:00.000Z', bridgeDeposit: { tx_hash: 'btc-tx-1', status: 'COMPLETED', }, }); assert.equal(credited.status, 'CREDITED'); assert.equal(credited.tx_hash, 'btc-tx-1'); assert.equal(credited.bridge_deposit_tx_hash, 'btc-tx-1'); assert.equal(credited.funding_observation_id, seen.funding_observation_id); assert.equal(credited.credited_at, '2026-04-03T08:10:00.000Z'); }); test('funding observation republishes when bridge metadata changes credited BTC wrapper', () => { const previous = correlateFundingObservation({ accountId: 'solver.near', assetId: 'nep141:nbtc.bridge.near', chain: 'btc:mainnet', fundingHandle: 'bc1qexample', source: 'btc_mempool_space', txHash: 'btc-tx-1', amount: '1500', confirmations: 1, observedAt: '2026-05-07T13:00:00.000Z', }); const next = { ...previous, asset_id: 'nep141:btc.omft.near', }; assert.equal(hasFundingObservationChanged(previous, next), true); }); test('history writer routes funding observations into the funding table family', () => { const routed = routeHistoryRecord({ topic: 'ops.funding_observation', event: { event_id: 'evt-funding-1', event_type: 'funding_observation', venue: 'near-intents', schema_version: 1, ingested_at: '2026-04-03T08:00:00.000Z', payload: { funding_observation_id: 'funding-1', account_id: 'solver.near', asset_id: 'nep141:btc.omft.near', chain: 'btc:mainnet', funding_handle: 'bc1qexample', source: 'btc_mempool_space', tx_hash: 'btc-tx-1', status: 'SEEN_CONFIRMED', amount: '1500', confirmations: 2, first_seen_at: '2026-04-03T08:00:00.000Z', last_seen_at: '2026-04-03T08:05:00.000Z', }, }, }); assert.equal(routed.table, 'funding_observations'); assert.equal(routed.record.decision_key, 'funding-1'); });