Automated Action 5bb78bd9be Implement Solana arbitrage analytics backend
- 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>
2025-05-12 14:13:06 +00:00

188 lines
4.9 KiB
Python

from typing import Any, List, Optional, Dict
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from app import crud
from app.api import deps
from app.schemas.pool import Pool, PoolWithDex, PoolList
router = APIRouter()
@router.get("/", response_model=PoolList)
def read_pools(
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
sort_by_tvl: bool = True
) -> Any:
"""
Retrieve pools with pagination.
"""
result = crud.pool.get_pools_with_dex(db, skip=skip, limit=limit)
pools_with_dex = []
for pool, dex in result:
pools_with_dex.append(PoolWithDex(
**pool.__dict__,
dex_name=dex.name,
dex_address=dex.address
))
total = crud.pool.get_count(db)
return {"pools": pools_with_dex, "total": total}
@router.get("/active", response_model=PoolList)
def read_most_active_pools(
db: Session = Depends(deps.get_db),
limit: int = Query(20, ge=1, le=100)
) -> Any:
"""
Get the most active pools by volume.
"""
pools = crud.pool.get_most_active_pools(db, limit=limit)
# Add DEX information
pools_with_dex = []
for p in pools:
dex = crud.dex.get(db, id=p.dex_id)
if dex:
pools_with_dex.append(PoolWithDex(
**p.__dict__,
dex_name=dex.name,
dex_address=dex.address
))
return {"pools": pools_with_dex, "total": len(pools_with_dex)}
@router.get("/{pool_id}", response_model=PoolWithDex)
def read_pool(
pool_id: int,
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific pool by id.
"""
pool = crud.pool.get(db, id=pool_id)
if not pool:
raise HTTPException(status_code=404, detail="Pool not found")
dex = crud.dex.get(db, id=pool.dex_id)
if not dex:
raise HTTPException(status_code=404, detail="DEX not found")
return PoolWithDex(
**pool.__dict__,
dex_name=dex.name,
dex_address=dex.address
)
@router.get("/address/{address}", response_model=PoolWithDex)
def read_pool_by_address(
address: str,
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific pool by address.
"""
pool = crud.pool.get_by_address(db, address=address)
if not pool:
raise HTTPException(status_code=404, detail="Pool not found")
dex = crud.dex.get(db, id=pool.dex_id)
if not dex:
raise HTTPException(status_code=404, detail="DEX not found")
return PoolWithDex(
**pool.__dict__,
dex_name=dex.name,
dex_address=dex.address
)
@router.get("/token/{token_address}", response_model=PoolList)
def read_pools_by_token(
token_address: str,
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100
) -> Any:
"""
Get pools that contain a specific token.
"""
pools = crud.pool.get_by_token(db, token_address=token_address, skip=skip, limit=limit)
# Add DEX information
pools_with_dex = []
for p in pools:
dex = crud.dex.get(db, id=p.dex_id)
if dex:
pools_with_dex.append(PoolWithDex(
**p.__dict__,
dex_name=dex.name,
dex_address=dex.address
))
return {"pools": pools_with_dex, "total": len(pools_with_dex)}
@router.get("/pair", response_model=PoolList)
def read_pools_by_token_pair(
token_a: str = Query(...),
token_b: str = Query(...),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100
) -> Any:
"""
Get pools for a specific token pair.
"""
pools = crud.pool.get_by_token_pair(
db, token_a=token_a, token_b=token_b, skip=skip, limit=limit
)
# Add DEX information
pools_with_dex = []
for p in pools:
dex = crud.dex.get(db, id=p.dex_id)
if dex:
pools_with_dex.append(PoolWithDex(
**p.__dict__,
dex_name=dex.name,
dex_address=dex.address
))
return {"pools": pools_with_dex, "total": len(pools_with_dex)}
@router.get("/tvl-range", response_model=PoolList)
def read_pools_by_tvl(
min_tvl: float = Query(..., ge=0),
max_tvl: Optional[float] = Query(None, ge=0),
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100
) -> Any:
"""
Get pools within a TVL range.
"""
pools = crud.pool.get_by_tvl_range(
db, min_tvl=min_tvl, max_tvl=max_tvl, skip=skip, limit=limit
)
# Add DEX information
pools_with_dex = []
for p in pools:
dex = crud.dex.get(db, id=p.dex_id)
if dex:
pools_with_dex.append(PoolWithDex(
**p.__dict__,
dex_name=dex.name,
dex_address=dex.address
))
return {"pools": pools_with_dex, "total": len(pools_with_dex)}