什么是 Private Channels 运营商?
运营商是一个受信任的、经过链上授权的实体,负责桥接 Solana 主网与私有通道网络。运营商由实例管理员通过 AddOperator 进行配置,该操作会创建一个链上 Operator PDA;没有此配置,任何参与方都无法调用 ReleaseFunds。实际上,运营商是一个组织或团队,负责运行以下服务:监听存款、在通道侧铸造代币、检测提款,并将资金结算回主网。运行一个实例可为您的用户提供不在 Solana 主网上显示的私密大额转账、超越原生 Solana TPS 的即时零费用吞吐量,以及通过 RBAC 实现的受控访问。
如果您是开发者,需要对接已有的 Private Channels 实例而非自行部署,请从 快速入门开始。
开始之前
前提条件
在主机上固定以下版本以匹配 Docker 镜像:
- Docker Engine 26+(macOS Apple Silicon:在「设置」->「虚拟机选项」中启用「Docker VMM」)
- Node.js 24.7.0 和 pnpm 10.15.1
- Solana CLI 3.1.13(Agave)
- Rust 1.91.0
- 用于 Devnet 的 Yellowstone gRPC 端点(可从 Helius、Triton、QuickNode 获取)
有关网络要求和默认端口分配,请参阅仓库中的
docs/TECHNICAL_REQUIREMENTS.md。
安装固定版本的 Solana 工具链并预热 SBF 缓存:
make install-toolchain
服务
运行一个 Private Channels 实例意味着承担五项持续性职责,每项职责由 Docker Compose 栈中的专用容器负责处理:
- 索引主网存款 -
indexer-solana通过 Yellowstone gRPC 监听 Solana 主网上的Deposit事件;operator-solana拾取已确认的存款,并在通道网络上铸造等值代币余额 - 索引通道提款 -
indexer-private-channel每秒轮询通道,检测WithdrawFunds销毁事件,并将待处理的提款记录写入数据库 - 在主网释放资金 -
operator-private-channel拾取待处理记录,并携带有效的 SMT 排除证明调用 Escrow Program 上的ReleaseFunds - 管理 SMT 根 -
operator-private-channel在树 epoch 轮换时自动调用ResetSmtRoot;链上的verify_smt_exclusion_proof检查是防止未授权提款的最后一道防线 - 运行网关和认证服务 - 网关是所有客户端流量的唯一公共端点;认证服务(可选)在设置
JWT_SECRET时强制执行 JWT/RBAC
有关完整的服务清单和端口分配,请参阅 配置参考。
安全说明: 写节点和读节点端口仅绑定到回环地址 (
127.0.0.1),但其他几项服务(网关、认证、运营商指标、Grafana、Prometheus、cAdvisor)默认发布到所有网络接口。有关完整的端口表,请参阅 配置参考, 并在任何面向公众的部署之前配置防火墙规则。RBAC 仅覆盖网关自身的 JSON-RPC 方法,不涵盖这些其他服务。
访问控制:开放模式与 RBAC
默认情况下,网关接受所有连接,无需任何令牌。要启用基于 JWT 的 RBAC,请设置 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 重新生成,否则会覆盖这些默认值。
在执行以下部署步骤时,逐步填入剩余的值;其中部分值仅在部署过程中才能获取。密钥存放在已被 gitignore 的 .env 文件中;非密钥变量存放在 .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 步中的链上实例管理员无关。本指南将第 4 步生成的运营商 keypair 填入 ADMIN_PRIVATE_KEY,并将可选的 OPERATOR_PRIVATE_KEY 留空,因此运营商签名者将回退使用相同的密钥。请勿将第 3 步中协议级别的实例管理员 keypair 填入上述任何一个变量。
有关完整的环境变量参考,请参阅 配置。
部署
配置 Admin UI
Admin UI 是一个基于浏览器的工具,用于创建和配置 Escrow 实例:它是一个开发和管理工具,而非面向用户的产品,也不是必须的运行时组件。其所有操作(CreateInstance、AllowMint、AddOperator)也可通过仓库中的 CLI 脚本执行。
cd admin-uipnpm installecho "PRIVATE_CHANNEL_RPC_URL=http://localhost:8899" > .envpnpm dev # opens at http://localhost:5173
创建 Escrow 实例
- 将您的浏览器钱包切换到 Devnet,并确保您有用于支付费用的 Devnet SOL
- 在 Admin UI 中,点击 Create New Instance 并批准交易
- 复制 Instance Address 并将其设置为
.env.devnet中的ESCROW_INSTANCE_ID
或者,使用 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)存放在已被 gitignore 的 .env 文件中。
如果您决定启用 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
一旦传入任意 --env-file 标志,Compose 将禁用其自动加载 .env 的功能,因此末尾的 --env-file .env 是必需的。若缺少它,POSTGRES_PASSWORD、ADMIN_PRIVATE_KEY 和 JWT_SECRET(即您存放在 .env 中的值)将解析为空,导致服务栈无法正常启动。
请在配置实例之前先启动服务。Indexer 实时流式处理事件,因此先启动服务栈可确保
AllowMint和您的首笔存款按顺序被索引,无需回填。
配置实例
服务栈运行后,通过 Admin UI 将代币 Mint 加入白名单并添加您的运营商:
- Allow Mint:Admin Functions -> Mint Management -> 输入 Mint 地址 -> 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。若使用主网,请注意:
- 程序 ID 通过
declare_id!()编译嵌入:请确认您使用的是仓库中正确的主网 ID - Yellowstone gRPC 端点需要主网套餐;Devnet 端点不会流式传输主网事件
- 运营商钱包每次调用
ReleaseFunds都需支付 SOL 费用,请根据预期的提款量规划 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 以外的任何网络之前,请务必更改此密码。
故障排除
存款后通道余额未更新
- 在主网浏览器上确认主网存款交易已成功上链
- 确认
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 秒,因为 indexer 在记账前会应用最终性安全延迟
提款未结算至主网
- 确认
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 - 确认
ADMIN_PRIVATE_KEY中的运营商 keypair 与通过AddOperator在链上注册的密钥一致 - 如果日志显示「SMT root mismatch」,服务将主动关闭而非提交无效证明。请停止服务栈,从一致的状态恢复后重新启动
JWT 认证失败(所有请求均返回 401)
- 确认网关容器和认证服务容器上的
JWT_SECRET完全一致 - 确认服务栈是以
--profile auth启动的 - 令牌在 24 小时后过期;请重新认证以获取新令牌
首次构建耗时过长
这是正常现象。首次执行 make docker-devnet-build 需要编译所有 Rust 服务,在普通硬件上可能需要 30 至 60 分钟。后续构建将使用 Docker 层缓存,速度会显著加快。
后续步骤
Is this page helpful?