NostrをMacのターミナルでWebSocket直接でプロトコルのやり取りする方法

元ネタ

こちらのコマンド集&実行例を参考にしました。 Nostr Notes

準備

  • 自分のNostrアカウントを作成します。そしてそのpubkey(npub)の16進数表記を取得します。
    • damusが用意してくれているWebページでpubkeyを16進数表記に変更できます。
    • 私のpubkeyは npub1spj7zmtmgdl8gcndcqt6r783x6fhjqw5e54ll7cudgphwx0m72ys404su9 で16進数表記は 8065e16d7b437e74626dc017a1f8f136937901d4cd2bfffb1c6a037719fbf289 です。
  • NostrはWebSocketで通信しているので、そのプロトコルをやり取りできるwebsocatをインストールします。
    • brew install websocat
      

Nostrのrelayにどんなイベントが送られているのか覗いてみる

手始めにrelayにどんなイベントが届いているのかリアルタイムに監視してみます。負荷がかかる処理ですし大量に流れてくるので3秒も見れば十分でしょう。Ctrl+cで終了します。

$ echo '["REQ","tail",{"limit":0}]' | websocat -n wss://relay.damus.io
["EOSE","tail"]
["EVENT","tail",{"content":"dFODRdPq35xjrZF0DjovZd5cQwoIPkVgKoLHT1g03KCjmG/6j49xNCkKYpD/Jznw?iv=ARH7fUsLrRlhlx5MZI4SZw==","created_at":1676030953,"id":"dcc8a80d45b6230351bf5be1bbcdbe9e7a305a1398e7ea38b32ca5446e28617e","kind":4,"pubkey":"6b63fde4d8c989aeafe2d10acc4209c518393dde5771ff1f2837d4bfa1801eec","sig":"ca8eb71b9f343992916989aeb005f8d1847956e0b5e5ca42e27ab5224faef95b5bf4ad21b050522f4ca128c6549ccad1a951295d763c3aa08dae8d8d05e13ea9","tags":[["p","c186f6af371c63beb8935fef666f59d7c6941434e237434ec5576baa7254b142"]]}]
["EVENT","tail",{"content":"(第二版本)全国同城约炮!妹妹安排到位!点击链接进入下载 https://xdjz6.nl?channelCode=8314ML","created_at":1676030951,"id":"1695a933956653c0495f261c31aa190f5147d51e6163febcdc155dd2ceb4dd05","kind":1,"pubkey":"f61d03ee46bf11898f23a301d51cfcb2d6bb95b3fcd6e34596775abfbda17e8d","sig":"29f3da3381342607e1c26d48e62a44523e62156bd1b34e3c55326ab44ecd317e6dbf51a5705826853e1ed5d6faf99b991370cd1865d85d806ba0847708c40e72","tags":[]}]
["EVENT","tail",{"content":"+","created_at":1676030951,"id":"bdfbbe146616bc4b403dad7fe568ea81e6bea349b5b2c470baec06def8ba53cc","kind":7,"pubkey":"fe858a5db125adabf0cb4cf29c07baaeebe74ab36f2405a310250b12a970d36b","sig":"b22478f04246165a2ecf4bd06c151af4b42a18c5a12a8821cd9a94ceb2da07755dafc4efe0ee8aa447afb8b4522d6edccd8437d86187dd8d4292b7437a24a6a9","tags":[["e","509b601ad1282512bf311617da00766437b9b9696efddc8a9ebdd9d0dd8a57af"],["p","c48e29f04b482cc01ca1f9ef8c86ef8318c059e0e9353235162f080f26e14c11"]]}]
["EVENT","tail",{"content":"全国同城约炮!妹妹安排到位!点击链接进入下载 https://bb38.top","created_at":1676030951,"id":"5c3c25ef1a66a98260d1061b8744f6ae504dbfef2b0eb94bbf12aeb33ed2363b","kind":1,"pubkey":"efb3d1b19c693e886d6f4a99abc75e895ffc981bc35e64b154c886993e141fbb","sig":"983f45ce3d5746d897c1a34c3620233da3c288d54279f06c1b6fd4ba1b771b0416523e55e11055b45c97ee7429f8527110d1ec8f8a12609a3f353ffdf29e56c0","tags":[]}]
["EVENT","tail",{"content":"Telegram第一灰产群 @huichan\nTelegram鉴黄开车群 @jianhuanghui\nTelegram全国资源群 @quanguo\nTelegram搜群机器人 @pindao\nhttps://t.me/huichan\nhttps://t.me/jianhuanghui\nhttps://t.me/quanguo\nhttps://t.me/pindao","created_at":1676030953,"id":"18049500dcb5e32aa5727294777372ddfc9deb387b90af00df7d7699cf3089d8","kind":1,"pubkey":"ceba04cd91aa25a8edb605e4c653eea25ad80950f067c3c329c341227d64339e","sig":"d81ebe75faaa1ebbf083fc6f228826d9f4420184b9ab621e13348a988b0b71900778a1bef2039e9cbb3206392ff0c79fd5f11736fc545bf10a8f533acb3a3f47","tags":[]}]
^C

