tgeneric restore from command line - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 26682491b29c1a33d5d50db44566a01108839162 DIR parent 614f3df4b83bf197e60a510269e71f5a32b36661 HTML Author: ThomasV <thomasv@electrum.org> Date: Tue, 27 Oct 2015 14:33:41 +0100 generic restore from command line Diffstat: M electrum | 29 +++++++++++------------------ M gui/qt/installwizard.py | 67 +++++++++++-------------------- M lib/commands.py | 7 ++++--- M lib/wallet.py | 21 +++++++++++++++++++++ 4 files changed, 59 insertions(+), 65 deletions(-) --- DIR diff --git a/electrum b/electrum t@@ -136,26 +136,17 @@ def init_cmdline(config): if cmd.name in ['create', 'restore']: if storage.file_exists: sys.exit("Error: Remove the existing wallet first!") - if config.get('password') is not None: - password = config.get('password') - elif cmd.name == 'restore' and config.get('mpk'): - password = None - else: - password = prompt_password("Password (hit return if you do not wish to encrypt your wallet):") + + def password_dialog(): + return prompt_password("Password (hit return if you do not wish to encrypt your wallet):") if cmd.name == 'restore': - mpk = config.get('mpk') - if mpk: - if Wallet.is_old_mpk(mpk): - wallet = Wallet.from_old_mpk(mpk, storage) - if Wallet.is_xpub(mpk): - wallet = Wallet.from_xpub(mpk, storage) - else: - import getpass - seed = getpass.getpass(prompt="seed:", stream=None) if config.get('concealed') else raw_input("seed:") - if not Wallet.is_seed(seed): - sys.exit("Error: Invalid seed") - wallet = Wallet.from_seed(seed, password, storage) + import getpass + text = getpass.getpass(prompt="seed:", stream=None) if config.get('concealed') else raw_input("seed or key(s):") + try: + wallet = Wallet.from_text(text, password_dialog, storage) + except BaseException as e: + sys.exit(str(e)) if not config.get('offline'): network = Network(config) t@@ -163,6 +154,7 @@ def init_cmdline(config): wallet.start_threads(network) print_msg("Recovering wallet...") wallet.restore(lambda x: x) + wallet.synchronize() if wallet.is_found(): print_msg("Recovery successful") else: t@@ -172,6 +164,7 @@ def init_cmdline(config): print_msg("Warning: This wallet was restored offline. It may contain more addresses than displayed.") else: + password = password_dialog() wallet = Wallet(storage) seed = wallet.make_seed() wallet.add_seed(seed, password) DIR diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py t@@ -561,47 +561,26 @@ class InstallWizard(QDialog): def restore(self, t): - - if t == 'standard': - text = self.enter_seed_dialog(MSG_ENTER_ANYTHING, None) - if not text: - return - if Wallet.is_xprv(text): - password = self.password_dialog() - wallet = Wallet.from_xprv(text, password, self.storage) - elif Wallet.is_old_mpk(text): - wallet = Wallet.from_old_mpk(text, self.storage) - elif Wallet.is_xpub(text): - wallet = Wallet.from_xpub(text, self.storage) - elif Wallet.is_address(text): - wallet = Wallet.from_address(text, self.storage) - elif Wallet.is_private_key(text): - password = self.password_dialog() - wallet = Wallet.from_private_key(text, password, self.storage) - elif Wallet.is_seed(text): - password = self.password_dialog() - wallet = Wallet.from_seed(text, password, self.storage) - else: - raise BaseException('unknown wallet type') - - elif re.match('(\d+)of(\d+)', t): - n = int(re.match('(\d+)of(\d+)', t).group(2)) - key_list = self.multi_seed_dialog(n - 1) - if not key_list: - return - password = self.password_dialog() if any(map(lambda x: Wallet.is_seed(x) or Wallet.is_xprv(x), key_list)) else None - wallet = Wallet.from_multisig(key_list, password, self.storage, t) - - else: - self.storage.put('wallet_type', t, False) - # call the constructor to load the plugin (side effect) - Wallet(self.storage) - wallet = always_hook('installwizard_restore', self, self.storage) - if not wallet: - util.print_error("no wallet") - return - - # create first keys offline - self.waiting_dialog(wallet.synchronize) - - return wallet + if t == 'standard': + text = self.enter_seed_dialog(MSG_ENTER_ANYTHING, None) + if not text: + return + wallet = Wallet.from_text(text, self.password_dialog, self.storage) + elif re.match('(\d+)of(\d+)', t): + n = int(re.match('(\d+)of(\d+)', t).group(2)) + key_list = self.multi_seed_dialog(n - 1) + if not key_list: + return + password = self.password_dialog() if any(map(lambda x: Wallet.is_seed(x) or Wallet.is_xprv(x), key_list)) else None + wallet = Wallet.from_multisig(key_list, password, self.storage, t) + else: + self.storage.put('wallet_type', t, False) + # call the constructor to load the plugin (side effect) + Wallet(self.storage) + wallet = always_hook('installwizard_restore', self, self.storage) + if not wallet: + util.print_error("no wallet") + return + # create first keys offline + self.waiting_dialog(wallet.synchronize) + return wallet DIR diff --git a/lib/commands.py b/lib/commands.py t@@ -103,8 +103,10 @@ class Commands: """Create a new wallet""" @command('') - def restore(self, concealed=False, mpk=None): - """Restore a wallet from seed. """ + def restore(self, concealed=False): + """Restore a wallet. A wallet can be restored from a seed phrase, a + master public key, a master private key, a list of bitcoin addresses + or bitcoin private keys.""" @command('w') def deseed(self): t@@ -629,7 +631,6 @@ command_options = { 'entropy': (None, "--entropy", "Custom entropy"), 'language': ("-L", "--lang", "Default language for wordlist"), 'gap_limit': ("-G", "--gap", "Gap limit"), - 'mpk': (None, "--mpk", "Restore from master public key"), 'deserialized':("-d", "--deserialized","Return deserialized transaction"), 'privkey': (None, "--privkey", "Private key. Set to '?' to get a prompt."), 'unsigned': ("-u", "--unsigned", "Do not sign transaction"), DIR diff --git a/lib/wallet.py b/lib/wallet.py t@@ -2085,3 +2085,24 @@ class Wallet(object): self.storage.put('use_encryption', self.use_encryption, True) self.create_main_account(password) return self + + @classmethod + def from_text(klass, text, password_dialog, storage): + if Wallet.is_xprv(text): + password = password_dialog() + wallet = klass.from_xprv(text, password, storage) + elif Wallet.is_old_mpk(text): + wallet = klass.from_old_mpk(text, storage) + elif Wallet.is_xpub(text): + wallet = klass.from_xpub(text, storage) + elif Wallet.is_address(text): + wallet = klass.from_address(text, storage) + elif Wallet.is_private_key(text): + password = password_dialog() + wallet = klass.from_private_key(text, password, storage) + elif Wallet.is_seed(text): + password = password_dialog() + wallet = klass.from_seed(text, password, storage) + else: + raise BaseException('Invalid seedphrase or key') + return wallet