import hashlib import json import time from coincurve import PrivateKey, PublicKeyXOnly def sign_event(sk: bytes, pubkey: str, kind: int, content: str, tags: list[list[str]]) -> dict: event = { "pubkey": pubkey, "created_at": int(time.time()), "kind": kind, "tags": tags, "content": content, } serialized = json.dumps( [0, event["pubkey"], event["created_at"], event["kind"], event["tags"], event["content"]], separators=(",", ":"), ensure_ascii=False, ) event["id"] = hashlib.sha256(serialized.encode()).hexdigest() pk = PrivateKey(sk) sig = pk.sign_schnorr(bytes.fromhex(event["id"])) event["sig"] = sig.hex() if isinstance(sig, bytes) else sig return event def verify_event(event: dict) -> bool: try: serialized = json.dumps( [0, event["pubkey"], event["created_at"], event["kind"], event["tags"], event["content"]], separators=(",", ":"), ensure_ascii=False, ) expected_id = hashlib.sha256(serialized.encode()).hexdigest() if expected_id != event.get("id", ""): return False xonly = PublicKeyXOnly(bytes.fromhex(event["pubkey"])) return xonly.verify(bytes.fromhex(event["sig"]), bytes.fromhex(event["id"])) except Exception: return False