feat: add Paykit subscriptions - #1186

Open
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android
Open

feat: add Paykit subscriptions#1186
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #1199, which is stacked on #1178.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Preview

Final Android and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise initial-payment failure and retry and verify the Send sheet remains presented while the first period stays due.
  • Verify Lightning and on-chain subscription success choose purple/orange confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • Full testDevDebugUnitTest suite
  • Focused PaykitPaymentRequestRepoTest, PaykitPaymentRequestRepoSubscriptionTest, SubscriptionsScreenTest, and AppViewModelSendFlowTest
  • compileDevDebugKotlin
  • compileDevDebugAndroidTestKotlin
  • detekt --rerun-tasks
  • arm64 assembleDevDebug, install, and cold launch on API 36 emulator CodexBullTlsUiApi36
  • git diff --check

@greptile-apps

This comment has been minimized.

@jvsena42

Copy link
Copy Markdown
Member

could test the PR stack feature for this case

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from f189535 to a1a7907CompareAugust 28, 2026 13:29
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 2eecc75 to baf9894CompareAugust 28, 2026 14:36
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from 9e4ee27 to 19823e6CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from baf9894 to 5a876f8CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 5a876f8 to bb2f12fCompareAugust 31, 2026 17:53
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-payment-proofs-android to codex/paykit-hardware-payment-proofs-androidAugust 31, 2026 17:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from bb2f12f to 050b32bCompareAugust 31, 2026 17:58
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Done: the PR now uses the stack directly. #1186 is based on the hardware-proof fix #1199, which is based on #1178, so each review contains only its own layer.

@ovitrifovitrif 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.

A few leftovers on this layer:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_contact_timestamp is unused after the payment-request subtitle rewrite.
  • Local due-notification scheduling and beginPaymentRequestWaitingForUpdatedList have no tests that would fail if those paths broke.

Comment threadapp/src/main/java/to/bitkit/services/PaykitSdkService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitSubscription.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
jvsena42
jvsena42 previously requested changes Sep 1, 2026

@jvsena42jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Duplicated component

Image

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 82d6c73 to e1053b0CompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 1cbcc6f to 4cfdf4eCompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e1053b0 to 850c252CompareSeptember 1, 2026 12:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 4cfdf4e to dd53772CompareSeptember 1, 2026 12:54
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

@jvsena42 Fixed in dd53772. The duplicated fiat value came from replacing the subscription review sheet while its content was still composed. The flow now reuses the existing dismiss-delay-present sheet transition and waits for that transition before validating the destination. The focused send-flow regression passes.

@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The duplicated subscription payment UI is fixed in signed commit dd53772. The review sheet now completes its normal dismiss transition before the Send sheet is presented, and the focused send-flow regression covers the sequence. @jvsena42 please re-review the updated head when E2E finishes.

ovitrif
ovitrif previously requested changes Sep 1, 2026

@ovitrifovitrif 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.

prepareHardwareContactPayment marks the on-chain proof started before the hardware device signs, but onHardwareSignCancelled and send-sheet dismiss never call failOnchainPayment. The due request then stays in inFlightRequestIds and a later prepare() fails with OperationInProgress.

Also:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_timestamp is unused after paymentRequestDateTime was removed.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 850c252 to bac8656CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from dd53772 to 9bd7677CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from bac8656 to 6bb8501CompareSeptember 1, 2026 18:19

@ovitrifovitrif 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.

utACK

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from af462ca to 1d50070CompareSeptember 2, 2026 13:22
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 2 times, most recently from b242110 to f36505cCompareSeptember 2, 2026 13:31
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from ddd0195 to d0bf6c2CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from f36505c to 3b32ae0CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from d0bf6c2 to e84d74aCompareSeptember 2, 2026 13:46
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 3b32ae0 to e623010CompareSeptember 2, 2026 13:47
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e84d74a to 35c0b4cCompareSeptember 2, 2026 13:56
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 3 times, most recently from 3e5bab0 to bbce563CompareSeptember 2, 2026 14:15

@ovitrifovitrif 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.

Onchain Paykit payment still fails closed after proof prepare fails: markOnchainPaymentStarted(...).getOrThrow() in beforeSendAttempt (and the hardware onFailure return) still requires the unstarted proof that prepare would have stored. The new tests stub that mark to succeed, so they would not catch this.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

@ovitrifovitrif 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.

On-chain Paykit sends still fail closed when proof prepare fails. proceedWithPayment continues after getOrNull(), but beforeSendAttempt then calls markOnchainPaymentStarted(...).getOrThrow(), and hardware prepareHardwareContactPayment still returns false on that failure. The new tests stub the mark to succeed, so they do not catch this.

@jvsena42jvsena42 mentioned this pull request Sep 2, 2026
2 tasks
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 09f85e6 to 92b10ebCompareSeptember 2, 2026 17:52

@ovitrifovitrif 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.

utACK

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@jvsena42@ovitrif
, '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

feat: add Paykit subscriptions - #1186

Open
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android
Open

feat: add Paykit subscriptions#1186
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #1199, which is stacked on #1178.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Preview

