feat: add boltz savings swap#1081
Conversation
cd6afdc to
45fce11
Compare
Greptile SummaryThis PR adds a Boltz reverse-swap path for moving Lightning funds into on-chain savings. The main changes are:
Confidence Score: 5/5This looks safe to merge.
|
| Filename | Overview |
|---|---|
| app/src/main/java/to/bitkit/viewmodels/TransferViewModel.kt | Owns swap execution beyond the screen lifecycle, prevents concurrent starts, cancels stale quote requests, and subscribes before invoice payment. |
| app/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt | Starts claim event collection before the update stream, retries stream startup, and stops updates with the wallet lifecycle. |
| app/src/main/java/to/bitkit/ui/screens/transfer/SavingsProgressScreen.kt | Observes swap outcomes and displays pending claims as settling rather than completed. |
| app/src/main/java/to/bitkit/ui/screens/transfer/SavingsConfirmScreen.kt | Adds swap quotes, amount controls, fee details, and channel-close fallback behavior. |
| app/src/main/java/to/bitkit/services/BoltzService.kt | Wraps Boltz swap creation, queries, claims, refunds, and lifecycle event streaming. |
Reviews (2): Last reviewed commit: "fix: fall back to close when swap amount..." | Re-trigger Greptile
Fixed the failing E2E shardsTwo shards were failing deterministically on every run of this branch, and both were caused by this PR:
Both perform the same steps and then time out waiting for Root cause. bitkit-core resolves the Boltz regtest API to That left if (!amountTooLow && quote == null) return@SwipeToConfirmso the swipe became a silent no-op. The failure screenshots confirm it: the GRAB circle is latched at the far right, the "close channel instead" button is visible, and there is no coop-close attempt anywhere in the log after the swipe. On Why not fix it in the E2E repo. These specs assert post-transfer state only a channel close can produce: Fix, in 4fea1ad:
The raw Tests added in Corrections to earlier replies in this thread
Known limitation, not addressed hereThe swap is sized from |
# Conflicts: # app/src/test/java/to/bitkit/viewmodels/TransferViewModelTest.kt
|
We could run a Boltz instance in dev env in the future for better testing |
Agreed. For now I've been using mainnet for testing which will not be ideal long term. |

This PR adds a swap-based path for transferring spending balance to savings, so Lightning funds can move on-chain through a Boltz reverse swap instead of only by closing a channel.
Description
Preview
QA Notes
Manual Tests (swap path is mainnet only)
regression:Savings Confirm → Close channel instead: falls back to the channel-close path.regression:Start the app with a pending swap: swap resumes and balance updates once it lands on-chain.regression:On a regtest or testnet build, Transfer to Savings: confirm screen shows no quote, fees, slider, or "close channel instead", and the swipe closes the channel as before.regression:After a swap fails, start a second transfer to savings in the same session: the second attempt runs normally instead of bouncing back to the transfer root.Automated Checks
TransferViewModelTest.kt.SwapsViewModelTest.kt.WalletViewModelTest.kt.compileDevDebugKotlin,testDevDebugUnitTest, anddetektall pass.