relayから自分の過去のイベントを検索する

# リクエストを送るためのidを生成する
$ uuidgen | sed s/-//g | sed 's:\(.\):\L\1:g'
結果 → 4b62219adf744de5b81af76f8e2e99b9

# 自分が過去に投稿したノートを検索する。条件はkind:1、投稿者:自分、1個
$ echo '["REQ","4b62219adf744de5b81af76f8e2e99b9",{"authors":["8065e16d7b437e74626dc017a1f8f136937901d4cd2bfffb1c6a037719fbf289"],"kinds":[1],"limit":1}]' | websocat wss://relay-jp.nostr.wirednet.jp
応答 → ["EVENT","4b62219adf744de5b81af76f8e2e99b9",{"id":"bd5c74ab7616fbb1396fdc959d26b654ec74d568fe494355bdbe14a9798427f2","pubkey":"8065e16d7b437e74626dc017a1f8f136937901d4cd2bfffb1c6a037719fbf289","created_at":1676026132,"kind":1,"tags":[],"content":"夕食はコンソメスープ1杯","sig":"bfca2f2a37f4fdee8d0ec8ede7b61bc5cc291f5657cb598c6ad5040846deafb510cee434f513c8cc9b01b738065c0bdc8eb37dd0b89fa644a96329055e7b2f86"}]
["EOSE","4b62219adf744de5b81af76f8e2e99b9"]

# 通信を終了する
echo '["CLOSE", "4b62219adf744de5b81af76f8e2e99b9"]' | websocat wss://relay-jp.nostr.wirednet.jp
終了の応答は中身無し

relayからidを指定してイベントを取得する

# リクエストを送るためのidを生成する
$ uuidgen | sed s/-//g | sed 's:\(.\):\L\1:g'
結果 → 2c282a301c7848839b7df55e340be66c

# イベントをidを指定して取得する(上記で取得したイベント)
$ echo '["REQ","2c282a301c7848839b7df55e340be66c",{"ids":["bd5c74ab7616fbb1396fdc959d26b654ec74d568fe494355bdbe14a9798427f2"]}]' | websocat wss://relay-jp.nostr.wirednet.jp
応答 → ["EVENT","2c282a301c7848839b7df55e340be66c",{"id":"bd5c74ab7616fbb1396fdc959d26b654ec74d568fe494355bdbe14a9798427f2","pubkey":"8065e16d7b437e74626dc017a1f8f136937901d4cd2bfffb1c6a037719fbf289","created_at":1676026132,"kind":1,"tags":[],"content":"夕食はコンソメスープ1杯","sig":"bfca2f2a37f4fdee8d0ec8ede7b61bc5cc291f5657cb598c6ad5040846deafb510cee434f513c8cc9b01b738065c0bdc8eb37dd0b89fa644a96329055e7b2f86"}]
["EOSE","2c282a301c7848839b7df55e340be66c"]

# 通信を終了する
$ echo '["CLOSE", "2c282a301c7848839b7df55e340be66c"]' | websocat wss://relay-jp.nostr.wirednet.jp
終了の応答は中身無し

まとめ

単純にこれだけの手順でNostrのプロトコルをやり取りできます。後はNostrのプロトコル定義を読めばノートの投稿、ノートの削除、like以外のリアクション、等々なんでもできます。簡単ですね。 Let's happy hacking!

関連リンク