From add3ad93ff37f1daaedab5788f00663be299555c Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 30 Jul 2026 08:51:36 -0700 Subject: bolt12 zaps: pay offers, NWC pay/receive, per-user offers, NIP-44 - sendLightning fetches an invoice from lno1 offers (payer_note passthrough for NIP-177 zap intents) and pays it through the existing bolt12 path - NWC: new nwc#2 pay/receive methods (BIP-321 URIs, payer proofs stubbed until CLN 26.06 createproof), nip44_v2 alongside nip04 with per-request scheme detection, dual 23196/23197 notifications, 13194 refreshed when its content or encryption tag goes stale - standing per-user bolt12 offer via GET /offer; incoming bolt12 payments record invreq_payer_note as memo - parse/fetchinvoice routes handle offers; zap display parses kind 9736 receipts (amount tag + embedded intent) and drops a call to a sync() helper that never existed Co-Authored-By: Claude Fable 5 --- lib/nostr.ts | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'lib/nostr.ts') diff --git a/lib/nostr.ts b/lib/nostr.ts index 064e1952..ed1b2f42 100644 --- a/lib/nostr.ts +++ b/lib/nostr.ts @@ -4,7 +4,14 @@ import { l, warn } from "$lib/logging"; import { scan } from "$lib/strfry"; import { fail, fields, getUser, pick } from "$lib/utils"; import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; -import { finalizeEvent, getPublicKey, nip19, verifyEvent } from "nostr-tools"; +import { + finalizeEvent, + getPublicKey, + nip04, + nip19, + nip44, + verifyEvent, +} from "nostr-tools"; import type { Event } from "nostr-tools"; import { AbstractSimplePool } from "nostr-tools/abstract-pool"; import { Relay } from "nostr-tools/relay"; @@ -37,6 +44,21 @@ export const anon = (pubkey) => ({ followers: [], }); +// NIP-47 encryption schemes: clients pick one from the 13194 info event's +// `encryption` tag and mark their requests with the same tag; replies use +// whatever the request used. No tag means legacy nip04. +export const encryptionSchemes = "nip44_v2 nip04"; + +export const decryptPayload = (scheme, sk, pk, content) => + scheme === "nip44_v2" + ? nip44.decrypt(content, nip44.getConversationKey(hexToBytes(sk), pk)) + : nip04.decrypt(sk, pk, content); + +export const encryptPayload = (scheme, sk, pk, plaintext) => + scheme === "nip44_v2" + ? nip44.encrypt(plaintext, nip44.getConversationKey(hexToBytes(sk), pk)) + : nip04.encrypt(sk, pk, plaintext); + export async function publish(ev, url = config.nostr) { if (!verifyEvent(ev)) fail("Invalid event"); const r = await Relay.connect(url); -- cgit v1.2.3