unrip/test/quote-outcomes.test.mjs
philipp 61ba8f9208
All checks were successful
deploy / deploy (push) Successful in 32s
Expire submitted quotes using latest inventory snapshot
Proof: Fixes quote outcome expiry so no-settlement submissions age to not_filled using the latest durable inventory snapshot, even when the last actual inventory movement is older.

Assumptions: A later unchanged inventory snapshot after the quote deadline plus settlement grace is valid evidence that no matching settled inventory delta occurred in the repo-owned path.

Still fake: Not-filled remains inferred from deadline plus inventory evidence until venue-native terminal outcome events are persisted.
2026-04-10 15:31:11 +02:00

194 lines
6 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { deriveQuoteOutcomeRecords } from '../src/core/quote-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 submittedResult(quoteId, observedAt = '2026-04-02T18:13:30.000Z') {
return {
observed_at: observedAt,
payload: {
quote_id: quoteId,
command_id: `cmd-${quoteId}`,
decision_id: `decision-${quoteId}`,
status: 'submitted',
result_code: 'quote_response_ok',
},
};
}
function exactOutCommand(quoteId) {
return {
observed_at: '2026-04-02T18:13:29.000Z',
payload: {
quote_id: quoteId,
command_id: `cmd-${quoteId}`,
decision_id: `decision-${quoteId}`,
pair: `${BTC.assetId}->${EURE.assetId}`,
direction: 'eure_to_btc',
request_kind: 'exact_out',
asset_in: BTC.assetId,
asset_out: EURE.assetId,
amount_out: '21000021200021200022',
quote_output: {
amount_in: '37014',
},
min_deadline_ms: 60000,
},
};
}
function inventorySnapshot(observedAt, spendable) {
return {
observed_at: observedAt,
payload: {
inventory_id: `inventory-${observedAt}`,
synced_at: observedAt,
spendable,
},
};
}
test('quote outcome completes only when exact submitted quote delta is observed', () => {
const [outcome] = deriveQuoteOutcomeRecords({
submissions: [submittedResult('quote-settled')],
commands: [exactOutCommand('quote-settled')],
inventorySnapshots: [
inventorySnapshot('2026-04-02T18:13:00.000Z', {
[BTC.assetId]: '0',
[EURE.assetId]: '100000000000000000000',
}),
inventorySnapshot('2026-04-02T18:13:33.000Z', {
[BTC.assetId]: '37014',
[EURE.assetId]: '78999978799978799978',
}),
],
btcAsset: BTC,
eureAsset: EURE,
now: '2026-04-02T18:14:00.000Z',
});
assert.equal(outcome.outcome_status, 'completed');
assert.equal(outcome.attribution_status, 'heuristic_match');
assert.equal(outcome.attributed_inventory_delta.delta_units[BTC.assetId], '37014');
assert.equal(outcome.attributed_inventory_delta.delta_units[EURE.assetId], '-21000021200021200022');
});
test('submitted quote without settlement stays submitted before the deadline window expires', () => {
const [outcome] = deriveQuoteOutcomeRecords({
submissions: [submittedResult('quote-submitted', '2026-04-02T18:13:30.000Z')],
commands: [exactOutCommand('quote-submitted')],
inventorySnapshots: [
inventorySnapshot('2026-04-02T18:13:00.000Z', {
[BTC.assetId]: '0',
[EURE.assetId]: '100000000000000000000',
}),
],
btcAsset: BTC,
eureAsset: EURE,
now: '2026-04-02T18:13:45.000Z',
});
assert.equal(outcome.outcome_status, 'submitted');
assert.equal(outcome.attribution_status, 'unattributed');
assert.equal(outcome.attributed_inventory_delta, null);
});
test('submitted quote without settlement becomes not filled only after deadline and later inventory evidence', () => {
const [outcome] = deriveQuoteOutcomeRecords({
submissions: [submittedResult('quote-not-filled', '2026-04-02T18:13:30.000Z')],
commands: [exactOutCommand('quote-not-filled')],
inventorySnapshots: [
inventorySnapshot('2026-04-02T18:13:00.000Z', {
[BTC.assetId]: '0',
[EURE.assetId]: '100000000000000000000',
}),
inventorySnapshot('2026-04-02T18:15:40.000Z', {
[BTC.assetId]: '0',
[EURE.assetId]: '100000000000000000000',
}),
],
btcAsset: BTC,
eureAsset: EURE,
now: '2026-04-02T18:15:40.000Z',
});
assert.equal(outcome.outcome_status, 'not_filled');
assert.equal(outcome.outcome_reason, 'deadline_elapsed_without_settlement');
assert.equal(outcome.outcome_observed_at, '2026-04-02T18:15:40.000Z');
assert.equal(outcome.payload.evidence.latest_inventory_observed_at, '2026-04-02T18:15:40.000Z');
assert.equal(outcome.attributed_inventory_delta, null);
});
test('older unrelated inventory movement does not block later no-fill expiry', () => {
const [outcome] = deriveQuoteOutcomeRecords({
submissions: [submittedResult('quote-after-old-move', '2026-04-02T18:20:00.000Z')],
commands: [exactOutCommand('quote-after-old-move')],
inventorySnapshots: [
inventorySnapshot('2026-04-02T18:13:00.000Z', {
[BTC.assetId]: '0',
[EURE.assetId]: '100000000000000000000',
}),
inventorySnapshot('2026-04-02T18:13:33.000Z', {
[BTC.assetId]: '1',
[EURE.assetId]: '99999999999999999999',
}),
inventorySnapshot('2026-04-02T18:22:00.000Z', {
[BTC.assetId]: '1',
[EURE.assetId]: '99999999999999999999',
}),
],
btcAsset: BTC,
eureAsset: EURE,
now: '2026-04-02T18:22:00.000Z',
});
assert.equal(outcome.outcome_status, 'not_filled');
assert.equal(outcome.outcome_reason, 'deadline_elapsed_without_settlement');
assert.equal(outcome.payload.evidence.latest_inventory_observed_at, '2026-04-02T18:22:00.000Z');
});
test('ambiguous inventory movement is not counted as completed settlement', () => {
const outcomes = deriveQuoteOutcomeRecords({
submissions: [
submittedResult('quote-a', '2026-04-02T18:13:30.000Z'),
submittedResult('quote-b', '2026-04-02T18:13:31.000Z'),
],
commands: [
exactOutCommand('quote-a'),
exactOutCommand('quote-b'),
],
inventorySnapshots: [
inventorySnapshot('2026-04-02T18:13:00.000Z', {
[BTC.assetId]: '0',
[EURE.assetId]: '100000000000000000000',
}),
inventorySnapshot('2026-04-02T18:13:33.000Z', {
[BTC.assetId]: '37014',
[EURE.assetId]: '78999978799978799978',
}),
],
btcAsset: BTC,
eureAsset: EURE,
now: '2026-04-02T18:14:00.000Z',
});
assert.deepEqual(
outcomes.map((entry) => entry.outcome_status),
['awaiting_outcome', 'awaiting_outcome'],
);
assert.deepEqual(
outcomes.map((entry) => entry.attribution_status),
['ambiguous', 'ambiguous'],
);
});