feat: support paykit receiver paths#620
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
Greptile SummaryThis PR adds receiver-path support for Paykit contacts. The main changes are:
Confidence Score: 4/5The sign-out, profile deletion, and old private-state decode paths need fixes before merging.
Bitkit/Managers/PubkyProfileManager.swift; Bitkit/Services/PrivatePaykitService+Models.swift
|
| 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]
%%{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]
Reviews (1): Last reviewed commit: "fix: harden paykit receiver refresh" | Re-trigger Greptile
|
Starting review |
piotr-iohk
left a comment
There was a problem hiding this comment.
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/@pubkygreen ✅
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.
This PR:
bitkit/walletreceiver.bitkit/walletandbitkit/serverreceivers while keeping one visible contact per Pubky identity.bitkit/walletexplicitly.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/serverreceiver can be discovered and linked without receiving wallet invoices or addresses. Public contact payments and fallback remain scoped tobitkit/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
bitkit/walletreceiver is available for payment.bitkit/wallet; public fallback still works when private payment is unavailable.bitkit/serverreceiver is published: the contact remains one row and the new receiver is saved in the background.bitkit/servermarker that cannot send payments: Bitkit may maintain its private link but does not publish wallet invoices or addresses to that receiver.Automated Checks
PrivatePaykitServiceTests.swiftcovers receiver-scoped publication, cleanup, reservations, and wallet/server capability behavior.ContactsManagerTests.swiftcovers receiver discovery refresh for an already-saved contact.git diff --checkpassed on the changed files.ContactsManagerTestsclass run remains blocked locally by the existing app-group/keychain entitlement failure intestDeleteAllContactsThrowsWithoutActiveSession; the changed receiver-refresh test passes independently.