feat: home-screen hardware wallet (watch-only)#605
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bae69fd746
ℹ️ 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".
…calls. improved eficiency caching wallet Ids and comparing merged activities before notify activity changes
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5777dbbb4e
ℹ️ 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".
Observations from initial testingInitial observations (Trezor Safe 7, regtest + iPhone 13)Logs: bitkit_logs_2026-06-25_14-26-56.zip Test address (regtest native segwit): 1. first connect (problematic) — logs ~13:41 UTC ❌
2. recovery ✅
3. follow-up retest ✅
Follow-up suggestion (non-blocking):
In general the watch-only path works once xpub capture completes cleanly (4/4). First connect with 3/4 xpubs left Home at 0 despite the watcher starting. Other observations:
|
Agreed, I can move it on the last polish PR |
Follow-up (non-blocking): watch-only first-sync latency — balance & activities take a few seconds to appear after connectWhile re-testing on HEAD against the Trezor Bridge emulator, the hardware balance — and the device's activities — took several seconds to appear after a successful connect. Traced it in the session log:
Root cause: connect + xpub capture complete in ~70 ms; the lag is entirely
So "balance took a while" and "activities took a while" are the same first-sync latency — not a correctness issue, and distinct from the earlier 0-balance report (where the watcher started but never reported). Note this was over Bridge with only Suggested follow-up (app-side): show a loading state (spinner/skeleton) on the hardware row + activity placeholders while a device's first watcher sync is in flight, instead of a bare |
Fixed in 4d788bd |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 14566f6550
ℹ️ 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".
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
…se syncWatcher check logic
…sPinVerified) to reconnect on unlock so the pairing-code sheet can present.

This PR:
TrezorManagerfrom theTrezorViewModelgod object, adds a fully decoupledHwWalletManager, and splits the device-less on-chain calls out ofTrezorServiceinto a vendor-neutralOnChainHwService.Description
Brings the first slice of the Trezor hardware-wallet epic to the wallet home screen. A paired Trezor now shows as a watch-only balance: a device row under the Savings/Spending tiles, its sats folded into the headline total, and its on-chain transactions merged into the activity lists with a blue icon. Users with no paired device see a new Hardware suggestion card that opens an intro sheet, and a one-time pairing code is handled by an app-wide Pair Device sheet.
How it works: on connect, each device's account xpubs are captured and persisted. The watch-only layer then runs one on-chain xpub watcher per device and enabled address type, aggregates the per-device balance in memory, and persists each device's activity into bitkit-core scoped by a derived wallet id — so balances and activity stay available while the device is disconnected, and the activity lists merge hardware transactions through the normal pipeline. The same physical device re-paired is de-duplicated by its xpubs into a single tile.
Scope notes:
wallet_idto every activity. This migrates the whole app (not just hardware) to pass a wallet id through the activity APIs; the normal wallet uses the core default.deriveWalletId— the canonical cross-platform derivation finalized in core 0.3.4 — so iOS and Android produce identical ids for the same device.TrezorViewModelinto aTrezorManager, and the watch-onlyHwWalletManageris driven purely by the composition root (no manager-to-manager or service-to-viewmodel coupling). The device-less on-chain surface — Electrum account/address info, tx history/detail, compose, broadcast, and the xpub watcher — was also split out ofTrezorServiceinto a vendor-neutralOnChainHwServicebehind anOnChainWatcherServicingprotocol.HwWalletManagernow depends on no Trezor-named type;TrezorServiceis reduced to Trezor device FFI (connect, sign, on-device address/pubkey, credentials).Linked Issues/Tasks
Ports synonymdev/bitkit-android#999.
Related to #589
QA Notes
Trezor Emulator Setup
Test against the Trezor emulator from bitkit-docker:
--recurse-submodules, thendocker compose up -dand./scripts/trezor-emulator start.TREZOR_BRIDGE=trueTREZOR_BRIDGE_URL=http://127.0.0.1:21325TEST_TREZOR_EMU— that flag boots the standalone dev/test harness and bypasses the wallet.Manual Tests
regression:open Receive and other large sheets, and the normal on-chain/LN activity list and detail behave as before (wallet-scoped activity migration).Automated Checks
BitkitTests/HwWalletManagerTests.swift(aggregation, xpub dedup, displayName, merge-by-txid, received-tx detection, monitored-type filtering, watcher params, saturating total, stale-watcher, removeDevice, resetState),BitkitTests/HwWalletIdTests.swift,BitkitTests/HwAddressTypeTests.swift,BitkitTests/ActivityHardwareTests.swift.BitkitTests/TrezorViewModelWatcherTests.swiftretargeted toTrezorManagerafter the extraction; theMockWatcherServicemocks inTrezorViewModelWatcherTestsandHwWalletManagerTestsnow conform to the newOnChainWatcherServicingprotocol.BitkitTestssuite — 553/556 pass; the 3 failures are pre-existingAddressTypeIntegrationTestscases that hit the live Blocktank regtest deposit API (HTTP 404), unrelated to this change.swiftformat --lint,scripts/validate-translations.js, and a Debug build (iPhone 16 simulator) are clean.Screenshot / Video
connect-and-disconnect.mov