import time from typing import List, Optional import requests from bitcoinx import Headers, MissingHeader, CheckPoint, bits_to_work, P2PKH_Address, \ hash_to_hex_str from urllib3.exceptions import NewConnectionError from electrumsv.bitcoin import COINBASE_MATURITY from electrumsv.networks import Net, BLOCK_HEIGHT_OUT_OF_RANGE_ERROR from electrumsv.logs import logs MAX_BITS = 0x1d00ffff logger = logs.get_logger("app_state") # Makes this code docker-friendly (can access a node on host with "host.docker.internal" BITCOIN_NODE_HOST = os.environ.get("BITCOIN_NODE_HOST") or "127.0.0.1" BITCOIN_NODE_PORT = os.environ.get("BITCOIN_NODE_PORT") or 18332 BITCOIN_NODE_RPCUSER = os.environ.get("BITCOIN_NODE_RPCUSER") or "rpcuser" BITCOIN_NODE_RPCPASSWORD = os.environ.get("BITCOIN_NODE_RPCPASSWORD") or "rpcpassword" BITCOIN_NODE_URI = f"http://{BITCOIN_NODE_RPCUSER}:{BITCOIN_NODE_RPCPASSWORD}" \ f"@{BITCOIN_NODE_HOST}:{BITCOIN_NODE_PORT}" class HeadersRegTestMod(Headers): def connect(self, raw_header): """overwrite Headers method to skip checking of difficulty target""" header = self.coin.deserialized_header(raw_header, -1)
from PyQt5.QtGui import QDesktopServices from PyQt5.QtWidgets import (QWidget, QGridLayout, QLabel, QPushButton, QHBoxLayout, QVBoxLayout, QProgressDialog) from bitcoinx import TxOutput from electrumsv.app_state import app_state from electrumsv.constants import ADDRESSABLE_SCRIPT_TYPES, RECEIVING_SUBPATH from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.networks import Net from electrumsv.wallet import AbstractAccount from .main_window import ElectrumWindow from . import util logger = logs.get_logger("coinsplitting") TX_DESC_PREFIX = _("ElectrumSV coin splitting") RESULT_DUST_TIMEOUT = -2 RESULT_DIALOG_CLOSED = -1 RESULT_READY_FOR_SPLIT = 0 STAGE_INACTIVE = -1 STAGE_PREPARING = 0 STAGE_OBTAINING_DUST = 1 STAGE_SPLITTING = 2 STAGE_NAMES = { STAGE_INACTIVE: _("Inactive") + ".", STAGE_PREPARING: _("Preparing") + "..",
QDialog, QVBoxLayout, QLabel, QPushButton, QHBoxLayout, QTextEdit, QToolTip ) from bitcoinx import PublicKey, Address, hash_to_hex_str from electrumsv.app_state import app_state from electrumsv.bitcoin import base_encode from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.platform import platform from electrumsv.transaction import tx_output_to_display_text from electrumsv.util import bfh from .util import MessageBoxMixin, ButtonsLineEdit, Buttons, ColorScheme, read_QIcon logger = logs.get_logger("tx_dialog") class TxDialog(QDialog, MessageBoxMixin): def __init__(self, tx, parent, desc, prompt_if_unsaved): '''Transactions in the wallet will show their description. Pass desc to give a description for txs not yet in the wallet. ''' # We want to be a top-level window QDialog.__init__(self, parent=None) # Take a copy; it might get updated in the main window by the FX thread. If this # happens during or after a long sign operation the signatures are lost. self.tx = copy.deepcopy(tx) self.main_window = parent self.parent_wallet = parent.parent_wallet
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. '''Platform-specific customization for ElectrumSV''' import os import platform import sys from electrumsv.i18n import _ from electrumsv.logs import logs logger = logs.get_logger("platform") class Platform(object): module_map = { 'PyQt5': 'PyQt5', 'SimpleWebSocketServer': 'SimpleWebSocketServer', 'dns': 'dnspython', 'ecdsa': 'ecdsa', 'jsonrpclib': 'jsonrpclib-pelix', 'protobuf': 'protobuf', 'pyaes': 'pyaes', 'qrcode': 'qrcode', 'requests': 'requests', 'socks': 'PySocks',
QGridLayout, QLineEdit, QCheckBox, QLabel, QComboBox, QSizePolicy) from aiorpcx import NetAddress from bitcoinx import hash_to_hex_str from electrumsv.app_state import app_state from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.network import SVServer, SVProxy, SVUserAuth from electrumsv.networks import Net from .password_dialog import PasswordLineEdit from .util import Buttons, CloseButton, HelpButton, read_QIcon, MessageBox logger = logs.get_logger("networkui") class NetworkDialog(QDialog): network_updated_signal = pyqtSignal() def __init__(self, network, config): QDialog.__init__(self) self.setWindowTitle(_('Network')) self.setMinimumSize(500, 200) self.resize(560, 400) self.nlayout = NetworkChoiceLayout(network, config) vbox = QVBoxLayout(self) vbox.setSizeConstraint(QVBoxLayout.SetFixedSize) vbox.addLayout(self.nlayout.layout()) vbox.addLayout(Buttons(CloseButton(self)))
from electrumsv.app_state import app_state from electrumsv.constants import DATABASE_EXT, IntFlag, StorageKind from electrumsv.exceptions import DatabaseMigrationError, IncompatibleWalletError from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.storage import WalletStorage, categorise_file from electrumsv.util import get_wallet_name_from_path, read_resource_text from electrumsv.version import PACKAGE_VERSION from electrumsv.wallet import Wallet from .util import (AspectRatioPixmapLabel, can_show_in_file_explorer, create_new_wallet, icon_path, MessageBox, show_in_file_explorer) from .wizard_common import BaseWizard, HelpContext logger = logs.get_logger('wizard-wallet') PASSWORD_MISSING_TEXT = _( "This wallet is an older format that does not have a password. To " "be able to import it, you need to provide a password so that key data can be " "secured.") PASSWORD_NEW_TEXT = _( "Your password only encrypts your private keys and other essential data, " "only your choice of location secures the privacy of the rest of your wallet data." ) PASSWORD_EXISTING_TEXT = _( "Your wallet has a password, you will need to provide that password " "in order to access it. You will also be asked to provide it later, when your permission " "is needed for secure operations.") PASSWORD_REQUEST_TEXT = _(
from struct import pack import time from electrumsv.bip32 import bip32_path_to_uints, serialize_xpub from electrumsv.exceptions import UserCancelled from electrumsv.i18n import _ from electrumsv.keystore import bip39_normalize_passphrase from electrumsv.logs import logs from trezorlib.client import TrezorClient from trezorlib.exceptions import TrezorFailure, Cancelled, OutdatedFirmwareError from trezorlib.messages import WordRequestType, RecoveryDeviceType import trezorlib.btc import trezorlib.device logger = logs.get_logger("plugin.trezor") MESSAGES = { 3: _("Confirm the transaction output on your {} device"), 4: _("Confirm internal entropy on your {} device to begin"), 5: _("Write down the seed word shown on your {}"), 6: _("Confirm on your {} that you want to wipe it clean"), 7: _("Confirm on your {} device the message to sign"), 8: _("Confirm the total amount spent and the transaction fee on your {} device" ),
import os import re import sys import traceback from PyQt5 import QtCore, QtWidgets from PyQt5.QtGui import QFont, QTextCursor, QTextOption from electrumsv import util from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.platform import platform logger = logs.get_logger("console") class OverlayLabel(QtWidgets.QLabel): STYLESHEET = ''' QLabel, QLabel link { color: rgb(0, 0, 0); background-color: rgb(248, 240, 200); border: 1px solid; border-color: rgb(255, 114, 47); padding: 2px; } ''' def __init__(self, text, parent): super().__init__(text, parent)
def __init__(self, account: "AbstractAccount") -> None: self._account = weakref.proxy(account) self._logger = logs.get_logger("key-service")
def __init__(self, parent: QWidget, main_window: ElectrumWindow) -> None: super().__init__(parent) self._main_window = weakref.proxy(main_window) self._logger = logs.get_logger("transaction-list") self._wallet = main_window._wallet self._account_id: Optional[int] = None self._account: Optional[AbstractAccount] = None self._update_lock = threading.Lock() self._invoice_icon = read_QIcon(ICON_NAME_INVOICE_PAYMENT) self._headers = COLUMN_NAMES self.verticalHeader().setVisible(False) self.setAlternatingRowColors(True) self._pending_state: Dict[bytes, EventFlags] = {} self._pending_actions = set([ ListActions.RESET ]) self._main_window.transaction_state_signal.connect(self._on_transaction_state_change) self._main_window.transaction_added_signal.connect(self._on_transaction_added) self._main_window.transaction_deleted_signal.connect(self._on_transaction_deleted) self._main_window.account_change_signal.connect(self._on_account_changed) model = _ItemModel(self, self._headers) model.set_data([]) self._base_model = model # If the underlying model changes, observe it in the sort. proxy_model = _SortFilterProxyModel() proxy_model.setDynamicSortFilter(True) proxy_model.setSortRole(QT_SORT_ROLE) proxy_model.setSourceModel(model) self.setModel(proxy_model) fx = app_state.fx self._set_fiat_columns_enabled(fx and fx.get_fiat_address_config()) # Sort by type then by index, by making sure the initial sort is our type column. self.sortByColumn(DATE_ADDED_COLUMN, Qt.AscendingOrder) self.setSortingEnabled(True) self.horizontalHeader().setSectionResizeMode(LABEL_COLUMN, QHeaderView.Stretch) for i in range(FIAT_VALUE_COLUMN): if i != LABEL_COLUMN: self.horizontalHeader().setSectionResizeMode(i, QHeaderView.ResizeToContents) self.horizontalHeader().setMinimumSectionSize(20) verticalHeader = self.verticalHeader() verticalHeader.setSectionResizeMode(QHeaderView.Fixed) # This value will get pushed out if the contents are larger, so it does not have to be # correct, it just has to be minimal. lineHeight = QFontMetrics(app_state.app.font()).height() verticalHeader.setDefaultSectionSize(lineHeight) self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.setSelectionBehavior(QAbstractItemView.SelectRows) # New selections clear existing selections, unless the user holds down control. self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self._event_create_menu) app_state.app.base_unit_changed.connect(self._on_balance_display_change) app_state.app.fiat_balance_changed.connect(self._on_fiat_balance_display_change) app_state.app.fiat_ccy_changed.connect(self._on_fiat_balance_display_change) app_state.app.labels_changed_signal.connect(self.update_labels) app_state.app.num_zeros_changed.connect(self._on_balance_display_change) self.setEditTriggers(QAbstractItemView.DoubleClicked) self.doubleClicked.connect(self._event_double_clicked) self._last_not_synced = 0 self._timer = QTimer(self) self._timer.setSingleShot(False) self._timer.setInterval(1000) self._timer.timeout.connect(self._on_update_check)
def __init__(self, device_kind): self.device = self.keystore_class.device self.name = device_kind self.logger = logs.get_logger(device_kind)
from .qt import Ledger_Handler from electrumsv.wallet_database.tables import MasterKeyRow try: import hid from btchip.btchipComm import HIDDongleHIDAPI from btchip.btchip import btchip from btchip.btchipUtils import compress_public_key from btchip.btchipFirmwareWizard import checkFirmware from btchip.btchipException import BTChipException BTCHIP = True BTCHIP_DEBUG = logs.is_debug_level() except ImportError: BTCHIP = False logger = logs.get_logger("plugin.ledger") BITCOIN_CASH_SUPPORT = (1, 1, 8) class YInput(NamedTuple): value: Optional[int] script_sig: bytes txin_xpub_idx: int sequence: int class Ledger_Client(): handler: 'Ledger_Handler' def __init__(self, hidDevice):
from PyQt5.QtCore import QAbstractItemModel, QModelIndex, QVariant, Qt, QSortFilterProxyModel from PyQt5.QtGui import QFont, QBrush, QColor from PyQt5.QtWidgets import QTableView, QAbstractItemView, QHeaderView, QMenu from electrumsv.app_state import app_state from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.platform import platform from electrumsv.transaction import Transaction from electrumsv.util import timestamp_to_datetime, profiler, format_time from electrumsv.wallet import Abstract_Wallet import electrumsv.web as web from .util import read_QIcon, get_source_index logger = logs.get_logger("history-list") TX_ICONS = [ "unconfirmed.png", "unconfirmed.png", "unconfirmed.png", "unconfirmed.png", "clock1.png", "clock2.png", "clock3.png", "clock4.png", "clock5.png", "confirmed.png", ] TX_STATUS = [
MSG_BODY_UNSTABLE_AVAILABLE = ( "<br/><br/>" + "The latest unstable release {unstable_version} was released on " + "{unstable_date:%Y/%m/%d %I:%M%p}.") MSG_BODY_NO_SIGNEDS_AVAILABLE = ( "<img src='" + icon_path("icons8-warning-shield-32.png") + "'/>" + "<br/><br/>" + "The update check located unverifiable release information.<br/><br/>" + "This either means the developers forgot to sign the release information, or the web site has " + "been compromised. If updates are identified by later update checks, this means that there " + "are valid releases available, otherwise it is advised you avoid updating." ) logger = logs.get_logger("update_check.ui") class UpdateCheckDialog(WindowModalDialog): _timer = None def __init__(self, parent: ElectrumWindow) -> None: super().__init__(parent, 'ElectrumSV - ' + _('Update Check')) self.resize(600, 400) widget: QWidget = read_qt_ui("updater_widget.ui") layout: QVBoxLayout = widget.findChild(QVBoxLayout, "vertical_layout") self._title_label: QLabel = widget.findChild(QLabel, "title_label") self._title_label.setText(_(MSG_TITLE_CHECK))
import copy from typing import Dict, Any from PyQt5.QtWidgets import QDialog, QTextEdit, QVBoxLayout, QLabel from PyQt5.QtWidgets import QWidget, QHBoxLayout, QComboBox from btchip.btchip import BTChipException from electrumsv.gui.qt.password_dialog import PasswordLineEdit from electrumsv.i18n import _ from electrumsv.logs import logs from .ledger import Ledger_KeyStore logger = logs.get_logger("plugin.ledger.auth2fa") helpTxt = [ _("Your Ledger Wallet wants to tell you a one-time PIN code.<br><br>" "For best security you should unplug your device, open a text editor on another computer, " "put your cursor into it, and plug your device into that computer. " "It will output a summary of the transaction being signed and a one-time PIN.<br><br>" "Verify the transaction summary and type the PIN code here.<br><br>" "Before pressing enter, plug the device back into this computer.<br>" ), _("Verify the address below.<br>Type the character from your security card corresponding " "to the <u><b>BOLD</b></u> character."), ] class LedgerAuthDialog(QDialog): def __init__(self, handler, keystore: Ledger_KeyStore, data: Dict[str, Any]): '''Ask user for 2nd factor authentication. Support text and security card methods.
def __init__(self, parent: QWidget, wallet: Abstract_Wallet) -> None: super().__init__(parent) self._parent = parent self._wallet = wallet self._logger = logs.get_logger(f"address-list[{wallet.name()}]") self._update_lock = threading.Lock() self._is_synchronizing = False self._headers = COLUMN_NAMES self.verticalHeader().setVisible(False) self.setAlternatingRowColors(True) self._pending_state: Dict[Address, EventFlags] = {} self._pending_actions = set([ListActions.RESET]) self._parent.addresses_created_signal.connect( self._on_addresses_created) self._parent.addresses_updated_signal.connect( self._on_addresses_updated) model = _ItemModel(self, self._headers) model.set_data([]) self._base_model = model # If the underlying model changes, observe it in the sort. proxy_model = _SortFilterProxyModel() proxy_model.setDynamicSortFilter(True) proxy_model.setSortRole(QT_SORT_ROLE) proxy_model.setSourceModel(model) self.setModel(proxy_model) fx = app_state.fx self._set_fiat_columns_enabled(fx and fx.get_fiat_address_config()) # Sort by type then by index, by making sure the initial sort is our type column. self.sortByColumn(TYPE_COLUMN, Qt.AscendingOrder) self.setSortingEnabled(True) self.horizontalHeader().setSectionResizeMode(LABEL_COLUMN, QHeaderView.Stretch) for i in range(FIAT_BALANCE_COLUMN): if i != LABEL_COLUMN: self.horizontalHeader().setSectionResizeMode( i, QHeaderView.ResizeToContents) self.horizontalHeader().setMinimumSectionSize(20) self.verticalHeader().setMinimumSectionSize(20) # The initial spacing of rows is generous. This will draw in the spacing based on the # initial data we have put in the model, and give a more professional compact layout. # If there is no initial data, then this should be ineffectual, so we also call this on # explicit post-creation addition of rows as well to cover that case. self.resizeRowsToContents() self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.setSelectionBehavior(QAbstractItemView.SelectRows) # New selections clear existing selections, unless the user holds down control. self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self._event_create_menu) app_state.app.base_unit_changed.connect( self._on_balance_display_change) app_state.app.fiat_balance_changed.connect( self._on_fiat_balance_display_change) app_state.app.fiat_ccy_changed.connect( self._on_fiat_balance_display_change) app_state.app.labels_changed_signal.connect(self.update_labels) app_state.app.num_zeros_changed.connect( self._on_balance_display_change) self.setEditTriggers(QAbstractItemView.DoubleClicked) self.doubleClicked.connect(self._event_double_clicked) self._last_not_synced = 0 self._timer = QTimer(self) self._timer.setSingleShot(False) self._timer.setInterval(1000) self._timer.timeout.connect(self._on_update_check) self._timer.start()
def __init__(self): super().__init__() self.logger = logs.get_logger("restapi-dapp") self.app_state = app_state # easier to monkeypatch for testing self.add_routes()
def __init__(self, main_window: ElectrumWindow) -> None: super().__init__(main_window) self._logger = logs.get_logger("key-view") self._main_window = main_window self._account: AbstractAccount = None self._account_id: Optional[int] = None self._update_lock = threading.Lock() self._headers = COLUMN_NAMES self.verticalHeader().setVisible(False) self.setAlternatingRowColors(True) self._pending_state: Dict[int, Tuple[KeyInstanceRow, EventFlags]] = {} self._pending_actions = set([ListActions.RESET]) self._main_window.keys_created_signal.connect(self._on_keys_created) self._main_window.keys_updated_signal.connect(self._on_keys_updated) self._main_window.account_change_signal.connect( self._on_account_change) model = _ItemModel(self, self._headers) model.set_data([]) self._base_model = model # If the underlying model changes, observe it in the sort. self._proxy_model = proxy_model = _SortFilterProxyModel() proxy_model.setDynamicSortFilter(True) proxy_model.setSortRole(QT_SORT_ROLE) proxy_model.setSourceModel(model) self.setModel(proxy_model) fx = app_state.fx self._set_fiat_columns_enabled(fx and fx.get_fiat_address_config()) # Sort by type then by index, by making sure the initial sort is our type column. self.sortByColumn(TYPE_COLUMN, Qt.AscendingOrder) self.setSortingEnabled(True) self.horizontalHeader().setSectionResizeMode(LABEL_COLUMN, QHeaderView.Stretch) for i in range(FIAT_BALANCE_COLUMN): if i != LABEL_COLUMN: self.horizontalHeader().setSectionResizeMode( i, QHeaderView.ResizeToContents) self.horizontalHeader().setMinimumSectionSize(20) self.verticalHeader().setMinimumSectionSize(20) self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.setSelectionBehavior(QAbstractItemView.SelectRows) # New selections clear existing selections, unless the user holds down control. self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self._event_create_menu) app_state.app.base_unit_changed.connect( self._on_balance_display_change) app_state.app.fiat_balance_changed.connect( self._on_fiat_balance_display_change) app_state.app.fiat_ccy_changed.connect( self._on_fiat_balance_display_change) app_state.app.labels_changed_signal.connect(self.update_labels) app_state.app.num_zeros_changed.connect( self._on_balance_display_change) self.setEditTriggers(QAbstractItemView.DoubleClicked) self.doubleClicked.connect(self._event_double_clicked) self._last_not_synced = 0 self._timer = QTimer(self) self._timer.setSingleShot(False) self._timer.setInterval(1000) self._timer.timeout.connect(self._on_update_check)
BIP32Derivation, bip32_decompose_chain_string, Address, ) from electrumsv.app_state import app_state from electrumsv.device import Device from electrumsv.exceptions import UserCancelled from electrumsv.i18n import _ from electrumsv.keystore import Hardware_KeyStore from electrumsv.logs import logs from electrumsv.networks import Net from electrumsv.transaction import classify_tx_output, Transaction, TransactionContext from electrumsv.wallet import AbstractAccount logger = logs.get_logger("plugin.keepkey") try: from .client import KeepKeyClient import keepkeylib import keepkeylib.ckd_public from keepkeylib.client import types from usb1 import USBContext KEEPKEYLIB = True except Exception: logger.exception("Failed to import keepkeylib") KEEPKEYLIB = False from ..hw_wallet import HW_PluginBase # TREZOR initialization methods
def __init__(self) -> None: self._logger = logs.get_logger("local-rpc")
from bitcoinx import PublicKey, bip32_key_from_string from electrumsv import util, keystore from electrumsv.app_state import app_state from electrumsv.crypto import sha256d from electrumsv.extensions import cosigner_pool from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.transaction import Transaction from electrumsv.util import bh2u, bfh from electrumsv.wallet import Multisig_Wallet from electrumsv.gui.qt.util import WaitingDialog logger = logs.get_logger("cosignerpool") server = ServerProxy('https://cosigner.electrum.org/', allow_none=True) CosignerItem = namedtuple("CosignerItem", "window xpub K hash watching_only") class Listener(util.DaemonThread): def __init__(self, parent): super().__init__('cosigner') self.daemon = True self.parent = parent self.received = set() def clear(self, keyhash): server.delete(keyhash)
import traceback import requests from PyQt5.QtCore import QObject, pyqtSignal, Qt from PyQt5.QtWidgets import ( QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QTextEdit, QMessageBox, ) from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.version import PACKAGE_VERSION from .main_window import ElectrumWindow from .util import read_QIcon logger = logs.get_logger("exc-handler") issue_template = """<h2>Traceback</h2> <pre> {traceback} </pre> <h2>Additional information</h2> <ul> <li>ElectrumSV version: {app_version}</li> <li>Python version: {python_version}</li> <li>Operating system: {os}</li> <li>Wallet type: {wallet_type}</li> <li>Locale: {locale}</li> </ul>
import requests import threading from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QHBoxLayout, QLabel, QVBoxLayout, QMessageBox, QPushButton from electrumsv.app_state import app_state from electrumsv.crypto import aes_decrypt_with_iv, aes_encrypt_with_iv from electrumsv.exceptions import UserCancelled from electrumsv.extensions import label_sync from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.gui.qt.util import Buttons, EnterButton, WindowModalDialog, OkButton logger = logs.get_logger("labels") class LabelSync(object): def __init__(self): self.target_host = 'labels.electrum.org' self.wallets = {} app_state.app.window_opened_signal.connect(self.window_opened) app_state.app.window_closed_signal.connect(self.window_closed) def encode(self, wallet, msg): password, iv, wallet_id = self.wallets[wallet] encrypted = aes_encrypt_with_iv(password, iv, msg.encode('utf8')) return base64.b64encode(encrypted).decode() def decode(self, wallet, message):
from electrumsv.transaction import Transaction from electrumsv.util import to_string from ..hw_wallet import HW_PluginBase try: import hid DIGIBOX = True except ImportError as e: DIGIBOX = False if TYPE_CHECKING: from electrumsv.wallet_database.tables import MasterKeyRow from electrumsv.gui.qt.account_wizard import AccountWizard logger = logs.get_logger("plugin.bitbox") # ---------------------------------------------------------------------------------- # USB HID interface # def derive_keys(x): h = sha256d(x) h = hashlib.sha512(h).digest() return (h[:32], h[32:]) MIN_MAJOR_VERSION = 5
from electrumsv.i18n import _, set_language from electrumsv.logs import logs from electrumsv.wallet import Abstract_Wallet from . import dialogs from .cosigner_pool import CosignerPool from .main_window import ElectrumWindow from .exception_window import Exception_Hook from .installwizard import InstallWizard, GoBack from .label_sync import LabelSync from .log_window import SVLogWindow, SVLogHandler from .network_dialog import NetworkDialog from .util import ColorScheme, read_QIcon, MessageBox logger = logs.get_logger('app') class OpenFileEventFilter(QObject): def __init__(self, windows): super().__init__() self.windows = windows def eventFilter(self, obj, event): if event.type() == QtCore.QEvent.FileOpen: if len(self.windows) >= 1: self.windows[0].pay_to_URI(event.url().toString()) return True return False
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from struct import pack import time from keepkeylib.client import proto, BaseClient, ProtocolMixin from electrumsv.bip32 import serialize_xpub from electrumsv.exceptions import UserCancelled from electrumsv.i18n import _ from electrumsv.keystore import bip39_normalize_passphrase from electrumsv.logs import logs logger = logs.get_logger("keepkey.client") class KeepKeyClient(ProtocolMixin, BaseClient): def __init__(self, transport, handler, plugin): BaseClient.__init__(self, transport) ProtocolMixin.__init__(self, transport) assert hasattr(self, 'tx_api') # ProtocolMixin already constructed? self.proto = proto self.device = plugin.device self.handler = handler self.tx_api = plugin self.types = plugin.types self.msg = None self.creating_wallet = False self.used()
def __init__(self, main_window: ElectrumWindow) -> None: super().__init__(main_window) self._logger = logs.get_logger("key-view") self._main_window = weakref.proxy(main_window) self._account: AbstractAccount = None self._account_id: Optional[int] = None self._update_lock = threading.Lock() self._headers = COLUMN_NAMES self.verticalHeader().setVisible(False) self.setAlternatingRowColors(True) self._pending_state: Dict[int, EventFlags] = {} self._pending_actions = set([ListActions.RESET]) self._main_window.keys_created_signal.connect(self._on_keys_created) self._main_window.keys_updated_signal.connect(self._on_keys_updated) self._main_window.account_change_signal.connect( self._on_account_change) model = _ItemModel(self, self._headers) model.set_data(self._account_id, []) self._base_model = model # If the underlying model changes, observe it in the sort. self._proxy_model = proxy_model = _SortFilterProxyModel() proxy_model.setDynamicSortFilter(True) proxy_model.setSortRole(QT_SORT_ROLE) proxy_model.setSourceModel(model) self.setModel(proxy_model) fx = app_state.fx self._set_fiat_columns_enabled(fx and fx.get_fiat_address_config()) # Sort by type then by index, by making sure the initial sort is our type column. self.sortByColumn(BALANCE_COLUMN, Qt.DescendingOrder) self.setSortingEnabled(True) defaultFontMetrics = QFontMetrics(app_state.app.font()) def fw(s: str) -> int: return defaultFontMetrics.boundingRect(s).width() + 10 self._monospace_font = QFont(platform.monospace_font) monospaceFontMetrics = QFontMetrics(self._monospace_font) def mw(s: str) -> int: return monospaceFontMetrics.boundingRect(s).width() + 10 # We set the columm widths so that rendering is instant rather than taking a second or two # because ResizeToContents does not scale for thousands of rows. horizontalHeader = self.horizontalHeader() horizontalHeader.setMinimumSectionSize(20) horizontalHeader.resizeSection(TYPE_COLUMN, fw(COLUMN_NAMES[TYPE_COLUMN])) horizontalHeader.resizeSection(STATE_COLUMN, fw(COLUMN_NAMES[STATE_COLUMN])) horizontalHeader.resizeSection(KEY_COLUMN, fw("1442:01:m/000/1392")) horizontalHeader.resizeSection(SCRIPT_COLUMN, fw("MULTISIG_ACCUMULATOR")) horizontalHeader.setSectionResizeMode(LABEL_COLUMN, QHeaderView.Stretch) horizontalHeader.resizeSection(USAGES_COLUMN, fw(COLUMN_NAMES[USAGES_COLUMN])) balance_width = mw(app_state.format_amount(1.2, whitespaces=True)) horizontalHeader.resizeSection(BALANCE_COLUMN, balance_width) verticalHeader = self.verticalHeader() verticalHeader.setSectionResizeMode(QHeaderView.Fixed) # This value will get pushed out if the contents are larger, so it does not have to be # correct, it just has to be minimal. lineHeight = defaultFontMetrics.height() verticalHeader.setDefaultSectionSize(lineHeight) self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) self.setSelectionBehavior(QAbstractItemView.SelectRows) # New selections clear existing selections, unless the user holds down control. self.setSelectionMode(QAbstractItemView.ExtendedSelection) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self._event_create_menu) app_state.app.base_unit_changed.connect( self._on_balance_display_change) app_state.app.fiat_balance_changed.connect( self._on_fiat_balance_display_change) app_state.app.fiat_ccy_changed.connect( self._on_fiat_balance_display_change) app_state.app.labels_changed_signal.connect(self.update_labels) app_state.app.num_zeros_changed.connect( self._on_balance_display_change) self.setEditTriggers(QAbstractItemView.DoubleClicked) self.doubleClicked.connect(self._event_double_clicked) self._last_not_synced = 0 self._timer = QTimer(self) self._timer.setSingleShot(False) self._timer.setInterval(1000) self._timer.timeout.connect(self._on_update_check)
QToolTip, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, QWizard) from PyQt5.uic import loadUi from electrumsv.app_state import app_state from electrumsv.constants import DATABASE_EXT from electrumsv.exceptions import WaitingTaskCancelled from electrumsv.i18n import _, languages from electrumsv.logs import logs from electrumsv.types import WaitingUpdateCallback from electrumsv.util import resource_path if TYPE_CHECKING: from .main_window import ElectrumWindow logger = logs.get_logger("qt-util") dialogs = [] class EnterButton(QPushButton): def __init__(self, text, func, parent: Optional[QWidget] = None): super().__init__(text, parent) self.func = func self.clicked.connect(func) def keyPressEvent(self, e: QKeyEvent): if e.key() in (Qt.Key_Return, Qt.Key_Enter): self.func()
from electrumsv.i18n import _ from electrumsv.logs import logs from electrumsv.storage import WalletStorage from electrumsv.util import get_electron_cash_user_dir from electrumsv.wallet import ParentWallet from .network_dialog import NetworkChoiceLayout from .password_dialog import PasswordLayout, PW_NEW, PasswordLineEdit from .seed_dialog import SeedLayout, KeysLayout from .util import ( MessageBoxMixin, Buttons, WWLabel, ChoicesLayout, icon_path, WindowModalDialog, HelpLabel, MessageBox ) logger = logs.get_logger('wizard') class GoBack(Exception): pass MSG_GENERATING_WAIT = _("ElectrumSV is generating your addresses, please wait...") MSG_ENTER_ANYTHING = _("Please enter a seed phrase, a master key, a list of " "Bitcoin addresses, or a list of private keys") MSG_ENTER_SEED_OR_MPK = _("Please enter a seed phrase or a master key (xpub or xprv):") MSG_COSIGNER = _("Please enter the master public key of cosigner #{}:") MSG_ENTER_PASSWORD = _("Choose a password to encrypt your wallet keys.") + '\n'\ + _("Leave this field empty if you want to disable encryption.") MSG_RESTORE_PASSPHRASE = \ _("Please enter your seed derivation passphrase. " "Note: this is NOT your encryption password. "
QWizardPage, QGridLayout, QListWidget, QListWidgetItem, QSlider, QTextEdit, QWidget) from electrumsv.app_state import app_state from electrumsv.exceptions import InvalidPassword from electrumsv.device import DeviceInfo from electrumsv.i18n import _ from electrumsv import keystore from electrumsv.logs import logs from electrumsv import wallet_support from .main_window import ElectrumWindow from .password_dialog import PasswordLineEdit from .util import ChoicesLayout, icon_path, MessageBoxMixin, read_QIcon, WWLabel logger = logs.get_logger('wizard-account') DeviceList = List[Tuple[str, DeviceInfo]] PASSWORD_EXISTING_TEXT = _( "Your wallet has a password, and you will need to provide that " "password in order to add this account.") NO_DEVICES_FOUND_TEXT = _( "A scan has been unable to locate any connected hardware wallets. " "Once you have connected your hardware wallet, and if necessary turned it on, please " "press the 'Rescan' button to try again." ) + "\n\n" + _( "If any problems were encountered " "during the scan, they will be displayed below. If there are no indications why your " "hardware wallet is not being found, press the 'Help' button for further direction."