From 9f06a2d677e579609ab70e4f8dc0742d112cda47 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 10 Jul 2026 22:55:56 -0700 Subject: payments: use the debited tip when crediting internal transfers credit() now credits the tip the sender was actually debited (passed in by the internal-transfer callers) instead of independently re-reading the invoice. This closes a time-of-check/time-of-use gap where an invoice's tip could be changed between the sender debit and the receiver credit, letting a payer be credited a tip they were never charged. External receipts (lightning/ecash) keep reading the invoice tip, since there is no paired coinos debit to diverge from. Also harden POST /invoice/:id: validate the tip is a sane non-negative integer and reject tip changes on an already-settled invoice. Co-Authored-By: Claude Opus 4.8 (1M context) --- routes/payments.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'routes/payments.ts') diff --git a/routes/payments.ts b/routes/payments.ts index 7dc45058..9c62d2bb 100644 --- a/routes/payments.ts +++ b/routes/payments.ts @@ -641,7 +641,7 @@ export default { let p; if (payee === id) { p = await debit({ hash: pr, amount, memo, user }); - await credit({ hash: pr, amount, memo, ref: user.id }); + await credit({ hash: pr, amount, memo, ref: user.id, tip: p.tip }); } else p = await sendLightning({ user, pr, amount, fee, memo }); res.send(p); -- cgit v1.2.3