UNPKG

nip47

Version:

A flexible library for sending and receiving payments via NWC.

120 lines (117 loc) 3.38 kB
// src/nwc/PaymentRequest.ts import { NDKEvent } from "@nostr-dev-kit/ndk"; // src/nwc/Nwc.ts import { nip04, nip19, finishEvent } from "nostr-tools"; var Kinds = { NwcInfo: 13194, NwcRequest: 23194, NwcResponse: 23195 }; var NWC = class _NWC { // relay: Relay; relayUrl; secret; walletPubkey; options; subscribers; // from nostr-tools/nip47 static parseWalletConnectUrl(walletConnectUrl) { walletConnectUrl = walletConnectUrl.replace("nostrwalletconnect://", "http://").replace("nostr+walletconnect://", "http://"); const url = new URL(walletConnectUrl); const options = {}; options.walletPubkey = url.host; const secret = url.searchParams.get("secret"); const relayUrl = url.searchParams.get("relay"); if (secret) { options.secret = secret; } if (relayUrl) { options.relayUrl = relayUrl; } return options; } constructor(nostrWalletConnectUrl) { this.options = _NWC.parseWalletConnectUrl(nostrWalletConnectUrl); if (!this.options.relayUrl || !this.options.secret || !this.options.walletPubkey) { throw new Error( "invalid connection string. Requires relay, secret, and walletPubkey" ); } this.relayUrl = this.options.relayUrl; this.secret = this.options.secret.toLowerCase().startsWith("nsec") ? nip19.decode(this.options.secret).data : this.options.secret; this.walletPubkey = this.options.walletPubkey.toLowerCase().startsWith("npub") ? nip19.decode(this.options.walletPubkey).data : this.options.walletPubkey; this.subscribers = {}; if (globalThis.WebSocket === void 0) { console.error( "WebSocket is undefined. Make sure to `import websocket-polyfill` for nodejs environments" ); } } async makeNWCRequestEvent(invoice) { if (!invoice) throw new Error("invoice is required"); const content = { method: "pay_invoice", params: { invoice } }; const encryptedContent = await nip04.encrypt( this.secret, this.walletPubkey, JSON.stringify(content) ); const eventTemplate = { kind: Kinds.NwcRequest, created_at: Math.round(Date.now() / 1e3), content: encryptedContent, tags: [["p", this.walletPubkey]] }; return finishEvent(eventTemplate, this.secret); } async decryptContent(encryptedContent) { const content = await nip04.decrypt(this.secret, this.walletPubkey, encryptedContent); return JSON.parse(content); } }; // src/nwc/PaymentRequest.ts var PaymentRequestEvent = class _PaymentRequestEvent extends NDKEvent { invoice; nwc; event; constructor(nwc, invoice, event) { super(void 0, event); this.nwc = nwc; this.invoice = invoice; this.event = new NDKEvent(void 0, event); } static async create(nwcOrUrl, invoice) { let nwc; if (typeof nwcOrUrl === "string") { nwc = new NWC(nwcOrUrl); } else { nwc = nwcOrUrl; } const event = await nwc.makeNWCRequestEvent(invoice); return new _PaymentRequestEvent(nwc, invoice, event); } get responseFilter() { return { kinds: [23195], tags: [ ["e", this.id], ["p", this.pubkey] ] }; } getResponseFilter() { return this.responseFilter; } get relayToListenTo() { return this.nwc.relayUrl; } }; export { NWC, PaymentRequestEvent };