mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-05 05:15:12 +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
|
# can sign directly
|
||||||
task = partial(Transaction.sign, tx, self.tx_external_keypairs)
|
task = partial(Transaction.sign, tx, self.tx_external_keypairs)
|
||||||
else:
|
else:
|
||||||
# call hook to see if plugin needs gui interaction
|
|
||||||
run_hook('sign_tx', self, tx)
|
|
||||||
task = partial(self.wallet.sign_transaction, tx, password)
|
task = partial(self.wallet.sign_transaction, tx, password)
|
||||||
WaitingDialog(self, _('Signing transaction...'), task,
|
WaitingDialog(self, _('Signing transaction...'), task,
|
||||||
on_signed, on_failed)
|
on_signed, on_failed)
|
||||||
|
|
|
@ -426,7 +426,6 @@ class Commands:
|
||||||
if rbf:
|
if rbf:
|
||||||
tx.set_rbf(True)
|
tx.set_rbf(True)
|
||||||
if not unsigned:
|
if not unsigned:
|
||||||
run_hook('sign_tx', self.wallet, tx)
|
|
||||||
self.wallet.sign_transaction(tx, password)
|
self.wallet.sign_transaction(tx, password)
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,10 @@ from electrum.i18n import _
|
||||||
from electrum.plugins import hook
|
from electrum.plugins import hook
|
||||||
from .trustedcoin import TrustedCoinPlugin
|
from .trustedcoin import TrustedCoinPlugin
|
||||||
|
|
||||||
|
|
||||||
class Plugin(TrustedCoinPlugin):
|
class Plugin(TrustedCoinPlugin):
|
||||||
|
|
||||||
@hook
|
def prompt_user_for_otp(self, wallet, tx):
|
||||||
def sign_tx(self, wallet, tx):
|
|
||||||
if not isinstance(wallet, self.wallet_class):
|
if not isinstance(wallet, self.wallet_class):
|
||||||
return
|
return
|
||||||
if not wallet.can_sign_without_server():
|
if not wallet.can_sign_without_server():
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
import threading
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import re
|
import re
|
||||||
from decimal import Decimal
|
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_gui.qt.main_window import StatusBarButton
|
||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
from electrum.plugins import hook
|
from electrum.plugins import hook
|
||||||
|
from electrum.util import PrintError
|
||||||
from .trustedcoin import TrustedCoinPlugin, server
|
from .trustedcoin import TrustedCoinPlugin, server
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +47,38 @@ class TOS(QTextEdit):
|
||||||
error_signal = pyqtSignal(object)
|
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):
|
class Plugin(TrustedCoinPlugin):
|
||||||
|
|
||||||
def __init__(self, parent, config, name):
|
def __init__(self, parent, config, name):
|
||||||
|
@ -55,6 +89,7 @@ class Plugin(TrustedCoinPlugin):
|
||||||
wallet = window.wallet
|
wallet = window.wallet
|
||||||
if not isinstance(wallet, self.wallet_class):
|
if not isinstance(wallet, self.wallet_class):
|
||||||
return
|
return
|
||||||
|
wallet.handler_2fa = HandlerTwoFactor(self, window)
|
||||||
if wallet.can_sign_without_server():
|
if wallet.can_sign_without_server():
|
||||||
msg = ' '.join([
|
msg = ' '.join([
|
||||||
_('This wallet was restored from seed, and it contains two master private keys.'),
|
_('This wallet was restored from seed, and it contains two master private keys.'),
|
||||||
|
@ -88,19 +123,8 @@ class Plugin(TrustedCoinPlugin):
|
||||||
return
|
return
|
||||||
return pw.get_amount()
|
return pw.get_amount()
|
||||||
|
|
||||||
@hook
|
def prompt_user_for_otp(self, wallet, tx):
|
||||||
def sign_tx(self, window, tx):
|
wallet.handler_2fa.prompt_user_for_otp(wallet, 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 waiting_dialog(self, window, on_finished=None):
|
def waiting_dialog(self, window, on_finished=None):
|
||||||
task = partial(self.request_billing_info, window.wallet)
|
task = partial(self.request_billing_info, window.wallet)
|
||||||
|
|
|
@ -215,6 +215,7 @@ class Wallet_2fa(Multisig_Wallet):
|
||||||
Deterministic_Wallet.__init__(self, storage)
|
Deterministic_Wallet.__init__(self, storage)
|
||||||
self.is_billing = False
|
self.is_billing = False
|
||||||
self.billing_info = None
|
self.billing_info = None
|
||||||
|
self.auth_code = None
|
||||||
|
|
||||||
def can_sign_without_server(self):
|
def can_sign_without_server(self):
|
||||||
return not self.keystores['x2/'].is_watching_only()
|
return not self.keystores['x2/'].is_watching_only()
|
||||||
|
@ -272,6 +273,7 @@ class Wallet_2fa(Multisig_Wallet):
|
||||||
Multisig_Wallet.sign_transaction(self, tx, password)
|
Multisig_Wallet.sign_transaction(self, tx, password)
|
||||||
if tx.is_complete():
|
if tx.is_complete():
|
||||||
return
|
return
|
||||||
|
self.plugin.prompt_user_for_otp(self, tx)
|
||||||
if not self.auth_code:
|
if not self.auth_code:
|
||||||
self.print_error("sign_transaction: no auth code")
|
self.print_error("sign_transaction: no auth code")
|
||||||
return
|
return
|
||||||
|
@ -285,6 +287,7 @@ class Wallet_2fa(Multisig_Wallet):
|
||||||
self.print_error("twofactor: is complete", tx.is_complete())
|
self.print_error("twofactor: is complete", tx.is_complete())
|
||||||
# reset billing_info
|
# reset billing_info
|
||||||
self.billing_info = None
|
self.billing_info = None
|
||||||
|
self.auth_code = None
|
||||||
|
|
||||||
|
|
||||||
# Utility functions
|
# Utility functions
|
||||||
|
|
Loading…
Add table
Reference in a new issue