148 lines
8.3 KiB
Markdown
148 lines
8.3 KiB
Markdown
# Smart-Updown — пакет развёртывания (localnet)
|
||
|
||
Бинарная игра UP/DOWN на цену SOL. Пользователь ставит на направление (UP/DOWN)
|
||
на 15 секунд; при выигрыше получает ставку + 30% (1.3x). Дом (контракт) — оппонент.
|
||
Цена берётся off-chain релеером (он же админ) с вашей БД; SOL хранится в ваулте (PDA `global`).
|
||
|
||
Программа: **Anchor 0.31.1 + Solana 2.x (Rust)**, собирается в **SBPFv3** —
|
||
совместимо с агave-валидатором 4.2.x (= текущий mainnet Solana).
|
||
|
||
> **Фронтенд игры** живёт в отдельном репозитории:
|
||
> **https://git.binom.pw/subochev/fun-game-front2**
|
||
> (сюда деплоится/подключается клиент к контракту; бэкенд — допиливается следом).
|
||
|
||
---
|
||
|
||
## Состав пакета
|
||
|
||
```
|
||
smart-updown/
|
||
├── deploy/
|
||
│ ├── smart_updown.so # скомпилированная программа (SBF-байткод, кроссплатформенный)
|
||
│ └── smart_updown-keypair.json # authority-ключар программы (ID = 9ALsnx...)
|
||
├── idl/
|
||
│ ├── smart_updown.json # IDL (для клиента)
|
||
│ └── smart_updown.ts # типы TypeScript для клиента
|
||
├── relayer/ # off-chain релеер (админ + закрытие ставок)
|
||
│ ├── package.json
|
||
│ ├── tsconfig.json
|
||
│ ├── .env.example
|
||
│ ├── idl/ # копия IDL для клиента
|
||
│ └── src/
|
||
│ ├── index.ts # главный цикл
|
||
│ ├── ops.ts # initialize / createBet / closeBet / fundVault
|
||
│ ├── pda.ts # вывод PDA
|
||
│ ├── program.ts # клиент из IDL
|
||
│ ├── priceSource.ts # ЗАГЛУШКА цены SOL (вставить свой запрос к БД)
|
||
│ └── frontStub.ts # ЗАГЛУШКА фронта (откуда приходит выбор пользователя)
|
||
├── program/ # исходники контракта (опционально, для пересборки)
|
||
│ ├── Anchor.toml
|
||
│ ├── Cargo.toml / Cargo.lock
|
||
│ ├── rust-toolchain.toml # пинит Rust 1.89.0
|
||
│ └── programs/smart-updown/{src,tests}
|
||
├── deploy-localnet.sh # развёртывание на localnet
|
||
└── README.md
|
||
```
|
||
|
||
---
|
||
|
||
## 1. Требования (Linux x86_64)
|
||
|
||
- **Solana CLI (Agave)** — даёт `solana-test-validator`, `solana program deploy`,
|
||
`cargo build-sbf`, `solana-keygen`. Установка:
|
||
`sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"`
|
||
- **Node.js 18+ / npm** — для relayer.
|
||
- (опционально) **Rust 1.85+** через rustup — только если пересобираете программу.
|
||
|
||
> **Важно про `.so` и SBPF-версию**: контракт собирается под конкретный SBPF-архитектуру
|
||
> (здесь — **SBPFv3**, под агave 4.2.x). Собранный `.so` кроссплатформенный
|
||
> по CPU хоста (работает и с macOS-сборкой), но **должен совпадать по SBPF-версии
|
||
> с валидатором**, иначе деплой падает (`Detected sbpf_version ... not enabled`).
|
||
> При сборке через `cargo build-sbf --tools-version v1.57` — артефакт SBPFv3.
|
||
|
||
## 2. Развёртывание (localnet)
|
||
|
||
```bash
|
||
chmod +x deploy-localnet.sh
|
||
./deploy-localnet.sh
|
||
```
|
||
|
||
Скрипт:
|
||
1. переключает `solana config` на `http://127.0.0.1:8899`;
|
||
2. запускает `solana-test-validator` с программой (`--bpf-program 9ALsnx...`);
|
||
3. проверяет, что программа поднята под ID `9ALsnxXNzDBv3mokngCHbruRTWUZiWR7pf7vswS1fCpf`.
|
||
|
||
Подытог — программа доступна на localnet под тем же адресом, что зашит в IDL.
|
||
|
||
## 3. Relayer (админ + закрытие ставок)
|
||
|
||
```bash
|
||
cd relayer
|
||
npm install
|
||
cp .env.example .env # при желании поправить значения
|
||
# инициализация контракта (ваулт/Global):
|
||
npm run init
|
||
# один прогон ставки:
|
||
npm run run
|
||
# непрерывный цикл:
|
||
npm run loop
|
||
```
|
||
|
||
`init` создаёт `Global` (админ + релеер = keypair из `SMART_ADMIN_KEYPAIR`,
|
||
по умолчанию `~/.config/solana/id.json`). На localnet скрипт сам делает airDrop
|
||
bettor'ам и догружает ваулт банка. На mainnet airDrop выключите
|
||
(`SMART_ALLOW_AIRDROP=0`) и пополняйте ваулт переводами с админа.
|
||
|
||
> AirDrop на localnet выполняется от keypair, настроенного в `solana config`.
|
||
> Убедитесь, что он существует и имеет SOL (в скрипте деплоя это `id.json`,
|
||
> см. `solana config get`).
|
||
|
||
## 4. Заглушки — куда вставить реальное
|
||
|
||
- `relayer/src/priceSource.ts` — функция `getPrice()`. **Замените** на запрос цены
|
||
SOL из вашей БД. Единицы любые, главное согласованность между entry и exit.
|
||
- `relayer/src/frontStub.ts` — функция `nextBetRequest()`. **Замените** на приём
|
||
со стороны фронта: направление (UP/DOWN) и сумма, которые выбрал пользователь.
|
||
|
||
## 5. Деплой в новом окружении (если уже есть валидатор, без перезапуска)
|
||
|
||
```bash
|
||
solana config set --url http://127.0.0.1:8899
|
||
solana program deploy --program-id deploy/smart_updown-keypair.json deploy/smart_updown.so
|
||
```
|
||
|
||
## 6. (Опционально) Пересборка программы из исходников + тесты
|
||
|
||
Сборка контракта под **SBPFv3** (для агave 4.2.x):
|
||
|
||
```bash
|
||
cd program
|
||
# собрать .so (SBPFv3, с entrypoint):
|
||
cargo build-sbf --tools-version v1.57 --manifest-path programs/smart-updown/Cargo.toml
|
||
# артефакт появится в program/target/deploy/smart_updown.so
|
||
# интеграционные тесты (solana-program-test 2.x, 10 кейсов):
|
||
SBF_OUT_DIR="$(pwd)/target/deploy" cargo test -p smart-updown
|
||
```
|
||
|
||
> `--tools-version v1.5x` критичен: v1.57 даёт rustc ≥1.85 (нужен для edition2024)
|
||
> и валидный `.so` с символом `entrypoint`. **Нюанс про SBPF-версии для тестов**:
|
||
> тестовый рантайм `solana-program-test` не грузит SBPFv3-ELF — он принимает максимум
|
||
> arch-v0. Поэтому тесты гоняются на `.so`, собранном под v0 (тот же код), а в
|
||
> прод деплоится SBPFv3-артефакт. Логика контракта одна — различается только arch-цель.
|
||
|
||
Если пересобираете, IDL не меняется, пока не меняете layout аккаунтов/инструкций.
|
||
При смене дискриминаторов (напр. уход от `#[discrim]` при миграции на anchor 0.31.1)
|
||
обязательно перегенерируйте IDL и обновите `relayer/idl/` и `idl/`.
|
||
|
||
## 7. Переменные окружения relayer (см. .env.example)
|
||
|
||
| Переменная | По умолчанию | Описание |
|
||
|---|---|---|
|
||
| `SMART_RPC_URL` | `http://127.0.0.1:8899` | RPC кластера |
|
||
| `SMART_ALLOW_AIRDROP` | `1` | airDrop bettors/ваулта (localnet) |
|
||
| `SMART_ADMIN_KEYPAIR` | `~/.config/solana/id.json` | keypair админа/релеера |
|
||
| `SMART_MIN_AMOUNT` | `100000000` | мин. ставка (лампорты) |
|
||
| `SMART_MAX_AMOUNT` | `10000000000` | макс. ставка (лампорты) |
|
||
| `SMART_MULTIPLIER_BPS` | `13000` | выплата 1.3x (bps) |
|
||
| `SMART_EXPIRY_SECONDS` | `15` | экспирация (сек) |
|