diff options
| author | Adam Soltys <[email protected]> | 2026-07-30 08:57:17 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-07-30 08:57:17 -0700 |
| commit | f5a5b1ff856efcd2849275a301daabb80ef76638 (patch) | |
| tree | 18ad6cc4e109ddeca9d81b162e161c02cd781ec6 | |
| parent | add3ad93ff37f1daaedab5788f00663be299555c (diff) | |
| download | coinos-server-f5a5b1ff856efcd2849275a301daabb80ef76638.tar.gz coinos-server-f5a5b1ff856efcd2849275a301daabb80ef76638.zip | |
bolt12 payer proofs: disclose zap fields, lightningd v26.06.2 in sample
createproof's default proof omits invreq_payer_note, and passing include
replaces the default disclosure set — so for zap payments request both
invreq_payer_note and invoice_amount, which NIP-177 verification requires.
Verified end to end on v26.06.2: NWC pay over nip44 returns a proof that
decodes valid with note + amount disclosed and preimage matching the
payment hash.
Co-Authored-By: Claude Fable 5 <[email protected]>
| -rw-r--r-- | compose.yml.sample | 4 | ||||
| -rw-r--r-- | lib/nwc.ts | 27 |
2 files changed, 19 insertions, 12 deletions
diff --git a/compose.yml.sample b/compose.yml.sample index 7e24f0c2..8b774520 100644 --- a/compose.yml.sample +++ b/compose.yml.sample @@ -45,7 +45,7 @@ services: - ./data/lightning:/root/.lightning restart: always clb: - image: elementsproject/lightningd:v23.11.1-amd64 + image: ghcr.io/coinos/lightningd:v26.06.2 container_name: clb environment: LIGHTNINGD_NETWORK: regtest @@ -53,7 +53,7 @@ services: - ./data/lightningb:/root/.lightning restart: always clc: - image: elementsproject/lightningd:v23.11.1-amd64 + image: ghcr.io/coinos/lightningd:v26.06.2 container_name: clc environment: LIGHTNINGD_NETWORK: regtest @@ -351,16 +351,23 @@ const parseInstruction = (payment) => { return s.startsWith("ln") ? s : null; }; -// CLN v26.06 adds an experimental `createproof` RPC producing the lnp payer -// proof that NIP-177 zap receipts (kind 9736) embed: createproof(invstring, -// [note], [include]) -> { proofs: [{ bolt12: "lnp..." }] }. Feature-detect -// through the generic call() — on older nodes (current: v25.12) this errors -// and we omit the proof, which the nwc `pay` spec allows. The proof format is -// still draft; once 26.06 is deployed, check whether NIP-177's required -// fields (invreq_payer_note, invoice_amount) need an explicit `include` list. -const createPayerProof = async (invstring: string) => { +// CLN v26.06's experimental `createproof` RPC produces the lnp payer proof +// that NIP-177 zap receipts (kind 9736) embed. The default proof OMITS +// invreq_payer_note, which NIP-177 verification requires disclosed (it binds +// the payment to the zap intent) — and passing `include` REPLACES the default +// disclosure set, so invoice_amount must be re-listed alongside it or the +// amount gets hidden too. Feature-detected through the generic call() — on +// older nodes this errors and we omit the proof, which the nwc `pay` spec +// allows. +const createPayerProof = async ( + invstring: string, + hasPayerNote: boolean = false, +) => { try { - const r = await ln.call("createproof", { invstring }); + const r = await ln.call("createproof", { + invstring, + ...(hasPayerNote && { include: ["invreq_payer_note", "invoice_amount"] }), + }); return r?.proofs?.[0]?.bolt12; } catch (e) { return undefined; @@ -640,7 +647,7 @@ const handle = (method, params, ev, app, user) => // invoice fetched from it) payer_proof: instruction_type === "bolt12" - ? await createPayerProof(p.hash) + ? await createPayerProof(p.hash, !!payer_note) : undefined, created_at, settled_at: Math.floor(Date.now() / 1000), |