Final Android and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise initial-payment failure and retry and verify the Send sheet remains presented while the first period stays due.
  • Verify Lightning and on-chain subscription success choose purple/orange confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • Full testDevDebugUnitTest suite
  • Focused PaykitPaymentRequestRepoTest, PaykitPaymentRequestRepoSubscriptionTest, SubscriptionsScreenTest, and AppViewModelSendFlowTest
  • compileDevDebugKotlin
  • compileDevDebugAndroidTestKotlin
  • detekt --rerun-tasks
  • arm64 assembleDevDebug, install, and cold launch on API 36 emulator CodexBullTlsUiApi36
  • git diff --check

@greptile-apps

This comment has been minimized.

@jvsena42

Copy link
Copy Markdown
Member

could test the PR stack feature for this case

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from f189535 to a1a7907CompareAugust 28, 2026 13:29
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 2eecc75 to baf9894CompareAugust 28, 2026 14:36
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from 9e4ee27 to 19823e6CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from baf9894 to 5a876f8CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 5a876f8 to bb2f12fCompareAugust 31, 2026 17:53
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-payment-proofs-android to codex/paykit-hardware-payment-proofs-androidAugust 31, 2026 17:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from bb2f12f to 050b32bCompareAugust 31, 2026 17:58
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Done: the PR now uses the stack directly. #1186 is based on the hardware-proof fix #1199, which is based on #1178, so each review contains only its own layer.

@ovitrifovitrif 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.

A few leftovers on this layer:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_contact_timestamp is unused after the payment-request subtitle rewrite.
  • Local due-notification scheduling and beginPaymentRequestWaitingForUpdatedList have no tests that would fail if those paths broke.

Comment threadapp/src/main/java/to/bitkit/services/PaykitSdkService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitSubscription.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
jvsena42
jvsena42 previously requested changes Sep 1, 2026

@jvsena42jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Duplicated component

Image

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 82d6c73 to e1053b0CompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 1cbcc6f to 4cfdf4eCompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e1053b0 to 850c252CompareSeptember 1, 2026 12:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 4cfdf4e to dd53772CompareSeptember 1, 2026 12:54
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

@jvsena42 Fixed in dd53772. The duplicated fiat value came from replacing the subscription review sheet while its content was still composed. The flow now reuses the existing dismiss-delay-present sheet transition and waits for that transition before validating the destination. The focused send-flow regression passes.

@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The duplicated subscription payment UI is fixed in signed commit dd53772. The review sheet now completes its normal dismiss transition before the Send sheet is presented, and the focused send-flow regression covers the sequence. @jvsena42 please re-review the updated head when E2E finishes.

ovitrif
ovitrif previously requested changes Sep 1, 2026

@ovitrifovitrif 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.

prepareHardwareContactPayment marks the on-chain proof started before the hardware device signs, but onHardwareSignCancelled and send-sheet dismiss never call failOnchainPayment. The due request then stays in inFlightRequestIds and a later prepare() fails with OperationInProgress.

Also:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_timestamp is unused after paymentRequestDateTime was removed.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 850c252 to bac8656CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from dd53772 to 9bd7677CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from bac8656 to 6bb8501CompareSeptember 1, 2026 18:19

@ovitrifovitrif 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.

utACK

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from af462ca to 1d50070CompareSeptember 2, 2026 13:22
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 2 times, most recently from b242110 to f36505cCompareSeptember 2, 2026 13:31
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from ddd0195 to d0bf6c2CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from f36505c to 3b32ae0CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from d0bf6c2 to e84d74aCompareSeptember 2, 2026 13:46
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 3b32ae0 to e623010CompareSeptember 2, 2026 13:47
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e84d74a to 35c0b4cCompareSeptember 2, 2026 13:56
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 3 times, most recently from 3e5bab0 to bbce563CompareSeptember 2, 2026 14:15

@ovitrifovitrif 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.

Onchain Paykit payment still fails closed after proof prepare fails: markOnchainPaymentStarted(...).getOrThrow() in beforeSendAttempt (and the hardware onFailure return) still requires the unstarted proof that prepare would have stored. The new tests stub that mark to succeed, so they would not catch this.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

@ovitrifovitrif 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.

On-chain Paykit sends still fail closed when proof prepare fails. proceedWithPayment continues after getOrNull(), but beforeSendAttempt then calls markOnchainPaymentStarted(...).getOrThrow(), and hardware prepareHardwareContactPayment still returns false on that failure. The new tests stub the mark to succeed, so they do not catch this.

@jvsena42jvsena42 mentioned this pull request Sep 2, 2026
2 tasks
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 09f85e6 to 92b10ebCompareSeptember 2, 2026 17:52

@ovitrifovitrif 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.

utACK

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@jvsena42@ovitrif
, '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

feat: add Paykit subscriptions - #1186

Open
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android
Open

feat: add Paykit subscriptions#1186
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #1199, which is stacked on #1178.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Preview

Final Android and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise initial-payment failure and retry and verify the Send sheet remains presented while the first period stays due.
  • Verify Lightning and on-chain subscription success choose purple/orange confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • Full testDevDebugUnitTest suite
  • Focused PaykitPaymentRequestRepoTest, PaykitPaymentRequestRepoSubscriptionTest, SubscriptionsScreenTest, and AppViewModelSendFlowTest
  • compileDevDebugKotlin
  • compileDevDebugAndroidTestKotlin
  • detekt --rerun-tasks
  • arm64 assembleDevDebug, install, and cold launch on API 36 emulator CodexBullTlsUiApi36
  • git diff --check

