LUD-06
Zapにおいて
プロフィール欄のlud06の入力欄(別名称のことも)が用意されている場合があります。
技術的に言うと、lud06はプロフィール(kind:0)のJSONに含められるフィールドの一つです(NIP-57参照)。 LNURLにおいて
nostrのZap(NIP-57)はこのLUD-06に基づいています。 LUD-06の一連の処理の流れの中でnostrのZap関連の処理を追加で行う形です。
/icons/hr.icon
仕様
LUD-06: payRequestの基本仕様
これは、ウォレットで静的なQRコードをスキャンするか、静的なLNURLアドレスをクリックして、期待した支払いの詳細情報を得ることができるようにするアイデアである。詳細情報には通常のライトニングインボイスに比べて幅広いメタデータを含められる。そして、金額は固定であっても、決められた範囲の間であってもよい。 ユーザが支払いの条件を承諾(および、所定の金額が決まっていなければ金額を決定)したら、ウォレットはサービスを呼び出し、ライトニングインボイス明細(BOLT-11)を取得する。明細にはメタデータのハッシュ値 hタグ (description_hash) が含まれており、期待する金額とハッシュ値に一致した場合には、インボイスに対する支払いを続行する。 静的なQR/NFC/リンクへの支払い
1. ユーザはライトニングウォレットでLNURL QRコードをスキャンするか、lighting:LNURL..形式のリンクをペーストもしくは共有すると、ライトニングウォレットはLNURLをデコードする
(注釈)LNURL...形式のリンクの仕様はlud01を参照 2. ライトニングウォレットは、デコードしたLNURLを用いてライトニングサービスに対してGETリクエストを送る
3. ライトニングウォレットは、ライトニングサービスから次の形式のJSONレスポンスを受け取る:
code:_.json
{
"callback": string, // payリクエストのパラメータを受け付ける、ライトニングサービスのURL。
"maxSendable": number, // ライトニングサービスが受け取っても構わない最大の金額(millisatoshi)
"minSendable": number, // ライトニングサービスが受け取っても構わない最小の金額(millisatoshi)
// 1以上、maxSendable以下である必要がある。
"metadata": string, // メタデータのJSON。ここでは生の文字列として表現されなければならず、
// 後のシグニチャの検証ステップに渡す必要がある。
"tag": "payRequest" // LNURLの種別
}
もしくは
code:_.json
{"status": "ERROR", "reason": "error details..."}
(訳注)他の仕様でJSONレスポンスの追加の項目が定められています。
LUD-12では支払い時のコメントを指定できるようにcommentAllowedが定義されています。 NIP-57ではallowsNostrとnostrPubkeyが定義されています。 metadataJSONは配列であり、一つのtext/plainエントリを含まなければならない。他の種類のエントリは全て任意である。メタデータJSON配列は、image/png;base64とimage/jpeg;base64のいずれかを含むか、いずれも含まないようにしなければならない。
metadataJSON配列に含められるのは配列に限られる。metadata配列内の配列の最初の要素は、常にメタデータの種類を表す文字列であり、以降の要素はどんなJSON型であってもよい。実装はそれが常に文字列型であると仮定してはならない(MUST NOT)。
code:_.json
[
[
"text/plain", // 必須
string // 支払い時および取引履歴(transaction log)内に表示される短い説明
],
[
"text/long-desc", // 任意
string // 支払いについてのより長い説明。改行を含んでも良い(MAY)
],
[
"image/png;base64",
string // Base64 文字列(任意)。リストやグリッド内でこのLNURLを表すための512 x 512ピクセルのPNGサムネイル。最大136536文字(Base64エンコードで100KBに相当する画像データ)
],
[
"image/jpeg;base64", // optional
string // Base64 文字列(任意)。リストやグリッド内でこのLNURLを表すための512 x 512ピクセルのJPEGサムネイル。最大136536文字(Base64エンコードで100KBに相当する画像データ)
],
// 将来のためのエントリ
[
string,
any
]
]
そして、これは文字列として送信される
code:_.json
"\"text/plain\", \"lorem ipsum blah blah\""
4. ライトニングウォレットは、ユーザが支払う正確な金額を指定できる支払いダイアログを表示する。次の制約に縛られる:
最大の送金可能金額 = min(maxSendable, どれだけウォレットから支払えるかというローカルな見積もり)
最小の送金可能金額 = max(minSendable, ウォレットが許可する最小金額)
加えて、支払いダイアログは次を含まなければならない:
LNURLクエリ文字列から抽出したドメイン名
text/plain形式で送信されたメタデータを表示する手段
次を含んでも良い
image/pngまたはimage/jpegの内容を含むimage要素
5. ライトニングウォレットは、GETリクエストを送る
<callback><?|&>amount=<milliSatoshi>
amountはユーザが指定した金額でmillisatoshi単位。
6. ライトニングサービスはGETリクエストを受け取り、以下の形式のJSONレスポンスを返す:
code:_.json
{
pr: string, // bech32でシリアライズされたライトニングインボイス
routes: [] // から配列
}
または
{"status":"ERROR", "reason":"error details..."}
7. ライトニングウォレットは提供されたインボイス内のhタグがmetadata文字列をUTF-8エンコーディングでバイト列にしたもののハッシュ値と一致することを検証する
8. ライトニングウォレットは提供されたインボイス内の金額がユーザが先ほど指定した金額と等しいことを検証する
9. ライトニングウォレットはインボイスに対して支払う。この時点で追加でユーザへの確認を行う必要はない。
サーバサイドのLNURL-PAYのためのmetadataについての注意事項
クライアントからの最初の呼び出し時
metadataオブジェクトを組み立てて、JSONに変換し、文字列として親のJSONに含める。
クライアントから2回目の呼び出し時
1. 次の通りハッシュを計算する: sha256(utf8ByteArray(エスケープされていないmetadata文字列))
2. 得られたハッシュ値を用いて、支払いリクエストを生成する