Skip to content

Commit 19432c7

Browse files
committed
fixes
1 parent 8c1c88c commit 19432c7

8 files changed

Lines changed: 60 additions & 39 deletions

File tree

electrum/gui/qml/qeconfig.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import copy
22
from decimal import Decimal
3-
from typing import TYPE_CHECKING
3+
from typing import TYPE_CHECKING, Optional
44

55
from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QRegularExpression
66

@@ -362,11 +362,11 @@ def formatSatsForEditing(self, satoshis):
362362

363363
@pyqtSlot('qint64', result=str)
364364
@pyqtSlot(QEAmount, result=str)
365-
def formatMilliSatsForEditing(self, satoshis):
366-
if isinstance(satoshis, QEAmount):
367-
satoshis = Decimal(satoshis.msatsInt) / 1000
368-
elif isinstance(satoshis, int):
369-
satoshis = Decimal(satoshis) / 1000
365+
def formatMilliSatsForEditing(self, msatoshis):
366+
if isinstance(msatoshis, QEAmount):
367+
satoshis = Decimal(msatoshis.msatsInt) / 1000
368+
elif isinstance(msatoshis, int):
369+
satoshis = Decimal(msatoshis) / 1000
370370

371371
precision = 3 # config.amt_precision_post_satoshi is not exposed in preferences
372372
return self.config.format_amount(
@@ -380,8 +380,6 @@ def formatMilliSatsForEditing(self, satoshis):
380380
@pyqtSlot(QEAmount, result=str)
381381
@pyqtSlot(QEAmount, bool, result=str)
382382
def formatSats(self, satoshis, with_unit=False):
383-
if satoshis is None:
384-
return ''
385383
if isinstance(satoshis, QEAmount):
386384
satoshis = satoshis.satsInt
387385
if with_unit:
@@ -394,8 +392,6 @@ def formatSats(self, satoshis, with_unit=False):
394392
@pyqtSlot(QEAmount, result=str)
395393
@pyqtSlot(QEAmount, bool, result=str)
396394
def formatMilliSats(self, amount, with_unit=False):
397-
if amount is None:
398-
return ''
399395
if isinstance(amount, QEAmount):
400396
msats = amount.msatsInt
401397
elif isinstance(amount, int):

electrum/gui/qml/qefx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def satoshiValue(self, fiat):
161161
return ''
162162
v = fd / Decimal(rate) * COIN
163163
if not v.is_nan():
164-
self._amount.satsInt = v.to_integral_value()
164+
self._amount.satsInt = int(v.to_integral_value())
165165
return self._amount
166166

167167
@pyqtSlot(str, result=bool)

electrum/gui/qml/qetypes.py

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,28 +54,30 @@ def _msat_to_sat(self, amount_msat: int | None) -> int | None:
5454
return int(Decimal(amount_msat) / 1000) if amount_msat is not None else None
5555

5656
@pyqtProperty('qint64', notify=valueChanged)
57-
def satsInt(self):
57+
def satsInt(self) -> int:
5858
if self._amount_msat is None: # should normally be defined when accessing this property
5959
self._logger.warning('amount_msat is undefined, returning 0')
6060
return 0
6161
return self._msat_to_sat(self._amount_msat)
6262

6363
@satsInt.setter
64-
def satsInt(self, sats):
64+
def satsInt(self, sats: int):
65+
assert sats is None or isinstance(sats, int), 'sats must be int or None'
6566
msats = self._sat_to_msat(sats)
6667
if self._amount_msat != msats:
6768
self._amount_msat = msats
6869
self.valueChanged.emit()
6970

7071
@pyqtProperty('qint64', notify=valueChanged)
71-
def msatsInt(self):
72+
def msatsInt(self) -> int:
7273
if self._amount_msat is None: # should normally be defined when accessing this property
7374
self._logger.warning('amount_msat is undefined, returning 0')
7475
return 0
7576
return self._amount_msat
7677

7778
@msatsInt.setter
78-
def msatsInt(self, msats):
79+
def msatsInt(self, msats: int):
80+
assert msats is None or isinstance(msats, int), 'msats must be int or None'
7981
if self._amount_msat != msats:
8082
self._amount_msat = msats
8183
self.valueChanged.emit()
@@ -137,8 +139,7 @@ def lt(self, other: 'QEAmount|None') -> bool:
137139
if other is None:
138140
other = QEAmount()
139141
assert isinstance(other, QEAmount)
140-
if self.isMax or other.isMax:
141-
return False
142+
assert not (self.isMax or other.isMax), "'lt/lte' operator undefined for MAX amounts"
142143
if self.isEmpty and not other.isEmpty:
143144
return True
144145
return self.msatsInt < other.msatsInt
@@ -152,8 +153,7 @@ def gt(self, other: 'QEAmount|None') -> bool:
152153
if other is None:
153154
other = QEAmount()
154155
assert isinstance(other, QEAmount)
155-
if self.isMax or other.isMax:
156-
return False
156+
assert not (self.isMax or other.isMax), "'gt/gte' operator undefined for MAX amounts"
157157
if self.isEmpty and not other.isEmpty:
158158
return False
159159
return self.msatsInt > other.msatsInt
@@ -174,6 +174,13 @@ def max(self, one: 'QEAmount|None', two: 'QEAmount|None'):
174174
two = QEAmount()
175175
assert isinstance(one, QEAmount)
176176
assert isinstance(two, QEAmount)
177+
# TODO: as gt/lt is undefined for operands being isMax, we can either
178+
# - raise (let the GUI avoid comparisons against MAX)
179+
# - define MAX as always being larger than any value
180+
if one.isMax:
181+
return one
182+
if two.isMax:
183+
return two
177184
return one if one.gt(two) else two
178185

179186
@pyqtSlot('QVariant', 'QVariant', result='QVariant')
@@ -184,23 +191,30 @@ def min(self, one: 'QEAmount|None', two: 'QEAmount|None'):
184191
two = QEAmount()
185192
assert isinstance(one, QEAmount)
186193
assert isinstance(two, QEAmount)
194+
# TODO: as gt/lt is undefined for operands being isMax, we can either
195+
# - raise (let the GUI avoid comparisons against MAX)
196+
# - define MAX as always being larger than any value
197+
if one.isMax:
198+
return two
199+
if two.isMax:
200+
return one
187201
return one if one.lt(two) else two
188202

189-
def __eq__(self, other):
190-
if isinstance(other, QEAmount):
191-
return self._amount_msat == other._amount_msat and self._is_max == other._is_max
192-
elif isinstance(other, int):
193-
return self._amount_msat == other
203+
def __eq__(self, other: 'QEAmount') -> bool:
204+
assert True if other is None else isinstance(other, QEAmount)
194205

195-
return False
206+
if other is None:
207+
return False
196208

197-
def __str__(self):
209+
return self._amount_msat == other._amount_msat and self._is_max == other._is_max
210+
211+
def __str__(self) -> str:
198212
s = _('Amount')
199213
if self._is_max:
200214
return '%s(MAX)' % s
201215
return '%s(sats=%s, msats=%s)' % (s, str(self._msat_to_sat(self._amount_msat)), str(self._amount_msat))
202216

203-
def __repr__(self):
217+
def __repr__(self) -> str:
204218
return f"<QEAmount max={self._is_max} sats={self._msat_to_sat(self._amount_msat)} msats={self._amount_msat} empty={self.isEmpty}>"
205219

206220

electrum/gui/qml/qewallet.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,9 +703,13 @@ def createRequest(self, amount: QEAmount, message: str, expiration: int, lightni
703703
addr = None
704704

705705
if lightning:
706-
key = self.wallet.create_request(amount_msat=amount.msatsInt, message=message, exp_delay=expiration)
706+
amount_msat = None if amount.msatsInt == 0 else amount.msatsInt
707+
key = self.wallet.create_request(amount_msat=amount_msat, message=message, exp_delay=expiration)
707708
else:
708-
key = self.wallet.create_request(amount_sat=amount.satsInt, message=message, exp_delay=expiration, address=addr)
709+
amount_sat = None if amount.satsInt == 0 else amount.satsInt
710+
# GUI should not allow msat precision, but assert here to be sure
711+
assert amount.satsInt * 1000 == amount.msatsInt, 'onchain createRequest should not have msat precision'
712+
key = self.wallet.create_request(amount_sat=amount_sat, message=message, exp_delay=expiration, address=addr)
709713
except InvoiceError as e:
710714
self.requestCreateError.emit(_('Error creating payment request') + ':\n' + str(e))
711715
return

electrum/gui/qt/amountedit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def _get_text_from_amount(self, amount) -> str:
121121
return text
122122

123123
def setAmount(self, amount):
124-
text = self._get_text_from_amount(amount)
124+
text = self._get_text_from_amount(amount) if amount is not None else " "
125125
self.setText(text)
126126

127127

electrum/payment_identifier.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ async def _do_finalize(
389389
if not self.lnurl_data:
390390
raise Exception("Unexpected missing LNURL data")
391391

392-
amount_msat = amount_sat * 1000
392+
amount_msat = int(amount_sat * 1000)
393393
if not (self.lnurl_data.min_sendable_msat <= amount_msat <= self.lnurl_data.max_sendable_msat):
394394
self.error = _('Amount must be between {} and {} sat.').format(
395395
Decimal(self.lnurl_data.min_sendable_msat) / 1000,

electrum/wallet.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3038,13 +3038,15 @@ def create_request(
30383038
elif amount_sat is not None:
30393039
assert isinstance(amount_sat, int), f"{amount_msat!r}"
30403040
amount_msat = amount_sat * 1000
3041-
else:
3042-
amount_msat = None
30433041

30443042
message = message or ''
30453043
address = address or None # converts "" to None
30463044
exp_delay = exp_delay or 0
30473045
timestamp = int(Request._get_cur_time())
3046+
payment_hash = None
3047+
outputs = []
3048+
3049+
# lightning/onchain
30483050
if address is None:
30493051
assert self.has_lightning()
30503052
payment_hash = self.lnworker.create_payment_info(
@@ -3053,8 +3055,9 @@ def create_request(
30533055
write_to_disk=False,
30543056
)
30553057
else:
3056-
payment_hash = None
3057-
outputs = [PartialTxOutput.from_address_and_value(address, amount_sat)] if address else []
3058+
amount_sat = 0 if amount_sat is None else amount_sat
3059+
outputs = [PartialTxOutput.from_address_and_value(address, amount_sat)]
3060+
30583061
height = self.adb.get_local_height()
30593062
req = Request(
30603063
outputs=outputs,

tests/qml/test_qml_types.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,14 @@ def test_lt_gt_eq(self):
186186

187187
d = QEAmount(is_max=True)
188188

189-
self.assertFalse(d.lt(a))
190-
self.assertFalse(d.gt(a))
191-
self.assertFalse(a.lt(d))
192-
self.assertFalse(a.gt(d))
189+
with self.assertRaises(AssertionError):
190+
d.lt(a)
191+
with self.assertRaises(AssertionError):
192+
d.gt(a)
193+
with self.assertRaises(AssertionError):
194+
a.lt(d)
195+
with self.assertRaises(AssertionError):
196+
a.gt(d)
193197

194198
e = QEAmount(amount_msat=200)
195199
self.assertTrue(e.lte(b))

0 commit comments

Comments
 (0)