Что такое оператор Private Channels?
Оператор — это доверенная сущность с разрешениями на блокчейне, которая связывает Solana
Mainnet и сеть приватных каналов. Операторы регистрируются администратором
экземпляра через AddOperator, что создаёт Operator PDA на блокчейне;
без этого ни одна сторона не может вызвать ReleaseFunds. На практике оператор — это
организация или команда, запускающая сервисы, которые отслеживают депозиты, чеканят
токены на стороне канала, обнаруживают выводы средств и производят расчёты обратно в Mainnet.
Запуск экземпляра предоставляет вашим пользователям приватные высокообъёмные переводы, не
отображаемые в Solana Mainnet, мгновенную пропускную способность без комиссий сверх нативного Solana TPS
и управляемый доступ через RBAC.
Если вы разработчик, интегрирующийся с существующим экземпляром Private Channels, а не развёртывающий его, начните с Quickstart.
Перед началом работы
Предварительные требования
Зафиксируйте эти версии на хосте, чтобы они соответствовали образам Docker:
- Docker Engine 26+ (macOS Apple Silicon: включите «Docker VMM» в Settings -> Virtual Machine Options)
- Node.js 24.7.0 и pnpm 10.15.1
- Solana CLI 3.1.13 (Agave)
- Rust 1.91.0
- Yellowstone gRPC эндпоинт для Devnet (доступен у Helius, Triton, QuickNode)
Требования к сети и назначения портов по умолчанию см. в
docs/TECHNICAL_REQUIREMENTS.md
в репозитории.
Установите зафиксированный тулчейн Solana и прогрейте кэш SBF:
make install-toolchain
Сервисы
Запуск экземпляра Private Channels означает выполнение пяти постоянных обязанностей, каждая из которых обеспечивается выделенными контейнерами в стеке Docker Compose:
- Индексация Mainnet для депозитов —
indexer-solanaотслеживает Solana Mainnet на предмет событийDepositчерез Yellowstone gRPC;operator-solanaобрабатывает подтверждённые депозиты и чеканит эквивалентный баланс токенов в сети канала - Индексация канала для выводов —
indexer-private-channelопрашивает канал каждую секунду на предмет событий сжиганияWithdrawFundsи записывает ожидающие записи о выводах в базу данных - Высвобождение средств в Mainnet —
operator-private-channelобрабатывает ожидающие записи и вызываетReleaseFundsна Escrow Program с корректным доказательством исключения SMT - Управление корнем SMT —
operator-private-channelвызываетResetSmtRootавтоматически при ротации epoch дерева; проверкаverify_smt_exclusion_proofна блокчейне является последним рубежом защиты против несанкционированных выводов - Запуск шлюза и сервиса аутентификации — шлюз является единственной публичной
точкой входа для всего клиентского трафика; сервис аутентификации (опциональный) применяет
JWT/RBAC при установленном
JWT_SECRET
Полный перечень сервисов и назначения портов см. в Справочнике по конфигурации.
Примечание по безопасности: Порты узла записи и узла чтения привязаны только к loopback (
127.0.0.1), однако несколько других сервисов (шлюз, аутентификация, метрики оператора, Grafana, Prometheus, cAdvisor) по умолчанию публикуются на всех сетевых интерфейсах. Полную таблицу портов см. в Справочнике по конфигурации и закройте их брандмауэром перед любым публичным развёртыванием. RBAC распространяется только на собственные методы JSON-RPC шлюза, но не на эти другие сервисы.
Управление доступом: открытый режим и RBAC
По умолчанию шлюз принимает все соединения без токенов. Чтобы включить
RBAC на основе JWT, установите JWT_SECRET и запустите стек с --profile auth. См.
Аутентификация и роли для
полного справочника по конфигурации, включая настройку роли operator и
регистрацию кошельков пользователей.
Если вы включаете аутентификацию, добавьте следующее в ваше окружение перед запуском стека:
JWT_SECRET=<openssl rand -hex 32> # must match on gateway and auth serviceAUTH_PORT=8903
Настройка окружения
.env.devnet уже отслеживается в репозитории с заполненными значениями по умолчанию для devnet;
редактируйте его напрямую, не перегенерируя из .env.example,
иначе эти значения будут перезаписаны.
Заполните оставшиеся значения по мере прохождения шагов развёртывания ниже; некоторые
из них будут доступны только в середине процесса. Секреты указывайте в файле .env, игнорируемом git;
несекретные переменные — в .env.devnet.
Секреты — установите их немедленно:
POSTGRES_PASSWORD=<openssl rand -hex 32>POSTGRES_REPLICATION_PASSWORD=<openssl rand -hex 32>
Переменные, получаемые в процессе развёртывания:
ESCROW_INSTANCE_ID=<instance address - from Step 3>ADMIN_PRIVATE_KEY=<operator keypair as u8 array or base58 - from Step 4>DEVNET_RPC_URL=https://api.devnet.solana.comDEVNET_YELLOWSTONE_ENDPOINT=<your Yellowstone gRPC endpoint>INDEXER_YELLOWSTONE_TOKEN=<your Yellowstone auth token>
ADMIN_PRIVATE_KEY — это собственный обязательный подписант-плательщик комиссий для офчейн-сервисов,
не связанный с администратором экземпляра на блокчейне из Шага 3. В этом руководстве
keypair оператора, сгенерированный на Шаге 4, помещается в ADMIN_PRIVATE_KEY, а
опциональный OPERATOR_PRIVATE_KEY оставляется незаполненным, так что подписант оператора
использует тот же ключ. Никогда не помещайте keypair администратора экземпляра протокольного уровня из
Шага 3 ни в одну из этих переменных.
Полный справочник по переменным окружения см. в Конфигурации.
Развёртывание
Сборка образов
make docker-devnet-build
Эта команда компилирует все Rust-сервисы в общий образ Docker. Первая сборка занимает от 30 минут до часа.
Настройка Admin UI
Admin UI — это браузерный инструмент для создания и настройки экземпляра эскроу:
утилита для разработки и администрирования, а не продукт для конечных пользователей
и не обязательный компонент среды выполнения. Все выполняемые им операции
(CreateInstance, AllowMint, AddOperator) также можно запустить через CLI-скрипты
в репозитории.
cd admin-uipnpm installecho "PRIVATE_CHANNEL_RPC_URL=http://localhost:8899" > .envpnpm dev # opens at http://localhost:5173
Создание экземпляра эскроу
- Переключите кошелёк браузера на Devnet и убедитесь, что у вас есть Devnet SOL для оплаты комиссий
- В Admin UI нажмите Create New Instance и подтвердите транзакцию
- Скопируйте Instance Address и укажите его как
ESCROW_INSTANCE_IDв.env.devnet
Как вариант, используйте CLI-скрипт:
cargo run --bin create_instance -- https://api.devnet.solana.com ./keypairs/admin.json
Генерация keypair оператора
solana-keygen new -o operator-keypair.json -s --no-bip39-passphrasesolana-keygen pubkey operator-keypair.json
Укажите содержимое keypair как ADMIN_PRIVATE_KEY в вашем окружении. Публичный
ключ не является переменной окружения — вы передадите его напрямую как pubkey оператора
на шаге «Настройка экземпляра» ниже.
Финализация переменных окружения
Обновите .env.devnet, указав ESCROW_INSTANCE_ID, DEVNET_RPC_URL,
DEVNET_YELLOWSTONE_ENDPOINT и INDEXER_YELLOWSTONE_TOKEN. Поместите секреты
(POSTGRES_PASSWORD, POSTGRES_REPLICATION_PASSWORD, ADMIN_PRIVATE_KEY) в
файл .env, игнорируемый git.
Если вы решили включить RBAC
(Управление доступом: открытый режим и RBAC), также добавьте
JWT_SECRET и AUTH_PORT сейчас.
Запуск всех сервисов
Без аутентификации:
make docker-devnet-up
С аутентификацией:
docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet --env-file .env --profile auth up -d
Compose отключает автоматическую загрузку .env после передачи любого флага --env-file,
поэтому завершающий --env-file .env обязателен. Без него
POSTGRES_PASSWORD, ADMIN_PRIVATE_KEY и JWT_SECRET (которые вы поместили в
.env выше) будут пустыми и стек не запустится корректно.
Запускайте сервисы перед настройкой экземпляра. Индексер транслирует события в реальном времени, поэтому предварительный запуск стека гарантирует, что
AllowMintи ваш первый депозит будут проиндексированы по порядку без необходимости обратного заполнения.
Настройка экземпляра
При запущенном стеке добавьте токен в белый список и зарегистрируйте оператора через Admin UI:
- Allow Mint: Admin Functions -> Mint Management -> введите адрес минта -> Allow Mint
- Add Operator: Admin Functions -> Operator Management -> введите pubkey оператора -> Add Operator
Или через CLI:
cargo run --bin add_operator -- \https://api.devnet.solana.com \./keypairs/admin.json \<INSTANCE_ID> \<OPERATOR_PUBKEY>
Это руководство ориентировано на Solana devnet. Для Mainnet:
- Идентификаторы программ встраиваются через
declare_id!(): убедитесь, что вы используете корректные Mainnet ID из репозитория - Yellowstone gRPC эндпоинты требуют тарифного плана для Mainnet; devnet-эндпоинты не будут транслировать события Mainnet
- Кошелёк оператора оплачивает SOL-комиссии за каждый вызов
ReleaseFunds, поэтому рассчитайте баланс SOL исходя из ожидаемого объёма выводов - Смените все учётные данные по умолчанию (Grafana, PostgreSQL) перед любым публичным развёртыванием
Эксплуатация
Полезные команды
# View logs (all services)make docker-devnet-logs# View logs (specific service)docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f indexer-solana# Stop servicesmake docker-devnet-down# Stop and wipe all state (volumes)make docker-devnet-clean
Наблюдаемость
Стек включает Prometheus, Grafana и cAdvisor для мониторинга метрик и контейнеров.
Grafana доступна на порту 37429.
Пароль Grafana по умолчанию — admin. Смените его перед открытием порта 37429
для любой сети за пределами localhost.
Устранение неполадок
Баланс канала не обновляется после депозита
- Убедитесь, что транзакция депозита в Mainnet отображается в обозревателе Mainnet
- Проверьте, что
indexer-solanaзапущен:docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f indexer-solana - Проверьте, что
operator-solanaзапущен:docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f operator-solana - Убедитесь, что ваш Yellowstone gRPC эндпоинт доступен и токен действителен
(
DEVNET_YELLOWSTONE_ENDPOINT,INDEXER_YELLOWSTONE_TOKEN) - Подождите до 30 секунд после подтверждения на блокчейне, так как индексер применяет задержку безопасности финализации перед начислением средств
Вывод средств не расчитывается в Mainnet
- Проверьте, что
indexer-private-channelзапущен:docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f indexer-private-channel - Проверьте, что
operator-private-channelзапущен:docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f operator-private-channel - Убедитесь, что keypair оператора в
ADMIN_PRIVATE_KEYсовпадает с ключом, зарегистрированным черезAddOperatorна блокчейне - Если в логах отображается «SMT root mismatch», сервис останавливается, не отправляя некорректное доказательство. Остановите стек, восстановите из согласованного состояния и перезапустите
Ошибки JWT-аутентификации (401 на все запросы)
- Убедитесь, что
JWT_SECRETодинаков в контейнерах шлюза и сервиса аутентификации - Убедитесь, что стек был запущен с
--profile auth - Токены истекают через 24 часа; пройдите повторную аутентификацию для получения нового токена
Первая сборка занимает слишком много времени
Это ожидаемо. Первая команда make docker-devnet-build компилирует все Rust-сервисы и
может занять от 30 до 60 минут на типичном оборудовании. Последующие сборки используют кэш слоёв Docker
и выполняются значительно быстрее.
Дальнейшие шаги
Quickstart
Протестируйте ваше развёртывание: выполните депозит, перевод и вывод средств в devnet.
Конфигурация
Полный справочник по переменным окружения для всех сервисов.
Аутентификация и роли
Настройте аутентификацию JWT и создайте пользователей с ролью оператора.
Инструкции
Полный справочник по всем инструкциям на блокчейне.
Is this page helpful?