Hanzo Relay (crate name: hanzo-relay, internally hanzo-tunnel) is a Rust library that connects any local Hanzo app (dev, node, desktop, bot, extension) to the cloud relay at api.hanzo.ai for remote management and multiplayer.
Category: Hanzo Ecosystem Related Skills: hanzo/hanzo-bot.md, hanzo/hanzo-code.md, hanzo/hanzo-extension.md
Hanzo Relay (crate name: hanzo-relay, internally hanzo-tunnel) is a Rust library that connects any local Hanzo app (dev, node, desktop, bot, extension) to the cloud relay at api.hanzo.ai for remote management and multiplayer. WebSocket-based with automatic reconnection, JSON wire protocol, auth via JWT or API key, and optional mDNS LAN discovery. Think ngrok built into every Hanzo app.
sk-hanzo-...)hanzo-relay v0.1.0Repo: github.com/hanzoai/relay
| Item | Value | |------|-------| | Crate | hanzo-relay | | Repo | github.com/hanzoai/relay | | Version | 0.1.0 | | License | MIT | | Default relay | wss://api.hanzo.ai/v1/relay | | Default features | reconnect |
use hanzo_tunnel::{connect, TunnelConfig, AppKind};
let conn = connect(TunnelConfig {
relay_url: "wss://api.hanzo.ai/v1/relay".into(),
auth_token: "sk-hanzo-...".into(),
app_kind: AppKind::Dev,
display_name: "z-macbook".into(),
capabilities: vec!["chat".into(), "exec".into()],
..Default::default()
}).await?;
// Send events to cloud
conn.send_event("chat.delta", serde_json::json!({"text": "hello"})).await?;
// Receive commands from cloud
while let Some(cmd) = conn.recv_command().await {
println!("got: {} {}", cmd.method, cmd.params);
conn.respond(cmd.id, true, None).await?;
}
use hanzo_tunnel::connect_and_register;
let conn = connect_and_register(config).await?;
println!("Session URL: {:?}", conn.session_url);
// e.g., https://app.hanzo.bot/i/abc-123
use hanzo_tunnel::expose::{expose, ExposedService, ExposeProtocol};
expose(&conn.event_sender(), ExposedService {
name: "app-server".into(),
local_addr: "127.0.0.1:3000".into(),
protocol: ExposeProtocol::Http,
subdomain: Some("my-dev".into()),
}).await?;
All frames are JSON over WebSocket text messages, tagged by type:
| Direction | Frame | Purpose | |-----------|-------|---------| | Instance -> Cloud | register | Register app with capabilities and metadata | | Cloud -> Instance | registered | Acknowledge with session_url | | Instance -> Cloud | event | Stream data (chat.delta, exec.output, etc.) | | Cloud -> Instance | command | Send command (chat.send, config.update, etc.) | | Instance -> Cloud | response | Reply to a command (ok/error + data) | | Bidirectional | ping / pong | Keep-alive heartbeat |
pub enum AppKind {
Dev, // Development agent
Node, // Blockchain/AI node
Desktop, // Desktop application
Bot, // Bot instance
Extension, // Browser/IDE extension
}
| Feature | Default | Description | |---------|---------|-------------| | reconnect | Yes | Auto-reconnect with exponential backoff | | mdns | No | LAN discovery via mDNS (_hanzo._tcp.local.) | | tls-rustls | No | Use rustls instead of native-tls |
| File | Purpose | |------|---------| | src/lib.rs | TunnelConfig, TunnelConnection, connect(), connect_and_register() | | src/protocol.rs | Frame enum, all payload types, AppKind | | src/transport.rs | WebSocket transport with reconnection loop | | src/auth.rs | AuthToken (JWT vs API key auto-detection) | | src/expose.rs | Service exposure (HTTP/WS/TCP tunneling) | | src/registry.rs | Instance type, InvokeParams, InvokeResult | | src/discovery.rs | mDNS advertisement and discovery |
pub enum AuthToken {
Jwt { token: String }, // JWT from hanzo.id
ApiKey { key: String }, // sk-hanzo-... API key
}
// Auto-detects: 2+ dots = JWT, otherwise API key
let token = AuthToken::from_string("sk-hanzo-abc123");
pub struct TransportConfig {
pub url: String, // wss://api.hanzo.ai/v1/relay
pub auth: AuthToken,
pub initial_backoff: Duration, // 1s
pub max_backoff: Duration, // 60s
pub heartbeat_interval: Duration, // 30s
pub connect_timeout: Duration, // 10s
}
conn.send_event(event, data).await?; // Stream event to cloud
conn.recv_command().await; // Next command (None = closed)
conn.respond(id, ok, data).await?; // Reply to command
conn.respond_error(id, msg).await?; // Reply with error
conn.event_sender(); // Clone sender for spawned tasks
conn.shutdown(); // Graceful disconnect
conn.is_connected(); // Check liveness
hanzo/hanzo-bot.md - Bot framework (uses relay for cloud management)hanzo/hanzo-code.md - Dev agent (registers via relay)hanzo/hanzo-extension.md - Browser/IDE extensions (tunnel back to cloud)Last Updated: 2026-03-13 Category: Hanzo Ecosystem Related: tunnel, websocket, remote-management, cloud, rust, ngrok Prerequisites: Rust toolchain, Tokio runtime