import { bytesToHex } from "@noble/hashes/utils"; import { decode as invoiceDecode } from "light-bolt11-decoder"; export interface InvoiceDetails { amount?: number; expire?: number; timestamp?: number; description?: string; descriptionHash?: string; paymentHash?: string; expired: boolean; pr: string; } export function decodeInvoice(pr: string): InvoiceDetails | undefined { try { const parsed = invoiceDecode(pr); const amountSection = parsed.sections.find(a => a.name === "amount"); const amount = amountSection ? Number(amountSection.value as number | string) : undefined; const timestampSection = parsed.sections.find(a => a.name === "timestamp"); const timestamp = timestampSection ? Number(timestampSection.value as number | string) : undefined; const expirySection = parsed.sections.find(a => a.name === "expiry"); const expire = expirySection ? Number(expirySection.value as number | string) : undefined; const descriptionSection = parsed.sections.find(a => a.name === "description")?.value; const descriptionHashSection = parsed.sections.find(a => a.name === "description_hash")?.value; const paymentHashSection = parsed.sections.find(a => a.name === "payment_hash")?.value; const ret = { pr, amount: amount, expire: timestamp && expire ? timestamp + expire : undefined, timestamp: timestamp, description: descriptionSection as string | undefined, descriptionHash: descriptionHashSection ? typeof descriptionHashSection === "string" ? (descriptionHashSection as string) : bytesToHex(descriptionHashSection as Uint8Array) : undefined, paymentHash: paymentHashSection ? typeof paymentHashSection === "string" ? (paymentHashSection as string) : bytesToHex(paymentHashSection as Uint8Array) : undefined, expired: false, }; if (ret.expire) { ret.expired = ret.expire < new Date().getTime() / 1000; } return ret; } catch (e) { console.error(e); } }