feat: add Paykit server accounts#1084
Conversation
Greptile SummaryThis PR adds Paykit Server watch-only accounts. The main changes are:
Confidence Score: 5/5No additional blocking issue was found in this follow-up.
|
| Filename | Overview |
|---|---|
| app/src/main/java/to/bitkit/ui/screens/profile/PubkyAuthApprovalViewModel.kt | Adds the watch-only consent and companion-claim authorization flow. |
| app/src/main/java/to/bitkit/repositories/WatchOnlyAccountRepo.kt | Adds account preparation, tracking, activation, cancellation, and restore operations. |
| app/src/main/java/to/bitkit/data/WatchOnlyAccountStore.kt | Adds persistent account, allocation, backup, and reconciliation state. |
| app/src/main/java/to/bitkit/services/LightningService.kt | Adds LDK configuration and reconciliation for watch-only accounts. |
Reviews (3): Last reviewed commit: "fix: derive Paykit Noise key from wallet..." | Re-trigger Greptile
601cdaa to
3e1064d
Compare
dccbfe3 to
f0bfb2e
Compare
32b8c1d to
6782574
Compare
|
Reviewed this against the companion iOS PR and paykit-server (ADR 0001 / 0002 + README). UI gatingSettings → Advanced → Server Accounts is always visible today. Please hide it behind Enable Paykit UI (same pattern as Payment Preferences / other Paykit surfaces), so this unfinished server flow doesn’t show up for default users. How to test / blockerFull happy-path QA needs a real Paykit Server setup Scanner/paste → watch-only consent → authorize → account appears under Server Accounts → external fund of claimed xpub → restart/scan → spend → disable/re-enable tracking. That path isn’t available end-to-end right now: paykit-server is not runnable (README: partial implementation; Questions:
Without that, we can only review code/UI structure + unit coverage; not the live setup → claim → track → fund path. Other notes
CI / mergeMerge conflicts with the base branch ( Happy to re-test once there’s a setup URL path (or staging) and the above are addressed. |
5050c1e to
edb688f
Compare
|
Thanks — the app-side items are now addressed on the latest commit. UI gatingSettings → Advanced → Server Accounts is now only visible when Enable Paykit UI is enabled. Testing the flowReviewers can exercise the Bitkit-side flow using this disposable request: Enable Paykit UI, then paste or scan it. This exercises:
A requester does not need to remain connected: Paykit uploads both relay messages and Bitkit activates the account after both deliveries succeed. From Server Accounts, the reviewer can copy the xpub, derive a nonzero external address, fund it, restart Bitkit, spend the discovered funds, and test disabling/re-enabling tracking. Because the URL contains a public test secret, it should only be used with a disposable regtest wallet. What this does not verify is requester-side polling, decryption, and signature verification of the claim. That still requires a Paykit Server listener or receiver harness. Server stagingThe intended next server-side QA step is to deploy Paykit Server on staging once its runtime/listener composition is implemented. There is no staging endpoint yet, and that work is outside these mobile PRs. Retry and activation behaviorThe post-delivery cases are covered:
This behavior is covered by the repository and approval ViewModel tests. Protocol versionADR 0001's Regression and CIThe branch was rebased onto the latest stacked base and is currently mergeable. The full Android unit suite, Detekt, builds, and all current E2E checks pass, including the staging |
# Conflicts: # app/src/test/java/to/bitkit/repositories/BackupRepoTest.kt # app/src/test/java/to/bitkit/repositories/LightningRepoTest.kt # app/src/test/java/to/bitkit/viewmodels/AppViewModelSendFlowTest.kt
| } | ||
|
|
||
| private fun decodeQueryComponent(value: String): String = | ||
| URLDecoder.decode(value, StandardCharsets.UTF_8) |
There was a problem hiding this comment.
Call requires API level 33 (current min is 28)
| data object AuthorizationAccountMissing : WatchOnlyAccountError() | ||
| data object InvalidAccountName : WatchOnlyAccountError() | ||
| data object InvalidExtendedPublicKey : WatchOnlyAccountError() | ||
| data object NodeUnavailable : WatchOnlyAccountError() |
There was a problem hiding this comment.
nit: it us usually not reommended using data objects or data classes for Throwables, but for this specific use case I see no harm (These carry no per-instance data and are used purely as typed discriminants )


Description
This PR builds on #1066 to add Paykit Server watch-only accounts:
x-bitkit-claim=watch-only-account-v1and the exact/pub/paykit/v0/bitkit/server/:rwcapability, rejecting missing, unknown, duplicate, or mismatched companion parameters.approveAuthWithCompanionClaim, failing closed if companion delivery or normal authorization fails.0.1.0-rc37, LDK Node0.7.0-rc.57, and Bitkit Core0.4.2; Bitkit Core now supplies trusted extended-public-key serialization, so BitcoinJ is no longer required.The relay claim contains only the versioned account index, address type, and serialized xpub. Local names and tracking state are not disclosed. Ordinary Pubky Auth remains unchanged.
References:
QA Notes
This slice implements ADR 0001's
watch-only-account-v1claim, which is the currently agreed protocol. ADR 0002's proposedwatch-only-account-service-v1delegation flow has not been agreed and is not part of the current implementation.Reviewers can exercise the complete Bitkit-side setup and account lifecycle with this disposable test request:
Enable Paykit UI, then scan or paste the URL. It exercises watch-only consent, normal Pubky authorization, account allocation and xpub export, companion-claim delivery followed by AuthToken delivery, local activation, and Server Accounts management. The xpub can be copied from the account details and used for external address derivation, funding, restart discovery, spending, and tracking disable/re-enable testing.
The request secret is public, so this URL must only be used with a disposable regtest wallet. A Paykit Server listener or receiver harness is still required to verify requester-side relay polling, decryption, and signature verification. A staging deployment is intended once Paykit Server runtime/listener composition is available.
Manual Tests
Automated Checks
WatchOnlyAccountClaimCodecTest.ktWatchOnlyAccountStoreTest.ktWatchOnlyAccountRepoTest.ktWatchOnlyAccountLifecycleCoordinatorTest.ktWatchOnlyAccountRestoreTest.ktPubkyAuthApprovalViewModelTest.ktPubkyAuthRequestTest.ktPubkyRepoTest.ktLightningServiceTest.ktPaykitSdkServiceTest.ktPrivatePaykitRepoTest.kt./gradlew testDevDebugUnitTest./gradlew detekt(passes with unrelated existing findings)