from fastapi import APIRouter, Depends, Request, status from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from app.api.errors import from_api_error, http_error from app.auth.dependencies import get_current_user from app.bets.service import BetError, place_bet from app.db.models import User from app.db.session import get_session router = APIRouter(prefix="/bets", tags=["bets"]) class BetResponse(BaseModel): round_id: int bet_txid: str bet_amount_sats: int status: str @router.post("", response_model=BetResponse, status_code=status.HTTP_201_CREATED) async def create_bet( request: Request, user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session), ) -> BetResponse: listener = request.app.state.electrum_listener if listener.client is None: raise http_error( status.HTTP_503_SERVICE_UNAVAILABLE, "network_unavailable", "not connected to the network, try again shortly", ) async with request.app.state.user_locks.acquire(user.id): try: participant = await place_bet(session, listener.client, user) except BetError as exc: # A rejected broadcast isn't the client's fault — it's the network # refusing our transaction, so it answers 502 rather than 400 (B-07). code = ( status.HTTP_502_BAD_GATEWAY if exc.code == "broadcast_failed" else status.HTTP_400_BAD_REQUEST ) raise from_api_error(code, exc) from exc return BetResponse( round_id=participant.round_id, bet_txid=participant.bet_txid, bet_amount_sats=participant.bet_amount_sats, status=participant.status, )