Repository navigation
Conversation
|
Pushed
|
|
Pushed
|
|
Pushed |
Rebuilt on the split Spark head; carries the Pubky Swaps route (#1732) as it was merged into this branch.
# Conflicts: # app/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
Restore passes the Lightning payments the node sent, so bitkit-core checks each listed lockup against what was paid, and drives the swaps already on record too.
Regtest APKDownload bitkit-dev-debug universal APK (expires in 30 days). |
jvsena42
left a comment
There was a problem hiding this comment.
Delta review of 490bdb4: no findings, and both my LOWs are fixed.
- A swap that fails before its hold payment goes out now lands on the error screen with Retry from Amount, matching iOS.
- The claim poll runs on the repo's app scope.
The device gate (J1/J2 with the pubky-swap provider) is still pending.
Reviewer model: Claude Opus 5.5 (claude-opus-5-5)
Reasoning effort: not exposed
jvsena42
left a comment
There was a problem hiding this comment.
Delta review of 19f575c: no findings. A swap refused before its hold payment goes out now releases the contact's private payment list for ordinary contact sends too. The old helper only released it for requests. Nothing was paid to that address, so a retry can reuse the list.
The device gate is still pending.
Reviewer model: Claude Opus 5.5 (claude-opus-5-5)
Reasoning effort: not exposed
jvsena42
left a comment
There was a problem hiding this comment.
Delta review of cd13b13 (bitkit-core 0.8.0-swaps.9 → 0.8.0-swaps.11): no findings. This matches iOS #1170.
- The new core refuses a swap whose id is already saved. That happens in
commit_routebefore the hold invoice is paid, so it lands on the "refused commit → Retry from Amount" path from 490bdb4. SwapRecordis unchanged and the swap FFI signatures are unchanged.- The wake API changes in core don't touch any app call site.
The device gate is still pending.
Reviewer model: Claude Opus 5.5 (claude-opus-5-5)
Reasoning effort: not exposed
|
@coreyphillips I dismissed your two changes requests, because every blocking point in them is fixed in commits on this PR, and your later reviews mark those points as addressed. The dismissal messages name the commits. The non-blocking items are tracked:
Please review cd13b13 when you can. |
ben-kaufman
left a comment
There was a problem hiding this comment.
This approval covers source review of the opt-in regtest Debug scope under the one-device assumption. The early hold-failure private-list retry remains deferred to #1837 alongside the existing retry deferrals. J1/J2 and local app checks were not run at this head, so integrated-feature and release readiness remain unverified.
Reviewer model: gpt-6.1-sol, claude-opus-5-5
Reasoning effort: gpt-6.1-sol xhigh, claude-opus-5-5 high
|
@ovitrif this conflicts with |
# Conflicts: # gradle/libs.versions.toml
|
@jvsena42 merged |
rc14 adds an optional auth argument to the regtest calls with no Kotlin default; pass null to keep today's unauthenticated calls.
# Conflicts: # app/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt # app/src/test/java/to/bitkit/ui/WalletViewModelTest.kt # gradle/libs.versions.toml
|
Moved bitkit-core from the Then merged |
jvsena42
left a comment
There was a problem hiding this comment.
Delta review of the rebase onto master (7c56d7a9c, 46948b65b) and 9a7eebeb3 (bitkit-core 0.8.0-rc14): one LOW, inline.
- Core:
0.8.0-swaps.11is an ancestor of rc14, andpubky_swapsandpaykit_routeare identical between them.9a7eebeb3only addsauth = nullto the four regtest calls. - Route types:
PubkySwapsRouteRepo.kt:83-91sets all sevenPaykitRouteRequestfields, andAppViewModel.kt:4715-4737handles all fourPaykitRoutecases. - Merges: the conflicts are in
libs.versions.toml(rc14 plus master'sbreez-sdk-sparkand paykit rc7) and theWalletViewModelconstructor, which keeps bothpubkySwapsRouteRepoandsparkRepo. The swap files are byte-identical tocd13b132. - The LOW: Spark arriving from master now reaches the hold payment (inline). A restore also matches lockups only against node payments (
PubkySwapsRouteRepo.kt:123-124), so a Spark-paid swap left mid-flight refunds instead of being claimed. That loses nothing, so I'm not raising it separately.
The LOW can be fixed here or moved to a follow-up issue, your choice; please say which on the thread.
coreyphillips/pubky-swap f45e204) against bitkit-docker's LND and the marketplace stack. CI: build, build-and-test, lint, detekt, compose-ui and five e2e shards pass; two shards were still running.
Reviewer model: Claude Fable 5.2 (claude-fable-5-2), Claude Opus 5.5 (claude-opus-5-5)
Reasoning effort: not exposed
|
@ovitrif this conflicts with |
# Conflicts: # gradle/libs.versions.toml
# Conflicts: # app/build.gradle.kts # app/src/main/java/to/bitkit/services/CoreService.kt
|
@jvsena42 merged |
jvsena42
left a comment
There was a problem hiding this comment.
Delta review of c22b8f6ed and the master merges c866eb5dc/098c35550: my LOW is fixed (confirmed on the thread), and nothing new.
098c35550 resolves its two conflicts correctly. build.gradle.kts keeps the swap BuildConfig fields (PUBKY_SWAPS_ROUTES, PUBKY_SWAPS_PROVIDERS) and master's BLOCKTANK_REGTEST_AUTH. The four regtest calls in CoreService.kt take master's auth = Env.blocktankRegtestAuth instead of the branch's auth = null. c866eb5dc only resolves libs.versions.toml.
coreyphillips/pubky-swap f45e204) against bitkit-docker's LND and the marketplace stack.
Reviewer model: Claude Opus 5.5 (claude-opus-5-5)
Reasoning effort: not exposed
Closes #1826
Dependency: synonymdev/bitkit-core#182
Refs:
Description
PUBKY_SWAPS_PROVIDERSadds extra candidates for testing.paykit-cap.*and refuses a reply not signed by the provider's key or the key its records delegate to.Route: Pubky Swaps · <provider>, with the whole swap cost in the fee row.PUBKY_SWAPS_ROUTES=trueon regtest debug builds only.Builds against the bitkit-core release
0.8.0-rc14, which includes synonymdev/bitkit-core#182. The router lets services such as Spark compete with the providers as route legs; this PR passes none, and the Spark leg comes in #1754.Why this journey
What it needs to ship
swap/1in Paykit: the signedpaykit-cap.*negotiation runs over iroh; over Paykit Encrypted Links it needs the additive paykit-rs SDK API for extension kinds (Design review: Paykit Capabilities, a general capability and intent layer for Paykit peers (answers Paykit Intents question 8) pubky/paykit-rs#229, §17).Out of Scope
Design
N/A — no design available.
Preview
A wallet with only a spending balance pays a contact who accepts only on-chain bitcoin. The router finds a Pubky Swaps provider among the wallet's contacts, the confirm screen shows the route, the quote and contract are signed, and the contact receives exactly 20,000 sats on chain (Android emulator (API 35), 2x speed, regtest).
android-signed-swaps-route-2x.mp4
After a wallet restore from the seed, the swap the wallet left in flight before its claim is found at its provider and claimed to Savings, with the "Payment returned to Savings" notice (Android emulator (API 35), 2x speed, regtest; the phrase entry is not recorded). Recorded on bitkit-core
0.8.0-swaps.4, before restores took the node's payments.android-restore-j2c2x.mp4
QA Notes
Setup
main:docker compose up -d, then./pubky-marketplace upand./pubky-marketplace seed, thendocker compose --profile marketplace --profile payment-requests up -d --no-build fixture-issuer rc56-peeranddocker compose --profile lnurl-pay up -d --build --wait lnurl-server-fixture. A long-lived regtest chain can reach a block subsidy of 0, so start from a freshbitcoin_homevolume (docker compose down, remove the volume and./lnd,./lnurl-server/data) and fund with./bitcoin-cli fund.f45e204,cargo build --release -p swap-provider --features full. Run it on the project's LND with a throwaway BIP39 phrase inPUBKY_SWAP_RECOVERY_PHRASE__FILE:swap-provider --network regtest --directions submarine,reverse --min-amount 10000 --max-amount 1000000 --base-fee 100 --fee-ppm 2500 --confirmations 1 --wallet lnd --lnd-address https://127.0.0.1:23009 --lnd-cert <bitkit-docker>/lnd/tls.cert --lnd-macaroon <bitkit-docker>/lnd/data/chain/bitcoin/regtest/admin.macaroon --electrum-url tcp://127.0.0.1:60001 --data-dir <dir> --no-homeserver. Fund the LND on chain and mine six blocks. It prints its pubky on start, and signs with that key.E2E=true E2E_BACKEND=local E2E_LOCAL_HOST=127.0.0.1 E2E_HOMESERVER_PUBKY=$(./pubky-marketplace info | jq -r .homeserver_z32) PUBKY_SWAPS_ROUTES=true ./gradlew assembleDevDebug. Before first launch,adb reverse6286, 6287, 6288, 15411, 15412, 60001, 23735, 23000 and 23010.curl -H 'Host: 127.0.0.1:23010' 127.0.0.1:23010/generate/channel(500,000 sats to spending); leave savings empty; create a Pubky profile; save the provider's pubky and the fixture-issuer's pubky as contacts.fixture-issuer(curl 127.0.0.1:23012/healthgives its pubky), which publishes onlybtc-regtest-p2wpkh.Journeys
paykit-swap-route.xml— a spending-only wallet pays an on-chain-only contact through a Pubky Swaps provider found among its contacts, and the contact receives exactly 20,000 satspaykit-swap-restore.xml— a swap route left in flight before its claim is finished after a wipe and a restore from the recovery phrase: claimed to Savings, with the "Payment returned to Savings" noticeManual Tests
N/A
Automated Checks
AppViewModelSendFlowTest.kt— the routed send: it finishes once, as the hold payment's success, and tags the hold payment; quote, hold-payment and claim failures, and a hold-payment failure event ending the wait; a Direct answer moving to Savings; quotes from a replaced send or wallet dropped; Spending selectable for a swap-routed contact; the endpoint's method id matching its address; a stale amount or fee after edits; a late claim or failure after dismissal leaving the next send alone; a failed payment retrying from the amount with a fresh quotePubkySwapsRouteRepoTest.kt— the claim wait finishes on broadcast, retries a failed advance, and keeps advancing a swap whose wait ran outWalletViewModelTest.kt— swap restore after a wallet restore, with the restore's failed categories; swaps already on record driven without the Savings noticedetektandtestDevDebugUnitTestforWalletViewModelTest,AppViewModel*andPubkySwaps*at4b8c8df: passEvidence
9f6ec3bon a regtest emulator (API 35), bitkit-core0.8.0-swaps.9, provider coreyphillips/pubky-swapf45e204with--no-homeserver, and noPUBKY_SWAPS_PROVIDERS, so the provider came only from the wallet's contacts (the recording above):Route: Pubky Swaps · pubky…fez6yand a fee of ₿ 986 for 20,000 sats;hold invoice accepted,HTLC funded; awaiting client claimand, after one block,client claimed; hold invoice settled;d953772e4480f719bbf843f6df2015dd7befab453ef8d1944398f07c2abdb6c6, has one input, the provider's HTLC, and one output of exactly 0.0002 BTC to the contact's address.master, tracked in bug: saved contact payment stalls instead of failing #1827.257190c, bitkit-core0.8.0-swaps.4, provider coreyphillips/pubky-swapmainwith--no-homeserver:2d3aa3d…b577) had one input, the provider's lockup, and one output of exactly 0.0002 BTC to the wallet's own address. That take also showed the notice hidden under the "Received Bitcoin" sheet the claim opens, so it now stays until dismissed (257190c).PUBKY_SWAPS_PROVIDERSto the provider, in case contacts had not reloaded when the restore ran; they had, and the provider was also among them.46ad2a9, before quotes were signed on a regtest emulator (Android 15), with feat: pubky swaps as paykit route bitkit-core#182 at3fd9e9dand noPUBKY_SWAPS_PROVIDERS, so the provider came only from the wallet's contacts (the recording above):Route: Pubky Swaps · pubky…mpquoand a fee of ₿ 986 for 20,000 sats;hold invoice accepted,HTLC funded; awaiting client claimand, after one block,client claimed; hold invoice settled;PUBKY_SWAPS_PROVIDERS, paid the same way.Gaps
0.8.0-swaps.9, whose restore takes the node's payments.Models used
claude-opus-5-5(reasoning:medium),claude-sonnet(reasoning: Not exposed)claude-opus-5-5(reasoning:medium)Metadata note: the Sonnet entry is the research subagent that read pubky-swap and Bitkit's Paykit code; its exact model version is not exposed in this session's records.