diff --git a/electrum b/electrum index 94f0ec64..706e90ea 100755 --- a/electrum +++ b/electrum @@ -43,7 +43,7 @@ if jnius: script_dir = os.path.dirname(os.path.realpath(__file__)) is_bundle = getattr(sys, 'frozen', False) -is_local = not is_bundle and os.path.exists(os.path.join(script_dir, "electrum.desktop")) +is_local = not is_bundle and os.path.exists(os.path.join(script_dir, "electrum-zcash.desktop")) is_android = 'ANDROID_DATA' in os.environ # move this back to gui/kivy/__init.py once plugins are moved @@ -82,22 +82,22 @@ if not is_android: # load local module as electrum if is_local or is_android: import imp - imp.load_module('electrum', *imp.find_module('lib')) - imp.load_module('electrum_gui', *imp.find_module('gui')) - imp.load_module('electrum_plugins', *imp.find_module('plugins')) + imp.load_module('electrum_zcash', *imp.find_module('lib')) + imp.load_module('electrum_zcash_gui', *imp.find_module('gui')) + imp.load_module('electrum_zcash_plugins', *imp.find_module('plugins')) -from electrum import bitcoin -from electrum import SimpleConfig, Network -from electrum.wallet import Wallet, Imported_Wallet -from electrum.storage import WalletStorage -from electrum.util import print_msg, print_stderr, json_encode, json_decode -from electrum.util import set_verbosity, InvalidPassword, check_www_dir -from electrum.commands import get_parser, known_commands, Commands, config_variables -from electrum import daemon -from electrum import keystore -from electrum.mnemonic import Mnemonic -import electrum_plugins +from electrum_zcash import bitcoin +from electrum_zcash import SimpleConfig, Network +from electrum_zcash.wallet import Wallet, Imported_Wallet +from electrum_zcash.storage import WalletStorage +from electrum_zcash.util import print_msg, print_stderr, json_encode, json_decode +from electrum_zcash.util import set_verbosity, InvalidPassword, check_www_dir +from electrum_zcash.commands import get_parser, known_commands, Commands, config_variables +from electrum_zcash import daemon +from electrum_zcash import keystore +from electrum_zcash.mnemonic import Mnemonic +import electrum_zcash_plugins # get password routine def prompt_password(prompt, confirm=True): @@ -189,7 +189,7 @@ def init_daemon(config_options): storage = WalletStorage(config.get_wallet_path()) if not storage.file_exists(): print_msg("Error: Wallet file not found.") - print_msg("Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option") + print_msg("Type 'electrum-zcash create' to create a new wallet, or provide a path to a wallet with the -w option") sys.exit(0) if storage.is_encrypted(): if config.get('password'): @@ -224,7 +224,7 @@ def init_cmdline(config_options, server): if cmd.requires_wallet and not storage.file_exists(): print_msg("Error: Wallet file not found.") - print_msg("Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option") + print_msg("Type 'electrum-zcash create' to create a new wallet, or provide a path to a wallet with the -w option") sys.exit(0) # important warning @@ -292,7 +292,7 @@ def run_offline_command(config, config_options): return result def init_plugins(config, gui_name): - from electrum.plugins import Plugins + from electrum_zcash.plugins import Plugins return Plugins(config, is_local or is_android, gui_name) if __name__ == '__main__': @@ -351,7 +351,7 @@ if __name__ == '__main__': # check uri uri = config_options.get('url') if uri: - if not uri.startswith('bitcoin:'): + if not uri.startswith('zcash:'): print_stderr('unknown command:', uri) sys.exit(1) config_options['url'] = uri @@ -396,7 +396,7 @@ if __name__ == '__main__': d = daemon.Daemon(config, fd, False) d.start() if config.get('websocket_server'): - from electrum import websockets + from electrum_zcash import websockets websockets.WebSocketServer(config, d.network).start() if config.get('requests_dir'): check_www_dir(config.get('requests_dir')) @@ -420,7 +420,7 @@ if __name__ == '__main__': else: cmd = known_commands[cmdname] if cmd.requires_network: - print_msg("Daemon not running; try 'electrum daemon start'") + print_msg("Daemon not running; try 'electrum-zcash daemon start'") sys.exit(1) else: init_plugins(config, 'cmdline') diff --git a/electrum-env b/electrum-zcash-env similarity index 96% rename from electrum-env rename to electrum-zcash-env index 42220eda..6accad0a 100644 --- a/electrum-env +++ b/electrum-zcash-env @@ -19,6 +19,6 @@ fi export PYTHONPATH="/usr/local/lib/python3.5/site-packages:$PYTHONPATH" -./electrum "$@" +./electrum-zcash "$@" deactivate diff --git a/electrum.conf.sample b/electrum-zcash.conf.sample similarity index 68% rename from electrum.conf.sample rename to electrum-zcash.conf.sample index 60198a1e..d0955f0a 100644 --- a/electrum.conf.sample +++ b/electrum-zcash.conf.sample @@ -1,7 +1,7 @@ -# Configuration file for the electrum client +# Configuration file for the electrum-zcash client # Settings defined here are shared across wallets # -# copy this file to /etc/electrum.conf if you want read-only settings +# copy this file to /etc/electrum-zcash.conf if you want read-only settings [client] server = electrum.novit.ro:50001:t diff --git a/electrum-zcash.desktop b/electrum-zcash.desktop new file mode 100644 index 00000000..1e0b1bed --- /dev/null +++ b/electrum-zcash.desktop @@ -0,0 +1,17 @@ +# If you want electrum-zcash to appear in a linux app launcher ("start menu"), install this by doing: +# sudo desktop-file-install electrum-zcash.desktop + +[Desktop Entry] +Comment=Lightweight Zcash Client +Exec=electrum-zcash %u +GenericName[en_US]=Zcash Wallet +GenericName=Zcash Wallet +Icon=electrum-zcash.png +Name[en_US]=Electrum-Zcash Bitcoin Wallet +Name=Electrum-Zcash Bitcoin Wallet +Categories=Finance;Network; +StartupNotify=false +Terminal=false +Type=Application +MimeType=x-scheme-handler/zcash; + diff --git a/electrum.desktop b/electrum.desktop deleted file mode 100644 index 92540ea4..00000000 --- a/electrum.desktop +++ /dev/null @@ -1,17 +0,0 @@ -# If you want electrum to appear in a linux app launcher ("start menu"), install this by doing: -# sudo desktop-file-install electrum.desktop - -[Desktop Entry] -Comment=Lightweight Bitcoin Client -Exec=electrum %u -GenericName[en_US]=Bitcoin Wallet -GenericName=Bitcoin Wallet -Icon=electrum -Name[en_US]=Electrum Bitcoin Wallet -Name=Electrum Bitcoin Wallet -Categories=Finance;Network; -StartupNotify=false -Terminal=false -Type=Application -MimeType=x-scheme-handler/bitcoin; - diff --git a/lib/base_wizard.py b/lib/base_wizard.py index 58153f61..275f977c 100644 --- a/lib/base_wizard.py +++ b/lib/base_wizard.py @@ -79,27 +79,18 @@ class BaseWizard(object): ]) wallet_kinds = [ ('standard', _("Standard wallet")), - ('2fa', _("Wallet with two-factor authentication")), ('multisig', _("Multi-signature wallet")), - ('imported', _("Import Bitcoin addresses or private keys")), + ('imported', _("Import Zcash addresses or private keys")), ] choices = [pair for pair in wallet_kinds if pair[0] in wallet_types] self.choice_dialog(title=title, message=message, choices=choices, run_next=self.on_wallet_type) - def load_2fa(self): - self.storage.put('wallet_type', '2fa') - self.storage.put('use_trustedcoin', True) - self.plugin = self.plugins.load_plugin('trustedcoin') - def on_wallet_type(self, choice): self.wallet_type = choice if choice == 'standard': action = 'choose_keystore' elif choice == 'multisig': action = 'choose_multisig' - elif choice == '2fa': - self.load_2fa() - action = self.storage.get_action() elif choice == 'imported': action = 'import_addresses_or_keys' self.run(action) @@ -138,8 +129,8 @@ class BaseWizard(object): def import_addresses_or_keys(self): v = lambda x: keystore.is_address_list(x) or keystore.is_private_key_list(x) - title = _("Import Bitcoin Addresses") - message = _("Enter a list of Bitcoin addresses (this will create a watching-only wallet), or a list of private keys.") + title = _("Import Zcash Addresses") + message = _("Enter a list of Zcash addresses (this will create a watching-only wallet), or a list of private keys.") self.add_xpub_dialog(title=title, message=message, run_next=self.on_import, is_valid=v) def on_import(self, text): @@ -160,8 +151,8 @@ class BaseWizard(object): v = keystore.is_master_key title = _("Create keystore from a master key") message = ' '.join([ - _("To create a watching-only wallet, please enter your master public key (xpub/ypub/zpub)."), - _("To create a spending wallet, please enter a master private key (xprv/yprv/zprv).") + _("To create a watching-only wallet, please enter your master public key (xpub)."), + _("To create a spending wallet, please enter a master private key (xprv).") ]) self.add_xpub_dialog(title=title, message=message, run_next=self.on_restore_from_key, is_valid=v) else: @@ -285,13 +276,6 @@ class BaseWizard(object): self.passphrase_dialog(run_next=f) if is_ext else f('') elif self.seed_type == 'old': self.run('create_keystore', seed, '') - elif self.seed_type == '2fa': - if self.is_kivy: - self.show_error('2FA seeds are not supported in this version') - self.run('restore_from_seed') - else: - self.load_2fa() - self.run('on_restore_seed', seed, is_ext) else: raise BaseException('Unknown seed type', self.seed_type) @@ -424,5 +408,5 @@ class BaseWizard(object): self.wallet.synchronize() self.wallet.storage.write() self.terminate() - msg = _("Electrum is generating your addresses, please wait.") + msg = _("Electrum-Zcash is generating your addresses, please wait.") self.waiting_dialog(task, msg) diff --git a/lib/bitcoin.py b/lib/bitcoin.py index 918502ef..05730280 100644 --- a/lib/bitcoin.py +++ b/lib/bitcoin.py @@ -271,8 +271,6 @@ def seed_type(x): return 'old' elif is_new_seed(x): return 'standard' - elif is_new_seed(x, version.SEED_PREFIX_2FA): - return '2fa' return '' is_seed = lambda x: bool(seed_type(x)) @@ -558,7 +556,7 @@ from ecdsa.util import string_to_number, number_to_string def msg_magic(message): length = bfh(var_int(len(message))) - return b"\x18Bitcoin Signed Message:\n" + length + message + return b"\x18Zcash Signed Message:\n" + length + message def verify_message(address, sig, message): diff --git a/lib/commands.py b/lib/commands.py index 2f823c28..28aebaa1 100644 --- a/lib/commands.py +++ b/lib/commands.py @@ -81,7 +81,7 @@ def command(s): wallet = args[0].wallet password = kwargs.get('password') if c.requires_wallet and wallet is None: - raise BaseException("wallet not loaded. Use 'electrum daemon load_wallet'") + raise BaseException("wallet not loaded. Use 'electrum-zcash daemon load_wallet'") if c.requires_password and password is None and wallet.storage.get('use_encryption'): return {'error': 'Password required' } return func(*args, **kwargs) @@ -130,8 +130,8 @@ class Commands: @command('wn') def restore(self, text): """Restore a wallet from text. Text can be a seed phrase, a master - public key, a master private key, a list of bitcoin addresses - or bitcoin private keys. If you want to be prompted for your + public key, a master private key, a list of Zcash addresses + or Zcash private keys. If you want to be prompted for your seed, type '?' or ':' (concealed) """ raise BaseException('Not a JSON-RPC command') @@ -288,7 +288,7 @@ class Commands: @command('') def dumpprivkeys(self): """Deprecated.""" - return "This command is deprecated. Use a pipe instead: 'electrum listaddresses | electrum getprivatekeys - '" + return "This command is deprecated. Use a pipe instead: 'electrum-zcash listaddresses | electrum-zcash getprivatekeys - '" @command('') def validateaddress(self, address): @@ -332,7 +332,7 @@ class Commands: @command('n') def getmerkle(self, txid, height): - """Get Merkle branch of a transaction included in a block. Electrum + """Get Merkle branch of a transaction included in a block. Electrum-Zcash uses this to verify transactions (Simple Payment Verification).""" return self.network.synchronous_get(('blockchain.transaction.get_merkle', [txid, int(height)])) @@ -343,7 +343,7 @@ class Commands: @command('') def version(self): - """Return the version of electrum.""" + """Return the version of electrum-zcash.""" from .version import ELECTRUM_VERSION return ELECTRUM_VERSION @@ -491,7 +491,7 @@ class Commands: @command('w') def setlabel(self, key, label): - """Assign a label to an item. Item may be a bitcoin address or a + """Assign a label to an item. Item may be a Zcash address or a transaction ID""" self.wallet.set_label(key, label) @@ -569,7 +569,7 @@ class Commands: PR_PAID: 'Paid', PR_EXPIRED: 'Expired', } - out['amount (BTC)'] = format_satoshis(out.get('amount')) + out['amount (ZEC)'] = format_satoshis(out.get('amount')) out['status'] = pr_str[out.get('status', PR_UNKNOWN)] return out @@ -679,8 +679,8 @@ class Commands: param_descriptions = { 'privkey': 'Private key. Type \'?\' to get a prompt.', - 'destination': 'Bitcoin address, contact or alias', - 'address': 'Bitcoin address', + 'destination': 'Zcash address, contact or alias', + 'address': 'Zcash address', 'seed': 'Seed phrase', 'txid': 'Transaction ID', 'pos': 'Position', @@ -690,8 +690,8 @@ param_descriptions = { 'pubkey': 'Public key', 'message': 'Clear text message. Use quotes if it contains spaces.', 'encrypted': 'Encrypted message', - 'amount': 'Amount to be sent (in BTC). Type \'!\' to send the maximum available.', - 'requested_amount': 'Requested amount (in BTC).', + 'amount': 'Amount to be sent (in ZEC). Type \'!\' to send the maximum available.', + 'requested_amount': 'Requested amount (in ZEC).', 'outputs': 'list of ["address", amount]', 'redeem_script': 'redeem script (hexadecimal)', } @@ -708,7 +708,7 @@ command_options = { 'labels': ("-l", "Show the labels of listed addresses"), 'nocheck': (None, "Do not verify aliases"), 'imax': (None, "Maximum number of inputs"), - 'fee': ("-f", "Transaction fee (in BTC)"), + 'fee': ("-f", "Transaction fee (in ZEC)"), 'from_addr': ("-F", "Source address (must be a wallet address; use sweep to spend from non-wallet address)."), 'change_addr': ("-c", "Change address. Default is a spare address, or the source address if it's not in the wallet"), 'nbits': (None, "Number of bits of entropy"), @@ -753,10 +753,10 @@ config_variables = { 'requests_dir': 'directory where a bip70 file will be written.', 'ssl_privkey': 'Path to your SSL private key, needed to sign the request.', 'ssl_chain': 'Chain of SSL certificates, needed for signed requests. Put your certificate at the top and the root CA at the end', - 'url_rewrite': 'Parameters passed to str.replace(), in order to create the r= part of bitcoin: URIs. Example: \"(\'file:///var/www/\',\'https://electrum.org/\')\"', + 'url_rewrite': 'Parameters passed to str.replace(), in order to create the r= part of zcash: URIs. Example: \"(\'file:///var/www/\',\'https://electrum.org/\')\"', }, 'listrequests':{ - 'url_rewrite': 'Parameters passed to str.replace(), in order to create the r= part of bitcoin: URIs. Example: \"(\'file:///var/www/\',\'https://electrum.org/\')\"', + 'url_rewrite': 'Parameters passed to str.replace(), in order to create the r= part of zcash: URIs. Example: \"(\'file:///var/www/\',\'https://electrum.org/\')\"', } } @@ -820,7 +820,7 @@ def add_network_options(parser): def add_global_options(parser): group = parser.add_argument_group('global options') group.add_argument("-v", "--verbose", action="store_true", dest="verbose", default=False, help="Show debugging information") - group.add_argument("-D", "--dir", dest="electrum_path", help="electrum directory") + group.add_argument("-D", "--dir", dest="electrum_path", help="electrum-zcash directory") group.add_argument("-P", "--portable", action="store_true", dest="portable", default=False, help="Use local 'electrum_data' directory") group.add_argument("-w", "--wallet", dest="wallet_path", help="wallet path") group.add_argument("--testnet", action="store_true", dest="testnet", default=False, help="Use Testnet") @@ -828,12 +828,12 @@ def add_global_options(parser): def get_parser(): # create main parser parser = argparse.ArgumentParser( - epilog="Run 'electrum help ' to see the help for a command") + epilog="Run 'electrum-zcash help ' to see the help for a command") add_global_options(parser) subparsers = parser.add_subparsers(dest='cmd', metavar='') # gui - parser_gui = subparsers.add_parser('gui', description="Run Electrum's Graphical User Interface.", help="Run GUI (default)") - parser_gui.add_argument("url", nargs='?', default=None, help="bitcoin URI (or bip70 file)") + parser_gui = subparsers.add_parser('gui', description="Run Electrum-Zcash Graphical User Interface.", help="Run GUI (default)") + parser_gui.add_argument("url", nargs='?', default=None, help="Zcash URI (or bip70 file)") parser_gui.add_argument("-g", "--gui", dest="gui", help="select graphical user interface", choices=['qt', 'kivy', 'text', 'stdio']) parser_gui.add_argument("-o", "--offline", action="store_true", dest="offline", default=False, help="Run offline") parser_gui.add_argument("-m", action="store_true", dest="hide_gui", default=False, help="hide GUI on startup") diff --git a/lib/contacts.py b/lib/contacts.py index 3b5a3255..165d45b5 100644 --- a/lib/contacts.py +++ b/lib/contacts.py @@ -87,13 +87,13 @@ class Contacts(dict): 'type': 'openalias', 'validated': validated } - raise Exception("Invalid Bitcoin address or alias", k) + raise Exception("Invalid Zcash address or alias", k) def resolve_openalias(self, url): # support email-style addresses, per the OA standard url = url.replace('@', '.') records, validated = dnssec.query(url, dns.rdatatype.TXT) - prefix = 'btc' + prefix = 'zcash' for record in records: string = record.strings[0] if string.startswith('oa1:' + prefix): diff --git a/lib/daemon.py b/lib/daemon.py index 6bd5ec0b..b2244e80 100644 --- a/lib/daemon.py +++ b/lib/daemon.py @@ -299,6 +299,6 @@ class Daemon(DaemonThread): gui_name = config.get('gui', 'qt') if gui_name in ['lite', 'classic']: gui_name = 'qt' - gui = __import__('electrum_gui.' + gui_name, fromlist=['electrum_gui']) + gui = __import__('electrum_zcash_gui.' + gui_name, fromlist=['electrum_zcash_gui']) self.gui = gui.ElectrumGui(config, self, plugins) self.gui.main() diff --git a/lib/paymentrequest.py b/lib/paymentrequest.py index 8c9c6009..a79141cb 100644 --- a/lib/paymentrequest.py +++ b/lib/paymentrequest.py @@ -46,8 +46,8 @@ from . import rsakey from .bitcoin import TYPE_ADDRESS -REQUEST_HEADERS = {'Accept': 'application/bitcoin-paymentrequest', 'User-Agent': 'Electrum'} -ACK_HEADERS = {'Content-Type':'application/bitcoin-payment','Accept':'application/bitcoin-paymentack','User-Agent':'Electrum'} +REQUEST_HEADERS = {'Accept': 'application/zcash-paymentrequest', 'User-Agent': 'Electrum-Zcash'} +ACK_HEADERS = {'Content-Type':'application/zcash-payment','Accept':'application/zcash-paymentack','User-Agent':'Electrum-Zcash'} ca_path = requests.certs.where() ca_list = None @@ -75,9 +75,9 @@ def get_payment_request(url): try: response = requests.request('GET', url, headers=REQUEST_HEADERS) response.raise_for_status() - # Guard against `bitcoin:`-URIs with invalid payment request URLs + # Guard against `zcash:`-URIs with invalid payment request URLs if "Content-Type" not in response.headers \ - or response.headers["Content-Type"] != "application/bitcoin-paymentrequest": + or response.headers["Content-Type"] != "application/zcash-paymentrequest": data = None error = "payment URL not pointing to a payment request handling server" else: @@ -266,7 +266,7 @@ class PaymentRequest: paymnt.transactions.append(bfh(raw_tx)) ref_out = paymnt.refund_to.add() ref_out.script = util.bfh(transaction.Transaction.pay_script(TYPE_ADDRESS, refund_addr)) - paymnt.memo = "Paid using Electrum" + paymnt.memo = "Paid using Electrum-Zcash" pm = paymnt.SerializeToString() payurl = urllib.parse.urlparse(pay_det.payment_url) try: diff --git a/lib/plot.py b/lib/plot.py index 68595595..08f4301b 100644 --- a/lib/plot.py +++ b/lib/plot.py @@ -35,7 +35,7 @@ def plot_history(wallet, history): plt.subplots_adjust(bottom=0.2) plt.xticks( rotation=25 ) ax = plt.gca() - plt.ylabel('BTC') + plt.ylabel('ZEC') plt.xlabel('Month') xfmt = md.DateFormatter('%Y-%m-%d') ax.xaxis.set_major_formatter(xfmt) diff --git a/lib/plugins.py b/lib/plugins.py index c35d1746..24494492 100644 --- a/lib/plugins.py +++ b/lib/plugins.py @@ -48,9 +48,9 @@ class Plugins(DaemonThread): DaemonThread.__init__(self) if is_local: find = imp.find_module('plugins') - plugins = imp.load_module('electrum_plugins', *find) + plugins = imp.load_module('electrum_zcash_plugins', *find) else: - plugins = __import__('electrum_plugins') + plugins = __import__('electrum_zcash_plugins') self.pkgpath = os.path.dirname(plugins.__file__) self.config = config self.hw_wallets = {} @@ -95,7 +95,7 @@ class Plugins(DaemonThread): def load_plugin(self, name): if name in self.plugins: return self.plugins[name] - full_name = 'electrum_plugins.' + name + '.' + self.gui_name + full_name = 'electrum_zcash_plugins.' + name + '.' + self.gui_name loader = pkgutil.find_loader(full_name) if not loader: raise RuntimeError("%s implementation for %s plugin not found" @@ -442,10 +442,10 @@ class DeviceMgr(ThreadJob, PrintError): # The user input has wrong PIN or passphrase, or cancelled input, # or it is not pairable raise DeviceUnpairableError( - _('Electrum cannot pair with your %s.\n\n' - 'Before you request bitcoins to be sent to addresses in this ' + _('Electrum-Zcash cannot pair with your %s.\n\n' + 'Before you request Zcash coins to be sent to addresses in this ' 'wallet, ensure you can pair with your device, or that you have ' - 'its seed (and passphrase, if any). Otherwise all bitcoins you ' + 'its seed (and passphrase, if any). Otherwise all coins you ' 'receive will be unspendable.') % plugin.device) def unpaired_device_infos(self, handler, plugin, devices=None): diff --git a/lib/servers.json b/lib/servers.json index 1f639858..4096b464 100644 --- a/lib/servers.json +++ b/lib/servers.json @@ -1,228 +1,5 @@ { - "E-X.not.fyi": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "ELECTRUMX.not.fyi": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "ELEX01.blackpole.online": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "VPS.hsmiths.com": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "bitcoin.freedomnode.com": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "btc.smsys.me": { - "pruning": "-", - "s": "995", - "version": "1.1" - }, - "currentlane.lovebitco.in": { - "pruning": "-", - "t": "50001", - "version": "1.1" - }, - "daedalus.bauerj.eu": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "de01.hamster.science": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "ecdsa.net": { - "pruning": "-", - "s": "110", - "t": "50001", - "version": "1.1" - }, - "elec.luggs.co": { - "pruning": "-", - "s": "443", - "version": "1.1" - }, - "electrum.akinbo.org": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrum.antumbra.se": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrum.be": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrum.coinucopia.io": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrum.cutie.ga": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrum.festivaldelhumor.org": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrum.hsmiths.com": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrum.qtornado.com": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrum.vom-stausee.de": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrum3.hachre.de": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrumx.bot.nu": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "electrumx.westeurope.cloudapp.azure.com": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "elx01.knas.systems": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "ex-btc.server-on.net": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "helicarrier.bauerj.eu": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "mooo.not.fyi": { - "pruning": "-", - "s": "50012", - "t": "50011", - "version": "1.1" - }, - "ndnd.selfhost.eu": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "node.arihanc.com": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "node.xbt.eu": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "node1.volatilevictory.com": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "noserver4u.de": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "qmebr.spdns.org": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "raspi.hsmiths.com": { - "pruning": "-", - "s": "51002", - "t": "51001", - "version": "1.1" - }, - "s2.noip.pl": { - "pruning": "-", - "s": "50102", - "version": "1.1" - }, - "s5.noip.pl": { - "pruning": "-", - "s": "50105", - "version": "1.1" - }, - "songbird.bauerj.eu": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "us.electrum.be": { - "pruning": "-", - "s": "50002", - "t": "50001", - "version": "1.1" - }, - "us01.hamster.science": { + "localhost": { "pruning": "-", "s": "50002", "t": "50001", diff --git a/lib/servers_testnet.json b/lib/servers_testnet.json index 4ec92007..4096b464 100644 --- a/lib/servers_testnet.json +++ b/lib/servers_testnet.json @@ -1,8 +1,8 @@ { - "testnetnode.arihanc.com": {"t":"51001", "s":"51002"}, - "testnet1.bauerj.eu": {"t":"51001", "s":"51002"}, - "14.3.140.101": {"t":"51001", "s":"51002"}, - "testnet.hsmiths.com": {"t":"53011", "s":"53012"}, - "electrum.akinbo.org": {"t":"51001", "s":"51002"}, - "ELEX05.blackpole.online": {"t":"52011", "s":"52002"} + "localhost": { + "pruning": "-", + "s": "50002", + "t": "50001", + "version": "1.1" + } } diff --git a/lib/simple_config.py b/lib/simple_config.py index c28a85b9..70a79d23 100644 --- a/lib/simple_config.py +++ b/lib/simple_config.py @@ -9,7 +9,7 @@ from .util import user_dir, print_error, print_stderr, PrintError from .bitcoin import MAX_FEE_RATE, FEE_TARGETS -SYSTEM_CONFIG_PATH = "/etc/electrum.conf" +SYSTEM_CONFIG_PATH = "/etc/electrum-zcash.conf" config = None @@ -92,10 +92,10 @@ class SimpleConfig(PrintError): if not os.path.exists(path): if os.path.islink(path): raise BaseException('Dangling link: ' + path) - os.mkdir(path) + os.makedirs(path) os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) - self.print_error("electrum directory", path) + self.print_error("electrum-zcash directory", path) return path def fixup_config_keys(self, config, keypairs): @@ -278,7 +278,7 @@ class SimpleConfig(PrintError): def read_system_config(path=SYSTEM_CONFIG_PATH): - """Parse and return the system config settings in /etc/electrum.conf.""" + """Parse and return the system config settings in /etc/electrum-zcash.conf.""" result = {} if os.path.exists(path): import configparser @@ -293,7 +293,7 @@ def read_system_config(path=SYSTEM_CONFIG_PATH): return result def read_user_config(path): - """Parse and store the user config settings in electrum.conf into user_config[].""" + """Parse and store the user config settings in electrum-zcash.conf into user_config[].""" if not path: return {} config_path = os.path.join(path, "config") diff --git a/lib/storage.py b/lib/storage.py index d4adadde..f33e3ec3 100644 --- a/lib/storage.py +++ b/lib/storage.py @@ -327,7 +327,7 @@ class WalletStorage(PrintError): self.put('wallet_type', 'standard') self.put('keystore', d) - elif (wallet_type == '2fa') or multisig_type(wallet_type): + elif multisig_type(wallet_type): for key in xpubs.keys(): d = { 'type': 'bip32', diff --git a/lib/transaction.py b/lib/transaction.py index 3e8270a2..59fd19ed 100644 --- a/lib/transaction.py +++ b/lib/transaction.py @@ -809,7 +809,7 @@ class Transaction: secexp = pkey.secret private_key = bitcoin.MySigningKey.from_secret_exponent(secexp, curve = SECP256k1) public_key = private_key.get_verifying_key() - sig = private_key.sign_digest_deterministic(pre_hash, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der) + sig = private_key.sign_digest_deterministic(pre_hash, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der_canonize) assert public_key.verify_digest(sig, pre_hash, sigdecode = ecdsa.util.sigdecode_der) txin['signatures'][j] = bh2u(sig) + '01' #txin['x_pubkeys'][j] = pubkey diff --git a/lib/util.py b/lib/util.py index 40fd805a..5176d748 100644 --- a/lib/util.py +++ b/lib/util.py @@ -40,7 +40,7 @@ def inv_dict(d): return {v: k for k, v in d.items()} -base_units = {'BTC':8, 'mBTC':5, 'uBTC':2} +base_units = {'ZEC':8, 'mZEC':5, 'uZEC':2} fee_levels = [_('Within 25 blocks'), _('Within 10 blocks'), _('Within 5 blocks'), _('Within 2 blocks'), _('In the next block')] def normalize_version(v): @@ -216,6 +216,14 @@ def profiler(func): return lambda *args, **kw_args: do_profile(func, args, kw_args) +def android_headers_file_name(): + from bitcoin import TESTNET + s = 'blockchain_headers' + if TESTNET: + s += '_testnet' + return s + + def android_ext_dir(): import jnius env = jnius.autoclass('android.os.Environment') @@ -227,7 +235,7 @@ def android_data_dir(): return PythonActivity.mActivity.getFilesDir().getPath() + '/data' def android_headers_dir(): - d = android_ext_dir() + '/org.electrum.electrum' + d = android_ext_dir() + '/org.electrum-zcash.electrum-zcash' if not os.path.exists(d): os.mkdir(d) return d @@ -236,11 +244,11 @@ def android_check_data_dir(): """ if needed, move old directory to sandbox """ ext_dir = android_ext_dir() data_dir = android_data_dir() - old_electrum_dir = ext_dir + '/electrum' + old_electrum_dir = ext_dir + '/electrum-zcash' if not os.path.exists(data_dir) and os.path.exists(old_electrum_dir): import shutil - new_headers_path = android_headers_dir() + '/blockchain_headers' - old_headers_path = old_electrum_dir + '/blockchain_headers' + new_headers_path = android_headers_dir() + android_headers_file_name() + old_headers_path = old_electrum_dir + android_headers_file_name() if not os.path.exists(new_headers_path) and os.path.exists(old_headers_path): print_error("Moving headers file to", new_headers_path) shutil.move(old_headers_path, new_headers_path) @@ -317,11 +325,11 @@ def user_dir(): if 'ANDROID_DATA' in os.environ: return android_check_data_dir() elif os.name == 'posix': - return os.path.join(os.environ["HOME"], ".electrum") + return os.path.join(os.environ["HOME"], ".electrum-zcash") elif "APPDATA" in os.environ: - return os.path.join(os.environ["APPDATA"], "Electrum") + return os.path.join(os.environ["APPDATA"], "Electrum-Zcash") elif "LOCALAPPDATA" in os.environ: - return os.path.join(os.environ["LOCALAPPDATA"], "Electrum") + return os.path.join(os.environ["LOCALAPPDATA"], "Electrum-Zcash") else: #raise Exception("No home directory found in environment variables.") return @@ -421,36 +429,14 @@ def time_difference(distance_in_time, include_seconds): return "over %d years" % (round(distance_in_minutes / 525600)) mainnet_block_explorers = { - 'Biteasy.com': ('https://www.biteasy.com/blockchain', + 'blockexplorer.com': ('https://zcash.blockexplorer.com/blocks', {'tx': 'transactions', 'addr': 'addresses'}), - 'Bitflyer.jp': ('https://chainflyer.bitflyer.jp', - {'tx': 'Transaction', 'addr': 'Address'}), - 'Blockchain.info': ('https://blockchain.info', - {'tx': 'tx', 'addr': 'address'}), - 'blockchainbdgpzk.onion': ('https://blockchainbdgpzk.onion', - {'tx': 'tx', 'addr': 'address'}), - 'Blockr.io': ('https://btc.blockr.io', - {'tx': 'tx/info', 'addr': 'address/info'}), - 'Blocktrail.com': ('https://www.blocktrail.com/BTC', - {'tx': 'tx', 'addr': 'address'}), - 'BTC.com': ('https://chain.btc.com', - {'tx': 'tx', 'addr': 'address'}), - 'Chain.so': ('https://www.chain.so', - {'tx': 'tx/BTC', 'addr': 'address/BTC'}), - 'Insight.is': ('https://insight.bitpay.com', - {'tx': 'tx', 'addr': 'address'}), - 'TradeBlock.com': ('https://tradeblock.com/blockchain', - {'tx': 'tx', 'addr': 'address'}), - 'BlockCypher.com': ('https://live.blockcypher.com/btc', - {'tx': 'tx', 'addr': 'address'}), - 'Blockchair.com': ('https://blockchair.com/bitcoin', - {'tx': 'transaction', 'addr': 'address'}), 'system default': ('blockchain:', {'tx': 'tx', 'addr': 'address'}), } testnet_block_explorers = { - 'Blocktrail.com': ('https://www.blocktrail.com/tBTC', + 'testnet.z.cash': ('https://explorer.testnet.z.cash/', {'tx': 'tx', 'addr': 'address'}), 'system default': ('blockchain:', {'tx': 'tx', 'addr': 'address'}), @@ -461,7 +447,7 @@ def block_explorer_info(): return testnet_block_explorers if bitcoin.NetworkConstants.TESTNET else mainnet_block_explorers def block_explorer(config): - return config.get('block_explorer', 'Blocktrail.com') + return config.get('block_explorer', 'blockexplorer.com') def block_explorer_tuple(config): return block_explorer_info().get(block_explorer(config)) @@ -486,12 +472,12 @@ def parse_URI(uri, on_pr=None): if ':' not in uri: if not bitcoin.is_address(uri): - raise BaseException("Not a bitcoin address") + raise BaseException("Not a Zcash address") return {'address': uri} u = urllib.parse.urlparse(uri) - if u.scheme != 'bitcoin': - raise BaseException("Not a bitcoin URI") + if u.scheme != 'zcash': + raise BaseException("Not a Zcash URI") address = u.path # python for android fails to parse query @@ -508,7 +494,7 @@ def parse_URI(uri, on_pr=None): out = {k: v[0] for k, v in pq.items()} if address: if not bitcoin.is_address(address): - raise BaseException("Invalid bitcoin address:" + address) + raise BaseException("Invalid Zcash address:" + address) out['address'] = address if 'amount' in out: am = out['amount'] @@ -558,7 +544,7 @@ def create_URI(addr, amount, message): query.append('amount=%s'%format_satoshis_plain(amount)) if message: query.append('message=%s'%urllib.parse.quote(message)) - p = urllib.parse.ParseResult(scheme='bitcoin', netloc='', path=addr, params='', query='&'.join(query), fragment='') + p = urllib.parse.ParseResult(scheme='zcash', netloc='', path=addr, params='', query='&'.join(query), fragment='') return urllib.parse.urlunparse(p) diff --git a/lib/version.py b/lib/version.py index 1ab7e9f9..d842284f 100644 --- a/lib/version.py +++ b/lib/version.py @@ -3,11 +3,8 @@ PROTOCOL_VERSION = '1.1' # protocol version requested # The hash of the mnemonic seed must begin with this SEED_PREFIX = '01' # Standard wallet -SEED_PREFIX_2FA = '101' # Two-factor authentication def seed_prefix(seed_type): if seed_type == 'standard': return SEED_PREFIX - elif seed_type == '2fa': - return SEED_PREFIX_2FA diff --git a/lib/wallet.py b/lib/wallet.py index c211e87b..6e893958 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -69,8 +69,8 @@ TX_STATUS = [ def relayfee(network): - RELAY_FEE = 5000 - MAX_RELAY_FEE = 50000 + RELAY_FEE = 1000 + MAX_RELAY_FEE = 10000 f = network.relay_fee if network and network.relay_fee else RELAY_FEE return min(f, MAX_RELAY_FEE) @@ -868,7 +868,7 @@ class Abstract_Wallet(PrintError): _type, data, value = o if _type == TYPE_ADDRESS: if not is_address(data): - raise BaseException("Invalid bitcoin address:" + data) + raise BaseException("Invalid Zcash address:" + data) if value == '!': if i_max is not None: raise BaseException("More than one output set to spend max") @@ -1199,7 +1199,7 @@ class Abstract_Wallet(PrintError): if not r: return out = copy.copy(r) - out['URI'] = 'bitcoin:' + addr + '?amount=' + format_satoshis(out.get('amount')) + out['URI'] = 'zcash:' + addr + '?amount=' + format_satoshis(out.get('amount')) status, conf = self.get_request_status(addr) out['status'] = status if conf is not None: diff --git a/lib/www/index.html b/lib/www/index.html index 14725b1f..0cc8b944 100644 --- a/lib/www/index.html +++ b/lib/www/index.html @@ -32,9 +32,9 @@ if (id) { .done( function(data) { new QRCode(document.getElementById("qrcode"), data.URI); $("

").text(data.memo).appendTo($("p#reason")); - $("

").text(data.amount/100000000 + "BTC").appendTo($("p#amount")); + $("

").text(data.amount/100000000 + "ZEC").appendTo($("p#amount")); $("a").attr("href", data.URI); - $("

").text("Powered by Electrum").appendTo($("p#powered")); + $("

").text("Powered by Electrum-Zcash").appendTo($("p#powered")); var websocket_server = data.websocket_server; var websocket_port = data.websocket_port; $(function () { @@ -84,10 +84,10 @@ if (id) { }; // See http://stackoverflow.com/questions/29186154/chrome-clicking-mailto-links-closes-websocket-connection -$(document).on('click', 'a[href^="bitcoin:"]', function (e) { +$(document).on('click', 'a[href^="zcash:"]', function (e) { e.preventDefault(); - var btcWindow = window.open($(e.currentTarget).attr('href')); - btcWindow.close(); + var zcashWindow = window.open($(e.currentTarget).attr('href')); + zcashWindow.close(); return false; }); @@ -99,7 +99,7 @@ $(document).on('click', 'a[href^="bitcoin:"]', function (e) {

- Pay with Bitcoin + Pay with Zcash