from sqlalchemy.ext.asyncio import AsyncSession from app.db.models import Round, User from app.wallet.hd import derive_user_address async def own_address_for( session: AsyncSession, kind: str, user_id: int | None, round_id: int | None = None ) -> str: """The address that owns every input of a PendingTransaction of this kind — a user's own address for a bet/withdrawal, the pool address of the round for a payout (B-80: each round has its own, stored on the round). All our builders only ever spend one address's UTXOs per tx (see tx/broadcast.py:_signing_context, which derives the same address alongside the signing key it also needs). Shared by tx/confirmation.py and tx/reconcile.py (B-41): both now check blockchain.scripthash.get_history for this address instead of asking blockchain.transaction.get for a verbose reply, so the two can't derive different addresses for the same row. """ if kind == "payout": round_ = await session.get(Round, round_id) if round_id is not None else None if round_ is None or not round_.pool_address: raise ValueError(f"payout of round {round_id}: the round has no pool address") return round_.pool_address user = await session.get(User, user_id) return derive_user_address(user.derivation_index)