mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-03 12:30:07 +00:00
trustedcoin: sign first, then prompt for OTP
This commit is contained in:
parent
7c6364c2c7
commit
ceae43afe5
5 changed files with 42 additions and 18 deletions
|
@ -1584,8 +1584,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
|||
# can sign directly
|
||||
task = partial(Transaction.sign, tx, self.tx_external_keypairs)
|
||||
else:
|
||||
# call hook to see if plugin needs gui interaction
|
||||
run_hook('sign_tx', self, tx)
|
||||
task = partial(self.wallet.sign_transaction, tx, password)
|
||||
WaitingDialog(self, _('Signing transaction...'), task,
|
||||
on_signed, on_failed)
|
||||
|
|
|
@ -426,7 +426,6 @@ class Commands:
|
|||
if rbf:
|
||||
tx.set_rbf(True)
|
||||
if not unsigned:
|
||||
run_hook('sign_tx', self.wallet, tx)
|
||||
self.wallet.sign_transaction(tx, password)
|
||||
return tx
|
||||
|
||||
|
|
|
@ -27,10 +27,10 @@ from electrum.i18n import _
|
|||
from electrum.plugins import hook
|
||||
from .trustedcoin import TrustedCoinPlugin
|
||||
|
||||
|
||||
class Plugin(TrustedCoinPlugin):
|
||||
|
||||
@hook
|
||||
def sign_tx(self, wallet, tx):
|
||||
def prompt_user_for_otp(self, wallet, tx):
|
||||
if not isinstance(wallet, self.wallet_class):
|
||||
return
|
||||
if not wallet.can_sign_without_server():
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
# SOFTWARE.
|
||||
|
||||
from functools import partial
|
||||
import threading
|
||||
from threading import Thread
|
||||
import re
|
||||
from decimal import Decimal
|
||||
|
@ -37,6 +38,7 @@ from electrum_gui.qt.amountedit import AmountEdit
|
|||
from electrum_gui.qt.main_window import StatusBarButton
|
||||
from electrum.i18n import _
|
||||
from electrum.plugins import hook
|
||||
from electrum.util import PrintError
|
||||
from .trustedcoin import TrustedCoinPlugin, server
|
||||
|
||||
|
||||
|
@ -45,6 +47,38 @@ class TOS(QTextEdit):
|
|||
error_signal = pyqtSignal(object)
|
||||
|
||||
|
||||
class HandlerTwoFactor(QObject, PrintError):
|
||||
otp_start_signal = pyqtSignal(object, object)
|
||||
|
||||
def __init__(self, plugin, window):
|
||||
super().__init__()
|
||||
self.plugin = plugin
|
||||
self.window = window
|
||||
self.otp_start_signal.connect(self._prompt_user_for_otp)
|
||||
self.otp_done = threading.Event()
|
||||
|
||||
def prompt_user_for_otp(self, wallet, tx):
|
||||
self.otp_done.clear()
|
||||
self.otp_start_signal.emit(wallet, tx)
|
||||
self.otp_done.wait()
|
||||
|
||||
def _prompt_user_for_otp(self, wallet, tx):
|
||||
try:
|
||||
window = self.window.top_level_window()
|
||||
if not isinstance(wallet, self.plugin.wallet_class):
|
||||
return
|
||||
if not wallet.can_sign_without_server():
|
||||
self.print_error("twofactor:sign_tx")
|
||||
auth_code = None
|
||||
if wallet.keystores['x3/'].get_tx_derivations(tx):
|
||||
auth_code = self.plugin.auth_dialog(window)
|
||||
else:
|
||||
self.print_error("twofactor: xpub3 not needed")
|
||||
wallet.auth_code = auth_code
|
||||
finally:
|
||||
self.otp_done.set()
|
||||
|
||||
|
||||
class Plugin(TrustedCoinPlugin):
|
||||
|
||||
def __init__(self, parent, config, name):
|
||||
|
@ -55,6 +89,7 @@ class Plugin(TrustedCoinPlugin):
|
|||
wallet = window.wallet
|
||||
if not isinstance(wallet, self.wallet_class):
|
||||
return
|
||||
wallet.handler_2fa = HandlerTwoFactor(self, window)
|
||||
if wallet.can_sign_without_server():
|
||||
msg = ' '.join([
|
||||
_('This wallet was restored from seed, and it contains two master private keys.'),
|
||||
|
@ -88,19 +123,8 @@ class Plugin(TrustedCoinPlugin):
|
|||
return
|
||||
return pw.get_amount()
|
||||
|
||||
@hook
|
||||
def sign_tx(self, window, tx):
|
||||
wallet = window.wallet
|
||||
if not isinstance(wallet, self.wallet_class):
|
||||
return
|
||||
if not wallet.can_sign_without_server():
|
||||
self.print_error("twofactor:sign_tx")
|
||||
auth_code = None
|
||||
if wallet.keystores['x3/'].get_tx_derivations(tx):
|
||||
auth_code = self.auth_dialog(window)
|
||||
else:
|
||||
self.print_error("twofactor: xpub3 not needed")
|
||||
window.wallet.auth_code = auth_code
|
||||
def prompt_user_for_otp(self, wallet, tx):
|
||||
wallet.handler_2fa.prompt_user_for_otp(wallet, tx)
|
||||
|
||||
def waiting_dialog(self, window, on_finished=None):
|
||||
task = partial(self.request_billing_info, window.wallet)
|
||||
|
|
|
@ -215,6 +215,7 @@ class Wallet_2fa(Multisig_Wallet):
|
|||
Deterministic_Wallet.__init__(self, storage)
|
||||
self.is_billing = False
|
||||
self.billing_info = None
|
||||
self.auth_code = None
|
||||
|
||||
def can_sign_without_server(self):
|
||||
return not self.keystores['x2/'].is_watching_only()
|
||||
|
@ -272,6 +273,7 @@ class Wallet_2fa(Multisig_Wallet):
|
|||
Multisig_Wallet.sign_transaction(self, tx, password)
|
||||
if tx.is_complete():
|
||||
return
|
||||
self.plugin.prompt_user_for_otp(self, tx)
|
||||
if not self.auth_code:
|
||||
self.print_error("sign_transaction: no auth code")
|
||||
return
|
||||
|
@ -285,6 +287,7 @@ class Wallet_2fa(Multisig_Wallet):
|
|||
self.print_error("twofactor: is complete", tx.is_complete())
|
||||
# reset billing_info
|
||||
self.billing_info = None
|
||||
self.auth_code = None
|
||||
|
||||
|
||||
# Utility functions
|
||||
|
|
Loading…
Add table
Reference in a new issue