fix: align Pubky and Paykit flows - #636

Merged
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment
Jul 27, 2026
Merged

fix: align Pubky and Paykit flows#636
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Part of #571

Description

This PR aligns the Pubky profile, contacts, and Paykit contact-payment flows with the v61 Figma designs while keeping the Ring flow unchanged.

  • Removes the onboarding payment toggle and enables contact payments by default.
  • Replaces the separate payment-preference screen with one General Settings toggle controlling both public and private contact payments.
  • Shows Pay and Save when a contact exposes a payment endpoint, and Save only when no payment endpoint is available.
  • Aligns profile creation/editing, contact import, contact detail, contacts list, and saved-contact navigation with the current designs.
  • Uses raw truncated Pubky keys and updates the overlapping contact-avatar stack to the Figma sizing, overlap, border, and overflow treatment.
  • Adds direct profile-tag management and prevents overlapping tag saves.
  • Consolidates contact-payment publication and cleanup behavior into one service while preserving rollback state.

This PR is based directly on master. Incoming Paykit payment-request work remains outside this branch.

Linked Issues/Tasks

Screenshot / Video

Comparison screenshots were captured and reviewed locally for the changed onboarding, profile, contacts, import, settings, and avatar-stack states. Ring remains out of scope because that flow is being updated separately.

QA Notes

Manual Tests

  • 1. Profile onboarding → Pay with Contacts: no toggle is shown; Continue enables contact payments and opens Profile.
  • 2. Settings → General → Enable payments with contacts: one toggle controls both public and private contact-payment publication.
  • 3a. Contacts → Add Contact → enter a contact with a payment endpoint: Pay and Save actions are shown.
    • 3b. Enter a contact without a payment endpoint: only Save is shown.
  • 4. Contacts → import profile contacts → select/import: selection, overview, and completion screens match the v61 flow.
  • 5. Profile → add and remove tags: changes persist and controls remain disabled while a save is running.
  • 6. Contacts list with more than five contacts: avatar stack uses 32 pt circles, 8 pt overlap, five visible avatars, and the bordered overflow count.
  • 7.regression: Pubky Ring authorization and watch-only account flows remain unchanged.

Automated Checks

  • Unit tests added: ContactPaymentsServiceTests.swift covers default enablement, unified public/private publication, cleanup, partial failures, and rollback to both enabled and disabled states.
  • Unit tests modified: ContactsManagerTests.swift verifies raw truncated Pubky key display; PublicPaykitServiceTests.swift verifies the unified preference key cleanup.
  • Local: SwiftFormat lint passes for all changed Swift files, translation validation passes with 0 errors, and git diff --check passes.
  • Local simulator: the app and test targets compile and all 8 focused contact-payment tests pass in a disposable compatibility build using the locally available newer Paykit/LDK artifacts. The exact master artifact graph could not be re-fetched locally, so CI remains the authoritative locked-dependency build.
  • CI: standard build and test checks run by the PR bot.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from fb7d862 to 12ab412CompareJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-watch-only-accounts to masterJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman marked this pull request as ready for review July 20, 2026 11:11
@greptile-apps

greptile-appsBot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns the Pubky and Paykit contact flows with the v61 designs. The main changes are:

  • Consolidated public and private contact-payment settings and rollback handling.
  • Updated profile, contact, import, and saved-contact screens.
  • Added direct profile-tag management and overlapping-save protection.
  • Changed Pubky-key formatting and contact-avatar layouts.
  • Added focused tests for contact-payment state transitions.

Confidence Score: 4/5

The unified payment flow needs fixes for displayed state, unloaded contacts, and failed endpoint rollback.

  • An unconfirmed preference can appear enabled without publishing endpoints.
  • Enabling before contacts load can omit private endpoint publication.
  • A failed compensating cleanup can leave a public endpoint published after state is restored to disabled.
  • The remaining profile and contact UI changes are contained.

Bitkit/Views/Settings/GeneralSettingsView.swift; Bitkit/Services/ContactPaymentsService.swift

Important Files Changed

