Skip to content

feat: support paykit receiver paths#620

Open
ben-kaufman wants to merge 3 commits into
masterfrom
codex/paykit-rc33-receivers
Open

feat: support paykit receiver paths#620
ben-kaufman wants to merge 3 commits into
masterfrom
codex/paykit-rc33-receivers

Conversation

@ben-kaufman

@ben-kaufman ben-kaufman commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

This PR:

  1. Updates Paykit to v0.1.0-rc33 and configures the mobile app as the bitkit/wallet receiver.
  2. Discovers and saves supported bitkit/wallet and bitkit/server receivers while keeping one visible contact per Pubky identity.
  3. Scopes private links, payment details, reservations, retries, and cleanup to the exact receiver path.
  4. Publishes the wallet receiver marker with the app's current public/private capabilities and removes it when Paykit sharing is disabled.
  5. Refreshes receiver discovery when an existing contact is scanned or pasted, while normal send-to-contact continues to target bitkit/wallet explicitly.

Description

Paykit now supports multiple apps under one Pubky identity. This change adopts that model without changing Bitkit's contact UI: a person remains one contact, while their saved SDK contact record can track multiple receiver paths.

Private links are maintained for supported receivers that advertise private capabilities. Receiving details are published independently per receiver and only when that receiver can send payments, so a bitkit/server receiver can be discovered and linked without receiving wallet invoices or addresses. Public contact payments and fallback remain scoped to bitkit/wallet.

Receiver-record failures are isolated per contact, successful delivery reports are still persisted, and rescanning an existing contact shows the validation result immediately while its receiver metadata refreshes.

No migration is included because the receiver-path Paykit state has not shipped and existing development state can be discarded.

Companion Android PR: synonymdev/bitkit-android#1066

Linked Issues/Tasks

Screenshot / Video

N/A

QA Notes

Manual Tests

  • 1. Contacts → add a Paykit-enabled Bitkit user: one contact is saved and its bitkit/wallet receiver is available for payment.
  • 2. Send → Contact → select the saved contact: private payment resolves through bitkit/wallet; public fallback still works when private payment is unavailable.
  • 3. Existing contact → scan or paste the same Pubky key after a bitkit/server receiver is published: the contact remains one row and the new receiver is saved in the background.
  • 4. Contact with a bitkit/server marker that cannot send payments: Bitkit may maintain its private link but does not publish wallet invoices or addresses to that receiver.
  • 5. Settings → Payment Preferences → disable contact payment sharing: receiver-scoped payment details and the local receiver marker are cleaned up.

Automated Checks

  • PrivatePaykitServiceTests.swift covers receiver-scoped publication, cleanup, reservations, and wallet/server capability behavior.
  • ContactsManagerTests.swift covers receiver discovery refresh for an already-saved contact.
  • Local iOS simulator build passed; 25 focused public/private Paykit tests and the touched contact receiver-refresh test passed.
  • SwiftFormat lint and git diff --check passed on the changed files.
  • A full ContactsManagerTests class run remains blocked locally by the existing app-group/keychain entitlement failure in testDeleteAllContactsThrowsWithoutActiveSession; the changed receiver-refresh test passes independently.

@ben-kaufman
ben-kaufman marked this pull request as ready for review July 10, 2026 10:55
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds receiver-path support for Paykit contacts. The main changes are:

  • Paykit is upgraded and configured for the bitkit/wallet receiver.
  • Contacts can store supported bitkit/wallet and bitkit/server receiver paths.
  • Private links, reservations, invoices, retries, and cleanup are scoped per receiver path.
  • The wallet receiver marker is published or removed from sharing flows.
  • Scanner, paste, and contact flows refresh receiver metadata for existing contacts.

Confidence Score: 4/5

The sign-out, profile deletion, and old private-state decode paths need fixes before merging.

  • Private cleanup failures can stop profile deletion and sign-out before mandatory cleanup runs.
  • Existing private Paykit state can decode with invoices and publication flags missing after the schema change.
  • The receiver-path publication flow is otherwise scoped consistently in the changed code reviewed.

Bitkit/Managers/PubkyProfileManager.swift; Bitkit/Services/PrivatePaykitService+Models.swift

Security Review

Sign-out and profile deletion can remain incomplete when private Paykit cleanup fails, leaving receiver/public state active until the cleanup path is fixed.

Important Files Changed

Filename Overview
Bitkit/Managers/PubkyProfileManager.swift Profile deletion and sign-out now depend on throwing private Paykit cleanup, which can block required account and local-state cleanup.
Bitkit/Services/PrivatePaykitService+Models.swift Private Paykit contact state was reshaped for receiver paths without migration for old persisted invoices and publication flags.
Bitkit/Services/PrivatePaykitService+Contacts.swift Private payment publication, cleanup, delivery retries, and saved contact state are now keyed by receiver path.
Bitkit/Services/PrivatePaykitAddressReservationStore.swift Address reservations now distinguish wallet and server receivers while preserving wallet as the legacy key.
Bitkit/Services/PubkyService.swift Paykit SDK calls now pass receiver paths, receiver marker capabilities, and receiver-aware contact records.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Save or refresh contact] --> B[Discover supported receiver paths]
  B --> C[Store one contact record]
  C --> D[Select linkable and publishable receivers]
  D --> E[Publish private payment details per receiver path]
  D --> F[Clean stale receiver-path lists]
  G[Sharing disabled or sign-out] --> H[Remove private lists]
  G --> I[Remove public endpoints and receiver marker]
  H --> J[Clear receiver-scoped local state]
  I --> K[Receiver no longer discoverable]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
  A[Save or refresh contact] --> B[Discover supported receiver paths]
  B --> C[Store one contact record]
  C --> D[Select linkable and publishable receivers]
  D --> E[Publish private payment details per receiver path]
  D --> F[Clean stale receiver-path lists]
  G[Sharing disabled or sign-out] --> H[Remove private lists]
  G --> I[Remove public endpoints and receiver marker]
  H --> J[Clear receiver-scoped local state]
  I --> K[Receiver no longer discoverable]
Loading

Reviews (1): Last reviewed commit: "fix: harden paykit receiver refresh" | Re-trigger Greptile

Comment thread Bitkit/Managers/PubkyProfileManager.swift
Comment thread Bitkit/Managers/PubkyProfileManager.swift
Comment thread Bitkit/Services/PrivatePaykitService+Models.swift
@jvsena42

Copy link
Copy Markdown
Member

Starting review

@jvsena42 jvsena42 added this to the 2.5.0 milestone Jul 21, 2026

@piotr-iohk piotr-iohk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK

Manual regression (regtest / staging), iOS ↔ Android, on codex/paykit-rc33-receivers:

  • Native profile create + mutual contacts ✅
  • Cross-platform contact LN payments (both directions) ✅
  • Contact attribution after payments (setContact) ✅
  • Profile delete → recreate → re-add → pay again ✅
  • Pubky Ring import ✅ (Pubky auth completed)
  • Staging paykit fixtures republished under receiver paths; e2e @paykit / @pubky green ✅

Companion to android#1066. Android Ring import failure remains the known deferred follow-up from the prior Paykit PR, not a blocker for receiver-path support.

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.

3 participants