/** * Impure reconcile executor: wires decideReconcile (pure) with the I/O side-effects * (adoptPosition, resizePosition, archiveGoneState). * * Design contract: * - decideReconcile is the SOLE decision source (no second gone-computation here). * - CH fetch returning null/undefined → success:false, zero mutations (R7 fail-safe). * - getOpenPositions undefined (CH never fetched) → success:false, zero mutations. * - Execution order within the serialize pass: archive gone FIRST, then adopt/resize * (frees state before re-adopting; mirrors monitor order). * - Each action is individually try/caught; one failure does not abort the rest. * - Only successfully applied actions count toward ReconcileCounts. */ import type { SenpiClient } from "../senpi/client.js"; import type { StrategyState } from "../types/strategy.js"; import type { StateManager } from "../state/index.js"; import type { SenpiEventBus } from "../types/event-bus.js"; import type { PositionOpenedEvent } from "../types/dsl/index.js"; import type { OpenPosition } from "../senpi/types.js"; export interface RunReconcileDeps { address: string; strategyState: StrategyState; senpi: SenpiClient; stateManager: StateManager; /** * adoptPosition + resizePosition — satisfied by DslPlugin or a compatible adopter. * The opts shape is stated inline (not imported from the DSL handlers) so the port stays * the narrow thing reconcile actually needs: the tick that caused the adopt, when there is one. */ adopter: { adoptPosition(p: PositionOpenedEvent, opts?: { tickId?: string; }): Promise; resizePosition(p: PositionOpenedEvent, opts?: { tickId?: string; }): Promise; }; bus?: SenpiEventBus; /** The monitor tick driving this reconcile, when one is; absent on the boot reconcile. */ tickId?: string; /** * Serializes the whole fetch+decide+execute pass against the trade loop / other reconciles. * Default: run directly (T5 will pass a reconcileMutex-backed serializer). */ serialize?: (fn: () => Promise) => Promise; } export interface ReconcileCounts { adopted: number; resized: number; archived: number; } /** * Map an OpenPosition (from clearinghouse) to the PositionOpenedEvent shape expected * by adoptPosition / resizePosition. * * Field mapping: * address → address (strategy wallet; same as deps.address) * wallet → position.wallet if set, else address (clearinghouse rows rarely carry wallet) * coin → position.coin * szi → String(position.szi) — signed; positive=LONG, negative=SHORT * entryPx → String(position.entryPx ?? 0) * leverage → position.leverage ?? 1 * dex → position.dex if non-empty, else undefined (handlePositionOpened normalizes "") * * Note: PositionOpenedEvent.szi is a string (the handler parses it); OpenPosition.szi is a number. */ export declare function openPositionToPayload(pos: OpenPosition, address: string): PositionOpenedEvent; export declare function runReconcile(deps: RunReconcileDeps): Promise<{ success: boolean; counts: ReconcileCounts; }>; //# sourceMappingURL=reconcile-run.d.ts.map