1 from PyQt4.QtGui import *
2 from PyQt4.QtCore import *
3 import PyQt4.QtCore as QtCore
5 from electrum.i18n import _
6 from electrum import Wallet, mnemonic
8 from seed_dialog import SeedDialog
9 from network_dialog import NetworkDialog
11 from amountedit import AmountEdit
16 class InstallWizard(QDialog):
18 def __init__(self, config, network, storage):
19 QDialog.__init__(self)
21 self.network = network
22 self.storage = storage
23 self.setMinimumSize(575, 400)
24 self.setWindowTitle('Electrum')
25 self.connect(self, QtCore.SIGNAL('accept'), self.accept)
28 def restore_or_create(self):
33 msg = _("Electrum could not find an existing wallet.")+"\n\n"+_("Did you use Electrum before and want to restore a previous wallet or is this your first time and do you want to create a new wallet?")+"\n"
35 label.setWordWrap(True)
36 grid.addWidget(label, 0, 0)
41 b1.setText(_("Create new wallet"))
45 b2.setText(_("Restore wallet from seed"))
48 b3.setText(_("Restore wallet from master public key"))
50 grid.addWidget(b1,1,0)
51 grid.addWidget(b2,2,0)
52 grid.addWidget(b3,3,0)
54 vbox = QVBoxLayout(self)
58 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
73 def verify_seed(self, wallet):
74 r = self.seed_dialog(False)
78 if r != wallet.get_mnemonic(None):
79 QMessageBox.warning(None, _('Error'), _('Incorrect seed'), _('OK'))
85 def seed_dialog(self, is_restore=True):
87 if self.layout(): QWidget().setLayout(self.layout())
89 vbox = QVBoxLayout(self)
91 msg = _("Please enter your wallet seed.") + "\n"
93 msg = _("Your seed is important!") \
94 + "\n" + _("To make sure that you have properly saved your seed, please retype it here.")
97 logo.setPixmap(QPixmap(":icons/seed.png").scaledToWidth(56))
98 logo.setMaximumWidth(60)
101 label.setWordWrap(True)
104 seed_e.setMaximumHeight(100)
106 vbox.addWidget(label)
109 grid.addWidget(logo, 0, 0)
110 grid.addWidget(seed_e, 0, 1)
116 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
121 seed = unicode(seed_e.toPlainText())
124 QMessageBox.warning(None, _('Error'), _('No seed'), _('OK'))
131 def waiting_dialog(self, task, msg= _("Electrum is generating your addresses, please wait.")):
134 self.emit(QtCore.SIGNAL('accept'))
136 if self.layout(): QWidget().setLayout(self.layout())
137 vbox = QVBoxLayout(self)
138 self.waiting_label = QLabel(msg)
139 vbox.addWidget(self.waiting_label)
140 t = threading.Thread(target = target)
146 def mpk_dialog(self):
148 if self.layout(): QWidget().setLayout(self.layout())
150 vbox = QVBoxLayout(self)
152 vbox.addWidget(QLabel(_("Please enter your master public key.")))
157 label = QLabel(_("Key"))
158 grid.addWidget(label, 0, 0)
160 mpk_e.setMaximumHeight(100)
161 grid.addWidget(mpk_e, 0, 1)
163 label = QLabel(_("Chain"))
164 grid.addWidget(label, 1, 0)
165 chain_e = QTextEdit()
166 chain_e.setMaximumHeight(100)
167 grid.addWidget(chain_e, 1, 1)
172 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
174 if not self.exec_(): return None, None
176 mpk = str(mpk_e.toPlainText()).strip()
177 chain = str(chain_e.toPlainText()).strip()
181 def network_dialog(self):
183 if self.layout(): QWidget().setLayout(self.layout())
188 label = QLabel(_("Electrum communicates with remote servers to get information about your transactions and addresses. The servers all fulfil the same purpose only differing in hardware. In most cases you simply want to let Electrum pick one at random if you have a preference though feel free to select a server manually.") + "\n\n" \
189 + _("How do you want to connect to a server:")+" ")
190 label.setWordWrap(True)
191 grid.addWidget(label, 0, 0)
195 b1 = QRadioButton(gb)
196 b1.setText(_("Auto connect"))
199 b2 = QRadioButton(gb)
200 b2.setText(_("Select server manually"))
202 #b3 = QRadioButton(gb)
203 #b3.setText(_("Stay offline"))
205 grid.addWidget(b1,1,0)
206 grid.addWidget(b2,2,0)
207 #grid.addWidget(b3,3,0)
209 vbox = QVBoxLayout(self)
213 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
219 return NetworkDialog(self.network, self.config, None).do_exec()
222 self.config.set_key('auto_cycle', True, True)
226 self.config.set_key("server", None, True)
227 self.config.set_key('auto_cycle', False, True)
232 def show_seed(self, wallet):
233 from seed_dialog import make_seed_dialog
235 vbox = make_seed_dialog(wallet.get_mnemonic(None), wallet.imported_keys)
236 vbox.addLayout(ok_cancel_buttons(self, _("Next")))
238 if self.layout(): QWidget().setLayout(self.layout())
245 def password_dialog(self, wallet):
246 msg = _("Please choose a password to encrypt your wallet keys.")+'\n'\
247 +_("Leave these fields empty if you want to disable encryption.")
248 from password_dialog import make_password_dialog, run_password_dialog
249 if self.layout(): QWidget().setLayout(self.layout())
250 make_password_dialog(self, wallet, msg)
251 run_password_dialog(self, wallet, self)
256 action = self.restore_or_create()
257 if not action: exit()
259 wallet = Wallet(self.storage)
260 gap = self.config.get('gap_limit', 5)
262 wallet.gap_limit = gap
263 wallet.storage.put('gap_limit', gap, True)
265 if action == 'create':
266 wallet.init_seed(None)
267 self.show_seed(wallet)
268 if self.verify_seed(wallet):
271 wallet.create_accounts()
272 wallet.synchronize() # generate first addresses offline
273 self.waiting_dialog(create)
277 elif action == 'restore':
278 # ask for seed and gap.
279 seed = self.seed_dialog()
283 wallet.init_seed(seed)
285 QMessageBox.warning(None, _('Error'), _('Incorrect seed'), _('OK'))
290 elif action == 'watching':
291 # ask for seed and gap.
292 K, chain = self.mpk_dialog()
293 if not K or not chain:
296 wallet.create_watching_only_wallet(chain,K)
301 #if not self.config.get('server'):
302 self.network_dialog()
304 # start wallet threads
305 wallet.start_threads(self.network)
307 if action == 'restore':
309 self.waiting_dialog(lambda: wallet.restore(self.waiting_label.setText))
311 if wallet.is_found():
312 QMessageBox.information(None, _('Information'), _("Recovery successful"), _('OK'))
314 QMessageBox.information(None, _('Information'), _("No transactions found for this seed"), _('OK'))
316 wallet.fill_addressbook()
318 self.password_dialog(wallet)