feat(relayer): API v2 (canBet/30% от баланса) + п.8 — ничья играет заново

Тестовый TS-шлюз (relayer/), обслуживающий smart-updown.binom.pw и
testfront.binom.pw. Контракт и prod-Kotlin сервер не тронуты.

1+2. GET /state: canBet (boolean) + canBetReasonCode/canBetReason (русский
     текст) — можно ли ставить с фиксированным кошельком. Учитывает:
     захардкоженный адрес (GW_FIXED_BETTOR), наличие открытой ставки,
     хватает ли фантиков на ставку, лимиты [min,max], paused, наличие цены.
3-6. POST /bet: тело {"side":"up"|"down"} — сумма с фронта НЕ приходит,
     размер = GW_BET_PERCENT (30) % от баланса фантиков, клампится в
     [minAmount, maxAmount]. Ответ: {accepted, reasonCode, reason,
     retryAfterSeconds, betId, txSig, ...}.
7.   GET /state: openBet / lastBet (взаимоисключающие: открытая имеет
     приоритет) + поле status ("open"/"closed"), result, retryAfterSeconds.
8.   Ничья (refunded, exit==entry) игроку НЕ показывается: планировщик молча
     пересоздаёт ставку тем же размером и направлением (хук replayBet) и
     шлёт WS-событие bet_replay вместо bet_closed. Лимит GW_MAX_REPLAYS
     (дефолт 10) обрывает цепочку при «замороженной» цене.
9.   relayer/API.md — документация всех endpoint-ов и WS-событий.

Новые файлы: src/betRules.ts (правила ставки: canBetDecision,
computeBetAmountUnits), API.md.
Новые env: GW_FIXED_BETTOR, GW_BET_PERCENT (30), GW_MAX_REPLAYS (10).

Проверено: npm run typecheck + npm run test — 127 проверок, 0 провалов;
живая приёмка tools/gateway-api-v2-check.cjs — 26/26 на
https://smart-updown.binom.pw/api (включая реальную ставку → payout_done).
This commit is contained in:
subochev
2026-09-17 00:11:31 +03:00
parent 42dfa58582
commit dd4f16a930
8 changed files with 1411 additions and 135 deletions
+9
View File
@@ -29,6 +29,15 @@ smart:
priceHistory: '/app/data/price-history.db'
priceRetentionHours: 24
settleIntervalMs: 2000
# Захардкоженный беттор шлюза: шлюз ставит от его имени на 30% от баланса.
# Адрес «bettor-1» из тестового фронта, уже зарегистрирован в keystore
# и пополнен (~9800 фантиков, ~5 SOL).
fixedBettor: '6Q1koEYH3R2CdV13mwcPQTXbDjQhbyzY6N82f55o13s6'
betPercent: 30
# п.8 ТЗ: лимит переигровок ничьих на одну цепочку ставок (10 по умолчанию).
# Цена «заморожена» → каждая ставка рефандится → без лимита цепочка
# крутится бесконечно.
maxReplays: 10
nats:
url: 'nats://192.168.88.93:4222'