@greptile-apps

This comment has been minimized.

@jvsena42

Copy link
Copy Markdown
Member

could test the PR stack feature for this case

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from f189535 to a1a7907CompareAugust 28, 2026 13:29
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 2eecc75 to baf9894CompareAugust 28, 2026 14:36
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from 9e4ee27 to 19823e6CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from baf9894 to 5a876f8CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 5a876f8 to bb2f12fCompareAugust 31, 2026 17:53
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-payment-proofs-android to codex/paykit-hardware-payment-proofs-androidAugust 31, 2026 17:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from bb2f12f to 050b32bCompareAugust 31, 2026 17:58
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Done: the PR now uses the stack directly. #1186 is based on the hardware-proof fix #1199, which is based on #1178, so each review contains only its own layer.

@ovitrifovitrif 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.

A few leftovers on this layer:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_contact_timestamp is unused after the payment-request subtitle rewrite.
  • Local due-notification scheduling and beginPaymentRequestWaitingForUpdatedList have no tests that would fail if those paths broke.

Comment threadapp/src/main/java/to/bitkit/services/PaykitSdkService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitSubscription.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
jvsena42
jvsena42 previously requested changes Sep 1, 2026

@jvsena42jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Duplicated component

Image

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 82d6c73 to e1053b0CompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 1cbcc6f to 4cfdf4eCompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e1053b0 to 850c252CompareSeptember 1, 2026 12:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 4cfdf4e to dd53772CompareSeptember 1, 2026 12:54
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

@jvsena42 Fixed in dd53772. The duplicated fiat value came from replacing the subscription review sheet while its content was still composed. The flow now reuses the existing dismiss-delay-present sheet transition and waits for that transition before validating the destination. The focused send-flow regression passes.

@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The duplicated subscription payment UI is fixed in signed commit dd53772. The review sheet now completes its normal dismiss transition before the Send sheet is presented, and the focused send-flow regression covers the sequence. @jvsena42 please re-review the updated head when E2E finishes.

ovitrif
ovitrif previously requested changes Sep 1, 2026

@ovitrifovitrif 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.

prepareHardwareContactPayment marks the on-chain proof started before the hardware device signs, but onHardwareSignCancelled and send-sheet dismiss never call failOnchainPayment. The due request then stays in inFlightRequestIds and a later prepare() fails with OperationInProgress.

Also:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_timestamp is unused after paymentRequestDateTime was removed.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 850c252 to bac8656CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from dd53772 to 9bd7677CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from bac8656 to 6bb8501CompareSeptember 1, 2026 18:19

@ovitrifovitrif 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.

utACK

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from af462ca to 1d50070CompareSeptember 2, 2026 13:22
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 2 times, most recently from b242110 to f36505cCompareSeptember 2, 2026 13:31
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from ddd0195 to d0bf6c2CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from f36505c to 3b32ae0CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from d0bf6c2 to e84d74aCompareSeptember 2, 2026 13:46
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 3b32ae0 to e623010CompareSeptember 2, 2026 13:47
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e84d74a to 35c0b4cCompareSeptember 2, 2026 13:56
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 3 times, most recently from 3e5bab0 to bbce563CompareSeptember 2, 2026 14:15

@ovitrifovitrif 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.

Onchain Paykit payment still fails closed after proof prepare fails: markOnchainPaymentStarted(...).getOrThrow() in beforeSendAttempt (and the hardware onFailure return) still requires the unstarted proof that prepare would have stored. The new tests stub that mark to succeed, so they would not catch this.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

@ovitrifovitrif 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.

On-chain Paykit sends still fail closed when proof prepare fails. proceedWithPayment continues after getOrNull(), but beforeSendAttempt then calls markOnchainPaymentStarted(...).getOrThrow(), and hardware prepareHardwareContactPayment still returns false on that failure. The new tests stub the mark to succeed, so they do not catch this.

@jvsena42jvsena42 mentioned this pull request Sep 2, 2026
2 tasks
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 09f85e6 to 92b10ebCompareSeptember 2, 2026 17:52

@ovitrifovitrif 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.

utACK

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@jvsena42@ovitrif
, '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

feat: add Paykit subscriptions - #1186

Open
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android
Open

feat: add Paykit subscriptions#1186
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #1199, which is stacked on #1178.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Preview

Final Android and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise initial-payment failure and retry and verify the Send sheet remains presented while the first period stays due.
  • Verify Lightning and on-chain subscription success choose purple/orange confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • Full testDevDebugUnitTest suite
  • Focused PaykitPaymentRequestRepoTest, PaykitPaymentRequestRepoSubscriptionTest, SubscriptionsScreenTest, and AppViewModelSendFlowTest
  • compileDevDebugKotlin
  • compileDevDebugAndroidTestKotlin
  • detekt --rerun-tasks
  • arm64 assembleDevDebug, install, and cold launch on API 36 emulator CodexBullTlsUiApi36
  • git diff --check

@greptile-apps

This comment has been minimized.

@jvsena42

Copy link
Copy Markdown
Member

