const DEFAULT_ATTRIBUTION_WINDOW_MS = 10 * 60 * 1000; const DEFAULT_SETTLEMENT_GRACE_MS = 60 * 1000; export const REQUEST_TERMINAL_SETTLEMENT_ATTRIBUTION_STATUSES = new Set([ 'linked_settlement', 'heuristic_match', ]); export function deriveIntentRequestOutcomeRecords({ preflights = [], submissions = [], inventorySnapshots = [], btcAsset, eureAsset, now = Date.now(), attributionWindowMs = DEFAULT_ATTRIBUTION_WINDOW_MS, settlementGraceMs = DEFAULT_SETTLEMENT_GRACE_MS, } = {}) { const preflightsByRequest = new Map( preflights .map(normalizePreflight) .filter((entry) => entry?.request_id) .map((entry) => [entry.request_id, entry]), ); const expectedDeltasByRequest = new Map(); for (const preflight of preflightsByRequest.values()) { const expectedDelta = buildExpectedRequestDelta(preflight, null); if (expectedDelta) expectedDeltasByRequest.set(preflight.request_id, expectedDelta); } const activeAssetIds = uniqueAssetIds([ ...expectedDeltasByRequest.values(), Object.fromEntries([btcAsset?.assetId, eureAsset?.assetId].filter(Boolean).map((assetId) => [assetId, 0n])), ]); const latestSubmissionByRequest = new Map(); for (const submission of submissions.map(normalizeSubmission).filter(Boolean)) { if (!submission.request_id) continue; const previous = latestSubmissionByRequest.get(submission.request_id); if (!previous || timestampValue(submission.submitted_at) >= timestampValue(previous.submitted_at)) { latestSubmissionByRequest.set(submission.request_id, submission); } } const inventoryDeltas = deriveInventoryDeltas({ inventorySnapshots, activeAssetIds, }); const latestInventoryAt = latestSnapshotTimestamp(inventorySnapshots); return [...preflightsByRequest.values()] .map((preflight) => deriveOneOutcome({ preflight, submission: latestSubmissionByRequest.get(preflight.request_id) || null, inventoryDeltas, latestInventoryAt, now, attributionWindowMs, settlementGraceMs, })) .filter(Boolean); } export function deriveInventoryDeltas({ inventorySnapshots = [], activeAssetIds = [] } = {}) { const sorted = inventorySnapshots .map(normalizeInventorySnapshot) .filter((entry) => entry?.observed_at) .sort((left, right) => timestampValue(left.observed_at) - timestampValue(right.observed_at)); const deltas = []; for (let index = 1; index < sorted.length; index += 1) { const previous = sorted[index - 1]; const current = sorted[index]; const deltaUnits = {}; let changed = false; for (const assetId of activeAssetIds) { const delta = safeBigInt(current.spendable?.[assetId]) - safeBigInt(previous.spendable?.[assetId]); deltaUnits[assetId] = delta.toString(); if (delta !== 0n) changed = true; } if (!changed) continue; deltas.push({ movement_id: `${previous.observed_at}->${current.observed_at}`, observed_at: current.observed_at, previous_observed_at: previous.observed_at, inventory_id: current.inventory_id, previous_inventory_id: previous.inventory_id, delta_units: deltaUnits, }); } return deltas; } function deriveOneOutcome({ preflight, submission, inventoryDeltas, latestInventoryAt, now, attributionWindowMs, settlementGraceMs, }) { if (!submission) { return baseOutcomeRecord({ preflight, submission: null, outcome_status: preflight.state === 'draft' ? 'draft' : 'blocked', outcome_observed_at: preflight.created_at, outcome_source: 'request_preflight', outcome_reason: preflight.reason_code || 'preflight_recorded', attribution_status: 'unattributed', attribution_method: null, attributed_inventory_delta: null, evidence: { preflight_state: preflight.state }, }); } if (['failed', 'blocked'].includes(submission.status)) { return baseOutcomeRecord({ preflight, submission, outcome_status: submission.status, outcome_observed_at: submission.submitted_at, outcome_source: 'request_submission_result', outcome_reason: submission.result_code || submission.status, attribution_status: 'unattributed', attribution_method: null, attributed_inventory_delta: null, evidence: { relay_status: submission.relay_status || null }, }); } const expectedDelta = buildExpectedRequestDelta(preflight, submission); const matches = expectedDelta ? inventoryDeltas.filter((movement) => movementMatchesExpectedDelta({ movement, expectedDelta, submittedAt: submission.submitted_at, attributionWindowMs, })) : []; if (matches.length === 1) { const movement = matches[0]; return baseOutcomeRecord({ preflight, submission, outcome_status: 'completed', outcome_observed_at: movement.observed_at, outcome_source: 'intent_inventory_spendable_delta', outcome_reason: 'matched_inventory_delta', attribution_status: 'heuristic_match', attribution_method: 'exact_asset_delta_within_window', attributed_inventory_delta: { inventory_id: movement.inventory_id, previous_inventory_id: movement.previous_inventory_id, observed_at: movement.observed_at, previous_observed_at: movement.previous_observed_at, delta_units: movement.delta_units, attribution_window_ms: attributionWindowMs, uncertainty: 'Matched by exact asset-unit delta after request submission; no venue-native fill id is linked.', }, evidence: { settlement_movement_id: movement.movement_id, settlement_source: 'intent_inventory_snapshots', relay_status: submission.relay_status || null, }, }); } if (matches.length > 1) { return baseOutcomeRecord({ preflight, submission, outcome_status: 'awaiting_settlement', outcome_observed_at: submission.submitted_at, outcome_source: 'request_submission_and_inventory_snapshots', outcome_reason: 'ambiguous_inventory_delta_match', attribution_status: 'ambiguous', attribution_method: null, attributed_inventory_delta: null, evidence: { candidate_movement_count: matches.length, candidate_movement_ids: matches.map((entry) => entry.movement_id), relay_status: submission.relay_status || null, }, }); } if (submission.relay_status === 'SETTLED' && hasFreshInventoryAfterStatusCheck({ submission, latestInventoryAt })) { return baseOutcomeRecord({ preflight, submission, outcome_status: 'failed', outcome_observed_at: latestInventoryAt || submission.status_checked_at || submission.submitted_at, outcome_source: 'solver_relay_status_and_inventory_snapshots', outcome_reason: 'relay_settled_without_expected_inventory_delta', attribution_status: 'unattributed', attribution_method: null, attributed_inventory_delta: null, evidence: { relay_status: submission.relay_status, relay_status_response: submission.relay_status_response, latest_inventory_observed_at: latestInventoryAt, uncertainty: 'Relay reported settlement, but durable inventory did not show the expected source decrease and destination increase.', }, }); } if (submission.relay_status === 'NOT_FOUND_OR_NOT_VALID') { return baseOutcomeRecord({ preflight, submission, outcome_status: 'not_filled', outcome_observed_at: submission.status_checked_at || submission.submitted_at, outcome_source: 'solver_relay_get_status', outcome_reason: 'relay_not_found_or_not_valid', attribution_status: 'unattributed', attribution_method: null, attributed_inventory_delta: null, evidence: { relay_status: submission.relay_status, relay_status_response: submission.relay_status_response, }, }); } const expiredWindow = getExpiredSettlementWindow({ submission, preflight, latestInventoryAt, now, settlementGraceMs, }); if (expiredWindow) { return baseOutcomeRecord({ preflight, submission, outcome_status: 'not_filled', outcome_observed_at: expiredWindow.latestInventoryAt || expiredWindow.expiresAt || submission.submitted_at, outcome_source: 'request_deadline_and_inventory_snapshots', outcome_reason: 'deadline_elapsed_without_settlement', attribution_status: 'unattributed', attribution_method: null, attributed_inventory_delta: null, evidence: { deadline_at: preflight.deadline_at || null, settlement_grace_ms: settlementGraceMs, settlement_window_expired_at: expiredWindow.expiresAt, latest_inventory_observed_at: expiredWindow.latestInventoryAt, relay_status: submission.relay_status || null, }, }); } return baseOutcomeRecord({ preflight, submission, outcome_status: 'awaiting_settlement', outcome_observed_at: submission.submitted_at, outcome_source: 'request_submission_result', outcome_reason: submission.relay_status === 'SETTLED' ? 'relay_settled_but_inventory_delta_missing' : 'accepted_by_relay_without_settlement', attribution_status: 'unattributed', attribution_method: null, attributed_inventory_delta: null, evidence: { relay_status: submission.relay_status || null, relay_status_response: submission.relay_status_response || null, uncertainty: 'Relay acceptance or status is not counted as completed until inventory movement is linked.', }, }); } function buildExpectedRequestDelta(preflight, submission) { const destinationAmount = submission?.destination_amount_units || preflight?.destination_amount_units || preflight?.selected_quote?.amount_out || preflight?.quoted_destination_amount_units; if (!preflight?.source_asset_id || !preflight?.destination_asset_id) return null; if (!preflight?.source_amount_units || !destinationAmount) return null; return { [preflight.source_asset_id]: -safeBigInt(preflight.source_amount_units), [preflight.destination_asset_id]: safeBigInt(destinationAmount), }; } function baseOutcomeRecord({ preflight, submission, outcome_status, outcome_observed_at, outcome_source, outcome_reason, attribution_status, attribution_method, attributed_inventory_delta, evidence, }) { const payload = { request_id: preflight.request_id, idempotency_key: preflight.idempotency_key, submission_id: submission?.submission_id || null, intent_hash: submission?.intent_hash || null, source_asset_id: preflight.source_asset_id, source_symbol: preflight.source_symbol || null, destination_asset_id: preflight.destination_asset_id, destination_symbol: preflight.destination_symbol || null, source_amount_units: preflight.source_amount_units, destination_amount_units: submission?.destination_amount_units || preflight.destination_amount_units || null, notional: preflight.notional || null, notional_asset_id: preflight.notional_asset_id || null, notional_symbol: preflight.notional_symbol || null, min_destination_amount_units: preflight.min_destination_amount_units, quote_hash: submission?.quote_hash || preflight.selected_quote?.quote_hash || null, submitted_at: submission?.submitted_at || null, deadline_at: preflight.deadline_at || null, outcome_status, outcome_observed_at, outcome_source, outcome_reason, attribution_status, attribution_method, attributed_inventory_delta, evidence, }; return { request_id: preflight.request_id, idempotency_key: preflight.idempotency_key, submission_id: submission?.submission_id || null, intent_hash: submission?.intent_hash || null, submission_status: submission?.status || null, relay_status: submission?.relay_status || null, submitted_at: submission?.submitted_at || null, outcome_status, outcome_observed_at, outcome_source, outcome_reason, attribution_status, attribution_method, attributed_inventory_delta, payload, }; } function movementMatchesExpectedDelta({ movement, expectedDelta, submittedAt, attributionWindowMs, }) { const submittedTs = timestampValue(submittedAt); const movementTs = timestampValue(movement.observed_at); if (!Number.isFinite(submittedTs) || !Number.isFinite(movementTs)) return false; if (movementTs < submittedTs) return false; if (movementTs - submittedTs > attributionWindowMs) return false; for (const [assetId, expected] of Object.entries(expectedDelta)) { if (safeBigInt(movement.delta_units?.[assetId]) !== expected) return false; } for (const [assetId, actual] of Object.entries(movement.delta_units || {})) { if (Object.prototype.hasOwnProperty.call(expectedDelta, assetId)) continue; if (safeBigInt(actual) !== 0n) return false; } return true; } function hasFreshInventoryAfterStatusCheck({ submission, latestInventoryAt }) { const statusCheckedTs = timestampValue(submission.status_checked_at || submission.submitted_at); const latestInventoryTs = timestampValue(latestInventoryAt); return Number.isFinite(statusCheckedTs) && Number.isFinite(latestInventoryTs) && latestInventoryTs >= statusCheckedTs; } function getExpiredSettlementWindow({ submission, preflight, latestInventoryAt, now, settlementGraceMs, }) { const submittedTs = timestampValue(submission.submitted_at); if (!Number.isFinite(submittedTs)) return null; const deadlineTs = timestampValue(preflight.deadline_at); const fallbackDeadlineMs = Number(preflight.min_deadline_ms || 60_000); const expiresAt = Number.isFinite(deadlineTs) ? deadlineTs + settlementGraceMs : submittedTs + (Number.isFinite(fallbackDeadlineMs) ? fallbackDeadlineMs : 60_000) + settlementGraceMs; const nowTs = typeof now === 'number' ? now : timestampValue(now); const latestInventoryTs = timestampValue(latestInventoryAt); if ( Number.isFinite(nowTs) && nowTs >= expiresAt && Number.isFinite(latestInventoryTs) && latestInventoryTs >= expiresAt ) { return { expiresAt: new Date(expiresAt).toISOString(), latestInventoryAt: toIsoTimestamp(latestInventoryAt), }; } return null; } function normalizePreflight(entry) { const payload = payloadOf(entry); if (!payload) return null; return { request_id: payload.request_id || entry?.request_id || null, idempotency_key: payload.idempotency_key || entry?.idempotency_key || null, state: payload.state || null, reason_code: payload.reason_code || null, source_asset_id: payload.source_asset_id || null, source_symbol: payload.source_symbol || null, destination_asset_id: payload.destination_asset_id || null, destination_symbol: payload.destination_symbol || null, source_amount_units: payload.source_amount_units || null, destination_amount_units: payload.destination_amount_units || null, notional: payload.notional || null, notional_asset_id: payload.notional_asset_id || null, notional_symbol: payload.notional_symbol || null, min_destination_amount_units: payload.min_destination_amount_units || null, quoted_destination_amount_units: payload.quoted_destination_amount_units || null, selected_quote: payload.selected_quote || null, min_deadline_ms: payload.min_deadline_ms || null, deadline_at: payload.deadline_at || null, created_at: toIsoTimestamp( payload.created_at || entry?.observed_at || entry?.ingested_at, ), }; } function normalizeSubmission(entry) { const payload = payloadOf(entry); if (!payload) return null; return { request_id: payload.request_id || entry?.request_id || null, idempotency_key: payload.idempotency_key || entry?.idempotency_key || null, submission_id: payload.submission_id || null, status: payload.status || null, result_code: payload.result_code || null, quote_hash: payload.quote_hash || null, intent_hash: payload.intent_hash || null, destination_amount_units: payload.destination_amount_units || null, submitted_at: toIsoTimestamp( payload.submitted_at || entry?.observed_at || entry?.ingested_at, ), relay_status: payload.relay_status || null, relay_status_response: payload.relay_status_response || null, status_checked_at: payload.status_checked_at || null, }; } function normalizeInventorySnapshot(entry) { const payload = payloadOf(entry); if (!payload?.spendable) return null; return { inventory_id: payload.inventory_id || null, observed_at: toIsoTimestamp( entry?.observed_at || entry?.ingested_at || payload.observed_at || payload.synced_at, ), spendable: payload.spendable || {}, }; } function latestSnapshotTimestamp(inventorySnapshots) { const timestamps = inventorySnapshots .map((entry) => normalizeInventorySnapshot(entry)?.observed_at) .filter(Boolean) .sort((left, right) => timestampValue(right) - timestampValue(left)); return timestamps[0] || null; } function payloadOf(entry) { if (!entry) return null; return entry.payload || entry; } function uniqueAssetIds(deltaRecords = []) { const ids = new Set(); for (const record of deltaRecords || []) { for (const assetId of Object.keys(record || {})) { if (assetId) ids.add(assetId); } } return [...ids]; } function safeBigInt(value) { if (value == null || value === '') return 0n; return BigInt(String(value)); } function toIsoTimestamp(value) { if (!value) return null; const date = new Date(value); return Number.isNaN(date.getTime()) ? null : date.toISOString(); } function timestampValue(value) { const parsed = Date.parse(value || ''); return Number.isFinite(parsed) ? parsed : NaN; }