Browse Source

Merge pull request #7590 from matejcik/matejcik/trezorlib-0.13

trezorlib 0.13 compatibility
patch-4
ghost43 3 years ago
committed by GitHub
parent
commit
97e61cfacd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      contrib/requirements/requirements-hw.txt
  2. 4
      electrum/plugins/trezor/clientbase.py
  3. 79
      electrum/plugins/trezor/trezor.py

2
contrib/requirements/requirements-hw.txt

@ -1,5 +1,5 @@
hidapi
trezor[hidapi]>=0.12.0
trezor[hidapi]>=0.13.0,<0.14
safet>=0.1.5
keepkey>=6.3.1
btchip-python>=0.1.32

4
electrum/plugins/trezor/clientbase.py

@ -268,8 +268,8 @@ class TrezorClientBase(HardwareClientBase, Logger):
# ========= UI methods ==========
def button_request(self, code):
message = self.msg or MESSAGES.get(code) or MESSAGES['default']
def button_request(self, br):
message = self.msg or MESSAGES.get(br.code) or MESSAGES['default']
self.handler.show_message(message.format(self.device), self.client.cancel)
def get_pin(self, code=None):

79
electrum/plugins/trezor/trezor.py

@ -30,7 +30,7 @@ try:
from trezorlib.messages import (
Capability, BackupType, RecoveryDeviceType, HDNodeType, HDNodePathType,
InputScriptType, OutputScriptType, MultisigRedeemScriptType,
TxInputType, TxOutputType, TxOutputBinType, TransactionType, SignTx)
TxInputType, TxOutputType, TxOutputBinType, TransactionType, AmountUnit)
from trezorlib.client import PASSPHRASE_ON_DEVICE
@ -54,6 +54,7 @@ except Exception as e:
Capability = _EnumMissing()
BackupType = _EnumMissing()
RecoveryDeviceType = _EnumMissing()
AmountUnit = _EnumMissing()
PASSPHRASE_ON_DEVICE = object()
@ -117,8 +118,8 @@ class TrezorPlugin(HW_PluginBase):
libraries_URL = 'https://pypi.org/project/trezor/'
minimum_firmware = (1, 5, 2)
keystore_class = TrezorKeyStore
minimum_library = (0, 12, 0)
maximum_library = (0, 13)
minimum_library = (0, 13, 0)
maximum_library = (0, 14)
SUPPORTED_XTYPES = ('standard', 'p2wpkh-p2sh', 'p2wpkh', 'p2wsh-p2sh', 'p2wsh')
DEVICE_IDS = (TREZOR_PRODUCT_KEY,)
@ -326,6 +327,8 @@ class TrezorPlugin(HW_PluginBase):
return InputScriptType.SPENDADDRESS
if electrum_txin_type in ('p2sh',):
return InputScriptType.SPENDMULTISIG
if electrum_txin_type in ('p2tr',):
return InputScriptType.SPENDTAPROOT
raise ValueError('unexpected txin type: {}'.format(electrum_txin_type))
def get_trezor_output_script_type(self, electrum_txin_type: str):
@ -337,16 +340,32 @@ class TrezorPlugin(HW_PluginBase):
return OutputScriptType.PAYTOADDRESS
if electrum_txin_type in ('p2sh',):
return OutputScriptType.PAYTOMULTISIG
if electrum_txin_type in ('p2tr',):
return OutputScriptType.PAYTOTAPROOT
raise ValueError('unexpected txin type: {}'.format(electrum_txin_type))
def get_trezor_amount_unit(self):
if self.config.decimal_point == 0:
return AmountUnit.SATOSHI
elif self.config.decimal_point == 2:
return AmountUnit.MICROBITCOIN
elif self.config.decimal_point == 5:
return AmountUnit.MILLIBITCOIN
else:
return AmountUnit.BITCOIN
@runs_in_hwd_thread
def sign_transaction(self, keystore, tx: PartialTransaction, prev_tx):
prev_tx = {bfh(txhash): self.electrum_tx_to_txtype(tx) for txhash, tx in prev_tx.items()}
client = self.get_client(keystore)
inputs = self.tx_inputs(tx, for_sig=True, keystore=keystore)
outputs = self.tx_outputs(tx, keystore=keystore)
details = SignTx(lock_time=tx.locktime, version=tx.version)
signatures, _ = client.sign_tx(self.get_coin_name(), inputs, outputs, details=details, prev_txes=prev_tx)
signatures, _ = client.sign_tx(self.get_coin_name(),
inputs, outputs,
lock_time=tx.locktime,
version=tx.version,
amount_unit=self.get_trezor_amount_unit(),
prev_txes=prev_tx)
signatures = [(bh2u(x) + '01') for x in signatures]
tx.update_signatures(signatures)
@ -379,39 +398,30 @@ class TrezorPlugin(HW_PluginBase):
def tx_inputs(self, tx: Transaction, *, for_sig=False, keystore: 'TrezorKeyStore' = None):
inputs = []
for txin in tx.inputs():
txinputtype = TxInputType()
if txin.is_coinbase_input():
prev_hash = b"\x00"*32
prev_index = 0xffffffff # signed int -1
txinputtype = TxInputType(
prev_hash=b"\x00"*32,
prev_index=0xffffffff, # signed int -1
)
else:
txinputtype = TxInputType(
prev_hash=txin.prevout.txid,
prev_index=txin.prevout.out_idx,
)
if for_sig:
assert isinstance(tx, PartialTransaction)
assert isinstance(txin, PartialTxInput)
assert keystore
if len(txin.pubkeys) > 1:
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin)
multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes)
else:
multisig = None
script_type = self.get_trezor_input_script_type(txin.script_type)
txinputtype = TxInputType(
script_type=script_type,
multisig=multisig)
txinputtype.multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes)
txinputtype.script_type = self.get_trezor_input_script_type(txin.script_type)
my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txin)
if full_path:
txinputtype.address_n = full_path
prev_hash = txin.prevout.txid
prev_index = txin.prevout.out_idx
if txin.value_sats() is not None:
txinputtype.amount = txin.value_sats()
txinputtype.prev_hash = prev_hash
txinputtype.prev_index = prev_index
if txin.script_sig is not None:
txinputtype.script_sig = txin.script_sig
txinputtype.amount = txin.value_sats()
txinputtype.script_sig = txin.script_sig
txinputtype.sequence = txin.nsequence
inputs.append(txinputtype)
@ -446,15 +456,18 @@ class TrezorPlugin(HW_PluginBase):
return txoutputtype
def create_output_by_address():
txoutputtype = TxOutputType()
txoutputtype.amount = txout.value
if address:
txoutputtype.script_type = OutputScriptType.PAYTOADDRESS
txoutputtype.address = address
return TxOutputType(
amount=txout.value,
script_type=OutputScriptType.PAYTOADDRESS,
address=address,
)
else:
txoutputtype.script_type = OutputScriptType.PAYTOOPRETURN
txoutputtype.op_return_data = trezor_validate_op_return_output_and_get_data(txout)
return txoutputtype
return TxOutputType(
amount=txout.value,
script_type=OutputScriptType.PAYTOOPRETURN,
op_return_data=trezor_validate_op_return_output_and_get_data(txout),
)
outputs = []
has_change = False

Loading…
Cancel
Save