import test from 'node:test'; import assert from 'node:assert/strict'; import { deriveIntentRequestOutcomeRecords } from '../src/core/intent-request-outcomes.mjs'; const BTC = { assetId: 'nep141:btc.omft.near', symbol: 'BTC', decimals: 8, }; const EURE = { assetId: 'nep141:eure.omft.near', symbol: 'EURe', decimals: 18, }; function preflight(overrides = {}) { return { request_id: 'request-1', idempotency_key: 'idem-1', state: 'draft', reason_code: 'quote_available', source_asset_id: EURE.assetId, destination_asset_id: BTC.assetId, source_amount_units: '5000000000000000000', min_destination_amount_units: '9800', quoted_destination_amount_units: '10000', selected_quote: { quote_hash: 'quote-hash-1', amount_out: '10000', }, min_deadline_ms: 60000, deadline_at: '2026-04-12T10:01:00.000Z', created_at: '2026-04-12T10:00:00.000Z', ...overrides, }; } function submission(overrides = {}) { return { request_id: 'request-1', idempotency_key: 'idem-1', submission_id: 'submission-1', status: 'accepted_by_relay', result_code: 'publish_intent_accepted', quote_hash: 'quote-hash-1', intent_hash: 'intent-hash-1', destination_amount_units: '10000', submitted_at: '2026-04-12T10:00:10.000Z', relay_status: 'PENDING', ...overrides, }; } function outcomes({ preflights = [preflight()], submissions = [], inventorySnapshots = [], now = '2026-04-12T10:00:30.000Z' } = {}) { return deriveIntentRequestOutcomeRecords({ preflights, submissions, inventorySnapshots, btcAsset: BTC, eureAsset: EURE, now: Date.parse(now), }); } test('relay settled without expected inventory delta is failed, not completed', () => { const [record] = outcomes({ submissions: [submission({ relay_status: 'SETTLED' })], inventorySnapshots: [ { observed_at: '2026-04-12T10:00:00.000Z', spendable: { [EURE.assetId]: '5000000000000000000', [BTC.assetId]: '0', }, }, { observed_at: '2026-04-12T10:00:20.000Z', spendable: { [EURE.assetId]: '5000000000000000000', [BTC.assetId]: '0', }, }, ], }); assert.equal(record.submission_status, 'accepted_by_relay'); assert.equal(record.relay_status, 'SETTLED'); assert.equal(record.outcome_status, 'failed'); assert.equal(record.outcome_reason, 'relay_settled_without_expected_inventory_delta'); assert.equal(record.attribution_status, 'unattributed'); assert.equal(record.attributed_inventory_delta, null); assert.notEqual(record.outcome_status, 'completed'); assert.notEqual(record.outcome_status, 'not_filled'); }); test('accepted pending request without inventory delta remains awaiting settlement', () => { const [record] = outcomes({ submissions: [submission({ relay_status: 'PENDING' })], inventorySnapshots: [ { observed_at: '2026-04-12T10:00:20.000Z', spendable: { [EURE.assetId]: '5000000000000000000', [BTC.assetId]: '0', }, }, ], }); assert.equal(record.outcome_status, 'awaiting_settlement'); assert.equal(record.outcome_reason, 'accepted_by_relay_without_settlement'); assert.equal(record.attributed_inventory_delta, null); }); test('completed request requires exact EURe decrease and BTC increase after submission', () => { const [record] = outcomes({ submissions: [submission()], inventorySnapshots: [ { inventory_id: 'inventory-before', observed_at: '2026-04-12T10:00:00.000Z', spendable: { [EURE.assetId]: '5000000000000000000', [BTC.assetId]: '0', }, }, { inventory_id: 'inventory-after', observed_at: '2026-04-12T10:00:15.000Z', spendable: { [EURE.assetId]: '0', [BTC.assetId]: '10000', }, }, ], }); assert.equal(record.outcome_status, 'completed'); assert.equal(record.outcome_source, 'intent_inventory_spendable_delta'); assert.equal(record.outcome_reason, 'matched_inventory_delta'); assert.equal(record.attribution_status, 'heuristic_match'); assert.equal(record.attributed_inventory_delta.inventory_id, 'inventory-after'); assert.deepEqual(record.attributed_inventory_delta.delta_units, { [BTC.assetId]: '10000', [EURE.assetId]: '-5000000000000000000', }); }); test('accepted request becomes not filled only after deadline grace and fresh inventory evidence', () => { const [record] = outcomes({ submissions: [submission()], inventorySnapshots: [ { observed_at: '2026-04-12T10:02:01.000Z', spendable: { [EURE.assetId]: '5000000000000000000', [BTC.assetId]: '0', }, }, ], now: '2026-04-12T10:02:01.000Z', }); assert.equal(record.outcome_status, 'not_filled'); assert.equal(record.outcome_reason, 'deadline_elapsed_without_settlement'); assert.equal(record.attribution_status, 'unattributed'); assert.equal(record.attributed_inventory_delta, null); }); test('blocked preflight remains blocked and is distinct from request rejection or completion', () => { const [record] = outcomes({ preflights: [preflight({ state: 'blocked', reason_code: 'insufficient_spendable_eure' })], }); assert.equal(record.outcome_status, 'blocked'); assert.equal(record.outcome_reason, 'insufficient_spendable_eure'); assert.equal(record.submission_status, null); assert.notEqual(record.outcome_status, 'completed'); assert.notEqual(record.outcome_status, 'rejected'); });