mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-02 18:25:21 +00:00
trezor: bump lib version, implement new passphrase-on-device UI
This commit is contained in:
parent
3b7299bfde
commit
4cd50dd75a
6 changed files with 103 additions and 11 deletions
|
@ -8,7 +8,7 @@
|
||||||
# see https://github.com/spesmilo/electrum/issues/5859
|
# see https://github.com/spesmilo/electrum/issues/5859
|
||||||
Cython>=0.27
|
Cython>=0.27
|
||||||
|
|
||||||
trezor[hidapi]>=0.11.5
|
trezor[hidapi]>=0.12.0
|
||||||
safet>=0.1.5
|
safet>=0.1.5
|
||||||
keepkey>=6.3.1
|
keepkey>=6.3.1
|
||||||
btchip-python>=0.1.26
|
btchip-python>=0.1.26
|
||||||
|
|
|
@ -2,7 +2,7 @@ from electrum.i18n import _
|
||||||
|
|
||||||
fullname = 'Trezor Wallet'
|
fullname = 'Trezor Wallet'
|
||||||
description = _('Provides support for Trezor hardware wallet')
|
description = _('Provides support for Trezor hardware wallet')
|
||||||
requires = [('trezorlib','github.com/trezor/python-trezor')]
|
requires = [('trezorlib','pypi.org/project/trezor/')]
|
||||||
registers_keystore = ('hardware', 'trezor', _("Trezor wallet"))
|
registers_keystore = ('hardware', 'trezor', _("Trezor wallet"))
|
||||||
available_for = ['qt', 'cmdline']
|
available_for = ['qt', 'cmdline']
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ from electrum.bip32 import BIP32Node, convert_bip32_path_to_list_of_uint32 as pa
|
||||||
from electrum.logging import Logger
|
from electrum.logging import Logger
|
||||||
from electrum.plugins.hw_wallet.plugin import OutdatedHwFirmwareException, HardwareClientBase
|
from electrum.plugins.hw_wallet.plugin import OutdatedHwFirmwareException, HardwareClientBase
|
||||||
|
|
||||||
from trezorlib.client import TrezorClient
|
from trezorlib.client import TrezorClient, PASSPHRASE_ON_DEVICE
|
||||||
from trezorlib.exceptions import TrezorFailure, Cancelled, OutdatedFirmwareError
|
from trezorlib.exceptions import TrezorFailure, Cancelled, OutdatedFirmwareError
|
||||||
from trezorlib.messages import WordRequestType, FailureType, RecoveryDeviceType, ButtonRequestType
|
from trezorlib.messages import WordRequestType, FailureType, RecoveryDeviceType, ButtonRequestType
|
||||||
import trezorlib.btc
|
import trezorlib.btc
|
||||||
|
@ -30,8 +30,10 @@ MESSAGES = {
|
||||||
_("Confirm the total amount spent and the transaction fee on your {} device"),
|
_("Confirm the total amount spent and the transaction fee on your {} device"),
|
||||||
ButtonRequestType.Address:
|
ButtonRequestType.Address:
|
||||||
_("Confirm wallet address on your {} device"),
|
_("Confirm wallet address on your {} device"),
|
||||||
ButtonRequestType.PassphraseType:
|
ButtonRequestType._Deprecated_ButtonRequest_PassphraseType:
|
||||||
_("Choose on your {} device where to enter your passphrase"),
|
_("Choose on your {} device where to enter your passphrase"),
|
||||||
|
ButtonRequestType.PassphraseEntry:
|
||||||
|
_("Please enter your passphrase on the {} device"),
|
||||||
'default': _("Check your {} device to continue"),
|
'default': _("Check your {} device to continue"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +261,7 @@ class TrezorClientBase(HardwareClientBase, Logger):
|
||||||
raise Cancelled
|
raise Cancelled
|
||||||
return pin
|
return pin
|
||||||
|
|
||||||
def get_passphrase(self):
|
def get_passphrase(self, available_on_device):
|
||||||
if self.creating_wallet:
|
if self.creating_wallet:
|
||||||
msg = _("Enter a passphrase to generate this wallet. Each time "
|
msg = _("Enter a passphrase to generate this wallet. Each time "
|
||||||
"you use this wallet your {} will prompt you for the "
|
"you use this wallet your {} will prompt you for the "
|
||||||
|
@ -267,7 +269,11 @@ class TrezorClientBase(HardwareClientBase, Logger):
|
||||||
"access the bitcoins in the wallet.").format(self.device)
|
"access the bitcoins in the wallet.").format(self.device)
|
||||||
else:
|
else:
|
||||||
msg = _("Enter the passphrase to unlock this wallet:")
|
msg = _("Enter the passphrase to unlock this wallet:")
|
||||||
passphrase = self.handler.get_passphrase(msg, self.creating_wallet)
|
|
||||||
|
self.handler.passphrase_on_device = available_on_device
|
||||||
|
passphrase = self.handler.trezor_get_passphrase(msg, self.creating_wallet)
|
||||||
|
if passphrase is PASSPHRASE_ON_DEVICE:
|
||||||
|
return passphrase
|
||||||
if passphrase is None:
|
if passphrase is None:
|
||||||
raise Cancelled
|
raise Cancelled
|
||||||
passphrase = bip39_normalize_passphrase(passphrase)
|
passphrase = bip39_normalize_passphrase(passphrase)
|
||||||
|
|
|
@ -1,7 +1,22 @@
|
||||||
from electrum.plugin import hook
|
from electrum.plugin import hook
|
||||||
from .trezor import TrezorPlugin
|
from electrum.i18n import _
|
||||||
|
from electrum.util import print_stderr
|
||||||
|
from .trezor import TrezorPlugin, PASSPHRASE_ON_DEVICE
|
||||||
from ..hw_wallet import CmdLineHandler
|
from ..hw_wallet import CmdLineHandler
|
||||||
|
|
||||||
|
class TrezorCmdLineHandler(CmdLineHandler):
|
||||||
|
def __init__(self):
|
||||||
|
self.passphrase_on_device = False
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def get_passphrase(self, msg, confirm):
|
||||||
|
import getpass
|
||||||
|
print_stderr(msg)
|
||||||
|
if self.passphrase_on_device and self.yes_no_question(_('Enter passphrase on device?')):
|
||||||
|
return PASSPHRASE_ON_DEVICE
|
||||||
|
else:
|
||||||
|
return getpass.getpass('')
|
||||||
|
|
||||||
class Plugin(TrezorPlugin):
|
class Plugin(TrezorPlugin):
|
||||||
handler = CmdLineHandler()
|
handler = CmdLineHandler()
|
||||||
@hook
|
@hook
|
||||||
|
|
|
@ -16,7 +16,7 @@ from electrum.util import bh2u
|
||||||
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
|
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
|
||||||
from ..hw_wallet.plugin import only_hook_if_libraries_available
|
from ..hw_wallet.plugin import only_hook_if_libraries_available
|
||||||
from .trezor import (TrezorPlugin, TIM_NEW, TIM_RECOVER, TrezorInitSettings,
|
from .trezor import (TrezorPlugin, TIM_NEW, TIM_RECOVER, TrezorInitSettings,
|
||||||
Capability, BackupType, RecoveryDeviceType)
|
PASSPHRASE_ON_DEVICE, Capability, BackupType, RecoveryDeviceType)
|
||||||
|
|
||||||
|
|
||||||
PASSPHRASE_HELP_SHORT =_(
|
PASSPHRASE_HELP_SHORT =_(
|
||||||
|
@ -119,6 +119,7 @@ class QtHandler(QtHandlerBase):
|
||||||
self.close_matrix_dialog_signal.connect(self._close_matrix_dialog)
|
self.close_matrix_dialog_signal.connect(self._close_matrix_dialog)
|
||||||
self.pin_matrix_widget_class = pin_matrix_widget_class
|
self.pin_matrix_widget_class = pin_matrix_widget_class
|
||||||
self.matrix_dialog = None
|
self.matrix_dialog = None
|
||||||
|
self.passphrase_on_device = False
|
||||||
|
|
||||||
def get_pin(self, msg):
|
def get_pin(self, msg):
|
||||||
self.done.clear()
|
self.done.clear()
|
||||||
|
@ -163,6 +164,72 @@ class QtHandler(QtHandlerBase):
|
||||||
self.matrix_dialog.get_matrix(msg)
|
self.matrix_dialog.get_matrix(msg)
|
||||||
self.done.set()
|
self.done.set()
|
||||||
|
|
||||||
|
def passphrase_dialog(self, msg, confirm):
|
||||||
|
# If confirm is true, require the user to enter the passphrase twice
|
||||||
|
parent = self.top_level_window()
|
||||||
|
d = WindowModalDialog(parent, _('Enter Passphrase'))
|
||||||
|
|
||||||
|
OK_button = OkButton(d, _('Enter Passphrase'))
|
||||||
|
OnDevice_button = QPushButton(_('Enter Passphrase on Device'))
|
||||||
|
|
||||||
|
new_pw = QLineEdit()
|
||||||
|
new_pw.setEchoMode(2)
|
||||||
|
conf_pw = QLineEdit()
|
||||||
|
conf_pw.setEchoMode(2)
|
||||||
|
|
||||||
|
vbox = QVBoxLayout()
|
||||||
|
label = QLabel(msg + "\n")
|
||||||
|
label.setWordWrap(True)
|
||||||
|
|
||||||
|
grid = QGridLayout()
|
||||||
|
grid.setSpacing(8)
|
||||||
|
grid.setColumnMinimumWidth(0, 150)
|
||||||
|
grid.setColumnMinimumWidth(1, 100)
|
||||||
|
grid.setColumnStretch(1,1)
|
||||||
|
|
||||||
|
vbox.addWidget(label)
|
||||||
|
|
||||||
|
grid.addWidget(QLabel(_('Passphrase:')), 0, 0)
|
||||||
|
grid.addWidget(new_pw, 0, 1)
|
||||||
|
|
||||||
|
if confirm:
|
||||||
|
grid.addWidget(QLabel(_('Confirm Passphrase:')), 1, 0)
|
||||||
|
grid.addWidget(conf_pw, 1, 1)
|
||||||
|
|
||||||
|
vbox.addLayout(grid)
|
||||||
|
|
||||||
|
def enable_OK():
|
||||||
|
if not confirm:
|
||||||
|
ok = True
|
||||||
|
else:
|
||||||
|
ok = new_pw.text() == conf_pw.text()
|
||||||
|
OK_button.setEnabled(ok)
|
||||||
|
|
||||||
|
new_pw.textChanged.connect(enable_OK)
|
||||||
|
conf_pw.textChanged.connect(enable_OK)
|
||||||
|
|
||||||
|
vbox.addWidget(OK_button)
|
||||||
|
|
||||||
|
if self.passphrase_on_device:
|
||||||
|
vbox.addWidget(OnDevice_button)
|
||||||
|
|
||||||
|
d.setLayout(vbox)
|
||||||
|
|
||||||
|
self.passphrase = None
|
||||||
|
|
||||||
|
def ok_clicked():
|
||||||
|
self.passphrase = new_pw.text()
|
||||||
|
|
||||||
|
def on_device_clicked():
|
||||||
|
self.passphrase = PASSPHRASE_ON_DEVICE
|
||||||
|
|
||||||
|
OK_button.clicked.connect(ok_clicked)
|
||||||
|
OnDevice_button.clicked.connect(on_device_clicked)
|
||||||
|
OnDevice_button.clicked.connect(d.accept)
|
||||||
|
|
||||||
|
d.exec_()
|
||||||
|
self.done.set()
|
||||||
|
|
||||||
|
|
||||||
class QtPlugin(QtPluginBase):
|
class QtPlugin(QtPluginBase):
|
||||||
# Derived classes must provide the following class-static variables:
|
# Derived classes must provide the following class-static variables:
|
||||||
|
|
|
@ -32,6 +32,8 @@ try:
|
||||||
InputScriptType, OutputScriptType, MultisigRedeemScriptType,
|
InputScriptType, OutputScriptType, MultisigRedeemScriptType,
|
||||||
TxInputType, TxOutputType, TxOutputBinType, TransactionType, SignTx)
|
TxInputType, TxOutputType, TxOutputBinType, TransactionType, SignTx)
|
||||||
|
|
||||||
|
from trezorlib.client import PASSPHRASE_ON_DEVICE
|
||||||
|
|
||||||
TREZORLIB = True
|
TREZORLIB = True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.exception('error importing trezorlib')
|
_logger.exception('error importing trezorlib')
|
||||||
|
@ -52,6 +54,8 @@ except Exception as e:
|
||||||
BackupType = _EnumMissing()
|
BackupType = _EnumMissing()
|
||||||
RecoveryDeviceType = _EnumMissing()
|
RecoveryDeviceType = _EnumMissing()
|
||||||
|
|
||||||
|
PASSPHRASE_ON_DEVICE = object()
|
||||||
|
|
||||||
|
|
||||||
# Trezor initialization methods
|
# Trezor initialization methods
|
||||||
TIM_NEW, TIM_RECOVER = range(2)
|
TIM_NEW, TIM_RECOVER = range(2)
|
||||||
|
@ -109,11 +113,11 @@ class TrezorPlugin(HW_PluginBase):
|
||||||
# wallet_class, types
|
# wallet_class, types
|
||||||
|
|
||||||
firmware_URL = 'https://wallet.trezor.io'
|
firmware_URL = 'https://wallet.trezor.io'
|
||||||
libraries_URL = 'https://github.com/trezor/python-trezor'
|
libraries_URL = 'https://pypi.org/project/trezor/'
|
||||||
minimum_firmware = (1, 5, 2)
|
minimum_firmware = (1, 5, 2)
|
||||||
keystore_class = TrezorKeyStore
|
keystore_class = TrezorKeyStore
|
||||||
minimum_library = (0, 11, 5)
|
minimum_library = (0, 12, 0)
|
||||||
maximum_library = (0, 12)
|
maximum_library = (0, 13)
|
||||||
SUPPORTED_XTYPES = ('standard', 'p2wpkh-p2sh', 'p2wpkh', 'p2wsh-p2sh', 'p2wsh')
|
SUPPORTED_XTYPES = ('standard', 'p2wpkh-p2sh', 'p2wpkh', 'p2wsh-p2sh', 'p2wsh')
|
||||||
DEVICE_IDS = (TREZOR_PRODUCT_KEY,)
|
DEVICE_IDS = (TREZOR_PRODUCT_KEY,)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue