From 8fa019f65b1971ba42aec7fab1f90302ebaa558e Mon Sep 17 00:00:00 2001 From: Marko Bencun Date: Wed, 7 Oct 2020 11:16:50 +0200 Subject: [PATCH] plugins/bitbox02: add support for p2wsh-p2sh multisig --- electrum/plugins/bitbox02/bitbox02.py | 32 ++++++++++++++++++--------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/electrum/plugins/bitbox02/bitbox02.py b/electrum/plugins/bitbox02/bitbox02.py index bbb6e717c..d42c5af21 100644 --- a/electrum/plugins/bitbox02/bitbox02.py +++ b/electrum/plugins/bitbox02/bitbox02.py @@ -229,6 +229,11 @@ class BitBox02Client(HardwareClientBase): out_type = bitbox02.btc.BTCPubRequest.YPUB else: out_type = bitbox02.btc.BTCPubRequest.UPUB + elif xtype == "p2wsh-p2sh": + if coin_network == bitbox02.btc.BTC: + out_type = bitbox02.btc.BTCPubRequest.CAPITAL_YPUB + else: + out_type = bitbox02.btc.BTCPubRequest.CAPITAL_UPUB elif xtype == "p2wsh": if coin_network == bitbox02.btc.BTC: out_type = bitbox02.btc.BTCPubRequest.CAPITAL_ZPUB @@ -276,13 +281,14 @@ class BitBox02Client(HardwareClientBase): @runs_in_hwd_thread def btc_multisig_config( - self, coin, bip32_path: List[int], wallet: Multisig_Wallet + self, coin, bip32_path: List[int], wallet: Multisig_Wallet, xtype: str, ): """ Set and get a multisig config with the current device and some other arbitrary xpubs. Registers it on the device if not already registered. + xtype: 'p2wsh' | 'p2wsh-p2sh' """ - + assert xtype in ("p2wsh", "p2wsh-p2sh") if self.bitbox02_device is None: raise Exception( "Need to setup communication first before attempting any BitBox02 calls" @@ -291,7 +297,7 @@ class BitBox02Client(HardwareClientBase): account_keypath = bip32_path[:4] xpubs = wallet.get_master_public_keys() our_xpub = self.get_xpub( - bip32.convert_bip32_intpath_to_strpath(account_keypath), "p2wsh" + bip32.convert_bip32_intpath_to_strpath(account_keypath), xtype ) multisig_config = bitbox02.btc.BTCScriptConfig( @@ -299,6 +305,10 @@ class BitBox02Client(HardwareClientBase): threshold=wallet.m, xpubs=[util.parse_xpub(xpub) for xpub in xpubs], our_xpub_index=xpubs.index(our_xpub), + script_type={ + "p2wsh": bitbox02.btc.BTCScriptConfig.Multisig.P2WSH, + "p2wsh-p2sh": bitbox02.btc.BTCScriptConfig.Multisig.P2WSH_P2SH, + }[xtype] ) ) @@ -341,13 +351,13 @@ class BitBox02Client(HardwareClientBase): script_config = bitbox02.btc.BTCScriptConfig( simple_type=bitbox02.btc.BTCScriptConfig.P2WPKH_P2SH ) - elif address_type == "p2wsh": + elif address_type in ("p2wsh-p2sh", "p2wsh"): if type(wallet) is Multisig_Wallet: script_config = self.btc_multisig_config( - coin_network, address_keypath, wallet + coin_network, address_keypath, wallet, address_type, ) else: - raise Exception("Can only use p2wsh with multisig wallets") + raise Exception("Can only use p2wsh-p2sh or p2wsh with multisig wallets") else: raise Exception( "invalid address xtype: {} is not supported by the BitBox02".format( @@ -446,11 +456,11 @@ class BitBox02Client(HardwareClientBase): tx_script_type = bitbox02.btc.BTCScriptConfig( simple_type=bitbox02.btc.BTCScriptConfig.P2WPKH_P2SH ) - elif tx_script_type == "p2wsh": + elif tx_script_type in ("p2wsh-p2sh", "p2wsh"): if type(wallet) is Multisig_Wallet: - tx_script_type = self.btc_multisig_config(coin, full_path, wallet) + tx_script_type = self.btc_multisig_config(coin, full_path, wallet, tx_script_type) else: - raise Exception("Can only use p2wsh with multisig wallets") + raise Exception("Can only use p2wsh-p2sh or p2wsh with multisig wallets") else: raise UserFacingException( "invalid input script type: {} is not supported by the BitBox02".format( @@ -602,7 +612,7 @@ class BitBox02Plugin(HW_PluginBase): minimum_library = (5, 0, 0) DEVICE_IDS = [(0x03EB, 0x2403)] - SUPPORTED_XTYPES = ("p2wpkh-p2sh", "p2wpkh", "p2wsh") + SUPPORTED_XTYPES = ("p2wpkh-p2sh", "p2wpkh", "p2wsh", "p2wsh-p2sh") def __init__(self, parent: HW_PluginBase, config: SimpleConfig, name: str): super().__init__(parent, config, name) @@ -647,7 +657,7 @@ class BitBox02Plugin(HW_PluginBase): ): if xtype not in self.SUPPORTED_XTYPES: raise ScriptTypeNotSupported( - _("This type of script is not supported with {}.").format(self.device) + _("This type of script is not supported with {}: {}").format(self.device, xtype) ) client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard) assert isinstance(client, BitBox02Client)