All checks were successful
deploy / deploy (push) Successful in 33s
Proof: Adds repo-owned EURe-to-BTC request preflight, signing, gated live submission, durable request/result/outcome persistence, dashboard request lifecycle rows, and tests proving submitted/relay accepted are not completed without inventory movement. Assumptions: The NEAR Intents solver relay quote, publish_intent, and get_status JSON-RPC methods accept signed raw_ed25519 token_diff payloads with quote_hashes; live validation remains bounded to 5 EUR per attempt, at most five attempts, and 200 bps slippage. Still fake: Venue-native terminal fill linkage and fee-complete realized PnL are still unavailable; request completion is attributed from durable inventory deltas unless the venue later exposes a linked settlement id.
161 lines
4.9 KiB
JavaScript
161 lines
4.9 KiB
JavaScript
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('request submitted or relay accepted does not become completed without inventory delta', () => {
|
|
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, 'awaiting_settlement');
|
|
assert.equal(record.outcome_reason, 'relay_settled_but_inventory_delta_missing');
|
|
assert.equal(record.attribution_status, 'unattributed');
|
|
assert.equal(record.attributed_inventory_delta, null);
|
|
assert.notEqual(record.outcome_status, 'completed');
|
|
});
|
|
|
|
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');
|
|
});
|