From b183ea72bffd504da6fead104600f1bd9f0a5811 Mon Sep 17 00:00:00 2001 From: Toheeb Ojuolape <45619240+Toheeb-Ojuolape@users.noreply.github.com> Date: Mon, 7 Oct 2024 11:23:53 +0100 Subject: [PATCH 1/2] fix: implemented network error handling for verify payment --- src/invoice.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/invoice.ts b/src/invoice.ts index 06f315f..e656cf3 100644 --- a/src/invoice.ts +++ b/src/invoice.ts @@ -59,12 +59,17 @@ export default class Invoice { async verifyPayment(): Promise { if (!this.verify) throw new Error("LNURL verify not available"); - const result = await fetch(this.verify); - const json = await result.json(); - if (json.preimage) { - this.preimage = json.preimage; - } + try { + const result = await fetch(this.verify); + const json = await result.json(); + if (json.preimage) { + this.preimage = json.preimage; + } - return json.settled; + return json.settled; + } catch (error) { + console.error("failed to check LNURL-verify", error) + return false + } } } From 5b8a333b4c0f20118896d4e0a5c32a146991a9c9 Mon Sep 17 00:00:00 2001 From: Roland Bewick Date: Sun, 20 Oct 2024 21:09:37 +0700 Subject: [PATCH 2/2] chore: add verify payment tests --- src/invoice.test.ts | 51 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/invoice.test.ts b/src/invoice.test.ts index b1ae695..4df11ba 100644 --- a/src/invoice.test.ts +++ b/src/invoice.test.ts @@ -1,4 +1,5 @@ import Invoice from "./invoice"; +import fetchMock from "jest-fetch-mock"; const paymentRequestWithoutMemo = "lnbc10n1pj4xmazpp5ns890al37jpreen4rlpl6fsw2hlp9n9hm0ts4dvwvcxq8atf4v6qhp50kncf9zk35xg4lxewt4974ry6mudygsztsz8qn3ar8pn3mtpe50scqzzsxqyz5vqsp5k508kdmvfpuac6lvn9wumr9x4mcpnh2t6jyp5kkxcjhueq4xjxqq9qyyssq0m88mwgknhkqfsa9u8e9dp8v93xlm0lqggslzj8mpsnx3mdzm8z5k9ns7g299pfm9zwm4crs00a364cmpraxr54jw5cf2qx9vycucggqz2ggul"; @@ -47,9 +48,57 @@ describe("Invoice", () => { expect(decodedInvoice.satoshi).toBe(75831); }); - test("did not expired", () => { + test("did not expire", () => { const decodedInvoice = new Invoice({ pr: paymentRequestWithoutMemo }); decodedInvoice.expiryDate = new Date(Date.now() + 1000); expect(decodedInvoice.hasExpired()).toBe(false); }); + + test("verify catches exception", async () => { + const invoice = new Invoice({ pr: paymentRequestWithoutMemo }); + invoice.verify = "https://example.com/verify"; + + fetchMock.mockIf(/.*/, (_) => { + throw new Error("Something went wrong"); + }); + + const result = await invoice.verifyPayment(); + expect(result).toBe(false); + }); + + test("verify settled payment", async () => { + const invoice = new Invoice({ pr: paymentRequestWithoutMemo }); + invoice.verify = "https://example.com/verify"; + const preimage = "dummy preimage"; + + fetchMock.mockIf(/.*/, (_) => { + return Promise.resolve( + JSON.stringify({ + settled: true, + preimage, + }), + ); + }); + + const result = await invoice.verifyPayment(); + expect(result).toBe(true); + expect(invoice.preimage).toBe(preimage); + }); + + test("verify on unsettled payment", async () => { + const invoice = new Invoice({ pr: paymentRequestWithoutMemo }); + invoice.verify = "https://example.com/verify"; + + fetchMock.mockIf(/.*/, (_) => { + return Promise.resolve( + JSON.stringify({ + settled: false, + }), + ); + }); + + const result = await invoice.verifyPayment(); + expect(result).toBe(false); + expect(invoice.preimage).toBe(null); + }); });