qml: handle non-deterministic wallet address selection when generating payment request
This commit is contained in:
@@ -20,6 +20,8 @@ ElDialog {
|
|||||||
property bool _render_qr: false // delay qr rendering until dialog is shown
|
property bool _render_qr: false // delay qr rendering until dialog is shown
|
||||||
|
|
||||||
property bool _ispaid: false
|
property bool _ispaid: false
|
||||||
|
property bool _ignore_gaplimit: false
|
||||||
|
property bool _reuse_address: false
|
||||||
|
|
||||||
parent: Overlay.overlay
|
parent: Overlay.overlay
|
||||||
modal: true
|
modal: true
|
||||||
@@ -310,20 +312,20 @@ ElDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRequest(ignoreGaplimit = false) {
|
function createRequest() {
|
||||||
var qamt = Config.unitsToSats(receiveDetailsDialog.amount)
|
var qamt = Config.unitsToSats(receiveDetailsDialog.amount)
|
||||||
if (qamt.satsInt > Daemon.currentWallet.lightningCanReceive.satsInt) {
|
if (qamt.satsInt > Daemon.currentWallet.lightningCanReceive.satsInt) {
|
||||||
console.log('Creating OnChain request')
|
console.log('Creating OnChain request')
|
||||||
Daemon.currentWallet.createRequest(qamt, receiveDetailsDialog.description, receiveDetailsDialog.expiry, false, ignoreGaplimit)
|
Daemon.currentWallet.createRequest(qamt, receiveDetailsDialog.description, receiveDetailsDialog.expiry, false, _ignore_gaplimit, _reuse_address)
|
||||||
} else {
|
} else {
|
||||||
console.log('Creating Lightning request')
|
console.log('Creating Lightning request')
|
||||||
Daemon.currentWallet.createRequest(qamt, receiveDetailsDialog.description, receiveDetailsDialog.expiry, true)
|
Daemon.currentWallet.createRequest(qamt, receiveDetailsDialog.description, receiveDetailsDialog.expiry, true, _ignore_gaplimit, _reuse_address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDefaultRequest(ignoreGaplimit = false) {
|
function createDefaultRequest() {
|
||||||
console.log('Creating default request')
|
console.log('Creating default request')
|
||||||
Daemon.currentWallet.createDefaultRequest(ignoreGaplimit)
|
Daemon.currentWallet.createDefaultRequest(_ignore_gaplimit, _reuse_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
@@ -333,13 +335,20 @@ ElDialog {
|
|||||||
}
|
}
|
||||||
function onRequestCreateError(code, error) {
|
function onRequestCreateError(code, error) {
|
||||||
if (code == 'gaplimit') {
|
if (code == 'gaplimit') {
|
||||||
var dialog = app.messageDialog.createObject(app, {'text': error, 'yesno': true})
|
var dialog = app.messageDialog.createObject(app, {text: error, yesno: true})
|
||||||
dialog.yesClicked.connect(function() {
|
dialog.yesClicked.connect(function() {
|
||||||
createDefaultRequest(true)
|
_ignore_gaplimit = true
|
||||||
|
createDefaultRequest()
|
||||||
|
})
|
||||||
|
} else if (code == 'non-deterministic') {
|
||||||
|
var dialog = app.messageDialog.createObject(app, {text: error, yesno: true})
|
||||||
|
dialog.yesClicked.connect(function() {
|
||||||
|
_reuse_address = true
|
||||||
|
createDefaultRequest()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
var dialog = app.messageDialog.createObject(app, {'text': error})
|
var dialog = app.messageDialog.createObject(app, {text: error})
|
||||||
}
|
}
|
||||||
dialog.open()
|
dialog.open()
|
||||||
}
|
}
|
||||||
@@ -388,7 +397,8 @@ ElDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
createDefaultRequest()
|
// callLater to make sure any popups are on top of the dialog stacking order
|
||||||
|
Qt.callLater(createDefaultRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hack. delay qr rendering until dialog is shown
|
// hack. delay qr rendering until dialog is shown
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import asyncio
|
|||||||
import queue
|
import queue
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from typing import Optional, TYPE_CHECKING
|
from typing import TYPE_CHECKING, Optional, Tuple
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer
|
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer
|
||||||
@@ -571,21 +571,20 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
|
|
||||||
threading.Thread(target=pay_thread).start()
|
threading.Thread(target=pay_thread).start()
|
||||||
|
|
||||||
def create_bitcoin_request(self, amount: int, message: str, expiration: int, ignore_gap: bool) -> Optional[str]:
|
def create_bitcoin_request(self, amount: int, message: str, expiration: int, *, ignore_gap: bool = False, reuse_address: bool = False) -> Optional[Tuple]:
|
||||||
addr = self.wallet.get_unused_address()
|
addr = self.wallet.get_unused_address()
|
||||||
if addr is None:
|
if addr is None:
|
||||||
if not self.wallet.is_deterministic(): # imported wallet
|
if not self.wallet.is_deterministic(): # imported wallet
|
||||||
# TODO implement
|
if not reuse_address:
|
||||||
return
|
msg = [
|
||||||
#msg = [
|
_('No more addresses in your wallet.'), ' ',
|
||||||
#_('No more addresses in your wallet.'), ' ',
|
_('You are using a non-deterministic wallet, which cannot create new addresses.'), ' ',
|
||||||
#_('You are using a non-deterministic wallet, which cannot create new addresses.'), ' ',
|
_('If you want to create new addresses, use a deterministic wallet instead.'), '\n\n',
|
||||||
#_('If you want to create new addresses, use a deterministic wallet instead.'), '\n\n',
|
_('Creating a new payment request will reuse one of your addresses and overwrite an existing request. Continue anyway?'),
|
||||||
#_('Creating a new payment request will reuse one of your addresses and overwrite an existing request. Continue anyway?'),
|
]
|
||||||
#]
|
self.requestCreateError.emit('non-deterministic',''.join(msg))
|
||||||
#if not self.question(''.join(msg)):
|
return
|
||||||
#return
|
addr = self.wallet.get_receiving_address()
|
||||||
#addr = self.wallet.get_receiving_address()
|
|
||||||
else: # deterministic wallet
|
else: # deterministic wallet
|
||||||
if not ignore_gap:
|
if not ignore_gap:
|
||||||
self.requestCreateError.emit('gaplimit',_("Warning: The next address will not be recovered automatically if you restore your wallet from seed; you may need to add it manually.\n\nThis occurs because you have too many unused addresses in your wallet. To avoid this situation, use the existing addresses first.\n\nCreate anyway?"))
|
self.requestCreateError.emit('gaplimit',_("Warning: The next address will not be recovered automatically if you restore your wallet from seed; you may need to add it manually.\n\nThis occurs because you have too many unused addresses in your wallet. To avoid this situation, use the existing addresses first.\n\nCreate anyway?"))
|
||||||
@@ -593,6 +592,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
addr = self.wallet.create_new_address(False)
|
addr = self.wallet.create_new_address(False)
|
||||||
|
|
||||||
req_key = self.wallet.create_request(amount, message, expiration, addr)
|
req_key = self.wallet.create_request(amount, message, expiration, addr)
|
||||||
|
self._logger.debug(f'created request with key {req_key}')
|
||||||
#try:
|
#try:
|
||||||
#self.wallet.add_payment_request(req)
|
#self.wallet.add_payment_request(req)
|
||||||
#except Exception as e:
|
#except Exception as e:
|
||||||
@@ -608,8 +608,8 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
@pyqtSlot(QEAmount, str, int)
|
@pyqtSlot(QEAmount, str, int)
|
||||||
@pyqtSlot(QEAmount, str, int, bool)
|
@pyqtSlot(QEAmount, str, int, bool)
|
||||||
@pyqtSlot(QEAmount, str, int, bool, bool)
|
@pyqtSlot(QEAmount, str, int, bool, bool)
|
||||||
def createRequest(self, amount: QEAmount, message: str, expiration: int, is_lightning: bool = False, ignore_gap: bool = False):
|
@pyqtSlot(QEAmount, str, int, bool, bool, bool)
|
||||||
# TODO: unify this method and create_bitcoin_request
|
def createRequest(self, amount: QEAmount, message: str, expiration: int, is_lightning: bool = False, ignore_gap: bool = False, reuse_address: bool = False):
|
||||||
try:
|
try:
|
||||||
if is_lightning:
|
if is_lightning:
|
||||||
if not self.wallet.lnworker.channels:
|
if not self.wallet.lnworker.channels:
|
||||||
@@ -620,10 +620,10 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
addr = self.wallet.get_unused_address()
|
addr = self.wallet.get_unused_address()
|
||||||
key = self.wallet.create_request(amount.satsInt, message, expiration, addr)
|
key = self.wallet.create_request(amount.satsInt, message, expiration, addr)
|
||||||
else:
|
else:
|
||||||
key, addr = self.create_bitcoin_request(amount.satsInt, message, expiration, ignore_gap)
|
key, addr = self.create_bitcoin_request(amount.satsInt, message, expiration, ignore_gap=ignore_gap, reuse_address=reuse_address)
|
||||||
if not key:
|
if not key:
|
||||||
return
|
return
|
||||||
self.addressModel.init_model()
|
self.addressModel.setDirty()
|
||||||
except InvoiceError as e:
|
except InvoiceError as e:
|
||||||
self.requestCreateError.emit('fatal',_('Error creating payment request') + ':\n' + str(e))
|
self.requestCreateError.emit('fatal',_('Error creating payment request') + ':\n' + str(e))
|
||||||
return
|
return
|
||||||
@@ -634,7 +634,8 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
@pyqtSlot(bool)
|
@pyqtSlot(bool)
|
||||||
def createDefaultRequest(self, ignore_gap: bool = False):
|
@pyqtSlot(bool, bool)
|
||||||
|
def createDefaultRequest(self, ignore_gap: bool = False, reuse_address: bool = False):
|
||||||
try:
|
try:
|
||||||
default_expiry = self.wallet.config.get('request_expiry', PR_DEFAULT_EXPIRATION_WHEN_CREATING)
|
default_expiry = self.wallet.config.get('request_expiry', PR_DEFAULT_EXPIRATION_WHEN_CREATING)
|
||||||
if self.wallet.lnworker and self.wallet.lnworker.channels:
|
if self.wallet.lnworker and self.wallet.lnworker.channels:
|
||||||
@@ -645,9 +646,10 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
pass
|
pass
|
||||||
key = self.wallet.create_request(None, None, default_expiry, addr)
|
key = self.wallet.create_request(None, None, default_expiry, addr)
|
||||||
else:
|
else:
|
||||||
key, addr = self.create_bitcoin_request(None, None, default_expiry, ignore_gap)
|
req = self.create_bitcoin_request(None, None, default_expiry, ignore_gap=ignore_gap, reuse_address=reuse_address)
|
||||||
if not key:
|
if not req:
|
||||||
return
|
return
|
||||||
|
key, addr = req
|
||||||
except InvoiceError as e:
|
except InvoiceError as e:
|
||||||
self.requestCreateError.emit('fatal',_('Error creating payment request') + ':\n' + str(e))
|
self.requestCreateError.emit('fatal',_('Error creating payment request') + ':\n' + str(e))
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user