
- Create project structure with FastAPI - Add database models for blocks, transactions, arbitrages, pools, and DEXes - Implement Solana RPC client for fetching blockchain data - Create arbitrage detection algorithm - Implement comprehensive API endpoints for analytics - Set up database migrations with Alembic - Add detailed project documentation generated with BackendIM... (backend.im) Co-Authored-By: Claude <noreply@anthropic.com>
69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
from typing import List, Optional, Dict, Any, Union, Tuple
|
|
|
|
from sqlalchemy import func, desc
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.crud.base import CRUDBase
|
|
from app.models.dex import Dex
|
|
from app.models.pool import Pool
|
|
from app.schemas.dex import DexCreate, DexUpdate
|
|
|
|
|
|
class CRUDDex(CRUDBase[Dex, DexCreate, DexUpdate]):
|
|
"""CRUD operations for DEXes."""
|
|
|
|
def get_by_address(self, db: Session, *, address: str) -> Optional[Dex]:
|
|
"""Get a DEX by its address."""
|
|
return db.query(Dex).filter(Dex.address == address).first()
|
|
|
|
def get_by_name(self, db: Session, *, name: str) -> Optional[Dex]:
|
|
"""Get a DEX by its name."""
|
|
return db.query(Dex).filter(Dex.name == name).first()
|
|
|
|
def get_with_pool_count(
|
|
self, db: Session, *, skip: int = 0, limit: int = 100
|
|
) -> List[Tuple[Dex, int]]:
|
|
"""Get DEXes with count of their pools."""
|
|
return db.query(
|
|
Dex, func.count(Pool.id).label('pool_count')
|
|
).outerjoin(
|
|
Pool, Dex.id == Pool.dex_id
|
|
).group_by(
|
|
Dex.id
|
|
).order_by(
|
|
desc('pool_count')
|
|
).offset(skip).limit(limit).all()
|
|
|
|
def get_with_volumes(
|
|
self, db: Session, *, skip: int = 0, limit: int = 100
|
|
) -> List[Dex]:
|
|
"""Get DEXes ordered by volume."""
|
|
return db.query(Dex).order_by(
|
|
desc(Dex.volume_24h)
|
|
).offset(skip).limit(limit).all()
|
|
|
|
def search_by_name(
|
|
self, db: Session, *, query: str, skip: int = 0, limit: int = 100
|
|
) -> List[Dex]:
|
|
"""Search DEXes by name."""
|
|
return db.query(Dex).filter(
|
|
Dex.name.ilike(f'%{query}%')
|
|
).offset(skip).limit(limit).all()
|
|
|
|
def update_volume(
|
|
self, db: Session, *, dex_id: int, volume_24h: float, volume_7d: Optional[float] = None
|
|
) -> Optional[Dex]:
|
|
"""Update the volume statistics for a DEX."""
|
|
db_obj = db.query(Dex).filter(Dex.id == dex_id).first()
|
|
if db_obj:
|
|
db_obj.volume_24h = volume_24h
|
|
if volume_7d is not None:
|
|
db_obj.volume_7d = volume_7d
|
|
db.add(db_obj)
|
|
db.commit()
|
|
db.refresh(db_obj)
|
|
return db_obj
|
|
|
|
|
|
# Create a single instance for use in dependency injection
|
|
dex = CRUDDex(Dex) |