import secrets from fastapi import HTTPException, status from generalresearch.redis_helper import RedisConfig from jb.api.magic_token import MAGIC_TOKEN_TTL, redis_token_key from jb.decorators import get_redis_config from jb.models.wallet import PendingCashout CASHOUT_TOKEN_PREFIX = "wallet:cashout:" def create_cashout_token( cashout: PendingCashout, redis_config: RedisConfig | None = None ) -> str: """Create a short-lived, single-use token bound to a cashout request.""" if redis_config is None: redis_config = get_redis_config() token = secrets.token_urlsafe(32) redis_config.create_redis_client().set( redis_token_key(token, CASHOUT_TOKEN_PREFIX), cashout.model_dump_json(), ex=MAGIC_TOKEN_TTL, ) return token def consume_cashout_token( token: str, redis_config: RedisConfig | None = None ) -> PendingCashout: if redis_config is None: redis_config = get_redis_config() raw_data = redis_config.create_redis_client().getdel( redis_token_key(token, CASHOUT_TOKEN_PREFIX) ) if raw_data is None: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired cashout confirmation token", ) return PendingCashout.model_validate_json(raw_data)