feat(backend): add market metadata storage and outcomes extension

This commit is contained in:
Bot
2026-08-31 01:58:30 +08:00
parent 37546f18da
commit 13686de581
3 changed files with 79 additions and 5 deletions
+35
View File
@@ -7,6 +7,8 @@ from app.schemas.dtos import (
TokenResponse,
AccountBalanceDTO,
LedgerEntryDTO,
CreateMarketMetadataRequest,
ResolveMarketRequest,
MarketDTO,
CreateOrderRequest,
OrderDTO
@@ -24,6 +26,39 @@ async def login_with_wallet(req: UserAuthRequest, session: AsyncSession = Depend
return TokenResponse(access_token=token, address=req.address.lower())
# ================= Market Routes =================
@api_router.post("/markets/metadata", response_model=MarketDTO)
async def create_market_metadata(
req: CreateMarketMetadataRequest,
current_user: str = Depends(get_current_user),
session: AsyncSession = Depends(get_db_session)
):
"""保存预测市场的链下元数据 (标题, 描述, 类别, 2~255个选项)"""
market_service = MarketService(session)
market = await market_service.save_market_metadata(
market_address=req.market_address,
question_id=req.question_id,
title=req.title,
description=req.description,
category=req.category,
outcomes=req.outcomes,
resolution_time=req.resolution_time,
creator=current_user
)
return MarketDTO(
market_address=market.market_address,
question_id=market.question_id,
title=market.title,
description=market.description,
category=market.category,
tier=market.tier,
creator=market.creator,
status=market.status.value if hasattr(market.status, 'value') else str(market.status),
outcomes=market.outcomes,
winning_outcome=market.winning_outcome,
resolution_time=market.resolution_time,
created_at=market.created_at
)
@api_router.get("/markets", response_model=List[MarketDTO])
async def get_markets(
category: Optional[str] = None,
+32
View File
@@ -12,6 +12,38 @@ class MarketService:
def __init__(self, session: AsyncSession):
self.session = session
async def save_market_metadata(
self,
market_address: str,
question_id: str,
title: str,
description: Optional[str],
category: str,
outcomes: List[str],
resolution_time,
creator: str
) -> MarketModel:
market = MarketModel(
market_address=market_address.lower(),
question_id=question_id.lower(),
title=title,
description=description,
category=category or "Others",
tier=1,
creator=creator.lower(),
curve_address="0xF0E189974c413506098AFB6Bc6Bf4C6715fBf7B1",
collateral_address="0xe776e957953EA69b7Eaa9d7d4098aBC076bDD5E7",
fee_rate=Decimal("0.006"),
resolution_time=resolution_time,
outcomes=outcomes,
num_outcomes=len(outcomes),
status=MarketStatus.ACTIVE,
created_at_block=0
)
self.session.add(market)
await self.session.flush()
return market
async def list_markets(self, category: Optional[str] = None, status: Optional[str] = None) -> List[MarketModel]:
stmt = select(MarketModel)
if category:
+12 -5
View File
@@ -28,13 +28,15 @@ class LedgerEntryDTO(BaseModel):
related_market: Optional[str] = None
created_at: datetime
class CreateMarketRequest(BaseModel):
class CreateMarketMetadataRequest(BaseModel):
market_address: str
question_id: str
title: str
description: Optional[str] = None
category: str = "Crypto"
tier: int = 1
category: str = "Others" # 默认 Others,支持用户自定义
outcomes: List[str] = Field(..., min_length=2, max_length=255) # 支持最多 255 个选项
resolution_time: datetime
outcomes: List[str] = Field(..., min_length=2, max_length=8)
creator: str
class MarketDTO(BaseModel):
market_address: str
@@ -50,10 +52,15 @@ class MarketDTO(BaseModel):
resolution_time: datetime
created_at: datetime
class ResolveMarketRequest(BaseModel):
market_address: str
question_id: str
winning_outcome_index: int = Field(..., ge=0, le=255)
class CreateOrderRequest(BaseModel):
market_address: str
vault_address: Optional[str] = None
outcome_index: int = Field(..., ge=0, le=7)
outcome_index: int = Field(..., ge=0, le=255)
side: str = Field(..., pattern="^(BUY|SELL)$")
amount: Decimal = Field(..., gt=0)
price: Optional[Decimal] = None