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

Issue:
Ticket Counter Broken
Test bought 2 tickets. Amount available didn't decrease. Amount Sold didn't increase...
![2022-08-24 22_43_47-LNbits — Mozilla Firefox](https://user-images.githubusercontent.com/9597295/186563808-2e7f4d33-66e0-45f6-8658-37821791ff32.png)




Discussion:
Taking a look at `extensions/events`, it looks like the CRUD method `set_ticket_paid` is never called. This method is responsible for incrementing the counter. It's been commented out in the extension. Wonder if there's a reason this was taken out or just an oversight?

Resolving patch:
diff --git a/lnbits/extensions/events/crud.py b/lnbits/extensions/events/crud.py
--- a/lnbits/extensions/events/crud.py
+++ b/lnbits/extensions/events/crud.py
@@ -19,39 +19,22 @@ async def create_ticket(
         (payment_hash, wallet, event, name, email, False, True),
     )
 
-    ticket = await get_ticket(payment_hash)
-    assert ticket, "Newly created ticket couldn't be retrieved"
-    return ticket
-
-
-async def set_ticket_paid(payment_hash: str) -> Tickets:
-    row = await db.fetchone("SELECT * FROM events.ticket WHERE id = ?", (payment_hash,))
-    if row[6] != True:
-        await db.execute(
-            """
-            UPDATE events.ticket
-            SET paid = true
-            WHERE id = ?
-            """,
-            (payment_hash,),
-        )
-
-        eventdata = await get_event(row[2])
-        assert eventdata, "Couldn't get event from ticket being paid"
-
-        sold = eventdata.sold + 1
-        amount_tickets = eventdata.amount_tickets - 1
-        await db.execute(
-            """
-            UPDATE events.events
-            SET sold = ?, amount_tickets = ?
-            WHERE id = ?
-            """,
-            (sold, amount_tickets, row[2]),
-        )
+    # UPDATE EVENT DATA ON SOLD TICKET
+    eventdata = await get_event(event)
+    assert eventdata, "Couldn't get event from ticket being paid"
+    sold = eventdata.sold + 1
+    amount_tickets = eventdata.amount_tickets - 1
+    await db.execute(
+        """
+        UPDATE events.events
+        SET sold = ?, amount_tickets = ?
+        WHERE id = ?
+        """,
+        (sold, amount_tickets, event),
+    )
 
     ticket = await get_ticket(payment_hash)
-    assert ticket, "Newly updated ticket couldn't be retrieved"
+    assert ticket, "Newly created ticket couldn't be retrieved"
     return ticket
 
 
diff --git a/lnbits/extensions/events/views_api.py b/lnbits/extensions/events/views_api.py
--- a/lnbits/extensions/events/views_api.py
+++ b/lnbits/extensions/events/views_api.py
@@ -24,7 +24,6 @@
     get_ticket,
     get_tickets,
     reg_ticket,
-    set_ticket_paid,
     update_event,
 )
 


Test patch:
Repository: lnbits/lnbits

Issue:
Usermanager: shows wrong key
Usermanager API sidebar shows invoice API keys for most operations but it should be the admin key.


Discussion:

Resolving patch:
diff --git a/lnbits/extensions/usermanager/crud.py b/lnbits/extensions/usermanager/crud.py
--- a/lnbits/extensions/usermanager/crud.py
+++ b/lnbits/extensions/usermanager/crud.py
@@ -63,10 +63,11 @@ async def get_usermanager_users(user_id: str) -> List[Users]:
     return [Users(**row) for row in rows]
 
 
-async def delete_usermanager_user(user_id: str) -> None:
-    wallets = await get_usermanager_wallets(user_id)
-    for wallet in wallets:
-        await delete_wallet(user_id=user_id, wallet_id=wallet.id)
+async def delete_usermanager_user(user_id: str, delete_core: bool = True) -> None:
+    if delete_core:
+        wallets = await get_usermanager_wallets(user_id)
+        for wallet in wallets:
+            await delete_wallet(user_id=user_id, wallet_id=wallet.id)
 
     await db.execute("DELETE FROM usermanager.users WHERE id = ?", (user_id,))
     await db.execute("""DELETE FROM usermanager.wallets WHERE "user" = ?""", (user_id,))
