Zcash changes to lib
This commit is contained in:
parent
717b3d7df2
commit
9f61882b3a
42
electrum
42
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')
|
||||
|
|
|
@ -19,6 +19,6 @@ fi
|
|||
|
||||
export PYTHONPATH="/usr/local/lib/python3.5/site-packages:$PYTHONPATH"
|
||||
|
||||
./electrum "$@"
|
||||
./electrum-zcash "$@"
|
||||
|
||||
deactivate
|
|
@ -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
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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 <command>' to see the help for a command")
|
||||
epilog="Run 'electrum-zcash help <command>' to see the help for a command")
|
||||
add_global_options(parser)
|
||||
subparsers = parser.add_subparsers(dest='cmd', metavar='<command>')
|
||||
# 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")
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
225
lib/servers.json
225
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",
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
|
62
lib/util.py
62
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)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -32,9 +32,9 @@ if (id) {
|
|||
.done( function(data) {
|
||||
new QRCode(document.getElementById("qrcode"), data.URI);
|
||||
$("<p />").text(data.memo).appendTo($("p#reason"));
|
||||
$("<p />").text(data.amount/100000000 + "BTC").appendTo($("p#amount"));
|
||||
$("<p />").text(data.amount/100000000 + "ZEC").appendTo($("p#amount"));
|
||||
$("a").attr("href", data.URI);
|
||||
$("<p />").text("Powered by Electrum").appendTo($("p#powered"));
|
||||
$("<p />").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) {
|
|||
<p id="reason"></p>
|
||||
<p id="amount"></p>
|
||||
<div style="background-color:#7777aa; border-radius: 5px; padding:10px;">
|
||||
<a style="color:#ffffff; text-decoration:none;" id="paylink" target="_blank">Pay with Bitcoin</a>
|
||||
<a style="color:#ffffff; text-decoration:none;" id="paylink" target="_blank">Pay with Zcash</a>
|
||||
</div>
|
||||
<br/>
|
||||
<div id="qrcode" align="center"></div>
|
||||
|
|
Loading…
Reference in New Issue