Operatoren

Was ist ein Private Channels-Operator?

Ein Operator ist eine vertrauenswürdige, on-chain-berechtigte Entität, die Solana Mainnet und das private Kanalnetzwerk verbindet. Operatoren werden vom Instanz-Admin über AddOperator bereitgestellt, wodurch eine on-chain Operator-PDA erstellt wird; ohne dies kann keine Partei ReleaseFunds aufrufen. In der Praxis ist ein Operator eine Organisation oder ein Team, das die Dienste betreibt, die auf Einzahlungen warten, kanalseitige Token prägen, Auszahlungen erkennen und Gelder zurück zum Mainnet abwickeln. Der Betrieb einer Instanz bietet Ihren Nutzern private Transfers mit hohem Volumen, die nicht auf Solana Mainnet erscheinen, sofortigen gebührenfreien Durchsatz jenseits des nativen Solana-TPS sowie kontrollierten Zugriff über RBAC.

Wenn Sie als Entwickler gegen eine bestehende Private Channels-Instanz integrieren, anstatt eine neue zu deployen, beginnen Sie stattdessen mit dem Quickstart.

Bevor Sie beginnen

Voraussetzungen

Pinnen Sie diese Versionen auf dem Host, um die Docker-Images abzugleichen:

  • Docker Engine 26+ (macOS Apple Silicon: "Docker VMM" in Einstellungen -> Virtual Machine Options aktivieren)
  • Node.js 24.7.0 und pnpm 10.15.1
  • Solana CLI 3.1.13 (Agave)
  • Rust 1.91.0
  • Ein Yellowstone-gRPC-Endpunkt für Devnet (verfügbar von Helius, Triton, QuickNode)

Informationen zu Netzwerkanforderungen und Standard-Port-Zuweisungen finden Sie in docs/TECHNICAL_REQUIREMENTS.md im Repository.

Installieren Sie die gepinnte Solana-Toolchain und wärmen Sie den SBF-Cache vor:

make install-toolchain

Dienste

Der Betrieb einer Private Channels-Instanz bedeutet, fünf laufende Verantwortlichkeiten zu übernehmen, die jeweils von dedizierten Containern im Docker Compose-Stack übernommen werden:

  1. Mainnet auf Einzahlungen indexieren - indexer-solana überwacht Solana Mainnet auf Deposit-Ereignisse über Yellowstone gRPC; operator-solana verarbeitet bestätigte Einzahlungen und prägt das entsprechende Token-Guthaben im Kanalnetzwerk
  2. Kanal auf Auszahlungen indexieren - indexer-private-channel fragt den Kanal jede Sekunde auf WithdrawFunds-Burn-Ereignisse ab und schreibt ausstehende Auszahlungsdatensätze in die Datenbank
  3. Gelder auf Mainnet freigeben - operator-private-channel verarbeitet ausstehende Datensätze und ruft ReleaseFunds auf dem Escrow-Programm mit einem gültigen SMT-Ausschlussbeweis auf
  4. SMT-Root verwalten - operator-private-channel ruft ResetSmtRoot automatisch auf, wenn sich Baum-epochs rotieren; die on-chain-Prüfung verify_smt_exclusion_proof ist die letzte Verteidigungslinie gegen unbefugte Auszahlungen
  5. Gateway und Auth-Dienst betreiben - das Gateway ist der einzige öffentliche Endpunkt für den gesamten Client-Verkehr; der Auth-Dienst (optional) erzwingt JWT/RBAC, wenn JWT_SECRET gesetzt ist

Das vollständige Dienstinventar und die Port-Zuweisungen finden Sie in der Konfigurationsreferenz.

Sicherheitshinweis: Write-Node- und Read-Node-Ports sind ausschließlich an Loopback (127.0.0.1) gebunden, aber mehrere andere Dienste (Gateway, Auth, Operator-Metriken, Grafana, Prometheus, cAdvisor) werden standardmäßig auf allen Netzwerkschnittstellen veröffentlicht. Die vollständige Port-Tabelle finden Sie in der Konfigurationsreferenz; sichern Sie diese mit einer Firewall ab, bevor Sie ein öffentlich zugängliches Deployment durchführen. RBAC deckt nur die eigenen JSON-RPC-Methoden des Gateways ab, nicht diese anderen Dienste.

Zugriffskontrolle: Offen vs. RBAC

Standardmäßig akzeptiert das Gateway alle Verbindungen; keine Token erforderlich. Um JWT-basiertes RBAC zu aktivieren, setzen Sie JWT_SECRET und starten Sie den Stack mit --profile auth. Siehe Authentifizierung & Rollen für die vollständige Konfigurationsreferenz, einschließlich der Bereitstellung der operator-Rolle und der Registrierung von Nutzer-Wallets.

