@soyeht/soyeht
v0.2.12
Published
OpenClaw channel plugin for the Soyeht Flutter mobile app
Readme
Soyeht OpenClaw Plugin
Channel plugin for connecting the Soyeht Flutter mobile app to an OpenClaw gateway.
V1 Architecture
The app and the OpenClaw instance communicate over HTTP + SSE on a shared network (typically Tailscale).
- Inbound (app → plugin):
POST {gatewayUrl}/soyeht/messages/inbound - Outbound (plugin → app):
GET {gatewayUrl}/soyeht/events/{accountId}?token=...(SSE) - Pairing: QR code scanned by the app, then HTTP handshake
No WebRTC. No public domain required. Tailscale resolves connectivity.
Install
openclaw plugins install @soyeht/soyeht --pin
openclaw plugins enable soyehtVerify:
openclaw plugins list
openclaw plugins info soyeht
openclaw plugins doctorConfiguration
Set gatewayUrl to the URL accessible from the app. With Tailscale, this is your instance's Tailscale IP or MagicDNS hostname:
# Using Tailscale IP
openclaw config set channels.soyeht.gatewayUrl "http://100.x.y.z:18789"
# Or using MagicDNS
openclaw config set channels.soyeht.gatewayUrl "http://my-machine.tailnet.ts.net:18789"
openclaw config set channels.soyeht.enabled true
openclaw gateway restartThe plugin will auto-generate a pairing QR on startup if no peers are paired.
Manual pairing
openclaw gateway call soyeht.security.pairing.start '{"accountId": "default", "allowOverwrite": true}'Full config reference
channels:
soyeht:
enabled: true
gatewayUrl: "http://100.x.y.z:18789" # required — your Tailscale/LAN URL
# Optional (only for legacy backend mode, not needed in V1):
# backendBaseUrl: "https://your-backend.example"
# pluginAuthToken: "your-token"Or with named accounts:
channels:
soyeht:
accounts:
default:
enabled: true
gatewayUrl: "http://100.x.y.z:18789"App endpoints
All called by the Flutter app against {gatewayUrl}:
| Method | Path | Purpose |
|--------|------|---------|
| GET | /soyeht/pairing/info?t={token} | Fetch plugin keys for pairing |
| POST | /soyeht/pairing/pair | Register peer + start handshake |
| POST | /soyeht/pairing/finish | Complete handshake, get streamToken |
| POST | /soyeht/messages/inbound | Send encrypted message to agent |
| GET | /soyeht/events/{accountId}?token={streamToken} | SSE stream for agent replies |
| GET | /soyeht/health | Health check (503 if not ready) |
QR format
The compact QR URL emitted by the plugin:
soyeht://pair?g={gatewayUrl}&t={pairingToken}&fp={fingerprint}The app parses the URL, then calls the HTTP pairing endpoints above.
Local development
npm ci
npm run validate # typecheck + tests
npm run test:watch # vitest in watch modePublish
npm version patch # bumps package.json + openclaw.plugin.json
npm publish