Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
8f0cb38
qt: add initial wizard classes for desktop client
accumulator Jul 11, 2023
9e096fb
wizard: remove view from is_last_view call, it's never used
accumulator Jul 12, 2023
d651220
extract proxy and server widgets
accumulator Jul 15, 2023
1440eab
qt wizardcomponent receives qeabstractwizard instance
accumulator Jul 26, 2023
39f34fd
implement first batch of pages for wallet wizard
accumulator Jul 26, 2023
786eab9
wizard: cleanup, variable naming consistency, imports, invalid accept…
accumulator Jul 27, 2023
113d698
wizard: avoid importing from installwizard.py
accumulator Jul 27, 2023
ffbddb9
wizard: implement confirm seed and wallet password pages
accumulator Jul 27, 2023
2407fab
wizard: also push final state on the stack
accumulator Jul 27, 2023
4a12b28
qt: submit final state to wizard and return proper dialog result when…
accumulator Jul 27, 2023
41cf7f9
qt: implement multisig and import addresses/keys pages
accumulator Jul 28, 2023
e43b005
qt: implement initial bip39 refine and account detect, restore from s…
accumulator Jul 28, 2023
d395b97
qt: add have_master_key gui, implement cosigners in have_seed and bip…
accumulator Jul 31, 2023
0222c93
wizard: add support for slip39
accumulator Jul 31, 2023
c485753
wizard: rename bip39_refine to script_and_derivation
accumulator Jul 31, 2023
a6caa3f
wizard: fix wizard_data instance not isolated between pages,
accumulator Aug 1, 2023
a6aff1e
qml: check passphrase not empty when checked
accumulator Aug 1, 2023
c99f71a
wizard: imports, flake
accumulator Aug 1, 2023
bcdacf3
wizard: add passing of params in navmap to wizard pages
accumulator Aug 1, 2023
1577308
qt: initial trustedcoin wizard pages
accumulator Aug 1, 2023
ac5ebb9
qt: refactor please_wait layout to widget to better control UI, add i…
accumulator Aug 3, 2023
0de6216
qt: have_seed and create_seed support 2fa
accumulator Aug 3, 2023
571d163
qt: introduce electrum/gui/qt_common, implement remaining trustedcoin…
accumulator Aug 3, 2023
fd28c66
qt: 2fa implement OTP check
accumulator Aug 4, 2023
3c232d7
small fixes
accumulator Aug 4, 2023
b7ed4c5
wip. trezor works for standard wallet, also for cosigners
accumulator Aug 8, 2023
d3a1cef
create ChoiceWidget, refactor ChoicesLayout to ChoiceWidget
accumulator Aug 8, 2023
902290e
qt: multisig checks with hardware cosigners
accumulator Aug 11, 2023
b2a41b6
qt: jade for new wizard
accumulator Aug 11, 2023
7a2633b
flake happifier
accumulator Aug 11, 2023
65fee65
trustedcoin: ChoicesLayout -> ChoiceWidget
accumulator Aug 14, 2023
dec4a8e
qml: wizard fixes
accumulator Aug 14, 2023
2a2459c
qt: implement server picker in server connect wizard
accumulator Aug 14, 2023
1e570bd
qt: make QtEventListener more robust against stale PyQt wrappers
accumulator Aug 15, 2023
83c2eb4
qt: initial open existing wallet from wizard,
accumulator Aug 15, 2023
b072f5d
wizard: typing
accumulator Aug 15, 2023
8663d89
qt: add HWW unlock wizardcomponent
accumulator Aug 16, 2023
7dd43fa
qt: add bitbox02 to new wizard
accumulator Aug 22, 2023
66e9f50
qt: generalize wizard HWW xpub
accumulator Aug 23, 2023
2739c2f
wizard: bitbox_ view prefixes to bitbox02_
accumulator Aug 23, 2023
48fb491
wizard: add digital bitbox to new wizard
accumulator Aug 23, 2023
d708313
wizard: add keepkey to new wizard
accumulator Aug 23, 2023
31ffeaf
wizard: add coldcard
accumulator Aug 23, 2023
46c60c9
wizard: add ledger
accumulator Aug 23, 2023
656442c
wizard: add missing imports
accumulator Aug 24, 2023
f23bd33
wizard: add safe_t, except for wallet initial setup support.
accumulator Aug 24, 2023
eb8212a
qt: trustedcoin plugin helper scoping refactor
accumulator Aug 24, 2023
7001bda
wizard: port storage/db changes
accumulator Aug 24, 2023
5ff945e
qt: wizard run_upgrades
accumulator Aug 28, 2023
7080a7d
qt: new wizard 2fa wallet online continuation from offline initial setup
accumulator Aug 28, 2023
314e3f9
qt: new wizard 2fa offline setup
accumulator Aug 28, 2023
97c9fd2
flake
accumulator Aug 28, 2023
faf3536
qt: single_password doesn't seem to be supported on desktop, disable …
accumulator Aug 29, 2023
ecc3004
qt: safe_t device init
accumulator Aug 29, 2023
5ab083b
qt: keepkey device init
accumulator Aug 29, 2023
8747ff3
small fixes, imports
accumulator Aug 29, 2023
1c7da01
rename qt_common to common_qt
accumulator Aug 31, 2023
4bbf99f
qt: remove old wizard entry code
accumulator Aug 31, 2023
0aebc1a
qt+plugins: cleanup. remove all old wizard code
accumulator Aug 31, 2023
53b12cb
qt: check HWW supported script types
accumulator Aug 31, 2023
bb8b82c
qt: wizard back button disabled while busy. Wrap error texts
accumulator Aug 31, 2023
5f27777
qt: trezor firmware checks on xpub and initial setup
accumulator Aug 31, 2023
2a81ab6
qml: show user feedback when wallet file has action pending
accumulator Sep 1, 2023
d68e6a6
qt: wizardcomponents all use Logger mixin. Fix missing self.plugins i…
accumulator Sep 6, 2023
087718f
hww: mark device_model_name(self) as @abstractmethod and override in …
accumulator Sep 6, 2023
f7b3400
plugin: device_model_name defaults to plugin name if not overridden.
accumulator Sep 7, 2023
d4d57c3
qt: automatically proceed wizard when unlocking existing wallet or su…
accumulator Sep 7, 2023
f3d843a
qt: hww scan, focus rescan button only if no devices found
accumulator Sep 7, 2023
03435eb
hw_wallet: inherit from ABC and use @abstractmethod decorators instea…
accumulator Sep 8, 2023
b761260
wizard: add Digital Bitbox initialization to new wizard, remove resca…
accumulator Sep 8, 2023
50d2cdb
wizard: improve hww uninitialized default msg. attempt fix flake issu…
accumulator Sep 11, 2023
dd64b5c
wizard: add bitbox02 new wallet init and checks to new wizard
accumulator Sep 11, 2023
7fd3b6c
wizard: remove finished call, it's unused
accumulator Sep 7, 2023
60d1d1e
wizard: add missing keepkey porting, fix password focus for default a…
accumulator Sep 14, 2023
7313259
wizard: keepkey and safe_t set valid on init, handle xprv validation,…
accumulator Sep 14, 2023
4101946
wizard: add non-hardened derivation path check for digital bitbox, re…
accumulator Sep 14, 2023
f69316d
trustedcoin: remove old wizard code
accumulator Sep 14, 2023
551a0e9
wizard: remove base_wizard.py
accumulator Sep 14, 2023
a1dea83
plugins: make HW_PluginBase an abstract baseclass
accumulator Sep 14, 2023
d2c7df3
wizard: fix hww scan debug_msg not working correctly
SomberNight Sep 15, 2023
1a91da6
coldcard: factor out manipulate_keystore_dict_during_wizard_setup
SomberNight Sep 15, 2023
ec0dbc7
wizard: fix assumption 'keystore_type' is present in wizard_data, fix…
accumulator Sep 15, 2023
5080c22
qt: fix device list after rescan
accumulator Sep 18, 2023
808f187
wizard: allow slip39 for multisig
accumulator Sep 18, 2023
22d3a5e
wizard: fix trezor initialisation/recover not setting page valid to True
accumulator Sep 18, 2023
81089a1
wizard: keepkey scope pin lineedit to instance
accumulator Sep 18, 2023
2caa8f1
wizard: make wizard.keystore_from_data more robust;
accumulator Sep 18, 2023
44a1595
wizard: don't use hww encryption of wallet files for anything besides…
accumulator Sep 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
738 changes: 0 additions & 738 deletions electrum/base_wizard.py

