124 lines
3.7 KiB
Python
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,
|
|
) |