fix: add quickpay daily spend limit - #672
Conversation
Track USD spend on the local calendar day so QuickPay can enforce a daily cap.
Expose the Android daily multiplier steps and resolved dollar cap in settings, and keep the value in backup.
Keep auto-pay PIN-free under the daily limit, record spend on success or pending, and send over-cap payments to Confirm.
Greptile SummaryThe PR adds a persisted, day-keyed QuickPay spending cap, routes over-cap payments through confirmation, and carries reservations through pending payment resolution.
Confidence Score: 4/5The PR is not yet safe to merge because an immediately settling payment can still leave a failed QuickPay reservation consuming the daily cap. The previous thread's final reply said the listener-before-binding order resolved the race, but terminal events are also handled independently by AppViewModel and can clear or release the hash after send returns but before the separately scheduled watch task binds the reservation. Files Needing Attention: Bitkit/ViewModels/WalletViewModel.swift, Bitkit/Views/Wallets/Send/SendQuickpay.swift, Bitkit/ViewModels/AppViewModel.swift
|
| Filename | Overview |
|---|---|
| Bitkit/ViewModels/WalletViewModel.swift | Adds timeout-aware payment watching, but defers reservation binding until a child watch task runs, preserving an early-terminal-event race. |
| Bitkit/Views/Wallets/Send/SendQuickpay.swift | Reserves spend and binds it through afterListening while retaining timed-out reservations for later terminal resolution. |
| Bitkit/Utilities/QuickPaySpendStore.swift | Implements synchronized daily spend and hash-keyed reservation persistence with idempotent terminal cleanup. |
| Bitkit/ViewModels/AppViewModel.swift | Resolves pending QuickPay payments and clears or releases their reservations on terminal events. |
| Bitkit/Utilities/PaymentNavigationHelper.swift | Applies the new daily-cap check when selecting QuickPay and provides replacement navigation for over-cap payments. |
Reviews (3): Last reviewed commit: "chore: drop QuickpaySettings preview" | Re-trigger Greptile
ben-kaufman
left a comment
There was a problem hiding this comment.
Three new findings from the re-audit.
This comment was marked as outdated.
This comment was marked as outdated.
|
Tested the QuickPay daily limit flow on local regtest with fixed-amount hold invoices. Covered:
The timeout now starts after I also reviewed the code structure around |
Keep existing cache fields required. Only the new spend ledger keys are optional.
Remove the unused daily-limit string, defaultThresholdUsd, settings preview, and unused SendQuickpay store injection.
This comment was marked as resolved.
This comment was marked as resolved.
Bind the reservation to the invoice hash before send. AppViewModel only routes events to noteTerminal. Persist a canonical ledger and reconcile against LDK without treating absence as failure.
Write only the canonical ledger. Drop unused phase/dispatch flags and collapse send-error classification to a Bool.
Restore from the Android three-field snapshot only. Local store stays a ledger. Drop unused record id and ledger version.
Write and restore quickPayAmount so the per-tx threshold round-trips with the daily multiplier.
Duplicate is NodeError.DuplicatePayment only.
Closes #670
This PR ports QuickPay daily spend limits from Android (synonymdev/bitkit-android#1159) so auto-pay stays PIN-free under a configurable daily cap.
Description
QuickPay stays confirmation-free and PIN-free while a payment is under the per-tx threshold and the daily cap (
threshold × multiplierUSD). Once the cap would be exceeded, the payment opens Confirm, where PIN for payments still applies if that setting is on.1,3,5,10,50(default5)$capquickPayDailyLimitMultiplierPreview
happy-daily-cap.mp4
over-cap.mp4
QA Notes
Manual Tests
$copy updates (threshold × multiplier).regression:Settings → QuickPay → leave QuickPay off → scan a fixed-amount LN invoice: Confirm still opens.regression:Variable amount LN invoice / LNURL-pay: still lands on Amount, not QuickPay.Automated Checks
BitkitTests/QuickPaySpendStoreTests.swift.BitkitTests/PaymentNavigationHelperTests.swift.BitkitTests/QuickPayLimitsTests.swift.BitkitTests/AddressTypeSettingsTests.swift.node scripts/validate-translations.js: 0 errors.