BitChat-over-Nostr transport — NIP-17 gift wrap, relay client, embedded packet helpers
Project description
bitchat-nostr
BitChat-over-Nostr transport for Python.
Implements the relay transport layer for BitChat: NIP-17 gift-wrap private messages, async relay client (NIP-01), and helpers for embedding BitChat binary packets inside Nostr events.
Installation
pip install bitchat-nostr
# Optional: NIP-44 encryption requires a secp256k1 library
pip install nostr-sdk # or pynostr, etc.
Quick Start
Listen for BitChat packets via Nostr relay
import asyncio
from bitchat_nostr import RelayClient, RelayConfig, NostrFilter, NostrKind, extract_packet_from_event
async def main():
async with RelayClient(RelayConfig(url='wss://relay.example.com')) as relay:
async def on_event(event, sub_id):
# After decrypting the gift wrap, extract the BitChat packet:
embedded = extract_packet_from_event(event)
if embedded:
print('Received BitChat packet from', embedded.sender_id_hex)
await relay.subscribe(
'bitchat-dm',
[NostrFilter(kinds=[int(NostrKind.GIFT_WRAP)])],
on_event,
)
await asyncio.sleep(60) # listen for 60 seconds
asyncio.run(main())
Send a BitChat packet via NIP-17
from bitchat_protocol import encode as encode_packet, BitchatPacket, MessageType
from bitchat_nostr import build_dm_rumor, wrap_and_send, RelayClient, RelayConfig
async def send():
# 1. Encode your BitChat packet
packet = BitchatPacket(version=1, type=int(MessageType.NOISE_ENCRYPTED), ...)
wire = encode_packet(packet, padding=False)
# 2. Build a NIP-17 DM rumor carrying the packet
rumor = build_dm_rumor(wire, sender_nostr_pubkey, recipient_nostr_pubkey)
# 3. Wrap and publish (requires your CryptoProvider implementation)
gift_wrap_event = wrap_and_send(rumor, sender_privkey, recipient_pubkey, crypto)
async with RelayClient(RelayConfig(url='wss://relay.example.com')) as relay:
ok = await relay.publish(gift_wrap_event)
print('Published:', ok)
API
RelayClient
RelayClient(config: RelayConfig, *, connect_timeout=5.0, publish_timeout=3.0, ...)
async with client:
await client.subscribe(id, filters, on_event, on_eose=None)
await client.unsubscribe(id)
await client.publish(event) -> bool
await client.close()
Embedding Helpers
encode_packet_to_base64(packet_bytes: bytes) -> str
decode_packet_from_base64(content: str) -> bytes | None
extract_packet_from_event(event: NostrEvent) -> EmbeddedBitChatPayload | None
build_dm_rumor(packet_bytes, sender_pubkey, recipient_pubkey) -> NostrRumor
build_geohash_presence_event(packet_bytes, sender_pubkey, geohash) -> NostrRumor
NIP-17 Gift Wrap
wrap_and_send(rumor, sender_privkey, recipient_pubkey, crypto) -> NostrEvent
receive_and_unwrap(gift_wrap_event, recipient_privkey, crypto) -> NostrRumor | None
# Individual steps:
seal_rumor(rumor, sender_privkey, recipient_pubkey, crypto) -> NostrEvent
gift_wrap(seal, recipient_pubkey, crypto) -> NostrEvent
unwrap_gift(gift_wrap_event, recipient_privkey, crypto) -> NostrEvent | None
unseal_rumor(seal_event, recipient_privkey, crypto) -> NostrRumor | None
CryptoProvider Protocol
class MyCrypto:
def nip44_encrypt(self, plaintext, sender_privkey, recipient_pubkey) -> str: ...
def nip44_decrypt(self, ciphertext, recipient_privkey, sender_pubkey) -> str | None: ...
def get_public_key(self, private_key) -> str: ...
def sign_event(self, event, private_key) -> NostrEvent: ...
def generate_ephemeral_key(self) -> bytes: ...
Running Tests
pip install -e ".[dev]"
pytest
License
Unlicense — public domain.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bitchat_nostr-0.1.0.tar.gz.
File metadata
- Download URL: bitchat_nostr-0.1.0.tar.gz
- Upload date:
- Size: 10.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b69b961fcc85274d62c6a2d20e16e0570537e28510bc77ccd7d2b5cdb2a9323
|
|
| MD5 |
103e657082966238fd643b05c7379a5c
|
|
| BLAKE2b-256 |
3fc7409b526558ed63d2846b50345afd16ada5064b5e467ed47208e4d5c280d5
|
File details
Details for the file bitchat_nostr-0.1.0-py3-none-any.whl.
File metadata
- Download URL: bitchat_nostr-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
078b9224207f1ecc3decf86f5f599b926530ac2b265912d7ccf2003f7415a73d
|
|
| MD5 |
47e587846ed2f0364edc7d18249e595c
|
|
| BLAKE2b-256 |
150a051b7ec9d6b7b681317024f15da74d7e81afe3b0e223e7f5cfd86fca4fd1
|