Files
Porfiry f105c1adff ADR-011: статика игры вынесена из куба на nginx (LXC 152 game-web), версии каталогами
- корень smart-updown.binom.pw -> nginx на Proxmox (LXC 152, 192.168.76.152)
- /api,/ws -> куб (router PathPrefix на внешнем Traefik VDS), куб не менялся
- версионирование: /opt/game/releases/<N>/, активная = симлинк /opt/game/current
- tools/proxmox-nginx: unpack-release.sh, publish-release.sh, game.nginx.conf, smart-updown.traefik.yaml, README
- приёмка живьём: корень 200 nginx/1.24.0 (Ubuntu), /27/ /28/ 200, /api/state 200 JSON, /api/ws цена, autoclose-check 9/9
- питфоллы: OCI-manifest в skopeo dir-дампе, слэш в конце версии, /solana-rpc мимо PathPrefix /api
2026-09-15 17:07:30 +03:00

111 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# pump-game-ops — мета-репозиторий проекта «Бинарная ракета» (Binary Rocket)
Единая точка для **сервисной документации, принятых решений и списка задач** проекта
мемкойн-игры на pump.fun. Кода тут нет — только то, что связывает компоненты между собой
(индексация), и что не живёт в конкретных репозиториях.
## Что это и зачем
У нас много компонентов (фронт, бэкенд, контракт, релейер). Здесь мы ведём:
- **карту репозиториев** (кто за что отвечает, где какая часть),
- **журнал решений** (почему так, а не иначе — ADR),
- **экономику токена** (свой мемкойн, курс, decimals, mint-адреса),
- **список задач/статусы** (трекаем весь проект тут — включая задачи, встающие на
кросс-компонентные решения: `forkable`/`pivotable` и т.п.).
## Карта репозиториев
| # | Компонент | Репозиторий | Путь (локально) | Язык/стек | Роль |
|---|---|---|---|---|---|
| 1 | **Смарт-контракт (оригинал)** | `akovalenko/Smart-game` | `~/WORK/games/Smart-game` | Rust/Anchor (Solana) | игровая логика ставок вверх/вниз, ваулт, выплата (**SOL**, не трогаем) |
| 1b | **Смарт-контракт (фантики)** | `subochev/smart-updown-token` | `~/WORK/games/smart-updown-token` | Rust/Anchor (Solana) | копия Smart-game для перевода на наши фантики (SPL-токен) — **работаем тут** |
| 2 | **Бэкенд (релейер) — ⏸ ВЫКЛЮЧЕН** | `subochev/smart-updown-server` | `~/WORK/games/smart-updown-server` | Kotlin/Spring Boot + solanaj | канонический Kotlin-бэк, programId `3NWEK…` (в цепь не задеплоен, WS нет). **Выключен 15.09.2026** (`replicas=0`, ingress удалён) — оба домена переведены на TS-шлюз; см. ADR-009 |
| 2b | **Игровой шлюз (боевой)** | `subochev/smart-updown-token` → `relayer/` | `~/WORK/games/smart-updown-token/relayer` | TypeScript (Node 22) | **кастодиальный TS-шлюз `:8895`** — реально обслуживает оба домена: ставки, кран, расчёт, WS. Контракт `9ALs…` |
| 3 | **Фронт (Unity)** | `subochev/fun-game-front2` | `~/WORK/games/fun-game-front2` | Unity WebGL + Phantom | UI, кошелёк, подпись create_bet |
| 4 | **Тестовый фронт** | `subochev/test-front` | `~/WORK/games/test-front` | HTML/JS + Phantom | технический дашборд для ручного теста экономики (пополнение/ставка/вывод) без Unity |
| 5 | **Мета-репо (этот)** | `subochev/pump-game-ops` | `~/WORK/games/pump-game-ops` | Markdown | документация, решения, задачи |
> Примечания:
> - Remote-адреса: `https://git.binom.pw/<owner>/<repo>.git`.
> - Ветки: `smart-updown-server` и `fun-game-front2` — `main`; `Smart-game` сейчас на `extract-sources`.
> - ⚠️ **Актуальный бэк — TS-шлюз (пункт 2b), не Kotlin.** Kotlin-бэк выключен, но его код и образ
> целы: откат — `kubectl scale deploy -n game smart-updown-server-smart-updown-server --replicas=1`
> плюс возврат его ingress из `/root/bak-smart-updown-15.09/` (см. ADR-009).
## Внешние зависимости (upstream)
binance-market — это **не часть игры**, а **общий инфраструктурный сервис инвест-кластера**,
который игра «Бинарная ракета» использует как **upstream-провайдер цены SOL**
(вместо заглушки `RandomPriceSource`, см. ADR-006 → ADR-007).
| Компонент | Репозиторий | Путь (локально) | Язык/стек | Роль для игры |
|---|---|---|---|---|
| **binance-market** (upstream цены) | `subochev/binance-market` | `~/common-projects/invest/binance-market` | Kotlin / Spring Boot 3.3.5 WebFlux | собирает рыночные данные с Binance (Binance WS: `depth@100ms` + `aggTrade`); выдаёт last-trade через `GET /ws/price?symbol=<sym>` (порт 8080) и через NATS-топик `market.price.<symbol>`; релейер использует это как **`PriceSource`** (см. ADR-007) |
Контракт между игрой и сервисом:
- **В кластере (предпочтительно):** подписка на NATS-топик `market.price.solusdt` (адрес задаётся
в релейере; прод-адрес см. в его конфиге).
- **Снаружи кластера / тест:** WebSocket `ws://<binance-market-хост>:8080/ws/price?symbol=solusdt`.
- Покрытие символов сейчас: `btcusdt,ethusdt,solusdt` (конфиг `binance.symbols` в values.yaml чарта).
## Принятые решения (сводка)
Ссылка на полный журнал — `docs/DECISIONS.md`. Ключевое:
- **Свой токен** на pump.fun (мемкойн Binary Rocket), не чужой.
- **Курс — живой рыночный** (Способ 1): ставки в фантиках, ввод/вывод через swap.
- **decimals = 6**, токен через **Token-2022** (по доке pump.fun `create_v2`).
- Ставки идут **фантиками через контракт** → контракт переводить с SOL на SPL-токен (это ядро).
- **Цена SOL** — от внешнего upstream `binance-market` (ADR-007), не своя оракуль-логика.
Как ходят данные (кто кому что шлёт, включая согласие/подпись игрока) — `docs/FLOW.md`
(sequence-диаграммы: текущий localnet-режим без Phantom и целевой боевой с pump.fun+Phantom).
## Статус проекта (сводка)
Задачи и статусы — в `TASKS.md`. Здесь — только верхи (актуально на **2026-09-15**):
- [x] **Игра работает на живом стенде** — оба домена на ОДНОМ TS-шлюзе (ADR-009).
- [x] Цена SOL — из `binance-market` по NATS, раздача фронту по WS (ADR-007/008).
- [x] Авто-закрытие ставок на шлюзе, расчёт — **математика проверена 3/3** (выигрыш 1.3×.
проигрыш 0, ничья — возврат залога).
- [x] Фаза 5 — фронт (Unity WebGL) — **живой, деплоится тегами** (деплой-памятка в `TASKS.md`).
- [ ] **Перед mainnet:** закрыть `SEC-16` (безвозвратная утечка SOL с игрока) — правка контракта
+ редеплой; см. `docs/SECURITY.md`.
- [ ] Фаза 4 — задействовать свап-клиент (`pump.fun`) — **клиент готов**; Фаза 0/1 (экономика
токена, контракт на фантиках) — по `TASKS.md`.
## Карта деплоя (кто где живёт)
| Что | Где | Адрес/идентификатор |
|---|---|---|
| **k3s-кластер** | VM `192.168.76.120`, ns `game` | — |
| **Игровой бэк (боевой)** | TS-шлюз `updown-relayer`, сервис `testfront-gateway-smart-updown-relayer:8895` | оба домена: `/api`, `/ws` |
| **Домены** | `smart-updown.binom.pw` (Unity-игра), `testfront.binom.pw` (тех-дашборд) | один и тот же бэк |
| **Статика игры (корень `smart-updown.binom.pw`)** | **nginx на Proxmox, LXC 152 `game-web` (192.168.76.152)** | `/opt/game/releases/<N>/`, активная — `/opt/game/current` (ADR-011) |
| **Фронт игры (сборка)** | репозиторий `fun-game-front2` → образ `images.binom.pw/fun/game-front2:<тег>` | из образа извлекается статика и кладётся на nginx (`tools/proxmox-nginx/`) |
| **Ingress-пути (куб)** | **`smart-updown-api`** — `/api`,`/ws` (ВНЕ helm); `fun-game-front2-…` — только `/` (уже не обслуживает домен) | ADR-010 |
| **Маршрутизация корня** | внешний Traefik VDS: `/api`,`/ws` → куб `192.168.76.120`; всё остальное → nginx `192.168.76.152` | ADR-011 |
| **Solana localnet** | LXC 151 на Proxmox `192.168.76.66` | RPC `192.168.76.181:8899` |
| **Контракт (в цепи)** | `9ALs…S1fCpf` (фантики, 4 инструкции) | прод-игра работает тут |
| **Реестр образов** | `images.binom.pw` | — |
## Безопасность
**Чек-лист — `docs/SECURITY.md`** (пункты `SEC-1…SEC-16`; аудит живого стенда 2026-09-13,
дополнен приёмкой боевого домена 2026-09-15).
- **Закрыто:** отсутствие авто-закрытия (шлюз сам закрывает по расписанию), окно выбора момента
расчёта игроком (цена берётся из истории на момент экспирации), зависание при равных ценах
(`SEC-9` → возврат залога), `POST /close` удалён (404).
- 🔴 **Открыто, блокер перед mainnet — `SEC-16`:** рента PDA-аккаунта ставки (**1 559 040 lamports**,
= 0.00155904 SOL) списывается с кошелька **игрока** и **не возвращается никогда** (аккаунт не
закрывается). На тестах маскируется краном; на mainnet это реальные деньги игрока, тающие без
проигрыша. Лечение — `close = bettor` в `close_bet` + редеплой.
- **Остальное открытое:** NATS без аутентификации, `/bet` и `/faucet` без авторизации (на
тестовом стенде допустимо), отложенные `SEC-13…SEC-15`.
## Прочее
- Ночная экономика и mint-адреса: `docs/ECONOMY.md`.
- Разделы задач общего характера (мок/деплой/стабильность) — в `TASKS.md`.
- **Диагностические и приёмочные скрипты** (живой стенд) — в `tools/`, с питфоллами замера в
`tools/README.md`.
- **k8s-манифесты вне helm** (отдельный ingress `/api`,`/ws`) — в `k8s/`.