diff --git a/lnbits/extensions/usermanager/views_api.py b/lnbits/extensions/usermanager/views_api.py
--- a/lnbits/extensions/usermanager/views_api.py
+++ b/lnbits/extensions/usermanager/views_api.py
@@ -52,15 +52,17 @@ async def api_usermanager_users_create(
 
 @usermanager_ext.delete("/api/v1/users/{user_id}")
 async def api_usermanager_users_delete(
-    user_id, wallet: WalletTypeInfo = Depends(require_admin_key)
+    user_id,
+    delete_core: bool = Query(True),
+    wallet: WalletTypeInfo = Depends(require_admin_key),
 ):
     user = await get_usermanager_user(user_id)
     if not user:
         raise HTTPException(
             status_code=HTTPStatus.NOT_FOUND, detail="User does not exist."
         )
-    await delete_usermanager_user(user_id)
-    raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
+    await delete_usermanager_user(user_id, delete_core)
+    return "", HTTPStatus.NO_CONTENT
 
 
 # Activate Extension
@@ -124,4 +126,4 @@ async def api_usermanager_wallets_delete(
             status_code=HTTPStatus.NOT_FOUND, detail="Wallet does not exist."
         )
     await delete_usermanager_wallet(wallet_id, get_wallet.user)
-    raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
+    return "", HTTPStatus.NO_CONTENT


Test patch:
Repository: lnbits/lnbits

Issue:
Lightning decode api Failed to decode
Hi

Calling `POST https://demo.lnbits.com/api/v1/payments/decode` with the body
```
{
    "data": "lnbc1u1psh...q8t3wp2"
}
```
 return "message": "Failed to decode"


Discussion:
Can you please try sending the invoice in a query parameter? `?data=lnbc1u1psh...q8t3wp2` and see if that solves it?
Hey @arcbtc, I think this is still an issue - can this potentially be reopened?

The response code is `200 OK` even if the invoice could not be decoded.
I don't think it is a breaking change to adapt it and send 4xx or 5xx depending on what the underlying issue is. 
What do you think?

Resolving patch:
diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py
--- a/lnbits/core/views/api.py
+++ b/lnbits/core/views/api.py
@@ -12,7 +12,7 @@
 import async_timeout
 import httpx
 import pyqrcode
-from fastapi import Depends, Header, Query, Request
+from fastapi import Depends, Header, Query, Request, Response
 from fastapi.exceptions import HTTPException
 from fastapi.params import Body
 from loguru import logger
@@ -584,8 +584,8 @@ class DecodePayment(BaseModel):
     data: str
 
 
-@core_app.post("/api/v1/payments/decode")
-async def api_payments_decode(data: DecodePayment):
+@core_app.post("/api/v1/payments/decode", status_code=HTTPStatus.OK)
+async def api_payments_decode(data: DecodePayment, response: Response):
     payment_str = data.data
     try:
         if payment_str[:5] == "LNURL":
@@ -606,6 +606,7 @@ async def api_payments_decode(data: DecodePayment):
                 "min_final_cltv_expiry": invoice.min_final_cltv_expiry,
             }
     except:
+        response.status_code = HTTPStatus.BAD_REQUEST
         return {"message": "Failed to decode"}
 
 


Test patch:
Repository: lnbits/lnbits

