Add static receive code configuration option, fix uniqueness and sorting, fix lnbits websocket connection

This commit is contained in:
Thomas Farstrike
2025-05-30 21:39:30 +02:00
parent db925ce9fb
commit df3d685790
2 changed files with 34 additions and 28 deletions
@@ -10,6 +10,7 @@ main_screen = None
settings_screen = None
# widgets
receive_qr = None
balance_label = None
payments_label = None
@@ -25,6 +26,7 @@ class SettingsScreen():
{"title": "LNBits URL", "key": "lnbits_url", "value_label": None},
{"title": "LNBits Read/Invoice Key", "key": "lnbits_readkey", "value_label": None},
{"title": "NWC URL", "key": "nwc_url", "value_label": None},
{"title": "Static receive code", "key": "static_receive_code", "value_label": None},
]
self.keyboard = None
self.textarea = None
@@ -192,7 +194,7 @@ def settings_button_tap(event):
mpos.ui.load_screen(settings_screen)
def build_main_ui():
global main_screen, balance_label, payments_label
global main_screen, balance_label, payments_label, receive_qr
main_screen = lv.obj()
main_screen.set_style_pad_all(10, 0)
balance_label = lv.label(main_screen)
@@ -203,7 +205,6 @@ def build_main_ui():
receive_qr.set_size(50)
receive_qr.set_dark_color(lv.color_black())
receive_qr.set_light_color(lv.color_white())
receive_qr.update("tfar@getalby.com", len("tfar@getalby.com"))
receive_qr.align(lv.ALIGN.TOP_RIGHT,0,0)
receive_qr.set_style_border_color(lv.color_white(), 0)
receive_qr.set_style_border_width(3, 0);
@@ -242,6 +243,9 @@ def janitor_cb(timer):
if lv.screen_active() == main_screen and (not wallet or not wallet.is_running()):
# just started the app or just returned from settings_screen
config = mpos.config.SharedPreferences("com.lightningpiggy.displaywallet")
static_receive_code = config.get_string("static_receive_code")
if static_receive_code:
receive_qr.update(static_receive_code, len(static_receive_code))
wallet_type = config.get_string("wallet_type")
if wallet_type == "lnbits":
try:
@@ -10,6 +10,8 @@ from nostr.filter import Filter, Filters
from nostr.event import EncryptedDirectMessage
from nostr.key import PrivateKey
from websocket import WebSocketApp
import mpos.apps
import mpos.time
import mpos.util
@@ -22,6 +24,7 @@ class UniqueSortedList:
self._items = []
def add(self, item):
print(f"before add: {str(self)}")
# Check if item already exists (using __eq__)
if item not in self._items:
# Insert item in sorted position for descending order (using __gt__)
@@ -31,6 +34,7 @@ class UniqueSortedList:
return
# If item is smaller than all existing items, append it
self._items.append(item)
print(f"after add: {str(self)}")
def __iter__(self):
# Return iterator for the internal list
@@ -67,13 +71,13 @@ class Payment:
sattext = "sats"
if self.amount_sats == 1:
sattext = "sat"
return f"{self.amount_sats} {sattext}: {self.comment}"
return f"{self.amount_sats} {sattext} @ {self.epoch_time}: {self.comment}"
def __eq__(self, other):
if not isinstance(other, Payment):
return False
return self.epoch_time == other.epoch_time and self.amount_sats == other.amount_sats and self.comment == other.comment
'''
def __lt__(self, other):
if not isinstance(other, Payment):
return NotImplemented
@@ -83,27 +87,29 @@ class Payment:
if not isinstance(other, Payment):
return NotImplemented
return (self.epoch_time, self.amount_sats, self.comment) <= (other.epoch_time, other.amount_sats, other.comment)
'''
def __gt__(self, other):
if not isinstance(other, Payment):
return NotImplemented
return (self.epoch_time, self.amount_sats, self.comment) > (other.epoch_time, other.amount_sats, other.comment)
#return (self.epoch_time, self.amount_sats, self.comment) > (other.epoch_time, other.amount_sats, other.comment)
return self.epoch_time > other.epoch_time
'''
def __ge__(self, other):
if not isinstance(other, Payment):
return NotImplemented
return (self.epoch_time, self.amount_sats, self.comment) >= (other.epoch_time, other.amount_sats, other.comment)
'''
class Wallet:
# These values could be loading from a cache.json file at __init__
last_known_balance = -1
#last_known_balance_timestamp = 0
payment_list = UniqueSortedList()
payment_list = None
def __init__(self):
self.keep_running = True
self.payment_list = UniqueSortedList()
def __str__(self):
if isinstance(self, LNBitsWallet):
@@ -165,14 +171,14 @@ class LNBitsWallet(Wallet):
amount = round(amount / 1000)
comment = transaction["memo"]
epoch_time = transaction["time"]
extra = transaction["extra"]
if extra:
extracomment = extra["comment"]
if extracomment:
if extracomment.get(0): # some LNBits 0.x versions return a list instead of a string here...
comment = extracomment.get(0)
else:
comment = extracomment
try:
extra = transaction.get("extra")
if extra:
comment = extra.get("comment")
first_from_list = comment.get(0) # some LNBits 0.x versions return a list instead of a string here...
comment = first_from_list
except Exception as e:
pass
return Payment(epoch_time, amount, comment)
# Example data: {"wallet_balance": 4936, "payment": {"checking_id": "037c14...56b3", "pending": false, "amount": 1000000, "fee": 0, "memo": "zap2oink", "time": 1711226003, "bolt11": "lnbc10u1pjl70y....qq9renr", "preimage": "0000...000", "payment_hash": "037c1438b20ef4729b1d3dc252c2809dc2a2a2e641c7fb99fe4324e182f356b3", "expiry": 1711226603.0, "extra": {"tag": "lnurlp", "link": "TkjgaB", "extra": "1000000", "comment": ["yes"], "lnaddress": "oink@demo.lnpiggy.com"}, "wallet_id": "c9168...8de4", "webhook": null, "webhook_status": null}}
@@ -185,7 +191,7 @@ class LNBitsWallet(Wallet):
self.handle_new_balance(new_balance, False) # handle new balance BUT don't trigger a full fetch_payments
transaction = payment_notification.get("payment")
print(f"Got transaction: {transaction}")
paymentObj = parseLNBitsPayment(transaction)
paymentObj = self.parseLNBitsPayment(transaction)
self.handle_new_payment(paymentObj)
except Exception as e:
print(f"websocket on_message got exception: {e}")
@@ -193,17 +199,13 @@ class LNBitsWallet(Wallet):
def websocket_thread(self):
print("Opening websocket for payment notifications...")
wsurl = self.lnbits_url + "/api/v1/ws/" + self.lnbits_readkey
wsurl = wsurl.replace("https://", "wss://")
wsurl = wsurl.replace("http://", "ws://")
self.ws = WebSocketApp(
wsurl,
on_message=self.on_message,
) # maybe add other callbacks to reconnect when disconnected etc.
self.ws.run_forever(
sslopt=ssl_options,
http_proxy_host=None if proxy is None else proxy.get("host"),
http_proxy_port=None if proxy is None else proxy.get("port"),
proxy_type=None if proxy is None else proxy.get("type"),
ping_interval=5
)
self.ws.run_forever()
def wallet_manager_thread(self):
@@ -261,10 +263,10 @@ class LNBitsWallet(Wallet):
response.close()
try:
payments_reply = json.loads(response_text)
#print(f"Got payments: {payments_reply}")
print(f"Got payments: {payments_reply}")
for transaction in payments_reply:
#print(f"Got transaction: {transaction}")
paymentObj = parseLNBitsPayment(transaction)
print(f"Got transaction: {transaction}")
paymentObj = self.parseLNBitsPayment(transaction)
self.handle_new_payment(paymentObj)
except Exception as e:
print(f"Could not parse reponse text '{response_text}' as JSON: {e}")