Skip to content

Comments

feat:Update Bluetooth pairing flow#402

Merged
somebodyLi merged 1 commit intoOneKeyHQ:mainfrom
lihuanhuan:pro_main
Dec 15, 2025
Merged

feat:Update Bluetooth pairing flow#402
somebodyLi merged 1 commit intoOneKeyHQ:mainfrom
lihuanhuan:pro_main

Conversation

@lihuanhuan
Copy link
Contributor

@lihuanhuan lihuanhuan commented Dec 15, 2025

Summary by CodeRabbit

  • New Features

    • Added device settings for language selection, auto-lock timeout, auto-shutdown timeout, and keyboard haptic feedback.
    • Added PIN keypad layout options (default or randomized) and USB lock control.
    • Enhanced Bluetooth pairing flow with dedicated screens for pairing success and failure states.
  • Localization

    • Added translations for all new settings across multiple supported languages (English, German, Spanish, French, Italian, Japanese, Korean, Portuguese, Russian, Chinese, and more).
    • Updated terminology for consistency in device settings prompts.

✏️ Tip: You can customize this high-level summary in your review settings.

@lihuanhuan lihuanhuan requested a review from a team as a code owner December 15, 2025 00:48
@coderabbitai
Copy link

coderabbitai bot commented Dec 15, 2025

Walkthrough

Introduces 18 new localization keys for device settings (language, auto-lock, auto-shutdown, haptics, PIN keypad, USB lock) and Bluetooth pairing flows, adds translations across 10 languages, and implements new Bluetooth pairing UI screens with version-aware branching and refactored UART pairing state management.

Changes

Cohort / File(s) Summary
Localization Keys
core/src/trezor/lvglui/i18n/keys.py
Added 18 new public identifiers for UI configuration prompts and device pairing flows (IDs 1051–1068). Minor comment fix: "asset" → "assets". Duplicated entries noted in same file.
Locale Translations
core/src/trezor/lvglui/i18n/locales/{en,de,es,fr,it,pt_br,ru,zh_cn,zh_hk}.py
Added 18 new translation strings per language for settings (language, auto-lock, auto-shutdown, keyboard haptics, PIN keypad, USB lock) and pairing prompts. German: terminology updates ("Wallet" → "Brieftasche", "Recovery Phrase" → "Wiederherstellungsphrase").
Locale Translations (Japanese)
core/src/trezor/lvglui/i18n/locales/ja.py
Replaced "回復フレーズ" with "シードフレーズ" across recovery/backup flows and related UI strings.
Locale Translations (Korean)
core/src/trezor/lvglui/i18n/locales/ko.py
Standardized terminology: "트랜잭션" → "거래"; "복구 문구" → "복구 구문". Minor wording refinements.
Bluetooth Pairing UI
core/src/trezor/lvglui/scrs/ble.py
Added _compare_version() helper; introduced version-aware UI branching in PairCodeDisplay.__init__ (compares BLE version against "2.3.5"). New public classes: PairFailedScreen, PairSuccessScreen. Added show_unload_anim() method.
UART Pairing State Management
core/src/trezor/uart.py
Replaced single SCREEN with PAIR_CODE_SCREEN, PAIR_ERROR_SCREEN, PAIR_SUCCESS_SCREEN. Added pending state: PENDING_PAIR_CODE, PENDING_PAIR_FAILED. Introduced helper functions: _clear_pairing_screens(), _display_pair_code(), _show_pending_pair_code(), _send_pair_code_response(). Refactored _deal_ble_pair() and _deal_pair_res() for multi-screen flow.
UI Layouts
core/src/trezor/ui/layouts/lvgl/__init__.py
Exported show_pairing_success. Replaced show_pairing_error() with new implementation using PairFailedScreen. Introduced show_pairing_success() with 3-second timeout race condition.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Version comparison logic: _compare_version() semantic versioning implementation in ble.py requires validation
  • Async state machine: UART pairing flow with pending queues (PENDING_PAIR_CODE, PENDING_PAIR_FAILED) and screen lifecycle management needs careful tracing
  • Global state coordination: Multiple global references across uart.py and ble.py (PAIR_CODE_SCREEN, PAIR_ERROR_SCREEN, PAIR_SUCCESS_SCREEN) must sync correctly
  • UI branching: Conditional UI creation based on BLE version in PairCodeDisplay.__init__ affects button layout and text—ensure both paths are tested
  • Translation duplicates: keys.py contains duplicate declarations (noted in summary)—verify these are intentional or cleanup required

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.74% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title accurately describes the main change—adding Bluetooth pairing flow updates across multiple UI, localization, and UART files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@revan-zhang
Copy link
Contributor

