From 5d68ce4f226985146f713cbde864ff6da7cf024b Mon Sep 17 00:00:00 2001 From: ThomasV Date: Tue, 29 Apr 2014 11:45:39 +0200 Subject: [PATCH] wizard: option to create multisig wallet manually --- gui/qt/installwizard.py | 61 +++++++++++++++++++++++++++++------------ lib/__init__.py | 2 +- lib/wallet.py | 16 +++++++---- 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py index 2fe9b3a62..a79c27313 100644 --- a/gui/qt/installwizard.py +++ b/gui/qt/installwizard.py @@ -3,7 +3,7 @@ from PyQt4.QtCore import * import PyQt4.QtCore as QtCore from electrum.i18n import _ -from electrum import Wallet, Wallet_2of3 +from electrum import Wallet, Wallet_2of2, Wallet_2of3 import seed_dialog from network_dialog import NetworkDialog @@ -250,14 +250,18 @@ class InstallWizard(QDialog): gb = QGroupBox() b1 = QRadioButton(gb) - b1.setText(_("Standard wallet (protected by password)")) + b1.setText(_("Standard wallet")) b1.setChecked(True) b2 = QRadioButton(gb) - b2.setText(_("Multi-signature wallet (two-factor authentication)")) + b2.setText(_("Wallet with two-factor authentication (plugin)")) + + b3 = QRadioButton(gb) + b3.setText(_("Multisig wallet (paired manually)")) grid.addWidget(b1,1,0) grid.addWidget(b2,2,0) + grid.addWidget(b3,3,0) vbox = QVBoxLayout() @@ -272,7 +276,9 @@ class InstallWizard(QDialog): if b1.isChecked(): return 'standard' elif b2.isChecked(): - return '2of3' + return 'multisig_plugin' + elif b3.isChecked(): + return 'multisig_manual' def run(self, action): @@ -283,17 +289,21 @@ class InstallWizard(QDialog): if action is None: return - if action == 'create': + if action == 'create': t = self.choose_wallet_type() if not t: return - if t == '2of3': - action = 'create_cold' - + if t == 'multisig_plugin': + action = 'create_2of3_1' + if t == 'multisig_manual': + action = 'create_2of2_1' - if action in ['create', 'create_cold', 'create_hot', 'create_remote']: + if action in ['create']: wallet = Wallet(self.storage) + elif action in ['create_2of2_1','create_2of2_2']: + wallet = Wallet_2of2(self.storage) + if action == 'create': seed = wallet.make_seed() @@ -304,16 +314,15 @@ class InstallWizard(QDialog): password = self.password_dialog() wallet.add_seed(seed, password) wallet.create_accounts(password) - # generate first addresses offline self.waiting_dialog(wallet.synchronize) - if action == 'create_cold': + if action == 'create_2of3_1': run_hook('create_cold_seed', self.storage, self) return - if action == 'create_hot': + if action in ['create_2of2_1', 'create_2of3_2']: msg = _('You are about to create the hot seed of a multisig wallet') if not self.question(msg): return @@ -324,10 +333,22 @@ class InstallWizard(QDialog): return password = self.password_dialog() wallet.add_seed(seed, password) - action = 'create_remote' + if action == 'create_2of2_1': + # display mpk + action = 'create_2of2_2' + else: + action = 'create_2of3_3' + if action == 'create_2of2_2': + xpub = self.enter_seed_dialog(True, 'cold') + if not Wallet.is_mpk(xpub): + return + wallet.add_master_public_key("cold/", xpub) + wallet.create_account() + self.waiting_dialog(wallet.synchronize) - if action == 'create_remote': + + if action == 'create_2of3_3': run_hook('create_remote_key', wallet, self) if not wallet.master_public_keys.get("remote/"): return @@ -352,13 +373,16 @@ class InstallWizard(QDialog): else: raise - elif t in ['2of2', '2of3']: + elif t in ['multisig_plugin', 'multisig_manual']: r = self.double_seed_dialog() if not r: return text1, text2 = r password = self.password_dialog() - wallet = Wallet_2of3(self.storage) + if t == 'multisig_manual': + wallet = Wallet_2of2(self.storage) + else: + wallet = Wallet_2of3(self.storage) if Wallet.is_seed(text1): wallet.add_seed(text1, password) @@ -375,9 +399,10 @@ class InstallWizard(QDialog): wallet.add_master_public_key("m/", text1) wallet.add_master_public_key("cold/", text2) - run_hook('restore_third_key', wallet, self) + if t == '2of3': + run_hook('restore_third_key', wallet, self) - wallet.create_accounts(None) + wallet.create_account() else: raise diff --git a/lib/__init__.py b/lib/__init__.py index 44d11d4ee..318a1e0ea 100644 --- a/lib/__init__.py +++ b/lib/__init__.py @@ -1,7 +1,7 @@ from version import ELECTRUM_VERSION from util import format_satoshis, print_msg, print_json, print_error, set_verbosity from wallet import WalletSynchronizer, WalletStorage -from wallet import Wallet, Wallet_2of3 +from wallet import Wallet, Wallet_2of2, Wallet_2of3 from verifier import TxVerifier from network import Network, DEFAULT_SERVERS, DEFAULT_PORTS, pick_random_server from interface import Interface diff --git a/lib/wallet.py b/lib/wallet.py index bc94861d1..46482eaa0 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -1486,8 +1486,7 @@ class Wallet_2of2(NewWallet): def can_create_accounts(self): return False - def create_account(self, account_id): - """Creates and saves the master keys, but does not save the account""" + def create_account(self): xpub1 = self.master_public_keys.get("m/") xpub2 = self.master_public_keys.get("cold/") account = BIP32_Account_2of2({'xpub':xpub1, 'xpub2':xpub2}) @@ -1498,6 +1497,13 @@ class Wallet_2of2(NewWallet): xpub2 = self.master_public_keys.get("cold/") return {'hot':xpub1, 'cold':xpub2} + def get_action(self): + xpub1 = self.master_public_keys.get("m/") + xpub2 = self.master_public_keys.get("cold/") + if xpub1 is None: + return 'create_2of2_1' + if xpub2 is None: + return 'create_2of2_2' @@ -1525,11 +1531,11 @@ class Wallet_2of3(Wallet_2of2): xpub2 = self.master_public_keys.get("cold/") xpub3 = self.master_public_keys.get("remote/") if xpub2 is None: - return 'create_cold' + return 'create_2of3_1' if xpub1 is None: - return 'create_hot' + return 'create_2of3_2' if xpub3 is None: - return 'create_remote' + return 'create_2of3_3' class WalletSynchronizer(threading.Thread):