logging: basics
This commit is contained in:
@@ -9,19 +9,23 @@ from PyQt5.QtWidgets import (QComboBox, QGridLayout, QLabel, QPushButton)
|
||||
|
||||
from electrum.plugin import BasePlugin, hook
|
||||
from electrum.gui.qt.util import WaitingDialog, EnterButton, WindowModalDialog, read_QIcon
|
||||
from electrum.util import print_msg, print_error
|
||||
from electrum.i18n import _
|
||||
from electrum.logging import get_logger
|
||||
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
try:
|
||||
import amodem.audio
|
||||
import amodem.main
|
||||
import amodem.config
|
||||
print_error('Audio MODEM is available.')
|
||||
_logger.info('Audio MODEM is available.')
|
||||
amodem.log.addHandler(amodem.logging.StreamHandler(sys.stderr))
|
||||
amodem.log.setLevel(amodem.logging.INFO)
|
||||
except ImportError:
|
||||
amodem = None
|
||||
print_error('Audio MODEM is not found.')
|
||||
_logger.info('Audio MODEM is not found.')
|
||||
|
||||
|
||||
class Plugin(BasePlugin):
|
||||
@@ -100,7 +104,7 @@ class Plugin(BasePlugin):
|
||||
dst = interface.player()
|
||||
amodem.main.send(config=self.modem_config, src=src, dst=dst)
|
||||
|
||||
print_msg('Sending:', repr(blob))
|
||||
_logger.info(f'Sending: {repr(blob)}')
|
||||
blob = zlib.compress(blob.encode('ascii'))
|
||||
|
||||
kbps = self.modem_config.modem_bps / 1e3
|
||||
@@ -118,7 +122,7 @@ class Plugin(BasePlugin):
|
||||
def on_finished(blob):
|
||||
if blob:
|
||||
blob = zlib.decompress(blob).decode('ascii')
|
||||
print_msg('Received:', repr(blob))
|
||||
_logger.info(f'Received: {repr(blob)}')
|
||||
parent.setText(blob)
|
||||
|
||||
kbps = self.modem_config.modem_bps / 1e3
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
from electrum.plugin import hook
|
||||
from electrum.util import print_msg, raw_input, print_stderr
|
||||
from electrum.logging import get_logger
|
||||
|
||||
from .coldcard import ColdcardPlugin
|
||||
from electrum.util import print_msg, print_error, raw_input, print_stderr
|
||||
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
class ColdcardCmdLineHandler:
|
||||
|
||||
@@ -24,10 +30,10 @@ class ColdcardCmdLineHandler:
|
||||
print_stderr(msg)
|
||||
|
||||
def show_error(self, msg, blocking=False):
|
||||
print_error(msg)
|
||||
print_stderr(msg)
|
||||
|
||||
def update_status(self, b):
|
||||
print_error('hw device status', b)
|
||||
_logger.info(f'hw device status {b}')
|
||||
|
||||
def finished(self):
|
||||
pass
|
||||
|
||||
@@ -13,12 +13,17 @@ from electrum.keystore import Hardware_KeyStore, xpubkey_to_pubkey, Xpub
|
||||
from electrum.transaction import Transaction
|
||||
from electrum.wallet import Standard_Wallet
|
||||
from electrum.crypto import hash_160
|
||||
from electrum.util import print_error, bfh, bh2u, versiontuple, UserFacingException
|
||||
from electrum.util import bfh, bh2u, versiontuple, UserFacingException
|
||||
from electrum.base_wizard import ScriptTypeNotSupported
|
||||
from electrum.logging import get_logger
|
||||
|
||||
from ..hw_wallet import HW_PluginBase
|
||||
from ..hw_wallet.plugin import LibraryFoundButUnusable
|
||||
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
try:
|
||||
import hid
|
||||
from ckcc.protocol import CCProtocolPacker, CCProtocolUnpacker
|
||||
@@ -114,10 +119,10 @@ class CKCCClient:
|
||||
or (self.dev.master_fingerprint != expected_xfp)
|
||||
or (self.dev.master_xpub != expected_xpub)):
|
||||
# probably indicating programing error, not hacking
|
||||
print_error("[coldcard]", f"xpubs. reported by device: {self.dev.master_xpub}. "
|
||||
f"stored in file: {expected_xpub}")
|
||||
raise RuntimeError("Expecting 0x%08x but that's not whats connected?!" %
|
||||
expected_xfp)
|
||||
_logger.info(f"xpubs. reported by device: {self.dev.master_xpub}. "
|
||||
f"stored in file: {expected_xpub}")
|
||||
raise RuntimeError("Expecting 0x%08x but that's not what's connected?!" %
|
||||
expected_xfp)
|
||||
|
||||
# check signature over session key
|
||||
# - mitm might have lied about xfp and xpub up to here
|
||||
@@ -127,7 +132,7 @@ class CKCCClient:
|
||||
|
||||
self._expected_device = ex
|
||||
|
||||
print_error("[coldcard]", "Successfully verified against MiTM")
|
||||
_logger.info("Successfully verified against MiTM")
|
||||
|
||||
def is_pairable(self):
|
||||
# can't do anything w/ devices that aren't setup (but not normally reachable)
|
||||
@@ -181,7 +186,7 @@ class CKCCClient:
|
||||
|
||||
def get_xpub(self, bip32_path, xtype):
|
||||
assert xtype in ColdcardPlugin.SUPPORTED_XTYPES
|
||||
print_error('[coldcard]', 'Derive xtype = %r' % xtype)
|
||||
_logger.info('Derive xtype = %r' % xtype)
|
||||
xpub = self.dev.send_recv(CCProtocolPacker.get_xpub(bip32_path), timeout=5000)
|
||||
# TODO handle timeout?
|
||||
# change type of xpub to the requested type
|
||||
@@ -296,7 +301,7 @@ class Coldcard_KeyStore(Hardware_KeyStore):
|
||||
return rv
|
||||
|
||||
def give_error(self, message, clear_client=False):
|
||||
print_error(message)
|
||||
self.logger.info(message)
|
||||
if not self.ux_busy:
|
||||
self.handler.show_error(message)
|
||||
else:
|
||||
@@ -363,7 +368,7 @@ class Coldcard_KeyStore(Hardware_KeyStore):
|
||||
except (CCUserRefused, CCBusyError) as exc:
|
||||
self.handler.show_error(str(exc))
|
||||
except CCProtoError as exc:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('Error showing address')
|
||||
self.handler.show_error('{}\n\n{}'.format(
|
||||
_('Error showing address') + ':', str(exc)))
|
||||
except Exception as e:
|
||||
@@ -546,11 +551,11 @@ class Coldcard_KeyStore(Hardware_KeyStore):
|
||||
self.handler.finished()
|
||||
|
||||
except (CCUserRefused, CCBusyError) as exc:
|
||||
print_error('[coldcard]', 'Did not sign:', str(exc))
|
||||
self.logger.info(f'Did not sign: {exc}')
|
||||
self.handler.show_error(str(exc))
|
||||
return
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('')
|
||||
self.give_error(e, True)
|
||||
return
|
||||
|
||||
@@ -581,11 +586,11 @@ class Coldcard_KeyStore(Hardware_KeyStore):
|
||||
finally:
|
||||
self.handler.finished()
|
||||
except CCProtoError as exc:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('Error showing address')
|
||||
self.handler.show_error('{}\n\n{}'.format(
|
||||
_('Error showing address') + ':', str(exc)))
|
||||
except BaseException as exc:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('')
|
||||
self.handler.show_error(exc)
|
||||
|
||||
|
||||
@@ -651,7 +656,7 @@ class ColdcardPlugin(HW_PluginBase):
|
||||
is_simulator=(device.product_key[1] == CKCC_SIMULATED_PID))
|
||||
return rv
|
||||
except:
|
||||
self.print_error('late failure connecting to device?')
|
||||
self.logger.info('late failure connecting to device?')
|
||||
return None
|
||||
|
||||
def setup_device(self, device_info, wizard, purpose):
|
||||
|
||||
@@ -74,12 +74,12 @@ class Listener(util.DaemonThread):
|
||||
try:
|
||||
message = server.get(keyhash)
|
||||
except Exception as e:
|
||||
self.print_error("cannot contact cosigner pool")
|
||||
self.logger.info("cannot contact cosigner pool")
|
||||
time.sleep(30)
|
||||
continue
|
||||
if message:
|
||||
self.received.add(keyhash)
|
||||
self.print_error("received message for", keyhash)
|
||||
self.logger.info(f"received message for {keyhash}")
|
||||
self.parent.obj.cosigner_receive_signal.emit(
|
||||
keyhash, message)
|
||||
# poll every 30 seconds
|
||||
@@ -121,11 +121,11 @@ class Plugin(BasePlugin):
|
||||
if type(wallet) != Multisig_Wallet:
|
||||
return
|
||||
if self.listener is None:
|
||||
self.print_error("starting listener")
|
||||
self.logger.info("starting listener")
|
||||
self.listener = Listener(self)
|
||||
self.listener.start()
|
||||
elif self.listener:
|
||||
self.print_error("shutting down listener")
|
||||
self.logger.info("shutting down listener")
|
||||
self.listener.stop()
|
||||
self.listener = None
|
||||
self.keys = []
|
||||
@@ -176,7 +176,7 @@ class Plugin(BasePlugin):
|
||||
_("Open your cosigner wallet to retrieve it."))
|
||||
def on_failure(exc_info):
|
||||
e = exc_info[1]
|
||||
try: traceback.print_exception(*exc_info)
|
||||
try: self.logger.error("on_failure", exc_info=exc_info)
|
||||
except OSError: pass
|
||||
window.show_error(_("Failed to send transaction to cosigning pool") + ':\n' + str(e))
|
||||
|
||||
@@ -193,12 +193,12 @@ class Plugin(BasePlugin):
|
||||
WaitingDialog(window, msg, task, on_success, on_failure)
|
||||
|
||||
def on_receive(self, keyhash, message):
|
||||
self.print_error("signal arrived for", keyhash)
|
||||
self.logger.info("signal arrived for", keyhash)
|
||||
for key, _hash, window in self.keys:
|
||||
if _hash == keyhash:
|
||||
break
|
||||
else:
|
||||
self.print_error("keyhash not found")
|
||||
self.logger.info("keyhash not found")
|
||||
return
|
||||
|
||||
wallet = window.wallet
|
||||
@@ -225,7 +225,7 @@ class Plugin(BasePlugin):
|
||||
privkey = BIP32Node.from_xkey(xprv).eckey
|
||||
message = bh2u(privkey.decrypt_message(message))
|
||||
except Exception as e:
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
self.logger.exception('')
|
||||
window.show_error(_('Error decrypting message') + ':\n' + str(e))
|
||||
return
|
||||
|
||||
|
||||
@@ -27,9 +27,14 @@ from electrum.transaction import Transaction
|
||||
from electrum.i18n import _
|
||||
from electrum.keystore import Hardware_KeyStore
|
||||
from ..hw_wallet import HW_PluginBase
|
||||
from electrum.util import print_error, to_string, UserCancelled, UserFacingException
|
||||
from electrum.util import to_string, UserCancelled, UserFacingException
|
||||
from electrum.base_wizard import ScriptTypeNotSupported, HWD_SETUP_NEW_WALLET
|
||||
from electrum.network import Network
|
||||
from electrum.logging import get_logger
|
||||
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
try:
|
||||
import hid
|
||||
@@ -406,7 +411,7 @@ class DigitalBitbox_Client():
|
||||
r = to_string(r, 'utf8')
|
||||
reply = json.loads(r)
|
||||
except Exception as e:
|
||||
print_error('Exception caught ' + repr(e))
|
||||
_logger.info(f'Exception caught {repr(e)}')
|
||||
return reply
|
||||
|
||||
|
||||
@@ -431,7 +436,7 @@ class DigitalBitbox_Client():
|
||||
if 'error' in reply:
|
||||
self.password = None
|
||||
except Exception as e:
|
||||
print_error('Exception caught ' + repr(e))
|
||||
_logger.info(f'Exception caught {repr(e)}')
|
||||
return reply
|
||||
|
||||
|
||||
@@ -679,7 +684,7 @@ class DigitalBitbox_KeyStore(Hardware_KeyStore):
|
||||
except BaseException as e:
|
||||
self.give_error(e, True)
|
||||
else:
|
||||
print_error("Transaction is_complete", tx.is_complete())
|
||||
_logger.info("Transaction is_complete {tx.is_complete()}")
|
||||
tx.raw = tx.serialize()
|
||||
|
||||
|
||||
@@ -746,7 +751,7 @@ class DigitalBitboxPlugin(HW_PluginBase):
|
||||
)
|
||||
try:
|
||||
text = Network.send_http_on_proxy('post', url, body=args.encode('ascii'), headers={'content-type': 'application/x-www-form-urlencoded'})
|
||||
print_error('digitalbitbox reply from server', text)
|
||||
_logger.info(f'digitalbitbox reply from server {text}')
|
||||
except Exception as e:
|
||||
self.handler.show_error(repr(e)) # repr because str(Exception()) == ''
|
||||
|
||||
|
||||
@@ -41,19 +41,21 @@ from PyQt5.QtCore import QObject, pyqtSignal, QThread
|
||||
from PyQt5.QtWidgets import (QVBoxLayout, QLabel, QGridLayout, QLineEdit,
|
||||
QInputDialog)
|
||||
|
||||
from electrum.gui.qt.util import (EnterButton, Buttons, CloseButton, OkButton,
|
||||
WindowModalDialog, get_parent_main_window)
|
||||
|
||||
from electrum.plugin import BasePlugin, hook
|
||||
from electrum.paymentrequest import PaymentRequest
|
||||
from electrum.i18n import _
|
||||
from electrum.util import PrintError
|
||||
from ...gui.qt.util import (EnterButton, Buttons, CloseButton, OkButton,
|
||||
WindowModalDialog, get_parent_main_window)
|
||||
from electrum.logging import Logger
|
||||
|
||||
|
||||
class Processor(threading.Thread, PrintError):
|
||||
class Processor(threading.Thread, Logger):
|
||||
polling_interval = 5*60
|
||||
|
||||
def __init__(self, imap_server, username, password, callback):
|
||||
threading.Thread.__init__(self)
|
||||
Logger.__init__(self)
|
||||
self.daemon = True
|
||||
self.username = username
|
||||
self.password = password
|
||||
@@ -90,7 +92,7 @@ class Processor(threading.Thread, PrintError):
|
||||
self.M = imaplib.IMAP4_SSL(self.imap_server)
|
||||
self.M.login(self.username, self.password)
|
||||
except BaseException as e:
|
||||
self.print_error('connecting failed: {}'.format(repr(e)))
|
||||
self.logger.info(f'connecting failed: {repr(e)}')
|
||||
self.connect_wait *= 2
|
||||
else:
|
||||
self.reset_connect_wait()
|
||||
@@ -99,7 +101,7 @@ class Processor(threading.Thread, PrintError):
|
||||
try:
|
||||
self.poll()
|
||||
except BaseException as e:
|
||||
self.print_error('polling failed: {}'.format(repr(e)))
|
||||
self.logger.info(f'polling failed: {repr(e)}')
|
||||
break
|
||||
time.sleep(self.polling_interval)
|
||||
time.sleep(random.randint(0, self.connect_wait))
|
||||
@@ -120,7 +122,7 @@ class Processor(threading.Thread, PrintError):
|
||||
s.sendmail(self.username, [recipient], msg.as_string())
|
||||
s.quit()
|
||||
except BaseException as e:
|
||||
self.print_error(e)
|
||||
self.logger.info(e)
|
||||
|
||||
|
||||
class QEmailSignalObject(QObject):
|
||||
@@ -151,7 +153,7 @@ class Plugin(BasePlugin):
|
||||
self.wallets = set()
|
||||
|
||||
def on_receive(self, pr_str):
|
||||
self.print_error('received payment request')
|
||||
self.logger.info('received payment request')
|
||||
self.pr = PaymentRequest(pr_str)
|
||||
self.obj.email_new_invoice_signal.emit()
|
||||
|
||||
@@ -188,12 +190,12 @@ class Plugin(BasePlugin):
|
||||
return
|
||||
recipient = str(recipient)
|
||||
payload = pr.SerializeToString()
|
||||
self.print_error('sending mail to', recipient)
|
||||
self.logger.info(f'sending mail to {recipient}')
|
||||
try:
|
||||
# FIXME this runs in the GUI thread and blocks it...
|
||||
self.processor.send(recipient, message, payload)
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('')
|
||||
window.show_message(str(e))
|
||||
else:
|
||||
window.show_message(_('Request sent.'))
|
||||
|
||||
@@ -105,8 +105,7 @@ class Plugin(BasePlugin):
|
||||
else:
|
||||
d.show_warning(_('{} is not covered by GreenAddress instant confirmation').format(tx.txid()), title=_('Verification failed!'))
|
||||
except BaseException as e:
|
||||
import traceback
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
self.logger.exception('')
|
||||
d.show_error(str(e))
|
||||
finally:
|
||||
d.verify_button.setText(self.button_label)
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
from electrum.util import print_error, print_stderr, raw_input
|
||||
from electrum.util import print_stderr, raw_input
|
||||
from electrum.logging import get_logger
|
||||
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
class CmdLineHandler:
|
||||
@@ -40,7 +44,7 @@ class CmdLineHandler:
|
||||
print_stderr(msg)
|
||||
|
||||
def update_status(self, b):
|
||||
print_error('hw device status', b)
|
||||
_logger.info(f'hw device status {b}')
|
||||
|
||||
def finished(self):
|
||||
pass
|
||||
|
||||
@@ -111,7 +111,7 @@ class HW_PluginBase(BasePlugin):
|
||||
_("Library version for '{}' is incompatible.").format(self.name)
|
||||
+ '\nInstalled: {}, Needed: {} <= x < {}'
|
||||
.format(library_version, version_str(self.minimum_library), max_version_str))
|
||||
self.print_stderr(self.libraries_available_message)
|
||||
self.logger.warning(self.libraries_available_message)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@@ -35,11 +35,12 @@ from electrum.gui.qt.util import (read_QIcon, WWLabel, OkButton, WindowModalDial
|
||||
Buttons, CancelButton, TaskThread)
|
||||
|
||||
from electrum.i18n import _
|
||||
from electrum.util import PrintError
|
||||
from electrum.logging import Logger
|
||||
|
||||
|
||||
# The trickiest thing about this handler was getting windows properly
|
||||
# parented on macOS.
|
||||
class QtHandlerBase(QObject, PrintError):
|
||||
class QtHandlerBase(QObject, Logger):
|
||||
'''An interface between the GUI (here, QT) and the device handling
|
||||
logic for handling I/O.'''
|
||||
|
||||
@@ -53,7 +54,8 @@ class QtHandlerBase(QObject, PrintError):
|
||||
status_signal = pyqtSignal(object)
|
||||
|
||||
def __init__(self, win, device):
|
||||
super(QtHandlerBase, self).__init__()
|
||||
QObject.__init__(self)
|
||||
Logger.__init__(self)
|
||||
self.clear_signal.connect(self.clear_dialog)
|
||||
self.error_signal.connect(self.error_dialog)
|
||||
self.message_signal.connect(self.message_dialog)
|
||||
|
||||
@@ -3,9 +3,10 @@ from struct import pack
|
||||
|
||||
from electrum import ecc
|
||||
from electrum.i18n import _
|
||||
from electrum.util import PrintError, UserCancelled
|
||||
from electrum.util import UserCancelled
|
||||
from electrum.keystore import bip39_normalize_passphrase
|
||||
from electrum.bip32 import BIP32Node, convert_bip32_path_to_list_of_uint32
|
||||
from electrum.logging import Logger
|
||||
|
||||
|
||||
class GuiMixin(object):
|
||||
@@ -93,7 +94,7 @@ class GuiMixin(object):
|
||||
return self.proto.CharacterAck(**char_info)
|
||||
|
||||
|
||||
class KeepKeyClientBase(GuiMixin, PrintError):
|
||||
class KeepKeyClientBase(GuiMixin, Logger):
|
||||
|
||||
def __init__(self, handler, plugin, proto):
|
||||
assert hasattr(self, 'tx_api') # ProtocolMixin already constructed?
|
||||
@@ -104,6 +105,7 @@ class KeepKeyClientBase(GuiMixin, PrintError):
|
||||
self.types = plugin.types
|
||||
self.msg = None
|
||||
self.creating_wallet = False
|
||||
Logger.__init__(self)
|
||||
self.used()
|
||||
|
||||
def __str__(self):
|
||||
@@ -137,7 +139,7 @@ class KeepKeyClientBase(GuiMixin, PrintError):
|
||||
def timeout(self, cutoff):
|
||||
'''Time out the client if the last operation was before cutoff.'''
|
||||
if self.last_operation < cutoff:
|
||||
self.print_error("timed out")
|
||||
self.logger.info("timed out")
|
||||
self.clear_session()
|
||||
|
||||
@staticmethod
|
||||
@@ -190,13 +192,13 @@ class KeepKeyClientBase(GuiMixin, PrintError):
|
||||
def clear_session(self):
|
||||
'''Clear the session to force pin (and passphrase if enabled)
|
||||
re-entry. Does not leak exceptions.'''
|
||||
self.print_error("clear session:", self)
|
||||
self.logger.info(f"clear session: {self}")
|
||||
self.prevent_timeouts()
|
||||
try:
|
||||
super(KeepKeyClientBase, self).clear_session()
|
||||
except BaseException as e:
|
||||
# If the device was removed it has the same effect...
|
||||
self.print_error("clear_session: ignoring error", str(e))
|
||||
self.logger.info(f"clear_session: ignoring error {e}")
|
||||
|
||||
def get_public_node(self, address_n, creating):
|
||||
self.creating_wallet = creating
|
||||
@@ -204,7 +206,7 @@ class KeepKeyClientBase(GuiMixin, PrintError):
|
||||
|
||||
def close(self):
|
||||
'''Called when Our wallet was closed or the device removed.'''
|
||||
self.print_error("closing client")
|
||||
self.logger.info("closing client")
|
||||
self.clear_session()
|
||||
# Release the device
|
||||
self.transport.close()
|
||||
|
||||
@@ -108,7 +108,7 @@ class KeepKeyPlugin(HW_PluginBase):
|
||||
return WebUsbTransport(device)
|
||||
|
||||
def _try_hid(self, device):
|
||||
self.print_error("Trying to connect over USB...")
|
||||
self.logger.info("Trying to connect over USB...")
|
||||
if device.interface_number == 1:
|
||||
pair = [None, device.path]
|
||||
else:
|
||||
@@ -119,15 +119,15 @@ class KeepKeyPlugin(HW_PluginBase):
|
||||
except BaseException as e:
|
||||
# see fdb810ba622dc7dbe1259cbafb5b28e19d2ab114
|
||||
# raise
|
||||
self.print_error("cannot connect at", device.path, str(e))
|
||||
self.logger.info(f"cannot connect at {device.path} {e}")
|
||||
return None
|
||||
|
||||
def _try_webusb(self, device):
|
||||
self.print_error("Trying to connect over WebUSB...")
|
||||
self.logger.info("Trying to connect over WebUSB...")
|
||||
try:
|
||||
return self.webusb_transport(device)
|
||||
except BaseException as e:
|
||||
self.print_error("cannot connect at", device.path, str(e))
|
||||
self.logger.info(f"cannot connect at {device.path} {e}")
|
||||
return None
|
||||
|
||||
def create_client(self, device, handler):
|
||||
@@ -137,10 +137,10 @@ class KeepKeyPlugin(HW_PluginBase):
|
||||
transport = self._try_hid(device)
|
||||
|
||||
if not transport:
|
||||
self.print_error("cannot connect to device")
|
||||
self.logger.info("cannot connect to device")
|
||||
return
|
||||
|
||||
self.print_error("connected to device at", device.path)
|
||||
self.logger.info(f"connected to device at {device.path}")
|
||||
|
||||
client = self.client_class(transport, handler, self)
|
||||
|
||||
@@ -148,14 +148,14 @@ class KeepKeyPlugin(HW_PluginBase):
|
||||
try:
|
||||
client.ping('t')
|
||||
except BaseException as e:
|
||||
self.print_error("ping failed", str(e))
|
||||
self.logger.info(f"ping failed {e}")
|
||||
return None
|
||||
|
||||
if not client.atleast_version(*self.minimum_firmware):
|
||||
msg = (_('Outdated {} firmware for device labelled {}. Please '
|
||||
'download the updated firmware from {}')
|
||||
.format(self.device, client.label(), self.firmware_URL))
|
||||
self.print_error(msg)
|
||||
self.logger.info(msg)
|
||||
if handler:
|
||||
handler.show_error(msg)
|
||||
else:
|
||||
@@ -215,7 +215,7 @@ class KeepKeyPlugin(HW_PluginBase):
|
||||
except UserCancelled:
|
||||
exit_code = 1
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('')
|
||||
handler.show_error(str(e))
|
||||
exit_code = 1
|
||||
finally:
|
||||
|
||||
@@ -8,4 +8,4 @@ class Plugin(LabelsPlugin):
|
||||
self.start_wallet(wallet)
|
||||
|
||||
def on_pulled(self, wallet):
|
||||
self.print_error('labels pulled from server')
|
||||
self.logger.info('labels pulled from server')
|
||||
|
||||
@@ -9,6 +9,6 @@ class Plugin(LabelsPlugin):
|
||||
self.start_wallet(wallet)
|
||||
|
||||
def on_pulled(self, wallet):
|
||||
self.print_error('on pulled')
|
||||
self.logger.info('on pulled')
|
||||
self.window._trigger_update_history()
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class LabelsPlugin(BasePlugin):
|
||||
return nonce
|
||||
|
||||
def set_nonce(self, wallet, nonce):
|
||||
self.print_error("set", wallet.basename(), "nonce to", nonce)
|
||||
self.logger.info(f"set {wallet.basename()} nonce to {nonce}")
|
||||
wallet.storage.put("wallet_nonce", nonce)
|
||||
|
||||
@hook
|
||||
@@ -109,7 +109,7 @@ class LabelsPlugin(BasePlugin):
|
||||
encoded_key = self.encode(wallet, key)
|
||||
encoded_value = self.encode(wallet, value)
|
||||
except:
|
||||
self.print_error('cannot encode', repr(key), repr(value))
|
||||
self.logger.info(f'cannot encode {repr(key)} {repr(value)}')
|
||||
continue
|
||||
bundle["labels"].append({'encryptedLabel': encoded_value,
|
||||
'externalId': encoded_key})
|
||||
@@ -121,13 +121,13 @@ class LabelsPlugin(BasePlugin):
|
||||
raise Exception('Wallet {} not loaded'.format(wallet))
|
||||
wallet_id = wallet_data[2]
|
||||
nonce = 1 if force else self.get_nonce(wallet) - 1
|
||||
self.print_error("asking for labels since nonce", nonce)
|
||||
self.logger.info(f"asking for labels since nonce {nonce}")
|
||||
try:
|
||||
response = await self.do_get("/labels/since/%d/for/%s" % (nonce, wallet_id))
|
||||
except Exception as e:
|
||||
raise ErrorConnectingServer(e) from e
|
||||
if response["labels"] is None:
|
||||
self.print_error('no new labels')
|
||||
self.logger.info('no new labels')
|
||||
return
|
||||
result = {}
|
||||
for label in response["labels"]:
|
||||
@@ -140,7 +140,7 @@ class LabelsPlugin(BasePlugin):
|
||||
json.dumps(key)
|
||||
json.dumps(value)
|
||||
except:
|
||||
self.print_error('error: no json', key)
|
||||
self.logger.info(f'error: no json {key}')
|
||||
continue
|
||||
result[key] = value
|
||||
|
||||
@@ -148,7 +148,7 @@ class LabelsPlugin(BasePlugin):
|
||||
if force or not wallet.labels.get(key):
|
||||
wallet.labels[key] = value
|
||||
|
||||
self.print_error("received %d labels" % len(response))
|
||||
self.logger.info(f"received {len(response)} labels")
|
||||
# do not write to disk because we're in a daemon thread
|
||||
wallet.storage.put('labels', wallet.labels)
|
||||
self.set_nonce(wallet, response["nonce"] + 1)
|
||||
@@ -160,7 +160,7 @@ class LabelsPlugin(BasePlugin):
|
||||
try:
|
||||
await self.pull_thread(wallet, force)
|
||||
except ErrorConnectingServer as e:
|
||||
self.print_error(str(e))
|
||||
self.logger.info(str(e))
|
||||
|
||||
def pull(self, wallet, force):
|
||||
if not wallet.network: raise Exception(_('You are offline.'))
|
||||
@@ -173,7 +173,7 @@ class LabelsPlugin(BasePlugin):
|
||||
def start_wallet(self, wallet):
|
||||
if not wallet.network: return # 'offline' mode
|
||||
nonce = self.get_nonce(wallet)
|
||||
self.print_error("wallet", wallet.basename(), "nonce is", nonce)
|
||||
self.logger.info(f"wallet {wallet.basename()} nonce is {nonce}")
|
||||
mpk = wallet.get_fingerprint()
|
||||
if not mpk:
|
||||
return
|
||||
|
||||
@@ -58,9 +58,9 @@ class Plugin(LabelsPlugin):
|
||||
def done_processing_success(self, dialog, result):
|
||||
dialog.show_message(_("Your labels have been synchronised."))
|
||||
|
||||
def done_processing_error(self, dialog, result):
|
||||
traceback.print_exception(*result, file=sys.stderr)
|
||||
dialog.show_error(_("Error synchronising labels") + ':\n' + str(result[:2]))
|
||||
def done_processing_error(self, dialog, exc_info):
|
||||
self.logger.error("Error synchronising labels", exc_info=exc_info)
|
||||
dialog.show_error(_("Error synchronising labels") + f':\n{repr(exc_info[1])}')
|
||||
|
||||
@hook
|
||||
def load_wallet(self, wallet, window):
|
||||
|
||||
@@ -13,10 +13,13 @@ from PyQt5.QtCore import QThread, pyqtSignal
|
||||
|
||||
from btchip.btchip import BTChipException
|
||||
|
||||
from electrum.i18n import _
|
||||
from electrum.util import print_msg
|
||||
from electrum import constants, bitcoin
|
||||
from electrum.gui.qt.qrcodewidget import QRCodeWidget
|
||||
from electrum.i18n import _
|
||||
from electrum import constants, bitcoin
|
||||
from electrum.logging import get_logger
|
||||
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
DEBUG = False
|
||||
@@ -354,4 +357,5 @@ class LedgerWebSocket(QThread):
|
||||
|
||||
def debug_msg(*args):
|
||||
if DEBUG:
|
||||
print_msg(*args)
|
||||
str_ = " ".join([str(item) for item in args])
|
||||
_logger.debug(str_)
|
||||
|
||||
@@ -10,12 +10,17 @@ from electrum.i18n import _
|
||||
from electrum.keystore import Hardware_KeyStore
|
||||
from electrum.transaction import Transaction
|
||||
from electrum.wallet import Standard_Wallet
|
||||
from electrum.util import print_error, bfh, bh2u, versiontuple, UserFacingException
|
||||
from electrum.util import bfh, bh2u, versiontuple, UserFacingException
|
||||
from electrum.base_wizard import ScriptTypeNotSupported
|
||||
from electrum.logging import get_logger
|
||||
|
||||
from ..hw_wallet import HW_PluginBase
|
||||
from ..hw_wallet.plugin import is_any_tx_output_on_change_branch
|
||||
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
try:
|
||||
import hid
|
||||
from btchip.btchipComm import HIDDongleHIDAPI, DongleWait
|
||||
@@ -236,7 +241,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
||||
return self.plugin.get_client(self)
|
||||
|
||||
def give_error(self, message, clear_client = False):
|
||||
print_error(message)
|
||||
_logger.info(message)
|
||||
if not self.signing:
|
||||
self.handler.show_error(message)
|
||||
else:
|
||||
@@ -499,10 +504,10 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
||||
elif e.sw == 0x6982:
|
||||
raise # pin lock. decorator will catch it
|
||||
else:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('')
|
||||
self.give_error(e, True)
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
self.logger.exception('')
|
||||
self.give_error(e, True)
|
||||
finally:
|
||||
self.handler.finished()
|
||||
@@ -533,10 +538,10 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
||||
e,
|
||||
_('Your device might not have support for this functionality.')))
|
||||
else:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('')
|
||||
self.handler.show_error(e)
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('')
|
||||
self.handler.show_error(e)
|
||||
finally:
|
||||
self.handler.finished()
|
||||
|
||||
@@ -137,7 +137,7 @@ class Plugin(RevealerPlugin):
|
||||
try:
|
||||
self.make_digital(self.d)
|
||||
except Exception:
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
self.logger.exception('')
|
||||
else:
|
||||
self.cypherseed_dialog(window)
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@ from struct import pack
|
||||
|
||||
from electrum import ecc
|
||||
from electrum.i18n import _
|
||||
from electrum.util import PrintError, UserCancelled
|
||||
from electrum.util import UserCancelled
|
||||
from electrum.keystore import bip39_normalize_passphrase
|
||||
from electrum.bip32 import BIP32Node, convert_bip32_path_to_list_of_uint32
|
||||
from electrum.logging import Logger
|
||||
|
||||
|
||||
class GuiMixin(object):
|
||||
@@ -95,7 +96,7 @@ class GuiMixin(object):
|
||||
return self.proto.WordAck(word=word)
|
||||
|
||||
|
||||
class SafeTClientBase(GuiMixin, PrintError):
|
||||
class SafeTClientBase(GuiMixin, Logger):
|
||||
|
||||
def __init__(self, handler, plugin, proto):
|
||||
assert hasattr(self, 'tx_api') # ProtocolMixin already constructed?
|
||||
@@ -106,6 +107,7 @@ class SafeTClientBase(GuiMixin, PrintError):
|
||||
self.types = plugin.types
|
||||
self.msg = None
|
||||
self.creating_wallet = False
|
||||
Logger.__init__(self)
|
||||
self.used()
|
||||
|
||||
def __str__(self):
|
||||
@@ -139,7 +141,7 @@ class SafeTClientBase(GuiMixin, PrintError):
|
||||
def timeout(self, cutoff):
|
||||
'''Time out the client if the last operation was before cutoff.'''
|
||||
if self.last_operation < cutoff:
|
||||
self.print_error("timed out")
|
||||
self.logger.info("timed out")
|
||||
self.clear_session()
|
||||
|
||||
@staticmethod
|
||||
@@ -192,13 +194,13 @@ class SafeTClientBase(GuiMixin, PrintError):
|
||||
def clear_session(self):
|
||||
'''Clear the session to force pin (and passphrase if enabled)
|
||||
re-entry. Does not leak exceptions.'''
|
||||
self.print_error("clear session:", self)
|
||||
self.logger.info(f"clear session: {self}")
|
||||
self.prevent_timeouts()
|
||||
try:
|
||||
super(SafeTClientBase, self).clear_session()
|
||||
except BaseException as e:
|
||||
# If the device was removed it has the same effect...
|
||||
self.print_error("clear_session: ignoring error", str(e))
|
||||
self.logger.info(f"clear_session: ignoring error {e}")
|
||||
|
||||
def get_public_node(self, address_n, creating):
|
||||
self.creating_wallet = creating
|
||||
@@ -206,7 +208,7 @@ class SafeTClientBase(GuiMixin, PrintError):
|
||||
|
||||
def close(self):
|
||||
'''Called when Our wallet was closed or the device removed.'''
|
||||
self.print_error("closing client")
|
||||
self.logger.info("closing client")
|
||||
self.clear_session()
|
||||
# Release the device
|
||||
self.transport.close()
|
||||
|
||||
@@ -115,31 +115,31 @@ class SafeTPlugin(HW_PluginBase):
|
||||
|
||||
def create_client(self, device, handler):
|
||||
try:
|
||||
self.print_error("connecting to device at", device.path)
|
||||
self.logger.info(f"connecting to device at {device.path}")
|
||||
transport = self.transport_handler.get_transport(device.path)
|
||||
except BaseException as e:
|
||||
self.print_error("cannot connect at", device.path, str(e))
|
||||
self.logger.info(f"cannot connect at {device.path} {e}")
|
||||
return None
|
||||
|
||||
if not transport:
|
||||
self.print_error("cannot connect at", device.path)
|
||||
self.logger.info(f"cannot connect at {device.path}")
|
||||
return
|
||||
|
||||
self.print_error("connected to device at", device.path)
|
||||
self.logger.info(f"connected to device at {device.path}")
|
||||
client = self.client_class(transport, handler, self)
|
||||
|
||||
# Try a ping for device sanity
|
||||
try:
|
||||
client.ping('t')
|
||||
except BaseException as e:
|
||||
self.print_error("ping failed", str(e))
|
||||
self.logger.info(f"ping failed {e}")
|
||||
return None
|
||||
|
||||
if not client.atleast_version(*self.minimum_firmware):
|
||||
msg = (_('Outdated {} firmware for device labelled {}. Please '
|
||||
'download the updated firmware from {}')
|
||||
.format(self.device, client.label(), self.firmware_URL))
|
||||
self.print_error(msg)
|
||||
self.logger.info(msg)
|
||||
if handler:
|
||||
handler.show_error(msg)
|
||||
else:
|
||||
@@ -199,7 +199,7 @@ class SafeTPlugin(HW_PluginBase):
|
||||
except UserCancelled:
|
||||
exit_code = 1
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('')
|
||||
handler.show_error(str(e))
|
||||
exit_code = 1
|
||||
finally:
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from electrum.util import PrintError
|
||||
from electrum.logging import get_logger
|
||||
|
||||
|
||||
class SafeTTransport(PrintError):
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
class SafeTTransport:
|
||||
|
||||
@staticmethod
|
||||
def all_transports():
|
||||
@@ -71,8 +74,7 @@ class SafeTTransport(PrintError):
|
||||
try:
|
||||
new_devices = transport.enumerate()
|
||||
except BaseException as e:
|
||||
self.print_error('enumerate failed for {}. error {}'
|
||||
.format(transport.__name__, str(e)))
|
||||
_logger.info(f'enumerate failed for {transport.__name__}. error {e}')
|
||||
else:
|
||||
devices.extend(new_devices)
|
||||
return devices
|
||||
|
||||
@@ -3,9 +3,10 @@ from struct import pack
|
||||
|
||||
from electrum import ecc
|
||||
from electrum.i18n import _
|
||||
from electrum.util import PrintError, UserCancelled, UserFacingException
|
||||
from electrum.util import UserCancelled, UserFacingException
|
||||
from electrum.keystore import bip39_normalize_passphrase
|
||||
from electrum.bip32 import BIP32Node, convert_bip32_path_to_list_of_uint32 as parse_path
|
||||
from electrum.logging import Logger
|
||||
|
||||
from trezorlib.client import TrezorClient
|
||||
from trezorlib.exceptions import TrezorFailure, Cancelled, OutdatedFirmwareError
|
||||
@@ -26,12 +27,13 @@ MESSAGES = {
|
||||
}
|
||||
|
||||
|
||||
class TrezorClientBase(PrintError):
|
||||
class TrezorClientBase(Logger):
|
||||
def __init__(self, transport, handler, plugin):
|
||||
self.client = TrezorClient(transport, ui=self)
|
||||
self.plugin = plugin
|
||||
self.device = plugin.device
|
||||
self.handler = handler
|
||||
Logger.__init__(self)
|
||||
|
||||
self.msg = None
|
||||
self.creating_wallet = False
|
||||
@@ -111,7 +113,7 @@ class TrezorClientBase(PrintError):
|
||||
def timeout(self, cutoff):
|
||||
'''Time out the client if the last operation was before cutoff.'''
|
||||
if self.last_operation < cutoff:
|
||||
self.print_error("timed out")
|
||||
self.logger.info("timed out")
|
||||
self.clear_session()
|
||||
|
||||
def i4b(self, x):
|
||||
@@ -158,17 +160,17 @@ class TrezorClientBase(PrintError):
|
||||
def clear_session(self):
|
||||
'''Clear the session to force pin (and passphrase if enabled)
|
||||
re-entry. Does not leak exceptions.'''
|
||||
self.print_error("clear session:", self)
|
||||
self.logger.info(f"clear session: {self}")
|
||||
self.prevent_timeouts()
|
||||
try:
|
||||
self.client.clear_session()
|
||||
except BaseException as e:
|
||||
# If the device was removed it has the same effect...
|
||||
self.print_error("clear_session: ignoring error", str(e))
|
||||
self.logger.info(f"clear_session: ignoring error {e}")
|
||||
|
||||
def close(self):
|
||||
'''Called when Our wallet was closed or the device removed.'''
|
||||
self.print_error("closing client")
|
||||
self.logger.info("closing client")
|
||||
self.clear_session()
|
||||
|
||||
def is_uptodate(self):
|
||||
|
||||
@@ -11,11 +11,15 @@ from electrum.plugin import Device
|
||||
from electrum.transaction import deserialize, Transaction
|
||||
from electrum.keystore import Hardware_KeyStore, is_xpubkey, parse_xpubkey
|
||||
from electrum.base_wizard import ScriptTypeNotSupported, HWD_SETUP_NEW_WALLET
|
||||
from electrum.logging import get_logger
|
||||
|
||||
from ..hw_wallet import HW_PluginBase
|
||||
from ..hw_wallet.plugin import (is_any_tx_output_on_change_branch, trezor_validate_op_return_output_and_get_data,
|
||||
LibraryFoundButUnusable)
|
||||
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
try:
|
||||
import trezorlib
|
||||
import trezorlib.transport
|
||||
@@ -32,8 +36,7 @@ try:
|
||||
|
||||
TREZORLIB = True
|
||||
except Exception as e:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
_logger.exception('error importing trezorlib')
|
||||
TREZORLIB = False
|
||||
|
||||
RECOVERY_TYPE_SCRAMBLED_WORDS, RECOVERY_TYPE_MATRIX = range(2)
|
||||
@@ -145,17 +148,17 @@ class TrezorPlugin(HW_PluginBase):
|
||||
|
||||
def create_client(self, device, handler):
|
||||
try:
|
||||
self.print_error("connecting to device at", device.path)
|
||||
self.logger.info(f"connecting to device at {device.path}")
|
||||
transport = trezorlib.transport.get_transport(device.path)
|
||||
except BaseException as e:
|
||||
self.print_error("cannot connect at", device.path, str(e))
|
||||
self.logger.info(f"cannot connect at {device.path} {e}")
|
||||
return None
|
||||
|
||||
if not transport:
|
||||
self.print_error("cannot connect at", device.path)
|
||||
self.logger.info(f"cannot connect at {device.path}")
|
||||
return
|
||||
|
||||
self.print_error("connected to device at", device.path)
|
||||
self.logger.info(f"connected to device at {device.path}")
|
||||
# note that this call can still raise!
|
||||
return TrezorClientBase(transport, handler, self)
|
||||
|
||||
@@ -208,7 +211,7 @@ class TrezorPlugin(HW_PluginBase):
|
||||
except UserCancelled:
|
||||
exit_code = 1
|
||||
except BaseException as e:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('')
|
||||
handler.show_error(str(e))
|
||||
exit_code = 1
|
||||
finally:
|
||||
|
||||
@@ -34,12 +34,12 @@ class Plugin(TrustedCoinPlugin):
|
||||
if not isinstance(wallet, self.wallet_class):
|
||||
return
|
||||
if not wallet.can_sign_without_server():
|
||||
self.print_error("twofactor:sign_tx")
|
||||
self.logger.info("twofactor:sign_tx")
|
||||
auth_code = None
|
||||
if wallet.keystores['x3/'].get_tx_derivations(tx):
|
||||
msg = _('Please enter your Google Authenticator code:')
|
||||
auth_code = int(input(msg))
|
||||
else:
|
||||
self.print_error("twofactor: xpub3 not needed")
|
||||
self.logger.info("twofactor: xpub3 not needed")
|
||||
wallet.auth_code = auth_code
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ from electrum.gui.qt.main_window import StatusBarButton
|
||||
from electrum.gui.qt.installwizard import InstallWizard
|
||||
from electrum.i18n import _
|
||||
from electrum.plugin import hook
|
||||
from electrum.util import PrintError, is_valid_email
|
||||
from electrum.util import is_valid_email
|
||||
from electrum.logging import Logger
|
||||
|
||||
from .trustedcoin import TrustedCoinPlugin, server
|
||||
|
||||
|
||||
@@ -50,12 +52,13 @@ class TOS(QTextEdit):
|
||||
error_signal = pyqtSignal(object)
|
||||
|
||||
|
||||
class HandlerTwoFactor(QObject, PrintError):
|
||||
class HandlerTwoFactor(QObject, Logger):
|
||||
|
||||
def __init__(self, plugin, window):
|
||||
super().__init__()
|
||||
QObject.__init__(self)
|
||||
self.plugin = plugin
|
||||
self.window = window
|
||||
Logger.__init__(self)
|
||||
|
||||
def prompt_user_for_otp(self, wallet, tx, on_success, on_failure):
|
||||
if not isinstance(wallet, self.plugin.wallet_class):
|
||||
@@ -63,7 +66,7 @@ class HandlerTwoFactor(QObject, PrintError):
|
||||
if wallet.can_sign_without_server():
|
||||
return
|
||||
if not wallet.keystores['x3/'].get_tx_derivations(tx):
|
||||
self.print_error("twofactor: xpub3 not needed")
|
||||
self.logger.info("twofactor: xpub3 not needed")
|
||||
return
|
||||
window = self.window.top_level_window()
|
||||
auth_code = self.plugin.auth_dialog(window)
|
||||
@@ -243,8 +246,7 @@ class Plugin(TrustedCoinPlugin):
|
||||
try:
|
||||
tos = server.get_terms_of_service()
|
||||
except Exception as e:
|
||||
import traceback
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
self.logger.exception('Could not retrieve Terms of Service')
|
||||
tos_e.error_signal.emit(_('Could not retrieve Terms of Service:')
|
||||
+ '\n' + str(e))
|
||||
return
|
||||
|
||||
@@ -37,17 +37,19 @@ from aiohttp import ClientResponse
|
||||
|
||||
from electrum import ecc, constants, keystore, version, bip32, bitcoin
|
||||
from electrum.bitcoin import TYPE_ADDRESS
|
||||
from electrum.bip32 import CKD_pub, BIP32Node, xpub_type
|
||||
from electrum.bip32 import BIP32Node, xpub_type
|
||||
from electrum.crypto import sha256
|
||||
from electrum.transaction import TxOutput
|
||||
from electrum.mnemonic import Mnemonic, seed_type, is_any_2fa_seed_type
|
||||
from electrum.wallet import Multisig_Wallet, Deterministic_Wallet
|
||||
from electrum.i18n import _
|
||||
from electrum.plugin import BasePlugin, hook
|
||||
from electrum.util import NotEnoughFunds, UserFacingException, PrintError
|
||||
from electrum.util import NotEnoughFunds, UserFacingException
|
||||
from electrum.storage import STO_EV_USER_PW
|
||||
from electrum.network import Network
|
||||
from electrum.base_wizard import BaseWizard
|
||||
from electrum.logging import Logger
|
||||
|
||||
|
||||
def get_signing_xpub(xtype):
|
||||
if not constants.net.TESTNET:
|
||||
@@ -117,11 +119,12 @@ class ErrorConnectingServer(Exception):
|
||||
return f"{header}:\n{reason}" if reason else header
|
||||
|
||||
|
||||
class TrustedCoinCosignerClient(PrintError):
|
||||
class TrustedCoinCosignerClient(Logger):
|
||||
def __init__(self, user_agent=None, base_url='https://api.trustedcoin.com/2/'):
|
||||
self.base_url = base_url
|
||||
self.debug = False
|
||||
self.user_agent = user_agent
|
||||
Logger.__init__(self)
|
||||
|
||||
async def handle_response(self, resp: ClientResponse):
|
||||
if resp.status != 200:
|
||||
@@ -142,7 +145,7 @@ class TrustedCoinCosignerClient(PrintError):
|
||||
raise ErrorConnectingServer('You are offline.')
|
||||
url = urljoin(self.base_url, relative_url)
|
||||
if self.debug:
|
||||
self.print_error(f'<-- {method} {url} {data}')
|
||||
self.logger.debug(f'<-- {method} {url} {data}')
|
||||
headers = {}
|
||||
if self.user_agent:
|
||||
headers['user-agent'] = self.user_agent
|
||||
@@ -167,7 +170,7 @@ class TrustedCoinCosignerClient(PrintError):
|
||||
raise ErrorConnectingServer(e)
|
||||
else:
|
||||
if self.debug:
|
||||
self.print_error(f'--> {response}')
|
||||
self.logger.debug(f'--> {response}')
|
||||
return response
|
||||
|
||||
def get_terms_of_service(self, billing_plan='electrum-per-tx-otp'):
|
||||
@@ -327,14 +330,14 @@ class Wallet_2fa(Multisig_Wallet):
|
||||
tx = mk_tx(outputs)
|
||||
if tx.input_value() >= fee:
|
||||
raise
|
||||
self.print_error("not charging for this tx")
|
||||
self.logger.info("not charging for this tx")
|
||||
else:
|
||||
tx = mk_tx(outputs)
|
||||
return tx
|
||||
|
||||
def on_otp(self, tx, otp):
|
||||
if not otp:
|
||||
self.print_error("sign_transaction: no auth code")
|
||||
self.logger.info("sign_transaction: no auth code")
|
||||
return
|
||||
otp = int(otp)
|
||||
long_user_id, short_id = self.get_user_id()
|
||||
@@ -349,7 +352,7 @@ class Wallet_2fa(Multisig_Wallet):
|
||||
if r:
|
||||
raw_tx = r.get('transaction')
|
||||
tx.update(raw_tx)
|
||||
self.print_error("twofactor: is complete", tx.is_complete())
|
||||
self.logger.info(f"twofactor: is complete {tx.is_complete()}")
|
||||
# reset billing_info
|
||||
self.billing_info = None
|
||||
self.plugin.start_request_thread(self)
|
||||
@@ -451,7 +454,7 @@ class TrustedCoinPlugin(BasePlugin):
|
||||
if wallet.can_sign_without_server():
|
||||
return
|
||||
if not wallet.keystores['x3/'].get_tx_derivations(tx):
|
||||
self.print_error("twofactor: xpub3 not needed")
|
||||
self.logger.info("twofactor: xpub3 not needed")
|
||||
return
|
||||
def wrapper(tx):
|
||||
self.prompt_user_for_otp(wallet, tx, on_success, on_failure)
|
||||
@@ -477,12 +480,12 @@ class TrustedCoinPlugin(BasePlugin):
|
||||
def request_billing_info(self, wallet: 'Wallet_2fa', *, suppress_connection_error=True):
|
||||
if wallet.can_sign_without_server():
|
||||
return
|
||||
self.print_error("request billing info")
|
||||
self.logger.info("request billing info")
|
||||
try:
|
||||
billing_info = server.get(wallet.get_user_id()[1])
|
||||
except ErrorConnectingServer as e:
|
||||
if suppress_connection_error:
|
||||
self.print_error(str(e))
|
||||
self.logger.info(str(e))
|
||||
return
|
||||
raise
|
||||
billing_index = billing_info['billing_index']
|
||||
|
||||
Reference in New Issue
Block a user