diff --git a/hwilib/devices/trezor.py b/hwilib/devices/trezor.py index d8cae99da..1848e8f42 100644 --- a/hwilib/devices/trezor.py +++ b/hwilib/devices/trezor.py @@ -316,8 +316,8 @@ def _prepare_device(self) -> None: # If this is a Trezor One or Keepkey, do Initialize if resp.model == '1' or resp.model == 'K1-14AM': self.client.init_device() - # For the T, we need to check if a passphrase needs to be entered - elif resp.model == 'T': + # For later models, we need to check if a passphrase needs to be entered + else: try: self.client.ensure_unlocked() except TrezorFailure: @@ -325,7 +325,7 @@ def _prepare_device(self) -> None: def _check_unlocked(self) -> None: self._prepare_device() - if self.client.features.model == 'T' and isinstance(self.client.ui, PassphraseUI): + if messages.Capability.PassphraseEntry in self.client.features.capabilities and isinstance(self.client.ui, PassphraseUI): self.client.ui.disallow_passphrase() if self.client.features.pin_protection and not self.client.features.unlocked: raise DeviceNotReadyError('{} is locked. Unlock by using \'promptpin\' and then \'sendpin\'.'.format(self.type)) @@ -846,7 +846,9 @@ def can_sign_taproot(self) -> bool: self._prepare_device() if self.client.features.model == "T": return bool(self.client.version >= (2, 4, 3)) - return bool(self.client.version >= (1, 10, 4)) + elif self.client.features.model == "1": + return bool(self.client.version >= (1, 10, 4)) + return True def enumerate(password: Optional[str] = None, expert: bool = False, chain: Chain = Chain.MAIN) -> List[Dict[str, Any]]: diff --git a/hwilib/devices/trezorlib/models.py b/hwilib/devices/trezorlib/models.py index 183dfb3eb..af83214a2 100644 --- a/hwilib/devices/trezorlib/models.py +++ b/hwilib/devices/trezorlib/models.py @@ -1,3 +1,19 @@ +# This file is part of the Trezor project. +# +# Copyright (C) 2012-2022 SatoshiLabs and contributors +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the License along with this library. +# If not, see . + from dataclasses import dataclass from typing import Collection, Optional, Tuple @@ -11,33 +27,75 @@ @dataclass(eq=True, frozen=True) class TrezorModel: name: str + internal_name: str minimum_version: Tuple[int, int, int] vendors: Collection[str] usb_ids: Collection[UsbId] default_mapping: mapping.ProtobufMapping -TREZOR_ONE = TrezorModel( +# ==== internal names ==== + +T1B1 = TrezorModel( name="1", + internal_name="T1B1", minimum_version=(1, 8, 0), vendors=VENDORS, usb_ids=((0x534C, 0x0001),), default_mapping=mapping.DEFAULT_MAPPING, ) -TREZOR_T = TrezorModel( +T2T1 = TrezorModel( name="T", + internal_name="T2T1", minimum_version=(2, 1, 0), vendors=VENDORS, usb_ids=((0x1209, 0x53C1), (0x1209, 0x53C0)), default_mapping=mapping.DEFAULT_MAPPING, ) -TREZORS = {TREZOR_ONE, TREZOR_T} +T2B1 = TrezorModel( + name="Safe 3", + internal_name="T2B1", + minimum_version=(2, 1, 0), + vendors=VENDORS, + usb_ids=((0x1209, 0x53C1), (0x1209, 0x53C0)), + default_mapping=mapping.DEFAULT_MAPPING, +) + +DISC1 = TrezorModel( + name="DISC1", + internal_name="D001", + minimum_version=(2, 1, 0), + vendors=VENDORS, + usb_ids=((0x1209, 0x53C1), (0x1209, 0x53C0)), + default_mapping=mapping.DEFAULT_MAPPING, +) + +# ==== model based names ==== + +TREZOR_ONE = T1B1 +TREZOR_T = T2T1 +TREZOR_R = T2B1 +TREZOR_SAFE3 = T2B1 +TREZOR_DISC1 = DISC1 + +TREZORS = {T1B1, T2T1, T2B1, DISC1} -def by_name(name: str) -> Optional[TrezorModel]: +def by_name(name: Optional[str]) -> Optional[TrezorModel]: + if name is None: + return T1B1 for model in TREZORS: if model.name == name: return model return None + + +def by_internal_name(name: Optional[str]) -> Optional[TrezorModel]: + if name is None: + return None + for model in TREZORS: + if model.internal_name == name: + return model + return None