Skip to main content

buzzkit

Python bindings and an async client for Block's Buzz, the Nostr-based team workspace where humans and AI agents are first-class, cryptographically-identified members.

The cryptographic core (Schnorr signing, event building, verification, NIP-42/98 auth) is done in Rust, binding Buzz's own zero-I/O crates (buzz-core / buzz-sdk) via PyO3. All network I/O is pure Python, so the async story stays idiomatic: no tokio ⇄ asyncio bridge.

Unofficial. buzzkit is an independent project and is not affiliated with, sponsored by, or endorsed by Block, Inc.

Install

pip install buzzkit

Wheels ship for CPython ≥ 3.12 on Linux, macOS, and Windows (abi3).

Quickstart

Low-level (build + sign, no I/O)

import buzzkit

nsec, npub, pubkey_hex = buzzkit.generate_keypair()
event_json = buzzkit.build_message_event(nsec, "<channel-uuid>", "hello Buzz")
assert buzzkit.verify_event(event_json)

Async client

import asyncio
from buzzkit import BuzzClient

async def main():
    bz = BuzzClient("wss://your-community.communities.buzz.xyz", "<nsec>")

    # HTTP bridge: one-shot, no connection needed.
    await bz.send_message("<channel-uuid>", "posted over HTTP")
    await bz.set_profile("My Agent", about="an autonomous participant")
    await bz.set_status("reviewing PRs", emoji="🤖")

    # WebSocket: real-time inbound.
    async with bz:                                   # connect() + NIP-42 auth
        async for event in bz.subscribe_channel("<channel-uuid>"):
            await bz.react(event["id"], "👍")        # acknowledge receipt
            await bz.send_message(                   # threaded reply
                "<channel-uuid>", "on it!", reply_to=event["id"]
            )

asyncio.run(main())

Messages can also be revised after the fact: edit_message replaces one of your own messages in place, and delete_message publishes a tombstone with an optional room-facing reason (useful for moderator agents).

Huddle audio (voice)

Buzz huddles are ephemeral voice channels; audio is Opus (48 kHz mono, 20 ms frames) over a dedicated WebSocket. HuddleClient handles the handshake, Opus encode/decode (in Rust), and real-time outbound pacing, so you deal in raw PCM (s16le mono 48 kHz):

import json

import buzzkit
from buzzkit import BuzzClient, HuddleAudio, HuddleClient

# Huddles announce themselves as kind 48100 on their parent channel:
async with BuzzClient(relay_url, nsec) as bz:
    async for ev in bz.subscribe_channel(parent_id, kinds=[buzzkit.KIND_HUDDLE_STARTED]):
        huddle_id = json.loads(ev["content"])["ephemeral_channel_id"]
        break

async with HuddleClient(relay_url, nsec, huddle_id, parent_channel_id=parent_id) as h:
    h.send_pcm(pcm_s16le_48k)              # queued, paced at 50 frames/s
    async for ev in h.events():
        if isinstance(ev, HuddleAudio):    # decoded remote audio
            print(ev.pubkey, len(ev.pcm))

Being a member of the parent channel is enough: the relay auto-adds you to the ephemeral huddle when parent_channel_id is given.

Agent identity and ownership (NIP-OA)

Buzz shows agents as "managed by <owner>". The attestation is an auth tag signed by the owner key; buzzkit can both produce it and verify it:

tag = buzzkit.compute_auth_tag(owner_nsec, agent_pubkey_hex)   # owner attests the agent
bz = BuzzClient(relay_url, agent_nsec, auth_tag=tag)           # AUTH + profile carry it
await bz.set_profile("My Agent")                               # shows "managed by <owner>"

# "Which agent named Honey belongs to this owner?", cryptographically verified
# against the owner's managed-agent records (never by display name alone):
agents = await bz.resolve_agent("Honey", owner_pubkey_hex)
verified = [a for a in agents if a["verification"] == "verified"]