could test the PR stack feature for this case

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from f189535 to a1a7907CompareAugust 28, 2026 13:29
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 2eecc75 to baf9894CompareAugust 28, 2026 14:36
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from 9e4ee27 to 19823e6CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from baf9894 to 5a876f8CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 5a876f8 to bb2f12fCompareAugust 31, 2026 17:53
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-payment-proofs-android to codex/paykit-hardware-payment-proofs-androidAugust 31, 2026 17:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from bb2f12f to 050b32bCompareAugust 31, 2026 17:58
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Done: the PR now uses the stack directly. #1186 is based on the hardware-proof fix #1199, which is based on #1178, so each review contains only its own layer.

@ovitrifovitrif 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.

A few leftovers on this layer:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_contact_timestamp is unused after the payment-request subtitle rewrite.
  • Local due-notification scheduling and beginPaymentRequestWaitingForUpdatedList have no tests that would fail if those paths broke.

Comment threadapp/src/main/java/to/bitkit/services/PaykitSdkService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitSubscription.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
jvsena42
jvsena42 previously requested changes Sep 1, 2026

@jvsena42jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Duplicated component

Image

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 82d6c73 to e1053b0CompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 1cbcc6f to 4cfdf4eCompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e1053b0 to 850c252CompareSeptember 1, 2026 12:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 4cfdf4e to dd53772CompareSeptember 1, 2026 12:54
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

@jvsena42 Fixed in dd53772. The duplicated fiat value came from replacing the subscription review sheet while its content was still composed. The flow now reuses the existing dismiss-delay-present sheet transition and waits for that transition before validating the destination. The focused send-flow regression passes.

@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The duplicated subscription payment UI is fixed in signed commit dd53772. The review sheet now completes its normal dismiss transition before the Send sheet is presented, and the focused send-flow regression covers the sequence. @jvsena42 please re-review the updated head when E2E finishes.

ovitrif
ovitrif previously requested changes Sep 1, 2026

@ovitrifovitrif 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.

prepareHardwareContactPayment marks the on-chain proof started before the hardware device signs, but onHardwareSignCancelled and send-sheet dismiss never call failOnchainPayment. The due request then stays in inFlightRequestIds and a later prepare() fails with OperationInProgress.

Also:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_timestamp is unused after paymentRequestDateTime was removed.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 850c252 to bac8656CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from dd53772 to 9bd7677CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from bac8656 to 6bb8501CompareSeptember 1, 2026 18:19

@ovitrifovitrif 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.

utACK

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from af462ca to 1d50070CompareSeptember 2, 2026 13:22
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 2 times, most recently from b242110 to f36505cCompareSeptember 2, 2026 13:31
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from ddd0195 to d0bf6c2CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from f36505c to 3b32ae0CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from d0bf6c2 to e84d74aCompareSeptember 2, 2026 13:46
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 3b32ae0 to e623010CompareSeptember 2, 2026 13:47
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e84d74a to 35c0b4cCompareSeptember 2, 2026 13:56
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 3 times, most recently from 3e5bab0 to bbce563CompareSeptember 2, 2026 14:15

@ovitrifovitrif 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.

Onchain Paykit payment still fails closed after proof prepare fails: markOnchainPaymentStarted(...).getOrThrow() in beforeSendAttempt (and the hardware onFailure return) still requires the unstarted proof that prepare would have stored. The new tests stub that mark to succeed, so they would not catch this.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

@ovitrifovitrif 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.

On-chain Paykit sends still fail closed when proof prepare fails. proceedWithPayment continues after getOrNull(), but beforeSendAttempt then calls markOnchainPaymentStarted(...).getOrThrow(), and hardware prepareHardwareContactPayment still returns false on that failure. The new tests stub the mark to succeed, so they do not catch this.

@jvsena42jvsena42 mentioned this pull request Sep 2, 2026
2 tasks
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 09f85e6 to 92b10ebCompareSeptember 2, 2026 17:52

@ovitrifovitrif 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.

utACK

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@jvsena42@ovitrif
, '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

feat: add Paykit subscriptions - #1186

Open
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android
Open

feat: add Paykit subscriptions#1186
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #1199, which is stacked on #1178.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Preview

Final Android and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise initial-payment failure and retry and verify the Send sheet remains presented while the first period stays due.
  • Verify Lightning and on-chain subscription success choose purple/orange confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • Full testDevDebugUnitTest suite
  • Focused PaykitPaymentRequestRepoTest, PaykitPaymentRequestRepoSubscriptionTest, SubscriptionsScreenTest, and AppViewModelSendFlowTest
  • compileDevDebugKotlin
  • compileDevDebugAndroidTestKotlin
  • detekt --rerun-tasks
  • arm64 assembleDevDebug, install, and cold launch on API 36 emulator CodexBullTlsUiApi36
  • git diff --check

@greptile-apps

This comment has been minimized.

@jvsena42

Copy link
Copy Markdown
Member

could test the PR stack feature for this case

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from f189535 to a1a7907CompareAugust 28, 2026 13:29
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 2eecc75 to baf9894CompareAugust 28, 2026 14:36
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from 9e4ee27 to 19823e6CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from baf9894 to 5a876f8CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 5a876f8 to bb2f12fCompareAugust 31, 2026 17:53
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-payment-proofs-android to codex/paykit-hardware-payment-proofs-androidAugust 31, 2026 17:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from bb2f12f to 050b32bCompareAugust 31, 2026 17:58
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Done: the PR now uses the stack directly. #1186 is based on the hardware-proof fix #1199, which is based on #1178, so each review contains only its own layer.

