fix: allow safe payment request retries - #1370
Conversation
|
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
jvsena42
left a comment
There was a problem hiding this comment.
One LOW inline (journey parity). No double-pay path found.
Checked and clean:
- Every
releasePrivatePaymentListcall follows a consume in the same coroutine and runs only on branches with nothing dispatched or with a definite failure. - On-chain:
sendAttemptedflips right beforelightningService.send. The definite list is ldk-node's pre-broadcast surface, andrecoverCatching { broadcastTxId ?: throw it }turns post-broadcast errors into success. - Lightning:
PaymentSendingFailedis synchronous and pre-HTLC in ldk-node.PersistenceFailed/DuplicatePayment/timeouts stay pending, andPaymentFailedis post-abandon. - Release is version-equality guarded and serialized, so it cannot undo a newer consumption.
- A retry re-resolves the request from the SDK and needs a new swipe. There is no auto re-present after the sheet was shown.
PrivateLinkPendingleaves the lifecycle untouched and keeps Dismiss working.- HW: consume happens after signing, right before broadcast, and preparation failure releases.
Paykit is on by default on master since #1359 (unreleased), so these paths run for everyone once this ships.
There was a problem hiding this comment.
Advice: ✅ Approve
Review: diff 21 files.
Pair PR synonymdev/bitkit-ios#826: diverges, see the parity finding.
Findings:
6 inline (6 LOW)
QA:
Tests queued.
Reviewed by claude-opus-5-5-xhigh via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest (author)
There was a problem hiding this comment.
Advice: ✅ Approve
Reaudit: diff 8 files.
No new findings; the rest is in the review.
Pair PR synonymdev/bitkit-ios#826: equivalent.
QA:
Tests queued.
Reviewed by gpt-6-sol-xhigh via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest (author)
There was a problem hiding this comment.
Advice: ✅ Approve
Reaudit: diff 8 files.
No new findings; the rest is in the review.
Pair PR synonymdev/bitkit-ios#826: same change.
QA:
No test ran: 554 unit tests failed on aarch64; x86 Gradle aborted under QEMU.
0 of 2 ran; the other 2 could not run on our setup, so this stays Advice.
Tests J1, J2 ⏭️
Test J1
The unit tests failed on aarch64; x86 Gradle aborted under QEMU.
log
LightningNodeServiceTest > foreground service timeout stops service before node stop completes FAILED
java.lang.AssertionError: The Robolectric native runtime is not supported on Linux (aarch64)
3019 tests completed, 554 failed
> Task :app:testDevDebugUnitTest FAILED
[Too many errors, abort]
qemu: uncaught target signal 6 (Aborted) - core dumped
Test J2
The unit tests failed on aarch64; x86 Gradle aborted under QEMU.
Reviewed by gpt-6-sol-xhigh via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest (author)
There was a problem hiding this comment.
Verdict: ✅ Approve
Retest for the review: journeys J1 and J2 now pass.
QA:
Tested on Android 15 emulator, regtest.
Tests J1, J2 ✅
Test J1
A private Payment Request can still be paid after its first send fails before Lightning dispatch.
J1.mp4 |
![]() | ![]() |
Test J2
The accepted regtest issuer fixture reaches Bitkit and opens payment confirmation.
J2.mp4 |
![]() | ![]() | ![]() |
The PR body includes definite-pre-broadcast-retry.xml and issuer-interoperability.xml.
Reviewed by gpt-6-sol-xhigh via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest (author)





Fixes #1348
Description
Out of Scope
Design
Preview
N/A because no capture is available.
QA Notes
Journeys
definite-pre-broadcast-retry.xml- retries the same request after a definite LNURL callback failure.issuer-interoperability.xml- checks the unpaid request amount and waiting status on the detail screen.Manual Tests
N/A
Automated Checks
PrivatePaykitRepoTest.kt- gates details on a linked peer and releases only the matching consumed version.PaymentRequestPresentationTest.kt- covers unpaid movement styling and pending status.AppViewModelSendFlowTest.kt- covers definite failures, recovery UI ownership, success, and uncertainty.