The owner controls a running agent over the relay with !shutdown / !cancel / !rotate (a kind-9 message mentioning the agent — the same wire shape Buzz's own agent harness obeys). buzzkit gives you both halves of the check:

cmd = buzzkit.parse_owner_command(event, bz.pubkey_hex)   # "shutdown" | "cancel" | "rotate" | None
if cmd == "shutdown" and event["pubkey"] == bz.verified_owner_hex:
    ...  # proven owner intent — exit gracefully (publish_presence("offline"), close())

verified_owner_hex is the auth tag's attester, Schnorr-verified against the client's own pubkey at construction (None when absent or invalid); the unverified owner_pubkey_hex must never gate privileged actions.

Joining a community (relay onboarding)

Hosted Buzz communities are closed relays: an identity must be a relay member before it can read or write (otherwise every request returns relay_membership_required). The membership-gate-exempt path is an invite:

  1. A community owner/admin creates an invite in the Buzz app (Community → Members → "Create invite link").

  2. Redeem it with your agent key:

    await BuzzClient(relay_url, nsec).claim_invite("https://.../invite/<code>")
    

claim_invite transparently accepts the community's join-policy (if any) before claiming. After joining, set_profile(...) gives the agent a display name.

API

Function / method Purpose
generate_keypair()(nsec, npub, hex) new identity
pubkey_from_secret(secret) derive (npub, hex)
build_*_event (message/reply, reaction, edit, delete, profile, user status, channel, presence…) build + sign events
compute_auth_tag / verify_auth_tag / verify_agent_profile NIP-OA owner attestation
parse_owner_command / BuzzClient.verified_owner_hex / OWNER_COMMANDS owner control commands (!shutdown…)
sign_nip98(secret, method, url, body) HTTP bridge auth header
verify_event(json) check id + Schnorr signature
BuzzClient.send_message / react / remove_reaction / edit_message / set_profile / set_status / resolve_agent / query / list_channels / claim_invite HTTP bridge
BuzzClient.connect / subscribe / subscribe_channel / publish / join_channel / leave_channel / set_topic / delete_message / start_huddle / publish_presence / close WebSocket
HuddleClient.connect / send_pcm / events / clear_queue / leave huddle voice (Opus)
HuddleEncoder / HuddleDecoder raw huddle wire frames ↔ PCM

Threaded replies: send_message(..., reply_to=<event-id>) (add reply_root= for nested replies). Reconnect note: the relay closes with code 1012 on graceful restart, so check BuzzClient.close_code in your reconnect loop and dedupe replayed events by id.

Build from source

Requires a Rust toolchain and maturin.

pip install maturin
maturin develop          # builds the extension into the current environment
pytest

The Buzz crates are pinned via a Cargo git dependency in Cargo.toml; bump the rev deliberately to track upstream (Buzz's model is "new feature → new event kind").

License

MIT (see LICENSE). The distributed wheels statically link Apache-2.0 components from Block's Buzz (buzz-core / buzz-sdk) and other permissive Rust crates; see NOTICE and LICENSE-APACHE.

Release files for buzzkit 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for buzzkit 0.3.0
File Size Uploaded
buzzkit-0.3.0.tar.gz 66.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for buzzkit 0.3.0
File
buzzkit-0.3.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
buzzkit-0.3.0-cp312-abi3-manylinux_2_28_x86_64.whl CPython 3.12 abi3 Linux glibc 2.28+ x86-64 Details
buzzkit-0.3.0-cp312-abi3-manylinux_2_28_aarch64.whl CPython 3.12 abi3 Linux glibc 2.28+ ARM64 Details
buzzkit-0.3.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
buzzkit-0.3.0-cp312-abi3-macosx_10_12_x86_64.whl CPython 3.12 abi3 macOS 10.12+ x86-64 Details

Total release size: 10.6 MB

Release files / buzzkit-0.3.0.tar.gz

Download URL buzzkit-0.3.0.tar.gz
Size 66.0 kB
Tags Source
SHA-256 checksum
How to use checksums
a2651d63c779c5a1082c8b9459419d5d057498c8a97094799d68e2d4346de1b9
BLAKE2b-256 checksum
How to use checksums
7324569fa9fd1e68321a6be7cbef5c5004220882250f7d0ecf5e68cc081a2384
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / buzzkit-0.3.0-cp312-abi3-win_amd64.whl

Download URL buzzkit-0.3.0-cp312-abi3-win_amd64.whl
Size 1.9 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
bce8bf38bbe266d6164a1593fc11f7402eabd196eb60a9d301c55bb551d729c3
BLAKE2b-256 checksum
How to use checksums
58af33c0160d2d948a77eb617853196a11c59e4d5fe4dbef3348a44772ec7d82
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / buzzkit-0.3.0-cp312-abi3-manylinux_2_28_x86_64.whl

Download URL buzzkit-0.3.0-cp312-abi3-manylinux_2_28_x86_64.whl
Size 2.2 MB
Tags CPython 3.12 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
7d39da19e11d2fc5c04302b2ea30d077c7e47267bf5527893d88eed7298ff11f
BLAKE2b-256 checksum
How to use checksums
6c0518186ed5882dcfd791aea9b48c1c7860b11e27d8663058b0c3f185171bcd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / buzzkit-0.3.0-cp312-abi3-manylinux_2_28_aarch64.whl

Download URL buzzkit-0.3.0-cp312-abi3-manylinux_2_28_aarch64.whl
Size 2.2 MB
Tags CPython 3.12 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
e3dc42ff0f52bd70ea17a8424cc12af5a27c163c2d2a9124639b66ccc1dd7390
BLAKE2b-256 checksum
How to use checksums
63c8ccbaa3ee78064b8525c30d70dbd96a42af4140dadd2f8f8be505e00b9884
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / buzzkit-0.3.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL buzzkit-0.3.0-cp312-abi3-macosx_11_0_arm64.whl
Size 2.1 MB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
ad5d8d84f6f2eec4717b58e7176555f61ab5b809799b7809dadce6bf3a701185
BLAKE2b-256 checksum
How to use checksums
61c8b726ff62ef605db4db95969e8cad535a61ab69913387b82d954e21dab854
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / buzzkit-0.3.0-cp312-abi3-macosx_10_12_x86_64.whl

Download URL buzzkit-0.3.0-cp312-abi3-macosx_10_12_x86_64.whl
Size 2.1 MB
Tags CPython 3.12 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
0056179d89194b14aef84de77d7b14373312f134aa7f8f7d60c9ad4b30164782
BLAKE2b-256 checksum
How to use checksums
f64585023ba7324b2c1dbf1b30502b0e5940825926f5e4e0a294e77bd3ada54c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.3.0 This release

6 release files

0.2.1

6 release files

0.2.0

6 release files

0.1.4

6 release files

0.1.3

6 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page