mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-21 02:19:51 +00:00
psbt: follow-ups: fix trezor
This commit is contained in:
parent
dd14a3fde5
commit
cc4f6804b0
5 changed files with 46 additions and 23 deletions
|
@ -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]
|
||||||
xpubs = [xfp_to_xpub_map[xfp] for xfp in xfps]
|
try:
|
||||||
|
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]
|
||||||
|
|
|
@ -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
|
||||||
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin)
|
if len(txin.pubkeys) > 1:
|
||||||
multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes)
|
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_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)
|
||||||
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout)
|
if len(txout.pubkeys) > 1:
|
||||||
multisig = self._make_multisig(txout.num_sig, xpubs_and_deriv_suffixes)
|
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout)
|
||||||
|
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(
|
||||||
|
|
|
@ -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
|
||||||
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin)
|
if len(txin.pubkeys) > 1:
|
||||||
multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes)
|
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_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)
|
||||||
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout)
|
if len(txout.pubkeys) > 1:
|
||||||
multisig = self._make_multisig(txout.num_sig, xpubs_and_deriv_suffixes)
|
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout)
|
||||||
|
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(
|
||||||
|
|
|
@ -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
|
||||||
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txin)
|
if len(txin.pubkeys) > 1:
|
||||||
multisig = self._make_multisig(txin.num_sig, xpubs_and_deriv_suffixes)
|
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)
|
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)
|
||||||
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout)
|
if len(txout.pubkeys) > 1:
|
||||||
multisig = self._make_multisig(txout.num_sig, xpubs_and_deriv_suffixes)
|
xpubs_and_deriv_suffixes = get_xpubs_and_der_suffixes_from_txinout(tx, txout)
|
||||||
|
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(
|
||||||
|
|
|
@ -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…
Add table
Reference in a new issue