f105c1adff
- корень 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
111 lines
11 KiB
Markdown
111 lines
11 KiB
Markdown
# 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/`. |