qt: new wizard 2fa wallet online continuation from offline initial setup
This commit is contained in:
@@ -33,6 +33,7 @@ from typing import Optional, TYPE_CHECKING, List, Sequence
|
|||||||
from electrum import GuiImportError, WalletStorage
|
from electrum import GuiImportError, WalletStorage
|
||||||
from .wizard.server_connect import QEServerConnectWizard
|
from .wizard.server_connect import QEServerConnectWizard
|
||||||
from .wizard.wallet import QENewWalletWizard
|
from .wizard.wallet import QENewWalletWizard
|
||||||
|
from electrum.wizard import WizardViewState
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import PyQt5
|
import PyQt5
|
||||||
@@ -435,10 +436,23 @@ class ElectrumGui(BaseElectrumGui, Logger):
|
|||||||
wizard.run_upgrades(db)
|
wizard.run_upgrades(db)
|
||||||
except UserCancelled:
|
except UserCancelled:
|
||||||
return
|
return
|
||||||
# TODO
|
|
||||||
# return if wallet creation is not complete
|
if action := db.get_action():
|
||||||
# if storage is None or db.get_action():
|
# wallet creation is not complete, 2fa online phase
|
||||||
# return
|
assert action[1] == 'accept_terms_of_use', 'only support for resuming trustedcoin split setup'
|
||||||
|
data = {
|
||||||
|
'xprv1': db.get('x1/')['xprv'],
|
||||||
|
'xpub1': db.get('x1/')['xpub'],
|
||||||
|
'xpub2': db.get('x2/')['xpub'],
|
||||||
|
}
|
||||||
|
wizard = QENewWalletWizard(self.config, self.app, self.plugins, self.daemon, path,
|
||||||
|
start_viewstate=WizardViewState('trustedcoin_tos_email', data, {}))
|
||||||
|
result = wizard.exec()
|
||||||
|
if result == QENewWalletWizard.Rejected:
|
||||||
|
self.logger.info('ok bye bye')
|
||||||
|
return
|
||||||
|
db.put('x3/', wizard.get_wizard_data()['x3/'])
|
||||||
|
db.write()
|
||||||
|
|
||||||
wallet = Wallet(db, config=self.config)
|
wallet = Wallet(db, config=self.config)
|
||||||
wallet.start_network(self.daemon.network)
|
wallet.start_network(self.daemon.network)
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ MSG_HW_STORAGE_ENCRYPTION = _("Set wallet file encryption.") + '\n'\
|
|||||||
class QENewWalletWizard(NewWalletWizard, QEAbstractWizard, MessageBoxMixin):
|
class QENewWalletWizard(NewWalletWizard, QEAbstractWizard, MessageBoxMixin):
|
||||||
_logger = get_logger(__name__)
|
_logger = get_logger(__name__)
|
||||||
|
|
||||||
def __init__(self, config: 'SimpleConfig', app: 'QElectrumApplication', plugins: 'Plugins', daemon: Daemon, path, parent=None):
|
def __init__(self, config: 'SimpleConfig', app: 'QElectrumApplication', plugins: 'Plugins', daemon: Daemon, path, *, start_viewstate=None):
|
||||||
NewWalletWizard.__init__(self, daemon, plugins)
|
NewWalletWizard.__init__(self, daemon, plugins)
|
||||||
QEAbstractWizard.__init__(self, config, app)
|
QEAbstractWizard.__init__(self, config, app, start_viewstate=start_viewstate)
|
||||||
|
|
||||||
self.setWindowTitle(_('Create/Restore wallet'))
|
self.setWindowTitle(_('Create/Restore wallet'))
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import copy
|
||||||
import threading
|
import threading
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
@@ -14,12 +15,13 @@ from electrum.gui.qt.util import Buttons, icon_path, MessageBoxMixin
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from electrum.simple_config import SimpleConfig
|
from electrum.simple_config import SimpleConfig
|
||||||
from electrum.gui.qt import QElectrumApplication
|
from electrum.gui.qt import QElectrumApplication
|
||||||
|
from electrum.wizard import WizardViewState
|
||||||
|
|
||||||
|
|
||||||
class QEAbstractWizard(QDialog, MessageBoxMixin):
|
class QEAbstractWizard(QDialog, MessageBoxMixin):
|
||||||
_logger = get_logger(__name__)
|
_logger = get_logger(__name__)
|
||||||
|
|
||||||
def __init__(self, config: 'SimpleConfig', app: 'QElectrumApplication'):
|
def __init__(self, config: 'SimpleConfig', app: 'QElectrumApplication', *, start_viewstate: 'WizardViewState' = None):
|
||||||
QDialog.__init__(self, None)
|
QDialog.__init__(self, None)
|
||||||
self.app = app
|
self.app = app
|
||||||
self.config = config
|
self.config = config
|
||||||
@@ -92,6 +94,8 @@ class QEAbstractWizard(QDialog, MessageBoxMixin):
|
|||||||
self.icon_filename = None
|
self.icon_filename = None
|
||||||
self.set_icon('electrum.png')
|
self.set_icon('electrum.png')
|
||||||
|
|
||||||
|
self.start_viewstate = start_viewstate
|
||||||
|
|
||||||
self.show()
|
self.show()
|
||||||
self.raise_()
|
self.raise_()
|
||||||
|
|
||||||
@@ -109,8 +113,11 @@ class QEAbstractWizard(QDialog, MessageBoxMixin):
|
|||||||
return QSize(800, 600)
|
return QSize(800, 600)
|
||||||
|
|
||||||
def strt(self):
|
def strt(self):
|
||||||
view = self.start_wizard()
|
if self.start_viewstate is not None:
|
||||||
self.load_next_component(view)
|
viewstate = self._current = self.start_viewstate
|
||||||
|
else:
|
||||||
|
viewstate = self.start_wizard()
|
||||||
|
self.load_next_component(viewstate.view, viewstate.wizard_data)
|
||||||
|
|
||||||
def load_next_component(self, view, wdata=None, params=None):
|
def load_next_component(self, view, wdata=None, params=None):
|
||||||
if wdata is None:
|
if wdata is None:
|
||||||
@@ -124,7 +131,7 @@ class QEAbstractWizard(QDialog, MessageBoxMixin):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._logger.error(f'not a class: {comp!r}')
|
self._logger.error(f'not a class: {comp!r}')
|
||||||
raise e
|
raise e
|
||||||
page.wizard_data = wdata
|
page.wizard_data = copy.deepcopy(wdata)
|
||||||
page.params = params
|
page.params = params
|
||||||
page.updated.connect(self.on_page_updated)
|
page.updated.connect(self.on_page_updated)
|
||||||
self._logger.debug(f'{page!r}')
|
self._logger.debug(f'{page!r}')
|
||||||
@@ -187,9 +194,9 @@ class QEAbstractWizard(QDialog, MessageBoxMixin):
|
|||||||
next = self.submit(wd)
|
next = self.submit(wd)
|
||||||
self.load_next_component(next.view, next.wizard_data, next.params)
|
self.load_next_component(next.view, next.wizard_data, next.params)
|
||||||
|
|
||||||
def start_wizard(self) -> str:
|
def start_wizard(self) -> 'WizardViewState':
|
||||||
self.start()
|
self.start()
|
||||||
return self._current.view
|
return self._current
|
||||||
|
|
||||||
def view_to_component(self, view) -> QWidget:
|
def view_to_component(self, view) -> QWidget:
|
||||||
return self.navmap[view]['gui']
|
return self.navmap[view]['gui']
|
||||||
|
|||||||
@@ -821,7 +821,7 @@ class TrustedCoinPlugin(BasePlugin):
|
|||||||
'trustedcoin_show_confirm_otp': {
|
'trustedcoin_show_confirm_otp': {
|
||||||
'accept': self.on_accept_otp_secret,
|
'accept': self.on_accept_otp_secret,
|
||||||
'next': 'wallet_password',
|
'next': 'wallet_password',
|
||||||
'last': lambda d: wizard.is_single_password()
|
'last': lambda d: wizard.is_single_password() or 'xprv1' in d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wizard.navmap_merge(views)
|
wizard.navmap_merge(views)
|
||||||
@@ -832,12 +832,11 @@ class TrustedCoinPlugin(BasePlugin):
|
|||||||
# wizard = self._wizard
|
# wizard = self._wizard
|
||||||
# wizard_data = wizard._current.wizard_data
|
# wizard_data = wizard._current.wizard_data
|
||||||
|
|
||||||
xprv1, xpub1, xprv2, xpub2 = self.xkeys_from_seed(wizard_data['seed'], wizard_data['seed_extra_words'])
|
if 'seed' not in wizard_data:
|
||||||
|
# online continuation
|
||||||
# NOTE: at this point, old style wizard creates a wallet file (w. password if set) and
|
xprv1, xpub1, xprv2, xpub2 = (wizard_data['xprv1'], wizard_data['xpub1'], None, wizard_data['xpub2'])
|
||||||
# stores the keystores and wizard state, in order to separate offline seed creation
|
else:
|
||||||
# and online retrieval of the OTP secret. For mobile, we don't do this, but
|
xprv1, xpub1, xprv2, xpub2 = self.xkeys_from_seed(wizard_data['seed'], wizard_data['seed_extra_words'])
|
||||||
# for desktop the wizard should support this usecase.
|
|
||||||
|
|
||||||
data = {'x1/': {'xpub': xpub1}, 'x2/': {'xpub': xpub2}}
|
data = {'x1/': {'xpub': xpub1}, 'x2/': {'xpub': xpub2}}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user