big refactoring: command line options and electrum.conf options override settings in wallet file.
This commit is contained in:
parent
0d11aa75c4
commit
5444f55e6b
63
electrum
63
electrum
|
@ -18,7 +18,6 @@
|
|||
|
||||
import re
|
||||
import sys
|
||||
# import argparse
|
||||
import optparse
|
||||
|
||||
try:
|
||||
|
@ -37,9 +36,9 @@ except ImportError:
|
|||
sys.exit("Error: AES does not seem to be installed. Try 'sudo pip install slowaes'")
|
||||
|
||||
try:
|
||||
from lib import Wallet, WalletSynchronizer, format_satoshis, mnemonic, prompt_password, parse_proxy_options, SimpleConfig
|
||||
from lib import Wallet, WalletSynchronizer, format_satoshis, mnemonic, prompt_password, SimpleConfig, pick_random_server
|
||||
except ImportError:
|
||||
from electrum import Wallet, WalletSynchronizer, format_satoshis, mnemonic, prompt_password, parse_proxy_options, SimpleConfig
|
||||
from electrum import Wallet, WalletSynchronizer, format_satoshis, mnemonic, prompt_password, SimpleConfig, pick_random_server
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
|
@ -95,33 +94,39 @@ options:\n --fee, -f: set transaction fee\n --fromaddr, -s: send from address
|
|||
|
||||
|
||||
|
||||
offline_commands = [ 'password', 'mktx', 'label', 'contacts', 'help', 'validateaddress', 'signmessage', 'verifymessage', 'eval', 'create', 'addresses', 'import', 'seed','deseed','reseed','freeze','unfreeze','prioritize','unprioritize']
|
||||
offline_commands = [ 'password', 'mktx',
|
||||
'label', 'contacts',
|
||||
'help', 'validateaddress',
|
||||
'signmessage', 'verifymessage',
|
||||
'eval', 'create', 'addresses',
|
||||
'import', 'seed',
|
||||
'deseed','reseed',
|
||||
'freeze','unfreeze',
|
||||
'prioritize','unprioritize']
|
||||
|
||||
|
||||
protected_commands = ['payto', 'password', 'mktx', 'seed', 'import','signmessage' ]
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# Load simple config class
|
||||
simple_config = SimpleConfig()
|
||||
|
||||
usage = "usage: %prog [options] command\nCommands: "+ (', '.join(known_commands))
|
||||
parser = optparse.OptionParser(prog=usage)
|
||||
parser.add_option("-g", "--gui", dest="gui", default=simple_config.config["gui"], help="gui")
|
||||
parser.add_option("-g", "--gui", dest="gui", help="gui")
|
||||
parser.add_option("-w", "--wallet", dest="wallet_path", help="wallet path (default: electrum.dat)")
|
||||
parser.add_option("-o", "--offline", action="store_true", dest="offline", default=False, help="remain offline")
|
||||
parser.add_option("-a", "--all", action="store_true", dest="show_all", default=False, help="show all addresses")
|
||||
parser.add_option("-b", "--balance", action="store_true", dest="show_balance", default=False, help="show the balance at listed addresses")
|
||||
parser.add_option("-k", "--keys",action="store_true", dest="show_keys",default=False, help="show the private keys of listed addresses")
|
||||
parser.add_option("-f", "--fee", dest="tx_fee", default="0.005", help="set tx fee")
|
||||
parser.add_option("-s", "--fromaddr", dest="from_addr", default=None, help="set source address for payto/mktx. if it isn't in the wallet, it will ask for the private key unless supplied in the format public_key:private_key. It's not saved in the wallet.")
|
||||
parser.add_option("-F", "--fromaddr", dest="from_addr", default=None, help="set source address for payto/mktx. if it isn't in the wallet, it will ask for the private key unless supplied in the format public_key:private_key. It's not saved in the wallet.")
|
||||
parser.add_option("-c", "--changeaddr", dest="change_addr", default=None, help="set the change address for payto/mktx. default is a spare address, or the source address if it's not in the wallet")
|
||||
parser.add_option("-s", "--server", dest="server", default=None, help="set server host:port:protocol, where protocol is t or h")
|
||||
parser.add_option("-p", "--proxy", dest="proxy", default=None, help="set proxy [type:]host[:port], where type is socks4,socks5 or http")
|
||||
options, args = parser.parse_args()
|
||||
|
||||
proxy = parse_proxy_options(options.proxy) if options.proxy else simple_config.config["proxy"]
|
||||
wallet = Wallet()
|
||||
wallet.set_path(options.wallet_path)
|
||||
wallet.read()
|
||||
# config is an object passed to the various constructors (wallet, interface, gui)
|
||||
config = SimpleConfig(options)
|
||||
wallet = Wallet(config)
|
||||
|
||||
if len(args)==0:
|
||||
url = None
|
||||
|
@ -136,31 +141,31 @@ if __name__ == '__main__':
|
|||
#this entire if/else block is just concerned with importing the
|
||||
#right GUI toolkit based the GUI command line option given
|
||||
if cmd == 'gui':
|
||||
|
||||
if options.gui=='gtk':
|
||||
pref_gui = config.get('gui','qt')
|
||||
if pref_gui == 'gtk':
|
||||
try:
|
||||
import lib.gui as gui
|
||||
except ImportError:
|
||||
import electrum.gui as gui
|
||||
elif options.gui=='qt':
|
||||
elif pref_gui == 'qt':
|
||||
try:
|
||||
import lib.gui_qt as gui
|
||||
except ImportError:
|
||||
import electrum.gui_qt as gui
|
||||
elif options.gui == 'lite':
|
||||
elif pref_gui == 'lite':
|
||||
try:
|
||||
import lib.gui_lite as gui
|
||||
except ImportError:
|
||||
import electrum.gui_lite as gui
|
||||
else:
|
||||
sys.exit("Error: Unknown GUI: " + options.gui)
|
||||
sys.exit("Error: Unknown GUI: " + pref_gui )
|
||||
|
||||
gui = gui.ElectrumGui(wallet)
|
||||
interface = WalletSynchronizer(wallet, True, gui.server_list_changed, proxy)
|
||||
gui = gui.ElectrumGui(wallet, config)
|
||||
interface = WalletSynchronizer(wallet, config, True, gui.server_list_changed)
|
||||
interface.start()
|
||||
|
||||
try:
|
||||
found = wallet.file_exists
|
||||
found = config.wallet_file_exists
|
||||
if not found:
|
||||
found = gui.restore_or_create()
|
||||
except SystemExit, e:
|
||||
|
@ -180,17 +185,19 @@ if __name__ == '__main__':
|
|||
if cmd not in known_commands:
|
||||
cmd = 'help'
|
||||
|
||||
if not wallet.file_exists and cmd not in ['help','create','restore']:
|
||||
if not config.wallet_file_exists and cmd not in ['help','create','restore']:
|
||||
print "Error: Wallet file not found."
|
||||
print "Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option"
|
||||
sys.exit(0)
|
||||
|
||||
if cmd in ['create', 'restore']:
|
||||
if wallet.file_exists:
|
||||
if config.wallet_file_exists:
|
||||
sys.exit("Error: Remove the existing wallet first!")
|
||||
password = prompt_password("Password (hit return if you do not wish to encrypt your wallet):")
|
||||
|
||||
w_host, w_port, w_protocol = wallet.server.split(':')
|
||||
server = config.get('server')
|
||||
if not server: server = pick_random_server()
|
||||
w_host, w_port, w_protocol = server.split(':')
|
||||
host = raw_input("server (default:%s):"%w_host)
|
||||
port = raw_input("port (default:%s):"%w_port)
|
||||
protocol = raw_input("protocol [t=tcp;h=http;n=native] (default:%s):"%w_protocol)
|
||||
|
@ -199,7 +206,7 @@ if __name__ == '__main__':
|
|||
if host: w_host = host
|
||||
if port: w_port = port
|
||||
if protocol: w_protocol = protocol
|
||||
wallet.server = w_host + ':' + w_port + ':' +w_protocol
|
||||
wallet.config.set_key('server', w_host + ':' + w_port + ':' +w_protocol)
|
||||
if fee: wallet.fee = float(fee)
|
||||
if gap: wallet.gap_limit = int(gap)
|
||||
|
||||
|
@ -216,7 +223,7 @@ if __name__ == '__main__':
|
|||
wallet.seed = str(seed)
|
||||
wallet.init_mpk( wallet.seed )
|
||||
if not options.offline:
|
||||
WalletSynchronizer(wallet, proxy=proxy).start()
|
||||
WalletSynchronizer(wallet, config).start()
|
||||
print "Recovering wallet..."
|
||||
wallet.up_to_date_event.clear()
|
||||
wallet.up_to_date = False
|
||||
|
@ -239,7 +246,7 @@ if __name__ == '__main__':
|
|||
print "Please keep it in a safe place; if you lose it, you will not be able to restore your wallet."
|
||||
print "Equivalently, your wallet seed can be stored and recovered with the following mnemonic code:"
|
||||
print "\""+' '.join(mnemonic.mn_encode(wallet.seed))+"\""
|
||||
print "Wallet saved in '%s'"%wallet.path
|
||||
print "Wallet saved in '%s'"%wallet.config.path
|
||||
|
||||
if password:
|
||||
wallet.update_password(wallet.seed, None, password)
|
||||
|
@ -259,7 +266,7 @@ if __name__ == '__main__':
|
|||
|
||||
# open session
|
||||
if cmd not in offline_commands and not options.offline:
|
||||
WalletSynchronizer(wallet, proxy=proxy).start()
|
||||
WalletSynchronizer(wallet, config).start()
|
||||
wallet.update()
|
||||
wallet.save()
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
from wallet import Wallet, format_satoshis, prompt_password
|
||||
from interface import WalletSynchronizer, parse_proxy_options
|
||||
from interface import TcpStratumInterface
|
||||
from interface import WalletSynchronizer, Interface, pick_random_server
|
||||
from simple_config import SimpleConfig
|
||||
|
|
10
lib/gui.py
10
lib/gui.py
|
@ -558,12 +558,13 @@ class ElectrumWindow:
|
|||
def show_message(self, msg):
|
||||
show_message(msg, self.window)
|
||||
|
||||
def __init__(self, wallet):
|
||||
def __init__(self, wallet, config):
|
||||
self.config = config
|
||||
self.wallet = wallet
|
||||
self.funds_error = False # True if not enough funds
|
||||
|
||||
self.window = MyWindow(gtk.WINDOW_TOPLEVEL)
|
||||
title = 'Electrum ' + self.wallet.electrum_version + ' - ' + self.wallet.path
|
||||
title = 'Electrum ' + self.wallet.electrum_version + ' - ' + self.config.path
|
||||
if not self.wallet.seed: title += ' [seedless]'
|
||||
self.window.set_title(title)
|
||||
self.window.connect("destroy", gtk.main_quit)
|
||||
|
@ -1298,11 +1299,12 @@ class ElectrumWindow:
|
|||
|
||||
class ElectrumGui():
|
||||
|
||||
def __init__(self, wallet):
|
||||
def __init__(self, wallet, config):
|
||||
self.wallet = wallet
|
||||
self.config = config
|
||||
|
||||
def main(self, url=None):
|
||||
ew = ElectrumWindow(self.wallet)
|
||||
ew = ElectrumWindow(self.wallet, self.config)
|
||||
if url: ew.set_url(url)
|
||||
gtk.main()
|
||||
|
||||
|
|
|
@ -13,17 +13,13 @@ except ImportError:
|
|||
qtVersion = qVersion()
|
||||
if not(int(qtVersion[0]) >= 4 and int(qtVersion[2]) >= 7):
|
||||
app = QApplication(sys.argv)
|
||||
QMessageBox.warning(None,"Could not start Lite GUI.", "Electrum was unable to load the 'Lite GUI' because it needs Qt version >= 4.7.\nElectrum was set to use the 'Qt' GUI")
|
||||
from simple_config import SimpleConfig
|
||||
cfg = SimpleConfig()
|
||||
cfg.set_key("gui", "qt",True)
|
||||
QMessageBox.warning(None,"Could not start Lite GUI.", "Electrum was unable to load the 'Lite GUI' because it needs Qt version >= 4.7.\nPlease use the 'Qt' GUI")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
|
||||
from decimal import Decimal as D
|
||||
from interface import DEFAULT_SERVERS
|
||||
from simple_config import SimpleConfig
|
||||
from util import get_resource_path as rsrc
|
||||
from i18n import _
|
||||
import decimal
|
||||
|
@ -61,10 +57,11 @@ def resize_line_edit_width(line_edit, text_input):
|
|||
|
||||
class ElectrumGui(QObject):
|
||||
|
||||
def __init__(self, wallet):
|
||||
def __init__(self, wallet, config):
|
||||
super(QObject, self).__init__()
|
||||
|
||||
self.wallet = wallet
|
||||
self.config = config
|
||||
self.app = QApplication(sys.argv)
|
||||
|
||||
def main(self, url):
|
||||
|
@ -76,7 +73,7 @@ class ElectrumGui(QObject):
|
|||
old_path = QDir.currentPath()
|
||||
actuator.load_theme()
|
||||
|
||||
self.mini = MiniWindow(actuator, self.expand)
|
||||
self.mini = MiniWindow(actuator, self.expand, self.config)
|
||||
driver = MiniDriver(self.wallet, self.mini)
|
||||
|
||||
# Reset path back to original value now that loading the GUI
|
||||
|
@ -88,12 +85,10 @@ class ElectrumGui(QObject):
|
|||
|
||||
timer = Timer()
|
||||
timer.start()
|
||||
self.expert = gui_qt.ElectrumWindow(self.wallet)
|
||||
self.expert = gui_qt.ElectrumWindow(self.wallet, self.config)
|
||||
self.expert.app = self.app
|
||||
self.expert.connect_slots(timer)
|
||||
self.expert.update_wallet()
|
||||
|
||||
|
||||
self.app.exec_()
|
||||
|
||||
def server_list_changed(self):
|
||||
|
@ -124,10 +119,11 @@ class ElectrumGui(QObject):
|
|||
|
||||
class MiniWindow(QDialog):
|
||||
|
||||
def __init__(self, actuator, expand_callback):
|
||||
def __init__(self, actuator, expand_callback, config):
|
||||
super(MiniWindow, self).__init__()
|
||||
|
||||
self.actuator = actuator
|
||||
self.config = config
|
||||
|
||||
self.btc_balance = None
|
||||
self.quote_currencies = ["EUR", "USD", "GBP"]
|
||||
|
@ -259,11 +255,12 @@ class MiniWindow(QDialog):
|
|||
close_shortcut = QShortcut(QKeySequence("Ctrl+W"), self)
|
||||
close_shortcut.activated.connect(self.close)
|
||||
|
||||
self.cfg = SimpleConfig()
|
||||
g = self.cfg.config["winpos-lite"]
|
||||
g = self.config.get("winpos-lite",[4, 25, 351, 149])
|
||||
self.setGeometry(g[0], g[1], g[2], g[3])
|
||||
show_history.setChecked(self.cfg.config["history"])
|
||||
self.show_history(self.cfg.config["history"])
|
||||
|
||||
show_hist = self.config.get("gui_show_history",False)
|
||||
show_history.setChecked(show_hist)
|
||||
self.show_history(show_hist)
|
||||
|
||||
self.setWindowIcon(QIcon(":electrum.png"))
|
||||
self.setWindowTitle("Electrum")
|
||||
|
@ -282,9 +279,8 @@ class MiniWindow(QDialog):
|
|||
|
||||
def closeEvent(self, event):
|
||||
g = self.geometry()
|
||||
self.cfg.set_key("winpos-lite", [g.left(),g.top(),g.width(),g.height()])
|
||||
self.cfg.set_key("history", self.history_list.isVisible())
|
||||
self.cfg.save_config()
|
||||
self.config.set_key("winpos-lite", [g.left(),g.top(),g.width(),g.height()],True)
|
||||
self.config.set_key("history", self.history_list.isVisible(),True)
|
||||
|
||||
super(MiniWindow, self).closeEvent(event)
|
||||
qApp.quit()
|
||||
|
@ -563,7 +559,7 @@ class MiniActuator:
|
|||
def __init__(self, wallet):
|
||||
"""Retrieve the gui theme used in previous session."""
|
||||
self.wallet = wallet
|
||||
self.theme_name = self.wallet.theme
|
||||
self.theme_name = self.wallet.config.get('litegui_theme','Cleanlook')
|
||||
self.themes = util.load_theme_paths()
|
||||
|
||||
def load_theme(self):
|
||||
|
@ -587,13 +583,14 @@ class MiniActuator:
|
|||
|
||||
def change_theme(self, theme_name):
|
||||
"""Change theme."""
|
||||
self.wallet.theme = self.theme_name = theme_name
|
||||
self.theme_name = theme_name
|
||||
self.wallet.config.set_key('litegui_theme',theme_name)
|
||||
self.load_theme()
|
||||
|
||||
def set_configured_currency(self, set_quote_currency):
|
||||
"""Set the inital fiat currency conversion country (USD/EUR/GBP) in
|
||||
the GUI to what it was set to in the wallet."""
|
||||
currency = self.wallet.conversion_currency
|
||||
currency = self.wallet.config.get('conversion_currency')
|
||||
# currency can be none when Electrum is used for the first
|
||||
# time and no setting has been created yet.
|
||||
if currency is not None:
|
||||
|
@ -601,7 +598,7 @@ class MiniActuator:
|
|||
|
||||
def set_config_currency(self, conversion_currency):
|
||||
"""Change the wallet fiat currency country."""
|
||||
self.wallet.conversion_currency = conversion_currency
|
||||
self.wallet.config.set_key('conversion_currency',conversion_currency,True)
|
||||
|
||||
def set_servers_gui_stuff(self, servers_menu, servers_group):
|
||||
self.servers_menu = servers_menu
|
||||
|
@ -620,7 +617,7 @@ class MiniActuator:
|
|||
print "Servers loaded."
|
||||
self.servers_list = interface.servers
|
||||
server_names = [details[0] for details in self.servers_list]
|
||||
current_server = self.wallet.server.split(":")[0]
|
||||
current_server = interface.server.split(":")[0]
|
||||
for server_name in server_names:
|
||||
server_action = self.servers_menu.addAction(server_name)
|
||||
server_action.setCheckable(True)
|
||||
|
@ -661,8 +658,7 @@ class MiniActuator:
|
|||
server_line = "%s:%s:%s" % (server_name, port, protocol)
|
||||
|
||||
# Should this have exception handling?
|
||||
self.cfg = SimpleConfig()
|
||||
self.wallet.set_server(server_line, self.cfg.config["proxy"])
|
||||
self.wallet.set_server(server_line, self.config.get(["proxy"]))
|
||||
|
||||
def copy_address(self, receive_popup):
|
||||
"""Copy the wallet addresses into the client."""
|
||||
|
|
|
@ -37,9 +37,7 @@ except:
|
|||
sys.exit("Error: Could not import icons_rc.py, please generate it with: 'pyrcc4 icons.qrc -o lib/icons_rc.py'")
|
||||
|
||||
from wallet import format_satoshis
|
||||
from simple_config import SimpleConfig
|
||||
import bmp, mnemonic, pyqrnative, qrscanner
|
||||
from simple_config import SimpleConfig
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
|
@ -185,11 +183,14 @@ def ok_cancel_buttons(dialog):
|
|||
|
||||
class ElectrumWindow(QMainWindow):
|
||||
|
||||
def __init__(self, wallet):
|
||||
def __init__(self, wallet, config):
|
||||
QMainWindow.__init__(self)
|
||||
self.wallet = wallet
|
||||
self.config = config
|
||||
self.wallet.register_callback(self.update_callback)
|
||||
|
||||
self.detailed_view = config.get('qt_detailed_view', False)
|
||||
|
||||
self.funds_error = False
|
||||
self.completions = QStringListModel()
|
||||
|
||||
|
@ -204,10 +205,10 @@ class ElectrumWindow(QMainWindow):
|
|||
tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||
self.setCentralWidget(tabs)
|
||||
self.create_status_bar()
|
||||
cfg = SimpleConfig()
|
||||
g = cfg.config["winpos-qt"]
|
||||
|
||||
g = self.config.get("winpos-qt",[100, 100, 840, 400])
|
||||
self.setGeometry(g[0], g[1], g[2], g[3])
|
||||
title = 'Electrum ' + self.wallet.electrum_version + ' - ' + self.wallet.path
|
||||
title = 'Electrum ' + self.wallet.electrum_version + ' - ' + self.config.path
|
||||
if not self.wallet.seed: title += ' [seedless]'
|
||||
self.setWindowTitle( title )
|
||||
|
||||
|
@ -696,10 +697,12 @@ class ElectrumWindow(QMainWindow):
|
|||
return w
|
||||
|
||||
def details_button_text(self):
|
||||
return _('Hide details') if self.wallet.gui_detailed_view else _('Show details')
|
||||
return _('Hide details') if self.detailed_view else _('Show details')
|
||||
|
||||
def toggle_detailed_view(self):
|
||||
self.wallet.gui_detailed_view = not self.wallet.gui_detailed_view
|
||||
self.detailed_view = not self.detailed_view
|
||||
self.config.set_key('qt_detailed_view', self.detailed_view, True)
|
||||
|
||||
self.details_button.setText(self.details_button_text())
|
||||
self.wallet.save()
|
||||
self.update_receive_tab()
|
||||
|
@ -731,11 +734,11 @@ class ElectrumWindow(QMainWindow):
|
|||
menu.addAction(_("Copy to Clipboard"), lambda: self.app.clipboard().setText(addr))
|
||||
menu.addAction(_("View QR code"),lambda: self.show_address_qrcode(addr))
|
||||
menu.addAction(_("Edit label"), lambda: self.edit_label(True))
|
||||
if self.wallet.gui_detailed_view:
|
||||
t = _("Unfreeze") if addr in self.wallet.frozen_addresses else _("Freeze")
|
||||
menu.addAction(t, lambda: self.toggle_freeze(addr))
|
||||
t = _("Unprioritize") if addr in self.wallet.prioritized_addresses else _("Prioritize")
|
||||
menu.addAction(t, lambda: self.toggle_priority(addr))
|
||||
|
||||
t = _("Unfreeze") if addr in self.wallet.frozen_addresses else _("Freeze")
|
||||
menu.addAction(t, lambda: self.toggle_freeze(addr))
|
||||
t = _("Unprioritize") if addr in self.wallet.prioritized_addresses else _("Prioritize")
|
||||
menu.addAction(t, lambda: self.toggle_priority(addr))
|
||||
menu.exec_(self.receive_list.viewport().mapToGlobal(position))
|
||||
|
||||
|
||||
|
@ -790,9 +793,9 @@ class ElectrumWindow(QMainWindow):
|
|||
def update_receive_tab(self):
|
||||
l = self.receive_list
|
||||
l.clear()
|
||||
l.setColumnHidden(0,not self.wallet.gui_detailed_view)
|
||||
l.setColumnHidden(3,not self.wallet.gui_detailed_view)
|
||||
l.setColumnHidden(4,not self.wallet.gui_detailed_view)
|
||||
l.setColumnHidden(0,not self.detailed_view)
|
||||
l.setColumnHidden(3,not self.detailed_view)
|
||||
l.setColumnHidden(4,not self.detailed_view)
|
||||
l.setColumnWidth(0, 50)
|
||||
l.setColumnWidth(1, 310)
|
||||
l.setColumnWidth(2, 250)
|
||||
|
@ -803,7 +806,7 @@ class ElectrumWindow(QMainWindow):
|
|||
is_red = False
|
||||
for address in self.wallet.all_addresses():
|
||||
|
||||
if self.wallet.is_change(address) and not self.wallet.gui_detailed_view:
|
||||
if self.wallet.is_change(address) and not self.detailed_view:
|
||||
continue
|
||||
|
||||
label = self.wallet.labels.get(address,'')
|
||||
|
@ -855,7 +858,7 @@ class ElectrumWindow(QMainWindow):
|
|||
|
||||
l = self.contacts_list
|
||||
l.clear()
|
||||
l.setColumnHidden(2, not self.wallet.gui_detailed_view)
|
||||
l.setColumnHidden(2, not self.detailed_view)
|
||||
l.setColumnWidth(0, 350)
|
||||
l.setColumnWidth(1, 330)
|
||||
l.setColumnWidth(2, 100)
|
||||
|
@ -1247,9 +1250,8 @@ class ElectrumWindow(QMainWindow):
|
|||
gap_e.textChanged.connect(lambda: numbify(nz_e,True))
|
||||
|
||||
gui = QComboBox()
|
||||
gui.addItems(['Lite', 'Qt'])
|
||||
cfg = SimpleConfig()
|
||||
gui.setCurrentIndex(gui.findText(cfg.config["gui"].capitalize()))
|
||||
gui.addItems(['Lite', 'Qt', 'Gtk'])
|
||||
gui.setCurrentIndex(gui.findText(self.config.get("gui","lite").capitalize()))
|
||||
grid.addWidget(QLabel(_('Default GUI') + ':'), 7, 0)
|
||||
grid.addWidget(gui, 7, 1)
|
||||
grid.addWidget(HelpButton(_('Select which GUI mode to use at start up. ')), 7, 2)
|
||||
|
@ -1298,9 +1300,7 @@ class ElectrumWindow(QMainWindow):
|
|||
else:
|
||||
QMessageBox.warning(self, _('Error'), _('Invalid value'), _('OK'))
|
||||
|
||||
cfg = SimpleConfig()
|
||||
cfg.set_key("gui", str(gui.currentText()).lower())
|
||||
cfg.save_config()
|
||||
self.config.set_key("gui", str(gui.currentText()).lower(), True)
|
||||
|
||||
|
||||
|
||||
|
@ -1312,7 +1312,7 @@ class ElectrumWindow(QMainWindow):
|
|||
status = _("Connected to")+" %s:%d\n%d blocks"%(interface.host, interface.port, wallet.blocks)
|
||||
else:
|
||||
status = _("Not connected")
|
||||
server = wallet.server
|
||||
server = interface.server
|
||||
else:
|
||||
import random
|
||||
status = _("Please choose a server.")
|
||||
|
@ -1458,37 +1458,28 @@ class ElectrumWindow(QMainWindow):
|
|||
if not d.exec_(): return
|
||||
server = unicode( host_line.text() )
|
||||
|
||||
try:
|
||||
if proxy_mode.currentText() != 'NONE':
|
||||
proxy = { u'mode':unicode(proxy_mode.currentText()).lower(), u'host':unicode(proxy_host.text()), u'port':unicode(proxy_port.text()) }
|
||||
else:
|
||||
proxy = None
|
||||
if proxy_mode.currentText() != 'NONE':
|
||||
proxy = { u'mode':unicode(proxy_mode.currentText()).lower(), u'host':unicode(proxy_host.text()), u'port':unicode(proxy_port.text()) }
|
||||
else:
|
||||
proxy = None
|
||||
|
||||
cfg = SimpleConfig()
|
||||
cfg.set_key("proxy", proxy, True)
|
||||
wallet.set_server(server, proxy)
|
||||
|
||||
except Exception as err:
|
||||
QMessageBox.information(None, _('Error'), str(err), _('OK'))
|
||||
if parent == None:
|
||||
sys.exit(1)
|
||||
else:
|
||||
return
|
||||
wallet.config.set_key("proxy", proxy, True)
|
||||
wallet.config.set_key("server", server, True)
|
||||
interface.set_server(server, proxy)
|
||||
|
||||
return True
|
||||
|
||||
def closeEvent(self, event):
|
||||
cfg = SimpleConfig()
|
||||
g = self.geometry()
|
||||
cfg.set_key("winpos-qt", [g.left(),g.top(),g.width(),g.height()])
|
||||
cfg.save_config()
|
||||
self.config.set_key("winpos-qt", [g.left(),g.top(),g.width(),g.height()], True)
|
||||
event.accept()
|
||||
|
||||
|
||||
class ElectrumGui:
|
||||
|
||||
def __init__(self, wallet, app=None):
|
||||
def __init__(self, wallet, config, app=None):
|
||||
self.wallet = wallet
|
||||
self.config = config
|
||||
if app is None:
|
||||
self.app = QApplication(sys.argv)
|
||||
|
||||
|
@ -1563,7 +1554,7 @@ class ElectrumGui:
|
|||
def main(self,url):
|
||||
s = Timer()
|
||||
s.start()
|
||||
w = ElectrumWindow(self.wallet)
|
||||
w = ElectrumWindow(self.wallet, self.config)
|
||||
if url: w.set_url(url)
|
||||
w.app = self.app
|
||||
w.connect_slots(s)
|
||||
|
|
108
lib/interface.py
108
lib/interface.py
|
@ -22,7 +22,7 @@ import threading, traceback, sys, time, json, Queue
|
|||
|
||||
from version import ELECTRUM_VERSION
|
||||
from util import print_error
|
||||
from simple_config import SimpleConfig
|
||||
|
||||
|
||||
DEFAULT_TIMEOUT = 5
|
||||
DEFAULT_SERVERS = [ 'electrum.novit.ro:50001:t',
|
||||
|
@ -30,23 +30,10 @@ DEFAULT_SERVERS = [ 'electrum.novit.ro:50001:t',
|
|||
|
||||
proxy_modes = ['socks4', 'socks5', 'http']
|
||||
|
||||
def replace_keys(obj, old_key, new_key):
|
||||
if isinstance(obj, dict):
|
||||
if old_key in obj:
|
||||
obj[new_key] = obj[old_key]
|
||||
del obj[old_key]
|
||||
for elem in obj.itervalues():
|
||||
replace_keys(elem, old_key, new_key)
|
||||
elif isinstance(obj, list):
|
||||
for elem in obj:
|
||||
replace_keys(elem, old_key, new_key)
|
||||
def pick_random_server():
|
||||
print "using random server"
|
||||
return random.choice( DEFAULT_SERVERS )
|
||||
|
||||
def old_to_new(d):
|
||||
replace_keys(d, 'blk_hash', 'block_hash')
|
||||
replace_keys(d, 'pos', 'index')
|
||||
replace_keys(d, 'nTime', 'timestamp')
|
||||
replace_keys(d, 'is_in', 'is_input')
|
||||
replace_keys(d, 'raw_scriptPubKey', 'raw_output_script')
|
||||
|
||||
def parse_proxy_options(s):
|
||||
if s.lower() == 'none': return None
|
||||
|
@ -65,7 +52,11 @@ def parse_proxy_options(s):
|
|||
proxy["port"] = "8080" if proxy["mode"] == "http" else "1080"
|
||||
return proxy
|
||||
|
||||
class Interface(threading.Thread):
|
||||
|
||||
|
||||
|
||||
class InterfaceAncestor(threading.Thread):
|
||||
|
||||
def __init__(self, host, port, proxy=None):
|
||||
threading.Thread.__init__(self)
|
||||
self.daemon = True
|
||||
|
@ -134,11 +125,11 @@ class Interface(threading.Thread):
|
|||
|
||||
|
||||
|
||||
class PollingInterface(Interface):
|
||||
class PollingInterface(InterfaceAncestor):
|
||||
""" non-persistent connection. synchronous calls"""
|
||||
|
||||
def __init__(self, host, port, proxy=None):
|
||||
Interface.__init__(self, host, port, proxy)
|
||||
InterfaceAncestor.__init__(self, host, port, proxy)
|
||||
self.session_id = None
|
||||
|
||||
def get_history(self, address):
|
||||
|
@ -146,14 +137,6 @@ class PollingInterface(Interface):
|
|||
|
||||
def poll(self):
|
||||
pass
|
||||
#if is_new or wallet.remote_url:
|
||||
# self.was_updated = True
|
||||
# is_new = wallet.synchronize()
|
||||
# wallet.update_tx_history()
|
||||
# wallet.save()
|
||||
# return is_new
|
||||
#else:
|
||||
# return False
|
||||
|
||||
def run(self):
|
||||
self.is_connected = True
|
||||
|
@ -249,11 +232,11 @@ class HttpStratumInterface(PollingInterface):
|
|||
|
||||
|
||||
|
||||
class TcpStratumInterface(Interface):
|
||||
class TcpStratumInterface(InterfaceAncestor):
|
||||
"""json-rpc over persistent TCP connection, asynchronous"""
|
||||
|
||||
def __init__(self, host, port, proxy=None):
|
||||
Interface.__init__(self, host, port, proxy)
|
||||
InterfaceAncestor.__init__(self, host, port, proxy)
|
||||
|
||||
def init_socket(self):
|
||||
global proxy_modes
|
||||
|
@ -328,38 +311,63 @@ class TcpStratumInterface(Interface):
|
|||
|
||||
|
||||
|
||||
class Interface(TcpStratumInterface, HttpStratumInterface):
|
||||
|
||||
def __init__(self, config):
|
||||
|
||||
try:
|
||||
s = config.get('server')
|
||||
host, port, protocol = s.split(':')
|
||||
port = int(port)
|
||||
except:
|
||||
s = pick_random_server()
|
||||
host, port, protocol = s.split(':')
|
||||
port = int(port)
|
||||
|
||||
proxy = config.get('proxy')
|
||||
self.server = host + ':%d:%s'%(port, protocol)
|
||||
|
||||
#print protocol, host, port
|
||||
if protocol == 't':
|
||||
TcpStratumInterface.__init__(self, host, port, proxy)
|
||||
elif protocol == 'h':
|
||||
HttpStratumInterface.__init__(self, host, port, proxy)
|
||||
else:
|
||||
print_error("Error: Unknown protocol")
|
||||
TcpStratumInterface.__init__(self, host, port, proxy)
|
||||
|
||||
|
||||
def set_server(self, server, proxy=None):
|
||||
# raise an error if the format isnt correct
|
||||
a,b,c = server.split(':')
|
||||
b = int(b)
|
||||
assert c in ['t', 'h']
|
||||
# set the server
|
||||
if server != self.server or proxy != self.proxy:
|
||||
print "changing server:", server, proxy
|
||||
self.server = server
|
||||
self.proxy = proxy
|
||||
self.is_connected = False # this exits the polling loop
|
||||
self.poke()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class WalletSynchronizer(threading.Thread):
|
||||
|
||||
def __init__(self, wallet, loop=False, servers_loaded_callback=None, proxy=None):
|
||||
def __init__(self, wallet, config, loop=False, servers_loaded_callback=None):
|
||||
threading.Thread.__init__(self)
|
||||
self.daemon = True
|
||||
self.wallet = wallet
|
||||
self.loop = loop
|
||||
self.proxy = proxy
|
||||
self.config = config
|
||||
self.init_interface()
|
||||
self.servers_loaded_callback = servers_loaded_callback
|
||||
|
||||
def init_interface(self):
|
||||
try:
|
||||
host, port, protocol = self.wallet.server.split(':')
|
||||
port = int(port)
|
||||
except:
|
||||
self.wallet.pick_random_server()
|
||||
host, port, protocol = self.wallet.server.split(':')
|
||||
port = int(port)
|
||||
|
||||
#print protocol, host, port
|
||||
if protocol == 't':
|
||||
InterfaceClass = TcpStratumInterface
|
||||
elif protocol == 'h':
|
||||
InterfaceClass = HttpStratumInterface
|
||||
else:
|
||||
print_error("Error: Unknown protocol")
|
||||
InterfaceClass = TcpStratumInterface
|
||||
|
||||
self.interface = InterfaceClass(host, port, self.proxy)
|
||||
self.interface = Interface(self.config)
|
||||
self.wallet.interface = self.interface
|
||||
|
||||
def handle_response(self, r):
|
||||
|
|
|
@ -1,66 +1,176 @@
|
|||
import json
|
||||
import os
|
||||
import json, ast
|
||||
import os, ast
|
||||
from util import user_dir
|
||||
|
||||
from version import ELECTRUM_VERSION, SEED_VERSION
|
||||
from interface import parse_proxy_options
|
||||
|
||||
|
||||
# old stuff.. should be removed at some point
|
||||
def replace_keys(obj, old_key, new_key):
|
||||
if isinstance(obj, dict):
|
||||
if old_key in obj:
|
||||
obj[new_key] = obj[old_key]
|
||||
del obj[old_key]
|
||||
for elem in obj.itervalues():
|
||||
replace_keys(elem, old_key, new_key)
|
||||
elif isinstance(obj, list):
|
||||
for elem in obj:
|
||||
replace_keys(elem, old_key, new_key)
|
||||
|
||||
def old_to_new(d):
|
||||
replace_keys(d, 'blk_hash', 'block_hash')
|
||||
replace_keys(d, 'pos', 'index')
|
||||
replace_keys(d, 'nTime', 'timestamp')
|
||||
replace_keys(d, 'is_in', 'is_input')
|
||||
replace_keys(d, 'raw_scriptPubKey', 'raw_output_script')
|
||||
|
||||
|
||||
|
||||
class SimpleConfig:
|
||||
|
||||
default_options = {
|
||||
"gui": "lite",
|
||||
"proxy": None,
|
||||
"winpos-qt": [100, 100, 840, 400],
|
||||
"winpos-lite": [4, 25, 351, 149],
|
||||
"history": False
|
||||
}
|
||||
def __init__(self, options):
|
||||
|
||||
self.wallet_config = {}
|
||||
self.read_wallet_config(options.wallet_path)
|
||||
|
||||
self.common_config = {}
|
||||
self.read_common_config()
|
||||
|
||||
self.options_config = {}
|
||||
|
||||
if options.server: self.options_config['server'] = options.server
|
||||
if options.proxy: self.options_config['proxy'] = parse_proxy_options(options.proxy)
|
||||
if options.gui: self.options_config['gui'] = options.gui
|
||||
|
||||
|
||||
|
||||
def set_key(self, key, value, save = False):
|
||||
# find where a setting comes from and save it there
|
||||
if self.options_config.get(key):
|
||||
return
|
||||
|
||||
elif self.wallet_config.get(key):
|
||||
self.wallet_config[key] = value
|
||||
if save: self.save_wallet_config()
|
||||
|
||||
elif self.common_config.get(key):
|
||||
self.common_config[key] = value
|
||||
if save: self.save_common_config()
|
||||
|
||||
def __init__(self):
|
||||
# Find electrum data folder
|
||||
self.config_folder = user_dir()
|
||||
# Read the file
|
||||
if os.path.exists(self.config_file_path()):
|
||||
self.load_config()
|
||||
else:
|
||||
self.config = self.default_options
|
||||
# Make config directory if it does not yet exist.
|
||||
if not os.path.exists(self.config_folder):
|
||||
os.mkdir(self.config_folder)
|
||||
self.save_config()
|
||||
# add key to wallet config
|
||||
self.wallet_config[key] = value
|
||||
if save: self.save_wallet_config()
|
||||
|
||||
# This is a friendly fallback to the old style default proxy options
|
||||
if(self.config.get("proxy") is not None and self.config["proxy"]["mode"] == "none"):
|
||||
self.set_key("proxy", None, True)
|
||||
|
||||
def set_key(self, key, value, save = True):
|
||||
self.config[key] = value
|
||||
if save == True:
|
||||
self.save_config()
|
||||
def get(self, key, default=None):
|
||||
# 1. command-line options always override everything
|
||||
if self.options_config.has_key(key):
|
||||
# print "found", key, "in options"
|
||||
out = self.options_config.get(key)
|
||||
|
||||
def save_config(self):
|
||||
if not os.path.exists(self.config_folder):
|
||||
os.mkdir(self.config_folder)
|
||||
f = open(self.config_file_path(), "w+")
|
||||
f.write(json.dumps(self.config))
|
||||
# 2. configuration file overrides wallet file
|
||||
elif self.common_config.has_key(key):
|
||||
out = self.common_config.get(key)
|
||||
|
||||
def load_config(self):
|
||||
f = open(self.config_file_path(), "r")
|
||||
file_contents = f.read()
|
||||
if file_contents:
|
||||
user_config = json.loads(file_contents)
|
||||
for i in user_config:
|
||||
self.config[i] = user_config[i]
|
||||
else:
|
||||
self.config = self.default_options
|
||||
self.save_config()
|
||||
out = self.wallet_config.get(key)
|
||||
|
||||
def config_file_path(self):
|
||||
return "%s" % (self.config_folder + "/config.json")
|
||||
|
||||
def __init__(self):
|
||||
# Find electrum data folder
|
||||
self.config_folder = user_dir()
|
||||
self.config = self.default_options
|
||||
# Read the file
|
||||
if os.path.exists(self.config_file_path()):
|
||||
self.load_config()
|
||||
self.save_config()
|
||||
if out is None and default is not None:
|
||||
out = default
|
||||
return out
|
||||
|
||||
|
||||
def is_modifiable(self, key):
|
||||
if self.options_config.has_key(key) or self.common_config.has_key(key):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def read_common_config(self):
|
||||
for name in [ os.path.join( user_dir(), 'electrum.conf') , '/etc/electrum.conf']:
|
||||
if os.path.exists(name):
|
||||
from interface import parse_proxy_options
|
||||
try:
|
||||
import ConfigParser
|
||||
except:
|
||||
print "cannot parse electrum.conf. please install ConfigParser"
|
||||
return
|
||||
|
||||
p = ConfigParser.ConfigParser()
|
||||
p.read(name)
|
||||
try:
|
||||
self.common_config['server'] = p.get('interface','server')
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.common_config['proxy'] = parse_proxy_options(p.get('interface','proxy'))
|
||||
except:
|
||||
pass
|
||||
break
|
||||
|
||||
|
||||
|
||||
def init_path(self, wallet_path):
|
||||
"""Set the path of the wallet."""
|
||||
if wallet_path is not None:
|
||||
self.path = wallet_path
|
||||
return
|
||||
|
||||
# Look for wallet file in the default data directory.
|
||||
# Keeps backwards compatibility.
|
||||
wallet_dir = user_dir()
|
||||
|
||||
# Make wallet directory if it does not yet exist.
|
||||
if not os.path.exists(wallet_dir):
|
||||
os.mkdir(wallet_dir)
|
||||
self.path = os.path.join(wallet_dir, "electrum.dat")
|
||||
|
||||
|
||||
|
||||
def save_common_config(self):
|
||||
s = repr(self.common_config)
|
||||
# todo: decide what to do
|
||||
print "not saving settings in common config:", s
|
||||
|
||||
|
||||
|
||||
def read_wallet_config(self, path):
|
||||
"""Read the contents of the wallet file."""
|
||||
self.wallet_file_exists = False
|
||||
self.init_path(path)
|
||||
try:
|
||||
with open(self.path, "r") as f:
|
||||
data = f.read()
|
||||
except IOError:
|
||||
return
|
||||
try:
|
||||
d = ast.literal_eval( data ) #parse raw data from reading wallet file
|
||||
old_to_new(d)
|
||||
except:
|
||||
raise IOError("Cannot read wallet file.")
|
||||
|
||||
self.wallet_config = d
|
||||
self.wallet_file_exists = True
|
||||
|
||||
|
||||
def set_interface(self, interface):
|
||||
pass
|
||||
|
||||
def set_gui(self, gui):
|
||||
pass
|
||||
|
||||
def save(self):
|
||||
self.save_wallet_config()
|
||||
|
||||
|
||||
def save_wallet_config(self):
|
||||
s = repr(self.wallet_config)
|
||||
f = open(self.path,"w")
|
||||
f.write( s )
|
||||
f.close()
|
||||
import stat
|
||||
os.chmod(self.path,stat.S_IREAD | stat.S_IWRITE)
|
||||
|
||||
|
|
199
lib/wallet.py
199
lib/wallet.py
|
@ -273,49 +273,40 @@ def format_satoshis(x, is_diff=False, num_zeros = 0):
|
|||
|
||||
|
||||
from version import ELECTRUM_VERSION, SEED_VERSION
|
||||
from interface import DEFAULT_SERVERS
|
||||
|
||||
|
||||
|
||||
|
||||
class Wallet:
|
||||
def __init__(self):
|
||||
def __init__(self, config={}):
|
||||
|
||||
self.config = config
|
||||
self.electrum_version = ELECTRUM_VERSION
|
||||
self.seed_version = SEED_VERSION
|
||||
self.update_callbacks = []
|
||||
|
||||
self.gap_limit = 5 # configuration
|
||||
self.use_change = True
|
||||
self.fee = 100000
|
||||
self.num_zeros = 0
|
||||
self.master_public_key = ''
|
||||
self.conversion_currency = None
|
||||
self.theme = "Cleanlook"
|
||||
|
||||
# saved fields
|
||||
self.use_encryption = False
|
||||
self.addresses = [] # receiving addresses visible for user
|
||||
self.change_addresses = [] # addresses used as change
|
||||
self.seed = '' # encrypted
|
||||
self.history = {}
|
||||
self.labels = {} # labels for addresses and transactions
|
||||
self.aliases = {} # aliases for addresses
|
||||
self.authorities = {} # trusted addresses
|
||||
self.frozen_addresses = []
|
||||
self.prioritized_addresses = []
|
||||
self.gui_detailed_view = False
|
||||
|
||||
self.receipts = {} # signed URIs
|
||||
self.receipt = None # next receipt
|
||||
self.addressbook = [] # outgoing addresses, for payments
|
||||
self.debug_server = False # write server communication debug info to stdout
|
||||
self.seed_version = config.get('seed_version', SEED_VERSION)
|
||||
self.gap_limit = config.get('gap_limit', 5)
|
||||
self.use_change = config.get('use_change',True)
|
||||
self.fee = int(config.get('fee',100000))
|
||||
self.num_zeros = int(config.get('num_zeros',0))
|
||||
self.master_public_key = config.get('master_public_key','').decode('hex')
|
||||
self.use_encryption = config.get('use_encryption', False)
|
||||
self.addresses = config.get('addresses', []) # receiving addresses visible for user
|
||||
self.change_addresses = config.get('change_addresses', []) # addresses used as change
|
||||
self.seed = config.get('seed', '') # encrypted
|
||||
self.history = config.get('history',{})
|
||||
self.labels = config.get('labels',{}) # labels for addresses and transactions
|
||||
self.aliases = config.get('aliases', {}) # aliases for addresses
|
||||
self.authorities = config.get('authorities', {}) # trusted addresses
|
||||
self.frozen_addresses = config.get('frozen_addresses',[])
|
||||
self.prioritized_addresses = config.get('prioritized_addresses',[])
|
||||
self.receipts = config.get('receipts',{}) # signed URIs
|
||||
self.addressbook = config.get('contacts', []) # outgoing addresses, for payments
|
||||
self.imported_keys = config.get('imported_keys',{})
|
||||
|
||||
# not saved
|
||||
self.receipt = None # next receipt
|
||||
self.tx_history = {}
|
||||
|
||||
self.imported_keys = {}
|
||||
|
||||
self.was_updated = True
|
||||
self.blocks = -1
|
||||
self.banner = ''
|
||||
|
@ -329,7 +320,10 @@ class Wallet:
|
|||
self.lock = threading.Lock()
|
||||
self.tx_event = threading.Event()
|
||||
|
||||
self.pick_random_server()
|
||||
self.update_tx_history()
|
||||
if self.seed_version != SEED_VERSION:
|
||||
raise ValueError("This wallet seed is deprecated. Please run upgrade.py for a diagnostic.")
|
||||
|
||||
|
||||
def register_callback(self, update_callback):
|
||||
with self.lock:
|
||||
|
@ -340,38 +334,9 @@ class Wallet:
|
|||
callbacks = self.update_callbacks[:]
|
||||
[update() for update in callbacks]
|
||||
|
||||
def pick_random_server(self):
|
||||
self.server = random.choice( DEFAULT_SERVERS ) # random choice when the wallet is created
|
||||
|
||||
def is_up_to_date(self):
|
||||
return self.interface.responses.empty() and not self.interface.unanswered_requests
|
||||
|
||||
def set_server(self, server, proxy=None):
|
||||
# raise an error if the format isnt correct
|
||||
a,b,c = server.split(':')
|
||||
b = int(b)
|
||||
assert c in ['t', 'h', 'n']
|
||||
# set the server
|
||||
if server != self.server or proxy != self.interface.proxy:
|
||||
self.server = server
|
||||
self.save()
|
||||
self.interface.proxy = proxy
|
||||
self.interface.is_connected = False # this exits the polling loop
|
||||
self.interface.poke()
|
||||
|
||||
def set_path(self, wallet_path):
|
||||
"""Set the path of the wallet."""
|
||||
if wallet_path is not None:
|
||||
self.path = wallet_path
|
||||
return
|
||||
# Look for wallet file in the default data directory.
|
||||
# Keeps backwards compatibility.
|
||||
wallet_dir = user_dir()
|
||||
|
||||
# Make wallet directory if it does not yet exist.
|
||||
if not os.path.exists(wallet_dir):
|
||||
os.mkdir(wallet_dir)
|
||||
self.path = os.path.join(wallet_dir, "electrum.dat")
|
||||
|
||||
def import_key(self, keypair, password):
|
||||
address, key = keypair.split(':')
|
||||
|
@ -390,6 +355,7 @@ class Wallet:
|
|||
raise BaseException('Address does not match private key')
|
||||
self.imported_keys[address] = self.pw_encode( key, password )
|
||||
|
||||
|
||||
def new_seed(self, password):
|
||||
seed = "%032x"%ecdsa.util.randrange( pow(2,128) )
|
||||
#self.init_mpk(seed)
|
||||
|
@ -630,91 +596,6 @@ class Wallet:
|
|||
self.update_tx_labels()
|
||||
|
||||
|
||||
def save(self):
|
||||
# TODO: Need special config storage class. Should not be mixed
|
||||
# up with the wallet.
|
||||
# Settings should maybe be stored in a flat ini file.
|
||||
s = {
|
||||
'seed_version': self.seed_version,
|
||||
'use_encryption': self.use_encryption,
|
||||
'use_change': self.use_change,
|
||||
'master_public_key': self.master_public_key.encode('hex'),
|
||||
'fee': self.fee,
|
||||
'server': self.server,
|
||||
'seed': self.seed,
|
||||
'addresses': self.addresses,
|
||||
'change_addresses': self.change_addresses,
|
||||
'history': self.history,
|
||||
'labels': self.labels,
|
||||
'contacts': self.addressbook,
|
||||
'imported_keys': self.imported_keys,
|
||||
'aliases': self.aliases,
|
||||
'authorities': self.authorities,
|
||||
'receipts': self.receipts,
|
||||
'num_zeros': self.num_zeros,
|
||||
'frozen_addresses': self.frozen_addresses,
|
||||
'prioritized_addresses': self.prioritized_addresses,
|
||||
'gui_detailed_view': self.gui_detailed_view,
|
||||
'gap_limit': self.gap_limit,
|
||||
'debug_server': self.debug_server,
|
||||
'conversion_currency': self.conversion_currency,
|
||||
'theme': self.theme
|
||||
}
|
||||
f = open(self.path,"w")
|
||||
f.write( repr(s) )
|
||||
f.close()
|
||||
import stat
|
||||
os.chmod(self.path,stat.S_IREAD | stat.S_IWRITE)
|
||||
|
||||
def read(self):
|
||||
"""Read the contents of the wallet file."""
|
||||
import interface
|
||||
|
||||
self.file_exists = False
|
||||
try:
|
||||
with open(self.path, "r") as f:
|
||||
data = f.read()
|
||||
except IOError:
|
||||
return
|
||||
try:
|
||||
d = ast.literal_eval( data ) #parse raw data from reading wallet file
|
||||
interface.old_to_new(d)
|
||||
|
||||
self.seed_version = d.get('seed_version')
|
||||
self.master_public_key = d.get('master_public_key').decode('hex')
|
||||
self.use_encryption = d.get('use_encryption')
|
||||
self.use_change = bool(d.get('use_change', True))
|
||||
self.fee = int(d.get('fee'))
|
||||
self.seed = d.get('seed')
|
||||
self.server = d.get('server')
|
||||
self.addresses = d.get('addresses')
|
||||
self.change_addresses = d.get('change_addresses')
|
||||
self.history = d.get('history')
|
||||
self.labels = d.get('labels')
|
||||
self.addressbook = d.get('contacts')
|
||||
self.imported_keys = d.get('imported_keys', {})
|
||||
self.aliases = d.get('aliases', {})
|
||||
self.authorities = d.get('authorities', {})
|
||||
self.receipts = d.get('receipts', {})
|
||||
self.num_zeros = d.get('num_zeros', 0)
|
||||
self.frozen_addresses = d.get('frozen_addresses', [])
|
||||
self.prioritized_addresses = d.get('prioritized_addresses', [])
|
||||
self.gui_detailed_view = d.get('gui_detailed_view', False)
|
||||
self.gap_limit = d.get('gap_limit', 5)
|
||||
self.debug_server = d.get('debug_server', False)
|
||||
self.conversion_currency = d.get('conversion_currency', 'USD')
|
||||
self.theme = d.get('theme', 'Cleanlook')
|
||||
except:
|
||||
raise IOError("Cannot read wallet file.")
|
||||
|
||||
self.update_tx_history()
|
||||
|
||||
if self.seed_version != SEED_VERSION:
|
||||
raise ValueError("This wallet seed is deprecated. Please run upgrade.py for a diagnostic.")
|
||||
|
||||
self.file_exists = True
|
||||
|
||||
|
||||
def get_address_flags(self, addr):
|
||||
flags = "C" if self.is_change(addr) else "I" if addr in self.imported_keys.keys() else "-"
|
||||
flags += "F" if addr in self.frozen_addresses else "P" if addr in self.prioritized_addresses else "-"
|
||||
|
@ -1134,3 +1015,29 @@ class Wallet:
|
|||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def save(self):
|
||||
s = {
|
||||
'seed_version': self.seed_version,
|
||||
'use_encryption': self.use_encryption,
|
||||
'use_change': self.use_change,
|
||||
'master_public_key': self.master_public_key.encode('hex'),
|
||||
'fee': self.fee,
|
||||
'seed': self.seed,
|
||||
'addresses': self.addresses,
|
||||
'change_addresses': self.change_addresses,
|
||||
'history': self.history,
|
||||
'labels': self.labels,
|
||||
'contacts': self.addressbook,
|
||||
'imported_keys': self.imported_keys,
|
||||
'aliases': self.aliases,
|
||||
'authorities': self.authorities,
|
||||
'receipts': self.receipts,
|
||||
'num_zeros': self.num_zeros,
|
||||
'frozen_addresses': self.frozen_addresses,
|
||||
'prioritized_addresses': self.prioritized_addresses,
|
||||
'gap_limit': self.gap_limit,
|
||||
}
|
||||
for k, v in s.items():
|
||||
self.config.set_key(k,v)
|
||||
self.config.save()
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from electrum import TcpStratumInterface
|
||||
from electrum import Interface
|
||||
|
||||
i = TcpStratumInterface('electrum.novit.ro', 50001)
|
||||
i = Interface({'server':'electrum.novit.ro:50001:t'})
|
||||
i.init_socket()
|
||||
i.start()
|
||||
i.send([('blockchain.numblocks.subscribe',[])])
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from electrum import TcpStratumInterface
|
||||
from electrum import Interface
|
||||
|
||||
try:
|
||||
addr = sys.argv[1]
|
||||
|
@ -9,7 +9,7 @@ except:
|
|||
print "usage: get_history <bitcoin_address>"
|
||||
sys.exit(1)
|
||||
|
||||
i = TcpStratumInterface('electrum.novit.ro', 50001)
|
||||
i = Interface({'server':'electrum.novit.ro:50001:t'})
|
||||
i.init_socket()
|
||||
i.start()
|
||||
i.send([('blockchain.address.get_history',[addr])])
|
||||
|
|
|
@ -21,7 +21,7 @@ import time, thread, sys, socket, os
|
|||
import urllib2,json
|
||||
import MySQLdb as mdb
|
||||
import Queue
|
||||
from electrum import Wallet, TcpStratumInterface
|
||||
from electrum import Wallet, Interface
|
||||
|
||||
import ConfigParser
|
||||
config = ConfigParser.ConfigParser()
|
||||
|
@ -157,7 +157,7 @@ if __name__ == '__main__':
|
|||
print "using database", db_name
|
||||
conn = mdb.connect(db_instance, db_user, db_password, db_name);
|
||||
|
||||
i = TcpStratumInterface(electrum_server, 50001)
|
||||
i = Interface({'server':"%s:%d:t"%(electrum_server, 50001)})
|
||||
i.init_socket()
|
||||
i.start()
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from electrum import TcpStratumInterface
|
||||
from electrum import Interface
|
||||
|
||||
i = TcpStratumInterface('electrum.novit.ro', 50001)
|
||||
i = Interface({'server':'electrum.novit.ro:50001:t'})
|
||||
i.init_socket()
|
||||
i.start()
|
||||
i.send([('server.peers.subscribe',[])])
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from electrum import TcpStratumInterface
|
||||
from electrum import Interface
|
||||
|
||||
try:
|
||||
addr = sys.argv[1]
|
||||
|
@ -9,7 +9,7 @@ except:
|
|||
print "usage: watch_address <bitcoin_address>"
|
||||
sys.exit(1)
|
||||
|
||||
i = TcpStratumInterface('electrum.novit.ro', 50001)
|
||||
i = Interface({'server':'electrum.novit.ro:50001:t'})
|
||||
i.init_socket()
|
||||
i.start()
|
||||
i.send([('blockchain.address.subscribe',[addr])])
|
||||
|
|
Loading…
Reference in New Issue