Wenn Sie Auth aktivieren, fügen Sie diese Variablen Ihrer Umgebung hinzu, bevor Sie den Stack starten:

JWT_SECRET=<openssl rand -hex 32> # must match on gateway and auth service
AUTH_PORT=8903

Umgebungs-Setup

.env.devnet wird bereits im Repository verwaltet und enthält devnet-spezifische Standardwerte; bearbeiten Sie diese Datei direkt, anstatt sie aus .env.example neu zu generieren, was diese Standardwerte überschreiben würde.

Füllen Sie die verbleibenden Werte aus, während Sie die nachfolgenden Deployment-Schritte durchlaufen; einige sind erst während des Deployments verfügbar. Secrets kommen in die gitignorierte .env-Datei; nicht geheime Variablen kommen in .env.devnet.

Secrets – sofort setzen:

POSTGRES_PASSWORD=<openssl rand -hex 32>
POSTGRES_REPLICATION_PASSWORD=<openssl rand -hex 32>

Während des Deployments ermittelte Variablen:

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.com
DEVNET_YELLOWSTONE_ENDPOINT=<your Yellowstone gRPC endpoint>
INDEXER_YELLOWSTONE_TOKEN=<your Yellowstone auth token>

ADMIN_PRIVATE_KEY ist der eigene, erforderliche Fee-Payer-Signer der Off-Chain-Dienste, unabhängig vom on-chain Instanz-Admin aus Schritt 3. Diese Anleitung legt das in Schritt 4 generierte Operator-keypair in ADMIN_PRIVATE_KEY und lässt das optionale OPERATOR_PRIVATE_KEY ungesetzt, sodass der Operator-Signer auf denselben Schlüssel zurückfällt. Legen Sie niemals das keypair des protokollseitigen Instanz-Admins aus Schritt 3 in eine der beiden Variablen.

Die vollständige Referenz zu Umgebungsvariablen finden Sie unter Konfiguration.

Deployment

Images bauen

make docker-devnet-build

Dieser Schritt kompiliert alle Rust-Dienste in ein gemeinsames Docker-Image. Der erste Build dauert 30 Minuten bis zu einer Stunde.

Admin-UI einrichten

Die Admin-UI ist ein browserbasiertes Tool zum Erstellen und Konfigurieren der Escrow-Instanz: ein Entwicklungs- und Administrations-Hilfsmittel, kein nutzerseitiges Produkt und keine erforderliche Laufzeitkomponente. Alle Operationen, die es ausführt (CreateInstance, AllowMint, AddOperator), können auch über die CLI-Skripte im Repository ausgeführt werden.

cd admin-ui
pnpm install
echo "PRIVATE_CHANNEL_RPC_URL=http://localhost:8899" > .env
pnpm dev # opens at http://localhost:5173

Escrow-Instanz erstellen

  1. Stellen Sie Ihre Browser-Wallet auf Devnet ein und stellen Sie sicher, dass Sie Devnet-SOL für Fee haben
  2. Klicken Sie in der Admin-UI auf Create New Instance und bestätigen Sie die Transaktion
  3. Kopieren Sie die Instance Address und setzen Sie sie als ESCROW_INSTANCE_ID in .env.devnet

Alternativ können Sie das CLI-Skript verwenden:

cargo run --bin create_instance -- https://api.devnet.solana.com ./keypairs/admin.json

Operator-keypair generieren

solana-keygen new -o operator-keypair.json -s --no-bip39-passphrase
solana-keygen pubkey operator-keypair.json

Setzen Sie den Inhalt des keypairs als ADMIN_PRIVATE_KEY in Ihrer Umgebung. Der pubkey ist keine Umgebungsvariable; Sie übergeben ihn direkt als Operator-pubkey im Schritt "Instanz konfigurieren" unten.

Umgebungsvariablen abschließen

Aktualisieren Sie .env.devnet mit ESCROW_INSTANCE_ID, DEVNET_RPC_URL, DEVNET_YELLOWSTONE_ENDPOINT und INDEXER_YELLOWSTONE_TOKEN. Secrets (POSTGRES_PASSWORD, POSTGRES_REPLICATION_PASSWORD, ADMIN_PRIVATE_KEY) kommen in die gitignorierte .env-Datei.

Wenn Sie sich für RBAC entschieden haben (Zugriffskontrolle: Offen vs. RBAC), fügen Sie jetzt auch JWT_SECRET und AUTH_PORT hinzu.

Alle Dienste starten

Ohne Auth:

make docker-devnet-up

Mit Auth:

docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet --env-file .env --profile auth up -d

Compose deaktiviert sein automatisches .env-Laden, sobald ein --env-file-Flag übergeben wird, daher ist das abschließende --env-file .env erforderlich. Ohne es werden POSTGRES_PASSWORD, ADMIN_PRIVATE_KEY und JWT_SECRET (die Sie oben in .env abgelegt haben) leer aufgelöst und der Stack startet nicht korrekt.

