Solana Wallet Manager: кошельки, ledger и безопасные транзакции
Кейс · Solana · FinTech · Laravel · 2026
Закрытая административная система управляет Solana-кошельками и финансовыми операциями: создаёт зашифрованные кошельки, синхронизирует SOL и SPL, проводит каждое списание через неизменяемый ledger, outbox, резервирование и сверку с блокчейном. Проект развёрнут в Devnet; Mainnet и финансовая отправка по умолчанию заблокированы.
Коротко: это не интерфейс «отправить монеты», а финансовый backend, в котором неоднозначный ответ RPC не превращается ни в повторную отправку, ни в преждевременный возврат резерва.
Задача: управлять кошельками без финансовых догадок
Обычной панели с балансом и кнопкой перевода недостаточно. Процесс может завершиться между подписью транзакции и ответом RPC; сеть может принять байты, а приложение — получить timeout. Если в этот момент автоматически повторить отправку, возникнет двойное списание. Если сразу вернуть резерв, внутренний баланс разойдётся с блокчейном.
Поэтому проект разделяет намерение пользователя, техническую попытку отправки, наблюдаемое движение в сети и бухгалтерскую запись. Каждая сущность хранит собственную историю и не подменяет соседнюю.
Что получает оператор
Управляемые кошельки
Создание Devnet-кошельков, отдельная Treasury-роль, публичные адреса, QR-код получения, баланс SOL и SPL-токенов.
История сети
Фоновая синхронизация баланса и подписей, разбор движений и ссылки на Solana Explorer с правильным cluster.
Финансовые операции
Статусы, попытки, резерв, ledger, сверки и восстановление собраны в одной карточке без редактирования финансовых фактов.
Контроль эксплуатации
Health-панель, метрики, очередь, outbox, heartbeat планировщика, предупреждения и отдельная очередь ручной проверки.
Единственный путь исходящей транзакции
В production-коде нет второго «короткого» метода отправки SOL или SPL. Экономическое намерение проходит один и тот же конвейер, а архитектурные тесты проверяют, что новый обходной вызов подписи или sendTransaction не появился.
Намерение и идемпотентность
Запрос фиксируется как неизменяемая FinancialOperation. Один ключ с теми же данными возвращает прежний результат; тот же ключ с другой суммой или адресом считается конфликтом.
intent · fingerprint · outboxРезерв
Средства резервируются атомарно до подписи. Доступный баланс вычисляется как подтверждённый минус активные резервы, а суммы хранятся целыми строками без float.
ledger · exact amount · lockПодготовка и отправка
Отдельная TransactionAttempt получает blockhash, подписывается в памяти и пересекает сетевую границу ровно один раз. Подписанные байты и приватный ключ не сохраняются.
prepare · sign · submit onceСверка
Фоновый процесс проверяет подпись и разбирает инструкцию: источник, назначение, актив, mint и точную сумму. Только совпавшее подтверждённое движение закрывает резерв.
reconciliation · chain evidenceSettlement или ручная проверка
Подтверждение создаёт settlement один раз. Несовпадение, противоречивые данные провайдеров или неизвестный результат оставляют резерв на месте и поднимают инцидент.
settle once · manual review
Что происходит при timeout после отправки
Известно, что отправки не было
Ошибка до сетевой границы или однозначный preflight reject завершает попытку; резерв можно освободить по заданному переходу состояния.
Транзакция принята
Подпись сохраняется как публичный идентификатор, операция остаётся зарезервированной и переходит к проверке подтверждения.
Результат неизвестен
EOF, reset или timeout после начала отправки получают статус unknown. Повторной отправки нет — только поиск исходной транзакции.
Есть расхождение
Другая сумма, получатель, mint или внешний исходящий перевод Treasury не исправляются автоматически и требуют разбора оператором.
Ledger, история сети и аудит — разные источники
Ledger отвечает на вопрос, почему изменился внутренний финансовый баланс. Blockchain movement хранит наблюдаемое событие Solana. Audit log фиксирует действие пользователя или администратора. Reconciliation связывает ожидаемую операцию с доказательством из сети.
Такое разделение позволяет повторно прочитать один и тот же signature, перезапустить job после потери ACK или увидеть одно движение со стороны двух управляемых кошельков — и не создать второе зачисление или settlement.
Доступ и хранение ключей
- Вход без общего пароля. Сначала проверяется существующий email, затем короткоживущий одноразовый код и TOTP из приложения-аутентификатора.
- Секреты зашифрованы. Приватный материал хранится через Laravel encryption и расшифровывается только в памяти непосредственно для подписи.
- Снаружи нет MySQL и Redis. База и очередь находятся во внутренней Docker-сети; публичный HTTPS завершается на внешнем reverse proxy.
- Админка не редактирует финансовую историю. Можно оставить append-only заметку, повторно запустить безопасную сверку или анализ восстановления, но нельзя вручную «подтвердить» перевод, переписать сумму или удалить ledger.
Наблюдаемость без автоматического «ремонта денег»
Система следит за RPC, очередями, outbox, reconciliation, recovery и scheduler heartbeat. Метрики используют только низкокардинальные метки: в них не попадают адреса, подписи, UUID операций, RPC URL или произвольные ответы провайдера.
Предупреждение можно подтвердить или закрыть с комментарием, но это не изменит финансовое состояние. Мониторинг сообщает о проблеме; решение о settlement или release остаётся за правилами ledger и reconciliation.
Стек и эксплуатация
Честные границы текущего релиза
Развёрнутая конфигурация зафиксирована на Solana Devnet. Три независимых флага запрещают новые финансовые операции, низкоуровневую отправку и Mainnet-транзакции. Mint MMCP не задан; выпуск токена и любые Mainnet-записи не входят в этот релиз.
Историческая сверка явно помечена как неполная: текущий scanner ограничен последними 25 подписями на адрес или token account. Интерфейс показывает это ограничение оператору и не выдаёт частичный обзор за полную историю.
Результат
Получился изолированный Wallet Manager, в котором создание кошелька, наблюдение за сетью и финансовое исполнение имеют разные границы ответственности. Самая важная часть — поведение в неопределённости: система не повторяет отправку наугад и не освобождает деньги без достаточного blockchain-доказательства.
Архитектура готовит проект к контролируемому запуску: Devnet позволяет проверить сценарии, health и аудит дают оператору картину состояния, а отдельная процедура Mainnet-readiness не позволяет включить боевую сеть случайной настройкой.
Solana · Laravel 13 · PHP 8.4 · MySQL · Redis · Ledger · Outbox · Reconciliation · TOTP · Docker




