Skip to content

feat: transfer to spending from HW wallet#616

Open
jvsena42 wants to merge 36 commits into
masterfrom
feat/hw-transfer-to-spending
Open

feat: transfer to spending from HW wallet#616
jvsena42 wants to merge 36 commits into
masterfrom
feat/hw-transfer-to-spending

Conversation

@jvsena42

@jvsena42 jvsena42 commented Jul 6, 2026

Copy link
Copy Markdown
Member

Refs #589

This PR adds the watch-only Transfer to Spending flow for funding a Lightning channel from a paired Trezor, with the on-chain funding transaction signed on the device. It builds on the connect-hardware flow (#614) and is an iOS port of bitkit-android's transfer-to-spending flow (synonymdev/bitkit-android#1039).

Description

  • Adds the Amount → Sign With Your Device → Transaction Signed flow, entered from the Hardware Wallet detail screen's Transfer To Spending button, then handing off to the existing Funds in Transfer progress screen.
  • Sources the available amount and MAX from the device's native-segwit account balance, minus the LSP fee and a composed on-chain mining-fee reserve, while respecting the LSP receiving-cap limit.
  • Composes the funding transaction, signs it on the Trezor, broadcasts it, then records the actual mining fee, fee rate, and channel on the transfer activity.
  • Confirms the hardware-wallet transfer activity from watcher data without clobbering its existing transfer metadata.
  • Prevents the total balance from double-counting during the paid-order → pending-channel → ready-channel transition by resolving each transfer's channel via its funding transaction.
  • Shows the shared Spending intro before the first hardware transfer, then continues straight to the hardware amount flow on subsequent transfers.
  • Hardens the signing path: reconnects a known Bluetooth device before signing, clears a stale session on a signing timeout, and gives the Trezor Bridge signing call a longer read timeout so on-device confirmation doesn't time out at 30s.
  • Reuses the existing transfer machinery — spending-limit calculation, Blocktank order, channel watcher, and the Funds in Transfer screen — swapping only local signing for on-device signing.

Because iOS is Bluetooth-only in production, the Android USB/Bridge stale-session handling is limited to what the dev/E2E Bridge needs (the longer signing read timeout). The device-signing orchestration is extracted into a small HwFundingSigner collaborator so the transfer view model keeps only the coordination that reuses the shared machinery. v1 funds from the native-segwit account only; multi-address-type spend is out of scope.

QA Notes

OBS: driven on the Trezor Bridge emulator on regtest; please re-verify the full happy path and confirmation on a physical device.

Manual Tests

  • 1. Hardware Wallet detail → Transfer To Spending → Amount: shows TRANSFER TO SPENDING, AVAILABLE from the device balance, and the 25% / MAX / unit-toggle controls.
  • 2. First-ever hardware transfer → Spending intro shows, Continue advances to the hardware Amount flow; subsequent transfers skip the intro.
  • 3. Amount → 25% or MAX → Continue → Sign: a Blocktank order is created and Sign shows the fee grid with the Trezor visual behind the button.
  • 4. Sign → Open Trezor Connect → approve on device: composes, signs, broadcasts, advances to Transaction Signed, then auto-forwards to Funds in Transfer; spending increases and the hardware balance drops by the signed send.
  • 5. MAX with a low LSP receiving cap: AVAILABLE is capped by the receivable amount and the wallet spends only the LSP fee plus the composed mining fee.
  • 6. After the funding tx confirms: the transfer activity confirms from watcher data and shows the actual composed mining fee.
  • 7. regression: Total Balance during paid-order → pending-channel → ready-channel does not double count the transfer amount while the pending channel appears.
  • 8a. BLE reconnect: device unlocked → Open Trezor Connect: silently reconnects, signs, and broadcasts.
    • 8b. on failure → Open Trezor Connect: shows the Reconnect Hardware Device error.
  • 9. Bridge signing: a long device-confirmation pause does not time out before approval (previously failed at 30s).
  • 10. Amount above the limit: input resets to MAX and shows the max-amount error toast.
  • 11a. Sign → Learn More: opens the liquidity info screen.
    • 11b. Sign → Advanced → adjust receiving balance: returns to Sign with updated fees.

Automated Checks

  • Unit tests added: BitkitTests/HwFundingSignerTests.swift (9), BitkitTests/TransferViewModelHwTests.swift (5), BitkitTests/HwWalletManagerFundingTests.swift (4), and shared BitkitTests/HwTransferMocks.swift — cover the fee-reserve math (rate + both fallbacks), the reconnect/compose/sign/timeout orchestration and stale-session cleanup, the view model's error mapping and signing re-entrancy guard, and the native-segwit funding balance + funding-account resolution. 18/18 pass on the iPhone 16 simulator.
  • Build passes: xcodebuild -workspace Bitkit.xcodeproj/project.xcworkspace -scheme Bitkit -configuration Debug -destination 'platform=iOS Simulator,id=<iPhone 16>' ONLY_ACTIVE_ARCH=YES build (concrete simulator UDID + ONLY_ACTIVE_ARCH=YES because the Rust xcframeworks are arm64-only).
  • node scripts/validate-translations.js: 0 errors (run with glob resolved locally, since this checkout has no package.json).
  • SwiftFormat: clean on changed files.
  • No unit tests for the BalanceManager double-count fix or TransferService channel-resolution/activity marking: iOS's LightningService/BlocktankService/CoreService lack the protocol seams Android's repos have, so these are covered by the regtest E2E rather than isolated unit tests.
  • CI: standard build and test checks run by the PR bot.

Linked Issues/Tasks

Screenshot / Video

transfer-emulator.mov
close-channel.mov

@jvsena42 jvsena42 self-assigned this Jul 6, 2026
@jvsena42 jvsena42 added this to the 2.4.0 milestone Jul 6, 2026
@jvsena42 jvsena42 mentioned this pull request Jul 6, 2026
9 tasks
@jvsena42

jvsena42 commented Jul 6, 2026

Copy link
Copy Markdown
Member Author

waiting for upstream branch merge

Base automatically changed from feat/hw-wallet-connect to master July 6, 2026 18:11
@jvsena42 jvsena42 marked this pull request as ready for review July 6, 2026 21:11
@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds the hardware-wallet transfer-to-spending flow. The main changes are:

  • Trezor-backed amount, signing, and signed-confirmation screens.
  • Hardware funding composition, signing, broadcast, and fee metadata.
  • Transfer activity creation and watcher-based confirmation sync.
  • Balance handling for paid orders and pending channels.
  • BLE reconnect and longer Bridge read timeout handling.

Confidence Score: 4/5

This is close, but the broadcast timeout path should be fixed before merging.

  • A delayed Electrum response can still leave a broadcast hardware funding transaction unrecorded.
  • The warning path does not create the transfer row, pending activity, or order watcher.
  • The rest of the reviewed hardware-transfer flow is scoped and uses the existing transfer machinery.

Bitkit/ViewModels/HwFundingSigner.swift and Bitkit/ViewModels/TransferViewModel.swift

Important Files Changed

Filename Overview
Bitkit/ViewModels/HwFundingSigner.swift Adds the hardware signing coordinator and separates broadcast timeout handling, but the uncertain broadcast case still cannot be tracked.
Bitkit/ViewModels/TransferViewModel.swift Adds hardware transfer coordination and records the paid order only after the signer returns successfully.
Bitkit/Services/TransferService.swift Adds helper paths for creating hardware transfer activity and associating the funding transaction with a channel.

Reviews (3): Last reviewed commit: "fix: port android warmup logic and recon..." | Re-trigger Greptile

Comment thread Bitkit/Views/Transfer/Hardware/SpendingAmountHw.swift
Comment thread Bitkit/ViewModels/HwFundingSigner.swift Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 102f858661

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Bitkit/Views/Transfer/Hardware/SpendingAmountHw.swift
Comment thread Bitkit/Views/Transfer/Hardware/SpendingAmountHw.swift Outdated
@jvsena42 jvsena42 enabled auto-merge July 7, 2026 09:17
@piotr-iohk

This comment was marked as outdated.

@jvsena42 jvsena42 marked this pull request as draft July 7, 2026 11:05
auto-merge was automatically disabled July 7, 2026 11:05

Pull request was converted to draft

@jvsena42

jvsena42 commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

draft for implement fixes

@jvsena42 jvsena42 marked this pull request as ready for review July 7, 2026 11:16

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e293b4920e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Bitkit/Views/Transfer/Hardware/SpendingAmountHw.swift Outdated
Comment thread Bitkit/Views/Transfer/Hardware/SpendingHwSign.swift
Comment thread Bitkit/ViewModels/TransferViewModel.swift
Comment thread Bitkit/Managers/BalanceManager.swift
@jvsena42 jvsena42 marked this pull request as draft July 7, 2026 12:01
@jvsena42

jvsena42 commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

draft for check comments

@jvsena42 jvsena42 marked this pull request as ready for review July 7, 2026 16:12
Comment thread Bitkit/ViewModels/HwFundingSigner.swift

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1d13e31089

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Bitkit/Managers/TrezorManager.swift
Comment thread Bitkit/Views/Transfer/Hardware/SpendingHwSign.swift Outdated
@jvsena42 jvsena42 requested a review from piotr-iohk July 7, 2026 16:44
@jvsena42

jvsena42 commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

code re-checked and video updated

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.

2 participants