Browse Source

psbt: follow-ups: fix trezor

patch-1
SomberNight 5 years ago
parent
commit
cc4f6804b0
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 8
      electrum/plugins/hw_wallet/plugin.py
  2. 10
      electrum/plugins/keepkey/keepkey.py
  3. 10
      electrum/plugins/safe_t/safe_t.py
  4. 8
      electrum/plugins/trezor/trezor.py
  5. 5
      electrum/transaction.py

8
electrum/plugins/hw_wallet/plugin.py

@ -24,16 +24,16 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.
from typing import TYPE_CHECKING, Dict, List, Union, Tuple from typing import TYPE_CHECKING, Dict, List, Union, Tuple, Sequence
from electrum.plugin import BasePlugin, hook from electrum.plugin import BasePlugin, hook
from electrum.i18n import _ from electrum.i18n import _
from electrum.bitcoin import is_address, TYPE_SCRIPT, opcodes from electrum.bitcoin import is_address, TYPE_SCRIPT, opcodes
from electrum.util import bfh, versiontuple, UserFacingException from electrum.util import bfh, versiontuple, UserFacingException
from electrum.transaction import TxOutput, Transaction, PartialTransaction, PartialTxInput, PartialTxOutput from electrum.transaction import TxOutput, Transaction, PartialTransaction, PartialTxInput, PartialTxOutput
from electrum.bip32 import BIP32Node
if TYPE_CHECKING: if TYPE_CHECKING:
from electrum.bip32 import BIP32Node
from electrum.wallet import Abstract_Wallet from electrum.wallet import Abstract_Wallet
from electrum.keystore import Hardware_KeyStore from electrum.keystore import Hardware_KeyStore
@ -162,7 +162,11 @@ def get_xpubs_and_der_suffixes_from_txinout(tx: PartialTransaction,
xfp_to_xpub_map = {xfp: bip32node for bip32node, (xfp, path) xfp_to_xpub_map = {xfp: bip32node for bip32node, (xfp, path)
in tx.xpubs.items()} # type: Dict[bytes, BIP32Node] in tx.xpubs.items()} # type: Dict[bytes, BIP32Node]
xfps = [txinout.bip32_paths[pubkey][0] for pubkey in txinout.pubkeys] xfps = [txinout.bip32_paths[pubkey][0] for pubkey in txinout.pubkeys]
try:
xpubs = [xfp_to_xpub_map[xfp] for xfp in xfps] xpubs = [xfp_to_xpub_map[xfp] for xfp in xfps]
except KeyError as e:
raise Exception(f"Partial transaction is missing global xpub for "
f"fingerprint ({str(e)}) in input/output") from e
xpubs_and_deriv_suffixes = [] xpubs_and_deriv_suffixes = []
for bip32node, pubkey in zip(xpubs, txinout.pubkeys): for bip32node, pubkey in zip(xpubs, txinout.pubkeys):
xfp, path = txinout.bip32_paths[pubkey] xfp, path = txinout.bip32_paths[pubkey]

10
electrum/plugins/keepkey/keepkey.py

@ -351,15 +351,18 @@ class KeepKeyPlugin(HW_PluginBase):
assert isinstance(tx, PartialTransaction) assert isinstance(tx, PartialTransaction)
assert isinstance(txin, PartialTxInput) assert isinstance(txin, PartialTxInput)
assert keystore assert keystore
if len(txin.pubkeys) > 1:
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin) xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin)
multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes) multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes)
else:
multisig = None
script_type = self.get_keepkey_input_script_type(txin.script_type) script_type = self.get_keepkey_input_script_type(txin.script_type)
txinputtype = self.types.TxInputType( txinputtype = self.types.TxInputType(
script_type=script_type, script_type=script_type,
multisig=multisig) multisig=multisig)
my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txin) my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txin)
if full_path: if full_path:
txinputtype.address_n = full_path txinputtype.address_n.extend(full_path)
prev_hash = txin.prevout.txid prev_hash = txin.prevout.txid
prev_index = txin.prevout.out_idx prev_index = txin.prevout.out_idx
@ -387,12 +390,15 @@ class KeepKeyPlugin(HW_PluginBase):
signatures=[b''] * len(pubkeys), signatures=[b''] * len(pubkeys),
m=m) m=m)
def tx_outputs(self, tx: PartialTransaction, *, keystore: 'KeepKey_KeyStore' = None): def tx_outputs(self, tx: PartialTransaction, *, keystore: 'KeepKey_KeyStore'):
def create_output_by_derivation(): def create_output_by_derivation():
script_type = self.get_keepkey_output_script_type(txout.script_type) script_type = self.get_keepkey_output_script_type(txout.script_type)
if len(txout.pubkeys) > 1:
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout) xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout)
multisig = self._make_multisig(txout.num_sig, xpubs_and_deriv_suffixes) multisig = self._make_multisig(txout.num_sig, xpubs_and_deriv_suffixes)
else:
multisig = None
my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txout) my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txout)
assert full_path assert full_path
txoutputtype = self.types.TxOutputType( txoutputtype = self.types.TxOutputType(

10
electrum/plugins/safe_t/safe_t.py

@ -347,15 +347,18 @@ class SafeTPlugin(HW_PluginBase):
assert isinstance(tx, PartialTransaction) assert isinstance(tx, PartialTransaction)
assert isinstance(txin, PartialTxInput) assert isinstance(txin, PartialTxInput)
assert keystore assert keystore
if len(txin.pubkeys) > 1:
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin) xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin)
multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes) multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes)
else:
multisig = None
script_type = self.get_safet_input_script_type(txin.script_type) script_type = self.get_safet_input_script_type(txin.script_type)
txinputtype = self.types.TxInputType( txinputtype = self.types.TxInputType(
script_type=script_type, script_type=script_type,
multisig=multisig) multisig=multisig)
my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txin) my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txin)
if full_path: if full_path:
txinputtype.address_n = full_path txinputtype._extend_address_n(full_path)
prev_hash = txin.prevout.txid prev_hash = txin.prevout.txid
prev_index = txin.prevout.out_idx prev_index = txin.prevout.out_idx
@ -383,12 +386,15 @@ class SafeTPlugin(HW_PluginBase):
signatures=[b''] * len(pubkeys), signatures=[b''] * len(pubkeys),
m=m) m=m)
def tx_outputs(self, tx: PartialTransaction, *, keystore: 'SafeTKeyStore' = None): def tx_outputs(self, tx: PartialTransaction, *, keystore: 'SafeTKeyStore'):
def create_output_by_derivation(): def create_output_by_derivation():
script_type = self.get_safet_output_script_type(txout.script_type) script_type = self.get_safet_output_script_type(txout.script_type)
if len(txout.pubkeys) > 1:
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout) xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout)
multisig = self._make_multisig(txout.num_sig, xpubs_and_deriv_suffixes) multisig = self._make_multisig(txout.num_sig, xpubs_and_deriv_suffixes)
else:
multisig = None
my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txout) my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txout)
assert full_path assert full_path
txoutputtype = self.types.TxOutputType( txoutputtype = self.types.TxOutputType(

8
electrum/plugins/trezor/trezor.py

@ -365,8 +365,11 @@ class TrezorPlugin(HW_PluginBase):
assert isinstance(tx, PartialTransaction) assert isinstance(tx, PartialTransaction)
assert isinstance(txin, PartialTxInput) assert isinstance(txin, PartialTxInput)
assert keystore assert keystore
if len(txin.pubkeys) > 1:
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin) xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin)
multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes) 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) script_type = self.get_trezor_input_script_type(txin.script_type)
txinputtype = TxInputType( txinputtype = TxInputType(
script_type=script_type, script_type=script_type,
@ -401,12 +404,15 @@ class TrezorPlugin(HW_PluginBase):
signatures=[b''] * len(pubkeys), signatures=[b''] * len(pubkeys),
m=m) m=m)
def tx_outputs(self, tx: PartialTransaction, *, keystore: 'TrezorKeyStore' = None): def tx_outputs(self, tx: PartialTransaction, *, keystore: 'TrezorKeyStore'):
def create_output_by_derivation(): def create_output_by_derivation():
script_type = self.get_trezor_output_script_type(txout.script_type) script_type = self.get_trezor_output_script_type(txout.script_type)
if len(txout.pubkeys) > 1:
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout) xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout)
multisig = self._make_multisig(txout.num_sig, xpubs_and_deriv_suffixes) multisig = self._make_multisig(txout.num_sig, xpubs_and_deriv_suffixes)
else:
multisig = None
my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txout) my_pubkey, full_path = keystore.find_my_pubkey_in_txinout(txout)
assert full_path assert full_path
txoutputtype = TxOutputType( txoutputtype = TxOutputType(

5
electrum/transaction.py

@ -1753,9 +1753,10 @@ class PartialTransaction(Transaction):
if self.is_complete(): if self.is_complete():
return return
only_der_suffix = not include_xpubs_and_full_paths only_der_suffix = not include_xpubs_and_full_paths
# only include xpubs for multisig wallets; currently only they need it in practice, # only include xpubs for multisig wallets; currently only they need it in practice
# and also the coldcard fw have a limitation that if they are included then all # note: coldcard fw have a limitation that if they are included then all
# inputs are assumed to be multisig... https://github.com/spesmilo/electrum/pull/5440#issuecomment-549504761 # inputs are assumed to be multisig... https://github.com/spesmilo/electrum/pull/5440#issuecomment-549504761
# note: trezor plugin needs xpubs included, if there are multisig inputs/change_outputs
from .wallet import Multisig_Wallet from .wallet import Multisig_Wallet
if include_xpubs_and_full_paths and isinstance(wallet, Multisig_Wallet): if include_xpubs_and_full_paths and isinstance(wallet, Multisig_Wallet):
from .keystore import Xpub from .keystore import Xpub

Loading…
Cancel
Save