diff --git a/electrum/gui/qml/components/ChannelOpenProgressDialog.qml b/electrum/gui/qml/components/ChannelOpenProgressDialog.qml index 5854dafdd..65918f8b3 100644 --- a/electrum/gui/qml/components/ChannelOpenProgressDialog.qml +++ b/electrum/gui/qml/components/ChannelOpenProgressDialog.qml @@ -25,6 +25,7 @@ ElDialog { property alias state: s.state property alias error: errorText.text + property alias info: infoText.text property alias peer: peerText.text function reset() { @@ -110,7 +111,6 @@ ElDialog { InfoTextArea { id: infoText visible: false - text: qsTr('Channel will be open after 3 confirmations') width: parent.width } } diff --git a/electrum/gui/qml/components/OpenChannel.qml b/electrum/gui/qml/components/OpenChannel.qml index a54e9331a..d5e8150ca 100644 --- a/electrum/gui/qml/components/OpenChannel.qml +++ b/electrum/gui/qml/components/OpenChannel.qml @@ -197,11 +197,28 @@ Pane { app.channelOpenProgressDialog.error = message } onChannelOpenSuccess: { - var message = 'success!' - if (!has_backup) - message = message + ' (but no backup. TODO: show QR)' + var message = qsTr('Channel established.') + ' ' + + qsTr('This channel will be usable after %1 confirmations').arg(min_depth) + if (!tx_complete) { + message = message + ' ' + qsTr('Please sign and broadcast the funding transaction.') + } app.channelOpenProgressDialog.state = 'success' - app.channelOpenProgressDialog.error = message + app.channelOpenProgressDialog.info = message + if (!has_onchain_backup) { + app.channelOpenProgressDialog.closed.connect(function() { + var dialog = app.genericShareDialog.createObject(app, + { + title: qsTr('Save Backup') + text: channelopener.channelBackup(cid), + text_help: qsTr('The channel you created is not recoverable from seed.') + + ' ' + qsTr('To prevent fund losses, please save this backup on another device.') + + ' ' + qsTr('It may be imported in another Electrum wallet with the same seed.') + } + ) + dialog.open() + }) + } + // TODO: handle incomplete TX channelopener.wallet.channelModel.new_channel(cid) app.stack.pop() } diff --git a/electrum/gui/qml/qechannelopener.py b/electrum/gui/qml/qechannelopener.py index 4932f7fe8..e11a4b4b8 100644 --- a/electrum/gui/qml/qechannelopener.py +++ b/electrum/gui/qml/qechannelopener.py @@ -6,6 +6,7 @@ from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from electrum.i18n import _ from electrum.gui import messages +from electrum.util import bfh from electrum.lnutil import extract_nodeid, LNPeerAddr, ln_dummy_address from electrum.lnworker import hardcoded_trampoline_nodes from electrum.logging import get_logger @@ -27,12 +28,13 @@ class QEChannelOpener(QObject, AuthMixin): _amount = QEAmount() _valid = False _opentx = None + _txdetails = None validationError = pyqtSignal([str,str], arguments=['code','message']) conflictingBackup = pyqtSignal([str], arguments=['message']) channelOpening = pyqtSignal([str], arguments=['peer']) channelOpenError = pyqtSignal([str], arguments=['message']) - channelOpenSuccess = pyqtSignal([str,bool], arguments=['cid','has_backup']) + channelOpenSuccess = pyqtSignal([str,bool,int], arguments=['cid','has_onchain_backup','min_depth','tx_complete']) dataChanged = pyqtSignal() # generic notify signal @@ -82,6 +84,11 @@ class QEChannelOpener(QObject, AuthMixin): def finalizer(self): return self._finalizer + txDetailsChanged = pyqtSignal() + @pyqtProperty(QETxDetails, notify=txDetailsChanged) + def txDetails(self): + return self._txdetails + @pyqtProperty(list, notify=dataChanged) def trampolineNodeNames(self): return list(hardcoded_trampoline_nodes().keys()) @@ -180,7 +187,16 @@ class QEChannelOpener(QObject, AuthMixin): push_amt_sat=0, password=password) self._logger.debug('opening channel succeeded') - self.channelOpenSuccess.emit(chan.channel_id.hex(), chan.has_onchain_backup()) + self.channelOpenSuccess.emit(chan.channel_id.hex(), chan.has_onchain_backup(), + chan.constraints.funding_txn_minimum_depth, funding_tx.is_complete()) + + # TODO: handle incomplete TX + #if not funding_tx.is_complete(): + #self._txdetails = QETxDetails(self) + #self._txdetails.rawTx = funding_tx + #self._txdetails.wallet = self._wallet + #self.txDetailsChanged.emit() + except (CancelledError,TimeoutError): error = _('Could not connect to channel peer') except Exception as e: @@ -212,3 +228,22 @@ class QEChannelOpener(QObject, AuthMixin): #close_button_text=_('OK'), #on_close=lambda: self.maybe_show_funding_tx(chan, funding_tx)) #popup.open() + + + #def maybe_show_funding_tx(self, chan, funding_tx): + #n = chan.constraints.funding_txn_minimum_depth + #message = '\n'.join([ + #_('Channel established.'), + #_('Remote peer ID') + ':' + chan.node_id.hex(), + #_('This channel will be usable after {} confirmations').format(n) + #]) + #if not funding_tx.is_complete(): + #message += '\n\n' + _('Please sign and broadcast the funding transaction') + #self.app.show_info(message) + + #if not funding_tx.is_complete(): + #self.app.tx_dialog(funding_tx) + + @pyqtSlot(str, result=str) + def channelBackup(self, cid): + return self._wallet.wallet.lnworker.export_channel_backup(bfh(cid))