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
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)
27 self.stack = QStackedLayout()
28 self.setLayout(self.stack)
31 def set_layout(self, layout):
34 self.stack.setCurrentIndex(self.stack.addWidget(w))
37 def restore_or_create(self):
42 msg = _("Electrum could not find an existing wallet.") + "\n\n" \
43 + _("What do you want to do?") + "\n"
45 label.setWordWrap(True)
46 grid.addWidget(label, 0, 0)
51 b1.setText(_("Create new wallet"))
55 b2.setText(_("Restore an existing wallet from its seed"))
58 b3.setText(_("Create a watching-only version of an existing wallet"))
60 grid.addWidget(b1,1,0)
61 grid.addWidget(b2,2,0)
62 grid.addWidget(b3,3,0)
69 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
84 def verify_seed(self, wallet):
85 r = self.seed_dialog(False)
89 if r != wallet.get_mnemonic(None):
90 QMessageBox.warning(None, _('Error'), _('Incorrect seed'), _('OK'))
96 def seed_dialog(self, is_restore=True):
100 msg = _("Please enter your wallet seed.") + "\n"
102 msg = _("Your seed is important!") \
103 + "\n" + _("To make sure that you have properly saved your seed, please retype it here.")
106 logo.setPixmap(QPixmap(":icons/seed.png").scaledToWidth(56))
107 logo.setMaximumWidth(60)
110 label.setWordWrap(True)
113 seed_e.setMaximumHeight(100)
115 vbox.addWidget(label)
118 grid.addWidget(logo, 0, 0)
119 grid.addWidget(seed_e, 0, 1)
124 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
126 self.set_layout(vbox)
130 seed = unicode(seed_e.toPlainText())
133 QMessageBox.warning(None, _('Error'), _('No seed'), _('OK'))
140 def waiting_dialog(self, task, msg= _("Electrum is generating your addresses, please wait.")):
143 self.emit(QtCore.SIGNAL('accept'))
146 self.waiting_label = QLabel(msg)
147 vbox.addWidget(self.waiting_label)
148 self.set_layout(vbox)
149 t = threading.Thread(target = target)
155 def mpk_dialog(self):
158 vbox.addWidget(QLabel(_("Please enter your master public key.")))
163 label = QLabel(_("Key"))
164 grid.addWidget(label, 0, 0)
166 mpk_e.setMaximumHeight(100)
167 grid.addWidget(mpk_e, 0, 1)
169 label = QLabel(_("Chain"))
170 #grid.addWidget(label, 1, 0)
171 chain_e = QTextEdit()
172 chain_e.setMaximumHeight(100)
173 #grid.addWidget(chain_e, 1, 1)
178 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
180 self.set_layout(vbox)
184 mpk = str(mpk_e.toPlainText()).strip()
185 chain = str(chain_e.toPlainText()).strip()
189 def network_dialog(self):
194 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" \
195 + _("How do you want to connect to a server:")+" ")
196 label.setWordWrap(True)
197 grid.addWidget(label, 0, 0)
201 b1 = QRadioButton(gb)
202 b1.setText(_("Auto connect"))
205 b2 = QRadioButton(gb)
206 b2.setText(_("Select server manually"))
208 #b3 = QRadioButton(gb)
209 #b3.setText(_("Stay offline"))
211 grid.addWidget(b1,1,0)
212 grid.addWidget(b2,2,0)
213 #grid.addWidget(b3,3,0)
219 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
221 self.set_layout(vbox)
226 return NetworkDialog(self.network, self.config, None).do_exec()
229 self.config.set_key('auto_cycle', True, True)
233 self.config.set_key("server", None, True)
234 self.config.set_key('auto_cycle', False, True)
239 def show_seed(self, wallet):
240 from seed_dialog import make_seed_dialog
241 vbox = make_seed_dialog(wallet.get_mnemonic(None), wallet.imported_keys)
242 vbox.addLayout(ok_cancel_buttons(self, _("Next")))
243 self.set_layout(vbox)
247 def password_dialog(self, wallet):
248 msg = _("Please choose a password to encrypt your wallet keys.")+'\n'\
249 +_("Leave these fields empty if you want to disable encryption.")
250 from password_dialog import make_password_dialog, run_password_dialog
251 self.set_layout( make_password_dialog(self, wallet, msg) )
252 return run_password_dialog(self, wallet, self)
257 action = self.restore_or_create()
261 #gap = self.config.get('gap_limit', 5)
263 # wallet.gap_limit = gap
264 # wallet.storage.put('gap_limit', gap, True)
266 if action == 'create':
267 wallet = Wallet(self.storage)
268 wallet.init_seed(None)
269 if not self.show_seed(wallet):
271 if not self.verify_seed(wallet):
273 ok, old_password, password = self.password_dialog(wallet)
275 wallet.save_seed(password)
276 wallet.synchronize() # generate first addresses offline
277 self.waiting_dialog(create)
279 elif action == 'restore':
280 seed = self.seed_dialog()
283 wallet = Wallet.from_seed(seed, self.storage)
284 ok, old_password, password = self.password_dialog(wallet)
285 wallet.save_seed(password)
287 elif action == 'watching':
288 mpk = self.mpk_dialog()
292 wallet.create_watching_only_wallet(mpk)
296 #if not self.config.get('server'):
298 if self.network.interfaces:
299 self.network_dialog()
301 QMessageBox.information(None, _('Warning'), _('You are offline'), _('OK'))
305 # start wallet threads
306 wallet.start_threads(self.network)
308 if action == 'restore':
310 self.waiting_dialog(lambda: wallet.restore(self.waiting_label.setText))
313 if wallet.is_found():
314 QMessageBox.information(None, _('Information'), _("Recovery successful"), _('OK'))
316 QMessageBox.information(None, _('Information'), _("No transactions found for this seed"), _('OK'))
318 QMessageBox.information(None, _('Information'), _("This wallet was restored offline. It may contain more addresses than displayed."), _('OK'))