Skip to content

feat: send paykit payment proofs - #1178

Open
ben-kaufman wants to merge 3 commits into
codex/paykit-payment-request-ui-androidfrom
codex/paykit-payment-proofs-android
Open

feat: send paykit payment proofs#1178
ben-kaufman wants to merge 3 commits into
codex/paykit-payment-request-ui-androidfrom
codex/paykit-payment-proofs-android

Conversation

@ben-kaufman

@ben-kaufman ben-kaufman commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

This PR sends a Paykit payment proof back to the requester after Bitkit successfully pays an incoming private payment request.

Description

  1. Persists the payer identity, request, and selected endpoint before request acceptance, then associates the Lightning payment hash before sending so restart recovery keeps the correct correlation.
  2. Persists successful on-chain transaction IDs and validated Lightning preimages before submitting them against the original one-time request and exact endpoint.
  3. Uses Paykit's durable private outbox, retries incomplete submissions during normal request refresh, and suppresses duplicate proofs already recorded by the SDK.
  4. Preserves earlier in-flight correlations across retries, clears the request after one proof is queued, and reads the secure store directly so wallet wipes cannot resurrect cached proof state.
  5. Attempts immediate SDK delivery if persisting a completed proof fails, without adding any user-facing UI.

This PR is stacked on #1172. Companion iOS PR: synonymdev/bitkit-ios#683

Preview

N/A — there are no UI changes.

QA Notes

Manual Tests

  • 1. Android → create a private request for iOS → iOS receives and pays on regtest: Android records the proof against the exact request, endpoint, and transaction ID.
  • 2. iOS → create a private request for Android → Android receives and pays on regtest: iOS records the proof against the exact request, endpoint, and transaction ID.

Automated Checks

  • PaykitPaymentProofRepoTest.kt: 8 tests cover restart retry, duplicate suppression, invalid Lightning preimage rejection, failed-payment cleanup, exact on-chain proof submission, overlapping retries, wallet-store clearing, and completed-proof persistence failure.
  • AppViewModelSendFlowTest.kt: covers proof persistence before private-list consumption and request acceptance, plus successful and failed payment lifecycle handling.
  • Full Android unit tests and focused proof/send-flow tests passed.
  • Detekt passed with only pre-existing unrelated findings.
  • git diff --check passed.

@greptile-apps

greptile-apps Bot commented Aug 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR durably correlates incoming private Paykit requests with on-chain or Lightning payments and submits validated payment proofs through Paykit's private outbox. It also connects proof preparation, completion, failure cleanup, and restart reconciliation to the existing send lifecycle.

  • Adds encrypted persistence and reconciliation for pending payment proofs.
  • Submits on-chain transaction IDs and hash-validated Lightning preimages.
  • Integrates proof lifecycle handling with request acceptance and payment events.
  • Adds repository and send-flow coverage for retries, duplicates, validation, and cleanup.

Confidence Score: 3/5

This PR should not merge until pending proof state is invalidated during wallet wipe so sensitive payment correlations cannot be restored into a later wallet.

The new singleton repository caches wallet-scoped proof records independently of the keychain lifecycle, allowing a later payment operation to repersist transaction identifiers or Lightning preimages that the wallet wipe had deleted.

Files Needing Attention: app/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt

Security Review

Wallet-scoped payment-proof data remains cached after a wallet wipe and can be persisted into a subsequently created wallet's keychain. The cache must be cleared or scoped to the active wallet lifecycle so wiped transaction IDs and Lightning preimages cannot be resurrected.

Important Files Changed

Filename Overview
app/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Implements durable proof correlation, validation, submission, and reconciliation, but its process-wide cache can resurrect proof data after wallet wipe.
app/src/main/java/to/bitkit/repositories/PaykitPaymentProofStore.kt Serializes pending proofs into wallet-indexed encrypted keychain storage.
app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt Integrates proof preparation and cleanup into payment submission and completes proofs from wallet events.
app/src/main/java/to/bitkit/services/PaykitSdkService.kt Adds the serialized SDK boundary for one-time payment-proof submission.
app/src/test/java/to/bitkit/repositories/PaykitPaymentProofRepoTest.kt Covers proof retry, duplicate suppression, validation, failure cleanup, and on-chain submission, but not cache invalidation across wallet wipe.

Sequence Diagram

sequenceDiagram
    participant UI as Send flow
    participant ProofRepo as Payment proof repository
    participant Wallet as Bitcoin/Lightning wallet
    participant Paykit as Paykit SDK
    UI->>ProofRepo: Prepare request and selected endpoint
    UI->>Wallet: Send payment
    alt On-chain success
        Wallet-->>UI: Transaction ID
        UI->>ProofRepo: Complete with transaction ID
    else Lightning payment
        UI->>ProofRepo: Associate payment hash
        Wallet-->>UI: Success event and preimage
        UI->>ProofRepo: Complete with validated preimage
    else Failure or cancellation
        UI->>ProofRepo: Remove correlation
    end
    ProofRepo->>Paykit: Queue payment proof
    ProofRepo->>Paykit: Process private outbox
Loading

Reviews (1): Last reviewed commit: "feat: send paykit payment proofs" | Re-trigger Greptile

Comment thread app/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt
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.

1 participant