ForcePilot/backend/package/yuxi/channel/extensions/nostr/event_utils.py
Kris 16455cb303 feat(channel): 添加 Nostr 渠道扩展
新增 Nostr 渠道扩展,支持在 Yuxi 平台中集成 Nostr 去中心化社交协议。

包含以下功能模块:
- bus: 事件总线与中继通信
- account: 账户管理
- key_utils: 密钥工具
- gateway: SSE/WebSocket 网关接入
- outbound: 外发消息管理
- gift_wrap: Gift Wrap 加密
- nip44: NIP-44 加密协议
- config_schema: 配置模式
- defaults: 默认配置
- profile_core: 用户资料核心
- profile_publisher: 资料发布
- event_utils: 事件工具
- deletion: 事件删除
- reactions: 表情反应
- metrics: 指标监控
- seen_tracker: 已读追踪
- session_route: 会话路由
- state_store: 状态存储
2026-05-21 11:31:51 +08:00

42 lines
1.3 KiB
Python

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