revan-zhang commented Dec 15, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@lihuanhuan lihuanhuan enabled auto-merge (squash) December 15, 2025 00:49
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
core/src/trezor/lvglui/scrs/ble.py (1)

37-80: Remove the btn_layout_ver() call or guard it with a check. When use_new_ui is False, confirm_text="" prevents btn_yes creation, making the btn_layout_ver() call on line 79 ineffective. While the method safely returns early, calling it is wasteful.

core/src/trezor/uart.py (1)

368-410: Unhandled decode error can drop pairing response.
Line 394 can throw and exit the task without any response.

-    pair_code = value.decode("utf-8")
+    try:
+        pair_code = value.decode("utf-8")
+    except Exception:
+        _send_pair_code_response(False, None)
+        return
🟡 Minor comments (20)
core/src/trezor/lvglui/i18n/keys.py-2322-2361 (1)

2322-2361: Inconsistent key naming / “TITLE” used for body-style strings

core/src/trezor/lvglui/i18n/locales/zh_hk.py-1054-1071 (1)

1054-1071: Mixed tone (“你/您”) and punctuation style across adjacent prompts

core/src/trezor/lvglui/i18n/locales/fr.py-1054-1071 (1)

1054-1071: FR strings contain awkward/English phrasing (“ouvrir/fermer”, “USB Lock”)

core/src/trezor/lvglui/i18n/locales/zh_cn.py-43-43 (1)

43-43: ZH_CN strings: inconsistent quote/punctuation style and mixed wording (“您想/您要”)

Also applies to: 1054-1071

core/src/trezor/lvglui/i18n/locales/pt_br.py-1054-1071 (1)

1054-1071: Incorrect mismatch text + inconsistent USB naming

Line 1068 “Não, não tem” is wrong for a match/mismatch response. Lines 1064-1065 mix “Bloqueio USB” and “USB Lock”.

core/src/trezor/lvglui/i18n/locales/ja.py-800-802 (1)

800-802: Mixed terminology in same flow

Line 800 uses “シードフレーズ”, but Line 801-802 still say “リカバリーフレーズ”.

core/src/trezor/lvglui/i18n/locales/ru.py-1054-1071 (1)

1054-1071: Awkward mismatch option

Line 1068 “Нет, не делает” reads unnatural for a match/mismatch response.

core/src/trezor/lvglui/i18n/locales/ko.py-1054-1071 (1)

1054-1071: Mixed speech levels / terminology

Line 1060 uses “켜시겠어요?” while nearby lines use “하시겠습니까?”, and Line 1070 uses “장치” where the file mostly uses “기기”.

core/src/trezor/lvglui/i18n/locales/ja.py-26-29 (1)

26-29: Seed vs recovery wording inconsistency

Line 26 still says “リカバリーフレーズ” while Line 27/29 use “シードフレーズ”.

core/src/trezor/lvglui/i18n/locales/ko.py-282-282 (1)

282-282: Grammar reads off

Line 282 “OneKey 암호화는 …” is awkward Korean.

core/src/trezor/lvglui/i18n/locales/es.py-1054-1071 (1)

1054-1071: Inconsistent tone + awkward button text

Line 1054-1065 mix “¿Quieres…?” and “¿Desea…?”. Line 1068 “No, no lo hace” reads off for a match/mismatch choice.

core/src/trezor/lvglui/scrs/ble.py-7-33 (1)

7-33: Version parsing silently defaults to old UI on malformed input

Non-numeric version segments (e.g., "2.3.5-rc1") trigger ValueError at line 20, returning -1 unconditionally. The condition at line 41 (_compare_version(...) >= 0) then evaluates false, activating the legacy UI without warning.

core/src/trezor/lvglui/i18n/locales/de.py-1054-1071 (1)

1054-1071: Inconsistent formal/informal address (Sie/du) in one flow.
Lines 1057, 1066-1068, 1071 use “du/dein” while surrounding strings use “Sie/Ihr”.

core/src/trezor/lvglui/i18n/locales/en.py-1054-1065 (1)

1054-1065: Spacing before question marks + awkward verb forms.
Lines 1060-1065 have ? and several phrases like “when USB plug or unplug”.

