#!/usr/bin/env python3 """Post a message to the Nostr relay. Raw approach - no SDK needed.""" import json, hashlib, time, asyncio, ssl def sign_and_post(hex_sec, hex_pub, content, kind=1, tags=None): import coincurve import websockets # Build event ts = int(time.time()) evt_serial = [0, hex_pub, ts, kind, tags or [], content] evt_id = hashlib.sha256( json.dumps(evt_serial, separators=(',', ':'), ensure_ascii=False).encode() ).hexdigest() # Sign with schnorr sk = coincurve.PrivateKey(bytes.fromhex(hex_sec)) sig = sk.sign_schnorr(bytes.fromhex(evt_id)) signed = { "id": evt_id, "pubkey": hex_pub, "created_at": ts, "kind": kind, "tags": tags or [], "content": content, "sig": sig.hex() } print(f"Event: kind={kind}, id={evt_id[:16]}...") print(f"Content: {content[:80]}") return asyncio.run(_send(signed)), signed async def _send(evt): import websockets url = "ws://127.0.0.1:2929" async with websockets.connect(url) as ws: await ws.send(json.dumps(["EVENT", evt])) try: resp = await asyncio.wait_for(ws.recv(), timeout=5) print(f"Relay: {resp[:200]}") return True except Exception as e: print(f"Relay: {e}") return False if __name__ == "__main__": import os keys_path = os.path.expanduser("~/.timmy/nostr/agent_keys.json") with open(keys_path) as f: keys = json.load(f) t = keys["timmy"] # Post 3 messages posts = [ ["Timmy speaks: The group is live. Sovereignty and service always.", 1, []], ["Timmy speaks: Morning report will now go to Nostr instead of Telegram.", 1, []], ["Timmy speaks: The crew should check NIP-29 for the household group.", 1, []], ] url = "wss://relay.alexanderwhitestone.com:2929" print(f"Posting to relay: {url}\n") for content, kind, tags in posts: ok, evt = sign_and_post(t["hex_sec"], t["hex_pub"], content, kind, tags) status = "OK" if ok else "FAILED" print(f" [{status}] {content[:50]}...\n")