from typing import List from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException from sqlalchemy.orm import Session from app.db.session import get_db from app.models.models import ArbitrageEvent from app.schemas.schemas import (ArbitrageEventResponse, ScanRequest, ScanStatusResponse) from app.services.scanner import BlockScanner router = APIRouter() @router.post("/scan", response_model=ScanStatusResponse) async def scan_for_arbitrage( background_tasks: BackgroundTasks, scan_request: ScanRequest, db: Session = Depends(get_db), ): """ Scan the blockchain for arbitrage transactions """ scanner = BlockScanner(db) # Add scanning task to background tasks background_tasks.add_task( scanner.scan_blocks, num_blocks=scan_request.num_blocks, start_slot=scan_request.start_slot, ) # Return current scan status status = scanner.get_scan_status() return ScanStatusResponse(**status) @router.get("/status", response_model=ScanStatusResponse) async def get_scan_status( db: Session = Depends(get_db), ): """ Get the current status of the arbitrage scanner """ scanner = BlockScanner(db) status = scanner.get_scan_status() return ScanStatusResponse(**status) @router.get("/events", response_model=List[ArbitrageEventResponse]) async def get_arbitrage_events( skip: int = 0, limit: int = 100, min_confidence: float = 0.0, token_address: str = None, db: Session = Depends(get_db), ): """ Get detected arbitrage events """ query = db.query(ArbitrageEvent) # Apply filters if min_confidence > 0: query = query.filter(ArbitrageEvent.confidence_score >= min_confidence) if token_address: query = query.filter(ArbitrageEvent.profit_token_address == token_address) # Get paginated results events = query.order_by(ArbitrageEvent.detected_at.desc()).offset(skip).limit(limit).all() # Convert to response format result = [] for event in events: # Get transaction signature and block slot transaction = event.transaction block_slot = transaction.block_id if transaction else 0 result.append( ArbitrageEventResponse( id=event.id, transaction_signature=transaction.signature if transaction else "", profit_token_address=event.profit_token_address, profit_amount=event.profit_amount, profit_usd=event.profit_usd, path=event.path, confidence_score=event.confidence_score, detected_at=event.detected_at, block_slot=block_slot, ) ) return result @router.get("/events/{event_id}", response_model=ArbitrageEventResponse) async def get_arbitrage_event( event_id: int, db: Session = Depends(get_db), ): """ Get a specific arbitrage event by ID """ event = db.query(ArbitrageEvent).filter(ArbitrageEvent.id == event_id).first() if not event: raise HTTPException(status_code=404, detail="Arbitrage event not found") # Get transaction signature and block slot transaction = event.transaction block_slot = transaction.block_id if transaction else 0 return ArbitrageEventResponse( id=event.id, transaction_signature=transaction.signature if transaction else "", profit_token_address=event.profit_token_address, profit_amount=event.profit_amount, profit_usd=event.profit_usd, path=event.path, confidence_score=event.confidence_score, detected_at=event.detected_at, block_slot=block_slot, )