core/src/trezor/lvglui/i18n/locales/de.py-277-278 (1)

277-278: German grammar error (“all” → “aller”).
Line 278: “all Ihrer” is incorrect German.

-    "Ein von Menschen lesbarer \"privater Schlüssel\" zum Generieren Ihrer Brieftasche. Ein Schlüssel zum Wiederherstellen all Ihrer Krypto-Assets.",
+    "Ein von Menschen lesbarer \"privater Schlüssel\" zum Generieren Ihrer Brieftasche. Ein Schlüssel zum Wiederherstellen aller Ihrer Krypto-Assets.",
core/src/trezor/lvglui/i18n/locales/de.py-287-287 (1)

287-287: Missing article / awkward header.
Line 287 reads incomplete in German.

-    "Was ist Wiederherstellungsphrase",
+    "Was ist eine Wiederherstellungsphrase?",
core/src/trezor/uart.py-530-559 (1)

530-559: Validation style nit + avoid list allocation.
Line 532: use a tuple.

-    if res not in [_BLE_PAIR_SUCCESS, _BLE_PAIR_FAILED]:
+    if res not in (_BLE_PAIR_SUCCESS, _BLE_PAIR_FAILED):
         return
core/src/trezor/lvglui/i18n/locales/de.py-873-873 (1)

873-873: Opcode casing mismatch (“Delegatecall” → “delegatecall”).
Line 873 should match the opcode spelling.

-    "Hochrisiko-Operation: Diese Transaktion enthält einen Delegatecall, der es externer Software ermöglichen könnte, Ihre Brieftasche zu kontrollieren.",
+    "Hochrisiko-Operation: Diese Transaktion enthält einen delegatecall, der es externer Software ermöglichen könnte, Ihre Brieftasche zu kontrollieren.",
core/src/trezor/lvglui/i18n/locales/en.py-278-278 (1)

278-278: Grammar: “private key” sentence is awkward + “asset” → “assets” already fixed but still clunky.
Line 278 reads ungrammatical.

-    "A human-readable \"private key\" to generate your wallet. A key to restore all your crypto assets.",
+    "A human-readable \"private key\" used to generate your wallet. A key to restore all your crypto assets.",
core/src/trezor/uart.py-319-329 (1)

319-329: Stale globals: not nulled when already destroyed.
Lines 323-329 only set PAIR_CODE_SCREEN / PAIR_SUCCESS_SCREEN to None when they were not destroyed.

 def _clear_pairing_screens():
@@
-    if PAIR_CODE_SCREEN is not None and not PAIR_CODE_SCREEN.destroyed:
-        PAIR_CODE_SCREEN.destroy()
-        PAIR_CODE_SCREEN = None
-    if PAIR_SUCCESS_SCREEN is not None and not PAIR_SUCCESS_SCREEN.destroyed:
-        PAIR_SUCCESS_SCREEN.destroy()
-        PAIR_SUCCESS_SCREEN = None
+    if PAIR_CODE_SCREEN is not None:
+        if not PAIR_CODE_SCREEN.destroyed:
+            PAIR_CODE_SCREEN.destroy()
+        PAIR_CODE_SCREEN = None
+    if PAIR_SUCCESS_SCREEN is not None:
+        if not PAIR_SUCCESS_SCREEN.destroyed:
+            PAIR_SUCCESS_SCREEN.destroy()
+        PAIR_SUCCESS_SCREEN = None
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b6ab910 and 065f64d.

📒 Files selected for processing (15)
  • core/src/trezor/lvglui/i18n/keys.py (2 hunks)
  • core/src/trezor/lvglui/i18n/locales/de.py (7 hunks)
  • core/src/trezor/lvglui/i18n/locales/en.py (2 hunks)
  • core/src/trezor/lvglui/i18n/locales/es.py (1 hunks)
  • core/src/trezor/lvglui/i18n/locales/fr.py (1 hunks)
  • core/src/trezor/lvglui/i18n/locales/it.py (1 hunks)
  • core/src/trezor/lvglui/i18n/locales/ja.py (9 hunks)
  • core/src/trezor/lvglui/i18n/locales/ko.py (22 hunks)
  • core/src/trezor/lvglui/i18n/locales/pt_br.py (1 hunks)
  • core/src/trezor/lvglui/i18n/locales/ru.py (1 hunks)
  • core/src/trezor/lvglui/i18n/locales/zh_cn.py (3 hunks)
  • core/src/trezor/lvglui/i18n/locales/zh_hk.py (1 hunks)
  • core/src/trezor/lvglui/scrs/ble.py (3 hunks)
  • core/src/trezor/uart.py (6 hunks)
  • core/src/trezor/ui/layouts/lvgl/__init__.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
