From f95c63c86aba55061f95428546d56a34711052c1 Mon Sep 17 00:00:00 2001 From: M1nd3r Date: Thu, 27 Mar 2025 12:42:50 +0100 Subject: [PATCH] fixup! feat(python): implement session based trezorlib --- python/src/trezorlib/client.py | 3 -- python/src/trezorlib/debuglink.py | 62 +----------------------------- python/src/trezorlib/ui.py | 63 ++----------------------------- 3 files changed, 5 insertions(+), 123 deletions(-) diff --git a/python/src/trezorlib/client.py b/python/src/trezorlib/client.py index cede4c8af5..130b0888ec 100644 --- a/python/src/trezorlib/client.py +++ b/python/src/trezorlib/client.py @@ -53,9 +53,6 @@ class ProtocolVersion(IntEnum): class TrezorClient: button_callback: t.Callable[[messages.ButtonRequest], None] | None = None - passphrase_callback: ( - t.Callable[[Session, messages.PassphraseRequest], t.Any] | None - ) = None pin_callback: t.Callable[[messages.PinMatrixRequest], str] | None = None _model: models.TrezorModel diff --git a/python/src/trezorlib/debuglink.py b/python/src/trezorlib/debuglink.py index 6801374c5c..10999977e5 100644 --- a/python/src/trezorlib/debuglink.py +++ b/python/src/trezorlib/debuglink.py @@ -33,15 +33,12 @@ from mnemonic import Mnemonic from . import btc, mapping, messages, models, protobuf from .client import ( - MAX_PASSPHRASE_LENGTH, - PASSPHRASE_ON_DEVICE, ProtocolVersion, TrezorClient, ) from .exceptions import Cancelled, TrezorFailure, UnexpectedMessageError from .log import DUMP_BYTES -from .messages import Capability, DebugWaitType -from .protobuf import MessageType +from .messages import DebugWaitType from .tools import parse_path from .transport import Timeout from .transport.session import Session @@ -1282,62 +1279,6 @@ class TrezorClientDebugLink(TrezorClient): new_client.debug.t1_screenshot_counter = self.debug.t1_screenshot_counter return new_client - def passphrase_callback( - self, session: Session, msg: messages.PassphraseRequest - ) -> t.Any: - available_on_device = ( - Capability.PassphraseEntry in session.features.capabilities - ) - - def send_passphrase( - passphrase: str | None = None, on_device: bool | None = None - ) -> MessageType: - msg = messages.PassphraseAck(passphrase=passphrase, on_device=on_device) - resp = session.call_raw(msg) - if isinstance(resp, messages.Deprecated_PassphraseStateRequest): - if resp.state is not None: - session.id = resp.state - else: - raise RuntimeError("Object resp.state is None") - resp = session.call_raw(messages.Deprecated_PassphraseStateAck()) - return resp - - # short-circuit old style entry - if msg._on_device is True: - return send_passphrase(None, None) - - try: - if isinstance(session, SessionDebugWrapper): - passphrase = self.ui.get_passphrase( - available_on_device=available_on_device - ) - if passphrase is None: - passphrase = session.passphrase - else: - raise NotImplementedError - except Cancelled: - session.call_raw(messages.Cancel()) - raise - - if passphrase is PASSPHRASE_ON_DEVICE: - if not available_on_device: - session.call_raw(messages.Cancel()) - raise RuntimeError("Device is not capable of entering passphrase") - else: - return send_passphrase(on_device=True) - - # else process host-entered passphrase - if passphrase is None: - passphrase = "" - if not isinstance(passphrase, str): - raise RuntimeError(f"Passphrase must be a str {type(passphrase)}") - passphrase = Mnemonic.normalize_string(passphrase) - if len(passphrase) > MAX_PASSPHRASE_LENGTH: - session.call_raw(messages.Cancel()) - raise ValueError("Passphrase too long") - - return send_passphrase(passphrase, on_device=False) - def close_transport(self) -> None: self.transport.close() self.debug.close() @@ -1359,7 +1300,6 @@ class TrezorClientDebugLink(TrezorClient): derive_cardano, ) ) - session.passphrase = passphrase return session def get_seedless_session( diff --git a/python/src/trezorlib/ui.py b/python/src/trezorlib/ui.py index 644993e709..8f278625d8 100644 --- a/python/src/trezorlib/ui.py +++ b/python/src/trezorlib/ui.py @@ -14,7 +14,6 @@ # You should have received a copy of the License along with this library. # If not, see . -import os import sys import typing as t @@ -22,7 +21,7 @@ import click from mnemonic import Mnemonic from . import device, messages -from .client import MAX_PIN_LENGTH +from .client import MAX_PIN_LENGTH, PASSPHRASE_ON_DEVICE from .exceptions import Cancelled from .messages import Capability, PinMatrixRequestType, WordRequestType from .transport.session import Session @@ -137,52 +136,6 @@ class ClickUI: else: return pin - def get_passphrase( - self, session: Session, request: messages.PassphraseRequest - ) -> t.Any: - available_on_device = ( - Capability.PassphraseEntry in session.features.capabilities - ) - if available_on_device and not self.passphrase_on_host: - return session.call_raw( - messages.PassphraseAck(passphrase=None, on_device=True) - ) - - env_passphrase = os.getenv("PASSPHRASE") - if env_passphrase is not None: - echo("Passphrase required. Using PASSPHRASE environment variable.") - return session.call_raw( - messages.PassphraseAck(passphrase=env_passphrase, on_device=False) - ) - - while True: - try: - passphrase = prompt( - "Passphrase required", - hide_input=True, - default="", - show_default=False, - ) - # In case user sees the input on the screen, we do not need confirmation - if not CAN_HANDLE_HIDDEN_INPUT: - break - second = prompt( - "Confirm your passphrase", - hide_input=True, - default="", - show_default=False, - ) - if passphrase == second: - break - else: - echo("Passphrase did not match. Please try again.") - except click.Abort: - raise Cancelled from None - - return session.call_raw( - messages.PassphraseAck(passphrase=passphrase, on_device=False) - ) - class ScriptUI: """Interface to be used by scripts, not directly by user. @@ -218,10 +171,7 @@ class ScriptUI: return pin @staticmethod - def get_passphrase(session: Session, request: messages.PassphraseRequest) -> t.Any: - available_on_device = ( - Capability.PassphraseEntry in session.features.capabilities - ) + def get_passphrase(available_on_device: bool) -> str | object: if available_on_device: print("?PASSPHRASE available_on_device") else: @@ -231,16 +181,11 @@ class ScriptUI: if passphrase == "CANCEL": raise Cancelled from None elif passphrase == "ON_DEVICE": - return session.call_raw( - messages.PassphraseAck(passphrase=None, on_device=True) - ) + return PASSPHRASE_ON_DEVICE elif not passphrase.startswith(":"): raise RuntimeError("Sent passphrase must start with ':'") else: - passphrase = passphrase[1:] - return session.call_raw( - messages.PassphraseAck(passphrase=passphrase, on_device=False) - ) + return passphrase[1:] def mnemonic_words(