@ovitrifovitrif 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.

A few leftovers on this layer:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_contact_timestamp is unused after the payment-request subtitle rewrite.
  • Local due-notification scheduling and beginPaymentRequestWaitingForUpdatedList have no tests that would fail if those paths broke.

Comment threadapp/src/main/java/to/bitkit/services/PaykitSdkService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitSubscription.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
jvsena42
jvsena42 previously requested changes Sep 1, 2026

@jvsena42jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Duplicated component

Image

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 82d6c73 to e1053b0CompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 1cbcc6f to 4cfdf4eCompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e1053b0 to 850c252CompareSeptember 1, 2026 12:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 4cfdf4e to dd53772CompareSeptember 1, 2026 12:54
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

@jvsena42 Fixed in dd53772. The duplicated fiat value came from replacing the subscription review sheet while its content was still composed. The flow now reuses the existing dismiss-delay-present sheet transition and waits for that transition before validating the destination. The focused send-flow regression passes.

@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The duplicated subscription payment UI is fixed in signed commit dd53772. The review sheet now completes its normal dismiss transition before the Send sheet is presented, and the focused send-flow regression covers the sequence. @jvsena42 please re-review the updated head when E2E finishes.

ovitrif
ovitrif previously requested changes Sep 1, 2026

@ovitrifovitrif 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.

prepareHardwareContactPayment marks the on-chain proof started before the hardware device signs, but onHardwareSignCancelled and send-sheet dismiss never call failOnchainPayment. The due request then stays in inFlightRequestIds and a later prepare() fails with OperationInProgress.

Also:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_timestamp is unused after paymentRequestDateTime was removed.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 850c252 to bac8656CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from dd53772 to 9bd7677CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from bac8656 to 6bb8501CompareSeptember 1, 2026 18:19

@ovitrifovitrif 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.

utACK

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from af462ca to 1d50070CompareSeptember 2, 2026 13:22
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 2 times, most recently from b242110 to f36505cCompareSeptember 2, 2026 13:31
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from ddd0195 to d0bf6c2CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from f36505c to 3b32ae0CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from d0bf6c2 to e84d74aCompareSeptember 2, 2026 13:46
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 3b32ae0 to e623010CompareSeptember 2, 2026 13:47
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e84d74a to 35c0b4cCompareSeptember 2, 2026 13:56
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 3 times, most recently from 3e5bab0 to bbce563CompareSeptember 2, 2026 14:15

@ovitrifovitrif 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.

Onchain Paykit payment still fails closed after proof prepare fails: markOnchainPaymentStarted(...).getOrThrow() in beforeSendAttempt (and the hardware onFailure return) still requires the unstarted proof that prepare would have stored. The new tests stub that mark to succeed, so they would not catch this.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

@ovitrifovitrif 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.

On-chain Paykit sends still fail closed when proof prepare fails. proceedWithPayment continues after getOrNull(), but beforeSendAttempt then calls markOnchainPaymentStarted(...).getOrThrow(), and hardware prepareHardwareContactPayment still returns false on that failure. The new tests stub the mark to succeed, so they do not catch this.

@jvsena42jvsena42 mentioned this pull request Sep 2, 2026
2 tasks
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 09f85e6 to 92b10ebCompareSeptember 2, 2026 17:52

@ovitrifovitrif 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.

utACK

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@jvsena42@ovitrif
, '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

feat: add Paykit subscriptions - #1186

Open
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android
Open

feat: add Paykit subscriptions#1186
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #1199, which is stacked on #1178.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Preview

Final Android and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise initial-payment failure and retry and verify the Send sheet remains presented while the first period stays due.
  • Verify Lightning and on-chain subscription success choose purple/orange confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • Full testDevDebugUnitTest suite
  • Focused PaykitPaymentRequestRepoTest, PaykitPaymentRequestRepoSubscriptionTest, SubscriptionsScreenTest, and AppViewModelSendFlowTest
  • compileDevDebugKotlin
  • compileDevDebugAndroidTestKotlin
  • detekt --rerun-tasks
  • arm64 assembleDevDebug, install, and cold launch on API 36 emulator CodexBullTlsUiApi36
  • git diff --check

@greptile-apps

This comment has been minimized.

@jvsena42

Copy link
Copy Markdown
Member

could test the PR stack feature for this case

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from f189535 to a1a7907CompareAugust 28, 2026 13:29
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 2eecc75 to baf9894CompareAugust 28, 2026 14:36
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from 9e4ee27 to 19823e6CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from baf9894 to 5a876f8CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 5a876f8 to bb2f12fCompareAugust 31, 2026 17:53
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-payment-proofs-android to codex/paykit-hardware-payment-proofs-androidAugust 31, 2026 17:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from bb2f12f to 050b32bCompareAugust 31, 2026 17:58
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Done: the PR now uses the stack directly. #1186 is based on the hardware-proof fix #1199, which is based on #1178, so each review contains only its own layer.

@ovitrifovitrif 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.

A few leftovers on this layer:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_contact_timestamp is unused after the payment-request subtitle rewrite.
  • Local due-notification scheduling and beginPaymentRequestWaitingForUpdatedList have no tests that would fail if those paths broke.

