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)
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" + ' ')
92 msg += _("Your seed can be entered as a sequence of words, or as a hexadecimal string."+ ' \n')
94 msg = _("Your seed is important!") \
95 + "\n" + _("To make sure that you have properly saved your seed, please retype it here." + ' ')
98 logo.setPixmap(QPixmap(":icons/seed.png").scaledToWidth(56))
99 logo.setMaximumWidth(60)
102 label.setWordWrap(True)
105 seed_e.setMaximumHeight(100)
107 vbox.addWidget(label)
110 grid.addWidget(logo, 0, 0)
111 grid.addWidget(seed_e, 0, 1)
117 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
123 seed = str(seed_e.toPlainText())
127 seed = mnemonic.mn_decode( seed.split() )
129 QMessageBox.warning(None, _('Error'), _('I cannot decode this'), _('OK'))
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'))
145 if self.layout(): QWidget().setLayout(self.layout())
146 vbox = QVBoxLayout(self)
147 self.waiting_label = QLabel(msg)
148 vbox.addWidget(self.waiting_label)
150 t = threading.Thread(target = target)
156 def mpk_dialog(self):
158 if self.layout(): QWidget().setLayout(self.layout())
160 vbox = QVBoxLayout(self)
161 msg = _("Please enter your master public key.")
164 label.setWordWrap(True)
165 vbox.addWidget(label)
168 mpk_e.setMaximumHeight(100)
169 vbox.addWidget(mpk_e)
176 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
178 if not self.exec_(): return
180 mpk = str(mpk_e.toPlainText())
184 def network_dialog(self):
186 if self.layout(): QWidget().setLayout(self.layout())
191 label = QLabel(_("Electrum communicates with Electrum 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 or stay offline.") + "\n\n" \
192 + _("How do you want to connect to a server: "))
193 label.setWordWrap(True)
194 grid.addWidget(label, 0, 0)
198 b1 = QRadioButton(gb)
199 b1.setText(_("Auto connect"))
202 b2 = QRadioButton(gb)
203 b2.setText(_("Select server manually"))
205 b3 = QRadioButton(gb)
206 b3.setText(_("Stay offline"))
208 grid.addWidget(b1,1,0)
209 grid.addWidget(b2,2,0)
210 grid.addWidget(b3,3,0)
212 vbox = QVBoxLayout(self)
216 vbox.addLayout(ok_cancel_buttons(self, _('Next')))
222 return NetworkDialog(self.network, self.config, None).do_exec()
225 self.config.set_key('auto_cycle', True, True)
229 self.config.set_key("server", None, True)
230 self.config.set_key('auto_cycle', False, True)
235 def show_seed(self, wallet):
236 from seed_dialog import make_seed_dialog
237 if self.layout(): QWidget().setLayout(self.layout())
238 make_seed_dialog(self, wallet.seed, wallet.imported_keys)
242 def password_dialog(self, wallet):
243 msg = _("Please choose a password to encrypt your wallet keys.")+'\n'\
244 +_("Leave these fields empty if you want to disable encryption.")
245 from password_dialog import make_password_dialog, run_password_dialog
246 if self.layout(): QWidget().setLayout(self.layout())
247 make_password_dialog(self, wallet, msg)
248 run_password_dialog(self, wallet, self)
253 action = self.restore_or_create()
254 if not action: exit()
256 wallet = Wallet(self.storage)
257 gap = self.config.get('gap_limit', 5)
259 wallet.gap_limit = gap
260 wallet.storage.put('gap_limit', gap, True)
262 if action == 'create':
263 wallet.init_seed(None)
264 self.show_seed(wallet)
265 if self.verify_seed(wallet):
268 wallet.create_accounts()
269 wallet.synchronize() # generate first addresses offline
270 self.waiting_dialog(create)
274 elif action == 'restore':
275 # ask for seed and gap.
276 seed = self.seed_dialog()
279 wallet.init_seed(str(seed))
282 elif action == 'watching':
283 # ask for seed and gap.
284 mpk = self.mpk_dialog()
293 QMessageBox.warning(None, _('Error'), _('error'), _('OK'))
295 wallet.create_watching_only_wallet(c0,K0)
300 #if not self.config.get('server'):
301 self.network_dialog()
303 # start wallet threads
304 wallet.start_threads(self.network)
306 if action == 'restore':
308 self.waiting_dialog(lambda: wallet.restore(self.waiting_label.setText))
310 if wallet.is_found():
311 QMessageBox.information(None, _('Information'), _("Recovery successful"), _('OK'))
313 QMessageBox.information(None, _('Information'), _("No transactions found for this seed"), _('OK'))
315 wallet.fill_addressbook()
317 self.password_dialog(wallet)