Handle Trezor canceled actions and bad arguments to trezorlib
This commit is contained in:
parent
9d52695699
commit
4e49da29ad
@ -1,9 +1,10 @@
|
|||||||
# Trezor interaction script
|
# Trezor interaction script
|
||||||
|
|
||||||
from ..hwwclient import HardwareWalletClient
|
from ..hwwclient import HardwareWalletClient
|
||||||
from ..errors import BadArgumentError, DeviceAlreadyInitError, DeviceAlreadyUnlockedError, UnavailableActionError, DeviceNotReadyError
|
from ..errors import ActionCanceledError, BadArgumentError, DeviceAlreadyInitError, DeviceAlreadyUnlockedError, DeviceConnectionError, UnavailableActionError, DeviceNotReadyError
|
||||||
from trezorlib.client import TrezorClient as Trezor
|
from trezorlib.client import TrezorClient as Trezor
|
||||||
from trezorlib.debuglink import TrezorClientDebugLink
|
from trezorlib.debuglink import TrezorClientDebugLink
|
||||||
|
from trezorlib.exceptions import Cancelled
|
||||||
from trezorlib.transport import enumerate_devices, get_transport
|
from trezorlib.transport import enumerate_devices, get_transport
|
||||||
from trezorlib.ui import ClickUI, mnemonic_words, PIN_MATRIX_DESCRIPTION
|
from trezorlib.ui import ClickUI, mnemonic_words, PIN_MATRIX_DESCRIPTION
|
||||||
from trezorlib import protobuf, tools, btc, device
|
from trezorlib import protobuf, tools, btc, device
|
||||||
@ -11,6 +12,7 @@ from trezorlib import messages as proto
|
|||||||
from ..base58 import get_xpub_fingerprint, decode, to_address, xpub_main_2_test, get_xpub_fingerprint_hex
|
from ..base58 import get_xpub_fingerprint, decode, to_address, xpub_main_2_test, get_xpub_fingerprint_hex
|
||||||
from ..serializations import ser_uint256, uint256_from_str
|
from ..serializations import ser_uint256, uint256_from_str
|
||||||
from .. import bech32
|
from .. import bech32
|
||||||
|
from usb1 import USBErrorNoDevice
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import binascii
|
import binascii
|
||||||
@ -66,6 +68,18 @@ class TrezorNoInit(Trezor):
|
|||||||
|
|
||||||
self.session_counter = 0
|
self.session_counter = 0
|
||||||
|
|
||||||
|
def trezor_exception(f):
|
||||||
|
def func(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
except ValueError as e:
|
||||||
|
raise BadArgumentError(str(e))
|
||||||
|
except Cancelled as e:
|
||||||
|
raise ActionCanceledError('{} canceled'.format(f.__name__))
|
||||||
|
except USBErrorNoDevice as e:
|
||||||
|
raise DeviceConnectionError('Device disconnected')
|
||||||
|
return func
|
||||||
|
|
||||||
# This class extends the HardwareWalletClient for Trezor specific things
|
# This class extends the HardwareWalletClient for Trezor specific things
|
||||||
class TrezorClient(HardwareWalletClient):
|
class TrezorClient(HardwareWalletClient):
|
||||||
|
|
||||||
@ -93,6 +107,7 @@ class TrezorClient(HardwareWalletClient):
|
|||||||
|
|
||||||
# Must return a dict with the xpub
|
# Must return a dict with the xpub
|
||||||
# Retrieves the public key at the specified BIP 32 derivation path
|
# Retrieves the public key at the specified BIP 32 derivation path
|
||||||
|
@trezor_exception
|
||||||
def get_pubkey_at_path(self, path):
|
def get_pubkey_at_path(self, path):
|
||||||
self._check_unlocked()
|
self._check_unlocked()
|
||||||
try:
|
try:
|
||||||
@ -107,6 +122,7 @@ class TrezorClient(HardwareWalletClient):
|
|||||||
|
|
||||||
# Must return a hex string with the signed transaction
|
# Must return a hex string with the signed transaction
|
||||||
# The tx must be in the psbt format
|
# The tx must be in the psbt format
|
||||||
|
@trezor_exception
|
||||||
def sign_tx(self, tx):
|
def sign_tx(self, tx):
|
||||||
self._check_unlocked()
|
self._check_unlocked()
|
||||||
|
|
||||||
@ -285,6 +301,7 @@ class TrezorClient(HardwareWalletClient):
|
|||||||
|
|
||||||
# Must return a base64 encoded string with the signed message
|
# Must return a base64 encoded string with the signed message
|
||||||
# The message can be any string
|
# The message can be any string
|
||||||
|
@trezor_exception
|
||||||
def sign_message(self, message, keypath):
|
def sign_message(self, message, keypath):
|
||||||
self._check_unlocked()
|
self._check_unlocked()
|
||||||
path = tools.parse_path(keypath)
|
path = tools.parse_path(keypath)
|
||||||
@ -292,6 +309,7 @@ class TrezorClient(HardwareWalletClient):
|
|||||||
return {'signature': base64.b64encode(result.signature).decode('utf-8')}
|
return {'signature': base64.b64encode(result.signature).decode('utf-8')}
|
||||||
|
|
||||||
# Display address of specified type on the device. Only supports single-key based addresses.
|
# Display address of specified type on the device. Only supports single-key based addresses.
|
||||||
|
@trezor_exception
|
||||||
def display_address(self, keypath, p2sh_p2wpkh, bech32):
|
def display_address(self, keypath, p2sh_p2wpkh, bech32):
|
||||||
self._check_unlocked()
|
self._check_unlocked()
|
||||||
expanded_path = tools.parse_path(keypath)
|
expanded_path = tools.parse_path(keypath)
|
||||||
@ -305,7 +323,9 @@ class TrezorClient(HardwareWalletClient):
|
|||||||
return {'address': address}
|
return {'address': address}
|
||||||
|
|
||||||
# Setup a new device
|
# Setup a new device
|
||||||
|
@trezor_exception
|
||||||
def setup_device(self, label='', passphrase=''):
|
def setup_device(self, label='', passphrase=''):
|
||||||
|
self.client.init_device()
|
||||||
if self.client.features.initialized:
|
if self.client.features.initialized:
|
||||||
raise DeviceAlreadyInitError('Device is already initialized. Use wipe first and try again')
|
raise DeviceAlreadyInitError('Device is already initialized. Use wipe first and try again')
|
||||||
passphrase_enabled = False
|
passphrase_enabled = False
|
||||||
@ -315,12 +335,14 @@ class TrezorClient(HardwareWalletClient):
|
|||||||
return {'success': True}
|
return {'success': True}
|
||||||
|
|
||||||
# Wipe this device
|
# Wipe this device
|
||||||
|
@trezor_exception
|
||||||
def wipe_device(self):
|
def wipe_device(self):
|
||||||
self._check_unlocked()
|
self._check_unlocked()
|
||||||
device.wipe(self.client)
|
device.wipe(self.client)
|
||||||
return {'success': True}
|
return {'success': True}
|
||||||
|
|
||||||
# Restore device from mnemonic or xprv
|
# Restore device from mnemonic or xprv
|
||||||
|
@trezor_exception
|
||||||
def restore_device(self, label=''):
|
def restore_device(self, label=''):
|
||||||
passphrase_enabled = False
|
passphrase_enabled = False
|
||||||
device.recover(self.client, label=label, input_callback=mnemonic_words, passphrase_protection=bool(self.password))
|
device.recover(self.client, label=label, input_callback=mnemonic_words, passphrase_protection=bool(self.password))
|
||||||
@ -331,10 +353,12 @@ class TrezorClient(HardwareWalletClient):
|
|||||||
raise UnavailableActionError('The Trezor does not support creating a backup via software')
|
raise UnavailableActionError('The Trezor does not support creating a backup via software')
|
||||||
|
|
||||||
# Close the device
|
# Close the device
|
||||||
|
@trezor_exception
|
||||||
def close(self):
|
def close(self):
|
||||||
self.client.close()
|
self.client.close()
|
||||||
|
|
||||||
# Prompt for a pin on device
|
# Prompt for a pin on device
|
||||||
|
@trezor_exception
|
||||||
def prompt_pin(self):
|
def prompt_pin(self):
|
||||||
self.client.init_device()
|
self.client.init_device()
|
||||||
if not self.client.features.pin_protection:
|
if not self.client.features.pin_protection:
|
||||||
@ -347,6 +371,7 @@ class TrezorClient(HardwareWalletClient):
|
|||||||
return {'success': True}
|
return {'success': True}
|
||||||
|
|
||||||
# Send the pin
|
# Send the pin
|
||||||
|
@trezor_exception
|
||||||
def send_pin(self, pin):
|
def send_pin(self, pin):
|
||||||
self.client.features = self.client.call_raw(proto.GetFeatures())
|
self.client.features = self.client.call_raw(proto.GetFeatures())
|
||||||
if isinstance(self.client.features, proto.Features):
|
if isinstance(self.client.features, proto.Features):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user