Comment threadapp/src/main/java/to/bitkit/services/PaykitSdkService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitSubscription.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
jvsena42
jvsena42 previously requested changes Sep 1, 2026

@jvsena42jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Duplicated component

Image

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 82d6c73 to e1053b0CompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 1cbcc6f to 4cfdf4eCompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e1053b0 to 850c252CompareSeptember 1, 2026 12:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 4cfdf4e to dd53772CompareSeptember 1, 2026 12:54
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

@jvsena42 Fixed in dd53772. The duplicated fiat value came from replacing the subscription review sheet while its content was still composed. The flow now reuses the existing dismiss-delay-present sheet transition and waits for that transition before validating the destination. The focused send-flow regression passes.

@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The duplicated subscription payment UI is fixed in signed commit dd53772. The review sheet now completes its normal dismiss transition before the Send sheet is presented, and the focused send-flow regression covers the sequence. @jvsena42 please re-review the updated head when E2E finishes.

ovitrif
ovitrif previously requested changes Sep 1, 2026

@ovitrifovitrif 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.

prepareHardwareContactPayment marks the on-chain proof started before the hardware device signs, but onHardwareSignCancelled and send-sheet dismiss never call failOnchainPayment. The due request then stays in inFlightRequestIds and a later prepare() fails with OperationInProgress.

Also:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_timestamp is unused after paymentRequestDateTime was removed.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 850c252 to bac8656CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from dd53772 to 9bd7677CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from bac8656 to 6bb8501CompareSeptember 1, 2026 18:19

@ovitrifovitrif 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.

utACK

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from af462ca to 1d50070CompareSeptember 2, 2026 13:22
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 2 times, most recently from b242110 to f36505cCompareSeptember 2, 2026 13:31
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from ddd0195 to d0bf6c2CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from f36505c to 3b32ae0CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from d0bf6c2 to e84d74aCompareSeptember 2, 2026 13:46
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 3b32ae0 to e623010CompareSeptember 2, 2026 13:47
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e84d74a to 35c0b4cCompareSeptember 2, 2026 13:56
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 3 times, most recently from 3e5bab0 to bbce563CompareSeptember 2, 2026 14:15

@ovitrifovitrif 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.

Onchain Paykit payment still fails closed after proof prepare fails: markOnchainPaymentStarted(...).getOrThrow() in beforeSendAttempt (and the hardware onFailure return) still requires the unstarted proof that prepare would have stored. The new tests stub that mark to succeed, so they would not catch this.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

@ovitrifovitrif 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.

On-chain Paykit sends still fail closed when proof prepare fails. proceedWithPayment continues after getOrNull(), but beforeSendAttempt then calls markOnchainPaymentStarted(...).getOrThrow(), and hardware prepareHardwareContactPayment still returns false on that failure. The new tests stub the mark to succeed, so they do not catch this.

@jvsena42jvsena42 mentioned this pull request Sep 2, 2026
2 tasks
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 09f85e6 to 92b10ebCompareSeptember 2, 2026 17:52

@ovitrifovitrif 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.

utACK

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@jvsena42@ovitrif
, '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

feat: add Paykit subscriptions - #1186

Open
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android
Open

feat: add Paykit subscriptions#1186
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #1199, which is stacked on #1178.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Preview

Final Android and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise initial-payment failure and retry and verify the Send sheet remains presented while the first period stays due.
  • Verify Lightning and on-chain subscription success choose purple/orange confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • Full testDevDebugUnitTest suite
  • Focused PaykitPaymentRequestRepoTest, PaykitPaymentRequestRepoSubscriptionTest, SubscriptionsScreenTest, and AppViewModelSendFlowTest
  • compileDevDebugKotlin
  • compileDevDebugAndroidTestKotlin
  • detekt --rerun-tasks
  • arm64 assembleDevDebug, install, and cold launch on API 36 emulator CodexBullTlsUiApi36
  • git diff --check

@greptile-apps

This comment has been minimized.

@jvsena42

Copy link
Copy Markdown
Member

could test the PR stack feature for this case

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from f189535 to a1a7907CompareAugust 28, 2026 13:29
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 2eecc75 to baf9894CompareAugust 28, 2026 14:36
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from 9e4ee27 to 19823e6CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from baf9894 to 5a876f8CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 5a876f8 to bb2f12fCompareAugust 31, 2026 17:53
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-payment-proofs-android to codex/paykit-hardware-payment-proofs-androidAugust 31, 2026 17:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from bb2f12f to 050b32bCompareAugust 31, 2026 17:58
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Done: the PR now uses the stack directly. #1186 is based on the hardware-proof fix #1199, which is based on #1178, so each review contains only its own layer.

@ovitrifovitrif 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.

A few leftovers on this layer:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_contact_timestamp is unused after the payment-request subtitle rewrite.
  • Local due-notification scheduling and beginPaymentRequestWaitingForUpdatedList have no tests that would fail if those paths broke.

Comment threadapp/src/main/java/to/bitkit/services/PaykitSdkService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitSubscription.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
jvsena42
jvsena42 previously requested changes Sep 1, 2026

@jvsena42jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Duplicated component

