Skip to content

feat: hardware wallets settings screen#612

Merged
jvsena42 merged 17 commits into
masterfrom
feat/hw-wallet-settings
Jul 2, 2026
Merged

feat: hardware wallets settings screen#612
jvsena42 merged 17 commits into
masterfrom
feat/hw-wallet-settings

Conversation

@jvsena42

@jvsena42 jvsena42 commented Jun 29, 2026

Copy link
Copy Markdown
Member

Part of #589

This PR adds a Hardware Wallets settings screen for viewing and managing paired devices, reachable from Settings ▸ General ▸ Payments.

Description

  • Adds a "Hardware Wallets" row to Settings ▸ General ▸ Payments whose value shows the paired-device count and opens the new screen.
  • Adds the Hardware Wallets settings screen: a list of paired devices (connection badge that turns green when connected, device name, ₿ balance) each with a per-row delete, plus an "Add Hardware Wallet" button that opens the existing hardware intro flow.
  • Tapping a device's name opens a Rename Hardware Wallet sheet (NAME field pre-filled + Save); the custom name persists per device, is shared across an xpub group, and flows back into the device's display name everywhere (settings list, Home tile, detail screen).
  • The trailing trash icon removes the device after the shared "funds are safe" confirmation, which stops its watchers, deletes its stored activity, and forgets every paired entry, so its row and the settings count update.
  • Shows an intro-style empty state (the same staggered device hero, accent headline, and copy as the hardware intro sheet) when no devices are paired.

This is the iOS port of synonymdev/bitkit-android#1032. iOS already had the watch-only data layer and shared components (HwWalletManager, the connection badge, the device illustrations, and the hardware intro sheet), so this PR is mainly the settings row, the new list screen, and the rename sheet, laid out to match the Figma frames. Renaming adds a persisted customLabel to the stored device that takes priority when resolving the display name.

Linked Issues/Tasks

Screenshot / Video

reconnect-with-custom-name.mov
delete-flow.mov

QA Notes

OBS: Only tested with emulator

Manual Tests

  • 1. Settings → General → Payments: "Hardware Wallets" row shows with the device icon and the paired-device count.
  • 2. Settings → Hardware Wallets (paired): each device shows a connection badge (green when connected), white name, ₿ balance and a trash icon.
  • 3a. Hardware Wallets → tap a device's name → Rename sheet opens with the current name pre-filled → edit → Save: the row name updates.
    • 3b. Home tile and Hardware Wallet detail show the new name; relaunch the app: the name persists.
    • 3c. Rename → clear the field: Save is disabled (empty name not allowed).
  • 4a. Hardware Wallets → tap a device's trash → confirm dialog (funds-safe copy) → Cancel: device stays listed.
    • 4b. tap trash → Remove: the device is removed and the Settings "Hardware Wallets" count decrements.
  • 5. No paired devices → Hardware Wallets: intro-style empty state (device hero + accent headline) and the Add button are shown.
  • 6. Hardware Wallets → tap Add Hardware Wallet: the hardware intro sheet opens.
  • 7. regression: Home hardware tile still shows the green/gray connection glyph (shared icon unchanged).

Automated Checks

  • 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.
  • Unit tests added: BitkitTests/HwWalletNameTests now asserts the customLabel override in resolveHwWalletName (custom name wins; empty falls back to label; nil falls back to the prefixed model) — 9 tests pass.
  • No tests added for the screen itself: it is SwiftUI view orchestration over the already-tested HwWalletManager.removeDevice and TrezorManager.forgetDevice; existing BitkitTests/HwWalletManagerTests still cover removal.
  • CI: standard build and test checks run by the PR bot.

@jvsena42 jvsena42 self-assigned this Jun 29, 2026
@jvsena42 jvsena42 added this to the 2.4.0 milestone Jun 29, 2026
@jvsena42 jvsena42 mentioned this pull request Jun 29, 2026
7 tasks
@piotr-iohk

Copy link
Copy Markdown
Collaborator

Observations from testing

