Skip to content

[codex] Add public Paykit payments to contacts#531

Open
ben-kaufman wants to merge 27 commits intomasterfrom
codex-paykit-public-endpoints-pr527
Open

[codex] Add public Paykit payments to contacts#531
ben-kaufman wants to merge 27 commits intomasterfrom
codex-paykit-public-endpoints-pr527

Conversation

@ben-kaufman
Copy link
Copy Markdown
Contributor

@ben-kaufman ben-kaufman commented Apr 29, 2026

Summary

  • Add public Paykit payments for saved contacts and scanned/pasted Pubky contacts.
  • Publish wallet payment endpoints from the Pay Contacts settings flow.
  • Support Lightning, on-chain, and combined BIP21 contact payment requests using the existing send flow.
  • Update Paykit endpoint IDs and bindings for paykit-rs v0.1.0-rc3.

Notes

  • Pubky scan/paste opens the contact flow first; payment starts from the contact screen.
  • On-chain endpoints are selected by priority: taproot, segwit, p2sh, then legacy.
  • You can verify and see the endpoints published on https://payky.app

Validation

  • swiftformat on touched Swift files
  • git diff --check
  • xcodebuild -resolvePackageDependencies -project Bitkit.xcodeproj
  • Full app build was attempted, but still fails in existing vss-rust-client-ffi generated bindings.
  • Translation validation was attempted, but the script currently needs the missing glob dependency.

@ben-kaufman ben-kaufman changed the title [codex] Complete public Paykit contact payments [codex] Add public Paykit payments to contacts Apr 29, 2026
@ben-kaufman ben-kaufman force-pushed the codex-paykit-public-endpoints-pr527 branch from 1d622bc to 18a0af9 Compare April 29, 2026 14:10
@ben-kaufman ben-kaufman marked this pull request as ready for review April 29, 2026 14:10
@ben-kaufman ben-kaufman force-pushed the codex-paykit-public-endpoints-pr527 branch from 18a0af9 to f1a122e Compare April 29, 2026 14:14
Comment thread CHANGELOG.md Outdated
Comment thread Bitkit/Views/Contacts/ContactActivityView.swift
Comment thread Bitkit/Views/Wallets/Send/SendConfirmationView.swift
Comment thread Bitkit/Views/Wallets/Send/SendPendingScreen.swift
Comment thread Bitkit/Views/Wallets/Send/SendSuccess.swift
Comment thread Bitkit/Views/Contacts/ContactActivityView.swift Outdated
Comment thread Bitkit/Services/PublicPaykitService.swift Outdated
@claude

This comment has been minimized.

@ben-kaufman ben-kaufman force-pushed the codex-paykit-public-endpoints-pr527 branch from 5b94276 to 3d1f2b2 Compare May 4, 2026 15:54
Comment thread CHANGELOG.md Outdated
Comment thread Bitkit/Views/Contacts/AddContactView.swift Outdated
Comment thread Bitkit/Services/CoreService.swift
Comment thread Bitkit/Services/CoreService.swift
Comment thread Bitkit/ViewModels/WalletViewModel.swift Outdated
@piotr-iohk
Copy link
Copy Markdown
Collaborator

Quick testing notes:

Screenshot 2026-05-04 at 22 10 52

@ben-kaufman
Copy link
Copy Markdown
Contributor Author

  1. I can remove the Send button, but thought it actually makes a lot of sense to have since there can be cases where you want to just pay without being a contact... Do you think we should still remove it?

  2. It's not actually possible to know who a public payment was received from. We will have received from for private payments eventually, but at least for now it's not possible to have for public.

  3. You can pay but it won't be a private payment

@piotr-iohk
Copy link
Copy Markdown
Collaborator

I can remove the Send button, but thought it actually makes a lot of sense to have since there can be cases where you want to just pay without being a contact... Do you think we should still remove it?

Ok, I think this makes sense. But I guess it should go through design/product acceptance fyi @aldertnl

You can pay but it won't be a private payment

  • got it, the note says "privately" indeed.

@ovitrif
Copy link
Copy Markdown
Collaborator

ovitrif commented May 4, 2026

@codex review

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: 3ea3f5832a

ℹ️ 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/Utilities/AppReset.swift Outdated
await VssBackupClient.shared.reset()
VssStoreIdProvider.shared.clearCache()

try await PubkyProfileManager.removePublicPaykitEndpoints(context: "AppReset.wipe")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep wipe flow resilient to endpoint unpublish failures

