Some checks failed
deploy / deploy (push) Failing after 43s
Proof: Pair-native trade semantics and multi-asset outcome truth; strategy, request preflight, outcome attribution, valuation visibility, dashboard labels, alerts, and ops watch paths now use DB pair/asset/route metadata with nBTC/EURe compatibility and nBTC/USDC regressions covered. Assumptions: Postgres asset, pair, strategy config, and price route rows remain canonical; supported reference adapters remain BTC/EUR and BTC/USDC; deployment is push-driven through the existing Forgejo workflow. Still fake: Arbitrary multi-hop valuation, new execution venues, fee-complete realized PnL, venue-native terminal fill ingestion, and autonomous optimization remain unbuilt.
232 lines
6.9 KiB
JavaScript
232 lines
6.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,
|
|
};
|
|
const USDC = {
|
|
assetId: 'nep141:usdc.omft.near',
|
|
symbol: 'USDC',
|
|
decimals: 6,
|
|
};
|
|
|
|
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');
|
|
});
|
|
|
|
test('completed BTC/USDC request uses preflight source and destination assets', () => {
|
|
const [record] = outcomes({
|
|
preflights: [preflight({
|
|
source_asset_id: USDC.assetId,
|
|
source_symbol: 'USDC',
|
|
destination_asset_id: BTC.assetId,
|
|
destination_symbol: 'BTC',
|
|
source_amount_units: '10000000',
|
|
destination_amount_units: '20000',
|
|
quoted_destination_amount_units: '20000',
|
|
notional: '10',
|
|
notional_asset_id: USDC.assetId,
|
|
notional_symbol: 'USDC',
|
|
})],
|
|
submissions: [submission({ destination_amount_units: '20000' })],
|
|
inventorySnapshots: [
|
|
{
|
|
inventory_id: 'inventory-before-usdc',
|
|
observed_at: '2026-04-12T10:00:00.000Z',
|
|
spendable: {
|
|
[USDC.assetId]: '10000000',
|
|
[BTC.assetId]: '0',
|
|
[EURE.assetId]: '1',
|
|
},
|
|
},
|
|
{
|
|
inventory_id: 'inventory-after-usdc',
|
|
observed_at: '2026-04-12T10:00:15.000Z',
|
|
spendable: {
|
|
[USDC.assetId]: '0',
|
|
[BTC.assetId]: '20000',
|
|
[EURE.assetId]: '1',
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
assert.equal(record.outcome_status, 'completed');
|
|
assert.equal(record.payload.notional_symbol, 'USDC');
|
|
assert.deepEqual(record.attributed_inventory_delta.delta_units, {
|
|
[BTC.assetId]: '20000',
|
|
[EURE.assetId]: '0',
|
|
[USDC.assetId]: '-10000000',
|
|
});
|
|
});
|