Merge pull request #9739 from accumulator/psbt_nostr_fixes
plugins: psbt_nostr: start processing PSBTs after wallet is_up_to_date
This commit is contained in:
@@ -38,7 +38,7 @@ from electrum.i18n import _
|
||||
from electrum.logging import Logger
|
||||
from electrum.plugin import BasePlugin
|
||||
from electrum.transaction import PartialTransaction, tx_from_any
|
||||
from electrum.util import log_exceptions, OldTaskGroup, ca_path, trigger_callback
|
||||
from electrum.util import log_exceptions, OldTaskGroup, ca_path, trigger_callback, event_listener
|
||||
from electrum.wallet import Multisig_Wallet
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -84,7 +84,10 @@ class CosignerWallet(Logger):
|
||||
|
||||
self.network = wallet.network
|
||||
self.config = self.wallet.config
|
||||
|
||||
self.pending = asyncio.Event()
|
||||
self.wallet_uptodate = asyncio.Event()
|
||||
|
||||
self.known_events = wallet.db.get_dict('cosigner_events')
|
||||
|
||||
for k, v in list(self.known_events.items()):
|
||||
@@ -114,10 +117,17 @@ class CosignerWallet(Logger):
|
||||
if self.network and self.nostr_pubkey:
|
||||
asyncio.run_coroutine_threadsafe(self.main_loop(), self.network.asyncio_loop)
|
||||
|
||||
@event_listener
|
||||
def on_event_wallet_updated(self, wallet):
|
||||
if self.wallet == wallet and wallet.is_up_to_date() and not self.wallet_uptodate.is_set():
|
||||
self.logger.debug('starting handling of PSBTs')
|
||||
self.wallet_uptodate.set()
|
||||
|
||||
@log_exceptions
|
||||
async def main_loop(self):
|
||||
self.logger.info("starting taskgroup.")
|
||||
try:
|
||||
await self.wallet_uptodate.wait() # start processing PSBTs only after wallet is_up_to_date
|
||||
async with self.taskgroup as group:
|
||||
await group.spawn(self.check_direct_messages())
|
||||
except Exception as e:
|
||||
@@ -189,7 +199,7 @@ class CosignerWallet(Logger):
|
||||
except Exception as e:
|
||||
self.logger.info(_("Unable to deserialize the transaction:") + "\n" + str(e))
|
||||
self.known_events[event.id] = now()
|
||||
return
|
||||
continue
|
||||
self.logger.info(f"received PSBT from {event.pubkey}")
|
||||
trigger_callback('psbt_nostr_received', self.wallet, event.pubkey, event.id, tx)
|
||||
await self.pending.wait()
|
||||
@@ -208,6 +218,14 @@ class CosignerWallet(Logger):
|
||||
# note that tx could also be unrelated from wallet?... (not ismine inputs)
|
||||
return True
|
||||
|
||||
def can_send_psbt(self, tx: Union[Transaction, PartialTransaction]) -> bool:
|
||||
if tx.is_complete() or self.wallet.can_sign(tx):
|
||||
return False
|
||||
for xpub, pubkey in self.cosigner_list:
|
||||
if self.cosigner_can_sign(tx, xpub):
|
||||
return True
|
||||
return False
|
||||
|
||||
def mark_pending_event_rcvd(self, event_id):
|
||||
self.logger.debug('marking event rcvd')
|
||||
self.known_events[event_id] = now()
|
||||
|
||||
@@ -58,23 +58,30 @@ class QReceiveSignalObject(QObject):
|
||||
def loader(self):
|
||||
return 'main.qml'
|
||||
|
||||
@pyqtSlot(QEWallet, str, result=bool)
|
||||
def canSendPsbt(self, wallet: 'QEWallet', tx: str) -> bool:
|
||||
cosigner_wallet = self._plugin.cosigner_wallets.get(wallet.wallet)
|
||||
if not cosigner_wallet:
|
||||
return False
|
||||
return cosigner_wallet.can_send_psbt(tx_from_any(tx, deserialize=True))
|
||||
|
||||
@pyqtSlot(QEWallet, str)
|
||||
def sendPsbt(self, wallet: 'QEWallet', tx: str):
|
||||
cosigner_wallet = self._plugin.cosigner_wallets[wallet.wallet]
|
||||
cosigner_wallet = self._plugin.cosigner_wallets.get(wallet.wallet)
|
||||
if not cosigner_wallet:
|
||||
return
|
||||
cosigner_wallet.send_psbt(tx_from_any(tx, deserialize=True))
|
||||
|
||||
@pyqtSlot(QEWallet, str)
|
||||
def acceptPsbt(self, wallet: 'QEWallet', event_id: str):
|
||||
cosigner_wallet = self._plugin.cosigner_wallets[wallet.wallet]
|
||||
cosigner_wallet = self._plugin.cosigner_wallets.get(wallet.wallet)
|
||||
if not cosigner_wallet:
|
||||
return
|
||||
cosigner_wallet.accept_psbt(event_id)
|
||||
|
||||
@pyqtSlot(QEWallet, str)
|
||||
def rejectPsbt(self, wallet: 'QEWallet', event_id: str):
|
||||
cosigner_wallet = self._plugin.cosigner_wallets[wallet.wallet]
|
||||
cosigner_wallet = self._plugin.cosigner_wallets.get(wallet.wallet)
|
||||
if not cosigner_wallet:
|
||||
return
|
||||
cosigner_wallet.reject_psbt(event_id)
|
||||
@@ -98,10 +105,12 @@ class Plugin(PsbtNostrPlugin):
|
||||
@hook
|
||||
def load_wallet(self, wallet: 'Abstract_Wallet'):
|
||||
# remove existing, only foreground wallet active
|
||||
if len(self.cosigner_wallets):
|
||||
self.remove_cosigner_wallet(self.cosigner_wallets[0])
|
||||
for wallet in self.cosigner_wallets.copy().keys():
|
||||
self.remove_cosigner_wallet(wallet)
|
||||
if not isinstance(wallet, Multisig_Wallet):
|
||||
return
|
||||
if wallet.wallet_type == '2fa':
|
||||
return
|
||||
self.add_cosigner_wallet(wallet, QmlCosignerWallet(wallet, self))
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Item {
|
||||
property variant dialog
|
||||
text: qsTr('Nostr')
|
||||
icon.source: Qt.resolvedUrl('../../../gui/icons/network.png')
|
||||
visible: Daemon.currentWallet.isMultisig && Daemon.currentWallet.walletType != '2fa'
|
||||
visible: AppController.plugin('psbt_nostr').canSendPsbt(Daemon.currentWallet, dialog.text)
|
||||
onClicked: {
|
||||
console.log('about to psbt nostr send')
|
||||
psbt_nostr_send_button.enabled = false
|
||||
|
||||
@@ -55,6 +55,8 @@ class Plugin(PsbtNostrPlugin):
|
||||
def load_wallet(self, wallet: 'Abstract_Wallet', window: 'ElectrumWindow'):
|
||||
if not isinstance(wallet, Multisig_Wallet):
|
||||
return
|
||||
if wallet.wallet_type == '2fa':
|
||||
return
|
||||
self.add_cosigner_wallet(wallet, QtCosignerWallet(wallet, window))
|
||||
|
||||
@hook
|
||||
@@ -77,15 +79,7 @@ class Plugin(PsbtNostrPlugin):
|
||||
def transaction_dialog_update(self, d: 'TxDialog'):
|
||||
if cw := self.cosigner_wallets.get(d.wallet):
|
||||
assert isinstance(cw, QtCosignerWallet)
|
||||
if d.tx.is_complete() or d.wallet.can_sign(d.tx):
|
||||
d.cosigner_send_button.setVisible(False)
|
||||
return
|
||||
for xpub, pubkey in cw.cosigner_list:
|
||||
if cw.cosigner_can_sign(d.tx, xpub):
|
||||
d.cosigner_send_button.setVisible(True)
|
||||
break
|
||||
else:
|
||||
d.cosigner_send_button.setVisible(False)
|
||||
d.cosigner_send_button.setVisible(cw.can_send_psbt(d.tx))
|
||||
|
||||
|
||||
class QtCosignerWallet(EventListener, CosignerWallet):
|
||||
|
||||
Reference in New Issue
Block a user