Merge branch 'master' into feature/label_sync
This commit is contained in:
commit
884371eedd
8
electrum
8
electrum
|
@ -34,8 +34,10 @@ except ImportError:
|
||||||
sys.exit("Error: AES does not seem to be installed. Try 'sudo pip install slowaes'")
|
sys.exit("Error: AES does not seem to be installed. Try 'sudo pip install slowaes'")
|
||||||
|
|
||||||
|
|
||||||
|
is_android = 'ANDROID_DATA' in os.environ
|
||||||
|
|
||||||
# load local module as electrum
|
# load local module as electrum
|
||||||
if os.path.exists("lib"):
|
if os.path.exists("lib") or is_android:
|
||||||
import imp
|
import imp
|
||||||
fp, pathname, description = imp.find_module('lib')
|
fp, pathname, description = imp.find_module('lib')
|
||||||
imp.load_module('electrum', fp, pathname, description)
|
imp.load_module('electrum', fp, pathname, description)
|
||||||
|
@ -89,8 +91,8 @@ if __name__ == '__main__':
|
||||||
set_verbosity(options.verbose)
|
set_verbosity(options.verbose)
|
||||||
|
|
||||||
# config is an object passed to the various constructors (wallet, interface, gui)
|
# config is an object passed to the various constructors (wallet, interface, gui)
|
||||||
if 'ANDROID_DATA' in os.environ:
|
if is_android:
|
||||||
config_options = {'wallet_path':"/sdcard/electrum.dat", 'portable':True, 'verbose':True, 'gui':'android'}
|
config_options = {'wallet_path':"/sdcard/electrum.dat", 'portable':True, 'verbose':True, 'gui':'android', 'auto_cycle':True}
|
||||||
else:
|
else:
|
||||||
config_options = eval(str(options))
|
config_options = eval(str(options))
|
||||||
for k, v in config_options.items():
|
for k, v in config_options.items():
|
||||||
|
|
|
@ -363,6 +363,24 @@ class ElectrumWindow(QMainWindow):
|
||||||
apply(cb, args)
|
apply(cb, args)
|
||||||
|
|
||||||
|
|
||||||
|
# custom wrappers for getOpenFileName and getSaveFileName, that remember the path selected by the user
|
||||||
|
def getOpenFileName(self, title, filter = None):
|
||||||
|
directory = self.config.get('io_dir', os.path.expanduser('~'))
|
||||||
|
fileName = unicode( QFileDialog.getOpenFileName(self, title, directory, filter) )
|
||||||
|
if fileName and directory != os.path.dirname(fileName):
|
||||||
|
self.config.set_key('io_dir', os.path.dirname(fileName), True)
|
||||||
|
return fileName
|
||||||
|
|
||||||
|
def getSaveFileName(self, title, filename, filter = None):
|
||||||
|
directory = self.config.get('io_dir', os.path.expanduser('~'))
|
||||||
|
path = os.path.join( directory, filename )
|
||||||
|
fileName = unicode( QFileDialog.getSaveFileName(self, title, path, filter) )
|
||||||
|
if fileName and directory != os.path.dirname(fileName):
|
||||||
|
self.config.set_key('io_dir', os.path.dirname(fileName), True)
|
||||||
|
return fileName
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
QMainWindow.close(self)
|
QMainWindow.close(self)
|
||||||
self.run_hook('close_main_window', (self,))
|
self.run_hook('close_main_window', (self,))
|
||||||
|
@ -808,9 +826,9 @@ class ElectrumWindow(QMainWindow):
|
||||||
else:
|
else:
|
||||||
QMessageBox.warning(self, _('Error'), msg, _('OK'))
|
QMessageBox.warning(self, _('Error'), msg, _('OK'))
|
||||||
else:
|
else:
|
||||||
filename = 'unsigned_tx_%s' % (time.mktime(time.gmtime()))
|
filename = label + '.txn' if label else 'unsigned_%s.txn' % (time.mktime(time.gmtime()))
|
||||||
try:
|
try:
|
||||||
fileName = QFileDialog.getSaveFileName(QWidget(), _("Select a transaction filename"), os.path.expanduser('~/%s' % (filename)))
|
fileName = self.getSaveFileName(_("Select a transaction filename"), filename, "*.txn")
|
||||||
with open(fileName,'w') as f:
|
with open(fileName,'w') as f:
|
||||||
f.write(json.dumps(tx.as_dict(),indent=4) + '\n')
|
f.write(json.dumps(tx.as_dict(),indent=4) + '\n')
|
||||||
QMessageBox.information(self, _('Unsigned transaction created'), _("Unsigned transaction was saved to file:") + " " +fileName, _('OK'))
|
QMessageBox.information(self, _('Unsigned transaction created'), _("Unsigned transaction was saved to file:") + " " +fileName, _('OK'))
|
||||||
|
@ -1667,13 +1685,13 @@ class ElectrumWindow(QMainWindow):
|
||||||
if not tx_dict["complete"]:
|
if not tx_dict["complete"]:
|
||||||
assert "input_info" in tx_dict.keys()
|
assert "input_info" in tx_dict.keys()
|
||||||
except:
|
except:
|
||||||
QMessageBox.critical(None, "Unable to parse transaction", _("Electrum was unable to parse your transaction:"))
|
QMessageBox.critical(None, "Unable to parse transaction", _("Electrum was unable to parse your transaction"))
|
||||||
return None
|
return None
|
||||||
return tx_dict
|
return tx_dict
|
||||||
|
|
||||||
|
|
||||||
def read_tx_from_file(self):
|
def read_tx_from_file(self):
|
||||||
fileName = QFileDialog.getOpenFileName(QWidget(), _("Select your transaction file"), os.path.expanduser('~'))
|
fileName = self.getOpenFileName(_("Select your transaction file"), "*.txn")
|
||||||
if not fileName:
|
if not fileName:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
|
@ -1690,11 +1708,11 @@ class ElectrumWindow(QMainWindow):
|
||||||
try:
|
try:
|
||||||
self.wallet.signrawtransaction(tx, input_info, [], password)
|
self.wallet.signrawtransaction(tx, input_info, [], password)
|
||||||
|
|
||||||
fileName = QFileDialog.getSaveFileName(QWidget(), _("Select where to save your signed transaction"), os.path.expanduser('~/signed_tx_%s' % (tx.hash()[0:8])))
|
fileName = self.getSaveFileName(_("Select where to save your signed transaction"), 'signed_%s.txn' % (tx.hash()[0:8]), "*.txn")
|
||||||
if fileName:
|
if fileName:
|
||||||
with open(fileName, "w+") as f:
|
with open(fileName, "w+") as f:
|
||||||
f.write(json.dumps(tx.as_dict(),indent=4) + '\n')
|
f.write(json.dumps(tx.as_dict(),indent=4) + '\n')
|
||||||
self.show_message(_("Transaction saved succesfully"))
|
self.show_message(_("Transaction saved successfully"))
|
||||||
if dialog:
|
if dialog:
|
||||||
dialog.done(0)
|
dialog.done(0)
|
||||||
except BaseException, e:
|
except BaseException, e:
|
||||||
|
@ -1704,7 +1722,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
def send_raw_transaction(self, raw_tx, dialog = ""):
|
def send_raw_transaction(self, raw_tx, dialog = ""):
|
||||||
result, result_message = self.wallet.sendtx( raw_tx )
|
result, result_message = self.wallet.sendtx( raw_tx )
|
||||||
if result:
|
if result:
|
||||||
self.show_message("Transaction succesfully sent: %s" % (result_message))
|
self.show_message("Transaction successfully sent: %s" % (result_message))
|
||||||
if dialog:
|
if dialog:
|
||||||
dialog.done(0)
|
dialog.done(0)
|
||||||
else:
|
else:
|
||||||
|
@ -1779,7 +1797,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
select_export = _('Select file to export your private keys to')
|
select_export = _('Select file to export your private keys to')
|
||||||
fileName = QFileDialog.getSaveFileName(QWidget(), select_export, os.path.expanduser('~/electrum-private-keys.csv'), "*.csv")
|
fileName = self.getSaveFileName(select_export, 'electrum-private-keys.csv', "*.csv")
|
||||||
if fileName:
|
if fileName:
|
||||||
with open(fileName, "w+") as csvfile:
|
with open(fileName, "w+") as csvfile:
|
||||||
transaction = csv.writer(csvfile)
|
transaction = csv.writer(csvfile)
|
||||||
|
@ -1801,7 +1819,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
|
|
||||||
|
|
||||||
def do_import_labels(self):
|
def do_import_labels(self):
|
||||||
labelsFile = QFileDialog.getOpenFileName(QWidget(), _("Open text file"), util.user_dir(), self.tr("Text Files (labels.dat)"))
|
labelsFile = self.getOpenFileName(_("Open labels file"), "*.dat")
|
||||||
if not labelsFile: return
|
if not labelsFile: return
|
||||||
try:
|
try:
|
||||||
f = open(labelsFile, 'r')
|
f = open(labelsFile, 'r')
|
||||||
|
@ -1818,11 +1836,11 @@ class ElectrumWindow(QMainWindow):
|
||||||
def do_export_labels(self):
|
def do_export_labels(self):
|
||||||
labels = self.wallet.labels
|
labels = self.wallet.labels
|
||||||
try:
|
try:
|
||||||
labelsFile = util.user_dir() + '/labels.dat'
|
fileName = self.getSaveFileName(_("Select file to save your labels"), 'electrum_labels.dat', "*.dat")
|
||||||
f = open(labelsFile, 'w+')
|
if fileName:
|
||||||
|
with open(fileName, 'w+') as f:
|
||||||
json.dump(labels, f)
|
json.dump(labels, f)
|
||||||
f.close()
|
QMessageBox.information(None, "Labels exported", _("Your labels where exported to")+" '%s'" % str(fileName))
|
||||||
QMessageBox.information(None, "Labels exported", _("Your labels where exported to")+" '%s'" % str(labelsFile))
|
|
||||||
except (IOError, os.error), reason:
|
except (IOError, os.error), reason:
|
||||||
QMessageBox.critical(None, "Unable to export labels", _("Electrum was unable to export your labels.")+"\n" + str(reason))
|
QMessageBox.critical(None, "Unable to export labels", _("Electrum was unable to export your labels.")+"\n" + str(reason))
|
||||||
|
|
||||||
|
@ -1871,18 +1889,18 @@ class ElectrumWindow(QMainWindow):
|
||||||
tabs.addTab(tab1, _('Display') )
|
tabs.addTab(tab1, _('Display') )
|
||||||
|
|
||||||
nz_label = QLabel(_('Display zeros'))
|
nz_label = QLabel(_('Display zeros'))
|
||||||
grid_ui.addWidget(nz_label, 3, 0)
|
grid_ui.addWidget(nz_label, 0, 0)
|
||||||
nz_e = QLineEdit()
|
nz_e = QLineEdit()
|
||||||
nz_e.setText("%d"% self.wallet.num_zeros)
|
nz_e.setText("%d"% self.wallet.num_zeros)
|
||||||
grid_ui.addWidget(nz_e, 3, 1)
|
grid_ui.addWidget(nz_e, 0, 1)
|
||||||
msg = _('Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"')
|
msg = _('Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"')
|
||||||
grid_ui.addWidget(HelpButton(msg), 3, 2)
|
grid_ui.addWidget(HelpButton(msg), 0, 2)
|
||||||
nz_e.textChanged.connect(lambda: numbify(nz_e,True))
|
nz_e.textChanged.connect(lambda: numbify(nz_e,True))
|
||||||
if not self.config.is_modifiable('num_zeros'):
|
if not self.config.is_modifiable('num_zeros'):
|
||||||
for w in [nz_e, nz_label]: w.setEnabled(False)
|
for w in [nz_e, nz_label]: w.setEnabled(False)
|
||||||
|
|
||||||
lang_label=QLabel(_('Language') + ':')
|
lang_label=QLabel(_('Language') + ':')
|
||||||
grid_ui.addWidget(lang_label , 8, 0)
|
grid_ui.addWidget(lang_label, 1, 0)
|
||||||
lang_combo = QComboBox()
|
lang_combo = QComboBox()
|
||||||
from i18n import languages
|
from i18n import languages
|
||||||
lang_combo.addItems(languages.values())
|
lang_combo.addItems(languages.values())
|
||||||
|
@ -1891,8 +1909,8 @@ class ElectrumWindow(QMainWindow):
|
||||||
except:
|
except:
|
||||||
index = 0
|
index = 0
|
||||||
lang_combo.setCurrentIndex(index)
|
lang_combo.setCurrentIndex(index)
|
||||||
grid_ui.addWidget(lang_combo, 8, 1)
|
grid_ui.addWidget(lang_combo, 1, 1)
|
||||||
grid_ui.addWidget(HelpButton(_('Select which language is used in the GUI (after restart).')+' '), 8, 2)
|
grid_ui.addWidget(HelpButton(_('Select which language is used in the GUI (after restart).')+' '), 1, 2)
|
||||||
if not self.config.is_modifiable('language'):
|
if not self.config.is_modifiable('language'):
|
||||||
for w in [lang_combo, lang_label]: w.setEnabled(False)
|
for w in [lang_combo, lang_label]: w.setEnabled(False)
|
||||||
|
|
||||||
|
@ -1900,7 +1918,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
currencies.insert(0, "None")
|
currencies.insert(0, "None")
|
||||||
|
|
||||||
cur_label=QLabel(_('Currency') + ':')
|
cur_label=QLabel(_('Currency') + ':')
|
||||||
grid_ui.addWidget(cur_label , 9, 0)
|
grid_ui.addWidget(cur_label , 2, 0)
|
||||||
cur_combo = QComboBox()
|
cur_combo = QComboBox()
|
||||||
cur_combo.addItems(currencies)
|
cur_combo.addItems(currencies)
|
||||||
try:
|
try:
|
||||||
|
@ -1908,20 +1926,21 @@ class ElectrumWindow(QMainWindow):
|
||||||
except:
|
except:
|
||||||
index = 0
|
index = 0
|
||||||
cur_combo.setCurrentIndex(index)
|
cur_combo.setCurrentIndex(index)
|
||||||
grid_ui.addWidget(cur_combo, 9, 1)
|
grid_ui.addWidget(cur_combo, 2, 1)
|
||||||
grid_ui.addWidget(HelpButton(_('Select which currency is used for quotes.')+' '), 9, 2)
|
grid_ui.addWidget(HelpButton(_('Select which currency is used for quotes.')+' '), 2, 2)
|
||||||
|
|
||||||
view_label=QLabel(_('Receive Tab') + ':')
|
view_label=QLabel(_('Receive Tab') + ':')
|
||||||
grid_ui.addWidget(view_label , 10, 0)
|
grid_ui.addWidget(view_label , 3, 0)
|
||||||
view_combo = QComboBox()
|
view_combo = QComboBox()
|
||||||
view_combo.addItems([_('Simple'), _('Advanced')])
|
view_combo.addItems([_('Simple'), _('Advanced')])
|
||||||
view_combo.setCurrentIndex(self.expert_mode)
|
view_combo.setCurrentIndex(self.expert_mode)
|
||||||
grid_ui.addWidget(view_combo, 10, 1)
|
grid_ui.addWidget(view_combo, 3, 1)
|
||||||
hh = _('This selects the interaction mode of the "Receive" tab.')+' ' + '\n\n' \
|
hh = _('This selects the interaction mode of the "Receive" tab.')+' ' + '\n\n' \
|
||||||
+ _('Simple') + ': ' + _('Show only addresses and labels.') + '\n\n' \
|
+ _('Simple') + ': ' + _('Show only addresses and labels.') + '\n\n' \
|
||||||
+ _('Advanced') + ': ' + _('Show address balances and add extra menu items to freeze/prioritize addresses.') + '\n\n'
|
+ _('Advanced') + ': ' + _('Show address balances and add extra menu items to freeze/prioritize addresses.') + '\n\n'
|
||||||
|
|
||||||
grid_ui.addWidget(HelpButton(hh), 10, 2)
|
grid_ui.addWidget(HelpButton(hh), 3, 2)
|
||||||
|
grid_ui.setRowStretch(4,1)
|
||||||
|
|
||||||
# wallet tab
|
# wallet tab
|
||||||
tab2 = QWidget()
|
tab2 = QWidget()
|
||||||
|
@ -1929,11 +1948,6 @@ class ElectrumWindow(QMainWindow):
|
||||||
grid_wallet.setColumnStretch(0,1)
|
grid_wallet.setColumnStretch(0,1)
|
||||||
tabs.addTab(tab2, _('Wallet') )
|
tabs.addTab(tab2, _('Wallet') )
|
||||||
|
|
||||||
grid_wallet.addWidget(QLabel(_("Load raw transaction")), 3, 0)
|
|
||||||
grid_wallet.addWidget(EnterButton(_("From file"), self.do_process_from_file),3,1)
|
|
||||||
grid_wallet.addWidget(EnterButton(_("From text"), self.do_process_from_text),3,2)
|
|
||||||
grid_wallet.addWidget(HelpButton(_("This will give you the option to sign or broadcast a transaction based on it's status.")),3,3)
|
|
||||||
|
|
||||||
fee_label = QLabel(_('Transaction fee'))
|
fee_label = QLabel(_('Transaction fee'))
|
||||||
grid_wallet.addWidget(fee_label, 0, 0)
|
grid_wallet.addWidget(fee_label, 0, 0)
|
||||||
fee_e = QLineEdit()
|
fee_e = QLineEdit()
|
||||||
|
@ -2002,12 +2016,18 @@ class ElectrumWindow(QMainWindow):
|
||||||
+ _('If you give it to someone, they will be able to see your transactions, but not to spend your money.') + ' ' \
|
+ _('If you give it to someone, they will be able to see your transactions, but not to spend your money.') + ' ' \
|
||||||
+ _('If you restore your wallet from it, a watching-only (deseeded) wallet will be created.')), 4, 3)
|
+ _('If you restore your wallet from it, a watching-only (deseeded) wallet will be created.')), 4, 3)
|
||||||
|
|
||||||
grid_io.setRowStretch(4,1)
|
|
||||||
|
grid_io.addWidget(QLabel(_("Load transaction")), 5, 0)
|
||||||
|
grid_io.addWidget(EnterButton(_("From file"), self.do_process_from_file), 5, 1)
|
||||||
|
grid_io.addWidget(EnterButton(_("From text"), self.do_process_from_text), 5, 2)
|
||||||
|
grid_io.addWidget(HelpButton(_("This will give you the option to sign or broadcast a transaction based on it's status.")), 5, 3)
|
||||||
|
|
||||||
|
grid_io.setRowStretch(5,1)
|
||||||
|
|
||||||
|
|
||||||
# plugins
|
# plugins
|
||||||
if self.plugins:
|
if self.plugins:
|
||||||
tab5 = QWidget()
|
tab5 = QScrollArea()
|
||||||
grid_plugins = QGridLayout(tab5)
|
grid_plugins = QGridLayout(tab5)
|
||||||
grid_plugins.setColumnStretch(0,1)
|
grid_plugins.setColumnStretch(0,1)
|
||||||
tabs.addTab(tab5, _('Plugins') )
|
tabs.addTab(tab5, _('Plugins') )
|
||||||
|
@ -2017,8 +2037,9 @@ class ElectrumWindow(QMainWindow):
|
||||||
try:
|
try:
|
||||||
name, description = p.get_info()
|
name, description = p.get_info()
|
||||||
cb = QCheckBox(name)
|
cb = QCheckBox(name)
|
||||||
|
cb.setDisabled(not p.is_available())
|
||||||
cb.setChecked(p.is_enabled())
|
cb.setChecked(p.is_enabled())
|
||||||
cb.stateChanged.connect(mk_toggle(cb,p))
|
cb.clicked.connect(mk_toggle(cb,p))
|
||||||
grid_plugins.addWidget(cb, i, 0)
|
grid_plugins.addWidget(cb, i, 0)
|
||||||
grid_plugins.addWidget(HelpButton(description), i, 2)
|
grid_plugins.addWidget(HelpButton(description), i, 2)
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -44,10 +44,12 @@ languages = {
|
||||||
'es':_('Spanish'),
|
'es':_('Spanish'),
|
||||||
'fr':_('French'),
|
'fr':_('French'),
|
||||||
'it':_('Italian'),
|
'it':_('Italian'),
|
||||||
|
'ja':_('Japanese'),
|
||||||
'lv':_('Latvian'),
|
'lv':_('Latvian'),
|
||||||
'nl':_('Dutch'),
|
'nl':_('Dutch'),
|
||||||
'ru':_('Russian'),
|
'ru':_('Russian'),
|
||||||
'sl':_('Slovenian'),
|
'sl':_('Slovenian'),
|
||||||
|
'ta':_('Tamil'),
|
||||||
'vi':_('Vietnamese'),
|
'vi':_('Vietnamese'),
|
||||||
'zh':_('Chinese')
|
'zh':_('Chinese')
|
||||||
}
|
}
|
||||||
|
|
|
@ -415,13 +415,10 @@ def CKD_prime(K, c, n):
|
||||||
class ElectrumSequence:
|
class ElectrumSequence:
|
||||||
""" Privatekey(type,n) = Master_private_key + H(n|S|type) """
|
""" Privatekey(type,n) = Master_private_key + H(n|S|type) """
|
||||||
|
|
||||||
def __init__(self, master_public_key, mpk2 = None):
|
def __init__(self, master_public_key, mpk2 = None, mpk3 = None):
|
||||||
self.master_public_key = master_public_key
|
self.master_public_key = master_public_key
|
||||||
if mpk2:
|
|
||||||
self.mpk2 = mpk2
|
self.mpk2 = mpk2
|
||||||
self.is_p2sh = True
|
self.mpk3 = mpk3
|
||||||
else:
|
|
||||||
self.is_p2sh = False
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def mpk_from_seed(klass, seed):
|
def mpk_from_seed(klass, seed):
|
||||||
|
@ -443,18 +440,23 @@ class ElectrumSequence:
|
||||||
return string_to_number( Hash( "%d:%d:"%(n,for_change) + mpk.decode('hex') ) )
|
return string_to_number( Hash( "%d:%d:"%(n,for_change) + mpk.decode('hex') ) )
|
||||||
|
|
||||||
def get_address(self, sequence):
|
def get_address(self, sequence):
|
||||||
if not self.is_p2sh:
|
if not self.mpk2:
|
||||||
pubkey = self.get_pubkey(sequence)
|
pubkey = self.get_pubkey(sequence)
|
||||||
address = public_key_to_bc_address( pubkey.decode('hex') )
|
address = public_key_to_bc_address( pubkey.decode('hex') )
|
||||||
else:
|
elif not self.mpk3:
|
||||||
pubkey1 = self.get_pubkey(sequence)
|
pubkey1 = self.get_pubkey(sequence)
|
||||||
pubkey2 = self.get_pubkey(sequence, use_mpk2=True)
|
pubkey2 = self.get_pubkey(sequence, use_mpk2=True)
|
||||||
address = Transaction.multisig_script([pubkey1, pubkey2], 2)["address"]
|
address = Transaction.multisig_script([pubkey1, pubkey2], 2)["address"]
|
||||||
|
else:
|
||||||
|
pubkey1 = self.get_pubkey(sequence)
|
||||||
|
pubkey2 = self.get_pubkey(sequence, mpk = self.mpk2)
|
||||||
|
pubkey3 = self.get_pubkey(sequence, mpk = self.mpk3)
|
||||||
|
address = Transaction.multisig_script([pubkey1, pubkey2, pubkey3], 2)["address"]
|
||||||
return address
|
return address
|
||||||
|
|
||||||
def get_pubkey(self, sequence, use_mpk2=False):
|
def get_pubkey(self, sequence, mpk=None):
|
||||||
curve = SECP256k1
|
curve = SECP256k1
|
||||||
mpk = self.mpk2 if use_mpk2 else self.master_public_key
|
if mpk is None: mpk = self.master_public_key
|
||||||
z = self.get_sequence(sequence, mpk)
|
z = self.get_sequence(sequence, mpk)
|
||||||
master_public_key = ecdsa.VerifyingKey.from_string( mpk.decode('hex'), curve = SECP256k1 )
|
master_public_key = ecdsa.VerifyingKey.from_string( mpk.decode('hex'), curve = SECP256k1 )
|
||||||
pubkey_point = master_public_key.pubkey.point + z*curve.generator
|
pubkey_point = master_public_key.pubkey.point + z*curve.generator
|
||||||
|
@ -484,21 +486,23 @@ class ElectrumSequence:
|
||||||
if master_public_key != self.master_public_key:
|
if master_public_key != self.master_public_key:
|
||||||
print_error('invalid password (mpk)')
|
print_error('invalid password (mpk)')
|
||||||
raise BaseException('Invalid password')
|
raise BaseException('Invalid password')
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_input_info(self, sequence):
|
def get_input_info(self, sequence):
|
||||||
|
if not self.mpk2:
|
||||||
if not self.is_p2sh:
|
|
||||||
pk_addr = self.get_address(sequence)
|
pk_addr = self.get_address(sequence)
|
||||||
redeemScript = None
|
redeemScript = None
|
||||||
else:
|
elif not self.mpk3:
|
||||||
pubkey1 = self.get_pubkey(sequence)
|
pubkey1 = self.get_pubkey(sequence)
|
||||||
pubkey2 = self.get_pubkey(sequence,use_mpk2=True)
|
pubkey2 = self.get_pubkey(sequence,mpk=self.mpk2)
|
||||||
pk_addr = public_key_to_bc_address( pubkey1.decode('hex') ) # we need to return that address to get the right private key
|
pk_addr = public_key_to_bc_address( pubkey1.decode('hex') ) # we need to return that address to get the right private key
|
||||||
redeemScript = Transaction.multisig_script([pubkey1, pubkey2], 2)['redeemScript']
|
redeemScript = Transaction.multisig_script([pubkey1, pubkey2], 2)['redeemScript']
|
||||||
|
else:
|
||||||
|
pubkey1 = self.get_pubkey(sequence)
|
||||||
|
pubkey2 = self.get_pubkey(sequence,mpk=self.mpk2)
|
||||||
|
pubkey3 = self.get_pubkey(sequence,mpk=self.mpk3)
|
||||||
|
pk_addr = public_key_to_bc_address( pubkey1.decode('hex') ) # we need to return that address to get the right private key
|
||||||
|
redeemScript = Transaction.multisig_script([pubkey1, pubkey2, pubkey3], 2)['redeemScript']
|
||||||
return pk_addr, redeemScript
|
return pk_addr, redeemScript
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ELECTRUM_VERSION = "1.7" # version of the client package
|
ELECTRUM_VERSION = "1.7" # version of the client package
|
||||||
PROTOCOL_VERSION = '0.6' # protocol version requested
|
PROTOCOL_VERSION = '0.6' # protocol version requested
|
||||||
SEED_VERSION = 4 # bump this every time the seed generation is modified
|
SEED_VERSION = 4 # bump this every time the seed generation is modified
|
||||||
TRANSLATION_ID = 3958 # version of the wiki page
|
TRANSLATION_ID = 3992 # version of the wiki page
|
||||||
|
|
|
@ -20,10 +20,13 @@ if __name__ == '__main__':
|
||||||
# android
|
# android
|
||||||
os.system('rm -rf dist/e4a-%s'%version)
|
os.system('rm -rf dist/e4a-%s'%version)
|
||||||
os.mkdir('dist/e4a-%s'%version)
|
os.mkdir('dist/e4a-%s'%version)
|
||||||
shutil.copyfile("electrum",'dist/e4a-%s/electrum.py'%version)
|
shutil.copyfile("electrum",'dist/e4a-%s/e4a.py'%version)
|
||||||
shutil.copytree("ecdsa",'dist/e4a-%s/ecdsa'%version)
|
shutil.copytree("ecdsa",'dist/e4a-%s/ecdsa'%version)
|
||||||
shutil.copytree("aes",'dist/e4a-%s/aes'%version)
|
shutil.copytree("aes",'dist/e4a-%s/aes'%version)
|
||||||
shutil.copytree("lib",'dist/e4a-%s/electrum'%version)
|
shutil.copytree("lib",'dist/e4a-%s/lib'%version)
|
||||||
|
os.mkdir('dist/e4a-%s/gui'%version)
|
||||||
|
shutil.copy("gui/gui_android.py",'dist/e4a-%s/gui'%version)
|
||||||
|
shutil.copy("gui/__init__.py",'dist/e4a-%s/gui'%version)
|
||||||
|
|
||||||
os.chdir("dist")
|
os.chdir("dist")
|
||||||
# create the zip file
|
# create the zip file
|
||||||
|
|
|
@ -92,38 +92,36 @@ class QR_Window(QWidget):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
config = {}
|
||||||
|
|
||||||
def get_info():
|
def get_info():
|
||||||
return 'Point of Sale', _('Show QR code window and amounts requested for each address. Add menu item to request amount.')
|
return 'Point of Sale', _('Show QR code window and amounts requested for each address. Add menu item to request amount.')
|
||||||
|
|
||||||
def init(gui):
|
def init(gui):
|
||||||
gui.requested_amounts = gui.config.get('requested_amounts',{})
|
global config
|
||||||
gui.merchant_name = gui.config.get('merchant_name', 'Invoice')
|
config = gui.config
|
||||||
|
gui.requested_amounts = config.get('requested_amounts',{})
|
||||||
|
gui.merchant_name = config.get('merchant_name', 'Invoice')
|
||||||
gui.qr_window = None
|
gui.qr_window = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enabled = False
|
|
||||||
|
|
||||||
def is_enabled():
|
def is_enabled():
|
||||||
return False
|
return config.get('pointofsale') is True
|
||||||
|
|
||||||
|
def is_available():
|
||||||
|
return True
|
||||||
|
|
||||||
def toggle(gui):
|
def toggle(gui):
|
||||||
global enabled
|
|
||||||
enabled = not enabled
|
|
||||||
toggle_QR_window(gui, enabled)
|
|
||||||
|
|
||||||
if enabled:
|
if not is_enabled():
|
||||||
gui.expert_mode = True
|
gui.expert_mode = True
|
||||||
gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Request')])
|
gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Request')])
|
||||||
|
|
||||||
gui.set_hook('item_changed', item_changed)
|
gui.set_hook('item_changed', item_changed)
|
||||||
gui.set_hook('current_item_changed', recv_changed)
|
gui.set_hook('current_item_changed', recv_changed)
|
||||||
gui.set_hook('receive_menu', receive_menu)
|
gui.set_hook('receive_menu', receive_menu)
|
||||||
gui.set_hook('update_receive_item', update_receive_item)
|
gui.set_hook('update_receive_item', update_receive_item)
|
||||||
gui.set_hook('timer_actions', timer_actions)
|
gui.set_hook('timer_actions', timer_actions)
|
||||||
gui.set_hook('close_main_window', close_main_window)
|
gui.set_hook('close_main_window', close_main_window)
|
||||||
|
enabled = True
|
||||||
else:
|
else:
|
||||||
gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Tx')])
|
gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Tx')])
|
||||||
gui.unset_hook('item_changed', item_changed)
|
gui.unset_hook('item_changed', item_changed)
|
||||||
|
@ -132,11 +130,15 @@ def toggle(gui):
|
||||||
gui.unset_hook('update_receive_item', update_receive_item)
|
gui.unset_hook('update_receive_item', update_receive_item)
|
||||||
gui.unset_hook('timer_actions', timer_actions)
|
gui.unset_hook('timer_actions', timer_actions)
|
||||||
gui.unset_hook('close_main_window', close_main_window)
|
gui.unset_hook('close_main_window', close_main_window)
|
||||||
|
enabled = False
|
||||||
|
|
||||||
|
config.set_key('pointofsale', enabled, True)
|
||||||
|
toggle_QR_window(gui, enabled)
|
||||||
return enabled
|
return enabled
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def toggle_QR_window(self, show):
|
def toggle_QR_window(self, show):
|
||||||
if show and not self.qr_window:
|
if show and not self.qr_window:
|
||||||
self.qr_window = QR_Window(self.exchanger)
|
self.qr_window = QR_Window(self.exchanger)
|
||||||
|
|
Loading…
Reference in New Issue