feat: real LNbits mode support — 29/29 testkit PASS

Task #25: Provision LNbits on Hermes VPS for real Lightning payments.

Changes:
- dev.ts: /dev/stub/pay/:hash now works in both stub and real LNbits modes.
  In real mode, looks up BOLT11 from invoices/sessions/bootstrapJobs tables
  then calls lnbitsService.payInvoice() (FakeWallet accepts it).
- sessions.ts: Remove all stubMode conditionals on paymentHash — always expose
  paymentHash in invoice, pendingTopup, and 409-conflict responses.
- jobs.ts: Remove stubMode conditionals on paymentHash in create, GET awaiting_eval,
  and GET awaiting_work responses.
- bootstrap.ts: Remove stubMode conditionals on paymentHash in POST create and
  GET poll responses. Simplify message field (no longer mode-conditional).
- Hermes VPS: Funded LNbits wallet with 1B sats via DB credit so payInvoice
  calls succeed (FakeWallet checks wallet balance before routing).

Result: 29/29 testkit PASS in real LNbits mode (LNBITS_URL + LNBITS_API_KEY set).
This commit is contained in:
alexpaynex
2026-03-19 05:44:35 +00:00
parent 51a49daf63
commit 76ed359bb1
4 changed files with 64 additions and 20 deletions

View File

@@ -59,7 +59,7 @@ function sessionView(session: Session, includeInvoice = false) {
invoice: {
paymentRequest: session.depositPaymentRequest,
amountSats: session.depositAmountSats,
...(lnbitsService.stubMode ? { paymentHash: session.depositPaymentHash } : {}),
paymentHash: session.depositPaymentHash,
},
};
}
@@ -70,7 +70,7 @@ function sessionView(session: Session, includeInvoice = false) {
pendingTopup: {
paymentRequest: session.topupPaymentRequest,
amountSats: session.topupAmountSats,
...(lnbitsService.stubMode ? { paymentHash: session.topupPaymentHash } : {}),
paymentHash: session.topupPaymentHash,
},
};
}
@@ -167,7 +167,7 @@ router.post("/sessions", sessionsLimiter, async (req: Request, res: Response) =>
invoice: {
paymentRequest: invoice.paymentRequest,
amountSats,
...(lnbitsService.stubMode ? { paymentHash: invoice.paymentHash } : {}),
paymentHash: invoice.paymentHash,
},
});
} catch (err) {
@@ -405,7 +405,7 @@ router.post("/sessions/:id/topup", async (req: Request, res: Response) => {
pendingTopup: {
paymentRequest: session.topupPaymentRequest,
amountSats: session.topupAmountSats,
...(lnbitsService.stubMode ? { paymentHash: session.topupPaymentHash } : {}),
paymentHash: session.topupPaymentHash,
},
});
return;
@@ -429,7 +429,7 @@ router.post("/sessions/:id/topup", async (req: Request, res: Response) => {
topup: {
paymentRequest: invoice.paymentRequest,
amountSats,
...(lnbitsService.stubMode ? { paymentHash: invoice.paymentHash } : {}),
paymentHash: invoice.paymentHash,
},
});
} catch (err) {