use random seed; do not trust the user for entropy
This commit is contained in:
parent
99a269fcf5
commit
2d835ed0c0
|
@ -171,8 +171,6 @@ oid_secp256k1 = (1,3,132,0,10)
|
||||||
SECP256k1 = ecdsa.curves.Curve("SECP256k1", curve_secp256k1, generator_secp256k1, oid_secp256k1 )
|
SECP256k1 = ecdsa.curves.Curve("SECP256k1", curve_secp256k1, generator_secp256k1, oid_secp256k1 )
|
||||||
|
|
||||||
|
|
||||||
no_wallet_message = "Wallet file not found.\nPlease provide a seed and a password. The seed will be to generate Bitcoin addresses. It should be long and random, and nobody should be able to guess it. Memorize it, or write it down and keep it in a vault. The password will be used to encrypt your local wallet file. You will need to enter your password everytime you use your wallet. If you lose your password, you can still recover your wallet with the seed."
|
|
||||||
|
|
||||||
def filter(s):
|
def filter(s):
|
||||||
out = re.sub('( [^\n]*|)\n','',s)
|
out = re.sub('( [^\n]*|)\n','',s)
|
||||||
out = out.replace(' ','')
|
out = out.replace(' ','')
|
||||||
|
@ -228,6 +226,7 @@ class Wallet:
|
||||||
self.host = 'ecdsa.org'
|
self.host = 'ecdsa.org'
|
||||||
self.port = 50000
|
self.port = 50000
|
||||||
self.fee = 0.005
|
self.fee = 0.005
|
||||||
|
self.version = 1
|
||||||
|
|
||||||
# saved fields
|
# saved fields
|
||||||
self.use_encryption = False
|
self.use_encryption = False
|
||||||
|
@ -245,6 +244,10 @@ class Wallet:
|
||||||
self.message = ''
|
self.message = ''
|
||||||
self.tx_history = {}
|
self.tx_history = {}
|
||||||
|
|
||||||
|
def new_seed(self, password):
|
||||||
|
seed = "%032x"%ecdsa.util.randrange( pow(2,128) )
|
||||||
|
self.seed = wallet.pw_encode( seed, password)
|
||||||
|
|
||||||
def is_mine(self, address):
|
def is_mine(self, address):
|
||||||
return address in self.addresses
|
return address in self.addresses
|
||||||
|
|
||||||
|
@ -260,6 +263,10 @@ class Wallet:
|
||||||
|
|
||||||
def create_new_address(self, for_change, password):
|
def create_new_address(self, for_change, password):
|
||||||
seed = self.pw_decode( self.seed, password)
|
seed = self.pw_decode( self.seed, password)
|
||||||
|
# strenghtening
|
||||||
|
for i in range(100000):
|
||||||
|
oldseed = seed
|
||||||
|
seed = hashlib.sha512(seed + oldseed).digest()
|
||||||
i = len( self.addresses ) - len(self.change_addresses) if not for_change else len(self.change_addresses)
|
i = len( self.addresses ) - len(self.change_addresses) if not for_change else len(self.change_addresses)
|
||||||
seed = Hash( "%d:%d:"%(i,for_change) + seed )
|
seed = Hash( "%d:%d:"%(i,for_change) + seed )
|
||||||
order = generator_secp256k1.order()
|
order = generator_secp256k1.order()
|
||||||
|
@ -283,23 +290,30 @@ class Wallet:
|
||||||
|
|
||||||
def recover(self, password):
|
def recover(self, password):
|
||||||
seed = self.pw_decode( self.seed, password)
|
seed = self.pw_decode( self.seed, password)
|
||||||
|
|
||||||
# todo: recover receiving addresses from tx
|
# todo: recover receiving addresses from tx
|
||||||
num_gap = 0
|
is_found = False
|
||||||
while True:
|
while True:
|
||||||
addr = self.create_new_address(True, password)
|
addr = self.create_new_address(True, password)
|
||||||
print "recovering", addr
|
#print "recovering", addr
|
||||||
if self.status[addr] is None: break
|
if self.status[addr] is not None:
|
||||||
|
is_found = True
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
num_gap = 0
|
num_gap = 0
|
||||||
while True:
|
while True:
|
||||||
addr = self.create_new_address(False, password)
|
addr = self.create_new_address(False, password)
|
||||||
print "recovering", addr
|
#print "recovering", addr
|
||||||
if self.status[addr] is None:
|
if self.status[addr] is None:
|
||||||
num_gap += 1
|
num_gap += 1
|
||||||
if num_gap == self.gap_limit: break
|
if num_gap == self.gap_limit: break
|
||||||
else:
|
else:
|
||||||
|
is_found = True
|
||||||
num_gap = 0
|
num_gap = 0
|
||||||
|
|
||||||
|
if not is_found: return False
|
||||||
|
|
||||||
# remove limit-1 addresses. [ this is ok, because change addresses are at the beginning of the list]
|
# remove limit-1 addresses. [ this is ok, because change addresses are at the beginning of the list]
|
||||||
n = self.gap_limit
|
n = self.gap_limit
|
||||||
self.addresses = self.addresses[:-n]
|
self.addresses = self.addresses[:-n]
|
||||||
|
@ -316,9 +330,10 @@ class Wallet:
|
||||||
self.addressbook.append(i)
|
self.addressbook.append(i)
|
||||||
# redo labels
|
# redo labels
|
||||||
self.update_tx_labels()
|
self.update_tx_labels()
|
||||||
|
return True
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
s = repr( (self.use_encryption, self.fee, self.host, self.blocks,
|
s = repr( (self.version, self.use_encryption, self.fee, self.host, self.blocks,
|
||||||
self.seed, self.addresses, self.private_keys,
|
self.seed, self.addresses, self.private_keys,
|
||||||
self.change_addresses, self.status, self.history,
|
self.change_addresses, self.status, self.history,
|
||||||
self.labels, self.addressbook) )
|
self.labels, self.addressbook) )
|
||||||
|
@ -334,11 +349,13 @@ class Wallet:
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
(self.use_encryption, self.fee, self.host, self.blocks,
|
sequence = ast.literal_eval( data )
|
||||||
|
(self.version, self.use_encryption, self.fee, self.host, self.blocks,
|
||||||
self.seed, self.addresses, self.private_keys,
|
self.seed, self.addresses, self.private_keys,
|
||||||
self.change_addresses, self.status, self.history,
|
self.change_addresses, self.status, self.history,
|
||||||
self.labels, self.addressbook) = ast.literal_eval( data )
|
self.labels, self.addressbook) = sequence
|
||||||
except:
|
except:
|
||||||
|
if len(sequence) == 12: raise BaseException("version error.")
|
||||||
return False
|
return False
|
||||||
self.update_tx_history()
|
self.update_tx_history()
|
||||||
return True
|
return True
|
||||||
|
@ -572,6 +589,10 @@ class Wallet:
|
||||||
return True, tx_hash
|
return True, tx_hash
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
cmd = sys.argv[1]
|
cmd = sys.argv[1]
|
||||||
|
@ -591,11 +612,7 @@ if __name__ == '__main__':
|
||||||
gui.main()
|
gui.main()
|
||||||
|
|
||||||
if not wallet.read():
|
if not wallet.read():
|
||||||
print no_wallet_message
|
|
||||||
seed = raw_input("Enter seed: ")
|
|
||||||
if len(seed)<20:
|
|
||||||
print "Seed too short. Please at least 20 characters"
|
|
||||||
exit(1)
|
|
||||||
if has_encryption:
|
if has_encryption:
|
||||||
password = getpass.getpass("Password (hit return if you do not wish to encrypt your wallet):")
|
password = getpass.getpass("Password (hit return if you do not wish to encrypt your wallet):")
|
||||||
if password:
|
if password:
|
||||||
|
@ -607,26 +624,30 @@ if __name__ == '__main__':
|
||||||
password = None
|
password = None
|
||||||
print "in order to use wallet encryption, please install pycrypto (sudo easy_install pycrypto)"
|
print "in order to use wallet encryption, please install pycrypto (sudo easy_install pycrypto)"
|
||||||
|
|
||||||
wallet.seed = wallet.pw_encode( seed, password)
|
host = raw_input("server (default:ecdsa.org):")
|
||||||
|
port = raw_input("port (default:50000):")
|
||||||
print "server name and port number (default: ecdsa.org:50000)"
|
fee = raw_input("fee (default 0.005):")
|
||||||
host = raw_input("server:")
|
if fee: wallet.fee = float(fee)
|
||||||
if not host: host = 'ecdsa.org'
|
if host: wallet.host = host
|
||||||
|
if port: wallet.port = int(port)
|
||||||
port = raw_input("port:")
|
seed = raw_input("if you are restoring an existing wallet, enter the seed. otherwise just press enter: ")
|
||||||
if not port: port = 50000
|
|
||||||
else: port = int(port)
|
|
||||||
|
|
||||||
print "default fee for transactions (default 0.005)"
|
|
||||||
fee = raw_input("default fee:")
|
|
||||||
if not fee: fee = 0.005
|
|
||||||
|
|
||||||
wallet.fee = fee
|
|
||||||
wallet.gap_limit = 5
|
wallet.gap_limit = 5
|
||||||
wallet.host = host
|
if seed:
|
||||||
wallet.port = port
|
gap = raw_input("gap limit (default 5):")
|
||||||
wallet.recover(password)
|
if gap: wallet.gap_limit = int(gap)
|
||||||
wallet.save()
|
print "recovering wallet..."
|
||||||
|
r = wallet.recover(password)
|
||||||
|
if r:
|
||||||
|
print "recovery successful"
|
||||||
|
wallet.save()
|
||||||
|
else:
|
||||||
|
print "no wallet found"
|
||||||
|
else:
|
||||||
|
wallet.new_seed(None)
|
||||||
|
print "Your seed is", wallet.seed
|
||||||
|
print "Please store it safely"
|
||||||
|
# generate first key
|
||||||
|
wallet.create_new_address(False, None)
|
||||||
|
|
||||||
wallet.new_session()
|
wallet.new_session()
|
||||||
wallet.update()
|
wallet.update()
|
||||||
|
|
209
client/gui.py
209
client/gui.py
|
@ -39,79 +39,116 @@ def numbify(entry, is_int = False):
|
||||||
def init_wallet(wallet):
|
def init_wallet(wallet):
|
||||||
|
|
||||||
if not wallet.read():
|
if not wallet.read():
|
||||||
seed = None
|
|
||||||
while not seed:
|
# ask if the user wants to create a new wallet, or recover from a seed.
|
||||||
|
# if he wants to recover, and nothing is found, do not create wallet
|
||||||
|
dialog = gtk.Dialog("electrum", parent=None,
|
||||||
|
flags=gtk.DIALOG_MODAL|gtk.DIALOG_NO_SEPARATOR,
|
||||||
|
buttons= ("create", 0, "restore",1, "cancel",2) )
|
||||||
|
|
||||||
|
label = gtk.Label("Wallet file not found.\nDo you want to create a new wallet,\n or to restore an existing one?" )
|
||||||
|
label.show()
|
||||||
|
dialog.vbox.pack_start(label)
|
||||||
|
dialog.show()
|
||||||
|
r = dialog.run()
|
||||||
|
dialog.destroy()
|
||||||
|
if r==2:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
is_recovery = (r==1)
|
||||||
|
|
||||||
|
if not is_recovery:
|
||||||
|
|
||||||
|
wallet.new_seed(None)
|
||||||
|
|
||||||
|
# ask for the server.
|
||||||
|
run_settings_dialog(wallet, is_create=True, is_recovery=False)
|
||||||
|
|
||||||
|
# generate first key
|
||||||
|
wallet.create_new_address(False, None)
|
||||||
|
|
||||||
|
# run a dialog indicating the seed, ask the user to remember it
|
||||||
dialog = gtk.MessageDialog(
|
dialog = gtk.MessageDialog(
|
||||||
parent = None,
|
parent = None,
|
||||||
flags = gtk.DIALOG_MODAL,
|
flags = gtk.DIALOG_MODAL,
|
||||||
buttons = gtk.BUTTONS_OK_CANCEL,
|
buttons = gtk.BUTTONS_OK,
|
||||||
message_format = "Wallet not found. Please enter a seed to create or recover your wallet. Minimum length: 20 characters" )
|
message_format = "Your secret seed is:\n"+ wallet.seed+ "\n\nPlease keep it in a safe place; if you lose it, you will not be able to restore your wallet." )
|
||||||
|
|
||||||
p_box = gtk.HBox()
|
|
||||||
p_label = gtk.Label('Seed:')
|
|
||||||
p_label.show()
|
|
||||||
p_box.pack_start(p_label)
|
|
||||||
p_entry = gtk.Entry()
|
|
||||||
p_entry.show()
|
|
||||||
p_box.pack_start(p_entry)
|
|
||||||
p_box.show()
|
|
||||||
dialog.vbox.pack_start(p_box, False, True, 0)
|
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
r = dialog.run()
|
r = dialog.run()
|
||||||
seed = p_entry.get_text()
|
dialog.destroy()
|
||||||
|
|
||||||
|
#ask for password
|
||||||
|
change_password_dialog(wallet, None)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# ask for the server, seed and gap.
|
||||||
|
run_settings_dialog(wallet, is_create=True, is_recovery=True)
|
||||||
|
|
||||||
|
dialog = gtk.MessageDialog(
|
||||||
|
parent = None,
|
||||||
|
flags = gtk.DIALOG_MODAL,
|
||||||
|
buttons = gtk.BUTTONS_CANCEL,
|
||||||
|
message_format = "Please wait..." )
|
||||||
|
dialog.show()
|
||||||
|
|
||||||
|
def recover_thread( wallet, dialog, password ):
|
||||||
|
wallet.is_found = wallet.recover( password )
|
||||||
|
if wallet.is_found:
|
||||||
|
wallet.save()
|
||||||
|
gobject.idle_add( dialog.destroy )
|
||||||
|
|
||||||
|
thread.start_new_thread( recover_thread, ( wallet, dialog, None ) ) # no password
|
||||||
|
r = dialog.run()
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
if r==gtk.RESPONSE_CANCEL: exit(1)
|
if r==gtk.RESPONSE_CANCEL: exit(1)
|
||||||
if len(seed) < 20:
|
if not wallet.is_found:
|
||||||
print len(seed)
|
show_message("No transactions found for this seed")
|
||||||
seed = None
|
|
||||||
|
|
||||||
# disable password during recovery
|
|
||||||
# change_password_dialog(None, wallet)
|
|
||||||
|
|
||||||
wallet.seed = seed
|
def settings_dialog(wallet, is_create, is_recovery):
|
||||||
|
|
||||||
run_settings_dialog( None, wallet, True)
|
|
||||||
|
|
||||||
|
if is_create:
|
||||||
dialog = gtk.MessageDialog(
|
dialog = gtk.MessageDialog(
|
||||||
parent = None,
|
parent = None,
|
||||||
flags = gtk.DIALOG_MODAL,
|
flags = gtk.DIALOG_MODAL,
|
||||||
buttons = gtk.BUTTONS_CANCEL,
|
buttons = gtk.BUTTONS_OK_CANCEL,
|
||||||
message_format = "Please wait..." )
|
message_format = "Please indicate the server and port number" if not is_recovery else 'Please enter the seed, the server and gap')
|
||||||
dialog.show()
|
else:
|
||||||
|
dialog = gtk.Dialog("settings", parent=None,
|
||||||
def recover_thread( wallet, dialog, password ):
|
flags=gtk.DIALOG_MODAL|gtk.DIALOG_NO_SEPARATOR,
|
||||||
wallet.recover( password )
|
buttons= ("cancel", 0, "ok", 1) )
|
||||||
wallet.save()
|
|
||||||
gobject.idle_add( dialog.destroy )
|
|
||||||
|
|
||||||
thread.start_new_thread( recover_thread, ( wallet, dialog, None ) ) # no password
|
|
||||||
r = dialog.run()
|
|
||||||
dialog.destroy()
|
|
||||||
if r==gtk.RESPONSE_CANCEL: exit(1)
|
|
||||||
|
|
||||||
def settings_dialog(wallet, is_recover):
|
|
||||||
|
|
||||||
dialog = gtk.MessageDialog(
|
|
||||||
parent = None,
|
|
||||||
flags = gtk.DIALOG_MODAL,
|
|
||||||
buttons = gtk.BUTTONS_OK_CANCEL,
|
|
||||||
message_format = "Please indicate the server, and the gap limit if you are recovering a lost wallet." if is_recover else 'Settings')
|
|
||||||
|
|
||||||
|
vbox = dialog.vbox
|
||||||
dialog.set_default_response(gtk.RESPONSE_OK)
|
dialog.set_default_response(gtk.RESPONSE_OK)
|
||||||
|
|
||||||
gap = gtk.HBox()
|
if is_recovery:
|
||||||
gap_label = gtk.Label('Max. gap:')
|
# ask seed, server and gap in the same dialog
|
||||||
gap_label.set_size_request(100,10)
|
|
||||||
gap_label.show()
|
seed_box = gtk.HBox()
|
||||||
gap.pack_start(gap_label,False, False, 10)
|
seed_label = gtk.Label('Seed:')
|
||||||
gap_entry = gtk.Entry()
|
seed_label.show()
|
||||||
gap_entry.set_text("%d"%wallet.gap_limit)
|
seed_box.pack_start(seed_label)
|
||||||
gap_entry.connect('changed', numbify, True)
|
seed_entry = gtk.Entry()
|
||||||
gap_entry.show()
|
seed_entry.show()
|
||||||
gap.pack_start(gap_entry,False,False, 10)
|
seed_box.pack_start(seed_entry)
|
||||||
add_help_button(gap, 'The maximum gap that is allowed between unused addresses in your wallet. During wallet recovery, this parameter is used to decide when to stop the recovery process. If you increase this value, you will need to remember it in order to be able to recover your wallet from seed.')
|
seed_box.show()
|
||||||
gap.show()
|
vbox.pack_start(seed_box, False, False, 5)
|
||||||
|
|
||||||
|
if is_recovery or (not is_create):
|
||||||
|
gap = gtk.HBox()
|
||||||
|
gap_label = gtk.Label('Max. gap:')
|
||||||
|
gap_label.set_size_request(100,10)
|
||||||
|
gap_label.show()
|
||||||
|
gap.pack_start(gap_label,False, False, 10)
|
||||||
|
gap_entry = gtk.Entry()
|
||||||
|
gap_entry.set_text("%d"%wallet.gap_limit)
|
||||||
|
gap_entry.connect('changed', numbify, True)
|
||||||
|
gap_entry.show()
|
||||||
|
gap.pack_start(gap_entry,False,False, 10)
|
||||||
|
add_help_button(gap, 'The maximum gap that is allowed between unused addresses in your wallet. During wallet recovery, this parameter is used to decide when to stop the recovery process. If you increase this value, you will need to remember it in order to be able to recover your wallet from seed.')
|
||||||
|
gap.show()
|
||||||
|
vbox.pack_start(gap, False,False, 5)
|
||||||
|
|
||||||
host = gtk.HBox()
|
host = gtk.HBox()
|
||||||
host_label = gtk.Label('Server:')
|
host_label = gtk.Label('Server:')
|
||||||
|
@ -124,10 +161,11 @@ def settings_dialog(wallet, is_recover):
|
||||||
host.pack_start(host_entry,False,False, 10)
|
host.pack_start(host_entry,False,False, 10)
|
||||||
add_help_button(host, 'The name and port number of your Bitcoin server, separated by a colon. Example: ecdsa.org:50000')
|
add_help_button(host, 'The name and port number of your Bitcoin server, separated by a colon. Example: ecdsa.org:50000')
|
||||||
host.show()
|
host.show()
|
||||||
|
vbox.pack_start(host, False,False, 5)
|
||||||
|
|
||||||
fee = gtk.HBox()
|
if not is_create:
|
||||||
fee_entry = gtk.Entry()
|
fee = gtk.HBox()
|
||||||
if not is_recover:
|
fee_entry = gtk.Entry()
|
||||||
fee_label = gtk.Label('Tx. fee:')
|
fee_label = gtk.Label('Tx. fee:')
|
||||||
fee_label.set_size_request(100,10)
|
fee_label.set_size_request(100,10)
|
||||||
fee_label.show()
|
fee_label.show()
|
||||||
|
@ -138,33 +176,41 @@ def settings_dialog(wallet, is_recover):
|
||||||
fee.pack_start(fee_entry,False,False, 10)
|
fee.pack_start(fee_entry,False,False, 10)
|
||||||
add_help_button(fee, 'Transaction fee. Recommended value:0.005')
|
add_help_button(fee, 'Transaction fee. Recommended value:0.005')
|
||||||
fee.show()
|
fee.show()
|
||||||
|
vbox.pack_start(fee, False,False, 5)
|
||||||
|
|
||||||
vbox = dialog.vbox
|
if not is_create:
|
||||||
vbox.pack_start(host, False,False, 5)
|
return dialog, fee_entry, gap_entry, host_entry
|
||||||
vbox.pack_start(gap, False,False, 5)
|
elif is_recovery:
|
||||||
vbox.pack_start(fee, False, False, 5)
|
return dialog, seed_entry, gap_entry, host_entry
|
||||||
return dialog, gap_entry, host_entry, fee_entry
|
else:
|
||||||
|
return dialog, host_entry
|
||||||
|
|
||||||
|
|
||||||
def run_settings_dialog( widget, wallet, is_recovery):
|
def run_settings_dialog( wallet, is_create, is_recovery):
|
||||||
dialog, gap_entry, host_entry, fee_entry = settings_dialog(wallet, is_recovery)
|
|
||||||
|
if not is_create:
|
||||||
|
dialog, fee_entry, gap_entry, host_entry = settings_dialog(wallet, is_create, is_recovery)
|
||||||
|
elif is_recovery:
|
||||||
|
dialog, seed_entry, gap_entry, host_entry = settings_dialog(wallet, is_create, is_recovery)
|
||||||
|
else:
|
||||||
|
dialog, host_entry, = settings_dialog(wallet, is_create, is_recovery)
|
||||||
|
|
||||||
dialog.show()
|
dialog.show()
|
||||||
r = dialog.run()
|
r = dialog.run()
|
||||||
gap = gap_entry.get_text()
|
|
||||||
hh = host_entry.get_text()
|
hh = host_entry.get_text()
|
||||||
fee = fee_entry.get_text()
|
if is_recovery:
|
||||||
|
gap = gap_entry.get_text()
|
||||||
|
seed = seed_entry.get_text()
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
if r==-6:
|
if r==-6:
|
||||||
if is_recovery:
|
exit(1)
|
||||||
exit(1)
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
a, b = hh.split(':')
|
a, b = hh.split(':')
|
||||||
wallet.gap_limit = int(gap)
|
|
||||||
wallet.host = a
|
wallet.host = a
|
||||||
wallet.port = int(b)
|
wallet.port = int(b)
|
||||||
wallet.fee = float(fee)
|
if is_recovery:
|
||||||
|
wallet.seed = seed
|
||||||
|
wallet.gap_limit = int(gap)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -205,9 +251,14 @@ def password_dialog():
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
if result: return pw
|
if result: return pw
|
||||||
|
|
||||||
def change_password_dialog(button, wallet, icon):
|
def change_password_dialog(wallet, icon):
|
||||||
dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL,
|
if icon:
|
||||||
'Your wallet is encrypted' if wallet.use_encryption else 'Your wallet is not encrypted')
|
msg = 'Your wallet is encrypted' if wallet.use_encryption else 'Your wallet is not encrypted'
|
||||||
|
else:
|
||||||
|
msg = "Please choose a password to encrypt your wallet keys"
|
||||||
|
|
||||||
|
dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, msg)
|
||||||
|
|
||||||
if wallet.use_encryption:
|
if wallet.use_encryption:
|
||||||
current_pw, current_pw_entry = password_line('Current password:')
|
current_pw, current_pw_entry = password_line('Current password:')
|
||||||
dialog.vbox.pack_start(current_pw, False, True, 0)
|
dialog.vbox.pack_start(current_pw, False, True, 0)
|
||||||
|
@ -308,7 +359,7 @@ class BitcoinGUI:
|
||||||
settings_icon.show()
|
settings_icon.show()
|
||||||
|
|
||||||
prefs_button = gtk.Button()
|
prefs_button = gtk.Button()
|
||||||
prefs_button.connect("clicked", run_settings_dialog, self.wallet, False)
|
prefs_button.connect("clicked", lambda x: run_settings_dialog(self.wallet, False, False) )
|
||||||
prefs_button.add(settings_icon)
|
prefs_button.add(settings_icon)
|
||||||
prefs_button.set_tooltip_text("Settings")
|
prefs_button.set_tooltip_text("Settings")
|
||||||
prefs_button.set_relief(gtk.RELIEF_NONE)
|
prefs_button.set_relief(gtk.RELIEF_NONE)
|
||||||
|
@ -322,7 +373,7 @@ class BitcoinGUI:
|
||||||
pw_icon.show()
|
pw_icon.show()
|
||||||
|
|
||||||
password_button = gtk.Button()
|
password_button = gtk.Button()
|
||||||
password_button.connect("clicked", change_password_dialog, self.wallet, pw_icon)
|
password_button.connect("clicked", lambda x: change_password_dialog(self.wallet, pw_icon))
|
||||||
password_button.add(pw_icon)
|
password_button.add(pw_icon)
|
||||||
password_button.set_relief(gtk.RELIEF_NONE)
|
password_button.set_relief(gtk.RELIEF_NONE)
|
||||||
password_button.show()
|
password_button.show()
|
||||||
|
|
Loading…
Reference in New Issue