// Cache Service - Redis Integration // Caches RPC responses and risk calculations import { logger } from '@/infrastructure/monitoring/logger'; // Placeholder for Redis client interface RedisClient { get: (key: string) => Promise; set: (key: string, value: string, ttl?: number) => Promise; del: (key: string) => Promise; exists: (key: string) => Promise; } export interface CacheConfig { enabled: boolean; defaultTtl: number; // seconds priceDataTtl: number; riskCalcTtl: number; exchangeRateTtl: number; } export class CacheService { private redis: RedisClient | null = null; private config: CacheConfig = { enabled: process.env.REDIS_ENABLED === 'true', defaultTtl: 300, // 5 minutes priceDataTtl: 60, // 1 minute riskCalcTtl: 300, // 5 minutes exchangeRateTtl: 30, // 30 seconds }; constructor(redisClient?: RedisClient) { if (redisClient) { this.redis = redisClient; } else if (this.config.enabled) { // TODO: Initialize Redis client // this.redis = new Redis(process.env.REDIS_URL || 'redis://localhost:6379'); logger.warn('Redis client not initialized - caching disabled'); this.config.enabled = false; } } /** * Get cached value */ async get(key: string): Promise { if (!this.config.enabled || !this.redis) { return null; } try { const value = await this.redis.get(key); if (value) { return JSON.parse(value) as T; } return null; } catch (error) { logger.error('Cache get error', { key, error }); return null; } } /** * Set cached value */ async set(key: string, value: any, ttl?: number): Promise { if (!this.config.enabled || !this.redis) { return; } try { const serialized = JSON.stringify(value); await this.redis.set(key, serialized, ttl || this.config.defaultTtl); } catch (error) { logger.error('Cache set error', { key, error }); } } /** * Delete cached value */ async delete(key: string): Promise { if (!this.config.enabled || !this.redis) { return; } try { await this.redis.del(key); } catch (error) { logger.error('Cache delete error', { key, error }); } } /** * Get cached price */ async getCachedPrice(tokenAddress: string): Promise { return this.get(`price:${tokenAddress}`); } /** * Set cached price */ async setCachedPrice(tokenAddress: string, price: string): Promise { await this.set(`price:${tokenAddress}`, price, this.config.priceDataTtl); } /** * Get cached exchange rate */ async getCachedExchangeRate(from: string, to: string): Promise { return this.get(`rate:${from}:${to}`); } /** * Set cached exchange rate */ async setCachedExchangeRate(from: string, to: string, rate: string): Promise { await this.set(`rate:${from}:${to}`, rate, this.config.exchangeRateTtl); } /** * Get cached risk calculation */ async getCachedRiskCalc(dealId: string, calcType: string): Promise { return this.get(`risk:${dealId}:${calcType}`); } /** * Set cached risk calculation */ async setCachedRiskCalc(dealId: string, calcType: string, result: any): Promise { await this.set(`risk:${dealId}:${calcType}`, result, this.config.riskCalcTtl); } /** * Invalidate deal cache */ async invalidateDealCache(dealId: string): Promise { const patterns = [ `risk:${dealId}:*`, `deal:${dealId}:*`, ]; // TODO: Implement pattern-based deletion if needed logger.debug('Deal cache invalidated', { dealId }); } } export const cacheService = new CacheService();