Skip to content

Conversation

@mmilata
Copy link
Member

@mmilata mmilata commented Apr 22, 2025

Uses cross-platform bleak library (you need to run poetry install). The library is async so we run it in a separate process and trezorlib talks to it using a pipe. It could potentially work on macOS but I haven't tested yet.

Bleak has a particular way of working with BLE devices, namely that it cannot see devices that are already connected to the system. This could affect Suite interoperability and may have to be worked around in platform-specific ways. For trezorlib to see a connected device you have to manually disconnect it first. Trezorlib disconnects from a connected device automatically using atexit.

For pairing to work you need to have the system pairing dialog open, then run trezorctl ble connect. In linux it would be possible to enter the pairing code through trezorlib, but this is IIUC impossible on macOS (see also hbldh/bleak#1100).

If I remember correctly the original BLE support on which this is based was written by @TychoVrahe.

@github-project-automation github-project-automation bot moved this to 🔎 Needs review in Firmware Apr 22, 2025
@github-actions
Copy link

github-actions bot commented Apr 22, 2025

en main(all)

model device_test click_test persistence_test
T2T1 test(all) main(all) test(all) main(all) test(all) main(all)
T3B1 test(all) main(all) test(all) main(all) test(all) main(all)
T3T1 test(all) main(all) test(all) main(all) test(all) main(all)
T3W1 test(all) main(all) test(all) main(all) test(all) main(all)

Latest CI run: 17658231521

@mmilata mmilata force-pushed the mmilata/ble-trezorlib branch from da3c742 to e2f4edb Compare April 23, 2025 14:43
@mmilata mmilata self-assigned this Apr 23, 2025
@mmilata mmilata added trezorlib Python library and the command line trezorctl tool. T3W1 Trezor Safe 7 python Pull requests that update Python code labels Apr 23, 2025
@mmilata mmilata marked this pull request as ready for review April 23, 2025 15:03
@mmilata mmilata requested a review from matejcik as a code owner April 23, 2025 15:03
@mmilata mmilata mentioned this pull request Apr 23, 2025
4 tasks
@mmilata mmilata force-pushed the mmilata/ble-trezorlib branch from ea387e6 to 287c0a6 Compare May 6, 2025 10:32
@mmilata mmilata force-pushed the mmilata/ble-trezorlib branch from 287c0a6 to 5ca3d38 Compare August 18, 2025 22:08
Copy link
Contributor

@romanz romanz left a comment

Choose a reason for hiding this comment

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

utACK, thanks!

@mmilata mmilata force-pushed the mmilata/ble-trezorlib branch from 64286bb to 4ed1e0d Compare August 19, 2025 18:00
@mmilata
Copy link
Member Author

mmilata commented Aug 19, 2025

@matejcik want to take a quick look? There are some potentially intrusive changes (async, persistent subprocess), then again none of it gets run when bleak is not installed.

Copy link
Contributor

@matejcik matejcik left a comment

Choose a reason for hiding this comment

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

LGTM, very reasonable actually

@Hannsek
Copy link
Contributor

Hannsek commented Aug 26, 2025

@romanz @matejcik can we merge this?

@romanz
Copy link
Contributor

romanz commented Aug 26, 2025

I'll rebase to resolve the conficts.

@romanz
Copy link
Contributor

romanz commented Aug 26, 2025

git range-diff output
$ git range-diff origin/main @{u} HEAD
1:  da8e2c7710 = 1:  ee81e2c144 feat(python): BLE support via bleak
2:  4ed1e0de91 ! 2:  2af5a7a683 build(core): poetry: add bleak dependency
    @@ Commit message
     
         [no changelog]
     
    - ## core/tools/pyproject.toml ##
    -@@ core/tools/pyproject.toml: readme = "README.md"
    - 
    - [tool.poetry.dependencies]
    - python = "^3.8"
    --trezor = "^0.13.9"
    -+trezor = "^0.14.0"
    - 
    - [build-system]
    - requires = ["poetry-core"]
    -
      ## poetry.lock ##
     @@ poetry.lock: wrapt = [
          {version = ">=1.14,<2", markers = "python_version >= \"3.11\""},
    @@ poetry.lock: ssh = ["bcrypt (>=3.1.5)"]
      [[package]]
      name = "demjson3"
      version = "3.0.5"
    -@@ poetry.lock: grpcio-tools = ["grpcio-tools (>=1.26.0rc1)"]
    - name = "noiseprotocol"
    - version = "0.3.1"
    - description = "Implementation of Noise Protocol Framework"
    --category = "main"
    - optional = false
    - python-versions = "~=3.5"
    -+groups = ["main"]
    - files = [
    -     {file = "noiseprotocol-0.3.1-py3-none-any.whl", hash = "sha256:2e1a603a38439636cf0ffd8b3e8b12cee27d368a28b41be7dbe568b2abb23111"},
    -     {file = "noiseprotocol-0.3.1.tar.gz", hash = "sha256:b092a871b60f6a8f07f17950dc9f7098c8fe7d715b049bd4c24ee3752b90d645"},
     @@ poetry.lock: typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""
      spelling = ["pyenchant (>=3.2,<4.0)"]
      testutils = ["gitpython (>3)"]
    @@ poetry.lock: typing-extensions = {version = ">=3.10.0", markers = "python_versio
      [[package]]
      name = "pyproject-api"
      version = "1.9.1"
    -@@ poetry.lock: test = ["devpi-process (>=1.0.2)", "pytest (>=8.3.4)", "pytest-mock (>=3.14)"]
    - 
    - [[package]]
    - name = "trezor"
    --version = "0.13.11"
    -+version = "0.14.0"
    - description = "Python library for communicating with Trezor Hardware Wallet"
    - optional = false
    - python-versions = ">=3.8"
    -@@ poetry.lock: develop = true
    - click = ">=7,<8.2"
    - construct = ">=2.9,<2.10.55 || >2.10.55"
    - construct-classes = ">=0.1.2"
    --cryptography = ">=43.0.3"
    -+cryptography = ">=41"
    - ecdsa = ">=0.9"
    - libusb1 = ">=1.6.4"
    - mnemonic = ">=0.20"
    -@@ poetry.lock: slip10 = ">=1.0.1"
    - typing_extensions = ">=4.7.1"
    - 
    - [package.extras]
    -+ble = ["bleak (>=0.22)"]
    - ethereum = ["web3 (>=5)"]
    - extra = ["Pillow (>=10)"]
    --full = ["Pillow (>=10)", "PyQt5", "hidapi (>=0.7.99.post20)", "stellar-sdk (>=6)", "web3 (>=5)"]
    -+full = ["Pillow (>=10)", "PyQt5", "bleak (>=0.22)", "hidapi (>=0.7.99.post20)", "stellar-sdk (>=6)", "web3 (>=5)"]
    - hidapi = ["hidapi (>=0.7.99.post20)"]
    - qt-widgets = ["PyQt5"]
    - stellar = ["stellar-sdk (>=6)"]
    -@@ poetry.lock: files = []
    - develop = true
    - 
    - [package.dependencies]
    --trezor = "^0.13.9"
    -+trezor = "^0.14.0"
    - 
    - [package.source]
    - type = "directory"
     @@ poetry.lock: version = "4.14.0"
      description = "Backported and Experimental Type Hints for Python 3.9+"
      optional = false
    @@ poetry.lock: files = [
     @@ poetry.lock: test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-it
      [metadata]
      lock-version = "2.1"
    - python-versions = "^3.9"
    --content-hash = "cbd46c4adf2c48ea4f80ac75d7ca76da5a3c204efe361354719395cb59336093"
    -+content-hash = "21cd4bcb19a37e52a29abbb14b758658bfbe2cb80bca4adc0dcea408adb6404f"
    + python-versions = ">=3.9,<4"
    +-content-hash = "2860557c9cd81bb82b4ae8b0afaea5d769f15d47e0d127ba9e7899ebe3793211"
    ++content-hash = "472fb015a90b6daafa2095d50beea37a24d3f8bd4967e7712dd554892652cb82"
     
      ## pyproject.toml ##
     @@ pyproject.toml: scan-build = "*"
3:  7be7463862 = 3:  713e51221e tests(python): remove python 3.8, add 3.13

@romanz romanz force-pushed the mmilata/ble-trezorlib branch from 7be7463 to 713e512 Compare August 26, 2025 16:18
@romanz
Copy link
Contributor

romanz commented Aug 26, 2025

Tested locally:

# trezorctl ble connect
Scanning...
Found 1 BLE device(s)
Device: T3W1 (ABC), 11:22:33:44:55:66
Connecting to T3W1 (ABC)...
Connected

# TREZOR_PATH=ble:11:22:33:44:55:66 trezorctl ping 123
Please confirm action on your Trezor device.
123

Sometimes it prints Received unexpected message: sync bit=X, expected=Y due to device-side re-transmissions.

@romanz
Copy link
Contributor

romanz commented Aug 26, 2025

It seems that bleak is installed by default, so every trezorctl call tries to use BLE - taking >5 seconds (if the device is not connected over Bluetooth).

Maybe we should not install bleak by default?
Or hide it behind a special trezorctl flag?
@Hannsek @matejcik

@mmilata mmilata force-pushed the mmilata/ble-trezorlib branch from 713e512 to 4eca838 Compare September 8, 2025 15:13
@mmilata
Copy link
Member Author

mmilata commented Sep 8, 2025

Good point, that is annoying. In 4eca838 BLE is enabled only if:

  • -B / --ble is given to trezorctl (for trezorctl users)
  • ble_enabled=True is passed to functions in trezorlib.transport (for application developers that want to have control over this)
  • TREZOR_BLE=1 environment var is set (for users of applications that use trezorlib but do not pass the flag above)

Also rebased on top of the uv changes. Please take a look.

Copy link
Contributor

@romanz romanz left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@mmilata mmilata force-pushed the mmilata/ble-trezorlib branch from 4eca838 to d78ff8b Compare September 11, 2025 21:51
@mmilata mmilata merged commit 5cef52b into main Sep 11, 2025
103 checks passed
@mmilata mmilata deleted the mmilata/ble-trezorlib branch September 11, 2025 22:30
@github-project-automation github-project-automation bot moved this from 🔎 Needs review to 🤝 Needs QA in Firmware Sep 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Pull requests that update Python code T3W1 Trezor Safe 7 trezorlib Python library and the command line trezorctl tool.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants