# SHiNE-promo-solana-devnet Временное промо-приложение для тестеров Web3-социальной сети SHiNE / «Сияние» в Solana Devnet. Основной сценарий: - приложение SHiNE открывает страницу вида `/?wallet=SOLANA_PUBLIC_KEY`; - пользователь вводит имя и промокод; - backend проверяет промокод и отправляет **реальную** devnet-транзакцию на `0.1 SOL`; - использованный промокод фиксируется в файле и больше не может быть применён. ## Стек - Java 21 - Spring Boot - Gradle - Thymeleaf + HTML/CSS/JS (server-side UI) ## Локальный запуск 1. Скопируйте пример настроек: ```bash cp config/application.example.properties src/main/resources/application.properties ``` 2. Положите реальный keypair-файл Solana CLI формата в: ```text config/devnet-wallet.json ``` 3. Запустите: ```bash ./gradlew bootRun ``` Приложение будет доступно на `http://localhost:8021`. ## Как указать порт По умолчанию используется: ```properties server.port=8021 ``` Изменить можно: - в `src/main/resources/application.properties`; - или через параметр запуска: ```bash ./gradlew bootRun --args='--server.port=8090' ``` ## Настройка Solana RPC Devnet Параметр: ```properties solana.rpc.url=https://api.devnet.solana.com ``` Для другого RPC достаточно заменить URL в properties. ## Настройка devnet keypair - Файл должен быть в формате Solana keypair JSON: массив из 64 чисел (`0..255`). - Пример лежит в `config/devnet-wallet.example.json`. - Рабочий файл: `config/devnet-wallet.json`. Важно: настоящий keypair **нельзя коммитить в GitHub**. Он добавлен в `.gitignore`. ## Где лежат промокоды Файл: ```text data/promo-codes.txt ``` ## Где лежит файл использованных промокодов Файл: ```text data/promo-used.txt ``` ## Формат `promo-codes.txt` - одна строка = один промокод; - пустые строки игнорируются; - строки с `#` игнорируются как комментарии; - промокод должен соответствовать regex: `[a-z0-9]{8}`. ## Формат `promo-used.txt` Каждая запись в формате: ```text promoCode | wallet | name | yyyy.MM.dd HH:mm | signature ``` Пример: ```text aidar2km | 8xF...abc | Иван Петров | 2026.04.27 18:45 | 5xTxSignature... ``` ## Пример URL ```text http://localhost:8021/?wallet=8zYQ...DevnetAddress ``` ## Пример API-запроса ```bash curl -X POST http://localhost:8021/api/promo/top-up \ -H "Content-Type: application/json" \ -d '{ "wallet":"SOLANA_PUBLIC_KEY", "name":"Иван Петров", "promoCode":"aidar2km" }' ``` ## Проверка транзакции в Solana Explorer Devnet Explorer URL формируется по шаблону: ```text https://explorer.solana.com/tx/{signature}?cluster=devnet ``` ## Сборка jar через Gradle ```bash ./gradlew clean build ``` JAR: ```text build/libs/SHiNE-promo-solana-devnet.jar ``` ## Запуск jar ```bash java -jar build/libs/SHiNE-promo-solana-devnet.jar ``` ## Health endpoint ```text GET /health ``` Ответ: ```json { "status": "ok", "app": "SHiNE-promo-solana-devnet" } ``` ## Логи - логируется старт приложения; - логируются успешные пополнения; - логируются ошибки транзакций; - приватный ключ не логируется. ## Gradle-задачи для серверного деплоя В `build.gradle` добавлены задачи: - `buildServerBundle` — готовит bundle в `build/server-bundle`; - `deployToServer` — копирует JAR и `application.properties` на сервер и перезапускает systemd-сервис. Запуск: ```bash ./gradlew deployToServer ``` Переопределение хоста/пути: ```bash ./gradlew deployToServer \ -PdeployHost=user@10.147.20.7 \ -PdeployPath=/home/user/docker/SHiNE-promo-solana-devnet \ -PdeployService=SHiNE-promo-solana-devnet ```