FilenameOverview
Bitkit/Services/ContactPaymentsService.swiftAdds unified endpoint publication, cleanup, and rollback, but a failed compensating cleanup can leave published state inconsistent with the restored preference.
Bitkit/Views/Settings/GeneralSettingsView.swiftAdds the unified toggle, but its default display and contact-list snapshot can diverge from actual endpoint publication.
Bitkit/Views/Profile/PayContactsView.swiftRemoves the onboarding toggle and enables contact payments through the consolidated service.
Bitkit/Views/Profile/ProfileView.swiftAdds direct tag creation and deletion with a synchronous overlapping-save guard.
Bitkit/Views/Contacts/AddContactView.swiftAdds conditional Pay and Save actions plus saved-contact navigation.
Bitkit/Views/Contacts/ContactDetailView.swiftAdds the saved-contact title and delete mode.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
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[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
Loading

Comments Outside Diff (1)

  1. Bitkit/Views/Settings/GeneralSettingsView.swift, line 47-48 (link)

    P1Enabled State Is Not Published

    For an authenticated user with no confirmed preference and both publication flags false, this fallback displays the toggle as enabled without calling setEnabled(true). If the user leaves it untouched, no endpoints are published and contacts still cannot pay them despite General Settings showing the feature as on.

Reviews (1): Last reviewed commit: "fix: harden contact payment settings" | Re-trigger Greptile

Comment threadBitkit/Services/ContactPaymentsService.swift
Comment threadBitkit/Views/Settings/GeneralSettingsView.swift
@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

Addressed the remaining Greptile review observations in 1006451:

  • An unconfirmed contact-payment preference is no longer rendered as already active. General Settings actively provisions the default-on state, shows the pending value while it runs, and only reports enabled after publication succeeds.
  • Contact publication now waits for the authenticated contact list to finish loading.
  • Public endpoint publication/removal is the final fallible transition, and local state is committed only after the complete operation succeeds.

Verification: SwiftFormat/diff checks pass, and all 8 focused ContactPaymentsServiceTests pass on the iOS simulator.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from 1006451 to 03acbcdCompareJuly 22, 2026 13:01

@piotr-iohkpiotr-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

@ovitrif
ovitrifforce-pushed the codex/pubky-paykit-figma-alignment branch from d769ad1 to cc972d7CompareJuly 27, 2026 15:54
@ovitrif

Copy link
Copy Markdown
Collaborator

Signed last commit and merged master into the branch, review status remains, no code changes, good to merge.

@ovitrif
ovitrif enabled auto-merge July 27, 2026 15:55
@ovitrif
ovitrif merged commit 8b5c8a1 into masterJul 27, 2026
11 checks passed
@ovitrif
ovitrif deleted the codex/pubky-paykit-figma-alignment branch July 27, 2026 17:40
@coreyphillipscoreyphillips mentioned this pull request Jul 29, 2026
13 tasks
Sign up for freeto 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

@ben-kaufman@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: align Pubky and Paykit flows - #636

Merged
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment
Jul 27, 2026
Merged

fix: align Pubky and Paykit flows#636
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Part of #571

Description

This PR aligns the Pubky profile, contacts, and Paykit contact-payment flows with the v61 Figma designs while keeping the Ring flow unchanged.

  • Removes the onboarding payment toggle and enables contact payments by default.
  • Replaces the separate payment-preference screen with one General Settings toggle controlling both public and private contact payments.
  • Shows Pay and Save when a contact exposes a payment endpoint, and Save only when no payment endpoint is available.
  • Aligns profile creation/editing, contact import, contact detail, contacts list, and saved-contact navigation with the current designs.
  • Uses raw truncated Pubky keys and updates the overlapping contact-avatar stack to the Figma sizing, overlap, border, and overflow treatment.
  • Adds direct profile-tag management and prevents overlapping tag saves.
  • Consolidates contact-payment publication and cleanup behavior into one service while preserving rollback state.

This PR is based directly on master. Incoming Paykit payment-request work remains outside this branch.

Linked Issues/Tasks

Screenshot / Video

Comparison screenshots were captured and reviewed locally for the changed onboarding, profile, contacts, import, settings, and avatar-stack states. Ring remains out of scope because that flow is being updated separately.

QA Notes

Manual Tests

  • 1. Profile onboarding → Pay with Contacts: no toggle is shown; Continue enables contact payments and opens Profile.
  • 2. Settings → General → Enable payments with contacts: one toggle controls both public and private contact-payment publication.
  • 3a. Contacts → Add Contact → enter a contact with a payment endpoint: Pay and Save actions are shown.
    • 3b. Enter a contact without a payment endpoint: only Save is shown.
  • 4. Contacts → import profile contacts → select/import: selection, overview, and completion screens match the v61 flow.
  • 5. Profile → add and remove tags: changes persist and controls remain disabled while a save is running.
  • 6. Contacts list with more than five contacts: avatar stack uses 32 pt circles, 8 pt overlap, five visible avatars, and the bordered overflow count.
  • 7.regression: Pubky Ring authorization and watch-only account flows remain unchanged.

Automated Checks

  • Unit tests added: ContactPaymentsServiceTests.swift covers default enablement, unified public/private publication, cleanup, partial failures, and rollback to both enabled and disabled states.
  • Unit tests modified: ContactsManagerTests.swift verifies raw truncated Pubky key display; PublicPaykitServiceTests.swift verifies the unified preference key cleanup.
  • Local: SwiftFormat lint passes for all changed Swift files, translation validation passes with 0 errors, and git diff --check passes.
  • Local simulator: the app and test targets compile and all 8 focused contact-payment tests pass in a disposable compatibility build using the locally available newer Paykit/LDK artifacts. The exact master artifact graph could not be re-fetched locally, so CI remains the authoritative locked-dependency build.
  • CI: standard build and test checks run by the PR bot.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from fb7d862 to 12ab412CompareJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-watch-only-accounts to masterJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman marked this pull request as ready for review July 20, 2026 11:11
@greptile-apps

greptile-appsBot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns the Pubky and Paykit contact flows with the v61 designs. The main changes are:

  • Consolidated public and private contact-payment settings and rollback handling.
  • Updated profile, contact, import, and saved-contact screens.
  • Added direct profile-tag management and overlapping-save protection.
  • Changed Pubky-key formatting and contact-avatar layouts.
  • Added focused tests for contact-payment state transitions.

Confidence Score: 4/5

The unified payment flow needs fixes for displayed state, unloaded contacts, and failed endpoint rollback.

  • An unconfirmed preference can appear enabled without publishing endpoints.
  • Enabling before contacts load can omit private endpoint publication.
  • A failed compensating cleanup can leave a public endpoint published after state is restored to disabled.
  • The remaining profile and contact UI changes are contained.

Bitkit/Views/Settings/GeneralSettingsView.swift; Bitkit/Services/ContactPaymentsService.swift

Important Files Changed

FilenameOverview
Bitkit/Services/ContactPaymentsService.swiftAdds unified endpoint publication, cleanup, and rollback, but a failed compensating cleanup can leave published state inconsistent with the restored preference.
Bitkit/Views/Settings/GeneralSettingsView.swiftAdds the unified toggle, but its default display and contact-list snapshot can diverge from actual endpoint publication.
Bitkit/Views/Profile/PayContactsView.swiftRemoves the onboarding toggle and enables contact payments through the consolidated service.
Bitkit/Views/Profile/ProfileView.swiftAdds direct tag creation and deletion with a synchronous overlapping-save guard.
Bitkit/Views/Contacts/AddContactView.swiftAdds conditional Pay and Save actions plus saved-contact navigation.
Bitkit/Views/Contacts/ContactDetailView.swiftAdds the saved-contact title and delete mode.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
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[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
Loading

Comments Outside Diff (1)

  1. Bitkit/Views/Settings/GeneralSettingsView.swift, line 47-48 (link)

    P1Enabled State Is Not Published

    For an authenticated user with no confirmed preference and both publication flags false, this fallback displays the toggle as enabled without calling setEnabled(true). If the user leaves it untouched, no endpoints are published and contacts still cannot pay them despite General Settings showing the feature as on.

Reviews (1): Last reviewed commit: "fix: harden contact payment settings" | Re-trigger Greptile

Comment threadBitkit/Services/ContactPaymentsService.swift
Comment threadBitkit/Views/Settings/GeneralSettingsView.swift
@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

Addressed the remaining Greptile review observations in 1006451:

  • An unconfirmed contact-payment preference is no longer rendered as already active. General Settings actively provisions the default-on state, shows the pending value while it runs, and only reports enabled after publication succeeds.
  • Contact publication now waits for the authenticated contact list to finish loading.
  • Public endpoint publication/removal is the final fallible transition, and local state is committed only after the complete operation succeeds.

Verification: SwiftFormat/diff checks pass, and all 8 focused ContactPaymentsServiceTests pass on the iOS simulator.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from 1006451 to 03acbcdCompareJuly 22, 2026 13:01

@piotr-iohkpiotr-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

@ovitrif
ovitrifforce-pushed the codex/pubky-paykit-figma-alignment branch from d769ad1 to cc972d7CompareJuly 27, 2026 15:54
@ovitrif

Copy link
Copy Markdown
Collaborator

Signed last commit and merged master into the branch, review status remains, no code changes, good to merge.

@ovitrif
ovitrif enabled auto-merge July 27, 2026 15:55
@ovitrif
ovitrif merged commit 8b5c8a1 into masterJul 27, 2026
11 checks passed
@ovitrif
ovitrif deleted the codex/pubky-paykit-figma-alignment branch July 27, 2026 17:40
@coreyphillipscoreyphillips mentioned this pull request Jul 29, 2026
13 tasks
Sign up for freeto 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

@ben-kaufman@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: align Pubky and Paykit flows - #636

Merged
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment
Jul 27, 2026
Merged

fix: align Pubky and Paykit flows#636
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Part of #571

Description

This PR aligns the Pubky profile, contacts, and Paykit contact-payment flows with the v61 Figma designs while keeping the Ring flow unchanged.

  • Removes the onboarding payment toggle and enables contact payments by default.
  • Replaces the separate payment-preference screen with one General Settings toggle controlling both public and private contact payments.
  • Shows Pay and Save when a contact exposes a payment endpoint, and Save only when no payment endpoint is available.
  • Aligns profile creation/editing, contact import, contact detail, contacts list, and saved-contact navigation with the current designs.
  • Uses raw truncated Pubky keys and updates the overlapping contact-avatar stack to the Figma sizing, overlap, border, and overflow treatment.
  • Adds direct profile-tag management and prevents overlapping tag saves.
  • Consolidates contact-payment publication and cleanup behavior into one service while preserving rollback state.

This PR is based directly on master. Incoming Paykit payment-request work remains outside this branch.

Linked Issues/Tasks

Screenshot / Video

Comparison screenshots were captured and reviewed locally for the changed onboarding, profile, contacts, import, settings, and avatar-stack states. Ring remains out of scope because that flow is being updated separately.

QA Notes

Manual Tests

  • 1. Profile onboarding → Pay with Contacts: no toggle is shown; Continue enables contact payments and opens Profile.
  • 2. Settings → General → Enable payments with contacts: one toggle controls both public and private contact-payment publication.
  • 3a. Contacts → Add Contact → enter a contact with a payment endpoint: Pay and Save actions are shown.
    • 3b. Enter a contact without a payment endpoint: only Save is shown.
  • 4. Contacts → import profile contacts → select/import: selection, overview, and completion screens match the v61 flow.
  • 5. Profile → add and remove tags: changes persist and controls remain disabled while a save is running.
  • 6. Contacts list with more than five contacts: avatar stack uses 32 pt circles, 8 pt overlap, five visible avatars, and the bordered overflow count.
  • 7.regression: Pubky Ring authorization and watch-only account flows remain unchanged.

Automated Checks

  • Unit tests added: ContactPaymentsServiceTests.swift covers default enablement, unified public/private publication, cleanup, partial failures, and rollback to both enabled and disabled states.
  • Unit tests modified: ContactsManagerTests.swift verifies raw truncated Pubky key display; PublicPaykitServiceTests.swift verifies the unified preference key cleanup.
  • Local: SwiftFormat lint passes for all changed Swift files, translation validation passes with 0 errors, and git diff --check passes.
  • Local simulator: the app and test targets compile and all 8 focused contact-payment tests pass in a disposable compatibility build using the locally available newer Paykit/LDK artifacts. The exact master artifact graph could not be re-fetched locally, so CI remains the authoritative locked-dependency build.
  • CI: standard build and test checks run by the PR bot.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from fb7d862 to 12ab412CompareJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-watch-only-accounts to masterJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman marked this pull request as ready for review July 20, 2026 11:11
@greptile-apps

greptile-appsBot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns the Pubky and Paykit contact flows with the v61 designs. The main changes are:

  • Consolidated public and private contact-payment settings and rollback handling.
  • Updated profile, contact, import, and saved-contact screens.
  • Added direct profile-tag management and overlapping-save protection.
  • Changed Pubky-key formatting and contact-avatar layouts.
  • Added focused tests for contact-payment state transitions.

Confidence Score: 4/5

The unified payment flow needs fixes for displayed state, unloaded contacts, and failed endpoint rollback.

  • An unconfirmed preference can appear enabled without publishing endpoints.
  • Enabling before contacts load can omit private endpoint publication.
  • A failed compensating cleanup can leave a public endpoint published after state is restored to disabled.
  • The remaining profile and contact UI changes are contained.

Bitkit/Views/Settings/GeneralSettingsView.swift; Bitkit/Services/ContactPaymentsService.swift

Important Files Changed

FilenameOverview
Bitkit/Services/ContactPaymentsService.swiftAdds unified endpoint publication, cleanup, and rollback, but a failed compensating cleanup can leave published state inconsistent with the restored preference.
Bitkit/Views/Settings/GeneralSettingsView.swiftAdds the unified toggle, but its default display and contact-list snapshot can diverge from actual endpoint publication.
Bitkit/Views/Profile/PayContactsView.swiftRemoves the onboarding toggle and enables contact payments through the consolidated service.
Bitkit/Views/Profile/ProfileView.swiftAdds direct tag creation and deletion with a synchronous overlapping-save guard.
Bitkit/Views/Contacts/AddContactView.swiftAdds conditional Pay and Save actions plus saved-contact navigation.
Bitkit/Views/Contacts/ContactDetailView.swiftAdds the saved-contact title and delete mode.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
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[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
Loading

Comments Outside Diff (1)

  1. Bitkit/Views/Settings/GeneralSettingsView.swift, line 47-48 (link)

    P1Enabled State Is Not Published

    For an authenticated user with no confirmed preference and both publication flags false, this fallback displays the toggle as enabled without calling setEnabled(true). If the user leaves it untouched, no endpoints are published and contacts still cannot pay them despite General Settings showing the feature as on.

Reviews (1): Last reviewed commit: "fix: harden contact payment settings" | Re-trigger Greptile

Comment threadBitkit/Services/ContactPaymentsService.swift
Comment threadBitkit/Views/Settings/GeneralSettingsView.swift
@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

Addressed the remaining Greptile review observations in 1006451:

  • An unconfirmed contact-payment preference is no longer rendered as already active. General Settings actively provisions the default-on state, shows the pending value while it runs, and only reports enabled after publication succeeds.
  • Contact publication now waits for the authenticated contact list to finish loading.
  • Public endpoint publication/removal is the final fallible transition, and local state is committed only after the complete operation succeeds.

Verification: SwiftFormat/diff checks pass, and all 8 focused ContactPaymentsServiceTests pass on the iOS simulator.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from 1006451 to 03acbcdCompareJuly 22, 2026 13:01

@piotr-iohkpiotr-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

@ovitrif
ovitrifforce-pushed the codex/pubky-paykit-figma-alignment branch from d769ad1 to cc972d7CompareJuly 27, 2026 15:54
@ovitrif

Copy link
Copy Markdown
Collaborator

Signed last commit and merged master into the branch, review status remains, no code changes, good to merge.

@ovitrif
ovitrif enabled auto-merge July 27, 2026 15:55
@ovitrif
ovitrif merged commit 8b5c8a1 into masterJul 27, 2026
11 checks passed
@ovitrif
ovitrif deleted the codex/pubky-paykit-figma-alignment branch July 27, 2026 17:40
@coreyphillipscoreyphillips mentioned this pull request Jul 29, 2026
13 tasks
Sign up for freeto 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

@ben-kaufman@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: align Pubky and Paykit flows - #636

Merged
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment
Jul 27, 2026
Merged

fix: align Pubky and Paykit flows#636
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Part of #571

Description

This PR aligns the Pubky profile, contacts, and Paykit contact-payment flows with the v61 Figma designs while keeping the Ring flow unchanged.

  • Removes the onboarding payment toggle and enables contact payments by default.
  • Replaces the separate payment-preference screen with one General Settings toggle controlling both public and private contact payments.
  • Shows Pay and Save when a contact exposes a payment endpoint, and Save only when no payment endpoint is available.
  • Aligns profile creation/editing, contact import, contact detail, contacts list, and saved-contact navigation with the current designs.
  • Uses raw truncated Pubky keys and updates the overlapping contact-avatar stack to the Figma sizing, overlap, border, and overflow treatment.
  • Adds direct profile-tag management and prevents overlapping tag saves.
  • Consolidates contact-payment publication and cleanup behavior into one service while preserving rollback state.

This PR is based directly on master. Incoming Paykit payment-request work remains outside this branch.

Linked Issues/Tasks

Screenshot / Video

Comparison screenshots were captured and reviewed locally for the changed onboarding, profile, contacts, import, settings, and avatar-stack states. Ring remains out of scope because that flow is being updated separately.

QA Notes

Manual Tests

  • 1. Profile onboarding → Pay with Contacts: no toggle is shown; Continue enables contact payments and opens Profile.
  • 2. Settings → General → Enable payments with contacts: one toggle controls both public and private contact-payment publication.
  • 3a. Contacts → Add Contact → enter a contact with a payment endpoint: Pay and Save actions are shown.
    • 3b. Enter a contact without a payment endpoint: only Save is shown.
  • 4. Contacts → import profile contacts → select/import: selection, overview, and completion screens match the v61 flow.
  • 5. Profile → add and remove tags: changes persist and controls remain disabled while a save is running.
  • 6. Contacts list with more than five contacts: avatar stack uses 32 pt circles, 8 pt overlap, five visible avatars, and the bordered overflow count.
  • 7.regression: Pubky Ring authorization and watch-only account flows remain unchanged.

Automated Checks

  • Unit tests added: ContactPaymentsServiceTests.swift covers default enablement, unified public/private publication, cleanup, partial failures, and rollback to both enabled and disabled states.
  • Unit tests modified: ContactsManagerTests.swift verifies raw truncated Pubky key display; PublicPaykitServiceTests.swift verifies the unified preference key cleanup.
  • Local: SwiftFormat lint passes for all changed Swift files, translation validation passes with 0 errors, and git diff --check passes.
  • Local simulator: the app and test targets compile and all 8 focused contact-payment tests pass in a disposable compatibility build using the locally available newer Paykit/LDK artifacts. The exact master artifact graph could not be re-fetched locally, so CI remains the authoritative locked-dependency build.
  • CI: standard build and test checks run by the PR bot.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from fb7d862 to 12ab412CompareJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-watch-only-accounts to masterJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman marked this pull request as ready for review July 20, 2026 11:11
@greptile-apps

greptile-appsBot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns the Pubky and Paykit contact flows with the v61 designs. The main changes are:

  • Consolidated public and private contact-payment settings and rollback handling.
  • Updated profile, contact, import, and saved-contact screens.
  • Added direct profile-tag management and overlapping-save protection.
  • Changed Pubky-key formatting and contact-avatar layouts.
  • Added focused tests for contact-payment state transitions.

Confidence Score: 4/5

The unified payment flow needs fixes for displayed state, unloaded contacts, and failed endpoint rollback.

  • An unconfirmed preference can appear enabled without publishing endpoints.
  • Enabling before contacts load can omit private endpoint publication.
  • A failed compensating cleanup can leave a public endpoint published after state is restored to disabled.
  • The remaining profile and contact UI changes are contained.

Bitkit/Views/Settings/GeneralSettingsView.swift; Bitkit/Services/ContactPaymentsService.swift

Important Files Changed

FilenameOverview
Bitkit/Services/ContactPaymentsService.swiftAdds unified endpoint publication, cleanup, and rollback, but a failed compensating cleanup can leave published state inconsistent with the restored preference.
Bitkit/Views/Settings/GeneralSettingsView.swiftAdds the unified toggle, but its default display and contact-list snapshot can diverge from actual endpoint publication.
Bitkit/Views/Profile/PayContactsView.swiftRemoves the onboarding toggle and enables contact payments through the consolidated service.
Bitkit/Views/Profile/ProfileView.swiftAdds direct tag creation and deletion with a synchronous overlapping-save guard.
Bitkit/Views/Contacts/AddContactView.swiftAdds conditional Pay and Save actions plus saved-contact navigation.
Bitkit/Views/Contacts/ContactDetailView.swiftAdds the saved-contact title and delete mode.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
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[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
Loading

Comments Outside Diff (1)

  1. Bitkit/Views/Settings/GeneralSettingsView.swift, line 47-48 (link)

    P1Enabled State Is Not Published

    For an authenticated user with no confirmed preference and both publication flags false, this fallback displays the toggle as enabled without calling setEnabled(true). If the user leaves it untouched, no endpoints are published and contacts still cannot pay them despite General Settings showing the feature as on.

Reviews (1): Last reviewed commit: "fix: harden contact payment settings" | Re-trigger Greptile

Comment threadBitkit/Services/ContactPaymentsService.swift
Comment threadBitkit/Views/Settings/GeneralSettingsView.swift
@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

Addressed the remaining Greptile review observations in 1006451:

  • An unconfirmed contact-payment preference is no longer rendered as already active. General Settings actively provisions the default-on state, shows the pending value while it runs, and only reports enabled after publication succeeds.
  • Contact publication now waits for the authenticated contact list to finish loading.
  • Public endpoint publication/removal is the final fallible transition, and local state is committed only after the complete operation succeeds.

Verification: SwiftFormat/diff checks pass, and all 8 focused ContactPaymentsServiceTests pass on the iOS simulator.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from 1006451 to 03acbcdCompareJuly 22, 2026 13:01

@piotr-iohkpiotr-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

@ovitrif
ovitrifforce-pushed the codex/pubky-paykit-figma-alignment branch from d769ad1 to cc972d7CompareJuly 27, 2026 15:54
@ovitrif

Copy link
Copy Markdown
Collaborator

Signed last commit and merged master into the branch, review status remains, no code changes, good to merge.

@ovitrif
ovitrif enabled auto-merge July 27, 2026 15:55
@ovitrif
ovitrif merged commit 8b5c8a1 into masterJul 27, 2026
11 checks passed
@ovitrif
ovitrif deleted the codex/pubky-paykit-figma-alignment branch July 27, 2026 17:40
@coreyphillipscoreyphillips mentioned this pull request Jul 29, 2026
13 tasks
Sign up for freeto 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

@ben-kaufman@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: align Pubky and Paykit flows - #636

Merged
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment
Jul 27, 2026
Merged

fix: align Pubky and Paykit flows#636
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Part of #571

Description

This PR aligns the Pubky profile, contacts, and Paykit contact-payment flows with the v61 Figma designs while keeping the Ring flow unchanged.

  • Removes the onboarding payment toggle and enables contact payments by default.
  • Replaces the separate payment-preference screen with one General Settings toggle controlling both public and private contact payments.
  • Shows Pay and Save when a contact exposes a payment endpoint, and Save only when no payment endpoint is available.
  • Aligns profile creation/editing, contact import, contact detail, contacts list, and saved-contact navigation with the current designs.
  • Uses raw truncated Pubky keys and updates the overlapping contact-avatar stack to the Figma sizing, overlap, border, and overflow treatment.
  • Adds direct profile-tag management and prevents overlapping tag saves.
  • Consolidates contact-payment publication and cleanup behavior into one service while preserving rollback state.

This PR is based directly on master. Incoming Paykit payment-request work remains outside this branch.

Linked Issues/Tasks

Screenshot / Video

Comparison screenshots were captured and reviewed locally for the changed onboarding, profile, contacts, import, settings, and avatar-stack states. Ring remains out of scope because that flow is being updated separately.

QA Notes

Manual Tests

  • 1. Profile onboarding → Pay with Contacts: no toggle is shown; Continue enables contact payments and opens Profile.
  • 2. Settings → General → Enable payments with contacts: one toggle controls both public and private contact-payment publication.
  • 3a. Contacts → Add Contact → enter a contact with a payment endpoint: Pay and Save actions are shown.
    • 3b. Enter a contact without a payment endpoint: only Save is shown.
  • 4. Contacts → import profile contacts → select/import: selection, overview, and completion screens match the v61 flow.
  • 5. Profile → add and remove tags: changes persist and controls remain disabled while a save is running.
  • 6. Contacts list with more than five contacts: avatar stack uses 32 pt circles, 8 pt overlap, five visible avatars, and the bordered overflow count.
  • 7.regression: Pubky Ring authorization and watch-only account flows remain unchanged.

Automated Checks

  • Unit tests added: ContactPaymentsServiceTests.swift covers default enablement, unified public/private publication, cleanup, partial failures, and rollback to both enabled and disabled states.
  • Unit tests modified: ContactsManagerTests.swift verifies raw truncated Pubky key display; PublicPaykitServiceTests.swift verifies the unified preference key cleanup.
  • Local: SwiftFormat lint passes for all changed Swift files, translation validation passes with 0 errors, and git diff --check passes.
  • Local simulator: the app and test targets compile and all 8 focused contact-payment tests pass in a disposable compatibility build using the locally available newer Paykit/LDK artifacts. The exact master artifact graph could not be re-fetched locally, so CI remains the authoritative locked-dependency build.
  • CI: standard build and test checks run by the PR bot.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from fb7d862 to 12ab412CompareJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-watch-only-accounts to masterJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman marked this pull request as ready for review July 20, 2026 11:11
@greptile-apps

greptile-appsBot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns the Pubky and Paykit contact flows with the v61 designs. The main changes are:

  • Consolidated public and private contact-payment settings and rollback handling.
  • Updated profile, contact, import, and saved-contact screens.
  • Added direct profile-tag management and overlapping-save protection.
  • Changed Pubky-key formatting and contact-avatar layouts.
  • Added focused tests for contact-payment state transitions.

Confidence Score: 4/5

The unified payment flow needs fixes for displayed state, unloaded contacts, and failed endpoint rollback.

  • An unconfirmed preference can appear enabled without publishing endpoints.
  • Enabling before contacts load can omit private endpoint publication.
  • A failed compensating cleanup can leave a public endpoint published after state is restored to disabled.
  • The remaining profile and contact UI changes are contained.

Bitkit/Views/Settings/GeneralSettingsView.swift; Bitkit/Services/ContactPaymentsService.swift

Important Files Changed

FilenameOverview
Bitkit/Services/ContactPaymentsService.swiftAdds unified endpoint publication, cleanup, and rollback, but a failed compensating cleanup can leave published state inconsistent with the restored preference.
Bitkit/Views/Settings/GeneralSettingsView.swiftAdds the unified toggle, but its default display and contact-list snapshot can diverge from actual endpoint publication.
Bitkit/Views/Profile/PayContactsView.swiftRemoves the onboarding toggle and enables contact payments through the consolidated service.
Bitkit/Views/Profile/ProfileView.swiftAdds direct tag creation and deletion with a synchronous overlapping-save guard.
Bitkit/Views/Contacts/AddContactView.swiftAdds conditional Pay and Save actions plus saved-contact navigation.
Bitkit/Views/Contacts/ContactDetailView.swiftAdds the saved-contact title and delete mode.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
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[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
Loading

Comments Outside Diff (1)

  1. Bitkit/Views/Settings/GeneralSettingsView.swift, line 47-48 (link)

    P1Enabled State Is Not Published

    For an authenticated user with no confirmed preference and both publication flags false, this fallback displays the toggle as enabled without calling setEnabled(true). If the user leaves it untouched, no endpoints are published and contacts still cannot pay them despite General Settings showing the feature as on.

Reviews (1): Last reviewed commit: "fix: harden contact payment settings" | Re-trigger Greptile

Comment threadBitkit/Services/ContactPaymentsService.swift
Comment threadBitkit/Views/Settings/GeneralSettingsView.swift
@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

Addressed the remaining Greptile review observations in 1006451:

  • An unconfirmed contact-payment preference is no longer rendered as already active. General Settings actively provisions the default-on state, shows the pending value while it runs, and only reports enabled after publication succeeds.
  • Contact publication now waits for the authenticated contact list to finish loading.
  • Public endpoint publication/removal is the final fallible transition, and local state is committed only after the complete operation succeeds.

Verification: SwiftFormat/diff checks pass, and all 8 focused ContactPaymentsServiceTests pass on the iOS simulator.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from 1006451 to 03acbcdCompareJuly 22, 2026 13:01

@piotr-iohkpiotr-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

@ovitrif
ovitrifforce-pushed the codex/pubky-paykit-figma-alignment branch from d769ad1 to cc972d7CompareJuly 27, 2026 15:54
@ovitrif

Copy link
Copy Markdown
Collaborator

Signed last commit and merged master into the branch, review status remains, no code changes, good to merge.

@ovitrif
ovitrif enabled auto-merge July 27, 2026 15:55
@ovitrif
ovitrif merged commit 8b5c8a1 into masterJul 27, 2026
11 checks passed
@ovitrif
ovitrif deleted the codex/pubky-paykit-figma-alignment branch July 27, 2026 17:40
@coreyphillipscoreyphillips mentioned this pull request Jul 29, 2026
13 tasks
Sign up for freeto 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

@ben-kaufman@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: align Pubky and Paykit flows - #636

Merged
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment
Jul 27, 2026
Merged

fix: align Pubky and Paykit flows#636
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Part of #571

Description

This PR aligns the Pubky profile, contacts, and Paykit contact-payment flows with the v61 Figma designs while keeping the Ring flow unchanged.

  • Removes the onboarding payment toggle and enables contact payments by default.
  • Replaces the separate payment-preference screen with one General Settings toggle controlling both public and private contact payments.
  • Shows Pay and Save when a contact exposes a payment endpoint, and Save only when no payment endpoint is available.
  • Aligns profile creation/editing, contact import, contact detail, contacts list, and saved-contact navigation with the current designs.
  • Uses raw truncated Pubky keys and updates the overlapping contact-avatar stack to the Figma sizing, overlap, border, and overflow treatment.
  • Adds direct profile-tag management and prevents overlapping tag saves.
  • Consolidates contact-payment publication and cleanup behavior into one service while preserving rollback state.

This PR is based directly on master. Incoming Paykit payment-request work remains outside this branch.

Linked Issues/Tasks

Screenshot / Video

Comparison screenshots were captured and reviewed locally for the changed onboarding, profile, contacts, import, settings, and avatar-stack states. Ring remains out of scope because that flow is being updated separately.

QA Notes

Manual Tests

  • 1. Profile onboarding → Pay with Contacts: no toggle is shown; Continue enables contact payments and opens Profile.
  • 2. Settings → General → Enable payments with contacts: one toggle controls both public and private contact-payment publication.
  • 3a. Contacts → Add Contact → enter a contact with a payment endpoint: Pay and Save actions are shown.
    • 3b. Enter a contact without a payment endpoint: only Save is shown.
  • 4. Contacts → import profile contacts → select/import: selection, overview, and completion screens match the v61 flow.
  • 5. Profile → add and remove tags: changes persist and controls remain disabled while a save is running.
  • 6. Contacts list with more than five contacts: avatar stack uses 32 pt circles, 8 pt overlap, five visible avatars, and the bordered overflow count.
  • 7.regression: Pubky Ring authorization and watch-only account flows remain unchanged.

Automated Checks

  • Unit tests added: ContactPaymentsServiceTests.swift covers default enablement, unified public/private publication, cleanup, partial failures, and rollback to both enabled and disabled states.
  • Unit tests modified: ContactsManagerTests.swift verifies raw truncated Pubky key display; PublicPaykitServiceTests.swift verifies the unified preference key cleanup.
  • Local: SwiftFormat lint passes for all changed Swift files, translation validation passes with 0 errors, and git diff --check passes.
  • Local simulator: the app and test targets compile and all 8 focused contact-payment tests pass in a disposable compatibility build using the locally available newer Paykit/LDK artifacts. The exact master artifact graph could not be re-fetched locally, so CI remains the authoritative locked-dependency build.
  • CI: standard build and test checks run by the PR bot.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from fb7d862 to 12ab412CompareJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-watch-only-accounts to masterJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman marked this pull request as ready for review July 20, 2026 11:11
@greptile-apps

greptile-appsBot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns the Pubky and Paykit contact flows with the v61 designs. The main changes are:

  • Consolidated public and private contact-payment settings and rollback handling.
  • Updated profile, contact, import, and saved-contact screens.
  • Added direct profile-tag management and overlapping-save protection.
  • Changed Pubky-key formatting and contact-avatar layouts.
  • Added focused tests for contact-payment state transitions.

Confidence Score: 4/5

The unified payment flow needs fixes for displayed state, unloaded contacts, and failed endpoint rollback.

  • An unconfirmed preference can appear enabled without publishing endpoints.
  • Enabling before contacts load can omit private endpoint publication.
  • A failed compensating cleanup can leave a public endpoint published after state is restored to disabled.
  • The remaining profile and contact UI changes are contained.

Bitkit/Views/Settings/GeneralSettingsView.swift; Bitkit/Services/ContactPaymentsService.swift

Important Files Changed

FilenameOverview
Bitkit/Services/ContactPaymentsService.swiftAdds unified endpoint publication, cleanup, and rollback, but a failed compensating cleanup can leave published state inconsistent with the restored preference.
Bitkit/Views/Settings/GeneralSettingsView.swiftAdds the unified toggle, but its default display and contact-list snapshot can diverge from actual endpoint publication.
Bitkit/Views/Profile/PayContactsView.swiftRemoves the onboarding toggle and enables contact payments through the consolidated service.
Bitkit/Views/Profile/ProfileView.swiftAdds direct tag creation and deletion with a synchronous overlapping-save guard.
Bitkit/Views/Contacts/AddContactView.swiftAdds conditional Pay and Save actions plus saved-contact navigation.
Bitkit/Views/Contacts/ContactDetailView.swiftAdds the saved-contact title and delete mode.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
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[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
Loading

Comments Outside Diff (1)

  1. Bitkit/Views/Settings/GeneralSettingsView.swift, line 47-48 (link)

    P1Enabled State Is Not Published

    For an authenticated user with no confirmed preference and both publication flags false, this fallback displays the toggle as enabled without calling setEnabled(true). If the user leaves it untouched, no endpoints are published and contacts still cannot pay them despite General Settings showing the feature as on.

Reviews (1): Last reviewed commit: "fix: harden contact payment settings" | Re-trigger Greptile

Comment threadBitkit/Services/ContactPaymentsService.swift
Comment threadBitkit/Views/Settings/GeneralSettingsView.swift
@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

Addressed the remaining Greptile review observations in 1006451:

  • An unconfirmed contact-payment preference is no longer rendered as already active. General Settings actively provisions the default-on state, shows the pending value while it runs, and only reports enabled after publication succeeds.
  • Contact publication now waits for the authenticated contact list to finish loading.
  • Public endpoint publication/removal is the final fallible transition, and local state is committed only after the complete operation succeeds.

Verification: SwiftFormat/diff checks pass, and all 8 focused ContactPaymentsServiceTests pass on the iOS simulator.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from 1006451 to 03acbcdCompareJuly 22, 2026 13:01

@piotr-iohkpiotr-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

@ovitrif
ovitrifforce-pushed the codex/pubky-paykit-figma-alignment branch from d769ad1 to cc972d7CompareJuly 27, 2026 15:54
@ovitrif

Copy link
Copy Markdown
Collaborator

Signed last commit and merged master into the branch, review status remains, no code changes, good to merge.

@ovitrif
ovitrif enabled auto-merge July 27, 2026 15:55
@ovitrif
ovitrif merged commit 8b5c8a1 into masterJul 27, 2026
11 checks passed
@ovitrif
ovitrif deleted the codex/pubky-paykit-figma-alignment branch July 27, 2026 17:40
@coreyphillipscoreyphillips mentioned this pull request Jul 29, 2026
13 tasks
Sign up for freeto 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

@ben-kaufman@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: align Pubky and Paykit flows - #636

Merged
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment
Jul 27, 2026
Merged

fix: align Pubky and Paykit flows#636
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Part of #571

Description

This PR aligns the Pubky profile, contacts, and Paykit contact-payment flows with the v61 Figma designs while keeping the Ring flow unchanged.

  • Removes the onboarding payment toggle and enables contact payments by default.
  • Replaces the separate payment-preference screen with one General Settings toggle controlling both public and private contact payments.
  • Shows Pay and Save when a contact exposes a payment endpoint, and Save only when no payment endpoint is available.
  • Aligns profile creation/editing, contact import, contact detail, contacts list, and saved-contact navigation with the current designs.
  • Uses raw truncated Pubky keys and updates the overlapping contact-avatar stack to the Figma sizing, overlap, border, and overflow treatment.
  • Adds direct profile-tag management and prevents overlapping tag saves.
  • Consolidates contact-payment publication and cleanup behavior into one service while preserving rollback state.

This PR is based directly on master. Incoming Paykit payment-request work remains outside this branch.

Linked Issues/Tasks

Screenshot / Video

Comparison screenshots were captured and reviewed locally for the changed onboarding, profile, contacts, import, settings, and avatar-stack states. Ring remains out of scope because that flow is being updated separately.

QA Notes

Manual Tests

  • 1. Profile onboarding → Pay with Contacts: no toggle is shown; Continue enables contact payments and opens Profile.
  • 2. Settings → General → Enable payments with contacts: one toggle controls both public and private contact-payment publication.
  • 3a. Contacts → Add Contact → enter a contact with a payment endpoint: Pay and Save actions are shown.
    • 3b. Enter a contact without a payment endpoint: only Save is shown.
  • 4. Contacts → import profile contacts → select/import: selection, overview, and completion screens match the v61 flow.
  • 5. Profile → add and remove tags: changes persist and controls remain disabled while a save is running.
  • 6. Contacts list with more than five contacts: avatar stack uses 32 pt circles, 8 pt overlap, five visible avatars, and the bordered overflow count.
  • 7.regression: Pubky Ring authorization and watch-only account flows remain unchanged.

Automated Checks

  • Unit tests added: ContactPaymentsServiceTests.swift covers default enablement, unified public/private publication, cleanup, partial failures, and rollback to both enabled and disabled states.
  • Unit tests modified: ContactsManagerTests.swift verifies raw truncated Pubky key display; PublicPaykitServiceTests.swift verifies the unified preference key cleanup.
  • Local: SwiftFormat lint passes for all changed Swift files, translation validation passes with 0 errors, and git diff --check passes.
  • Local simulator: the app and test targets compile and all 8 focused contact-payment tests pass in a disposable compatibility build using the locally available newer Paykit/LDK artifacts. The exact master artifact graph could not be re-fetched locally, so CI remains the authoritative locked-dependency build.
  • CI: standard build and test checks run by the PR bot.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from fb7d862 to 12ab412CompareJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-watch-only-accounts to masterJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman marked this pull request as ready for review July 20, 2026 11:11
@greptile-apps

greptile-appsBot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns the Pubky and Paykit contact flows with the v61 designs. The main changes are:

  • Consolidated public and private contact-payment settings and rollback handling.
  • Updated profile, contact, import, and saved-contact screens.
  • Added direct profile-tag management and overlapping-save protection.
  • Changed Pubky-key formatting and contact-avatar layouts.
  • Added focused tests for contact-payment state transitions.

Confidence Score: 4/5

The unified payment flow needs fixes for displayed state, unloaded contacts, and failed endpoint rollback.

  • An unconfirmed preference can appear enabled without publishing endpoints.
  • Enabling before contacts load can omit private endpoint publication.
  • A failed compensating cleanup can leave a public endpoint published after state is restored to disabled.
  • The remaining profile and contact UI changes are contained.

Bitkit/Views/Settings/GeneralSettingsView.swift; Bitkit/Services/ContactPaymentsService.swift

Important Files Changed

FilenameOverview
Bitkit/Services/ContactPaymentsService.swiftAdds unified endpoint publication, cleanup, and rollback, but a failed compensating cleanup can leave published state inconsistent with the restored preference.
Bitkit/Views/Settings/GeneralSettingsView.swiftAdds the unified toggle, but its default display and contact-list snapshot can diverge from actual endpoint publication.
Bitkit/Views/Profile/PayContactsView.swiftRemoves the onboarding toggle and enables contact payments through the consolidated service.
Bitkit/Views/Profile/ProfileView.swiftAdds direct tag creation and deletion with a synchronous overlapping-save guard.
Bitkit/Views/Contacts/AddContactView.swiftAdds conditional Pay and Save actions plus saved-contact navigation.
Bitkit/Views/Contacts/ContactDetailView.swiftAdds the saved-contact title and delete mode.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
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[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
Loading

Comments Outside Diff (1)

  1. Bitkit/Views/Settings/GeneralSettingsView.swift, line 47-48 (link)

    P1Enabled State Is Not Published

    For an authenticated user with no confirmed preference and both publication flags false, this fallback displays the toggle as enabled without calling setEnabled(true). If the user leaves it untouched, no endpoints are published and contacts still cannot pay them despite General Settings showing the feature as on.

Reviews (1): Last reviewed commit: "fix: harden contact payment settings" | Re-trigger Greptile

Comment threadBitkit/Services/ContactPaymentsService.swift
Comment threadBitkit/Views/Settings/GeneralSettingsView.swift
@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

Addressed the remaining Greptile review observations in 1006451:

  • An unconfirmed contact-payment preference is no longer rendered as already active. General Settings actively provisions the default-on state, shows the pending value while it runs, and only reports enabled after publication succeeds.
  • Contact publication now waits for the authenticated contact list to finish loading.
  • Public endpoint publication/removal is the final fallible transition, and local state is committed only after the complete operation succeeds.

Verification: SwiftFormat/diff checks pass, and all 8 focused ContactPaymentsServiceTests pass on the iOS simulator.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from 1006451 to 03acbcdCompareJuly 22, 2026 13:01

@piotr-iohkpiotr-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

@ovitrif
ovitrifforce-pushed the codex/pubky-paykit-figma-alignment branch from d769ad1 to cc972d7CompareJuly 27, 2026 15:54
@ovitrif

Copy link
Copy Markdown
Collaborator

Signed last commit and merged master into the branch, review status remains, no code changes, good to merge.

@ovitrif
ovitrif enabled auto-merge July 27, 2026 15:55
@ovitrif
ovitrif merged commit 8b5c8a1 into masterJul 27, 2026
11 checks passed
@ovitrif
ovitrif deleted the codex/pubky-paykit-figma-alignment branch July 27, 2026 17:40
@coreyphillipscoreyphillips mentioned this pull request Jul 29, 2026
13 tasks
Sign up for freeto 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

@ben-kaufman@ovitrif@piotr-iohk
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: align Pubky and Paykit flows - #636

Merged
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment
Jul 27, 2026
Merged

fix: align Pubky and Paykit flows#636
ovitrif merged 9 commits into
masterfrom
codex/pubky-paykit-figma-alignment

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Part of #571

Description

This PR aligns the Pubky profile, contacts, and Paykit contact-payment flows with the v61 Figma designs while keeping the Ring flow unchanged.

  • Removes the onboarding payment toggle and enables contact payments by default.
  • Replaces the separate payment-preference screen with one General Settings toggle controlling both public and private contact payments.
  • Shows Pay and Save when a contact exposes a payment endpoint, and Save only when no payment endpoint is available.
  • Aligns profile creation/editing, contact import, contact detail, contacts list, and saved-contact navigation with the current designs.
  • Uses raw truncated Pubky keys and updates the overlapping contact-avatar stack to the Figma sizing, overlap, border, and overflow treatment.
  • Adds direct profile-tag management and prevents overlapping tag saves.
  • Consolidates contact-payment publication and cleanup behavior into one service while preserving rollback state.

This PR is based directly on master. Incoming Paykit payment-request work remains outside this branch.

Linked Issues/Tasks

Screenshot / Video

Comparison screenshots were captured and reviewed locally for the changed onboarding, profile, contacts, import, settings, and avatar-stack states. Ring remains out of scope because that flow is being updated separately.

QA Notes

Manual Tests

  • 1. Profile onboarding → Pay with Contacts: no toggle is shown; Continue enables contact payments and opens Profile.
  • 2. Settings → General → Enable payments with contacts: one toggle controls both public and private contact-payment publication.
  • 3a. Contacts → Add Contact → enter a contact with a payment endpoint: Pay and Save actions are shown.
    • 3b. Enter a contact without a payment endpoint: only Save is shown.
  • 4. Contacts → import profile contacts → select/import: selection, overview, and completion screens match the v61 flow.
  • 5. Profile → add and remove tags: changes persist and controls remain disabled while a save is running.
  • 6. Contacts list with more than five contacts: avatar stack uses 32 pt circles, 8 pt overlap, five visible avatars, and the bordered overflow count.
  • 7.regression: Pubky Ring authorization and watch-only account flows remain unchanged.

Automated Checks

  • Unit tests added: ContactPaymentsServiceTests.swift covers default enablement, unified public/private publication, cleanup, partial failures, and rollback to both enabled and disabled states.
  • Unit tests modified: ContactsManagerTests.swift verifies raw truncated Pubky key display; PublicPaykitServiceTests.swift verifies the unified preference key cleanup.
  • Local: SwiftFormat lint passes for all changed Swift files, translation validation passes with 0 errors, and git diff --check passes.
  • Local simulator: the app and test targets compile and all 8 focused contact-payment tests pass in a disposable compatibility build using the locally available newer Paykit/LDK artifacts. The exact master artifact graph could not be re-fetched locally, so CI remains the authoritative locked-dependency build.
  • CI: standard build and test checks run by the PR bot.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from fb7d862 to 12ab412CompareJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-watch-only-accounts to masterJuly 20, 2026 09:09
@ben-kaufman
ben-kaufman marked this pull request as ready for review July 20, 2026 11:11
@greptile-apps

greptile-appsBot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR aligns the Pubky and Paykit contact flows with the v61 designs. The main changes are:

  • Consolidated public and private contact-payment settings and rollback handling.
  • Updated profile, contact, import, and saved-contact screens.
  • Added direct profile-tag management and overlapping-save protection.
  • Changed Pubky-key formatting and contact-avatar layouts.
  • Added focused tests for contact-payment state transitions.

Confidence Score: 4/5

The unified payment flow needs fixes for displayed state, unloaded contacts, and failed endpoint rollback.

  • An unconfirmed preference can appear enabled without publishing endpoints.
  • Enabling before contacts load can omit private endpoint publication.
  • A failed compensating cleanup can leave a public endpoint published after state is restored to disabled.
  • The remaining profile and contact UI changes are contained.

Bitkit/Views/Settings/GeneralSettingsView.swift; Bitkit/Services/ContactPaymentsService.swift

Important Files Changed

FilenameOverview
Bitkit/Services/ContactPaymentsService.swiftAdds unified endpoint publication, cleanup, and rollback, but a failed compensating cleanup can leave published state inconsistent with the restored preference.
Bitkit/Views/Settings/GeneralSettingsView.swiftAdds the unified toggle, but its default display and contact-list snapshot can diverge from actual endpoint publication.
Bitkit/Views/Profile/PayContactsView.swiftRemoves the onboarding toggle and enables contact payments through the consolidated service.
Bitkit/Views/Profile/ProfileView.swiftAdds direct tag creation and deletion with a synchronous overlapping-save guard.
Bitkit/Views/Contacts/AddContactView.swiftAdds conditional Pay and Save actions plus saved-contact navigation.
Bitkit/Views/Contacts/ContactDetailView.swiftAdds the saved-contact title and delete mode.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
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[General Settings toggle] --> B[ContactPaymentsService.setEnabled]
B --> C[Sync public endpoints]
B --> D[Prepare or remove private endpoints]
C --> E[Persist publication state]
D --> E
B -->|failure| F[Restore previous state]
G[Unconfirmed preference] --> H[Toggle displays enabled]
H -. no publication call .-> I[Endpoints remain unpublished]
Loading

Comments Outside Diff (1)

  1. Bitkit/Views/Settings/GeneralSettingsView.swift, line 47-48 (link)

    P1Enabled State Is Not Published

    For an authenticated user with no confirmed preference and both publication flags false, this fallback displays the toggle as enabled without calling setEnabled(true). If the user leaves it untouched, no endpoints are published and contacts still cannot pay them despite General Settings showing the feature as on.

Reviews (1): Last reviewed commit: "fix: harden contact payment settings" | Re-trigger Greptile

Comment threadBitkit/Services/ContactPaymentsService.swift
Comment threadBitkit/Views/Settings/GeneralSettingsView.swift
@ben-kaufmanChatGPT Codex Connector

Copy link
Copy Markdown
ContributorAuthor

Addressed the remaining Greptile review observations in 1006451:

  • An unconfirmed contact-payment preference is no longer rendered as already active. General Settings actively provisions the default-on state, shows the pending value while it runs, and only reports enabled after publication succeeds.
  • Contact publication now waits for the authenticated contact list to finish loading.
  • Public endpoint publication/removal is the final fallible transition, and local state is committed only after the complete operation succeeds.

Verification: SwiftFormat/diff checks pass, and all 8 focused ContactPaymentsServiceTests pass on the iOS simulator.

@ben-kaufman
ben-kaufmanforce-pushed the codex/pubky-paykit-figma-alignment branch from 1006451 to 03acbcdCompareJuly 22, 2026 13:01

@piotr-iohkpiotr-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

@ovitrif
ovitrifforce-pushed the codex/pubky-paykit-figma-alignment branch from d769ad1 to cc972d7CompareJuly 27, 2026 15:54
@ovitrif

Copy link
Copy Markdown
Collaborator

Signed last commit and merged master into the branch, review status remains, no code changes, good to merge.

@ovitrif
ovitrif enabled auto-merge July 27, 2026 15:55
@ovitrif
ovitrif merged commit 8b5c8a1 into masterJul 27, 2026
11 checks passed
@ovitrif
ovitrif deleted the codex/pubky-paykit-figma-alignment branch July 27, 2026 17:40
@coreyphillipscoreyphillips mentioned this pull request Jul 29, 2026
13 tasks
Sign up for freeto 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

@ben-kaufman@ovitrif@piotr-iohk