Testing observations (Trezor Safe 7, regtest + iPhone 13, #612 on latest HEAD, stacked on #611)

Logs:
bitkit_logs_2026-07-01_09-56-56.zip

Ran through the #612 QA checklist: Settings → Hardware Wallets row + count, device list (badge, rename, delete), empty state / Add flow, rename validation, disconnect/remove from settings, reconnect from dev Trezor screen. All listed manual tests pass.


QA checklist coverage

Test Result
1. Settings → General → Payments → Hardware Wallets row + count
2. Hardware Wallets list: badge, name, balance, trash
3a–c. Rename (incl. long name, empty → Save disabled, persists)
4a. Remove → Cancel → device stays
4b. Remove → confirm → row gone, count decrements
5. Empty state + Add button ✅ (exercised during remove/reconnect flows)
6. Add Hardware Wallet → intro sheet
7. Home tile green/grey glyph regression ✅ (glyph works; placement — see §1)

1. Home connection icon placement vs Figma ❌ (non-blocking)

Screenshot: on Home, the green BLE glyph sits next to the balance, but Figma has it next to the device name.
Screenshot 2026-06-30 at 14 34 00

Settings → Hardware Wallets list is correct (badge left of name — matches Android settings row).

Parity note: Android Home uses WalletBalanceView titleTrailing — icon on the name row. iOS HardwareWalletsGrid puts HwWalletConnectionIcon on the amount row (#605 layout). So this is an iOS Home vs Android/Figma gap, not introduced by #612. Worth fixing in a small follow-up (could be #613 or a quick layout tweak on the shared home cell).


2. Rename length cap ✅ (matches Android)

Long rename in logs (Trezor Safe 7 vvvb…) persisted at exactly 50 characters. iOS TrezorManager.deviceLabelMaxLength = 50; Android setDeviceLabel caps at 50 (HwWalletRepoTest). Trim + cap behaviour aligns.

Android parity: post-pair rename from Hardware Wallets settings is iOS-only in this PR (design added after Android #1032). Tracked on Android as bitkit-android#1056 (epic #998 subtask 10).


Follow-up tracking

  • §1 Home icon placement: fix here or track in #613.
  • Android rename from Settings: bitkit-android#1056 (epic #998). - rename design was added after Andorid initial implementation, added speparate ticket to implement it.

Overall: #612 settings screen, rename, and remove flows look good — approve once stacked on #611. Non-blocking follow-ups: Home icon placement (Figma/Android parity); Android settings rename UI (#1056).

@jvsena42

jvsena42 commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

Home icon placement tracked in #613

@jvsena42 jvsena42 marked this pull request as ready for review July 1, 2026 11:05
@greptile-apps

This comment was marked as 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: 5581bac490

ℹ️ 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/Services/Trezor/TrezorBLEManager.swift
Comment thread Bitkit/Services/Trezor/TrezorKnownDeviceStorage.swift
@jvsena42 jvsena42 marked this pull request as draft July 1, 2026 12:34
@jvsena42

This comment was marked as outdated.

Base automatically changed from feat/hw-wallet-activity to master July 1, 2026 13:45
@jvsena42

jvsena42 commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

Previews updated

…onnectOnce, so a reused BLE path can never carry a leaked suppression marker into a new session
@jvsena42 jvsena42 marked this pull request as ready for review July 2, 2026 11:48
Comment thread Bitkit/Views/Sheets/RenameHardwareWalletSheet.swift
@jvsena42

jvsena42 commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

self-review finished, waiting for CI

@jvsena42 jvsena42 requested a review from piotr-iohk July 2, 2026 14:02
@piotr-iohk

Copy link
Copy Markdown
Collaborator

Retest on latest HEAD (Trezor Safe 7, iPhone 13, regtest). Logs attached:
bitkit_logs_2026-07-02_13-37-36.zip

Verdict: approve ✅

Settings / rename / remove flows look good. The reconnect-indicator detection work in this PR (External disconnect → grey badge) behaves correctly. Full reconnect recovery is still flaky — fine to track in #613, not a blocker here.


Settings QA (#612 scope)

Test Result
General → Payments → Hardware Wallets row + count
Device list (badge, name, balance, trash)
Rename (long name, empty → Save disabled, persists)
Remove → Cancel / confirm
Empty state + Add flow
Rename cap 50 chars (matches Android)

No regressions on settings during the Jul 2 pass.


Connection indicator (reconnect commits)

Step Result
Paired + in range → green
iPhone BLE off → grey
BLE on again → green ✅ (Connected to Trezor @ 13:22:16)
Walk out of BLE range → grey ✅ (External disconnect @ 13:22:40)
Walk back in range (app open) → green ❌ stayed grey
Kill app + relaunch (Trezor unlocked) ⚠️ green on 2nd restart (@ 13:37:01)

Log-backed timeline after range loss (@ 13:22:40):

  • 13:24:59, 13:27:21 — foreground autoReconnectno known devices found nearby
  • 13:27:30 — 1st cold start → 3s scan, zero didDiscover
  • 13:36:15 — foreground autoReconnect → 0 devices
  • 13:36:49 — 2nd cold startdidDiscover (RSSI -75) → Connected to Trezor @ 13:37:01

Failed attempts had no connection/THP errors — scans simply found nothing (enumerateDevices: 0). Grey badge is correct whenever there is no session; the gap is discovery timing + no retry (single ~3s scan on foreground/cold start only, nothing while app stays open after disconnect).

Suggest extending #613 QA 4b with: backoff retries after external disconnect, longer/repeated scan while a known device exists but connectedDevice == nil.


Non-blocking follow-ups → #613

Already captured by @jvsena42 in #613 (comment) — agree, leave out of #612:

  • BLE power-off should resume in-flight continuations
  • Hide Hardware Wallets count when 0
  • Consolidate device-removal teardown onto HwWalletManager

Also tracked in #613 (from earlier QA):

  • Home icon placement (glyph on amount row vs Figma/Android name row)
  • Device busy / ping cadence while Trezor locked (#1030 parity)

Android parity: post-pair rename from Settings is iOS-only here → bitkit-android#1056.


Summary: Approve for settings screen + improved disconnect-state wiring. Reconnect recovery after range loss / flaky cold-start reconnect belongs in #613 alongside João's deferred items.

@jvsena42 jvsena42 merged commit c0e5f2a into master Jul 2, 2026
11 checks passed
@jvsena42 jvsena42 deleted the feat/hw-wallet-settings branch July 2, 2026 14:17
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