This file was deleted.

Empty file.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, QObject
from PyQt5.QtCore import pyqtSignal, pyqtProperty, QObject

from electrum.i18n import _
from electrum.logging import get_logger


class PluginQObject(QObject):
logger = get_logger(__name__)

Expand All @@ -24,6 +24,8 @@ def name(self): return self._name
@pyqtProperty(bool, notify=busyChanged)
def busy(self): return self._busy

# below only used for QML, not compatible yet with Qt

@pyqtProperty(bool, notify=pluginEnabledChanged)
def pluginEnabled(self): return self.plugin.is_enabled()

Expand Down
4 changes: 0 additions & 4 deletions electrum/gui/qml/components/WalletMainView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -317,10 +317,6 @@ Item {
function onOtpRequested() {
console.log('OTP requested')
var dialog = otpDialog.createObject(mainView)
dialog.accepted.connect(function() {
console.log('accepted ' + dialog.otpauth)
Daemon.currentWallet.finish_otp(dialog.otpauth)
})
dialog.open()
}
function onBroadcastFailed(txid, code, message) {
Expand Down
8 changes: 5 additions & 3 deletions electrum/gui/qml/components/wizard/WCCosignerKeystore.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ WizardComponent {
function apply() {
wizard_data['cosigner_keystore_type'] = keystoregroup.checkedButton.keystoretype
wizard_data['multisig_current_cosigner'] = cosigner
wizard_data['multisig_cosigner_data'][cosigner.toString()] = {}
wizard_data['multisig_cosigner_data'][cosigner.toString()] = {
'keystore_type': keystoregroup.checkedButton.keystoretype
}
}

ButtonGroup {
Expand Down Expand Up @@ -80,13 +82,13 @@ WizardComponent {
}
ElRadioButton {
ButtonGroup.group: keystoregroup
property string keystoretype: 'key'
property string keystoretype: 'masterkey'
checked: true
text: qsTr('Cosigner key')
}
ElRadioButton {
ButtonGroup.group: keystoregroup
property string keystoretype: 'seed'
property string keystoretype: 'haveseed'
text: qsTr('Cosigner seed')
}
}
Expand Down
2 changes: 1 addition & 1 deletion electrum/gui/qml/components/wizard/WCCreateSeed.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import "../controls"
WizardComponent {
securePage: true

valid: seedtext.text != ''
valid: seedtext.text != '' && extendcb.checked ? customwordstext.text != '' : true

function apply() {
wizard_data['seed'] = seedtext.text
Expand Down
3 changes: 3 additions & 0 deletions electrum/gui/qml/components/wizard/WCHaveSeed.qml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ WizardComponent {
valid = false
validationtext.text = ''

if (extendcb.checked && customwordstext.text == '')
return

var validSeed = bitcoin.verifySeed(seedtext.text, seed_variant_cb.currentValue, wizard_data['wallet_type'])
if (!cosigner || !validSeed) {
valid = validSeed
Expand Down
8 changes: 5 additions & 3 deletions electrum/gui/qml/qeapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
import sys
import html
import threading
import asyncio
from typing import TYPE_CHECKING, Set

from PyQt5.QtCore import (pyqtSlot, pyqtSignal, pyqtProperty, QObject, QUrl, QLocale,
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, pyqtProperty, QObject,
qInstallMessageHandler, QTimer, QSortFilterProxyModel)
from PyQt5.QtGui import QGuiApplication, QFontDatabase
from PyQt5.QtQml import qmlRegisterType, qmlRegisterUncreatableType, QQmlApplicationEngine
Expand Down Expand Up @@ -61,6 +60,7 @@

notification = None


class QEAppController(BaseCrashReporter, QObject):
_dummy = pyqtSignal()
userNotify = pyqtSignal(str, str)
Expand Down Expand Up @@ -319,6 +319,7 @@ def secureWindow(self, secure):
self._secureWindow = secure
self.secureWindowChanged.emit()


class ElectrumQmlApplication(QGuiApplication):

_valid = True
Expand Down Expand Up @@ -376,7 +377,7 @@ def __init__(self, args, *, config: 'SimpleConfig', daemon: 'Daemon', plugins: '
self.plugins = plugins
self._qeconfig = QEConfig(config)
self._qenetwork = QENetwork(daemon.network, self._qeconfig)
self.daemon = QEDaemon(daemon)
self.daemon = QEDaemon(daemon, self.plugins)
self.appController = QEAppController(self, self.daemon, self.plugins)
self._maxAmount = QEAmount(is_max=True)
self.context.setContextProperty('AppController', self.appController)
Expand Down Expand Up @@ -413,6 +414,7 @@ def message_handler(self, line, funct, file):
return
self.logger.warning(file)


class Exception_Hook(QObject, Logger):
_report_exception = pyqtSignal(object, object, object, object)

Expand Down
14 changes: 10 additions & 4 deletions electrum/gui/qml/qedaemon.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import os
import threading
from typing import TYPE_CHECKING

from PyQt5.QtCore import Qt, QAbstractListModel, QModelIndex
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject

from electrum.i18n import _
from electrum.logging import get_logger
from electrum.util import WalletFileException, standardize_path
from electrum.wallet import Abstract_Wallet
from electrum.plugin import run_hook
from electrum.lnchannel import ChannelState
from electrum.daemon import Daemon

from .auth import AuthMixin, auth_protect
from .qefx import QEFX
from .qewallet import QEWallet
from .qewalletdb import QEWalletDB
from .qewizard import QENewWalletWizard, QEServerConnectWizard

if TYPE_CHECKING:
from electrum.daemon import Daemon
from electrum.plugin import Plugins


# wallet list model. supports both wallet basenames (wallet file basenames)
# and whole Wallet instances (loaded wallets)
class QEWalletListModel(QAbstractListModel):
Expand Down Expand Up @@ -108,6 +112,7 @@ def updateWallet(self, path):
return
i += 1


class QEDaemon(AuthMixin, QObject):
_logger = get_logger(__name__)

Expand Down Expand Up @@ -135,9 +140,10 @@ class QEDaemon(AuthMixin, QObject):
walletOpenError = pyqtSignal([str], arguments=["error"])
walletDeleteError = pyqtSignal([str,str], arguments=['code', 'message'])

def __init__(self, daemon: 'Daemon', parent=None):
def __init__(self, daemon: 'Daemon', plugins: 'Plugins', parent=None):
super().__init__(parent)
self.daemon = daemon
self.plugins = plugins
self.qefx = QEFX(daemon.fx, daemon.config)

self._backendWalletLoaded.connect(self._on_backend_wallet_loaded)
Expand Down Expand Up @@ -334,7 +340,7 @@ def setPassword(self, password):
@pyqtProperty(QENewWalletWizard, notify=newWalletWizardChanged)
def newWalletWizard(self):
if not self._new_wallet_wizard:
self._new_wallet_wizard = QENewWalletWizard(self)
self._new_wallet_wizard = QENewWalletWizard(self, self.plugins)

return self._new_wallet_wizard

Expand Down
3 changes: 2 additions & 1 deletion electrum/gui/qml/qewalletdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject

from electrum.i18n import _
from electrum.logging import get_logger
from electrum.storage import WalletStorage, StorageEncryptionVersion
from electrum.wallet_db import WalletDB
Expand Down Expand Up @@ -189,7 +190,7 @@ def _load_db(self):
return
if self._db.get_action():
self._logger.warning('action pending. QML version doesn\'t support continuation of wizard')
return
raise WalletFileException(_('This wallet has an action pending. This is currently not supported on mobile'))

if self._db.requires_upgrade():
self._logger.warning('wallet requires upgrade, upgrading')
Expand Down
26 changes: 14 additions & 12 deletions electrum/gui/qml/qewizard.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import os
from typing import TYPE_CHECKING

from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
from PyQt5.QtQml import QQmlApplicationEngine

from electrum.logging import get_logger
from electrum import mnemonic
from electrum.wizard import NewWalletWizard, ServerConnectWizard

if TYPE_CHECKING:
from electrum.gui.qml.qedaemon import QEDaemon
from electrum.plugin import Plugins


class QEAbstractWizard(QObject):
_logger = get_logger(__name__)
Expand All @@ -26,7 +30,6 @@ def viewToComponent(self, view):
@pyqtSlot('QJSValue', result='QVariant')
def submit(self, wizard_data):
wdata = wizard_data.toVariant()
self.log_state(wdata)
view = self.resolve_next(self._current.view, wdata)
return { 'view': view.view, 'wizard_data': view.wizard_data }

Expand All @@ -46,10 +49,10 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard):
createError = pyqtSignal([str], arguments=["error"])
createSuccess = pyqtSignal()

def __init__(self, daemon, parent = None):
NewWalletWizard.__init__(self, daemon)
def __init__(self, daemon: 'QEDaemon', plugins: 'Plugins', parent = None):
NewWalletWizard.__init__(self, daemon.daemon, plugins)
QEAbstractWizard.__init__(self, parent)
self._daemon = daemon
self._qedaemon = daemon

# attach view names and accept handlers
self.navmap_merge({
Expand All @@ -59,13 +62,13 @@ def __init__(self, daemon, parent = None):
'create_seed': { 'gui': 'WCCreateSeed' },
'confirm_seed': { 'gui': 'WCConfirmSeed' },
'have_seed': { 'gui': 'WCHaveSeed' },
'bip39_refine': { 'gui': 'WCBIP39Refine' },
'script_and_derivation': { 'gui': 'WCScriptAndDerivation' },
'have_master_key': { 'gui': 'WCHaveMasterKey' },
'multisig': { 'gui': 'WCMultisig' },
'multisig_cosigner_keystore': { 'gui': 'WCCosignerKeystore' },
'multisig_cosigner_key': { 'gui': 'WCHaveMasterKey' },
'multisig_cosigner_seed': { 'gui': 'WCHaveSeed' },
'multisig_cosigner_bip39_refine': { 'gui': 'WCBIP39Refine' },
'multisig_cosigner_script_and_derivation': { 'gui': 'WCBIP39Refine' },
'imported': { 'gui': 'WCImport' },
'wallet_password': { 'gui': 'WCWalletPassword' }
})
Expand All @@ -81,7 +84,7 @@ def path(self, path):
self.pathChanged.emit()

def is_single_password(self):
return self._daemon.singlePasswordEnabled
return self._qedaemon.singlePasswordEnabled

@pyqtSlot('QJSValue', result=bool)
def hasDuplicateMasterKeys(self, js_data):
Expand All @@ -108,7 +111,7 @@ def createStorage(self, js_data, single_password_enabled, single_password):
data['encrypt'] = True
data['password'] = single_password

path = os.path.join(os.path.dirname(self._daemon.daemon.config.get_wallet_path()), data['wallet_name'])
path = os.path.join(os.path.dirname(self._qedaemon.daemon.config.get_wallet_path()), data['wallet_name'])

try:
self.create_storage(path, data)
Expand All @@ -125,10 +128,9 @@ def createStorage(self, js_data, single_password_enabled, single_password):

class QEServerConnectWizard(ServerConnectWizard, QEAbstractWizard):

def __init__(self, daemon, parent = None):
ServerConnectWizard.__init__(self, daemon)
def __init__(self, daemon: 'QEDaemon', parent=None):
ServerConnectWizard.__init__(self, daemon.daemon)
QEAbstractWizard.__init__(self, parent)
self._daemon = daemon

# attach view names
self.navmap_merge({
Expand Down
Loading