Add paired payload type and content flags while preserving the existing nsec behavior. Document the Buzz workspace payload shape and cover argument validation and verbatim interop payload handling. Co-authored-by: npub1ux8n2yfs8qfvgd75s7kyhar2mztac355v6vmrz4juc9l3msw4pgstums9e <e18f3511303812c437d487ac4bf46ad897dc46946699b18ab2e60bf8ee0ea851@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub1ux8n2yfs8qfvgd75s7kyhar2mztac355v6vmrz4juc9l3msw4pgstums9e <e18f3511303812c437d487ac4bf46ad897dc46946699b18ab2e60bf8ee0ea851@sprout-oss.stage.blox.sqprod.co>
buzz-pair
CLI tool for testing the NIP-AB device pairing protocol end-to-end. Exercises the full protocol over a live Nostr relay — designed for interop testing and NIP submission, not production use.
Quick Start
cargo build --release -p buzz-pairing-cli
# Terminal 1 — source (holds the secret)
./target/release/buzz-pair source --relay wss://relay.damus.io
# Terminal 2 — target (receives the secret)
./target/release/buzz-pair target --show-secret
# paste the QR URI from terminal 1 when prompted
Both sides display a 6-digit SAS code. Confirm they match on each side, and the key transfers.
Subcommands
source
Acts as the device holding the secret. Generates an ephemeral keypair and session secret, displays a nostrpair:// QR URI, waits for a target to connect, performs SAS verification, and sends the payload.
buzz-pair source --relay <RELAY_URL> [--nsec <BECH32_NSEC>]
buzz-pair source --relay <RELAY_URL> --payload-type <TYPE> --payload <CONTENT>
--relay— WebSocket relay URL (default:wss://relay.damus.io)--nsec— bech32 nsec to transfer. If omitted, generates a throwaway test key.--payload-type— type for explicit payload content:nsec,bunker,connect, orcustom.--payload— explicit payload content. Must be provided with--payload-type; it is sent verbatim so interop tests can exercise both valid and malformed payloads.
--payload-type and --payload let the generic interop tool exercise application-defined payloads without baking an application's schema into the CLI. For example, a Buzz workspace payload can be sent with:
buzz-pair source \
--relay wss://relay.example.com \
--payload-type custom \
--payload '{"relayUrl":"https://relay.example.com","pubkey":"<HEX_PUBKEY>","nsec":"<BECH32_NSEC>"}'
The workspace relayUrl is the HTTP API base URL, while --relay remains the WebSocket relay used for the pairing exchange.
target
Acts as the receiving device. Reads a nostrpair:// URI from stdin, connects to the relay encoded in the URI, sends an offer, verifies SAS, and receives the payload.
buzz-pair target [--relay <OVERRIDE_URL>] [--show-secret]
--relay— Override the relay URL from the QR code--show-secret— Print the received secret to stdout (off by default for safety)
test-vectors
Prints all derived cryptographic values from the NIP-AB spec's fixed test keys. Useful for verifying implementations against the spec.
buzz-pair test-vectors
Testing Against a Local Buzz Relay
The CLI supports NIP-42 authentication, so it works with Buzz relays out of the box.
Prerequisites
- Docker running (for Postgres, Redis, etc.)
- Buzz relay built:
cargo build --release -p buzz-relay
Start the relay
just setup # Docker services + schema
cargo build --release --workspace
screen -dmS relay bash -c "./target/release/buzz-relay 2>&1 | tee /tmp/buzz-relay.log"
sleep 3 && curl -s http://localhost:3000/health # → "ok"
Run the E2E test
An automated test script using expect is provided:
.scratch/e2e-pair-local.sh
This spawns source and target as PTY-driven subprocesses, feeds the QR URI between them, waits for both SAS codes to appear, delays to ensure relay subscriptions are registered, then confirms SAS on both sides. Prints PASS or FAIL with the SAS codes.
Requirements: expect (macOS: built-in at /usr/bin/expect)
Environment variables:
| Variable | Default | Description |
|---|---|---|
RELAY_URL |
ws://localhost:3000 |
Relay to test against |
TEST_TIMEOUT |
45 |
Per-step timeout in seconds |
SOURCE_CONFIRM_DELAY_MS |
3000 |
Delay after SAS display before confirming (lets relay register subscriptions) |
Manual two-terminal test
# Terminal 1
./target/release/buzz-pair source --relay ws://localhost:3000
# Terminal 2
./target/release/buzz-pair target --show-secret
# paste the nostrpair:// URI, confirm SAS on both sides
Protocol Overview
Source Relay Target
────── ───── ──────
Generate ephemeral keys
Display QR (pubkey+secret+relay)
Subscribe kind:24134 Scan QR
Generate ephemeral keys
Subscribe kind:24134
Wait for EOSE
◄─────────────────────── Send offer
Verify session_id
Compute SAS ◄──────────────────────────────────────────► Compute SAS
Display: "047291" Display: "047291"
[User confirms codes match]
Send sas-confirm ──────────────►─────────────────────►
Verify transcript_hash
[User confirms]
Send payload ──────────────────►─────────────────────►
Decrypt + import
◄─────────────────────── Send complete
Done Done
All events are NIP-44 encrypted, signed with ephemeral keys, and addressed via p tags. The relay sees only opaque ciphertext between throwaway pubkeys.