This commit is contained in:
k
2026-04-21 19:33:24 +08:00
parent 9a72566753
commit 3268080401
26 changed files with 1816 additions and 318 deletions
+11 -30
View File
@@ -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