aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-05 00:35:17 -0700
committerAdam Soltys <[email protected]>2026-09-05 00:35:17 -0700
commit917633aeeab8518af9e52a16532d8485dbd62e2a (patch)
treef476520ee15819936872744df0074da710fe104d /lib
parent54419060c1255f06d3c119b3f9c5334e1fa8bc07 (diff)
downloadcoinos-server-917633aeeab8518af9e52a16532d8485dbd62e2a.tar.gz
coinos-server-917633aeeab8518af9e52a16532d8485dbd62e2a.zip
credit: skip settlements for a deleted account instead of throwing
getUser(inv.uid) returns nothing when the account was deleted but its invoice or bolt12 offer still receives (OCEAN payouts to a deleted user's offer). The destructure on the next line threw inside the lightning listener, which never advanced pay_index and crash-looped the app every 50s, blocking all incoming lightning for two hours. Record the preimage in `missing` and return, as an unknown invoice already does. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01VMi2Y1oKPZ3TeeFmLej47y
Diffstat (limited to 'lib')
-rw-r--r--lib/payments.ts10
1 files changed, 10 insertions, 0 deletions
diff --git a/lib/payments.ts b/lib/payments.ts
index eba60eb0..b26b443f 100644
--- a/lib/payments.ts
+++ b/lib/payments.ts
@@ -385,6 +385,16 @@ export const credit = async ({
if (type === PaymentType.internal) amount += tip;
const user = await getUser(inv.uid);
+ if (!user) {
+ // The account is gone (deleted) but its invoice still receives — e.g. a
+ // bolt12 offer a mining pool keeps paying. Record the settlement in
+ // `missing` and skip, like an unknown invoice. Throwing here wedged the
+ // lightning listener on one settlement and blocked every later receipt
+ // for two hours (2026-09-05, pay_index 1068006).
+ warn("received payment for missing user", inv.uid, hash, amount);
+ await db.sAdd("missing", ref.split(":")[0]);
+ return;
+ }
const { id: uid, currency } = user;
const rates = await g("rates");