@ -1,10 +1,11 @@
from binascii import hexlify , unhexlify
import traceback
import sys
from typing import NamedTuple , Any , Optional , Dict , Union , List , Tuple , TYPE_CHECKING
from typing import NamedTuple , Any , Optional , Dict , Union , List , Tuple , TYPE_CHECKING , Sequence
from electrum . util import bfh , UserCancelled , UserFacingException
from electrum . bip32 import BIP32Node
from electrum import descriptor
from electrum import constants
from electrum . i18n import _
from electrum . transaction import Transaction , PartialTransaction , PartialTxInput , PartialTxOutput , Sighash
@ -13,8 +14,7 @@ from electrum.plugin import Device, runs_in_hwd_thread
from electrum . base_wizard import ScriptTypeNotSupported
from . . hw_wallet import HW_PluginBase
from . . hw_wallet . plugin import ( is_any_tx_output_on_change_branch , trezor_validate_op_return_output_and_get_data ,
get_xpubs_and_der_suffixes_from_txinout )
from . . hw_wallet . plugin import is_any_tx_output_on_change_branch , trezor_validate_op_return_output_and_get_data
if TYPE_CHECKING :
import usb1
@ -271,7 +271,7 @@ class KeepKeyPlugin(HW_PluginBase):
client . load_device_by_xprv ( item , pin , passphrase_protection ,
label , language )
def _make_node_path ( self , xpub , address_n ) :
def _make_node_path ( self , xpub : str , address_n : Sequence [ int ] ) :
bip32node = BIP32Node . from_xkey ( xpub )
node = self . types . HDNodeType (
depth = bip32node . depth ,
@ -351,14 +351,9 @@ class KeepKeyPlugin(HW_PluginBase):
script_type = self . get_keepkey_input_script_type ( wallet . txin_type )
# prepare multisig, if available:
xpubs = wallet . get_master_public_keys ( )
if len ( xpubs ) > 1 :
pubkeys = wallet . get_public_keys ( address )
# sort xpubs using the order of pubkeys
sorted_pairs = sorted ( zip ( pubkeys , xpubs ) )
multisig = self . _make_multisig (
wallet . m ,
[ ( xpub , deriv_suffix ) for pubkey , xpub in sorted_pairs ] )
desc = wallet . get_script_descriptor_for_address ( address )
if multi := desc . get_simple_multisig ( ) :
multisig = self . _make_multisig ( multi )
else :
multisig = None
@ -378,8 +373,7 @@ class KeepKeyPlugin(HW_PluginBase):
assert keystore
assert ( desc := txin . script_descriptor )
if multi := desc . get_simple_multisig ( ) :
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout ( tx , txin )
multisig = self . _make_multisig ( multi . thresh , xpubs_and_deriv_suffixes )
multisig = self . _make_multisig ( multi )
else :
multisig = None
script_type = self . get_keepkey_input_script_type ( desc . to_legacy_electrum_script_type ( ) )
@ -407,14 +401,18 @@ class KeepKeyPlugin(HW_PluginBase):
return inputs
def _make_multisig ( self , m , xpubs ) :
if len ( xpubs ) == 1 :
return None
pubkeys = [ self . _make_node_path ( xpub , deriv ) for xpub , deriv in xpubs ]
def _make_multisig ( self , desc : descriptor . MultisigDescriptor ) :
pubkeys = [ ]
for pubkey_provider in desc . pubkeys :
assert not pubkey_provider . is_range ( )
assert pubkey_provider . extkey is not None
xpub = pubkey_provider . pubkey
der_suffix = pubkey_provider . get_der_suffix_int_list ( )
pubkeys . append ( self . _make_node_path ( xpub , der_suffix ) )
return self . types . MultisigRedeemScriptType (
pubkeys = pubkeys ,
signatures = [ b ' ' ] * len ( pubkeys ) ,
m = m )
m = desc . thresh )
def tx_outputs ( self , tx : PartialTransaction , * , keystore : ' KeepKey_KeyStore ' ) :
@ -422,8 +420,7 @@ class KeepKeyPlugin(HW_PluginBase):
assert ( desc := txout . script_descriptor )
script_type = self . get_keepkey_output_script_type ( desc . to_legacy_electrum_script_type ( ) )
if multi := desc . get_simple_multisig ( ) :
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout ( tx , txout )
multisig = self . _make_multisig ( multi . thresh , xpubs_and_deriv_suffixes )
multisig = self . _make_multisig ( multi )
else :
multisig = None
my_pubkey , full_path = keystore . find_my_pubkey_in_txinout ( txout )