信息的自由流通和分享是互联网最大的魅力之一。
出于对更自由开放的互联网的向往,我决定启用碎片化信息发布平台,其中包括 Nostr (Notes and Other Stuff Transmitted by Relays)。Nostr 是一个协议,类似电子邮件协议;Nostr 的客户端,如 Damus ,可看作一个去中心化的 Twitter。
本文介绍了 Nostr 协议,以及如何使用 Python 发布 Nostr
Post 信息。
如果想关注本文作者,请前往 其他 页面查看
Nostr 介绍#
- 协议简介:nostr-protocol/nostr: a truly censorship-resistant alternative to Twitter that has a chance of working
- 协议细节:nostr-protocol/nips: Nostr Implementation Possibilities
通讯过程#
- 这个协议中有两个东西,一个是 client,一个是 relay,client 就是用户社交的客户端,relay 就是转发服务器。
- 用户不需要注册,用户只需要有一个密钥对(公钥 + 私钥)就好了,然后把要发的信息做签名,发给一组 relays
- 然后你的 Follower 就可以从这些 relays 上订阅到你的信息。(通过输入 公钥)
技术细节摘要#
-
技术实现上,nostr 使用 websocket + JSON 的方式。其中主要是下面这么几个指令
-
Client 到 Relay 主要是下面这几个指令:
EVENT
。发出事件,可以扩展出很多很多的动作来,比如:发信息,删信息,迁移信息,建 Channel …… 扩展性很好。REQ
。用于请求事件和订阅更新。收到REQ
消息后,relay 会查询其内部数据库并返回与过滤器匹配的事件,然后存储该过滤器,并将其接收的所有未来事件再次发送到同一 websocket,直到 websocket 关闭。CLOSE
。用于停止被REQ
请求的订阅。
-
Relay 到 Client 主要是下面几个指令:
EVENT
。用于发送客户端请求的事件。NOTICE
。用于向客户端发送人类可读的错误消息或其他信息
-
-
关于
EVENT
下面是几个常用的基本事件:0
:set_metadata
:比如,用户名,用户头像,用户简介等这样的信息。1
:text_note
:用户要发的信息内容2
:recommend_server
:用户想要推荐给关注者的 Relay 的 URL(例如wss://somerelay.com
)
Python 发布 Nostr 信息#
目标#
- 需求:提供私钥和一段字符串文本,使用 Python 发布 Nostr 纯文本 Post 信息
- 尽可能支持更多平台
方案#
调库。
jeffthibault/python-nostr: A Python library for Nostr 这个,实际操作发现有依赖 secp256k1 ,对 windows 系统不友好,排除。
比对后使用:
holgern/pynostr: Python library for nostr
pip install pynostr[websocket-client]
完整代码#
发布 Nostr Post 信息.py・GitHub,内容:
import json
import ssl
import time
import uuid
from pynostr.event import Event
from pynostr.relay_manager import RelayManager
from pynostr.filters import FiltersList, Filters
from pynostr.message_type import ClientMessageType
from pynostr.key import PrivateKey
relay_manager = RelayManager(timeout=6)
relay_manager.add_relay("wss://nostr-pub.wellorder.net")
relay_manager.add_relay("wss://relay.damus.io")
private_key = PrivateKey.from_nsec("你的私钥")
filters = FiltersList([Filters(authors=[private_key.public_key.hex()], limit=100)])
subscription_id = uuid.uuid1().hex
relay_manager.add_subscription_on_all_relays(subscription_id, filters)
event = Event("字符串消息")
event.sign(private_key.hex())
relay_manager.publish_event(event)
relay_manager.run_sync()
time.sleep(5)
while relay_manager.message_pool.has_ok_notices():
ok_msg = relay_manager.message_pool.get_ok_notice()
print(ok_msg)
while relay_manager.message_pool.has_events():
event_msg = relay_manager.message_pool.get_event()
print(event_msg.event.to_dict())
参考#
聊聊 nostr 和 审查 | 酷 壳 - CoolShell
以及文中链接。