Rebase 3.3.8

This commit is contained in:
kodxana 2020-02-18 08:04:06 +01:00 committed by GitHub
parent d97c635d28
commit 48a9c7f9dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 374 additions and 157 deletions

View file

@ -1,6 +1,5 @@
include LICENCE RELEASE-NOTES AUTHORS
include README.rst
include electrum.conf.sample
include electrum.desktop
include *.py
include run_electrum
@ -8,11 +7,15 @@ include contrib/requirements/requirements.txt
include contrib/requirements/requirements-hw.txt
recursive-include packages *.py
recursive-include packages cacert.pem
include icons.qrc
graft icons
graft electrum
prune electrum/tests
graft contrib/udev
exclude electrum/*.so
exclude electrum/*.so.0
global-exclude __pycache__
global-exclude *.py[co]
global-exclude *.py[co~]
global-exclude *.py.orig
global-exclude *.py.rej

View file

@ -26,13 +26,30 @@ Electrum - Lightweight Bitcoin client
Getting started
===============
Electrum is a pure python application. If you want to use the
Qt interface, install the Qt dependencies::
Electrum itself is pure Python, and so are most of the required dependencies.
Non-python dependencies
-----------------------
If you want to use the Qt interface, install the Qt dependencies::
sudo apt-get install python3-pyqt5
For elliptic curve operations, libsecp256k1 is a required dependency::
sudo apt-get install libsecp256k1-0
Alternatively, when running from a cloned repository, a script is provided to build
libsecp256k1 yourself::
./contrib/make_libsecp256k1.sh
Running from tar.gz
-------------------
If you downloaded the official package (tar.gz), you can run
Electrum from its root directory, without installing it on your
Electrum from its root directory without installing it on your
system; all the python dependencies are included in the 'packages'
directory. To run Electrum from its root directory, just do::
@ -40,40 +57,30 @@ directory. To run Electrum from its root directory, just do::
You can also install Electrum on your system, by running this command::
sudo apt-get install python3-setuptools
python3 -m pip install .[fast]
sudo apt-get install python3-setuptools python3-pip
python3 -m pip install --user .
This will download and install the Python dependencies used by
Electrum, instead of using the 'packages' directory.
The 'fast' extra contains some optional dependencies that we think
are often useful but they are not strictly needed.
Electrum instead of using the 'packages' directory.
If you cloned the git repository, you need to compile extra files
before you can run Electrum. Read the next section, "Development
Version".
version".
Development version
===================
-------------------
Check out the code from GitHub::
git clone git://github.com/spesmilo/electrum.git
cd electrum
git submodule update --init
Run install (this should install dependencies)::
python3 -m pip install .[fast]
python3 -m pip install --user .
Render the SVG icons to PNGs (optional)::
for i in lock unlock confirmed status_lagging status_disconnected status_connected_proxy status_connected status_waiting preferences; do convert -background none icons/$i.svg icons/$i.png; done
Compile the icons file for Qt::
sudo apt-get install pyqt5-dev-tools
pyrcc5 icons.qrc -o electrum/gui/qt/icons_rc.py
Compile the protobuf description file::
@ -83,7 +90,7 @@ Compile the protobuf description file::
Create translations (optional)::
sudo apt-get install python-requests gettext
./contrib/make_locale
./contrib/pull_locale
@ -91,25 +98,31 @@ Create translations (optional)::
Creating Binaries
=================
Linux (tarball)
---------------
To create binaries, create the 'packages' directory::
See :code:`contrib/build-linux/README.md`.
./contrib/make_packages
This directory contains the python dependencies used by Electrum.
Linux (AppImage)
----------------
See :code:`contrib/build-linux/appimage/README.md`.
Mac OS X / macOS
--------
----------------
See :code:`contrib/osx/README.md`.
See `contrib/build-osx/`.
Windows
-------
See `contrib/build-wine/`.
See :code:`contrib/build-wine/README.md`.
Android
-------
See `electrum/gui/kivy/Readme.md` file.
See :code:`electrum/gui/kivy/Readme.md`.

View file

@ -1,3 +1,174 @@
# Release 4.0 - (Not released yet; release notes are incomplete)
* Lightning Network
* Qt GUI: Separation between output selection and transaction finalization.
* Http PayServer can be configured from GUI
# Release 3.3.8 - (July 11, 2019)
* fix some bugs with recent bump fee (RBF) improvements (#5483, #5502)
* fix #5491: watch-only wallets could not bump fee in some cases
* appimage: URLs could not be opened on some desktop environments (#5425)
* faster tx signing for segwit inputs for really large txns (#5494)
* A few other minor bugfixes and usability improvements.
# Release 3.3.7 - (July 3, 2019)
* The AppImage Linux x86_64 binary and the Windows setup.exe
(so now all Windows binaries) are now built reproducibly.
* Bump fee (RBF) improvements:
Implemented a new fee-bump strategy that can add new inputs,
so now any tx can be fee-bumped (d0a4366). The old strategy
was to decrease the value of outputs (starting with change).
We will now try the new strategy first, and only use the old
as a fallback (needed e.g. when spending "Max").
* CoinChooser improvements:
- more likely to construct txs without change (when possible)
- less likely to construct txs with really small change (e864fa5)
- will now only spend negative effective value coins when
beneficial for privacy (cb69aa8)
* fix long-standing bug that broke wallets with >65k addresses (#5366)
* Windows binaries: we now build the PyInstaller boot loader ourselves,
as this seems to reduce anti-virus false positives (1d0f679)
* Android: (fix) BIP70 payment requests could not be paid (#5376)
* Android: allow copy-pasting partial transactions from/to clipboard
* Fix a performance regression for large wallets (c6a54f0)
* Qt: fix some high DPI issues related to text fields (37809be)
* Trezor:
- allow bypassing "too old firmware" error (#5391)
- use only the Bridge to scan devices if it is available (#5420)
* hw wallets: (known issue) on Win10-1903, some hw devices
(that also have U2F functionality) can only be detected with
Administrator privileges. (see #5420 and #5437)
A workaround is to run as Admin, or for Trezor to install the Bridge.
* Several other minor bugfixes and usability improvements.
# Release 3.3.6 - (May 16, 2019)
* qt: fix crash during 2FA wallet creation (#5334)
* fix synchronizer not to keep resubscribing to addresses of
already closed wallets (e415c0d9)
* fix removing addresses/keys from imported wallets (#4481)
* kivy: fix crash when aborting 2FA wallet creation (#5333)
* kivy: fix rare crash when changing exchange rate settings (#5329)
* A few other minor bugfixes and usability improvements.
# Release 3.3.5 - (May 9, 2019)
* The logging system has been overhauled (#5296).
Logs can now also optionally be written to disk, disabled by default.
* Fix a bug in synchronizer (#5122) where client could get stuck.
Also, show the progress of history sync in the GUI. (#5319)
* fix Revealer in Windows and MacOS binaries (#5027)
* fiat rate providers:
- added CoinGecko.com and CoinCap.io
- BitcoinAverage now only provides historical exchange rates for
paying customers. Changed default provider to CoinGecko.com (#5188)
* hardware wallets:
- Ledger: Nano X is now recognized (#5140)
- KeepKey:
- device was not getting detected using Windows binary (#5165)
- support firmware 6.0.0+ (#5205)
- Trezor: implemented "seedless" mode (#5118)
* Coin Control in Qt: implemented freezing individual UTXOs
in addition to freezing addresses (#5152)
* TrustedCoin (2FA wallets):
- better error messages (#5184)
- longer signing timeout (#5221)
* Kivy:
- fix bug with local transactions (#5156)
- allow selecting fiat rate providers without historical data (#5162)
* fix CPFP: the fees already paid by the parent were not included in
the calculation, so it always overestimated (#5244)
* Testnet: there is now a warning when the client is started in
testnet mode as there were a number of reports of users getting
scammed through social engineering (#5295)
* CoinChooser: performance of creating transactions has been improved
significantly for large wallets. (d56917f4)
* Importing/sweeping WIF keys: stricter checks (#4638, #5290)
* Electrum protocol: the client's "user agent" has been changed from
"3.3.5" to "electrum/3.3.5". Other libraries connecting to servers
can consider not "spoofing" to be Electrum. (#5246)
* Several other minor bugfixes and usability improvements.
# Release 3.3.4 - (February 13, 2019)
* AppImage: we now also distribute self-contained binaries for x86_64
Linux in the form of an AppImage (#5042). The Python interpreter,
PyQt5, libsecp256k1, PyCryptodomex, zbar, hidapi/libusb (including
hardware wallet libraries) are all bundled. Note that users of
hw wallets still need to set udev rules themselves.
* hw wallets: fix a regression during transaction signing that prompts
the user too many times for confirmations (commit 2729909)
* transactions now set nVersion to 2, to mimic Bitcoin Core
* fix Qt bug that made all hw wallets unusable on Windows 8.1 (#4960)
* fix bugs in wallet creation wizard that resulted in corrupted
wallets being created in rare cases (#5082, #5057)
* fix compatibility with Qt 5.12 (#5109)
# Release 3.3.3 - (January 25, 2019)
* Do not expose users to server error messages (#4968)
* Notify users of new releases. Release announcements must be signed,
and they are verified byElectrum using a hardcoded Bitcoin address.
* Hardware wallet fixes (#4991, #4993, #5006)
* Display only QR code in QRcode Window
* Fixed code signing on MacOS
* Randomise locktime of transactions
# Release 3.3.2 - (December 21, 2018)
* Fix Qt history export bug
* Improve network timeouts
* Prepend server transaction_broadcast error messages with
explanatory message. Render error messages as plain text.
# Release 3.3.1 - (December 20, 2018)
* Qt: Fix invoices tab crash (#4941)
* Android: Minor GUI improvements
# Release 3.3.0 - Hodler's Edition (December 19, 2018)
* The network layer has been rewritten using asyncio and aiorpcx.
In addition to easier maintenance, this makes the client
more robust against misbehaving servers.
* The minimum python version was increased to 3.6
* The blockchain headers and fork handling logic has been generalized.
Clients by default now follow chain based on most work, not length.
* New wallet creation defaults to native segwit (bech32).
* Segwit 2FA: TrustedCoin now supports native segwit p2wsh
two-factor wallets.
* RBF batching (opt-in): If the wallet has an unconfirmed RBF
transaction, new payments will be added to that transaction,
instead of creating new transactions.
* MacOS: support QR code scanner in binaries.
* Android APK:
- build using Google NDK instead of Crystax NDK
- target API 28
- do not use external storage (previously for block headers)
* hardware wallets:
- Coldcard now supports spending from p2wpkh-p2sh,
fixed p2pkh signing for fw 1.1.0
- Archos Safe-T mini: fix #4726 signing issue
- KeepKey: full segwit support
- Trezor: refactoring and compat with python-trezor 0.11
- Digital BitBox: support firmware v5.0.0
* fix bitcoin URI handling when app already running (#4796)
* Qt listings rewritten:
the History tab now uses QAbstractItemModel, the other tabs use
QStandardItemModel. Performance should be better for large wallets.
* Several other minor bugfixes and usability improvements.
# Release 3.2.3 - (September 3, 2018)
* hardware wallet: the Safe-T mini from Archos is now supported.

19
SECURITY.md Normal file
View file

@ -0,0 +1,19 @@
# Security Policy
## Reporting a Vulnerability
To report security issues send an email to electrumdev@gmail.com.
The following keys may be used to communicate sensitive information to developers:
| Name | Fingerprint |
|------|-------------|
| ThomasV | 6694 D8DE 7BE8 EE56 31BE D950 2BD5 824B 7F94 70E6 |
| SomberNight | 4AD6 4339 DFA0 5E20 B3F6 AD51 E7B7 48CD AF5E 5ED9 |
You can import a key by running the following command with that
individuals fingerprint: `gpg --recv-keys "<fingerprint>"`
Ensure that you put quotes around fingerprints containing spaces.
These public keys can also be found in the Electrum git repository,
in the top-level `pubkeys` folder.

View file

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
#
# This script creates a virtualenv named 'env' and installs all
# python dependencies before activating the env and running Electrum.

View file

@ -10,7 +10,8 @@ Icon=electrum
Name[en_US]=Electrum Bitcoin Wallet
Name=Electrum Bitcoin Wallet
Categories=Finance;Network;
StartupNotify=false
StartupNotify=true
StartupWMClass=electrum
Terminal=false
Type=Application
MimeType=x-scheme-handler/bitcoin;

View file

@ -25,12 +25,26 @@
# SOFTWARE.
import os
import sys
import warnings
import asyncio
MIN_PYTHON_VERSION = "3.6.1" # FIXME duplicated from setup.py
_min_python_version_tuple = tuple(map(int, (MIN_PYTHON_VERSION.split("."))))
if sys.version_info[:3] < _min_python_version_tuple:
sys.exit("Error: Electrum requires Python version >= %s..." % MIN_PYTHON_VERSION)
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_android = 'ANDROID_DATA' in os.environ
if is_local: # running from source
# developers should probably see all deprecation warnings.
warnings.simplefilter('default', DeprecationWarning)
# move this back to gui/kivy/__init.py once plugins are moved
os.environ['KIVY_DATA_DIR'] = os.path.abspath(os.path.dirname(__file__)) + '/electrum/gui/kivy/data/'
@ -44,37 +58,41 @@ def check_imports():
import dns
import pyaes
import ecdsa
import requests
import certifi
import qrcode
import google.protobuf
import jsonrpclib
import aiorpcx
except ImportError as e:
sys.exit("Error: %s. Try 'sudo pip install <module-name>'"%str(e))
sys.exit(f"Error: {str(e)}. Try 'sudo python3 -m pip install <module-name>'")
# the following imports are for pyinstaller
from google.protobuf import descriptor
from google.protobuf import message
from google.protobuf import reflection
from google.protobuf import descriptor_pb2
from jsonrpclib import SimpleJSONRPCServer
# make sure that certificates are here
assert os.path.exists(requests.utils.DEFAULT_CA_BUNDLE_PATH)
assert os.path.exists(certifi.where())
if not is_android:
check_imports()
from electrum.logging import get_logger, configure_logging
from electrum import util
from electrum import constants
from electrum import SimpleConfig
from electrum.wallet_db import WalletDB
from electrum.wallet import Wallet
from electrum.storage import WalletStorage, get_derivation_used_for_hw_device_encryption
from electrum.util import print_msg, print_stderr, json_encode, json_decode, UserCancelled
from electrum.util import set_verbosity, InvalidPassword
from electrum.util import InvalidPassword
from electrum.commands import get_parser, known_commands, Commands, config_variables
from electrum import daemon
from electrum import keystore
from electrum.util import create_and_start_event_loop
_logger = get_logger(__name__)
# get password routine
def prompt_password(prompt, confirm=True):
@ -89,31 +107,7 @@ def prompt_password(prompt, confirm=True):
return password
def init_daemon(config_options):
config = SimpleConfig(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")
sys.exit(0)
if storage.is_encrypted():
if storage.is_encrypted_with_hw_device():
plugins = init_plugins(config, 'cmdline')
password = get_password_for_hw_device_encrypted_storage(plugins)
elif config.get('password'):
password = config.get('password')
else:
password = prompt_password('Password:', False)
if not password:
print_msg("Error: Password required")
sys.exit(1)
else:
password = None
config_options['password'] = password
def init_cmdline(config_options, server):
config = SimpleConfig(config_options)
def init_cmdline(config_options, wallet_path, server):
cmdname = config.get('cmd')
cmd = known_commands[cmdname]
@ -128,12 +122,12 @@ def init_cmdline(config_options, server):
cmd.requires_network = True
# instantiate wallet for command-line
storage = WalletStorage(config.get_wallet_path())
storage = WalletStorage(wallet_path)
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")
sys.exit(0)
sys_exit(1)
# important warning
if cmd.name in ['getprivatekeys']:
@ -141,9 +135,17 @@ def init_cmdline(config_options, server):
print_stderr("Exposing a single private key can compromise your entire wallet!")
print_stderr("In particular, DO NOT use 'redeem private key' services proposed by third parties.")
# will we need a password
if not storage.is_encrypted():
db = WalletDB(storage.read(), manual_upgrades=False)
use_encryption = db.get('use_encryption')
else:
use_encryption = True
# commands needing password
if (cmd.requires_wallet and storage.is_encrypted() and server is None)\
or (cmd.requires_password and (storage.get('use_encryption') or storage.is_encrypted())):
if ( (cmd.requires_wallet and storage.is_encrypted() and server is False)\
or (cmdname == 'load_wallet' and storage.is_encrypted())\
or (cmd.requires_password and use_encryption)):
if storage.is_encrypted_with_hw_device():
# this case is handled later in the control flow
password = None
@ -153,7 +155,7 @@ def init_cmdline(config_options, server):
password = prompt_password('Password:', False)
if not password:
print_msg("Error: Password required")
sys.exit(1)
sys_exit(1)
else:
password = None
@ -173,18 +175,18 @@ def get_connected_hw_devices(plugins):
name, plugin = splugin.name, splugin.plugin
if not plugin:
e = splugin.exception
print_stderr(f"{name}: error during plugin init: {repr(e)}")
_logger.error(f"{name}: error during plugin init: {repr(e)}")
continue
try:
u = devmgr.unpaired_device_infos(None, plugin)
except:
devmgr.print_error(f'error getting device infos for {name}: {e}')
except Exception as e:
_logger.error(f'error getting device infos for {name}: {repr(e)}')
continue
devices += list(map(lambda x: (name, x), u))
return devices
def get_password_for_hw_device_encrypted_storage(plugins):
def get_password_for_hw_device_encrypted_storage(plugins) -> str:
devices = get_connected_hw_devices(plugins)
if len(devices) == 0:
print_msg("Error: No connected hw device found. Cannot decrypt this wallet.")
@ -200,14 +202,16 @@ def get_password_for_hw_device_encrypted_storage(plugins):
xpub = plugin.get_xpub(device_info.device.id_, derivation, 'standard', plugin.handler)
except UserCancelled:
sys.exit(0)
password = keystore.Xpub.get_pubkey_from_xpub(xpub, ())
password = keystore.Xpub.get_pubkey_from_xpub(xpub, ()).hex()
return password
def run_offline_command(config, config_options, plugins):
async def run_offline_command(config, config_options, plugins):
cmdname = config.get('cmd')
cmd = known_commands[cmdname]
password = config_options.get('password')
if 'wallet_path' in cmd.options and config_options.get('wallet_path') is None:
config_options['wallet_path'] = config.get_wallet_path()
if cmd.requires_wallet:
storage = WalletStorage(config.get_wallet_path())
if storage.is_encrypted():
@ -215,7 +219,9 @@ def run_offline_command(config, config_options, plugins):
password = get_password_for_hw_device_encrypted_storage(plugins)
config_options['password'] = password
storage.decrypt(password)
wallet = Wallet(storage)
db = WalletDB(storage.read(), manual_upgrades=False)
wallet = Wallet(db, storage, config=config)
config_options['wallet'] = wallet
else:
wallet = None
# check password
@ -235,13 +241,13 @@ def run_offline_command(config, config_options, plugins):
# options
kwargs = {}
for x in cmd.options:
kwargs[x] = (config_options.get(x) if x in ['password', 'new_password'] else config.get(x))
cmd_runner = Commands(config, wallet, None)
kwargs[x] = (config_options.get(x) if x in ['wallet_path', 'wallet', 'password', 'new_password'] else config.get(x))
cmd_runner = Commands(config=config)
func = getattr(cmd_runner, cmd.name)
result = func(*args, **kwargs)
result = await func(*args, **kwargs)
# save wallet
if wallet:
wallet.storage.write()
wallet.save_db()
return result
@ -249,6 +255,11 @@ def init_plugins(config, gui_name):
from electrum.plugin import Plugins
return Plugins(config, gui_name)
def sys_exit(i):
# stop event loop and exit
loop.call_soon_threadsafe(stop_loop.set_result, 1)
loop_thread.join(timeout=1)
sys.exit(i)
if __name__ == '__main__':
# The hook will only be used in the Qt GUI right now
@ -262,6 +273,9 @@ if __name__ == '__main__':
sys.argv.append('-h')
# old '-v' syntax
# Due to this workaround that keeps old -v working,
# more advanced usages of -v need to use '-v='.
# e.g. -v=debug,network=warning,interface=error
try:
i = sys.argv.index('-v')
except ValueError:
@ -309,8 +323,8 @@ if __name__ == '__main__':
if config_options.get('portable'):
config_options['electrum_path'] = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'electrum_data')
# kivy sometimes freezes when we write to sys.stderr
set_verbosity(config_options.get('verbosity') if config_options.get('gui') != 'kivy' else '')
if not config_options.get('verbosity'):
warnings.simplefilter('ignore', DeprecationWarning)
# check uri
uri = config_options.get('url')
@ -318,11 +332,9 @@ if __name__ == '__main__':
if not uri.startswith('bitcoin:'):
print_stderr('unknown command:', uri)
sys.exit(1)
config_options['url'] = uri
# todo: defer this to gui
# singleton
config = SimpleConfig(config_options)
cmdname = config.get('cmd')
if config.get('testnet'):
constants.set_testnet()
@ -331,70 +343,86 @@ if __name__ == '__main__':
elif config.get('simnet'):
constants.set_simnet()
cmdname = config.get('cmd')
if cmdname == 'daemon' and config.get("detach"):
# fork before creating the asyncio event loop
pid = os.fork()
if pid:
print_stderr("starting daemon (PID %d)" % pid)
sys.exit(0)
else:
# redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
si = open(os.devnull, 'r')
so = open(os.devnull, 'w')
se = open(os.devnull, 'w')
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
loop, stop_loop, loop_thread = create_and_start_event_loop()
if cmdname == 'gui':
fd, server = daemon.get_fd_or_server(config)
configure_logging(config)
fd = daemon.get_file_descriptor(config)
if fd is not None:
plugins = init_plugins(config, config.get('gui', 'qt'))
d = daemon.Daemon(config, fd)
d.init_gui(config, plugins)
sys.exit(0)
d.run_gui(config, plugins)
sys_exit(0)
else:
result = server.gui(config_options)
result = daemon.request(config, 'gui', (config_options,))
elif cmdname == 'daemon':
subcommand = config.get('subcommand')
if subcommand in ['load_wallet']:
init_daemon(config_options)
if subcommand in [None, 'start']:
fd, server = daemon.get_fd_or_server(config)
if fd is not None:
if subcommand == 'start':
pid = os.fork()
if pid:
print_stderr("starting daemon (PID %d)" % pid)
sys.exit(0)
init_plugins(config, 'cmdline')
d = daemon.Daemon(config, fd)
if config.get('websocket_server'):
from electrum import websockets
websockets.WebSocketServer(config, d.network)
if config.get('requests_dir'):
path = os.path.join(config.get('requests_dir'), 'index.html')
if not os.path.exists(path):
print("Requests directory not configured.")
print("You can configure it using https://github.com/spesmilo/electrum-merchant")
sys.exit(1)
d.join()
sys.exit(0)
else:
result = server.daemon(config_options)
configure_logging(config)
fd = daemon.get_file_descriptor(config)
if fd is not None:
# run daemon
init_plugins(config, 'cmdline')
d = daemon.Daemon(config, fd)
d.run_daemon()
sys_exit(0)
else:
server = daemon.get_server(config)
if server is not None:
result = server.daemon(config_options)
else:
print_msg("Daemon not running")
sys.exit(1)
print_msg("Daemon already running")
sys_exit(1)
else:
# command line
server = daemon.get_server(config)
init_cmdline(config_options, server)
if server is not None:
result = server.run_cmdline(config_options)
cmd = known_commands[cmdname]
wallet_path = config.get_wallet_path()
if not config.get('offline'):
init_cmdline(config_options, wallet_path, True)
timeout = config.get('timeout', 60)
if timeout: timeout = int(timeout)
try:
result = daemon.request(config, 'run_cmdline', (config_options,), timeout)
except daemon.DaemonNotRunning:
print_msg("Daemon not running; try 'electrum daemon -d'")
if not cmd.requires_network:
print_msg("To run this command without a daemon, use --offline")
sys_exit(1)
except Exception as e:
print_stderr(str(e) or repr(e))
sys_exit(1)
else:
cmd = known_commands[cmdname]
if cmd.requires_network:
print_msg("Daemon not running; try 'electrum daemon start'")
sys.exit(1)
else:
plugins = init_plugins(config, 'cmdline')
result = run_offline_command(config, config_options, plugins)
# print result
print_msg("This command cannot be run offline")
sys_exit(1)
init_cmdline(config_options, wallet_path, False)
plugins = init_plugins(config, 'cmdline')
coro = run_offline_command(config, config_options, plugins)
fut = asyncio.run_coroutine_threadsafe(coro, loop)
try:
result = fut.result()
except Exception as e:
print_stderr(str(e) or repr(e))
sys_exit(1)
if isinstance(result, str):
print_msg(result)
elif type(result) is dict and result.get('error'):
print_stderr(result.get('error'))
elif result is not None:
print_msg(json_encode(result))
sys.exit(0)
sys_exit(0)

View file

@ -17,7 +17,7 @@ _min_python_version_tuple = tuple(map(int, (MIN_PYTHON_VERSION.split("."))))
if sys.version_info[:3] < _min_python_version_tuple:
sys.exit("Error: Electrum requires Python version >= {}...".format(MIN_PYTHON_VERSION))
sys.exit("Error: Electrum requires Python version >= %s..." % MIN_PYTHON_VERSION)
with open('contrib/requirements/requirements.txt') as f:
requirements = f.read().splitlines()
@ -47,34 +47,16 @@ if platform.system() in ['Linux', 'FreeBSD', 'DragonFly']:
usr_share = os.path.expanduser('~/.local/share')
data_files += [
(os.path.join(usr_share, 'applications/'), ['electrum.desktop']),
(os.path.join(usr_share, icons_dirname), ['icons/electrum.png'])
(os.path.join(usr_share, icons_dirname), ['electrum/gui/icons/electrum.png']),
]
extras_require = {
'hardware': requirements_hw,
'fast': ['pycryptodomex'],
'gui': ['pyqt5'],
}
extras_require['full'] = [pkg for sublist in list(extras_require.values()) for pkg in sublist]
class CustomInstallCommand(install):
def run(self):
install.run(self)
# potentially build Qt icons file
try:
import PyQt5
except ImportError:
pass
else:
try:
path = os.path.join(self.install_lib, "electrum/gui/qt/icons_rc.py")
if not os.path.exists(path):
subprocess.call(["pyrcc5", "icons.qrc", "-o", path])
except Exception as e:
print('Warning: building icons file failed with {}'.format(e))
setup(
name="Electrum",
version=version.ELECTRUM_VERSION,
@ -96,6 +78,9 @@ setup(
'wordlist/*.txt',
'locale/*/LC_MESSAGES/electrum.mo',
],
'electrum.gui': [
'icons/*',
],
},
scripts=['electrum/electrum'],
data_files=data_files,
@ -105,7 +90,4 @@ setup(
license="MIT Licence",
url="https://electrum.org",
long_description="""Lightweight Bitcoin Wallet""",
cmdclass={
'install': CustomInstallCommand,
},
)