2025-05-28 21:53:03 +00:00

124 lines
3.7 KiB
Python

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,
)