Skip to content

feat: add boltz savings swap#1081

Open
coreyphillips wants to merge 11 commits into
masterfrom
feat/savings-swap
Open

feat: add boltz savings swap#1081
coreyphillips wants to merge 11 commits into
masterfrom
feat/savings-swap

Conversation

@coreyphillips

@coreyphillips coreyphillips commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

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

  • Adds a Boltz reverse swap flow to the transfer-to-savings journey. The confirm screen now shows a live quote (amount to savings, network fee, service fee, and the amount you will receive) and lets the user proceed with a swap or fall back to closing the channel.
  • Guards against amounts that are too low to swap, holding back a small reserve for Lightning routing fees and surfacing a clear message when the amount cannot be transferred.
  • Waits for the on-chain claim during the progress step and resumes any pending swaps when the wallet starts, refreshing balances automatically once a swap lands on-chain. The updates stream now also stops with the node when the app goes to background.
  • Adds a Swaps section under Dev Settings to list swaps and claim a reverse swap, backed by a new service that wraps the Boltz module. The manual claim button only shows while the swap is actually claimable (lockup on-chain and no claim broadcast yet).
  • Adds a reusable slider component used by the swap amount controls.
  • Bumps bitkit-core to 0.5.1, which introduces the Boltz module this flow depends on.

Preview

QA Notes

Manual Tests (Must use mainnet for now)

  • 1. With a spending balance, Transfer to Savings → Savings Confirm: quote shows amount to savings, network fee, service fee, and you'll receive.
  • 2. Savings Confirm → change amount: quote recomputes for the new amount.
  • 3. Savings Confirm → set an amount below the swap minimum: amount-too-low message shows and confirm is blocked.
  • 4a. Savings Confirm → confirm swap → Savings Progress: completes after the on-chain claim.
    • 4b. After claim: savings balance reflects the swapped funds without a manual sync.
  • 5. regression: Savings Confirm → Close channel instead: falls back to the channel-close path.
  • 6. regression: Start the app with a pending swap: swap resumes and balance updates once it lands on-chain.
  • 7a. Dev Settings → Swaps → tap a swap → Swap Detail: Claim now shows only for an unclaimed reverse swap with its lockup in mempool or confirmed.
    • 7b. Swap Detail of a created, expired, refunded, or claimed swap: no Claim button.

Automated Checks

  • Unit tests added: savings swap quote limits, slider clamping, swap execution outcomes (claimed, error, timeout, payment failure), and that a second start is ignored while a swap is in flight, in TransferViewModelTest.kt.
  • Unit tests added: claimable status gating, swap list sorting, and manual claim in SwapsViewModelTest.kt.
  • Unit tests modified: inject the new Boltz service dependency into the wallet view model setup in WalletViewModelTest.kt.
  • Ran locally against bitkit-core 0.5.1: compileDevDebugKotlin, testDevDebugUnitTest, and detekt all pass.

Comment thread app/src/main/java/to/bitkit/services/BoltzService.kt Fixed
@coreyphillips
coreyphillips marked this pull request as ready for review July 16, 2026 12:58
@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a Boltz reverse-swap path for moving Lightning funds into on-chain savings. The main changes are:

  • Live swap quotes, fee details, and adjustable transfer amounts.
  • Background swap execution, claim tracking, and pending-swap recovery.
  • A settling state for swaps whose claims have not landed yet.
  • Developer screens for listing and manually claiming swaps.
  • A reusable amount slider and the required bitkit-core update.

Confidence Score: 5/5

This looks safe to merge.

  • The latest changes address the event subscription and screen lifecycle races.
  • Swap update startup now retries, and claim events trigger balance refreshes.
  • Pending claims are shown as settling instead of completed.
  • No blocking issue was found in the updated code.

Important Files Changed

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

Comment thread app/src/main/java/to/bitkit/ui/screens/transfer/SavingsProgressScreen.kt Outdated
Comment thread app/src/main/java/to/bitkit/viewmodels/TransferViewModel.kt Outdated
Comment thread app/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt Outdated
Comment thread app/src/main/java/to/bitkit/viewmodels/TransferViewModel.kt
Comment thread app/src/main/java/to/bitkit/viewmodels/WalletViewModel.kt
@coreyphillips
coreyphillips requested a review from piotr-iohk July 20, 2026 15:14
@piotr-iohk
piotr-iohk marked this pull request as draft July 21, 2026 06:09
@piotr-iohk
piotr-iohk marked this pull request as ready for review July 21, 2026 06:09
Sign up for free to 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