Files

150 lines
8.0 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.
# FLOW.md — как ходят данные: кто, кому и в какой момент (sequence-диаграммы)
**Репо:** `pump-game-ops` (мета-репо, документация). **Статус:** живой, дополняется.
Цель — раз и навсегда зафиксировать **порядок обмена сообщениями** между участниками
(фронт, бэкенд/релейер, контракт, RFС Solana, кошелёк, pump.fun), чтобы было понятно
«кто кому что шлёт и в какой момент», включая тонкость **согласия игрока (подписи)**.
Легенда участников:
- **Клиент (браузер / Unity WebGL)** — UI игрока.
- **Phantom** — браузерный кошелёк (держит приватный ключ игрока; **согласие = подпись**).
- **Бэкенд (релейер)** — наш сервер: строит/ретраслит ставки, держит ваулт-фандинг.
- **Контракт** — `smart-updown-token` на цепочке Solana (ваулт фантиков, create/close bet).
- **RPC Solana** — узел цепочки (localnet `192.168.76.199:8890`, на бою — публичный).
- **pump.fun** — меняльная лавка (на бою; SOL↔фантики по живому курсу).
---
## 1. КАК ЭТО РАБОТАЕТ СЕЙЧАС (localnet, тестовый пульт, БЕЗ pump.fun и без Phantom)
> Текущее состояние (см. `test-front`, `smart-updown-token/relayer`). Ставка подписывается
> **сервером** (custodial-кошелёк шлюза), кошелёк игрока в подписи НЕ участвует.
> Фантики и SOL **накинуты вручную** (тест), обменника нет.
```mermaid
sequenceDiagram
participant U as Игрок (браузер)
participant F as Пульт (test-front)
participant G as HTTP-шлюз gateway.ts
participant S as Контракт (localnet)
participant R as RPC Solana (8890)
U->>F: открыть страницу, «Обновить state»
F->>G: GET /state
G->>S: readGlobal()
S-->>G: min/max/expiry/vault/counter
G-->>F: JSON (лимиты, vault)
F-->>U: показать лимиты/ваулт
U->>F: «Проверить баланс» (адрес)
F->>G: GET /balance/{address}
G->>R: getBalance, getTokenAccountBalance (ATA)
R-->>G: SOL + фантики
G-->>F: {sol, tokenHuman}
F-->>U: «Фантики: N, SOL: M»
U->>F: «Сделать ставку» (сумма, сторона)
F->>G: POST /bet {side, amountUnits, address?}
G->>S: createBet (подпись КЛЮЧОМ ШЛЮЗА)
S-->>G: tx (в сеть)
G-->>F: {id, bettor, tx}
F-->>U: «Ставка id=X ушла»
Note over U,G: пауза ~15с (expiry) — контракт не даёт закрыть раньше
U->>F: «Закрыть ставку» (id)
F->>G: POST /close {id}
G->>S: closeBet (по текущей цене, подпись шлюза)
S-->>G: исход (payout_done / house_won)
G-->>F: {statusName, exitPrice}
F-->>U: «выиграл» / «дом выиграл»
```
**Кто подписывает согласие игрока?** В этом режиме — **никто из игрока**. Согласие
даётся **нажатием кнопки** в пульте; подписывает **сервер (custodial-ключ шлюза)**.
Настоящего вывода/пополнения нет — балансы накинуты.
---
## 2. КАК ЭТО ДОЛЖНО РАБОТАТЬ ПО-НАСТОЯЩЕМУ (боевой, pump.fun + Phantom + подпись игрока)
> Целевая архитектура (фазы devnet→mainnet). Здесь **согласие игрока = подпись в Phantom**,
> а обмен делается через **pump.fun** по живому курсу.
```mermaid
sequenceDiagram
participant U as Игрок
participant F as Фронт (Unity/WebGL)
participant P as Phantom (кошелёк)
participant B as Бэкенд (релейер)
participant S as Контракт (фантики)
participant R as RPC Solana
participant PF as pump.fun (лавка)
%% --- ПОПОЛНЕНИЕ: SOL -> фантики ---
U->>F: «Пополнить» (SOL)
F->>P: запросить подпись swap (акис consent)
P-->>U: «Согласен(на) на обмен?»
U-->>P: ОК
P-->>F: подписанная swap-транзакция
F->>B: POST /api/pump/swap (подпись)
B->>PF: swap SOL→фантики (живой курс)
PF->>R: обработать swap
R-->>B: фантики на ATA игрока
B-->>F: ok
F-->>U: «Баланс +N фантиков»
%% --- СТАВКА ---
U->>F: «Поставить» (сумма, сторона)
F->>P: построить createBet, запросить подпись
P-->>U: «Подтвердить ставку?»
U-->>P: ОК (согласие)
P-->>F: подписанная createBet
F->>B: POST /api/bet (ретрансляция)
B->>R: sendRawTransaction (ваулт→контракт)
R-->>B: tx принята
B-->>F: {id, status}
F-->>U: «Ставка ушла, ждём исход»
%% --- ВЫВОД: фантики -> SOL ---
U->>F: «Вывести» (фантики)
F->>P: запросить подпись swap
P-->>U: «Согласен(на) на обмен?»
U-->>P: ОК
P-->>F: подписанный swap
F->>B: POST /api/pump/swap (обратный)
B->>PF: swap фантики→SOL (живой курс)
PF->>R: обработать
R-->>B: SOL на кошелёк игрока
B-->>F: ok
F-->>U: «Баланс -N фантиков, +SOL»
```
**Главное отличие от текущего:** в бою **согласие игрока** — это **криптографическая
подпись в Phantom** на каждое действие с деньгами (пополнение, ставка, вывод). Сервер
**никогда не видит приватный ключ игрока** — только подписанную транзакцию, которую
ретранслирует в сеть. Пульт без Phantom (раздел 1) — только для гонки механики на localnet.
---
## 3. Сравнение «сейчас» vs «боевой»
| Аспект | Сейчас (localnet) | Боевой (devnet→mainnet) |
|---|---|---|
| Согласие игрока | кнопка пульта | **подпись в Phantom** |
| Кто подписывает ставку | сервер (custodial ключ шлюза) | **игрок (Phantom)** |
| Пополнение/вывод | нет (балансы накинуты) | **swap через pump.fun** по живому курсу |
| Сеть | localnet (192.168.76.199:8890) | devnet→mainnet (реальная Solana) |
| Валюта | тестовые фантики (накинуты) | REAL фантики за реальный SOL |
| Приватный ключ | на сервере (custodial) | **только в Phantom игрока** |
---
## 4. Опорные репозитории/файлы
- Пульт без Phantom: `subochev/test-front` → `index.html` (дёргает шлюз по `/api/...`).
- HTTP-шлюз: `subochev/smart-updown-token` → `relayer/src/gateway.ts` (`/state`,
`/balance/{address}`, `/bet`, `/close`, `/faucet/{address}` — последний только localnet).
- Релейер (серверный казначей): там же → `relayer/`.
- Бэкенд-свап-клиент pump.fun: `subochev/smart-updown-server` → `src/main/kotlin/.../PumpApiClient.kt`,
`PumpApiController.kt` (`/api/pump/swap`).
- Публика: `deploy/flows` (этот файл).