Make the public-endpoint cleanup best-effort here instead of hard-failing the entire wipe. removePublicPaykitEndpoints performs remote operations and can throw on transient network/session issues; because it now runs before wallet.wipe() and database/keychain cleanup, users in offline or degraded network conditions can be blocked from completing reset flows (forgot PIN, recovery reset, dev wipe), leaving local sensitive state uncleared.

Useful? React with 👍 / 👎.

Comment on lines +275 to +276
func contactActivities(publicKey: String) async throws -> [Activity] {
try await coreService.activity.get(contact: publicKey, sortDirection: .desc)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply replaced-transaction filtering to contact activity list

Filter contact activities with the same replacement-transaction logic used by syncState() before presenting them. This method currently returns raw coreService.activity.get(...) results, so contact-specific history can surface replaced/boosted originals that are intentionally hidden in the main activity feed, causing duplicate or stale sent entries for the same payment flow.

Useful? React with 👍 / 👎.

@claude

This comment has been minimized.

@claude

This comment has been minimized.

@piotr-iohk
Copy link
Copy Markdown
Collaborator

piotr-iohk commented May 5, 2026

Tested roughly against this plan. Tested against staging.

Areas tested and 🟢 for me (encountered issue #536, but seems unrelated to paykit).

  • send/receive with imported pubky to saved/unsaved contact (onchain and lightning)
  • send/receive with created pubky to saved/unsaved contact (onchain and lightning)
  • RBF sent tx to concat
  • CPFP on received tx from contact
  • enable/disable payments with contacts

Some testing notes / observations:

  • Enter manually is not supporting pubky (since we have it supported on paste/qr code scan etc. - then Send -> Enter manually should also support it)
Screenshot 2026-05-05 at 14 10 21
  • RBF-ed transaction not shown in profile activity (Instead there is a sent tx with Removed from Mempol note)
    • to reproduce:
    • send to contact and RBF transaction
    • see transactions in contact activity
Screenshot 2026-05-05 at 14 30 16

piotr-iohk
piotr-iohk previously approved these changes May 5, 2026
Copy link
Copy Markdown
Collaborator

@piotr-iohk piotr-iohk left a comment

Choose a reason for hiding this comment

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

LGTM, remaining obesrvations can be addressed separately, issue for tracking: #539

ovitrif
ovitrif previously approved these changes May 5, 2026
Copy link
Copy Markdown
Collaborator

@ovitrif ovitrif left a comment

Choose a reason for hiding this comment

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

LGTM

Tested using same script like on Android counterpart ([codex] add public contact payments).

Focused on validating, besides happy flow, edge cases to ensure Public pay2contact payment methods are always up-to-date.

@ben-kaufman ben-kaufman dismissed stale reviews from ovitrif and piotr-iohk via 31b2b28 May 5, 2026 15:51
ovitrif
ovitrif previously approved these changes May 5, 2026
Copy link
Copy Markdown
Collaborator

@ovitrif ovitrif left a comment

Choose a reason for hiding this comment

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

Validated fix in last commit for Payky 🎉

@ovitrif ovitrif enabled auto-merge May 5, 2026 16:38
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: 768c3d05a8

ℹ️ 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 on lines +161 to +163
if app.lnurlPayData != nil {
return .lnurlPayAmount
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Route fixed LNURL contact payments to confirmation

When appropriateSendRoute returns .quickpay for a contact LNURL payment, this branch always forces .lnurlPayAmount, even for fixed-amount LNURL requests. That regresses fixed flows from a direct confirmation path to manual amount entry, and can leave users stuck on a disabled continue button when balance is below the fixed amount (instead of reaching normal confirmation/validation). Preserve fixed-amount behavior by routing fixed LNURL contacts to .lnurlPayConfirm rather than always .lnurlPayAmount.

Useful? React with 👍 / 👎.

Comment on lines +55 to +57
private func handleAddContactScan(_ input: String) {
navigation?.navigateBack()
navigation?.navigate(.addContact(publicKey: input))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reuse pubky route resolution for add-contact scans

The add-contact scanner path now unconditionally navigates to .addContact(publicKey:), so scanning your own pubky or an already-saved contact no longer opens the existing profile/detail route and instead drops into an error flow (self/duplicate). This is a functional regression from the main scanner behavior and makes contact QR scans from the contacts tab fail for valid existing keys; route this through the same resolvePastedPubkyRoute logic used elsewhere.

Useful? React with 👍 / 👎.

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