Starten Sie die Dienste, bevor Sie die Instanz konfigurieren. Der Indexer streamt Ereignisse in Echtzeit; wenn Sie den Stack zuerst hochfahren, wird sichergestellt, dass AllowMint und Ihre erste Einzahlung geordnet indexiert werden, ohne dass ein Backfill erforderlich ist.

Instanz konfigurieren

Mit dem laufenden Stack können Sie einen Token-Mint auf der Whitelist eintragen und Ihren Operator über die Admin-UI hinzufügen:

  1. Allow Mint: Admin Functions -> Mint Management -> Mint-Adresse eingeben -> Allow Mint
  2. Add Operator: Admin Functions -> Operator Management -> Operator-pubkey eingeben -> Add Operator

Oder über CLI:

cargo run --bin add_operator -- \
https://api.devnet.solana.com \
./keypairs/admin.json \
<INSTANCE_ID> \
<OPERATOR_PUBKEY>

Diese Anleitung richtet sich an Solana Devnet. Für Mainnet:

  • Programm-IDs werden über declare_id!() einkompiliert: Stellen Sie sicher, dass Sie die richtigen Mainnet-IDs aus dem Repository verwenden
  • Yellowstone-gRPC-Endpunkte erfordern einen Mainnet-Plan; Devnet-Endpunkte streamen keine Mainnet-Ereignisse
  • Die Operator-Wallet zahlt SOL-Fee für jeden ReleaseFunds-Aufruf; passen Sie das SOL-Guthaben entsprechend Ihrem erwarteten Auszahlungsvolumen an
  • Ändern Sie alle Standard-Zugangsdaten (Grafana, PostgreSQL), bevor Sie ein öffentlich zugängliches Deployment durchführen

Betrieb

Nützliche Befehle

# 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 services
make docker-devnet-down
# Stop and wipe all state (volumes)
make docker-devnet-clean

Observability

Der Stack enthält Prometheus, Grafana und cAdvisor für Metriken und Container-Monitoring. Grafana ist auf Port 37429 erreichbar.

Das Standard-Grafana-Passwort lautet admin. Ändern Sie es, bevor Sie Port 37429 für ein Netzwerk außerhalb von localhost freigeben.

Fehlerbehebung

Kanal-Guthaben wird nach einer Einzahlung nicht aktualisiert

  1. Bestätigen Sie, dass die Mainnet-Einzahlungstransaktion in einem Mainnet-Explorer erscheint
  2. Überprüfen Sie, ob indexer-solana läuft: docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f indexer-solana
  3. Überprüfen Sie, ob operator-solana läuft: docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f operator-solana
  4. Überprüfen Sie, ob Ihr Yellowstone-gRPC-Endpunkt erreichbar ist und das Token gültig ist (DEVNET_YELLOWSTONE_ENDPOINT, INDEXER_YELLOWSTONE_TOKEN)
  5. Warten Sie bis zu 30 Sekunden nach der on-chain-Bestätigung, da der Indexer eine Finality-Sicherheitsverzögerung anwendet, bevor er das Guthaben gutschreibt

Auszahlung wird nicht auf Mainnet abgewickelt

  1. Überprüfen Sie, ob indexer-private-channel läuft: docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f indexer-private-channel
  2. Überprüfen Sie, ob operator-private-channel läuft: docker compose -f docker-compose.devnet.yml --env-file versions.env --env-file .env.devnet logs -f operator-private-channel
  3. Bestätigen Sie, dass das Operator-keypair in ADMIN_PRIVATE_KEY mit dem Schlüssel übereinstimmt, der mit AddOperator on-chain registriert wurde
  4. Wenn die Logs "SMT root mismatch" anzeigen, fährt der Dienst herunter, anstatt einen ungültigen Beweis einzureichen. Stoppen Sie den Stack, stellen Sie einen konsistenten Zustand wieder her und starten Sie neu

JWT-Authentifizierungsfehler (401 bei allen Anfragen)

  1. Bestätigen Sie, dass JWT_SECRET auf den Gateway- und Auth-Dienst-Containern identisch ist
  2. Bestätigen Sie, dass der Stack mit --profile auth gestartet wurde
  3. Token laufen nach 24 Stunden ab; authentifizieren Sie sich erneut, um ein neues Token zu erhalten

Erster Build dauert zu lange

Das ist zu erwarten. Der erste make docker-devnet-build kompiliert alle Rust-Dienste und kann auf typischer Hardware 30–60 Minuten dauern. Nachfolgende Builds nutzen den Docker-Layer-Cache und sind deutlich schneller.

Nächste Schritte

Is this page helpful?

© 2026 Solana Foundation. Alle Rechte vorbehalten.