From b8c040dedcfae091acab2a66cdee3ce33e3bec4b Mon Sep 17 00:00:00 2001 From: Caffeine Date: Mon, 14 Sep 2026 02:24:53 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D1=80=D0=B8=D0=B2=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=B8=20README=20=D0=B8=20API.md=20=D0=B2=20=D1=81=D0=BE?= =?UTF-8?q?=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D0=B5=20?= =?UTF-8?q?=D1=81=20=D0=B6=D0=B8=D0=B2=D1=8B=D0=BC=20=D1=81=D1=82=D0=B5?= =?UTF-8?q?=D0=BD=D0=B4=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Оба файла описывали состояние, которого больше нет, и содержали ошибки, из-за которых внешний разработчик не собрал бы рабочий фронт: - README описывал Phantom, swap ввод/вывод (POST /api/pump/swap), STUB-ключи и Фазу 1 — ничего этого в index.html нет. Указан нерабочий API base (smart-updown.binom.pw вместо testfront.binom.pw) и адрес контракта FMM…. «Ставка через поллинг» — поллинга нет, события по WS. - API.md держал раздел «часть ставок зависает без исхода» со статусом «не исправлено» — баг закрыт 14.09.2026 в контракте. По этой доке писали бы обходной код под проблему, которой нет. README переписан под фактический index.html: HTTP-шлюз без Phantom, сценарий кошелёк→фаусет→ставка→WS-исход, три исхода, правило 409. Секция API.md заменена на «Ничья при exitPrice == entryPrice» (штатный исход, доля ~трети), историческая сноска на SEC-9 сохранена. Проверено: полный сценарий снаружи по новой доке проходит (кошелёк → фаусет 10000 → ставка id=44 → исход по балансу). --- API.md | 27 +++++++++--------------- README.md | 62 +++++++++++++++++++++++++++---------------------------- 2 files changed, 41 insertions(+), 48 deletions(-) diff --git a/API.md b/API.md index 1c36b20..1d444b6 100644 --- a/API.md +++ b/API.md @@ -144,27 +144,20 @@ await fetch(`${BASE}/bet`, { --- -## ⚠️ Известная проблема: часть ставок зависает без исхода +## Ничья при `exitPrice == entryPrice` -**Симптом:** пришло `bet_open`, а `bet_closed` не приходит вообще; повторная ставка с того же -адреса вечно отвечает `409`. +Если цена на момент экспирации в точности равна цене входа, ставка **не зависает**: +контракт возвращает игроку **ровно сумму ставки без множителя**, ставка переходит в +статус `3`, по WS уходит `bet_closed` со `statusName: "refunded"`. -**Причина:** если цена на момент экспирации в точности равна цене входа, контракт -(`close_bet.rs:66`) молча выходит `return Ok(())` — статус остаётся `open`, ставка не -финализируется. А поскольку цена выхода берётся по **фиксированному** моменту экспирации, -повторные попытки планировщика получают ту же самую пару значений — и цикл не заканчивается -никогда (лог: `settle: #N still open (exit==entry at …), will retry`). +Доля таких окон — около **трети** ставок (замер 33.6 % на 34 769 окнах). Это **нормальный +штатный исход**, а не ошибка: клиенту надо просто показать третий вид результата. -**Масштаб (замер на 580 минутах живой истории, 34 769 окон):** **33.6 %** ставок попадают в -равные цены — **примерно каждая третья**. +Рекомендация фронту: обрабатывать **три** исхода `bet_closed` (`payout_done` / `house_won` +/ `refunded`) и не показывать `refunded` как проигрыш. -**Что это значит для фронта:** каждая третья ставка не завершится, а игрок потеряет -возможность играть с этого адреса (правило «одна открытая ставка» + `409`). -**Обходите:** для каждого игрока используйте новый адрес на ставку, либо показывайте -«ставка в ожидании». - -**Статус:** не исправлено, ждёт решения владельца (политика ничьей / закрытие соседней ценой -из истории). Подробности — `pump-game-ops/docs/SECURITY.md`, пункт **SEC-9**. +> Исторически (до 14.09.2026) такие ставки зависали навсегда; разбор — +> `pump-game-ops/docs/SECURITY.md`, пункт `SEC-9`. --- diff --git a/README.md b/README.md index 4f2e858..75fe464 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,46 @@ # test-front — технический тестовый фронт (Binary Rocket) -Чисто технический веб-дашборд для **ручного тестирования механики экономики** -(пополнение фантиками → ставка → вывод) БЕЗ Unity. Только кнопки + вывод технической -информации и лог. Никакой «красоты» — он для гонок сценариев. +Чисто технический веб-дашборд для **ручной проверки механики** через HTTP-шлюз: +кнопки + лог. Без Phantom, без swap, без вывода средств — только постановка ставок +фантиками и наблюдение за событиями. ## Зачем -Unity-фронт (`fun-game-front2`) хорош для продакшена, но для быстрых итераций по -экономике (swap ввод/вывод, ставка фантиками, поллинг результата) он тяжёлый. -Этот фронт дёргает те же эндпоинты бэкенда и даёт мгновенный отклик. +Технический пульт для проверки контракта «вручную»: быстро прогнать сценарий +«создать кошелёк → пополнить тестовым фаусетом → поставить → дождаться исхода». +Полный контракт API (HTTP + WS, поля событий, коды ошибок) — **[API.md](API.md)**. ## Возможности -- Подключение Phantom, показ адреса. -- Отображение баланса: **фантики** (токен Binary Rocket) + SOL. -- **Пополнить** — swap SOL→фантики через `POST /api/pump/swap` (подпись в Phantom). -- **Вывести** — swap фантики→SOL. -- **Ставка** (вверх/вниз) в фантиках через контракт: `GET /api/state` → - `POST /api/bet` → **события по WebSocket** (`bet_open` при постановке, `bet_closed` при - расчёте). Поллинг не нужен: шлюз закрывает ставку сам по таймеру. - Полный контракт API (HTTP + WS, поля событий, ошибки) — **[API.md](API.md)**. +- Поля в шапке: **Шлюз (API)**, **WS URL**, **Адрес**. +- **Создать кошелёк** — генерирует новый custodial-адрес через шлюз. +- **Пополнить кошелёк** — тестовый фаусет: наливает SOL и фантики. +- **Сделать ставку** — `POST /api/bet` (`side` `UP`/`DOWN`, `amountUnits`). +- События по **WebSocket** (`price`, `bet_open`, `bet_closed`) — поллинга нет. - Лог всех действий + кнопки «Копировать» / «Очистить». ## Как пользоваться -1. Открыть `index.html` (или раздать через любой статик-хостинг / nginx). -2. В шапке задать конфиг: - - **API base** — бэкенд (напр. `https://smart-updown.binom.pw`). - - **RPC** — публичный Solana RPC (напр. `https://rpc.solanatracker.io/public`). - - **Program** — адрес контракта (по умолч. `FMM...`). - - **Token mint** — адрес mint наших фантиков. -3. Подключить Phantom. -4. Гонять сценарии: пополнить → сделать ставку → дождаться исхода → вывести. +1. Открыть `https://testfront.binom.pw/` — `index.html` отдаётся из куба + (namespace `game`). Поле «Шлюз (API)» можно оставить пустым — фронт возьмёт + свой адрес. +2. Нажать **Создать кошелёк** — в поле «Адрес» появится custodial-адрес. +3. Нажать **Пополнить кошелёк** — тестовый фаусет нальёт SOL и фантики. +4. Выбрать сторону (`UP` / `DOWN`) и сумму (в пределах `minAmountHuman` / + `maxAmountHuman` из `/api/state`: `100` … `10000` фантиков) → **Сделать ставку**. +5. Результат придёт сам по WS примерно через `expirySeconds` (15 с). -> Примечания -> - Фронт читает/пишет токен-аккаунты через RPC; для Token-2022 decimals читается из mint. -> - STUB-ключи create_bet пока зашиты под SOL-версию контракта. Когда контракт переведут -> на токен (Фаза 1), этот блок обновить под токеновые ключи. -> - API base должен отдавать CORS (nginx-прокси), иначе браузер заблокирует fetch. +Три возможных исхода ставки: +- **выиграл** — `statusName: "payout_done"`, выплата с множителем; +- **проиграл** — `statusName: "house_won"`, ставка остаётся в ваулте; +- **возврат при ничьей** — `statusName: "refunded"`, залог возвращён ровно + суммой ставки без множителя (подробнее — [API.md](API.md), раздел + «Ничья при `exitPrice == entryPrice`»). + +> Правило: **одна открытая ставка на адрес** — вторая ставка с того же адреса +> получит `409`. Дождитесь `bet_closed` по WS, прежде чем ставить снова. ## Статус -- [x] каркас: балансы, swap ввод/вывод -- [x] ставка вверх/вниз через контракт (поллинг) -- [ ] перевести подпись под токеновую версию контракта (после Фазы 1) -- [ ] реальный провайдер цены вместо RandomPriceSource (за нами) \ No newline at end of file + +- [x] каркас: кошелёк, фаусет, ставка, события по WS +- [x] контракт: возврат при ничьей (`exitPrice == entryPrice`) \ No newline at end of file