Image

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 82d6c73 to e1053b0CompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 1cbcc6f to 4cfdf4eCompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e1053b0 to 850c252CompareSeptember 1, 2026 12:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 4cfdf4e to dd53772CompareSeptember 1, 2026 12:54
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

@jvsena42 Fixed in dd53772. The duplicated fiat value came from replacing the subscription review sheet while its content was still composed. The flow now reuses the existing dismiss-delay-present sheet transition and waits for that transition before validating the destination. The focused send-flow regression passes.

@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The duplicated subscription payment UI is fixed in signed commit dd53772. The review sheet now completes its normal dismiss transition before the Send sheet is presented, and the focused send-flow regression covers the sequence. @jvsena42 please re-review the updated head when E2E finishes.

ovitrif
ovitrif previously requested changes Sep 1, 2026

@ovitrifovitrif 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.

prepareHardwareContactPayment marks the on-chain proof started before the hardware device signs, but onHardwareSignCancelled and send-sheet dismiss never call failOnchainPayment. The due request then stays in inFlightRequestIds and a later prepare() fails with OperationInProgress.

Also:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_timestamp is unused after paymentRequestDateTime was removed.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 850c252 to bac8656CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from dd53772 to 9bd7677CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from bac8656 to 6bb8501CompareSeptember 1, 2026 18:19

@ovitrifovitrif 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.

utACK

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from af462ca to 1d50070CompareSeptember 2, 2026 13:22
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 2 times, most recently from b242110 to f36505cCompareSeptember 2, 2026 13:31
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from ddd0195 to d0bf6c2CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from f36505c to 3b32ae0CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from d0bf6c2 to e84d74aCompareSeptember 2, 2026 13:46
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 3b32ae0 to e623010CompareSeptember 2, 2026 13:47
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e84d74a to 35c0b4cCompareSeptember 2, 2026 13:56
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 3 times, most recently from 3e5bab0 to bbce563CompareSeptember 2, 2026 14:15

@ovitrifovitrif 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.

Onchain Paykit payment still fails closed after proof prepare fails: markOnchainPaymentStarted(...).getOrThrow() in beforeSendAttempt (and the hardware onFailure return) still requires the unstarted proof that prepare would have stored. The new tests stub that mark to succeed, so they would not catch this.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

@ovitrifovitrif 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.

On-chain Paykit sends still fail closed when proof prepare fails. proceedWithPayment continues after getOrNull(), but beforeSendAttempt then calls markOnchainPaymentStarted(...).getOrThrow(), and hardware prepareHardwareContactPayment still returns false on that failure. The new tests stub the mark to succeed, so they do not catch this.

@jvsena42jvsena42 mentioned this pull request Sep 2, 2026
2 tasks
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 09f85e6 to 92b10ebCompareSeptember 2, 2026 17:52

@ovitrifovitrif 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.

utACK

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@jvsena42@ovitrif
, '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

feat: add Paykit subscriptions - #1186

Open
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android
Open

feat: add Paykit subscriptions#1186
ben-kaufman wants to merge 11 commits into
codex/paykit-hardware-payment-proofs-androidfrom
codex/paykit-subscriptions-android

Conversation

@ben-kaufman

@ben-kaufmanben-kaufman commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Description

Adds the payer side of Paykit subscriptions, stacked on #1199, which is stacked on #1178.

  • Receives private subscription proposals and lets the payer review and confirm them.
  • Requires an immediately due first period to be paid before showing the subscribed success state; failed or uncertain payments remain due and can be retried.
  • Turns each unpaid billing period into the existing incoming payment-request flow, including automatic presentation, the bell queue, and the Payments tab.
  • Schedules local due-payment notifications and opens the corresponding request when the notification is selected.
  • Adds the Figma-aligned Subscriptions and Payments tabs, subscription detail/status views, cancellation, empty states, and fixed/open-ended summaries.
  • Associates payment proofs with their exact billing period so recurring periods remain independent while retaining private-only resolution and fresh Private Payment List requirements.
  • Keeps subscribe-and-pay inside one continuously presented sheet, including initial-payment failure and retry, without the modal dismissal/reappearance gap.
  • Retains the settled payment rail in completed request and subscription history so Lightning feedback is purple and on-chain feedback is orange, including success confetti.

This PR intentionally covers payer-side receipt only. Subscription creation, Discover, automatic payment without confirmation, and renewal are not included because they are outside this MVP or are not currently exposed by Paykit.

Dependencies:

Preview

Final Android and cross-platform proof recordings were completed locally; they are not attached to the PR.

QA Notes

Manual Tests

  • Receive an immediate-start private subscription proposal and verify review → payment → success stays in one continuously presented sheet.
  • Exercise initial-payment failure and retry and verify the Send sheet remains presented while the first period stays due.
  • Verify Lightning and on-chain subscription success choose purple/orange confetti and matching completed-payment icons.
  • Receive a future-start proposal, trigger its due notification, and open the exact billing-period payment.
  • Dismiss and reopen a due request from the bell queue and Payments tab, then pay it with fresh private payment details.
  • Review active, expired, fixed-term, and open-ended subscription details and cancel an active subscription.