core/src/trezor/lvglui/scrs/ble.py (4)
core/src/trezor/lvglui/scrs/common.py (3)
  • FullSizeWindow (353-696)
  • show_unload_anim (683-688)
  • destroy (612-616)
core/src/trezor/uart.py (1)
  • get_ble_version (788-792)
core/src/storage/device.py (1)
  • get_ble_version (510-515)
core/src/trezor/lvglui/scrs/template.py (6)
  • show_unload_anim (3278-3280)
  • show_unload_anim (3607-3608)
  • destroy (4402-4403)
  • destroy (5435-5436)
  • destroy (5464-5465)
  • destroy (5526-5527)
core/src/trezor/ui/layouts/lvgl/__init__.py (2)
core/src/trezor/lvglui/scrs/ble.py (5)
  • PairFailedScreen (104-123)
  • destroy (85-91)
  • destroy (115-123)
  • destroy (135-141)
  • PairSuccessScreen (126-141)
core/src/trezor/loop.py (1)
  • sleep (258-274)
🪛 Ruff (0.14.8)
core/src/trezor/lvglui/i18n/locales/zh_cn.py

43-43: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


278-278: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


1055-1055: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


1060-1060: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


1061-1061: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


1066-1066: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


1067-1067: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


1068-1068: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


1069-1069: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)

core/src/trezor/lvglui/scrs/ble.py

28-28: zip() without an explicit strict= parameter

Add explicit value for parameter strict=

(B905)

core/src/trezor/lvglui/i18n/locales/ru.py

1069-1069: String contains ambiguous с (CYRILLIC SMALL LETTER ES). Did you mean c (LATIN SMALL LETTER C)?

(RUF001)

core/src/trezor/lvglui/i18n/locales/ja.py

35-35: String contains ambiguous (FULLWIDTH NUMBER SIGN). Did you mean # (NUMBER SIGN)?

(RUF001)


41-41: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


43-43: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


49-49: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


54-54: String contains ambiguous (FULLWIDTH NUMBER SIGN). Did you mean # (NUMBER SIGN)?

(RUF001)


62-62: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


63-63: String contains ambiguous (FULLWIDTH EXCLAMATION MARK). Did you mean ! (EXCLAMATION MARK)?

(RUF001)


277-277: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


283-283: String contains ambiguous (FULLWIDTH COLON). Did you mean : (COLON)?

(RUF001)


284-284: String contains ambiguous (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?

(RUF001)


284-284: String contains ambiguous (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?

(RUF001)


285-285: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


287-287: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


291-291: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


293-293: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


295-295: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


446-446: String contains ambiguous (FULLWIDTH TILDE). Did you mean ~ (TILDE)?

(RUF001)


451-451: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


453-453: String contains ambiguous (FULLWIDTH EXCLAMATION MARK). Did you mean ! (EXCLAMATION MARK)?

(RUF001)


1060-1060: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


1066-1066: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)

core/src/trezor/ui/layouts/lvgl/__init__.py

1379-1380: try-except-pass detected, consider logging the exception

(S110)


1379-1379: Do not catch blind exception: Exception

(BLE001)


1396-1397: try-except-pass detected, consider logging the exception

(S110)


1396-1396: Do not catch blind exception: Exception

(BLE001)

core/src/trezor/lvglui/i18n/locales/zh_hk.py

1066-1066: String contains ambiguous (FULLWIDTH QUESTION MARK). Did you mean ? (QUESTION MARK)?

(RUF001)


1067-1067: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


1068-1068: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)


1069-1069: String contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF001)

core/src/trezor/lvglui/i18n/locales/it.py

1071-1071: String contains ambiguous (RIGHT SINGLE QUOTATION MARK). Did you mean ``` (GRAVE ACCENT)?

(RUF001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Style check
  • GitHub Check: Defs check
  • GitHub Check: Gen check

@424778940z 424778940z disabled auto-merge December 15, 2025 10:25
@somebodyLi somebodyLi merged commit e01716b into OneKeyHQ:main Dec 15, 2025
9 checks passed
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.

4 participants