import { IWalletRepository, ICopySignalRepository, ITradeRepository, ISimulationExecutionRepository, IEventJournalRepository, } from '../../src/domain/interfaces.js'; import { WatchedWallet, CopySignal, Trade, SimulatedExecution, EventJournalEntry, } from '../../src/domain/models.js'; export class InMemoryWalletRepository implements IWalletRepository { public wallets: WatchedWallet[] = []; async getWatchedWallets(): Promise { return this.wallets.filter((w) => w.isActive); } async isWalletWatched(address: string): Promise { return this.wallets.some((w) => w.address === address && w.isActive); } async addWatchedWallet( wallet: Omit, ): Promise { const newWallet: WatchedWallet = { id: Math.random().toString(), ...wallet, createdAt: new Date(), updatedAt: new Date(), }; this.wallets.push(newWallet); return newWallet; } } export class InMemoryCopySignalRepository implements ICopySignalRepository { public signals: CopySignal[] = []; async saveSignal(signal: CopySignal): Promise { this.signals.push(signal); } async getSignalByCorrelationId(correlationId: string): Promise { return this.signals.find((s) => s.correlationId === correlationId) || null; } } export class InMemoryTradeRepository implements ITradeRepository { public trades: Trade[] = []; async saveTrade(trade: Trade): Promise { const idx = this.trades.findIndex((t) => t.id === trade.id); if (idx !== -1) { this.trades[idx] = trade; } else { this.trades.push(trade); } } async updateTrade(trade: Trade): Promise { await this.saveTrade(trade); } async getTradeByCorrelationIdAndScenario( correlationId: string, latencyScenario: number, ): Promise { return ( this.trades.find( (t) => t.correlationId === correlationId && t.latencyScenario === latencyScenario, ) || null ); } async getActiveTradesForScenario(latencyScenario: number): Promise { return this.trades.filter((t) => t.latencyScenario === latencyScenario && t.status === 'open'); } async getTradeById(id: string): Promise { return this.trades.find((t) => t.id === id) || null; } async getTradesForScenario(latencyScenario: number): Promise { return this.trades.filter((t) => t.latencyScenario === latencyScenario); } } export class InMemorySimulationExecutionRepository implements ISimulationExecutionRepository { public executions: SimulatedExecution[] = []; async saveExecution(execution: SimulatedExecution): Promise { this.executions.push(execution); } async getExecutionsByTradeId(tradeId: string): Promise { return this.executions.filter((e) => e.tradeId === tradeId); } async getPendingExecutionsBefore(timestamp: Date): Promise { return this.executions.filter( (e) => e.status === 'pending' && e.executionTimestamp <= timestamp, ); } async updateExecution(execution: SimulatedExecution): Promise { const idx = this.executions.findIndex((e) => e.id === execution.id); if (idx !== -1) { this.executions[idx] = execution; } } } export class InMemoryEventJournalRepository implements IEventJournalRepository { public events: EventJournalEntry[] = []; async logEvent(entry: EventJournalEntry): Promise { this.events.push(entry); } async getEventsByCorrelationId(correlationId: string): Promise { return this.events.filter((e) => e.correlationId === correlationId); } } export class InMemoryStrategyRunsRepository { public runs: any[] = []; async saveRun(run: any): Promise { this.runs.push(run); } }