Issue:
[BUG] LNDhub extension return unusable `getinfo` response
**Describe the bug**
The [getinfo call](https://github.com/lnbits/lnbits/blob/main/lnbits/extensions/lndhub/views_api.py#L22) simply returns `bad auth` everytime, which breaks integrations like for us in BTCPay Server (see btcpayserver/btcpayserver#4414).

**Expected behavior**
Return [valid information](https://github.com/BlueWallet/LndHub/blob/master/doc/Send-requirements.md#get-getinfo), which we can use to connect. For us that would mean having a list of `uris` and a `block_height` being set.



Discussion:

Resolving patch:
diff --git a/lnbits/extensions/lndhub/views_api.py b/lnbits/extensions/lndhub/views_api.py
--- a/lnbits/extensions/lndhub/views_api.py
+++ b/lnbits/extensions/lndhub/views_api.py
@@ -21,7 +21,7 @@
 
 @lndhub_ext.get("/ext/getinfo")
 async def lndhub_getinfo():
-    raise HTTPException(status_code=HTTPStatus.UNAUTHORIZED, detail="bad auth")
+    return {"alias": LNBITS_SITE_TITLE}
 
 
 class AuthData(BaseModel):


Test patch:
Repository: lnbits/lnbits

Issue:
[BUG] Topup button visible but request returns 401 unauthorized
**Describe the bug**
The "+" topup button is visible for an admin user (set via LNBITS_ADMIN_USERS env variable) but clicking it (specifying amount + enter) returns 401 unauthorized

**Expected behavior**
I expect the topup button to not even be visible when I do not have privileges to use it. Or it should work when it's visible

**Screenshots**
![image](https://user-images.githubusercontent.com/6108688/209833372-af0b7395-1219-4c1c-a092-45497a618a98.png)
![image](https://user-images.githubusercontent.com/6108688/209833341-705842fc-bf25-4e56-aa22-5b1674e7e1b5.png)

**Desktop (please complete the following information):**
 - LNbits version: 0.9.5.3



Discussion:
There's two possible routes for this! 
1. This shouldn't happen, and the 'plus' sign shouldn't show up unless you're a super user (which means you need to have Admin UI enabled) 
2. We should make it so that when the user/owner of the LNbits instance is not using the AdminUI this feature is available...

@dni @motorina0 ?
yes, 1. + should only be visible with superuser, as @arcbtc decided.
2. that means regular admin are not allowed to topup.

@arcbtc is that ok? 
we could also change it so admins can also brrr.  
so we do not have this issue when users are not using admin_ui.

without admin_ui that topup feature is not accessible at all with this approach


Resolving patch:
diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py
--- a/lnbits/core/views/generic.py
+++ b/lnbits/core/views/generic.py
@@ -131,6 +131,8 @@ async def wallet(
             )
         if user_id == settings.super_user or user_id in settings.lnbits_admin_users:
             user.admin = True
+        if user_id == settings.super_user:
+            user.super_user = True
 
     if not wallet_id:
         if user.wallets and not wallet_name:  # type: ignore


Test patch:
Repository: lnbits/lnbits

Issue:
[BUG] No way to block the creation of users.
**Describe the bug**
Setting allowed users in the GUI and/or the .env file blocks access to non-allowed users, but does not block the creation of new users through the public frontend page IE lnbits.mydomain.com

**To Reproduce**
Steps to reproduce the behavior:

1. As admin user, create a new users in the usermanager extension.
2. Set this new user as "allowed user" in the admin GUI and the .env.
3. Restart LNbits.
4. Visit the public frontend and try to create a new user. The GUI states "User not authorized." but the new user is in fact still created, his userID is visible in the URL and the creation is logged.

**Expected behavior**
Setting "allowed users" blocks the creation of new users by anyone other than the admin.
A clear message is displayed that visitors of the frontend are not allowed to create new users.

LNbits version: 0.10.8
Database: sqlite


Discussion:

Resolving patch:
diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py
--- a/lnbits/core/views/api.py
+++ b/lnbits/core/views/api.py
@@ -172,6 +172,11 @@ async def api_create_wallet(
 
 @api_router.post("/api/v1/account", response_model=Wallet)
 async def api_create_account(data: CreateWallet) -> Wallet:
+    if len(settings.lnbits_allowed_users) > 0:
+        raise HTTPException(
+            status_code=HTTPStatus.BAD_REQUEST,
+            detail="Account creation is disabled.",
+        )
     account = await create_account()
     return await create_wallet(user_id=account.id, wallet_name=data.name)
 


Test patch:
Repository: lnbits/lnbits

Issue:
Wallet not handling LNURLp redirects
I have configure the LNURL https://btc.us/.well-known/lnurlp/bilall to redirect to https://getalby.com/lnurlp/bilall with the status code 301.
This means that is bilall@btc.us is added as recipient in the wallet, the wallet should send the payment to bilall@getalby.com.

However, adding bilall@btc.us throws a 503 error. Adding bilall@getalby.com works perfectly though.

Note: I was using the Legend demo server for this: https://legend.lnbits.com/

These screenshots show the btc.us redirect not working.
![lnbits btc 1](https://user-images.githubusercontent.com/62988673/190961753-f1a65774-74ab-42eb-b96d-32623b17c12e.jpeg)
![lnbits btc 2](https://user-images.githubusercontent.com/62988673/190961759-a3ba194b-2952-42a8-a1b0-a442d4fbee24.jpeg)

These show the getalby.com address working.
![lnbits getalby 1](https://user-images.githubusercontent.com/62988673/190961763-6756ef7c-6fdc-4782-aff7-45159cfde07a.jpeg)
![lnbits getalby 2](https://user-images.githubusercontent.com/62988673/190961741-db4f193c-427a-4ef6-95e8-ac06562bdd91.jpeg)





Discussion:
I think it makes sense to follow redirects for lightning addresses as domains should be able to redirect to other valid lightning addresses. I can volunteer to write a fix for this.
Can it be closed? @pseudozach , @bilalanees98 ?
@talvasconcelos is it fixed? I haven't tested recently or is the spec updated to disallow following redirects?
Was asking because you mentioned a fix! 
no I haven't fixed it. why should it be closed? it should either be fixed or it can be closed as spec compliant.

Resolving patch:
diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py
--- a/lnbits/core/views/api.py
+++ b/lnbits/core/views/api.py
@@ -541,8 +541,9 @@ async def api_lnurlscan(code: str, wallet: WalletTypeInfo = Depends(get_key_type
         assert lnurlauth_key.verifying_key
         params.update(pubkey=lnurlauth_key.verifying_key.to_string("compressed").hex())
     else:
-        async with httpx.AsyncClient() as client:
+        async with httpx.AsyncClient(follow_redirects=True) as client:
             r = await client.get(url, timeout=5)
+            r.raise_for_status()
             if r.is_error:
                 raise HTTPException(
                     status_code=HTTPStatus.SERVICE_UNAVAILABLE,


Test patch:
Repository: lnbits/lnbits

Issue:
[BUG] deleted wallets still show up in frontend
![screenshot-1694590265](https://github.com/lnbits/lnbits/assets/1743657/d23b4a1a-95ab-4e79-b61b-8444f0501570)

wallet is still visible, when deleted, discoverd it here.

https://github.com/lnbits/lnbits/pull/1932/files#r1323243651

i think we have to put it into the CRUD aswell


Discussion:
is this on main? dev?


the wallets on the UI are pulled from the user, which uses the CRUD. since there's no filter on there, you get all the wallets. 

we can remove them at the UI level, just frontend sugar. 

either here, removing the deleted wallets from the user obj: https://github.com/lnbits/lnbits/blob/6acbf823ae6f7ea519cfec9e2eb32498adbf1b3e/lnbits/static/js/base.js#L160-L174

or here, purely UI sugar, wallets are still on the user obj, just not displayed: https://github.com/lnbits/lnbits/blob/6acbf823ae6f7ea519cfec9e2eb32498adbf1b3e/lnbits/static/js/components.js#L75-L86
its on `dev` its our owrking branch now

Resolving patch:
diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py
--- a/lnbits/core/crud.py
+++ b/lnbits/core/crud.py
@@ -61,25 +61,37 @@ async def get_account(
     return User(**row) if row else None
 
 
-async def get_user(user_id: str, conn: Optional[Connection] = None) -> Optional[User]:
+async def get_user(
+    user_id: str,
+    conn: Optional[Connection] = None,
+    include_deleted_wallets: Optional[bool] = False,
+) -> Optional[User]:
     user = await (conn or db).fetchone(
         "SELECT id, email FROM accounts WHERE id = ?", (user_id,)
     )
 
     if user:
+        clauses = ["user = ?"]
+        values: List[Any] = [user_id]
+
+        if not include_deleted_wallets:
+            clauses.append("deleted = ?")
+            values.append(False)
+
+        where = "WHERE " + " AND ".join(clauses) if clauses else ""
         extensions = await (conn or db).fetchall(
             """SELECT extension FROM extensions WHERE "user" = ? AND active""",
             (user_id,),
         )
         wallets = await (conn or db).fetchall(
-            """
+            f"""
             SELECT *, COALESCE((
                 SELECT balance FROM balances WHERE wallet = wallets.id
             ), 0) AS balance_msat
             FROM wallets
-            WHERE "user" = ?
+            {where}
             """,
-            (user_id,),
+            tuple(values),
         )
     else:
         return None


Test patch:
Repository: lnbits/lnbits

Issue:
Logo in QR code everywhere (also in extensions)
Include logo in all QRs generated by the instance 
- or an extension on the instance (tpos, satspay, devices, invoices, ..)
-- or a variety ID from an extension on the instance (stall-ID, device-ID, ..)

Admins should be able to overwrite or turn off.


Default is on and pre-set to the LNbits logo
https://github.com/lnbits/lnbits/blob/3260acbcc7e907fa9c9c60d0582bf974031f917b/docs/logos/lnbits.png


Discussion:

Resolving patch:
diff --git a/lnbits/helpers.py b/lnbits/helpers.py
--- a/lnbits/helpers.py
+++ b/lnbits/helpers.py
@@ -49,6 +49,7 @@ def template_renderer(additional_folders: Optional[List] = None) -> Jinja2Templa
     t.env.globals["SITE_TAGLINE"] = settings.lnbits_site_tagline
     t.env.globals["SITE_DESCRIPTION"] = settings.lnbits_site_description
     t.env.globals["LNBITS_THEME_OPTIONS"] = settings.lnbits_theme_options
+    t.env.globals["LNBITS_QR_LOGO"] = settings.lnbits_qr_logo
     t.env.globals["LNBITS_VERSION"] = settings.version
     t.env.globals["LNBITS_ADMIN_UI"] = settings.lnbits_admin_ui
     t.env.globals["LNBITS_NODE_UI"] = (
diff --git a/lnbits/settings.py b/lnbits/settings.py
--- a/lnbits/settings.py
+++ b/lnbits/settings.py
@@ -85,6 +85,7 @@ class ThemesSettings(LNbitsSettings):
     lnbits_ad_space_enabled: bool = Field(default=False)
     lnbits_allowed_currencies: List[str] = Field(default=[])
     lnbits_default_accounting_currency: Optional[str] = Field(default=None)
+    lnbits_qr_logo: str = Field(default="/static/images/logos/lnbits.svg")
 
 
 class OpsSettings(LNbitsSettings):


Test patch:
Repository: lnbits/lnbits

Issue:
LNDRestWallet: catch http errors
This PR catches the errors in `lndrest.py` that can happen when for example the LND certificate has expired. 

This can lead to stuck payments.


Discussion:

Resolving patch:
diff --git a/lnbits/wallets/lndrest.py b/lnbits/wallets/lndrest.py
--- a/lnbits/wallets/lndrest.py
+++ b/lnbits/wallets/lndrest.py
@@ -195,6 +195,12 @@ async def get_payment_status(self, checking_id: str) -> PaymentStatus:
                             if "message" in line["error"]
                             else line["error"]
                         )
+                        if (
+                            line["error"].get("code") == 5
+                            and line["error"].get("message")
+                            == "payment isn't initiated"
+                        ):
+                            return PaymentStatus(False)
                         return PaymentStatus(None)
                     payment = line.get("result")
                     if payment is not None and payment.get("status"):


Test patch:
Repository: lnbits/lnbits

Issue:
Extra and memo is not coming in trx history, while passing while paying invoice[BUG]
When I am paying the invoice and passing extra and memo parameter, its not coming in transaction history.

How to reproduce ? 
Just create a invoice on any website
and paid that invoice and in body pass the memo and extra object
After that hit transaction history, the memo and extra is not going to come

Expected behavior
Extra field should give whatever we pass in it
Memo should give whatever string we passed in it.


Discussion:
`extra` is not passed along when making a payment, ex: `"out: true"`.

https://github.com/lnbits/lnbits/blob/7306df34459714b4b2e21cbf066d582c03b6ffd6/lnbits/core/views/api.py#L334-L338 


But I think we need to pass as , it is necessary to have some fields like this

Resolving patch:
diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py
--- a/lnbits/core/views/api.py
+++ b/lnbits/core/views/api.py
@@ -332,9 +332,13 @@ async def api_payments_create_invoice(data: CreateInvoice, wallet: Wallet):
     }
 
 
-async def api_payments_pay_invoice(bolt11: str, wallet: Wallet):
+async def api_payments_pay_invoice(
+    bolt11: str, wallet: Wallet, extra: Optional[dict] = None
+):
     try:
-        payment_hash = await pay_invoice(wallet_id=wallet.id, payment_request=bolt11)
+        payment_hash = await pay_invoice(
+            wallet_id=wallet.id, payment_request=bolt11, extra=extra
+        )
     except ValueError as e:
         raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail=str(e))
     except PermissionError as e:
@@ -375,7 +379,7 @@ async def api_payments_create(
                 detail="BOLT11 string is invalid or not given",
             )
         return await api_payments_pay_invoice(
-            invoiceData.bolt11, wallet.wallet
+            invoiceData.bolt11, wallet.wallet, invoiceData.extra
         )  # admin key
     elif not invoiceData.out:
         # invoice key


Test patch:
Repository: lnbits/lnbits

Issue:
[Feature request] Add server url to "API keys and API docs" section
**Is your feature request related to a problem? Please describe.**
When linking lnbits with external services, (e.g. [zaprite](https://zaprite.com/)) one needs to specify two things: node url and invoice key. 

![image](https://github.com/lnbits/lnbits/assets/19181985/64920942-d120-4d50-951f-99aa8e6b1cca)

Invoice key is clearly visible in the "API keys and API docs" section, but it's sometimes unclear what my "LNbits Node URL" is. 

![image](https://github.com/lnbits/lnbits/assets/19181985/9ae7086b-f48b-4b56-b2aa-6f4a3f42fd96)

**Describe the solution you'd like**
Display "LNbits Node URL" in "Node URL, API keys and docs"


Discussion:
This is great. Would definitely help our users.

Resolving patch:
diff --git a/tools/i18n-ai-tool.py b/tools/i18n-ai-tool.py
--- a/tools/i18n-ai-tool.py
+++ b/tools/i18n-ai-tool.py
@@ -64,6 +64,7 @@ def translate_string(lang_from, lang_to, text):
         "cs": "Czech",
         "sk": "Slovak",
         "kr": "Korean",
+        "fi": "Finnish",
     }[lang_to]
     assert os.getenv("OPENAI_API_KEY"), "OPENAI_API_KEY env var not set"
     client = OpenAI()


Test patch: