internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: raspiblitz/raspiblitz

Issue:
Move BlitzTUI log to RAM disk
The RAM disk (`/var/cache/raspiblitz/`) is a nice way to avoid reads and writes to either the SD card or the external disk for non-persistent data. Several things can be moved; the BlitzTUI log should be  a prime example.


Discussion:

Resolving patch:
diff --git a/home.admin/BlitzTUI/blitztui/file_logger.py b/home.admin/BlitzTUI/blitztui/file_logger.py
--- a/home.admin/BlitzTUI/blitztui/file_logger.py
+++ b/home.admin/BlitzTUI/blitztui/file_logger.py
@@ -1,3 +1,4 @@
+import getpass
 import json
 import logging
 import logging.config
@@ -20,7 +21,14 @@ def setup_logging(default_path=os.path.abspath(os.path.expanduser('~/.blitz-tui.
         if IS_WIN32_ENV:
             log_file = "blitz-tui.log"
         else:
-            log_file = os.path.abspath(os.path.expanduser('~/blitz-tui.log'))
+            if os.path.isdir('/var/cache/raspiblitz'):
+                try:
+                    os.mkdir('/var/cache/raspiblitz/{}'.format(getpass.getuser()))
+                except FileExistsError:
+                    pass
+                log_file = os.path.abspath('/var/cache/raspiblitz/{}/blitz-tui.log'.format(getpass.getuser()))
+            else:
+                log_file = os.path.abspath(os.path.expanduser('~/blitz-tui.log'))
 
         default_config_as_dict = dict(
             version=1,
@@ -36,8 +44,8 @@ def setup_logging(default_path=os.path.abspath(os.path.expanduser('~/.blitz-tui.
                                        'level': log_level,
                                        'formatter': 'extended',
                                        'filename': log_file,
-                                       'maxBytes': 10485760,
-                                       'backupCount': 0,
+                                       'maxBytes': 2*1024*1024,  # 2 MB
+                                       'backupCount': 1,
                                        'encoding': 'utf8'}},
             loggers={'infoblitz': {'level': 'DEBUG',
                                    'handlers': ['console', 'file_handler'],
diff --git a/home.admin/BlitzTUI/blitztui/version.py b/home.admin/BlitzTUI/blitztui/version.py
--- a/home.admin/BlitzTUI/blitztui/version.py
+++ b/home.admin/BlitzTUI/blitztui/version.py
@@ -4,5 +4,5 @@
 # 3) we can import it into your module module
 """
 
-__version_info__ = ('0', '47', '0')
+__version_info__ = ('0', '48', '1')
 __version__ = '.'.join(__version_info__)


Test patch:
Repository: raspiblitz/raspiblitz

Issue:
RC1 only allow one letsencrypt subscription at a time
On my test machine I had two letsencrypt domains that were messing up after a recovery. Best would be to allow just one letsencrypt at a time at the moment.


Discussion:

Resolving patch:
diff --git a/home.admin/config.scripts/blitz.subscriptions.letsencrypt.py b/home.admin/config.scripts/blitz.subscriptions.letsencrypt.py
--- a/home.admin/config.scripts/blitz.subscriptions.letsencrypt.py
+++ b/home.admin/config.scripts/blitz.subscriptions.letsencrypt.py
@@ -208,6 +208,15 @@ def dynu_update(domain, token, ip):
 #####################
 
 def subscriptions_new(ip, dnsservice, domain, token, target):
+
+    # check if already one subscrption exists (limit to just one)
+    # https://github.com/rootzoll/raspiblitz/issues/1786
+    if Path(SUBSCRIPTIONS_FILE).is_file():
+        subs = toml.load(SUBSCRIPTIONS_FILE)
+        if "subscriptions_letsencrypt" in subs:
+            if len(subs['subscriptions_letsencrypt']) > 0:
+                raise BlitzError("not more than one letsencrypt subscription", "cancel existing letsencrypt first")
+
     # domain needs to be the full domain name
     if domain.find(".") == -1:
         raise BlitzError("not a fully qualified domain name", domain)


Test patch:
Repository: raspiblitz/raspiblitz

Issue:
Improve 'headless' Mode
![headlessRaspiblitz](https://user-images.githubusercontent.com/23216537/113026767-6786c580-9157-11eb-8ff0-b3b85a011e28.jpg)
Hey Blitzy Folk!
I assembled and configured my lovely Raspiblitz and it's working AWESOMELY.  I asked it to run tor, Electrum Rust server, and the BTC RPC Explorer with no problems.  
I can SSH into it with nary a glitch so I took off the LCD.  Everything is running smoothly so I decided to venture off the map into RasbiBlitz Commandline.  I looked at a script "00infoLCD.sh" it had comments about headless CPU/log clutter, just add the line "headless=on" into /mnt/hdd/raspiblitz.conf , so I added the line to the file and rebooted.  Everything is still working but the info screen still updates every 20 seconds or so.
![raspiCovered](https://user-images.githubusercontent.com/23216537/113029526-86d32200-915a-11eb-9e69-dab783dbd833.png)



Discussion:
Good you are interested in what is running, very nice.
About the update, maintain the default time, there is no problem in that... but if you want to let more time pass for each update, add `sleep 30` (unit is seconds) here https://github.com/rootzoll/raspiblitz/blob/755b7460ca7d8f6aa614748e534ec0941fc891ea/home.admin/00infoBlitz.sh#L306 or here
https://github.com/rootzoll/raspiblitz/blob/755b7460ca7d8f6aa614748e534ec0941fc891ea/home.admin/00mainMenu.sh#L176
I advert this will not improve anything.

I can see that cat looking deep into my eyes.
Oh, the main menu script!  I've been looking for that, Thanks Ben10Brasileiro.

Resolving patch:
diff --git a/home.admin/config.scripts/blitz.gpio.py b/home.admin/config.scripts/blitz.gpio.py
new file mode 100644
--- /dev/null
+++ b/home.admin/config.scripts/blitz.gpio.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import sys
+import RPi.GPIO as GPIO
+
+if len(sys.argv) <= 2 or sys.argv[1] in ["-h", "--help", "help"]:
+    print ("# IMPORTANT: call with SUDO")
+    print ("# read inputs on raspberryPi GPIO pins")
+    print ("# blitz.gpio.py in [pinnumber]")
+    print ("err='missing parameters'")
+    sys.exit(1)
+
+if sys.argv[2].isdigit() and int(sys.argv[2])>0 and int(sys.argv[2])<=40:
+    GPIO.setmode(GPIO.BCM)
+    GPIO.setup(int(sys.argv[2]),GPIO.IN)
+    print ("pinValue", end="=")
+    print (GPIO.input(int(sys.argv[2])))
+    GPIO.cleanup()
+else:
+    print ("err='not a valid pin number between 1 and 40'")
+    sys.exit(1)
\ No newline at end of file


Test patch:
Repository: raspiblitz/raspiblitz

Issue:
notifyme no longer works
Just noticed that the sstmp package is no longer included in the updated base image.

```
admin@raspberrypi:~ $ sudo apt install ssmtp
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package ssmtp is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'ssmtp' has no installation candidate
```

Need to find an simple alternative.


Discussion:

Resolving patch:
diff --git a/home.admin/XXsendNotification.py b/home.admin/XXsendNotification.py
--- a/home.admin/XXsendNotification.py
+++ b/home.admin/XXsendNotification.py
@@ -11,7 +11,7 @@
 except ImportError:
     raise ImportError("Please install missing package: python3 -m pip install smime")
 
-SSMTP_BIN = "/usr/sbin/ssmtp"
+SMTP_BIN = "/usr/bin/msmtp"
 
 
 def main():
@@ -107,7 +107,7 @@ def mail(recipient: str = None, message: str = None, subject: str = None, cert:
             'From: {} <{}>'.format(from_name, from_address),
             "Subject: {}".format(subject),
             "",
-            "{}".format(message.encode('utf8'))
+            "{}".format(message)
         ]
 
         with open(cert, 'rb') as pem:
@@ -126,11 +126,11 @@ def mail(recipient: str = None, message: str = None, subject: str = None, cert:
         msg_to_send = msg.as_bytes()
 
     # send message via e-Mail
-    if not os.path.exists(SSMTP_BIN):
-        raise Exception("File not found: {}".format(SSMTP_BIN))
+    if not os.path.exists(SMTP_BIN):
+        raise Exception("File not found: {}".format(SMTP_BIN))
 
     try:
-        cmd = [SSMTP_BIN, recipient]
+        cmd = [SMTP_BIN, recipient]
         subprocess.run(cmd, input=msg_to_send, stderr=subprocess.STDOUT)
 
     except subprocess.CalledProcessError as err:


Test patch:
Repository: raspiblitz/raspiblitz

Issue:
LNBits - wrong github reference
I installed LNBits on my raspi but noticed a lot of new extensions didn't get installed.

It seems like LNBits development has moved to this repo "https://github.com/lnbits/lnbits-legend"

https://github.com/rootzoll/raspiblitz/blob/a500cc7cf2727f9cf1c587fcca8307b72e9c4f66/home.admin/config.scripts/bonus.lnbits.sh#L264


Discussion:

Resolving patch:
diff --git a/home.admin/config.scripts/blitz.subscriptions.ip2tor.py b/home.admin/config.scripts/blitz.subscriptions.ip2tor.py
--- a/home.admin/config.scripts/blitz.subscriptions.ip2tor.py
+++ b/home.admin/config.scripts/blitz.subscriptions.ip2tor.py
@@ -613,7 +613,7 @@ def menuMakeSubscription(blitzServiceName, torAddress, torPort):
         d = Dialog(dialog="dialog", autowidgetsize=True)
         d.set_background_title("Select IP2TOR Bridge Shop (communication secured thru TOR)")
         code, text = d.inputbox(
-            "Enter Address of a IP2TOR Shop (OR JUST USE DEFAULT):",
+            "Enter Address of the IP2TOR Shop (OR JUST PRESS OK):",
             height=10, width=72, init=shopurl,
             title="Shop Address")
 
@@ -1079,6 +1079,7 @@ def subscription_by_service():
             subs = toml.load(SUBSCRIPTIONS_FILE)
             for idx, sub in enumerate(subs['subscriptions_ip2tor']):
                 if sub['active'] and sub['name'] == service_name:
+                    print("id='{0}'".format(sub['id']))
                     print("type='{0}'".format(sub['type']))
                     print("ip='{0}'".format(sub['ip']))
                     print("port='{0}'".format(sub['port']))


Test patch:
Repository: raspiblitz/raspiblitz

Issue:
IP2Tor disable or revive?
The IP2Tor service provided by FULMO is not working correctly and will not be continued. Thats wy the following issues were reported:

- [x] #2247
- [x] #3335
- [x] #3417

There is some commitment by the community to setup a new instance of this service .- but we have to see if that will be ready for v1.9.0 or in that version the IP2Tor gets deactivated for now. 


Discussion:

Resolving patch:
diff --git a/home.admin/config.scripts/blitz.subscriptions.py b/home.admin/config.scripts/blitz.subscriptions.py
--- a/home.admin/config.scripts/blitz.subscriptions.py
+++ b/home.admin/config.scripts/blitz.subscriptions.py
@@ -225,7 +225,7 @@ def main():
 
     choices = list()
     choices.append(("LIST", "My Subscriptions"))
-    choices.append(("NEW1", "+ IP2TOR Bridge (paid)"))
+    #choices.append(("NEW1", "+ IP2TOR Bridge (paid)"))
     choices.append(("NEW2", "+ LetsEncrypt HTTPS Domain (free)"))
 
     d = Dialog(dialog="dialog", autowidgetsize=True)


Test patch:
Repository: raspiblitz/raspiblitz

Issue:
Recheck DuckDNS
![duckdns](https://github.com/raspiblitz/raspiblitz/assets/2472225/cef21950-15e1-4f1b-b74c-d5b86a6a68f0)



Discussion:
![Bildschirmfoto vom 2024-04-18 22-16-23](https://github.com/raspiblitz/raspiblitz/assets/152734664/7cf86970-6051-4b67-af7b-4b9b4306344f)

Also recheck #2255 when on this

Resolving patch:
diff --git a/home.admin/config.scripts/blitz.subscriptions.ip2tor.py b/home.admin/config.scripts/blitz.subscriptions.ip2tor.py
--- a/home.admin/config.scripts/blitz.subscriptions.ip2tor.py
+++ b/home.admin/config.scripts/blitz.subscriptions.ip2tor.py
@@ -622,9 +622,9 @@ def menuMakeSubscription(blitzServiceName, torAddress, torPort):
         if lastusedShop == choice_url_ip2torcom: lastusedShop="" 
 
         # FULMO Shop
-        choice_url_fulmo="fulmo7x6yvgz6zs2b2ptduvzwevxmizhq23klkenslt5drxx2physlqd.onion"
-        choices.append(("B", "Fulmo Shop"))
-        if lastusedShop == choice_url_fulmo: lastusedShop="" 
+        #choice_url_fulmo="fulmo7x6yvgz6zs2b2ptduvzwevxmizhq23klkenslt5drxx2physlqd.onion"
+        #choices.append(("B", "Fulmo Shop"))
+        #if lastusedShop == choice_url_fulmo: lastusedShop="" 
 
         # add before option if different from static options
         if len(lastusedShop) > 0: choices.append(("Y", lastusedShop))
diff --git a/home.admin/config.scripts/blitz.subscriptions.letsencrypt.py b/home.admin/config.scripts/blitz.subscriptions.letsencrypt.py
--- a/home.admin/config.scripts/blitz.subscriptions.letsencrypt.py
+++ b/home.admin/config.scripts/blitz.subscriptions.letsencrypt.py
@@ -334,8 +334,10 @@ def subscriptions_cancel(s_id):
 
     print(json.dumps(subs, indent=2))
 
-    # todo: deinstall letsencrypt if this was last subscription
-
+    # deinstall letsencrypt/dyndns if this was last subscription
+    if len(subs['subscriptions_letsencrypt']) == 0:
+        os.system("/home/admin/config.scripts/bonus.letsencrypt.sh off")
+        os.system("/home/admin/config.scripts/internet.dyndomain.sh off")
 
 def get_subscription(subscription_id):
     try:
diff --git a/home.admin/config.scripts/blitz.subscriptions.py b/home.admin/config.scripts/blitz.subscriptions.py
--- a/home.admin/config.scripts/blitz.subscriptions.py
+++ b/home.admin/config.scripts/blitz.subscriptions.py
@@ -268,8 +268,8 @@ def main():
         cfg.reload()
         if not cfg.run_behind_tor.value:
             Dialog(dialog="dialog", autowidgetsize=True).msgbox('''
-    The IP2TOR service just makes sense if you run
-    your RaspiBlitz behind TOR.
+    The IP2TOR service just makes sense if you
+    run your RaspiBlitz behind TOR.
             ''', title="Info")
             sys.exit(0)
 


Test patch:
Repository: lnbits/lnbits

Issue:
LNURLp links give errors on WalletofSatoshi and BlueWallet
Using this LNURLp link: https://lnbits.com/lnurlp/212

BlueWallet Error: "Alert: Bad response from server"
Wallet of Satoshi Error: "Error: Could not complete payment, please try again."


Discussion:
Same 
This is not related to walletofsatoshi or bluewallet.

It looks like an error on your Success URL set up for that LNURLp.

Check below the Success URL field.

What did you put on your Success URL field?

It needs to start with https://.....

![image](https://user-images.githubusercontent.com/6444444/119782921-1b2fdb80-bea3-11eb-833a-75e9d3b0ee60.png)


Resolving patch:
diff --git a/lnbits/extensions/lnurlp/views_api.py b/lnbits/extensions/lnurlp/views_api.py
--- a/lnbits/extensions/lnurlp/views_api.py
+++ b/lnbits/extensions/lnurlp/views_api.py
@@ -87,6 +87,9 @@ async def api_link_create_or_update(link_id=None):
         round(g.data["min"]) != g.data["min"] or round(g.data["max"]) != g.data["max"]
     ):
         return jsonify({"message": "Must use full satoshis."}), HTTPStatus.BAD_REQUEST
+    
+    if g.data["success_url"][:8] != "https://":
+        return jsonify({"message": "Success URL must be secure https://..."}), HTTPStatus.BAD_REQUEST
 
     if link_id:
         link = await get_pay_link(link_id)


Test patch:
Repository: lnbits/lnbits

Issue:
No success message and URL returned with LNURLp links
As the title says, the neither the URL, nor the message are returned to the wallet making the payment. This used to work when I was still on the [latest `raspiblitz` tag](https://github.com/lnbits/lnbits/releases/tag/raspiblitz). Now on [this commit](https://github.com/lnbits/lnbits/commit/7ab4553ef5083f6746bd6fe747775ba57e2e54a4) (the issue could have appeared during any of the commits in between), it has stopped working, even on newly created LNURLp links.
Edit: Reproducible on lnbits.com


Discussion:
To reproduce: Go to [lnbits.com](https://lnbits.com), activate the LNURLp extension, and create a link with a success message and URL. Pay to this link with any wallet that supports it. No success message or URL will be reported back to the wallet.

Resolving patch:
diff --git a/lnbits/extensions/lnurlp/lnurl.py b/lnbits/extensions/lnurlp/lnurl.py
--- a/lnbits/extensions/lnurlp/lnurl.py
+++ b/lnbits/extensions/lnurlp/lnurl.py
@@ -95,13 +95,17 @@ async def api_lnurl_callback(link_id):
         extra={"tag": "lnurlp", "link": link.id, "comment": comment},
     )
 
-    resp = {
-        "routes": [],
-        "pr": payment_request,
-    }
-
     success_action = link.success_action(payment_hash)
     if success_action:
-        resp["success_action"] = success_action
+        resp = LnurlPayActionResponse(
+            pr=payment_request,
+            success_action=success_action,
+            routes=[],
+        )
+    else:
+        resp = LnurlPayActionResponse(
+            pr=payment_request,
+            routes=[],
+        )
 
-    return jsonify(resp), HTTPStatus.OK
+    return jsonify(resp.dict()), HTTPStatus.OK


Test patch:
Repository: lnbits/lnbits

Issue:
Send webhooks for internal payments as well
Webhooks only work for external incoming payments but not for internal ones. 


Discussion:

Resolving patch:
diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py
--- a/lnbits/core/crud.py
+++ b/lnbits/core/crud.py
@@ -180,13 +180,18 @@ async def get_wallet_for_key(
 
 
 async def get_standalone_payment(
-    checking_id_or_hash: str, conn: Optional[Connection] = None
+    checking_id_or_hash: str,
+    conn: Optional[Connection] = None,
+    incoming: Optional[bool] = False,
 ) -> Optional[Payment]:
+    clause: str = "checking_id = ? OR hash = ?"
+    if incoming:
+        clause = f"({clause}) AND amount > 0"
     row = await (conn or db).fetchone(
-        """
+        f"""
         SELECT *
         FROM apipayments
-        WHERE checking_id = ? OR hash = ?
+        WHERE {clause}
         LIMIT 1
         """,
         (checking_id_or_hash, checking_id_or_hash),
diff --git a/lnbits/tasks.py b/lnbits/tasks.py
--- a/lnbits/tasks.py
+++ b/lnbits/tasks.py
@@ -114,7 +114,7 @@ async def perform_balance_checks():
 
 
 async def invoice_callback_dispatcher(checking_id: str):
-    payment = await get_standalone_payment(checking_id)
+    payment = await get_standalone_payment(checking_id, incoming=True)
     if payment and payment.is_in:
         await payment.set_pending(False)
         for send_chan in invoice_listeners:


Test patch:
Repository: lnbits/lnbits

Issue:
LNURLp: Edit existing LNURLP from sat to fiat currency unintentionally divides value by 100 
Reproduce: 
* Create 100 sat link, save
* Edit link, change price to 5€, save
* Observe that amount is now 0.05€ instead of 5€

Most likely cause by PR #663 


Discussion:

Resolving patch:
diff --git a/lnbits/extensions/lnurlp/crud.py b/lnbits/extensions/lnurlp/crud.py
--- a/lnbits/extensions/lnurlp/crud.py
+++ b/lnbits/extensions/lnurlp/crud.py
@@ -9,11 +9,6 @@ async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:
 
     returning = "" if db.type == SQLITE else "RETURNING ID"
     method = db.execute if db.type == SQLITE else db.fetchone
-    # database only allows int4 entries for min and max. For fiat currencies,
-    # we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents.
-    if data.currency and data.fiat_base_multiplier:
-        data.min *= data.fiat_base_multiplier
-        data.max *= data.fiat_base_multiplier
 
     result = await (method)(
         f"""
diff --git a/lnbits/extensions/lnurlp/views_api.py b/lnbits/extensions/lnurlp/views_api.py
--- a/lnbits/extensions/lnurlp/views_api.py
+++ b/lnbits/extensions/lnurlp/views_api.py
@@ -89,6 +89,12 @@ async def api_link_create_or_update(
             detail="Must use full satoshis.", status_code=HTTPStatus.BAD_REQUEST
         )
 
+    # database only allows int4 entries for min and max. For fiat currencies,
+    # we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents.
+    if data.currency and data.fiat_base_multiplier:
+        data.min *= data.fiat_base_multiplier
+        data.max *= data.fiat_base_multiplier
+
     if "success_url" in data and data.success_url[:8] != "https://":
         raise HTTPException(
             detail="Success URL must be secure https://...",


Test patch:
Repository: lnbits/lnbits

Issue:
Split payments shares <1%
Trying to set a payment share <1% will result in 500 INTERNAL SERVER ERROR.
This should work as it would be very useful as a fee for hosting lnbits but 1% is too much.
![grafik](https://user-images.githubusercontent.com/51097237/174864872-55ed946c-ce0a-4dc6-8c90-ec2e70c29f54.png)



Discussion:
probably it only allows integers!

On Tue, Jun 21, 2022, 6:45 PM exitfiat ***@***.***> wrote:

> Trying to set a payment share <1% will result in 500 INTERNAL SERVER ERROR.
> This should work as it would be very useful as a fee for hosting lnbits
> but 1% is too much.
> [image: grafik]
> <https://github.com/assets/51097237/55ed946c-ce0a-4dc6-8c90-ec2e70c29f54>
>
> —
> Reply to this email directly, view it on GitHub
> <https://github.com/lnbits/lnbits-legend/issues/673>, or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AC4F74W5X6UYFUHUTKDB5J3VQH5R3ANCNFSM5ZNEZLIQ>
> .
> You are receiving this because you are subscribed to this thread.Message
> ID: ***@***.***>
>

@talvasconcelos you're right, just looked in the code under models.py it says input type of percentage is int
Pull request in #679 

Resolving patch:
diff --git a/lnbits/extensions/splitpayments/migrations.py b/lnbits/extensions/splitpayments/migrations.py
--- a/lnbits/extensions/splitpayments/migrations.py
+++ b/lnbits/extensions/splitpayments/migrations.py
@@ -14,3 +14,41 @@ async def m001_initial(db):
         );
         """
     )
+
+
+async def m002_float_percent(db):
+    """
+    Add float percent and migrates the existing data.
+    """
+    await db.execute("ALTER TABLE splitpayments.targets RENAME TO splitpayments_old")
+    await db.execute(
+        """
+        CREATE TABLE splitpayments.targets (
+            wallet TEXT NOT NULL,
+            source TEXT NOT NULL,
+            percent REAL NOT NULL CHECK (percent >= 0 AND percent <= 100),
+            alias TEXT,
+
+            UNIQUE (source, wallet)
+        );
+    """
+    )
+
+    for row in [
+        list(row)
+        for row in await db.fetchall("SELECT * FROM splitpayments.splitpayments_old")
+    ]:
+        await db.execute(
+            """
+            INSERT INTO splitpayments.targets (
+                wallet,
+                source,
+                percent,
+                alias
+            )
+            VALUES (?, ?, ?, ?)
+            """,
+            (row[0], row[1], row[2], row[3]),
+        )
+
+    await db.execute("DROP TABLE splitpayments.splitpayments_old")
diff --git a/lnbits/extensions/splitpayments/models.py b/lnbits/extensions/splitpayments/models.py
--- a/lnbits/extensions/splitpayments/models.py
+++ b/lnbits/extensions/splitpayments/models.py
@@ -7,14 +7,14 @@
 class Target(BaseModel):
     wallet: str
     source: str
-    percent: int
+    percent: float
     alias: Optional[str]
 
 
 class TargetPutList(BaseModel):
     wallet: str = Query(...)
     alias: str = Query("")
-    percent: int = Query(..., ge=1)
+    percent: float = Query(..., ge=0.01)
 
 
 class TargetPut(BaseModel):


Test patch:
Repository: lnbits/lnbits

Issue:
Switching to `FakeWallet` deletes pending outgoing payments from another backend.
Needs investigation.

What I observed: create outgoing pending payment from other wallet, stop LNbits, change to `FakeWallet`, start LNbits. 

-> Payments get deleted because of a `failed` state that is returned in `lnbits.core.models:check_pending:148`.


Discussion:

Resolving patch:
diff --git a/lnbits/wallets/fake.py b/lnbits/wallets/fake.py
--- a/lnbits/wallets/fake.py
+++ b/lnbits/wallets/fake.py
@@ -91,10 +91,10 @@ async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse
             )
 
     async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
-        return PaymentStatus(False)
+        return PaymentStatus(None)
 
     async def get_payment_status(self, checking_id: str) -> PaymentStatus:
-        return PaymentStatus(False)
+        return PaymentStatus(None)
 
     async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
         self.queue = asyncio.Queue(0)


Test patch: