fix: restore failed payment requests - #826
ben-kaufman wants to merge 7 commits into
Conversation
|
pwltr
left a comment
There was a problem hiding this comment.
Requesting changes for the HIGH-priority build failure noted inline.
| try await prepareIncomingPaymentRequest() | ||
| try await PaykitPaymentProofService.shared.markOnchainPaymentStarted(request, address: address) | ||
| } catch { | ||
| _ = paykitPaymentRequestManager.paymentRequestForRetry(request.id) |
There was a problem hiding this comment.
HIGH — Fix the async retry call so this head builds.
The new paymentRequestForRetry(request.id) call is actor-isolated, but this async function invokes it without await. The compiler reports “expression is async but is not marked with await” at this line; the current-head unit, integration, and local-build jobs all fail before tests can run. Please await the call (or otherwise perform the required actor hop) and rerun those checks.
There was a problem hiding this comment.
Added the missing actor hop. The retry test now awaits the lookup too and models the accepted SDK state before retrying.
There was a problem hiding this comment.
Verdict: ♻️ Comment
Review: diff 23 files.
Findings:
2 inline (1 MEDIUM, 1 LOW)
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 5 files.
No new findings; the rest is in the review.
Retest suggested: Tests 1, J1, J2.
Matching Android PR: synonymdev/bitkit-android#1370.
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 1 file.
No new findings; the rest is in the review.
Retest suggested: Tests 1, J1, J2 (Each prior QA item includes journeys/payment-requests/README.md, which the merge changes).
Pair PR synonymdev/bitkit-android#1370: equivalent.
QA:
Tests queued.
Reviewed by gpt-6-xhigh via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest (author)
There was a problem hiding this comment.
Verdict: ⛔️ Request Changes
Tests for the review: Test 1 fails; journeys J1 and J2 failed on our test setup, not the app.
QA:
Tested on two iOS 26.5 simulators (iPhone 17 Pro).
Test 1 ❌
Test 1
Peer Pay and Dismiss vanish during recovery.
1.mp4 |
![]() | ![]() |
log
Before block: PaymentRequestRow for Qa826peerRc56, 1,197 sats; PaymentRequestsBell, 2 pending.
WARN: Deferred incoming Paykit payment request presentation: category=resolution reason=payment_details_pending counterparty=pubky8qt3xpy...
t=0,2: PaymentRequestWaitingForDetailsToast, "Payment details are still being recovered. Try again shortly."
t=4,6,8,10,12,14,16,18,20,22,24,26,28,30: no toast; PaymentRequestsBell, 1 pending.
Pending sheet after Pay: only the unrelated fixture row remained; the peer's Pay and Dismiss controls were absent.
Tests J1, J2 ⏭️
Test J1
Not run: our test setup failed, not the app: Fixture private link stayed Linking before payment review.
J1.mp4 |
![]() |
log
WARN: Stopped retrying requested incoming Paykit payment request after 15 presentation attempts - PaykitPaymentRequestService.swift:1123
WARN: Rejected incoming Paykit payment request presentation: category=resolution reason=no_supported_endpoint counterparty=pubkyrxgn7p4... - AppScene.swift:1380
Fixture API: recovery required: Encrypted Link Handshake is still in progress (HTTP 400).
Test J2
Not run: our test setup failed, not the app: Journey fixed request ID cannot be published by fixture.
J2.mp4 |
![]() |
log
Fixture /health: status ready, role fixture-issuer, receiver_path bitkit/server, endpoint btc-regtest-p2wpkh, address bcrt1qyjhzj87lrzyhdnq3ag3rhy7qt5pr9dp2ez93fj.
Fixture /sync: generation 3, state Linked.
Fixture /request: generated request ID c29db742..., deadline null, state Proposed (HTTP 200).
`sim-1`: Payment Request, 100 000 sats, FROM eqgu...485y, Swipe To Pay.
Warning
During recovery, the pending request and its Pay and Dismiss controls disappeared. Keep the request actionable while payment details recover. The two fixture-backed journeys remain unverified because their setup could not reach the specified payment steps.
Reviewed by gpt-6-sol-xhigh via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest (author)
|
Recovery-required unpaid requests now stay in the pending list across refresh and restart, so their Pay and Dismiss controls remain available. Paid, canceled, rejected, recurring, unsupported, and expired requests are still excluded. |
There was a problem hiding this comment.
Advice: ✅ Approve
Reaudit: diff 2 files.
No new findings; the rest is in the review.
Retest suggested: Tests 1, J1, J2 (Test 1 covers the parser's recovery path; J1 and J2 still need to pass after fixture setup failures).
Pair PR synonymdev/bitkit-android#1370: equivalent.
QA:
Tests queued.
Reviewed by gpt-6-sol-medium via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest (author)




Fixes #776
This PR restores failed private Payment Requests and keeps requests usable while private-link recovery is still pending.
Description
RecoveryRequiredandLinkingas pending while the supported SDK recovery continues, and releases presentation ownership so Pay and Dismiss remain available.Out of Scope
RecoveryRequired.paykit-rschanges.Design
Preview
N/A because no capture is available.
QA Notes
Journeys
definite-pre-broadcast-retry.xml- retries the same private Payment Request after a definite failure before Lightning dispatch.issuer-interoperability.xml- shows an unpaid request with an unsigned amount and lifecycle status before payment.Manual Tests
RecoveryRequiredorLinking→ tap Pay → information feedback appears, Pay and Dismiss remain available, and a later retry opens recovered details - recovery-state injection is not in Capabilities.Not run locally because the controlled linked recovery fixture was unavailable.
Automated Checks
PrivatePaykitServiceTests.swift- releases only the matching consumed version after a definite pre-broadcast failure and classifies private-link recovery states as pending.PaykitPaymentRequestServiceTests.swift- releases presentation ownership during pending recovery and shows movement styling only after payment proof.PublicPaykitServiceTests.swift- maps pending recovery to informational presentation feedback.HwFundingSignerTests.swift- retries hardware preparation after a definite failure without signing again.git diff --check- passed.