Files
timmy-home/nostr/post_nip42.py

72 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""Post to the Nostr relay with NIP-42 AUTH handshake."""
import json, time, asyncio, secrets, hashlib
import websockets
from nostr.key import PrivateKey
from nostr.event import Event
NSEC = "nsec1fcy6u8hgz46vtnyl95z6e97klneaq2qc0ytgnu5xs3vt4rlx4uqs3y644j"
RELAY = "ws://127.0.0.1:2929"
pk = PrivateKey.from_nsec(NSEC)
def make_evt(kind, content, tags=None):
tags = tags or []
evt = Event(public_key=pk.hex(), created_at=int(time.time()), kind=kind, content=content, tags=tags)
pk.sign_event(evt)
return {"id": evt.id, "pubkey": evt.public_key, "created_at": evt.created_at,
"kind": evt.kind, "tags": evt.tags, "content": evt.content, "sig": evt.signature}
async def post(evt_dict):
async with websockets.connect(RELAY) as ws:
await ws.send(json.dumps(["EVENT", evt_dict]))
while True:
try:
raw = await asyncio.wait_for(ws.recv(), timeout=5)
resp = json.loads(raw)
if resp[0] == "AUTH":
challenge = resp[1]
auth_evt = make_evt(22242, "", [
["relay", "relay.alexanderwhitestone.com:2929"],
["challenge", challenge]
])
print(f' auth challenge: {challenge[:16]}...')
await ws.send(json.dumps(["AUTH", auth_evt["id"]]))
await ws.send(json.dumps(["EVENT", evt_dict]))
continue
if resp[0] == "OK":
ok = resp[2]
msg = resp[3] if len(resp) > 3 else ""
print(f' OK: {ok} {msg}')
return ok
print(f' {resp[0]}: {resp[1] if len(resp)>1 else ""}')
except asyncio.TimeoutError:
print(' accepted (timeout)')
return True
async def main():
code = secrets.token_hex(4)
print(f'Timmy npub: {pk.bech32()}')
print(f'Group code: {code}\n')
print('1. Group metadata (kind 39000)')
await post(make_evt(39000, json.dumps({"name": "Timmy Time", "about": "Timmy Foundation household"}),
[["d", code], ["name", "Timmy Time"], ["pubkey", pk.hex()]]))
print('2. Test message (kind 1)')
await post(make_evt(1, "Timmy speaks: Nostr comms pipeline live."))
print('3. Group chat (kind 9)')
await post(make_evt(9, "Welcome to Timmy Time household group.", [["h", code]]))
print('4. Morning report (kind 1)')
await post(make_evt(1, "MORNING REPORT - Nostr operational"))
cfg = {"relay": "wss://relay.alexanderwhitestone.com:2929", "group_code": code,
"created": time.strftime("%Y-%m-%d %H:%M:%S")}
with open("/root/nostr-relay/group_config.json", "w") as f:
json.dump(cfg, f, indent=2)
print(f'\nConfig saved: {code}')
asyncio.run(main())