diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py index e09c75114..749861ff5 100644 --- a/plugins/ledger/ledger.py +++ b/plugins/ledger/ledger.py @@ -7,7 +7,7 @@ import electrum from electrum.bitcoin import EncodeBase58Check, DecodeBase58Check, TYPE_ADDRESS from electrum.i18n import _ from electrum.plugins import BasePlugin, hook -from ..hw_wallet import BIP32_HW_Wallet +from electrum.keystore import Hardware_KeyStore from ..hw_wallet import HW_PluginBase from electrum.util import format_satoshis_plain, print_error @@ -26,12 +26,12 @@ except ImportError: BTCHIP = False -class BTChipWallet(BIP32_HW_Wallet): +class Ledger_KeyStore(Hardware_KeyStore): wallet_type = 'btchip' device = 'Ledger' - def __init__(self, storage): - BIP32_HW_Wallet.__init__(self, storage) + def __init__(self): + Hardware_KeyStore.__init__(self) # Errors and other user interaction is done through the wallet's # handler. The handler is per-window and preserved across # device reconnects @@ -39,6 +39,18 @@ class BTChipWallet(BIP32_HW_Wallet): self.force_watching_only = False self.device_checked = False self.signing = False + self.client = None + + def get_derivation(self): + return "m/44'/0'/%d'"%self.account_id + + def load(self, storage, name): + self.xpub = storage.get('master_public_keys', {}).get(name) + self.account_id = int(storage.get('account_id')) + + def init_xpub(self): + client = self.get_client() + self.xpub = self.get_public_key(self.get_derivation()) def give_error(self, message, clear_client = False): print_error(message) @@ -47,7 +59,7 @@ class BTChipWallet(BIP32_HW_Wallet): else: self.signing = False if clear_client: - self.plugin.client = None + self.client = None self.device_checked = False raise Exception(message) @@ -271,7 +283,7 @@ class BTChipWallet(BIP32_HW_Wallet): self.signing = False def check_proper_device(self): - pubKey = DecodeBase58Check(self.master_public_keys["x/0'"])[45:] + pubKey = DecodeBase58Check(self.xpub)[45:] if not self.device_checked: self.handler.show_message("Checking device") try: @@ -306,24 +318,7 @@ class BTChipWallet(BIP32_HW_Wallet): return False, None, None return True, response, response - -class LedgerPlugin(HW_PluginBase): - libraries_available = BTCHIP - wallet_class = BTChipWallet - - def __init__(self, parent, config, name): - HW_PluginBase.__init__(self, parent, config, name) - # FIXME shouldn't be a plugin member. Then this constructor can go. - self.client = None - - def btchip_is_connected(self, wallet): - try: - wallet.get_client().getFirmwareVersion() - except: - return False - return True - - def get_client(self, wallet, force_pair=True, noPin=False): + def get_client(self, force_pair=True, noPin=False): aborted = False client = self.client if not client or client.bad: @@ -388,8 +383,21 @@ class LedgerPlugin(HW_PluginBase): else: raise e client.bad = False - wallet.device_checked = False - wallet.proper_device = False + self.device_checked = False + self.proper_device = False self.client = client return self.client + + +class LedgerPlugin(HW_PluginBase): + libraries_available = BTCHIP + keystore_class = Ledger_KeyStore + + def btchip_is_connected(self, keystore): + try: + keystore.get_client().getFirmwareVersion() + except Exception as e: + self.print_error("get_client", str(e)) + return False + return True diff --git a/plugins/ledger/qt.py b/plugins/ledger/qt.py index 0dfec8982..4b61eedf8 100644 --- a/plugins/ledger/qt.py +++ b/plugins/ledger/qt.py @@ -6,40 +6,41 @@ import PyQt4.QtCore as QtCore from electrum.i18n import _ from electrum.plugins import hook -from .ledger import LedgerPlugin, BTChipWallet +from .ledger import LedgerPlugin, Ledger_KeyStore from ..hw_wallet.qt import QtHandlerBase class Plugin(LedgerPlugin): @hook def load_wallet(self, wallet, window): - if type(wallet) != BTChipWallet: + keystore = wallet.get_keystore() + if type(keystore) != self.keystore_class: return - wallet.handler = BTChipQTHandler(window) - if self.btchip_is_connected(wallet): - if not wallet.check_proper_device(): + keystore.handler = BTChipQTHandler(window) + if self.btchip_is_connected(keystore): + if not keystore.check_proper_device(): window.show_error(_("This wallet does not match your Ledger device")) wallet.force_watching_only = True else: window.show_error(_("Ledger device not detected.\nContinuing in watching-only mode.")) wallet.force_watching_only = True - def on_create_wallet(self, wallet, wizard): - assert type(wallet) == self.wallet_class - wallet.handler = BTChipQTHandler(wizard) -# self.select_device(wallet) - wallet.create_hd_account(None) + def on_create_wallet(self, keystore, wizard): + assert type(keystore) == self.keystore_class + keystore.handler = BTChipQTHandler(wizard) + keystore.init_xpub() + print keystore.xpub + wizard.create_wallet(keystore, None) class BTChipQTHandler(QtHandlerBase): def __init__(self, win): super(BTChipQTHandler, self).__init__(win, 'Ledger') - def word_dialog(self, msg): response = QInputDialog.getText(self.top_level_window(), "Ledger Wallet Authentication", msg, QLineEdit.Password) if not response[1]: self.word = None else: self.word = str(response[0]) - self.done.set() + self.done.set()