import test from 'node:test'; import assert from 'node:assert/strict'; import { evaluateTradeOpportunity } from '../src/core/strategy.mjs'; import { CURRENT_EURE_ASSET_ID, CURRENT_NBTC_ASSET_ID, CURRENT_USDC_ASSET_ID, GNOSIS_USDC_ASSET_ID, LEGACY_OMFT_BTC_ASSET_ID, normalizeOneClickToken, } from '../src/core/trading-config.mjs'; import { createPairStrategyConfigVersion, enableObserveOnlyPair, importSupportedAssets, loadAssetCatalogSummary, loadTradingConfig, pauseTradingPair, seedTradingConfig, setTradingPairMode, } from '../src/lib/postgres.mjs'; test('1Click token normalizer preserves live asset fields', () => { const token = normalizeOneClickToken({ assetId: CURRENT_NBTC_ASSET_ID, decimals: 8, blockchain: 'near', symbol: 'BTC', price: 80293, priceUpdatedAt: '2026-05-12T16:25:00.425Z', contractAddress: 'nbtc.bridge.near', }); assert.equal(token.assetId, CURRENT_NBTC_ASSET_ID); assert.equal(token.decimals, 8); assert.equal(token.symbol, 'BTC'); assert.equal(token.latestPrice, '80293'); assert.equal(token.priceUpdatedAt, '2026-05-12T16:25:00.425Z'); }); test('1Click token normalizer maps Gnosis assets to bridge chain id', () => { const token = normalizeOneClickToken({ assetId: GNOSIS_USDC_ASSET_ID, decimals: 6, blockchain: 'gnosis', symbol: 'USDC', price: 1, priceUpdatedAt: '2026-05-12T16:25:00.425Z', contractAddress: '0x2a22f9c3b484c3629090feed35f17ff8f88f76f0', }); assert.equal(token.blockchain, 'gnosis'); assert.equal(token.chain, 'eth:100'); }); test('supported token import is idempotent, does not enable inventory, and retires missing assets', async () => { const pool = createMemoryPool(); const first = await importSupportedAssets(pool, { fetchedAt: '2026-05-12T16:30:00.000Z', response: [ token(CURRENT_NBTC_ASSET_ID, 'BTC', 8), token(CURRENT_EURE_ASSET_ID, 'EURe', 18), ], }); assert.equal(first.added_count, 2); assert.equal(pool.assets.get(CURRENT_NBTC_ASSET_ID).enabled_for_inventory, false); assert.equal(Object.hasOwn(first, 'raw_response'), false); const second = await importSupportedAssets(pool, { fetchedAt: '2026-05-12T16:31:00.000Z', response: [ token(CURRENT_NBTC_ASSET_ID, 'BTC', 8), token(CURRENT_EURE_ASSET_ID, 'EURe', 18), ], }); assert.equal(second.added_count, 0); assert.equal(second.unchanged_count, 2); const third = await importSupportedAssets(pool, { fetchedAt: '2026-05-12T16:32:00.000Z', response: [ { ...token(CURRENT_NBTC_ASSET_ID, 'BTC', 8), price: 81000 }, ], }); assert.equal(third.updated_count, 1); assert.equal(third.retired_count, 1); assert.equal(pool.assets.get(CURRENT_EURE_ASSET_ID).supported, false); assert.equal(pool.assets.get(CURRENT_EURE_ASSET_ID).retired_at, '2026-05-12T16:32:00.000Z'); }); test('asset catalog summary omits raw token payloads from bootstrap rows', async () => { const pool = createMemoryPool(); await importSupportedAssets(pool, { fetchedAt: '2026-05-12T16:30:00.000Z', response: [{ ...token(CURRENT_NBTC_ASSET_ID, 'BTC', 8), routes: Array.from({ length: 100 }, (_, index) => ({ route: index, detail: 'not for bootstrap' })), }], }); const summary = await loadAssetCatalogSummary(pool, { limit: 250 }); const [asset] = summary.items; assert.equal(summary.counts.known, 1); assert.equal(asset.asset_id, CURRENT_NBTC_ASSET_ID); assert.equal(asset.raw_payload_available, true); assert.equal(Object.hasOwn(asset, 'raw_payload'), false); assert.equal(Object.hasOwn(asset, 'rawPayload'), false); }); test('seeded DB config preserves current nBTC/EURe pair, 49 bps edge, and legacy BTC tracking', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool, { now: '2026-05-12T16:35:00.000Z' }); await seedTradingConfig(pool, { now: '2026-05-12T16:36:00.000Z' }); const snapshot = await loadTradingConfig(pool); assert.equal(snapshot.ok, true); assert.equal(snapshot.activePair, `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`); assert.equal(snapshot.pairs.length, 2); assert.equal(snapshot.pairByKey.get(snapshot.activePair).strategyConfig.edgeBps, 49); assert.equal(snapshot.trackedAssetIds.includes(LEGACY_OMFT_BTC_ASSET_ID), true); assert.equal(snapshot.assetRegistry.get(CURRENT_USDC_ASSET_ID).chain, 'eth'); assert.equal(snapshot.trackedAssetIds.includes(CURRENT_USDC_ASSET_ID), false); assert.equal([...snapshot.makerPairKeys].some((pair) => pair.includes(LEGACY_OMFT_BTC_ASSET_ID)), false); }); test('supported-token import corrects legacy USDC Gnosis chain without inventory-enabling it', async () => { const pool = createMemoryPool(); pool.assets.set(GNOSIS_USDC_ASSET_ID, { asset_id: GNOSIS_USDC_ASSET_ID, venue: 'near-intents', symbol: 'USDC', label: 'USDC', decimals: 6, blockchain: 'gnosis', chain: 'gnosis', contract_address: '0x2a22f9c3b484c3629090feed35f17ff8f88f76f0', latest_price: '1', price_updated_at: '2026-05-12T16:25:00.425Z', supported: true, retired_at: null, enabled_for_inventory: false, role: null, withdraw_address: '', raw_payload: { source: 'legacy_test_row' }, last_supported_at: '2026-05-12T16:25:00.425Z', updated_at: '2026-05-12T16:25:00.425Z', }); await importSupportedAssets(pool, { fetchedAt: '2026-05-12T16:35:00.000Z', response: [{ assetId: GNOSIS_USDC_ASSET_ID, decimals: 6, blockchain: 'gnosis', symbol: 'USDC', price: 1, priceUpdatedAt: '2026-05-12T16:25:00.425Z', contractAddress: '0x2a22f9c3b484c3629090feed35f17ff8f88f76f0', }], }); const snapshot = await loadTradingConfig(pool); const usdc = snapshot.assetRegistry.get(GNOSIS_USDC_ASSET_ID); assert.equal(usdc.chain, 'eth:100'); assert.equal(usdc.enabledForInventory, false); }); test('missing DB pair config fails closed', async () => { const snapshot = await loadTradingConfig(createMemoryPool()); assert.equal(snapshot.ok, false); assert.equal(snapshot.blockReason, 'no_enabled_pairs'); assert.equal(snapshot.enabledPairKeys.size, 0); }); test('edge update creates a new active strategy version', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); const next = await createPairStrategyConfigVersion(pool, { pairId: `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`, edgeBps: 75, maxNotional: '42', changedBy: 'test', reason: 'test edge update', }); const snapshot = await loadTradingConfig(pool); const versions = [...pool.strategyConfigs.values()] .filter((row) => row.pair_id === `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`); assert.equal(next.version, 2); assert.equal(snapshot.pairByKey.get(`${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`).strategyConfig.edgeBps, 75); assert.equal(snapshot.pairByKey.get(`${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`).strategyConfig.maxNotional, '42'); assert.equal(versions.find((row) => row.version === 1).active, false); }); test('strategy config update rejects invalid max notional', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); await assert.rejects( createPairStrategyConfigVersion(pool, { pairId: `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`, edgeBps: 75, maxNotional: '0', }), /max_notional must be greater than zero/, ); }); test('observe-only enable does not downgrade an active trading pair', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); const pairId = `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`; const pair = await enableObserveOnlyPair(pool, { assetIn: CURRENT_NBTC_ASSET_ID, assetOut: CURRENT_EURE_ASSET_ID, changedBy: 'test', reason: 'avoid downgrade', }); const snapshot = await loadTradingConfig(pool); assert.equal(pair.pairId, pairId); assert.equal(pair.mode, 'both'); assert.equal(snapshot.pairByKey.get(pairId).makerEnabled, true); assert.equal(snapshot.pairByKey.get(pairId).takerEnabled, true); }); test('observe-only enable creates a non-trading tracked pair', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); const pair = await enableObserveOnlyPair(pool, { assetIn: LEGACY_OMFT_BTC_ASSET_ID, assetOut: CURRENT_EURE_ASSET_ID, changedBy: 'test', reason: 'watch legacy route', }); const snapshot = await loadTradingConfig(pool); assert.equal(pair.mode, 'observe_only'); assert.equal(snapshot.pairByKey.get(`${LEGACY_OMFT_BTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`).observeEnabled, true); assert.equal(snapshot.pairByKey.get(`${LEGACY_OMFT_BTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`).makerEnabled, false); assert.equal(snapshot.pairByKey.get(`${LEGACY_OMFT_BTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`).takerEnabled, false); }); test('repo seed does not re-enable pair runtime flags already stored in DB', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); const pairId = `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`; const routeId = `${pairId}:btc-eur-reference`; Object.assign(pool.pairs.get(pairId), { mode: 'observe_only', enabled: false, status: 'disabled', }); Object.assign(pool.routes.get(routeId), { enabled: false, }); await seedTradingConfig(pool); const snapshot = await loadTradingConfig(pool); const pair = snapshot.pairByKey.get(pairId); assert.equal(pair.enabled, false); assert.equal(pair.mode, 'observe_only'); assert.equal(pair.status, 'disabled'); assert.equal(pool.routes.get(routeId).enabled, false); assert.equal(pair.priceRoute, null); assert.equal(pair.makerEnabled, false); assert.equal(pair.takerEnabled, false); }); test('pair mode updates activate a directed pair without inventing a price route', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); const pairId = `${LEGACY_OMFT_BTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`; await enableObserveOnlyPair(pool, { assetIn: LEGACY_OMFT_BTC_ASSET_ID, assetOut: CURRENT_EURE_ASSET_ID, changedBy: 'test', reason: 'watch legacy route', }); const updated = await setTradingPairMode(pool, { pairId, mode: 'maker', edgeBps: 75, maxNotional: '25', changedBy: 'test', reason: 'operator activation test', }); const snapshot = await loadTradingConfig(pool); const pair = snapshot.pairByKey.get(pairId); assert.equal(updated.mode, 'maker'); assert.equal(updated.strategyConfig.edgeBps, 75); assert.equal(updated.strategyConfig.maxNotional, '25'); assert.equal(pair.enabled, true); assert.equal(pair.makerEnabled, true); assert.equal(pair.strategyConfig.edgeBps, 75); assert.equal(pair.strategyConfig.maxNotional, '25'); assert.equal(pair.canTrade, false); assert.equal(pair.blockReason, 'price_route_missing'); }); test('pair mode activation wires known BTC/USDC route and inventory tracking', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); const pairId = `${CURRENT_NBTC_ASSET_ID}->${CURRENT_USDC_ASSET_ID}`; await setTradingPairMode(pool, { pairId, mode: 'maker', edgeBps: 49, maxNotional: '150', changedBy: 'test', reason: 'operator btc usdc activation test', }); const snapshot = await loadTradingConfig(pool); const pair = snapshot.pairByKey.get(pairId); assert.equal(pair.canTrade, true); assert.equal(pair.blockReason, null); assert.equal(pair.priceRoute.source, 'btc_usdc_reference'); assert.equal(pair.priceRoute.baseAssetId, CURRENT_NBTC_ASSET_ID); assert.equal(pair.priceRoute.quoteAssetId, CURRENT_USDC_ASSET_ID); assert.equal(snapshot.assetRegistry.get(CURRENT_USDC_ASSET_ID).chain, 'eth'); assert.equal(snapshot.assetRegistry.get(CURRENT_USDC_ASSET_ID).enabledForInventory, true); assert.equal(snapshot.trackedAssetIds.includes(CURRENT_USDC_ASSET_ID), true); }); test('Gnosis USDC no longer gets the automatic BTC/USDC trading route', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); pool.assets.set(GNOSIS_USDC_ASSET_ID, { asset_id: GNOSIS_USDC_ASSET_ID, venue: 'near-intents', symbol: 'USDC', label: 'USDC', decimals: 6, blockchain: 'gnosis', chain: 'eth:100', contract_address: '0x2a22f9c3b484c3629090feed35f17ff8f88f76f0', latest_price: '1', price_updated_at: '2026-05-12T16:25:00.425Z', supported: true, retired_at: null, enabled_for_inventory: false, role: null, withdraw_address: '', raw_payload: { source: 'test' }, last_supported_at: '2026-05-12T16:25:00.425Z', updated_at: '2026-05-12T16:25:00.425Z', }); const pairId = `${CURRENT_NBTC_ASSET_ID}->${GNOSIS_USDC_ASSET_ID}`; await setTradingPairMode(pool, { pairId, mode: 'maker', edgeBps: 49, maxNotional: '150', changedBy: 'test', reason: 'operator gnosis usdc activation test', }); const snapshot = await loadTradingConfig(pool); const pair = snapshot.pairByKey.get(pairId); assert.equal(pair.canTrade, false); assert.equal(pair.blockReason, 'price_route_missing'); assert.equal(pair.priceRoute, null); }); test('pair mode activation rejects invalid initial edge config', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); await assert.rejects( setTradingPairMode(pool, { assetIn: LEGACY_OMFT_BTC_ASSET_ID, assetOut: CURRENT_EURE_ASSET_ID, mode: 'both', edgeBps: 0, }), /edge_bps must be a positive integer/, ); }); test('pair pause disables trading without deleting strategy config or seed restoring it', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); const pairId = `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`; const paused = await pauseTradingPair(pool, { pairId, changedBy: 'test', reason: 'operator pause test', }); await seedTradingConfig(pool); const snapshot = await loadTradingConfig(pool); const pair = snapshot.pairByKey.get(pairId); assert.equal(paused.status, 'disabled'); assert.equal(pair.enabled, false); assert.equal(pair.mode, 'both'); assert.equal(pair.status, 'disabled'); assert.equal(pair.strategyConfig.edgeBps, 49); assert.equal(pair.makerEnabled, false); assert.equal(pair.takerEnabled, false); }); test('pair mode activation requires both assets to be registered', async () => { const pool = createMemoryPool(); await seedTradingConfig(pool); await assert.rejects( setTradingPairMode(pool, { assetIn: CURRENT_NBTC_ASSET_ID, assetOut: 'nep141:not-imported.near', mode: 'maker', }), /asset_out is not registered/, ); }); test('strategy uses DB pair config for current pair and persists config version', async () => { const pool = createMemoryPool(); const snapshot = await seedTradingConfig(pool); const result = evaluateTradeOpportunity({ demandEvent: { payload: { quote_id: 'quote-db-1', pair: `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`, asset_in: CURRENT_NBTC_ASSET_ID, asset_out: CURRENT_EURE_ASSET_ID, request_kind: 'exact_in', amount_in: '5000', min_deadline_ms: '60000', }, }, priceEvent: priceEvent(), inventoryEvent: inventoryEvent(), config: snapshot, armed: true, now: Date.parse('2026-05-12T16:35:05.000Z'), }); assert.equal(result.decision.decision, 'actionable'); assert.equal(result.decision.edge_bps, '49'); assert.equal(result.decision.pair_config_version, '1'); assert.equal(result.command.quote_output.amount_out, '4975500000000000000'); assert.equal(result.command.pair_config_id, `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}:v1`); }); function token(assetId, symbol, decimals) { return { assetId, decimals, blockchain: symbol === 'EURe' ? 'gnosis' : 'near', symbol, price: symbol === 'EURe' ? 1.17 : 80293, priceUpdatedAt: '2026-05-12T16:25:00.425Z', contractAddress: assetId.replace(/^nep141:/, ''), }; } function priceEvent() { return { ingested_at: '2026-05-12T16:35:00.000Z', payload: { price_id: 'price-db-1', pair: `${CURRENT_NBTC_ASSET_ID}->${CURRENT_EURE_ASSET_ID}`, eur_per_btc: '100000.00000000', eure_per_btc: '100000.00000000', btc_per_eur: '0.000010000000', btc_per_eure: '0.000010000000', source_used: 'kraken', }, }; } function inventoryEvent() { return { ingested_at: '2026-05-12T16:35:00.000Z', payload: { inventory_id: 'inventory-db-1', spendable: { [CURRENT_NBTC_ASSET_ID]: '1000000', [CURRENT_EURE_ASSET_ID]: '10000000000000000000', [LEGACY_OMFT_BTC_ASSET_ID]: '0', }, pending_inbound: { [CURRENT_NBTC_ASSET_ID]: '0', [CURRENT_EURE_ASSET_ID]: '0', [LEGACY_OMFT_BTC_ASSET_ID]: '0', }, }, }; } function createMemoryPool() { return { assets: new Map(), pairs: new Map(), strategyConfigs: new Map(), routes: new Map(), importRuns: new Map(), audit: [], async query(sql, params = []) { if (/CREATE TABLE|CREATE (UNIQUE )?INDEX/i.test(sql)) return { rows: [], rowCount: 0 }; if (/SELECT \* FROM trading_assets\s*$/i.test(sql)) return rows(this.assets); if (/SELECT\s+asset_id,[\s\S]+raw_payload_available[\s\S]+FROM trading_assets/i.test(sql)) { return selectAssetCatalogRows(this, params); } if (/SELECT \*\s+FROM trading_assets\s+ORDER BY/i.test(sql)) return rows(this.assets); if (/INSERT INTO trading_assets/i.test(sql)) return insertAsset(this, params); if (/UPDATE trading_assets[\s\S]+enabled_for_inventory = true/i.test(sql)) { return enableInventoryAssets(this, params); } if (/UPDATE trading_assets/i.test(sql)) return retireAssets(this, params); if (/INSERT INTO supported_asset_import_runs/i.test(sql)) return insertImportRun(this, params); if (/SELECT \*\s+FROM supported_asset_import_runs/i.test(sql)) { return { rows: [...this.importRuns.values()].slice(-1), rowCount: this.importRuns.size ? 1 : 0 }; } if (/COUNT\(\*\)::INT AS known_count/i.test(sql)) { const assets = [...this.assets.values()]; return { rows: [{ known_count: assets.length, supported_count: assets.filter((asset) => asset.supported).length, retired_count: assets.filter((asset) => asset.retired_at || !asset.supported).length, inventory_enabled_count: assets.filter((asset) => asset.enabled_for_inventory).length, }], rowCount: 1, }; } if (/INSERT INTO trading_pairs/i.test(sql)) return insertPair(this, params, sql); if (/SELECT \*\s+FROM trading_pairs\s+WHERE pair_id = \$1/i.test(sql)) { const row = this.pairs.get(params[0]); return { rows: row ? [row] : [], rowCount: row ? 1 : 0 }; } if (/SELECT \*\s+FROM trading_pairs/i.test(sql)) return rows(this.pairs); if (/INSERT INTO pair_strategy_configs/i.test(sql)) return insertStrategyConfig(this, params); if (/SELECT \*\s+FROM pair_strategy_configs\s+WHERE active = true/i.test(sql)) { return { rows: [...this.strategyConfigs.values()].filter((row) => row.active), rowCount: 0 }; } if (/SELECT \*\s+FROM pair_strategy_configs\s+WHERE pair_id = \$1 AND active = true/i.test(sql)) { const active = [...this.strategyConfigs.values()] .filter((row) => row.pair_id === params[0] && row.active) .sort((left, right) => right.version - left.version)[0]; return { rows: active ? [active] : [], rowCount: active ? 1 : 0 }; } if (/UPDATE pair_strategy_configs SET active = false/i.test(sql)) { let count = 0; for (const row of this.strategyConfigs.values()) { if (row.pair_id === params[0] && row.active) { row.active = false; count += 1; } } return { rows: [], rowCount: count }; } if (/INSERT INTO pair_price_routes/i.test(sql)) return insertRoute(this, params, sql); if (/SELECT \*\s+FROM pair_price_routes/i.test(sql)) { return { rows: [...this.routes.values()].filter((row) => row.enabled), rowCount: 0 }; } if (/INSERT INTO pair_config_audit_log/i.test(sql)) { this.audit.push(params); return { rows: [], rowCount: 1 }; } throw new Error(`unhandled SQL in memory pool: ${sql}`); }, }; } function rows(map) { return { rows: [...map.values()], rowCount: map.size }; } function selectAssetCatalogRows(pool, params) { const limit = Math.max(1, Number(params[0]) || 50); const selected = [...pool.assets.values()] .sort((left, right) => String(left.symbol).localeCompare(String(right.symbol)) || String(left.asset_id).localeCompare(String(right.asset_id))) .slice(0, limit) .map((row) => ({ asset_id: row.asset_id, venue: row.venue, symbol: row.symbol, label: row.label, decimals: row.decimals, blockchain: row.blockchain, chain: row.chain, contract_address: row.contract_address, latest_price: row.latest_price, price_updated_at: row.price_updated_at, supported: row.supported, retired_at: row.retired_at, enabled_for_inventory: row.enabled_for_inventory, role: row.role, withdraw_address: row.withdraw_address, raw_payload_available: Object.keys(row.raw_payload || {}).length > 0, updated_at: row.updated_at, })); return { rows: selected, rowCount: selected.length }; } function insertAsset(pool, params) { const seed = params.length === 16; const [ assetId, venue, symbol, label, decimals, blockchain, chain, contractAddress, latestPrice, priceUpdatedAt, ] = params; const previous = pool.assets.get(assetId); const row = { ...(previous || {}), asset_id: assetId, venue, symbol, label, decimals, blockchain, chain, contract_address: contractAddress, latest_price: latestPrice, price_updated_at: priceUpdatedAt, supported: seed ? (previous?.supported || params[10]) : true, retired_at: null, enabled_for_inventory: seed ? previous?.enabled_for_inventory === true || params[11] === true : previous?.enabled_for_inventory === true, role: seed ? params[12] : previous?.role || null, withdraw_address: seed ? params[13] : previous?.withdraw_address || '', raw_payload: JSON.parse(seed ? params[14] : params[10]), last_supported_at: seed ? params[15] : params[11], updated_at: seed ? params[15] : params[11], }; pool.assets.set(assetId, row); return { rows: [], rowCount: previous ? 0 : 1 }; } function retireAssets(pool, params) { const [retiredAt, importedIds] = params; let count = 0; for (const row of pool.assets.values()) { if (row.venue === 'near-intents' && row.supported && !importedIds.includes(row.asset_id)) { row.supported = false; row.retired_at ||= retiredAt; row.updated_at = retiredAt; count += 1; } } return { rows: [], rowCount: count }; } function enableInventoryAssets(pool, params) { const [assetIds, updatedAt] = params; let count = 0; for (const assetId of assetIds) { const row = pool.assets.get(assetId); if (!row) continue; row.enabled_for_inventory = true; row.updated_at = updatedAt; count += 1; } return { rows: [], rowCount: count }; } function insertImportRun(pool, params) { const row = { run_id: params[0], source_url: params[1], fetched_at: params[2], status: params[3], token_count: params[4], added_count: params[5], updated_count: params[6], unchanged_count: params[7], retired_count: params[8], raw_response_hash: params[9], error: params[10], raw_response: params[11] == null ? null : JSON.parse(params[11]), }; pool.importRuns.set(row.run_id, row); return { rows: [], rowCount: 1 }; } function insertPair(pool, params, sql = '') { const previous = pool.pairs.get(params[0]); const row = { pair_id: params[0], venue: params[1], asset_in: params[2], asset_out: params[3], mode: /mode = trading_pairs\.mode/i.test(sql) && previous ? previous.mode : params[4], enabled: /enabled = trading_pairs\.enabled/i.test(sql) && previous ? previous.enabled : params[5], status: /status = trading_pairs\.status/i.test(sql) && previous ? previous.status : params[6], created_at: params[7], updated_at: params[7], }; pool.pairs.set(row.pair_id, row); return { rows: [], rowCount: 1 }; } function insertStrategyConfig(pool, params) { const configId = params[0]; if (pool.strategyConfigs.has(configId)) return { rows: [], rowCount: 0 }; const row = { config_id: configId, pair_id: params[1], version: params[2], active: params[3], edge_bps: params[4], max_notional: params[5], min_notional: params[6], slippage_bps: params[7], min_deadline_ms: params[8], price_max_age_ms: params[9], inventory_max_age_ms: params[10], request_default_notional: params[11], request_max_notional: params[12], request_max_slippage_bps: params[13], created_by: params[14], reason: params[15], created_at: '2026-05-12T16:35:00.000Z', }; pool.strategyConfigs.set(configId, row); return { rows: [], rowCount: 1 }; } function insertRoute(pool, params, sql = '') { const previous = pool.routes.get(params[0]); const row = { route_id: params[0], pair_id: params[1], source: params[2], base_asset_id: params[3], quote_asset_id: params[4], route_config: JSON.parse(params[5]), max_age_ms: params[6], enabled: /enabled = pair_price_routes\.enabled/i.test(sql) && previous ? previous.enabled : params[7], created_at: params[8], updated_at: params[8], }; pool.routes.set(row.route_id, row); return { rows: [], rowCount: 1 }; }