続・NostrクライアントのLN組み込み方法-Zaps-
前回の続きです。
特に「Snortで試験的にノート単位に投げ銭できる機能」について。実は記事書いた直後にリリースされて慌ててw追記してたんですが追い付かないということで別記事にしました。
今回のここがすごい!
「Snortで試験的にノート単位に投げ銭できる機能」では一つブレイクスルーが起こっています。それは「ウォレットにインボイスを放り投げた後に払い込み完了を提示できる」ようになったことです。これによりペイメントのライフサイクルが一通りカバーされたことになります。
Snortの画面
なにを当たり前のことをという向きもあるかもしれませんが、Nostrクライアントで払い込み完了を追跡することはとても難しいです。基本的にNostrとLNウォレットはまったく別のアプリケーションで両者の間を繋ぐのはインボイス文字列だけです。ウォレットもNostrからキックされずに、インボイス文字列をコピペするなりQRコードで読み取ったものを渡されるだけかもしれません。またその場でリアルタイムに処理される前提もありません。
なのでNostrクライアントでその後をトラックすることは難しく、これまではあくまで請求書を送付したり(LNインボイス)振り込み口座を提示する(LNアドレス)という一方的に放り投げてただけだったわけです。といっても魔法のようにNostrクライアントがトラックできるようになったわけではなく、今回の対応方法もインボイスを発行/お金を振り込まれるサービス側(LNURL)にNostrカスタマイズを入れさせるというものになります。
プロポーザルの概要について
前回の記事ではよくわからんで終わっていましたが、当日夜(日本時間)にスペックをまとめたプロポーザルも起こされました(早い!)。LNURLが、Nostr用のインボイスを発行して、さらにNostrイベントの発行を行っていることがポイントでした。名称は"Lightning Zaps"で確定のようです。プロポーザルは、NostrとLNURLの双方の発明者であるfiatjaf氏からツッコミが入り、またそれが妥当な指摘のために、エンドポイントURLのインターフェースなどは変わりそうなのですが、概要はそう変わらないだろうということで簡単にまとめてみます。
全体の流れ
図は、Nostrクライアント上に提示されているLNアドレスへ投げ銭が開始してから、Nostrクライアント上に払い込み完了したイベントが表示されるまでの流れを示しています。
- 投げ銭の内容が固まったらNostrイベントデータを添付してインボイスの発行を依頼する
- 説明欄にNostr用のデータを記載したインボイスを発行して返却する
- Nostrクライアントで提示されたインボイスをユーザーが何かしらの手段でウォレットに渡す
- ウォレットがLNに支払いを実行する
- インボイスの発行者であるLNURLが管理しているLNノードにsatoshiが届く
- LNURLサーバが投げ銭成功のNostrイベントを発行する
- Nostrクライアントがイベントを受信して投げ銭履歴を表示する
特にポイントとなるところを補足します。
対応しているLNアドレスの識別
LNアドレスに投げ銭する場合は、LNアドレスの有効状態やインボイス発行依頼する先の情報をhttps://[domain]/.well-known/lnurlp/[username]
から取得しています。そのレスポンス内容にNostr対応を示す情報を追加しています。ただし、ここに突っ込み入っていてlnurlp=LNURL Payから独立させるためにzaps専用のエンドポイントに変わりそうです。(2/15 追記 マージされましたが変更無しでした。PRのディスカッションが盛り上がっているので興味ある方は覗いてみてください。)
インボイスの説明欄に書き込むNostrイベント(kind:9734)
これは投げ銭する側のNostrイベントです。投げ銭される者や対象ノートのIDや金額、そしてこのイベントを作成している者が投げ銭したということを「表明」するものになります。表明であって証明でないところは、インボイスを別の人が払っちゃう事態がありえるからですね。この内容をエンクリプトするパターンも用意されていたが複雑になり過ぎるという理由で今回は外され追加提案に回されました。また、このイベントはデータを作成しただけです。支払いを検知した後にLNURLが発行するイベントに添付されることになります。そのため投げ銭する者にちゃんと届くように作成者のリレーサーバリストも書き込まれています。
支払いを検知した後に発行するNostrイベント(kind:9735)
これが実際にNostrリレーサーバに発行されるイベントです。LNURL側はウォッチしているLNノードにsatoshiが届くと、インボイスの説明欄に書かれているNostrイベントを取り出して、いわば受領イベントを作成して発行します。以下のようにNostイベントのkind:9734とkind:9735が親子になったイベントとなります。
{
"pubkey": "LNURLが持っているNostrアカウントの公開鍵",
"kind": 9735,
"tags": [
[
"p",
"投げ銭された者の公開鍵"
],
[
"bolt11",
"インボイスの文字列lnbc〜"
],
[
"description",
"投げ銭した者が作成したkind:9734のNostrイベント"
],
[
"preimage",
"インボイスのpreimage"
]
],
}
所感
とにかくNostrクライアントはLNノードを持たないしLNプロトコルとも直接喋らずにインボイス文字列だけで取り扱えるようになっているところがおもしろいと思っています。NostrとLNという二つのデセントライズドなオープンプロトコルが協調できていますし、前回も述べましたがどんなアプリでも簡単に真似できます。
とはいえ、さすがに払込完了のトラックは難しく、今回はLNURL側にそのすり合わせの責務が寄せられることになりました。しかし、LNURLもLNの上に作られたオープンプロトコル/スペックの位置付けになるため、他のLNURLのスペックに干渉するという懸念から、本提案のNIP-57に変更依頼が出されています。LN、LNURL、Nostrの3つのオープンプロトコルの責務分担が難しいですね。アーキテクチャ層のスタックにおいて3つの中ではNostrが一番上になるため、Nostrに相当するレイヤーの他のwebサービスでやるときはLNプロトコルを喋るなりLNノードを持つようにして、今回LNURLが寄せられた責務を吸収するのが無難かもしれません。
また、NIP-57の変更依頼理由の一つにはBOLT-12を見越した抽象化も挙げられています。他のLNURLのスペックを削ぎ落としてzapsだけにすることでBOLT-12にも載りやすくなるだろうと。LNURLの多くはBOLT-12に取り込まれる運命なわけですが、LNアドレス以外の点でもNostrではBOLT-12のOfferやInvoiceRequestのユースケースをやりたいという声が挙がっているため、NostrによりBOLT-12が進む展開もありそうだなあ、あってほしい。