commit cf1f533613549e918bae5c73ae8a8d243fe8b933
parent 2385cc3ad8f1a72cafca42137272735bd1fdc2a1
Author: thomasv <thomasv@gitorious>
Date: Tue, 20 Nov 2012 15:30:46 +0100
allow offline creation/recovery within the gui
Diffstat:
M | electrum | | | 49 | +++++++++++++++++++++++++++++++------------------ |
M | lib/gui.py | | | 118 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
M | lib/gui_qt.py | | | 73 | ++++++++++++++++++++++++++++++++++++++----------------------------------- |
M | lib/interface.py | | | 2 | ++ |
4 files changed, 133 insertions(+), 109 deletions(-)
diff --git a/electrum b/electrum
@@ -197,36 +197,49 @@ if __name__ == '__main__':
else:
sys.exit("Error: Unknown GUI: " + pref_gui )
+ gui = gui.ElectrumGui(wallet, config)
+
interface = Interface(config, True)
+ wallet.interface = interface
interface.start()
interface.send([('server.peers.subscribe',[])])
- wallet.interface = interface
-
- gui = gui.ElectrumGui(wallet, config)
+ found = config.wallet_file_exists
+ if not found:
+ a = gui.restore_or_create()
+ if not a: exit()
+
+ if a =='create':
+ wallet.new_seed(None)
+ wallet.init_mpk( wallet.seed )
+ else:
+ # ask for seed and gap.
+ if not gui.seed_dialog(): exit()
+ wallet.init_mpk( wallet.seed )
+
+ # select a server.
+ s = gui.network_dialog()
+ if s is None:
+ gui.create_wallet()
+
+
interface.register_callback('peers', gui.server_list_changed)
verifier = WalletVerifier(interface, config)
wallet.set_verifier(verifier)
-
WalletSynchronizer(wallet, config).start()
- try:
- found = config.wallet_file_exists
- if not found:
- found = gui.restore_or_create()
- except SystemExit(e):
- exit(e)
- except BaseException(e):
- import traceback
- traceback.print_exc(file=sys.stdout)
- #gui.show_message(e.message)
- exit(1)
- if not found:
- exit(1)
+ if not found and a == 'restore' and s is not None:
+ try:
+ ok = gui.restore_wallet()
+ except:
+ import traceback
+ traceback.print_exc(file=sys.stdout)
+ exit()
- verifier.start()
+ if not ok: exit()
+ verifier.start()
gui.main(url)
wallet.save()
sys.exit(0)
diff --git a/lib/gui.py b/lib/gui.py
@@ -97,58 +97,8 @@ def restore_create_dialog(wallet):
dialog.destroy()
if r==2: return False
-
- is_recovery = (r==1)
-
- # ask for the server.
- if not run_network_dialog( wallet, parent=None ): return False
-
- if not is_recovery:
-
- wallet.new_seed(None)
- # generate first key
- wallet.init_mpk( wallet.seed )
- wallet.up_to_date_event.clear()
- wallet.update()
+ return 'restore' if r==1 else 'create'
- # run a dialog indicating the seed, ask the user to remember it
- show_seed_dialog(wallet, None, None)
-
- #ask for password
- change_password_dialog(wallet, None, None)
- else:
- # ask for seed and gap.
- run_recovery_dialog( wallet )
-
- dialog = gtk.MessageDialog(
- parent = None,
- flags = gtk.DIALOG_MODAL,
- buttons = gtk.BUTTONS_CANCEL,
- message_format = "Please wait..." )
- dialog.show()
-
- def recover_thread( wallet, dialog ):
- wallet.init_mpk( wallet.seed ) # not encrypted at this point
- wallet.up_to_date_event.clear()
- wallet.update()
-
- if wallet.is_found():
- # history and addressbook
- wallet.update_tx_history()
- wallet.fill_addressbook()
- print "Recovery successful"
-
- gobject.idle_add( dialog.destroy )
-
- thread.start_new_thread( recover_thread, ( wallet, dialog ) )
- r = dialog.run()
- dialog.destroy()
- if r==gtk.RESPONSE_CANCEL: return False
- if not wallet.is_found:
- show_message("No transactions found for this seed")
-
- wallet.save()
- return True
def run_recovery_dialog(wallet):
@@ -197,12 +147,13 @@ def run_recovery_dialog(wallet):
dialog.destroy()
if r==gtk.RESPONSE_CANCEL:
- sys.exit(1)
+ return False
+
try:
gap = int(gap)
except:
show_message("error")
- sys.exit(1)
+ return False
try:
seed.decode('hex')
@@ -211,11 +162,12 @@ def run_recovery_dialog(wallet):
seed = mnemonic.mn_decode( seed.split(' ') )
if not seed:
show_message("no seed")
- sys.exit(1)
+ return False
wallet.seed = seed
wallet.gap_limit = gap
wallet.save()
+ return True
@@ -328,7 +280,7 @@ def run_network_dialog( wallet, parent ):
status = "Not connected"
else:
import random
- status = "Please choose a server."
+ status = "Please choose a server.\nSelect cancel if you are offline."
server = interface.server
plist, servers_list = interface.get_servers_list()
@@ -575,6 +527,7 @@ class ElectrumWindow:
self.window.set_border_width(0)
self.window.connect('mykeypress', gtk.main_quit)
self.window.set_default_size(720, 350)
+ self.wallet_updated = False
vbox = gtk.VBox()
@@ -651,7 +604,6 @@ class ElectrumWindow:
self.context_id = self.status_bar.get_context_id("statusbar")
self.update_status_bar()
- self.wallet_updated = False
self.wallet.interface.register_callback('updated', self.update_callback)
@@ -1302,3 +1254,57 @@ class ElectrumGui():
def server_list_changed(self):
pass
+
+ def seed_dialog(self):
+ # ask for seed and gap.
+ return run_recovery_dialog( self.wallet )
+
+ def network_dialog(self):
+ return run_network_dialog( self.wallet, parent=None )
+
+ def create_wallet(self):
+ wallet = self.wallet
+ wallet.new_seed(None)
+ # generate first key
+ wallet.init_mpk( wallet.seed )
+ wallet.synchronize()
+ #wallet.up_to_date_event.clear()
+ #wallet.update()
+ # run a dialog indicating the seed, ask the user to remember it
+ show_seed_dialog(wallet, None, None)
+ #ask for password
+ change_password_dialog(wallet, None, None)
+
+ def restore_wallet(self):
+ wallet = self.wallet
+
+ dialog = gtk.MessageDialog(
+ parent = None,
+ flags = gtk.DIALOG_MODAL,
+ buttons = gtk.BUTTONS_CANCEL,
+ message_format = "Please wait..." )
+ dialog.show()
+ wallet.save()
+
+ def recover_thread( wallet, dialog ):
+ wallet.init_mpk( wallet.seed ) # not encrypted at this point
+ wallet.up_to_date_event.clear()
+ wallet.update()
+
+ if wallet.is_found():
+ # history and addressbook
+ wallet.update_tx_history()
+ wallet.fill_addressbook()
+ print "Recovery successful"
+
+ gobject.idle_add( dialog.destroy )
+
+ thread.start_new_thread( recover_thread, ( wallet, dialog ) )
+ r = dialog.run()
+ dialog.destroy()
+ if r==gtk.RESPONSE_CANCEL: return False
+ if not wallet.is_found:
+ show_message("No transactions found for this seed")
+
+ wallet.save()
+ return True
diff --git a/lib/gui_qt.py b/lib/gui_qt.py
@@ -1367,11 +1367,13 @@ class ElectrumWindow(QMainWindow):
status = _("Connected to")+" %s\n%d blocks"%(interface.host, wallet.verifier.height)
else:
status = _("Not connected")
+ server = interface.server
else:
import random
- status = _("Please choose a server.")
+ status = _("Please choose a server.") + "\n" + _("Select 'Cancel' if you are offline.")
+ server = None
+ interface.proxy = None
- server = interface.server
plist, servers_list = interface.get_servers_list()
d = QDialog(parent)
@@ -1414,8 +1416,6 @@ class ElectrumWindow(QMainWindow):
grid.addWidget(server_host, 0, 2)
grid.addWidget(server_port, 0, 3)
- host, port, protocol = server.split(':')
-
def change_protocol(p):
protocol = protocol_letters[p]
host = unicode(server_host.text())
@@ -1465,7 +1465,10 @@ class ElectrumWindow(QMainWindow):
server_protocol.model().setData(j, QtCore.QVariant(0,False), QtCore.Qt.UserRole-1)
- change_server(host,protocol)
+ if server:
+ host, port, protocol = server.split(':')
+ change_server(host,protocol)
+
servers_list_widget.connect(servers_list_widget, SIGNAL('itemClicked(QTreeWidgetItem*, int)'), lambda x: change_server(unicode(x.text(0))))
grid.addWidget(servers_list_widget, 1, 1, 1, 3)
@@ -1541,16 +1544,30 @@ class ElectrumGui:
def restore_or_create(self):
-
msg = _("Wallet file not found.")+"\n"+_("Do you want to create a new wallet, or to restore an existing one?")
r = QMessageBox.question(None, _('Message'), msg, _('Create'), _('Restore'), _('Cancel'), 0, 2)
- if r==2: return False
+ if r==2: return None
+ return 'restore' if r==1 else 'create'
+
+ def seed_dialog(self):
+ return ElectrumWindow.seed_dialog( self.wallet )
+
+ def network_dialog(self):
+ return ElectrumWindow.network_dialog( self.wallet, parent=None )
- is_recovery = (r==1)
+ def create_wallet(self):
wallet = self.wallet
- # ask for the server.
- if not ElectrumWindow.network_dialog( wallet, parent=None ): return False
+ # generate the first addresses
+ wallet.synchronize()
+ # run a dialog indicating the seed, ask the user to remember it
+ ElectrumWindow.show_seed_dialog(wallet)
+ # ask for password
+ ElectrumWindow.change_password_dialog(wallet)
+ wallet.save()
+
+ def restore_wallet(self):
+ wallet = self.wallet
# wait until we are connected, because the user might have selected another server
if not wallet.interface.is_connected:
waiting = lambda: False if wallet.interface.is_connected else "connecting...\n"
@@ -1559,32 +1576,18 @@ class ElectrumGui:
waiting = lambda: False if wallet.up_to_date else "Please wait...\nAddresses generated: %d\nKilobytes received: %.1f"\
%(len(wallet.all_addresses()), wallet.interface.bytes_received/1024.)
- if not is_recovery:
- wallet.new_seed(None)
- wallet.init_mpk( wallet.seed )
- wallet.up_to_date_event.clear()
- wallet.up_to_date = False
- wallet.interface.poke('synchronizer')
- waiting_dialog(waiting)
- # run a dialog indicating the seed, ask the user to remember it
- ElectrumWindow.show_seed_dialog(wallet)
- #ask for password
- ElectrumWindow.change_password_dialog(wallet)
+ wallet.up_to_date_event.clear()
+ wallet.up_to_date = False
+ wallet.interface.poke('synchronizer')
+ waiting_dialog(waiting)
+ if wallet.is_found():
+ # history and addressbook
+ wallet.fill_addressbook()
+ print "Recovery successful"
+ wallet.save()
else:
- # ask for seed and gap.
- if not ElectrumWindow.seed_dialog( wallet ): return False
- wallet.init_mpk( wallet.seed )
- wallet.up_to_date_event.clear()
- wallet.up_to_date = False
- wallet.interface.poke('synchronizer')
- waiting_dialog(waiting)
- if wallet.is_found():
- # history and addressbook
- wallet.fill_addressbook()
- print "Recovery successful"
- wallet.save()
- else:
- QMessageBox.information(None, _('Error'), _("No transactions found for this seed"), _('OK'))
+ QMessageBox.information(None, _('Error'), _("No transactions found for this seed"), _('OK'))
+ return False
wallet.save()
return True
diff --git a/lib/interface.py b/lib/interface.py
@@ -352,6 +352,8 @@ class Interface(threading.Thread):
def __init__(self, config=None, loop=False):
+ self.server = None
+ self.proxy = None
if config is None:
from simple_config import SimpleConfig