Caffeine fb9a7f4e8b feat(relayer): migrate to SPL-token (фантики)
- ops: readGlobal читает vaultBalance (getTokenAccountBalance), createBet/closeBet передают bettorToken/vaultToken/tokenProgram, ensureVaultFunded наливает токен (mintTo, allowOwnerOffCurve)
- pda: vaultPda([global,vault]), config:.env.new SMART_TOKEN_MINT, суммы в токен-единицах
- check.ts: 14 проверок сигнатур создания create/close под новым токеновым IDL
- @solana/spl-token dependency; .gitignore + node_modules/dist
2026-09-10 00:19:21 +03:00

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)

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 (админ + закрытие ставок)

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. Деплой в новом окружении (если уже есть валидатор, без перезапуска)

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):

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 экспирация (сек)
S
Description
Смарт-контракт Binary Rocket: игра вверх/вниз, валюту ставок переводим на наши фантики (SPL-токен). Копия Smart-game, не трогаем оригинал.
Readme 663 KiB
Languages
TypeScript 81.8%
Rust 16.6%
Shell 0.9%
Go Template 0.6%
Dockerfile 0.1%