Skip to content

feat: add Paykit private payments#549

Open
ben-kaufman wants to merge 2 commits into
masterfrom
codex/paykit-private-payments
Open

feat: add Paykit private payments#549
ben-kaufman wants to merge 2 commits into
masterfrom
codex/paykit-private-payments

Conversation

@ben-kaufman
Copy link
Copy Markdown
Contributor

Description

This PR adds private Paykit payments for saved contacts.

It:

  1. Adds Paykit encrypted-link wrappers and a private Paykit service for contact link handshakes, recovery, private endpoint publishing, private endpoint fetching, and public fallback.
  2. Reserves dedicated per-contact on-chain receive indexes and uses the new LDK address-info APIs to prevent private addresses from colliding with normal receive addresses.
  3. Adds private Lightning invoice rotation, private on-chain rotation, contact/payment attribution, contact delete/sign-out/wipe cleanup, and backup/restore support for private link state plus reservation ceilings.
  4. Updates contact payment entry points so saved contact sends prefer private Paykit when ready and fall back to public Paykit when private resolution is unavailable.
  5. Adds focused private Paykit tests and a changelog fragment.

Linked Issues/Tasks

N/A

QA Notes

Manual Tests

  • 1. Alice contact detail → Send to Bob saved contact: private on-chain payment opens and sends successfully.
  • 2. Bob Activity → received payment from Alice: activity contact is set to Alice.
  • 3. Bob private receive address → receive funds: private address rotates before it is republished to Alice.
  • 4. Alice Contacts → delete Bob: private endpoint tombstone is sent and local private state is cleared after cleanup succeeds.
  • 5. Bob Settings → copy seed → Dev Settings wipe → restore seed: wallet restores, private reservation ceiling is preserved, and the next normal receive address skips the reserved range.
  • 6. regression: contact with no private-ready link → Send: public Paykit remains the fallback path when available.

Automated Checks

  • git diff --check && git diff --cached --check
  • swiftformat --lint on touched private Paykit/contact files
  • node scripts/validate-translations.js
  • Old Xcode targeted test: PrivatePaykitServiceTests passed, 12 tests, 0 failures
  • Old Xcode app build with E2E flags passed during the final private Paykit verification pass

Screenshot / Video

N/A

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3dee822d5e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Bitkit/Services/PrivatePaykitService+Contacts.swift
@ben-kaufman ben-kaufman force-pushed the codex/paykit-private-payments branch from dbdb9ef to 600cdf9 Compare May 13, 2026 17:38
@piotr-iohk
Copy link
Copy Markdown
Collaborator

Observations from initial testing round:

1. encountered "Duplicate payment" on private ln send. (After few sends between private contacts)
Alice-> Bob
Bob -> Alice
Alice: bitkit_logs_2026-05-14_12-43-46.zip
Bob: bitkit_logs_2026-05-14_12-43-30.zip

Screen.Recording.2026-05-14.at.14.40.31.mov

2. seems that sometimes the payment falls back to public(?) ("Received from..." is not appearing on the Recepient's activity list)
See payments between Paykit Sender and Alice C:

Paykit Sender: bitkit_logs_2026-05-14_12-02-47.zip
Alice C: bitkit_logs_2026-05-14_12-02-28.zip

Screen.Recording.2026-05-14.at.13.58.13.mov

3. As shown in the recording above, the payment button sometimes appears after a short delay. A similar delay can also be observed when tapping the contact’s pay icon. This is just an observation for now.


4. Private Paykit fallback / stale link observation

I could not reproduce this reliably yet, but I hit it once on an older wallet that already had funds.

Rough flow was:

  • Bob had an existing funded wallet.
  • Bob created a Pubky profile.
  • Paykit Sender added Bob as a contact.
  • Bob added Paykit Sender as a contact.
  • Bob attempted to pay that contact -> resulted in "Payment failed" toast
  • In Bob’s logs, private Paykit resolution failed with a Noise decryption error, after which the app fell back to public Paykit:
failed to receive private payments: DecryptionError: pubky-noise receive_message failed: DecryptionError
Discarding cached private Paykit endpoints...
Falling back to public Paykit...

Bob: bitkit_logs_2026-05-14_11-11-10.zip
Paykit Sender: bitkit_logs_2026-05-14_12-02-47.zip

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.

2 participants