done
This commit is contained in:
+11
-30
@@ -1,48 +1,33 @@
|
||||
import logging
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from eth_account import Account
|
||||
from eth_account.messages import encode_defunct
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.database import get_db
|
||||
from app.models import Subscription
|
||||
from app.schemas import SubscribeRequest, SubscribeResponse
|
||||
from app.services.signed_request import verify_signed_request
|
||||
|
||||
router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
SIGN_MESSAGE = "Sign in to TrumpSignal"
|
||||
|
||||
|
||||
from typing import Optional
|
||||
|
||||
def _recover_signer(signature: str) -> Optional[str]:
|
||||
"""Recover signer address from an EIP-191 personal_sign signature."""
|
||||
try:
|
||||
message = encode_defunct(text=SIGN_MESSAGE)
|
||||
recovered = Account.recover_message(message, signature=signature)
|
||||
return recovered.lower()
|
||||
except Exception as exc:
|
||||
logger.warning("Signature recovery failed: %s", exc)
|
||||
return None
|
||||
ACTION_SUBSCRIBE = "subscribe"
|
||||
|
||||
|
||||
@router.post("/subscribe", response_model=SubscribeResponse)
|
||||
async def subscribe(body: SubscribeRequest, db: AsyncSession = Depends(get_db)):
|
||||
wallet = body.wallet.lower().strip()
|
||||
|
||||
# Verify EIP-191 signature
|
||||
recovered = _recover_signer(body.signature)
|
||||
if recovered is None or recovered != wallet:
|
||||
raise HTTPException(
|
||||
status_code=401,
|
||||
detail="Signature verification failed: recovered address does not match wallet",
|
||||
)
|
||||
verify_signed_request(
|
||||
action=ACTION_SUBSCRIBE,
|
||||
wallet=wallet,
|
||||
timestamp_ms=body.timestamp,
|
||||
signature=body.signature,
|
||||
body=None,
|
||||
)
|
||||
|
||||
# Upsert subscription
|
||||
result = await db.execute(
|
||||
select(Subscription).where(Subscription.wallet_address == wallet)
|
||||
)
|
||||
@@ -50,11 +35,7 @@ async def subscribe(body: SubscribeRequest, db: AsyncSession = Depends(get_db)):
|
||||
now = datetime.now(timezone.utc).replace(tzinfo=None)
|
||||
|
||||
if sub is None:
|
||||
sub = Subscription(
|
||||
wallet_address=wallet,
|
||||
active=True,
|
||||
subscribed_at=now,
|
||||
)
|
||||
sub = Subscription(wallet_address=wallet, active=True, subscribed_at=now)
|
||||
db.add(sub)
|
||||
else:
|
||||
sub.active = True
|
||||
|
||||
Reference in New Issue
Block a user