unrip/test/strategy.test.mjs
philipp 41b9ec680b
Some checks failed
deploy / deploy (push) Failing after 1m35s
Implement funded NEAR Intents trade loop
Proof: first non-mocked tradeable loop for one pair using funded NEAR Intents inventory, Kafka, and PostgreSQL.

Assumptions: solver-side execution is performed by signed token_diff quote responses over the Solver Relay; EURe is treated as 1:1 with EUR; k3s runtime uses unrip-dev.near as the named signer account.

Still fake: signer key is not yet registered on intents.near, strategy and executor remain disarmed by default, and no live mainnet quote response has been submitted from this repo yet.
2026-04-02 10:01:15 +02:00

153 lines
4.2 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { evaluateTradeOpportunity } from '../src/core/strategy.mjs';
function makeConfig() {
const tradingBtc = {
assetId: 'nep141:btc.omft.near',
symbol: 'BTC',
decimals: 8,
chain: 'btc:mainnet',
};
const tradingEure = {
assetId: 'nep141:eure.omft.near',
symbol: 'EURe',
decimals: 18,
chain: 'eth:100',
};
return {
tradingBtc,
tradingEure,
activePair: `${tradingBtc.assetId}->${tradingEure.assetId}`,
assetRegistry: new Map([
[tradingBtc.assetId, tradingBtc],
[tradingEure.assetId, tradingEure],
]),
strategyGrossThresholdPct: 2,
strategyMaxNotionalEure: 5,
strategyPriceMaxAgeMs: 30_000,
strategyInventoryMaxAgeMs: 30_000,
};
}
function makePriceEvent(overrides = {}) {
return {
ingested_at: new Date('2026-04-02T10:00:00.000Z').toISOString(),
payload: {
price_id: 'price-1',
pair: 'nep141:btc.omft.near->nep141:eure.omft.near',
eur_per_btc: '100000.00000000',
eure_per_btc: '100000.00000000',
btc_per_eur: '0.000010000000',
btc_per_eure: '0.000010000000',
...overrides,
},
};
}
function makeInventoryEvent(overrides = {}) {
return {
ingested_at: new Date('2026-04-02T10:00:00.000Z').toISOString(),
payload: {
inventory_id: 'inventory-1',
spendable: {
'nep141:btc.omft.near': '1000000',
'nep141:eure.omft.near': '10000000000000000000',
},
pending_inbound: {
'nep141:btc.omft.near': '0',
'nep141:eure.omft.near': '0',
},
...overrides,
},
};
}
test('strategy emits actionable exact-in BTC -> EURe command when armed and inventory is fresh', () => {
const config = makeConfig();
const result = evaluateTradeOpportunity({
demandEvent: {
payload: {
quote_id: 'quote-1',
pair: config.activePair,
asset_in: config.tradingBtc.assetId,
asset_out: config.tradingEure.assetId,
request_kind: 'exact_in',
amount_in: '5000',
min_deadline_ms: '60000',
},
},
priceEvent: makePriceEvent(),
inventoryEvent: makeInventoryEvent(),
config,
armed: true,
now: Date.parse('2026-04-02T10:00:05.000Z'),
});
assert.equal(result.decision.decision, 'actionable');
assert.equal(result.decision.decision_reason, 'actionable');
assert.ok(result.command);
assert.equal(result.command.quote_output.amount_out, '4900000000000000000');
});
test('strategy blocks when pending deposit exists but credited inventory is insufficient', () => {
const config = makeConfig();
const result = evaluateTradeOpportunity({
demandEvent: {
payload: {
quote_id: 'quote-2',
pair: config.activePair,
asset_in: config.tradingBtc.assetId,
asset_out: config.tradingEure.assetId,
request_kind: 'exact_in',
amount_in: '5000',
min_deadline_ms: '60000',
},
},
priceEvent: makePriceEvent(),
inventoryEvent: makeInventoryEvent({
spendable: {
'nep141:btc.omft.near': '1000000',
'nep141:eure.omft.near': '1000000000000000000',
},
pending_inbound: {
'nep141:btc.omft.near': '0',
'nep141:eure.omft.near': '5000000000000000000',
},
}),
config,
armed: true,
now: Date.parse('2026-04-02T10:00:05.000Z'),
});
assert.equal(result.decision.decision, 'rejected');
assert.equal(result.decision.decision_reason, 'pending_deposit_not_credited');
assert.equal(result.command, undefined);
});
test('strategy blocks stale prices before command emission', () => {
const config = makeConfig();
const result = evaluateTradeOpportunity({
demandEvent: {
payload: {
quote_id: 'quote-3',
pair: config.activePair,
asset_in: config.tradingEure.assetId,
asset_out: config.tradingBtc.assetId,
request_kind: 'exact_out',
amount_out: '10000',
min_deadline_ms: '60000',
},
},
priceEvent: makePriceEvent(),
inventoryEvent: makeInventoryEvent(),
config,
armed: true,
now: Date.parse('2026-04-02T10:00:45.000Z'),
});
assert.equal(result.decision.decision_reason, 'stale_reference_price');
assert.equal(result.command, undefined);
});