Automated Checks

  • Full testDevDebugUnitTest suite
  • Focused PaykitPaymentRequestRepoTest, PaykitPaymentRequestRepoSubscriptionTest, SubscriptionsScreenTest, and AppViewModelSendFlowTest
  • compileDevDebugKotlin
  • compileDevDebugAndroidTestKotlin
  • detekt --rerun-tasks
  • arm64 assembleDevDebug, install, and cold launch on API 36 emulator CodexBullTlsUiApi36
  • git diff --check

@greptile-apps

This comment has been minimized.

@jvsena42

Copy link
Copy Markdown
Member

could test the PR stack feature for this case

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from f189535 to a1a7907CompareAugust 28, 2026 13:29
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 2eecc75 to baf9894CompareAugust 28, 2026 14:36
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-payment-proofs-android branch from 9e4ee27 to 19823e6CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from baf9894 to 5a876f8CompareAugust 31, 2026 13:10
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 5a876f8 to bb2f12fCompareAugust 31, 2026 17:53
@ben-kaufman
ben-kaufman changed the base branch from codex/paykit-payment-proofs-android to codex/paykit-hardware-payment-proofs-androidAugust 31, 2026 17:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from bb2f12f to 050b32bCompareAugust 31, 2026 17:58
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

Done: the PR now uses the stack directly. #1186 is based on the hardware-proof fix #1199, which is based on #1178, so each review contains only its own layer.

@ovitrifovitrif 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.

A few leftovers on this layer:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_contact_timestamp is unused after the payment-request subtitle rewrite.
  • Local due-notification scheduling and beginPaymentRequestWaitingForUpdatedList have no tests that would fail if those paths broke.

Comment threadapp/src/main/java/to/bitkit/services/PaykitSdkService.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitPaymentProofRepo.kt Outdated
Comment threadapp/src/main/java/to/bitkit/repositories/PaykitSubscription.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
jvsena42
jvsena42 previously requested changes Sep 1, 2026

@jvsena42jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Duplicated component

Image

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 82d6c73 to e1053b0CompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 1cbcc6f to 4cfdf4eCompareSeptember 1, 2026 12:48
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e1053b0 to 850c252CompareSeptember 1, 2026 12:54
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 4cfdf4e to dd53772CompareSeptember 1, 2026 12:54
@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

@jvsena42 Fixed in dd53772. The duplicated fiat value came from replacing the subscription review sheet while its content was still composed. The flow now reuses the existing dismiss-delay-present sheet transition and waits for that transition before validating the destination. The focused send-flow regression passes.

@ben-kaufman

Copy link
Copy Markdown
ContributorAuthor

The duplicated subscription payment UI is fixed in signed commit dd53772. The review sheet now completes its normal dismiss transition before the Send sheet is presented, and the focused send-flow regression covers the sequence. @jvsena42 please re-review the updated head when E2E finishes.

ovitrif
ovitrif previously requested changes Sep 1, 2026

@ovitrifovitrif 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.

prepareHardwareContactPayment marks the on-chain proof started before the hardware device signs, but onHardwareSignCancelled and send-sheet dismiss never call failOnchainPayment. The due request then stays in inFlightRequestIds and a later prepare() fails with OperationInProgress.

Also:

  • Several new Kotlin sites still use inline fully-qualified names where an import would do.
  • wallet__payment_request_timestamp is unused after paymentRequestDateTime was removed.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
Comment threadapp/src/main/java/to/bitkit/ui/screens/subscriptions/SubscriptionsScreen.kt Outdated
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from 850c252 to bac8656CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from dd53772 to 9bd7677CompareSeptember 1, 2026 18:06
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from bac8656 to 6bb8501CompareSeptember 1, 2026 18:19

@ovitrifovitrif 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.

utACK

@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from af462ca to 1d50070CompareSeptember 2, 2026 13:22
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 2 times, most recently from b242110 to f36505cCompareSeptember 2, 2026 13:31
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from ddd0195 to d0bf6c2CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from f36505c to 3b32ae0CompareSeptember 2, 2026 13:39
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from d0bf6c2 to e84d74aCompareSeptember 2, 2026 13:46
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 3b32ae0 to e623010CompareSeptember 2, 2026 13:47
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-hardware-payment-proofs-android branch from e84d74a to 35c0b4cCompareSeptember 2, 2026 13:56
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch 3 times, most recently from 3e5bab0 to bbce563CompareSeptember 2, 2026 14:15

@ovitrifovitrif 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.

Onchain Paykit payment still fails closed after proof prepare fails: markOnchainPaymentStarted(...).getOrThrow() in beforeSendAttempt (and the hardware onFailure return) still requires the unstarted proof that prepare would have stored. The new tests stub that mark to succeed, so they would not catch this.

Comment threadapp/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

@ovitrifovitrif 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.

On-chain Paykit sends still fail closed when proof prepare fails. proceedWithPayment continues after getOrNull(), but beforeSendAttempt then calls markOnchainPaymentStarted(...).getOrThrow(), and hardware prepareHardwareContactPayment still returns false on that failure. The new tests stub the mark to succeed, so they do not catch this.

@jvsena42jvsena42 mentioned this pull request Sep 2, 2026
2 tasks
@ben-kaufman
ben-kaufmanforce-pushed the codex/paykit-subscriptions-android branch from 09f85e6 to 92b10ebCompareSeptember 2, 2026 17:52

@ovitrifovitrif 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.

utACK

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@jvsena42@ovitrif