from datetime import datetime from typing import Dict, List, Optional, Any from pydantic import BaseModel, Field class InstructionBase(BaseModel): program_id: str instruction_type: str instruction_index: Optional[int] = None accounts: Optional[str] = None data: Optional[str] = None parsed_data: Optional[Dict[str, Any]] = None class InstructionCreate(InstructionBase): transaction_id: int class Instruction(InstructionBase): id: int transaction_id: int class Config: from_attributes = True class SwapBase(BaseModel): program_id: str token_in_address: str token_out_address: str amount_in: float amount_out: float user_account: Optional[str] = None class SwapCreate(SwapBase): transaction_id: int instruction_id: int class Swap(SwapBase): id: int transaction_id: int instruction_id: int timestamp: datetime class Config: from_attributes = True class TokenTransferBase(BaseModel): token_address: str from_address: str to_address: str amount: float program_id: str class TokenTransferCreate(TokenTransferBase): transaction_id: int instruction_id: Optional[int] = None class TokenTransfer(TokenTransferBase): id: int transaction_id: int instruction_id: Optional[int] = None timestamp: datetime class Config: from_attributes = True class ArbitrageEventBase(BaseModel): profit_token_address: str profit_amount: float profit_usd: Optional[float] = None path: str swap_sequence: Optional[str] = None confidence_score: float = Field(..., ge=0.0, le=1.0) class ArbitrageEventCreate(ArbitrageEventBase): transaction_id: int class ArbitrageEvent(ArbitrageEventBase): id: int transaction_id: int detected_at: datetime class Config: from_attributes = True class TransactionBase(BaseModel): signature: str fee: int status: str raw_data: str class TransactionCreate(TransactionBase): block_id: int class Transaction(TransactionBase): id: int block_id: int timestamp: datetime instructions: List[Instruction] = [] swaps: List[Swap] = [] token_transfers: List[TokenTransfer] = [] arbitrage_events: List[ArbitrageEvent] = [] class Config: from_attributes = True class BlockBase(BaseModel): slot: int blockhash: str parent_blockhash: str processed: bool = False class BlockCreate(BlockBase): pass class Block(BlockBase): id: int timestamp: datetime transactions: List[Transaction] = [] class Config: from_attributes = True class ArbitrageEventResponse(BaseModel): id: int transaction_signature: str profit_token_address: str profit_amount: float profit_usd: Optional[float] = None path: str confidence_score: float detected_at: datetime block_slot: int class ScanStatusResponse(BaseModel): last_scanned_block: int last_scan_time: datetime arbitrage_events_count: int scan_in_progress: bool class ScanRequest(BaseModel): num_blocks: int = Field(10, ge=1, le=100) start_slot: Optional[int] = None