from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from typing import List, Optional from app.api.dependencies import get_db_session, get_current_user, create_access_token from app.schemas.dtos import ( UserAuthRequest, TokenResponse, AccountBalanceDTO, LedgerEntryDTO, MarketDTO, CreateOrderRequest, OrderDTO ) from app.domains.ledger.service import LedgerService from app.domains.trading.service import MarketService, TradingService api_router = APIRouter(prefix="/v1") # ================= Auth Routes ================= @api_router.post("/auth/login", response_model=TokenResponse) async def login_with_wallet(req: UserAuthRequest, session: AsyncSession = Depends(get_db_session)): """Web3 SIWE 钱包快速认证""" token = create_access_token(req.address) return TokenResponse(access_token=token, address=req.address.lower()) # ================= Market Routes ================= @api_router.get("/markets", response_model=List[MarketDTO]) async def get_markets( category: Optional[str] = None, status: Optional[str] = None, session: AsyncSession = Depends(get_db_session) ): """获取预测市场列表""" market_service = MarketService(session) markets = await market_service.list_markets(category, status) return [ MarketDTO( market_address=m.market_address, question_id=m.question_id, title=m.title, description=m.description, category=m.category, tier=m.tier, creator=m.creator, status=m.status.value if hasattr(m.status, 'value') else str(m.status), outcomes=m.outcomes, winning_outcome=m.winning_outcome, resolution_time=m.resolution_time, created_at=m.created_at ) for m in markets ] # ================= Orders & Trading ================= @api_router.post("/orders", response_model=OrderDTO) async def place_order( req: CreateOrderRequest, current_user: str = Depends(get_current_user), session: AsyncSession = Depends(get_db_session) ): """创建并执行交易委托""" trading_service = TradingService(session) order = await trading_service.place_order( user_address=current_user, market_address=req.market_address, outcome_index=req.outcome_index, side=req.side, amount=req.amount, price=req.price ) return OrderDTO( order_id=order.order_id, market_address=order.market_address, user_address=order.user_address, side=order.side, outcome_index=order.outcome_index, amount=order.amount, status=order.status, fee=order.fee, created_at=order.created_at ) # ================= Ledger & Balances ================= @api_router.get("/wallet/balance", response_model=AccountBalanceDTO) async def get_balance( current_user: str = Depends(get_current_user), session: AsyncSession = Depends(get_db_session) ): """查询用户资金与冻结余额""" ledger_service = LedgerService(session) bal = await ledger_service.get_or_create_balance(current_user) return AccountBalanceDTO( address=bal.address, collateral_symbol=bal.collateral_symbol, available_balance=bal.available_balance, frozen_balance=bal.frozen_balance ) @api_router.get("/wallet/ledger", response_model=List[LedgerEntryDTO]) async def get_ledger_history( current_user: str = Depends(get_current_user), limit: int = 50, session: AsyncSession = Depends(get_db_session) ): """查询不可变复式记账流水""" ledger_service = LedgerService(session) entries = await ledger_service.list_user_ledger(current_user, limit) return [ LedgerEntryDTO( id=e.id, entry_type=e.entry_type.value if hasattr(e.entry_type, 'value') else str(e.entry_type), amount=e.amount, balance_after=e.balance_after, frozen_after=e.frozen_after, related_market=e.related_market, created_at=e.created_at ) for e in entries ]