aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* move UTXO lockUnspent from build() to sendOnchain()Adam Soltys2026-05-171-10/+9
| | | | | | | | | | | | | | build() is called from both /payments (the actual send path) and /fee (the fee-estimation endpoint). Locking UTXOs in build() meant that every fee quote was reserving inputs that never got broadcast, slowly leaking UTXO locks until a bitcoind restart cleared them — eventually starving the wallet of selectable inputs even when balance was healthy. The lock belongs at the point where we're actually about to broadcast, which is sendOnchain. Released in the catch path on broadcast failure; on success, the inputs become spent and the lock is moot. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* mirror payment records to arc + atomic /confirm lock to prevent double-creditsAdam Soltys2026-05-172-4/+37
| | | | | | | | | | | | | | | | | | | | | | | | Follows up the Apr 29 double-credit incident. Two parallel callers of /confirm (walletnotify, catchUp, bulk sweeps) could each read p.confirmed=false and each run the multi() that increments balance — because main-db pointers were sometimes missing while arc still had them, gf()'s arc fallback returned stale state. Three pieces here: - routes/payments.ts: SET NX EX 60 lock around the /confirm credit block keyed by `confirmlock:${txid}:${vout}`. Concurrent callers short-circuit cleanly. The lock is released on success and on every early-return. - lib/payments.ts credit() + routes/payments.ts /confirm: mirror the payment/invoice records and the `payment:<txid>:<vout>` / `payment:<hash>` pointer keys into arc as soon as they're written. gf() will then find the prior credit via arc fallback even if the main-db copy is wiped by a future data-loss event. - routes/payments.ts hide `revertedDuplicate` payments from the user's payment list — matches the same filter added to lib/nwc.ts list_transactions so reverted records never surface in either rendering path. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* nwc: handle stale client state cleanly and skip reverted-duplicate recordsAdam Soltys2026-05-171-1/+5
| | | | | | | | | | | | | | | | | | Three small NWC robustness fixes that surfaced from the Apr 29 double-credit cleanup: - fail loudly when an NWC request references a pubkey whose user record no longer exists (migrated/deleted account); previously crashed inside handle() on `user.id` - swallow `pubkey not found` and `user not found` in the per-event catch so deleted-app/migrated-user spam doesn't fill the error log — these are client-side staleness, not server faults - use gf() instead of g() when fetching payment records (consistent with the rest of the codebase: arc fallback for wiped main-db pointers) - filter `revertedDuplicate` payments out of list_transactions so clients never see the doubled records that were later reverted Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* serialize limit check + reservation under per-asset mutexAdam Soltys2026-05-171-26/+81
| | | | | | | | | | | | | | | | | | | The previous check at debit() read ${type}:limit, compared amount, and deferred any decrement to the next freezeCheck tick (every 10s). That made the check non-atomic: a burst of concurrent withdrawals could each pass the same stale limit value before any reconciliation happened. Combined with the /gateway abuse, this allowed the hot wallet to be drained. withLimitLock() serializes the check + db.decrBy inside a per-type async mutex, and freezeCheck also takes the lock when overwriting limits so its 10s reconciliation can't race in-flight checks. Single-process only; distributed lock or TigerBeetle reservation needed if app ever scales out. Trade-off: decremented limits are not refunded on payment failure — they get reset by the next freezeCheck within 10s. Acceptable false-deny window in exchange for correctness against bursts. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* remove /gateway endpointAdam Soltys2026-05-172-10/+0
| | | | | | | | | Unauthenticated arbitrary db.set abuse vector. Exploited to inflate user balances and override safety controls (bitcoin:limit, limit, hardfreeze, freeze) in real time, leading to a hot-wallet drain. Route and handler both fully removed. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
* prevent duplicate utxo selectionAdam Soltys2026-04-261-1/+17
|
* check listpays before reversingAdam Soltys2026-04-252-5/+14
|
* remove nwc fieldAdam Soltys2026-04-011-1/+0
|
* nwc heartbeatAdam Soltys2026-03-292-14/+28
|
* lnurl proxyAdam Soltys2026-03-275-1/+146
|
* don't remove missing paymentsAdam Soltys2026-03-241-2/+1
|
* dockerfilesAdam Soltys2026-03-1911-0/+124
|
* ensure lightning payments get processedAdam Soltys2026-03-192-1/+11
|
* listener logsAdam Soltys2026-03-182-3/+2
|
* stop republishing primal eventsAdam Soltys2026-03-182-3/+14
|
* remove logsAdam Soltys2026-03-1714-50/+8
|
* catch reverse errorsAdam Soltys2026-03-173-2/+1859
|
* adjust ln minfeeregtest-dataAdam Soltys2026-03-159-26/+314
|
* pass bytes for app secretAdam Soltys2026-03-143-2/+3
|
* use bytes for nostr toolsAdam Soltys2026-03-133-4/+5
|
* fix pending payment cleanup and login password verificationAdam Soltys2026-03-062-5/+11
| | | | | | | Skip non-lightning entries in pending payments check and handle malformed password hashes gracefully during login. Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix login/reset glitchesAdam Soltys2026-03-031-7/+18
|
* handle socket errorsAdam Soltys2026-02-253-16/+334
|
* fix lnurl description_hash mismatchAdam Soltys2026-02-251-2/+6
| | | | Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix transitive dependency vulnerabilitiesAdam Soltys2026-02-242-9/+17
| | | | Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix addmanagersAdam Soltys2026-02-101-5/+4
|
* filter null managersAdam Soltys2026-02-101-2/+2
|
* check forwarded host headerAdam Soltys2026-02-061-1/+1
|
* health checkAdam Soltys2026-02-068-157/+272
|
* whitelist ua'sAdam Soltys2026-02-041-0/+11
|
* strip email from usernameAdam Soltys2026-02-021-0/+1
|
* consult archive for older paymentsAdam Soltys2026-01-305-12/+17
|
* relay reconnect logicAdam Soltys2026-01-302-31/+48
|
* purge old nwc eventsAdam Soltys2026-01-281-2/+12
|
* check usernameAdam Soltys2026-01-291-11/+1
|
* ip fallbackAdam Soltys2026-01-271-0/+5
|
* skip captcha for torAdam Soltys2026-01-271-0/+4
|
* case insensitive usernamesAdam Soltys2026-01-261-1/+4
|
* loggingAdam Soltys2026-01-261-0/+1
|
* captcha bypass whitelistAdam Soltys2026-01-261-10/+13
|
* read payments from archiveAdam Soltys2026-01-224-16/+66
|
* fix admin resetsAdam Soltys2026-01-221-7/+3
|
* api key captcha bypassAdam Soltys2026-01-221-3/+11
|
* captcha thresholdsAdam Soltys2026-01-211-11/+18
|
* require auth for accountsAdam Soltys2026-01-211-0/+5
|
* recaptcha on loginAdam Soltys2026-01-211-2/+32
|
* ignoreAdam Soltys2026-01-211-0/+2
|
* quiet nwc failuresAdam Soltys2026-01-211-8/+8
|
* loggingAdam Soltys2026-01-213-11/+11
|
* check usernameAdam Soltys2026-01-193-1/+3
|