Skip to content

fix: add quickpay daily spend limit - #672

Open
ovitrif wants to merge 12 commits into
masterfrom
fix/670-quickpay-day-limit
Open

fix: add quickpay daily spend limit#672
ovitrif wants to merge 12 commits into
masterfrom
fix/670-quickpay-day-limit

Conversation

@ovitrif

@ovitrif ovitrif commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

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 × multiplier USD). Once the cap would be exceeded, the payment opens Confirm, where PIN for payments still applies if that setting is on.

  • Daily multiplier steps: 1, 3, 5, 10, 50 (default 5)
  • Spend is reserved in USD cents before pay, kept on Success/Pending, and released on failure only from the matching calendar day
  • Spend resets on the local calendar day and is kept if the clock rolls back
  • Settings add a second slider and show the resolved daily $ cap
  • The multiplier is included in settings backup as quickPayDailyLimitMultiplier
  • Slider labels and the currency-conversion error are localized. Over-cap is silent Confirm
  • Successful QuickPay shows amount plus the paid routing fee
  • Over-cap or a lost reserve race replaces QuickPay with Confirm, so Back does not return to the auto-pay loader
  • Try Again remounts QuickPay so a new payment starts

Preview

QuickPay Settings Over Cap → Confirm + PIN
happy-daily-cap.mp4
over-cap.mp4
Screenshot

QA Notes

Manual Tests

  • 1. Settings → QuickPay → enable QuickPay → move threshold and daily multiplier sliders: resolved daily $ copy updates (threshold × multiplier).
  • 2. Unlocked, under per-tx and daily cap, PIN for payments on → scan a fixed-amount LN invoice: QuickPay runs with no payment PIN.
  • 3. Exhaust or exceed the daily cap → scan another eligible invoice: Confirm opens; payment PIN is required if that setting is on.
  • 4. regression: Settings → QuickPay → leave QuickPay off → scan a fixed-amount LN invoice: Confirm still opens.
  • 5. regression: Variable amount LN invoice / LNURL-pay: still lands on Amount, not QuickPay.
  • 6. QuickPay success: displayed amount includes the paid routing fee.
  • 7. Over daily cap → Confirm: Back does not return to the QuickPay loader.
  • 8. QuickPay failure → Try Again: a new payment starts.

Automated Checks

  • Unit tests added: day-keyed USD-cent spend reserve/release/reset and clock-rollback keep-spend in BitkitTests/QuickPaySpendStoreTests.swift.
  • Unit tests added: QuickPay routing under the cap, at the cap, and over the cap, plus replace-QuickPay navigation, in BitkitTests/PaymentNavigationHelperTests.swift.
  • Unit tests added: fee-inclusive success amount and multiplier fallback in BitkitTests/QuickPayLimitsTests.swift.
  • Unit tests modified: backup/restore of the daily multiplier, including the Android key, in BitkitTests/AddressTypeSettingsTests.swift.
  • node scripts/validate-translations.js: 0 errors.
  • Focused unit tests passed locally on iPhone 16 (iOS 18.5).
  • CI: standard build and test checks run by the PR bot.

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.
@ovitrif ovitrif changed the title fix: add QuickPay daily spend limit fix: add quickpay daily spend limit Aug 18, 2026
@ovitrif ovitrif self-assigned this Aug 18, 2026
@ovitrif ovitrif added this to the 2.5.0 milestone Aug 18, 2026
@ovitrif
ovitrif marked this pull request as ready for review August 18, 2026 16:30
@ovitrif
ovitrif requested review from ben-kaufman and pwltr August 18, 2026 16:30
@greptile-apps

greptile-apps Bot commented Aug 18, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a configurable QuickPay daily spend cap and tracks reserved spend through successful, failed, and pending Lightning payments.

  • Adds persistent, day-keyed USD-cent spend accounting and hash-keyed pending-payment reservations.
  • Routes payments exceeding the daily cap through confirmation and applicable PIN checks.
  • Adds daily-limit settings, backup compatibility, localization, fee-inclusive success amounts, and focused tests.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
Bitkit/Views/Wallets/Send/SendQuickpay.swift Reserves QuickPay spend before submission and binds the reservation to the payment hash after the event listener is active.
Bitkit/ViewModels/WalletViewModel.swift Exposes listener-registration and timeout callbacks with the submitted payment hash while returning settled fee information.
Bitkit/ViewModels/AppViewModel.swift Resolves pending QuickPay reservations on terminal payment events and propagates paid fees for the success screen.
Bitkit/Utilities/QuickPaySpendStore.swift Implements synchronized daily spend accounting, reservation persistence, rollover handling, and release behavior.
Bitkit/Utilities/PaymentNavigationHelper.swift Applies per-transaction and daily QuickPay eligibility checks and provides confirmation fallback routing.
Bitkit/ViewModels/SettingsViewModel.swift Persists, restores, sanitizes, resets, and backs up the configurable daily-limit multiplier.

Sequence Diagram

sequenceDiagram
    participant Q as SendQuickpay
    participant S as QuickPaySpendStore
    participant W as WalletViewModel
    participant A as AppViewModel
    Q->>S: Reserve daily spend
    Q->>W: sendWithTimeout
    W->>W: Register payment event listener
    W->>Q: afterListening(paymentHash)
    Q->>S: Remember reservation by hash
    alt Payment settles
        W-->>Q: Success or failure
        Q->>S: Keep or release reservation
    else Payment times out
        W->>A: Add pending payment hash
        A-->>S: Later clear on success or release on failure
    end
Loading

Reviews (2): Last reviewed commit: "fix: port QuickPay cents spend ledger" | Re-trigger Greptile

Comment thread Bitkit/Views/Wallets/Send/SendQuickpay.swift
ben-kaufman

This comment was marked as resolved.

@ovitrif
ovitrif requested a review from ben-kaufman August 18, 2026 22:02

@ben-kaufman ben-kaufman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three new findings from the re-audit.

Comment thread Bitkit/Utilities/QuickPaySpendStore.swift
Comment thread Bitkit/Views/Wallets/Send/SendPendingScreen.swift Outdated
Comment thread Bitkit/Views/Wallets/Send/SendQuickpay.swift Outdated
@ovitrif ovitrif removed this from the 2.5.0 milestone Aug 19, 2026
@ovitrif

This comment was marked as outdated.

@ovitrif
ovitrif marked this pull request as draft August 19, 2026 13:59
@ovitrif
ovitrif marked this pull request as ready for review August 19, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Port QuickPay daily spend limit from Android

2 participants