prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN 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."
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `lnbits/extensions/lnurlp/views_api.py`
  Content:
  ```
  1 from quart import g, jsonify, request
  2 from http import HTTPStatus
  3 from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl  # type: ignore
  4 
  5 from lnbits.core.crud import get_user
  6 from lnbits.decorators import api_check_wallet_key, api_validate_post_request
  7 from lnbits.utils.exchange_rates import currencies, get_fiat_rate_satoshis
  8 
  9 from . import lnurlp_ext
  10 from .crud import (
  11     create_pay_link,
  12     get_pay_link,
  13     get_pay_links,
  14     update_pay_link,
  15     delete_pay_link,
  16 )
  17 
  18 
  19 @lnurlp_ext.route("/api/v1/currencies", methods=["GET"])
  20 async def api_list_currencies_available():
  21     return jsonify(list(currencies.keys()))
  22 
  23 
  24 @lnurlp_ext.route("/api/v1/links", methods=["GET"])
  25 @api_check_wallet_key("invoice")
  26 async def api_links():
  27     wallet_ids = [g.wallet.id]
  28 
  29     if "all_wallets" in request.args:
  30         wallet_ids = (await get_user(g.wallet.user)).wallet_ids
  31 
  32     try:
  33         return (
  34             jsonify(
  35                 [
  36                     {**link._asdict(), **{"lnurl": link.lnurl}}
  37                     for link in await get_pay_links(wallet_ids)
  38                 ]
  39             ),
  40             HTTPStatus.OK,
  41         )
  42     except LnurlInvalidUrl:
  43         return (
  44             jsonify(
  45                 {
  46                     "message": "LNURLs need to be delivered over a publically accessible `https` domain or Tor."
  47                 }
  48             ),
  49             HTTPStatus.UPGRADE_REQUIRED,
  50         )
  51 
  52 
  53 @lnurlp_ext.route("/api/v1/links/<link_id>", methods=["GET"])
  54 @api_check_wallet_key("invoice")
  55 async def api_link_retrieve(link_id):
  56     link = await get_pay_link(link_id)
  57 
  58     if not link:
  59         return jsonify({"message": "Pay link does not exist."}), HTTPStatus.NOT_FOUND
  60 
  61     if link.wallet != g.wallet.id:
  62         return jsonify({"message": "Not your pay link."}), HTTPStatus.FORBIDDEN
  63 
  64     return jsonify({**link._asdict(), **{"lnurl": link.lnurl}}), HTTPStatus.OK
  65 
  66 
  67 @lnurlp_ext.route("/api/v1/links", methods=["POST"])
  68 @lnurlp_ext.route("/api/v1/links/<link_id>", methods=["PUT"])
  69 @api_check_wallet_key("invoice")
  70 @api_validate_post_request(
  71     schema={
  72         "description": {"type": "string", "empty": False, "required": True},
  73         "min": {"type": "number", "min": 0.01, "required": True},
  74         "max": {"type": "number", "min": 0.01, "required": True},
  75         "currency": {"type": "string", "nullable": True, "required": False},
  76         "comment_chars": {"type": "integer", "required": True, "min": 0, "max": 800},
  77         "webhook_url": {"type": "string", "required": False},
  78         "success_text": {"type": "string", "required": False},
  79         "success_url": {"type": "string", "required": False},
  80     }
  81 )
  82 async def api_link_create_or_update(link_id=None):
  83     if g.data["min"] > g.data["max"]:
  84         return jsonify({"message": "Min is greater than max."}), HTTPStatus.BAD_REQUEST
  85 
  86     if g.data.get("currency") == None and (
  87         round(g.data["min"]) != g.data["min"] or round(g.data["max"]) != g.data["max"]
  88     ):
  89         return jsonify({"message": "Must use full satoshis."}), HTTPStatus.BAD_REQUEST
  90 
  91     if link_id:
  92         link = await get_pay_link(link_id)
  93 
  94         if not link:
  95             return (
  96                 jsonify({"message": "Pay link does not exist."}),
  97                 HTTPStatus.NOT_FOUND,
  98             )
  99 
  100         if link.wallet != g.wallet.id:
  101             return jsonify({"message": "Not your pay link."}), HTTPStatus.FORBIDDEN
  102 
  103         link = await update_pay_link(link_id, **g.data)
  104     else:
  105         link = await create_pay_link(wallet_id=g.wallet.id, **g.data)
  106 
  107     return (
  108         jsonify({**link._asdict(), **{"lnurl": link.lnurl}}),
  109         HTTPStatus.OK if link_id else HTTPStatus.CREATED,
  110     )
  111 
  112 
  113 @lnurlp_ext.route("/api/v1/links/<link_id>", methods=["DELETE"])
  114 @api_check_wallet_key("invoice")
  115 async def api_link_delete(link_id):
  116     link = await get_pay_link(link_id)
  117 
  118     if not link:
  119         return jsonify({"message": "Pay link does not exist."}), HTTPStatus.NOT_FOUND
  120 
  121     if link.wallet != g.wallet.id:
  122         return jsonify({"message": "Not your pay link."}), HTTPStatus.FORBIDDEN
  123 
  124     await delete_pay_link(link_id)
  125 
  126     return "", HTTPStatus.NO_CONTENT
  127 
  128 
  129 @lnurlp_ext.route("/api/v1/rate/<currency>", methods=["GET"])
  130 async def api_check_fiat_rate(currency):
  131     try:
  132         rate = await get_fiat_rate_satoshis(currency)
  133     except AssertionError:
  134         rate = None
  135 
  136     return jsonify({"rate": rate}), HTTPStatus.OK
  137
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: 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 @@
           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)
  
verification_info: {"golden_diff": "diff --git a/lnbits/extensions/lnurlp/views_api.py b/lnbits/extensions/lnurlp/views_api.py\n--- a/lnbits/extensions/lnurlp/views_api.py\n+++ b/lnbits/extensions/lnurlp/views_api.py\n@@ -87,6 +87,9 @@\n         round(g.data[\"min\"]) != g.data[\"min\"] or round(g.data[\"max\"]) != g.data[\"max\"]\n     ):\n         return jsonify({\"message\": \"Must use full satoshis.\"}), HTTPStatus.BAD_REQUEST\n+    \n+    if g.data[\"success_url\"][:8] != \"https://\":\n+        return jsonify({\"message\": \"Success URL must be secure https://...\"}), HTTPStatus.BAD_REQUEST\n \n     if link_id:\n         link = await get_pay_link(link_id)\n", "issue": "LNURLp links give errors on WalletofSatoshi and BlueWallet\nUsing this LNURLp link: https://lnbits.com/lnurlp/212\r\n\r\nBlueWallet Error: \"Alert: Bad response from server\"\r\nWallet of Satoshi Error: \"Error: Could not complete payment, please try again.\"\n", "before_files": [{"content": "from quart import g, jsonify, request\nfrom http import HTTPStatus\nfrom lnurl.exceptions import InvalidUrl as LnurlInvalidUrl  # type: ignore\n\nfrom lnbits.core.crud import get_user\nfrom lnbits.decorators import api_check_wallet_key, api_validate_post_request\nfrom lnbits.utils.exchange_rates import currencies, get_fiat_rate_satoshis\n\nfrom . import lnurlp_ext\nfrom .crud import (\n    create_pay_link,\n    get_pay_link,\n    get_pay_links,\n    update_pay_link,\n    delete_pay_link,\n)\n\n\n@lnurlp_ext.route(\"/api/v1/currencies\", methods=[\"GET\"])\nasync def api_list_currencies_available():\n    return jsonify(list(currencies.keys()))\n\n\n@lnurlp_ext.route(\"/api/v1/links\", methods=[\"GET\"])\n@api_check_wallet_key(\"invoice\")\nasync def api_links():\n    wallet_ids = [g.wallet.id]\n\n    if \"all_wallets\" in request.args:\n        wallet_ids = (await get_user(g.wallet.user)).wallet_ids\n\n    try:\n        return (\n            jsonify(\n                [\n                    {**link._asdict(), **{\"lnurl\": link.lnurl}}\n                    for link in await get_pay_links(wallet_ids)\n                ]\n            ),\n            HTTPStatus.OK,\n        )\n    except LnurlInvalidUrl:\n        return (\n            jsonify(\n                {\n                    \"message\": \"LNURLs need to be delivered over a publically accessible `https` domain or Tor.\"\n                }\n            ),\n            HTTPStatus.UPGRADE_REQUIRED,\n        )\n\n\n@lnurlp_ext.route(\"/api/v1/links/<link_id>\", methods=[\"GET\"])\n@api_check_wallet_key(\"invoice\")\nasync def api_link_retrieve(link_id):\n    link = await get_pay_link(link_id)\n\n    if not link:\n        return jsonify({\"message\": \"Pay link does not exist.\"}), HTTPStatus.NOT_FOUND\n\n    if link.wallet != g.wallet.id:\n        return jsonify({\"message\": \"Not your pay link.\"}), HTTPStatus.FORBIDDEN\n\n    return jsonify({**link._asdict(), **{\"lnurl\": link.lnurl}}), HTTPStatus.OK\n\n\n@lnurlp_ext.route(\"/api/v1/links\", methods=[\"POST\"])\n@lnurlp_ext.route(\"/api/v1/links/<link_id>\", methods=[\"PUT\"])\n@api_check_wallet_key(\"invoice\")\n@api_validate_post_request(\n    schema={\n        \"description\": {\"type\": \"string\", \"empty\": False, \"required\": True},\n        \"min\": {\"type\": \"number\", \"min\": 0.01, \"required\": True},\n        \"max\": {\"type\": \"number\", \"min\": 0.01, \"required\": True},\n        \"currency\": {\"type\": \"string\", \"nullable\": True, \"required\": False},\n        \"comment_chars\": {\"type\": \"integer\", \"required\": True, \"min\": 0, \"max\": 800},\n        \"webhook_url\": {\"type\": \"string\", \"required\": False},\n        \"success_text\": {\"type\": \"string\", \"required\": False},\n        \"success_url\": {\"type\": \"string\", \"required\": False},\n    }\n)\nasync def api_link_create_or_update(link_id=None):\n    if g.data[\"min\"] > g.data[\"max\"]:\n        return jsonify({\"message\": \"Min is greater than max.\"}), HTTPStatus.BAD_REQUEST\n\n    if g.data.get(\"currency\") == None and (\n        round(g.data[\"min\"]) != g.data[\"min\"] or round(g.data[\"max\"]) != g.data[\"max\"]\n    ):\n        return jsonify({\"message\": \"Must use full satoshis.\"}), HTTPStatus.BAD_REQUEST\n\n    if link_id:\n        link = await get_pay_link(link_id)\n\n        if not link:\n            return (\n                jsonify({\"message\": \"Pay link does not exist.\"}),\n                HTTPStatus.NOT_FOUND,\n            )\n\n        if link.wallet != g.wallet.id:\n            return jsonify({\"message\": \"Not your pay link.\"}), HTTPStatus.FORBIDDEN\n\n        link = await update_pay_link(link_id, **g.data)\n    else:\n        link = await create_pay_link(wallet_id=g.wallet.id, **g.data)\n\n    return (\n        jsonify({**link._asdict(), **{\"lnurl\": link.lnurl}}),\n        HTTPStatus.OK if link_id else HTTPStatus.CREATED,\n    )\n\n\n@lnurlp_ext.route(\"/api/v1/links/<link_id>\", methods=[\"DELETE\"])\n@api_check_wallet_key(\"invoice\")\nasync def api_link_delete(link_id):\n    link = await get_pay_link(link_id)\n\n    if not link:\n        return jsonify({\"message\": \"Pay link does not exist.\"}), HTTPStatus.NOT_FOUND\n\n    if link.wallet != g.wallet.id:\n        return jsonify({\"message\": \"Not your pay link.\"}), HTTPStatus.FORBIDDEN\n\n    await delete_pay_link(link_id)\n\n    return \"\", HTTPStatus.NO_CONTENT\n\n\n@lnurlp_ext.route(\"/api/v1/rate/<currency>\", methods=[\"GET\"])\nasync def api_check_fiat_rate(currency):\n    try:\n        rate = await get_fiat_rate_satoshis(currency)\n    except AssertionError:\n        rate = None\n\n    return jsonify({\"rate\": rate}), HTTPStatus.OK\n", "path": "lnbits/extensions/lnurlp/views_api.py"}], "after_files": [{"content": "from quart import g, jsonify, request\nfrom http import HTTPStatus\nfrom lnurl.exceptions import InvalidUrl as LnurlInvalidUrl  # type: ignore\n\nfrom lnbits.core.crud import get_user\nfrom lnbits.decorators import api_check_wallet_key, api_validate_post_request\nfrom lnbits.utils.exchange_rates import currencies, get_fiat_rate_satoshis\n\nfrom . import lnurlp_ext\nfrom .crud import (\n    create_pay_link,\n    get_pay_link,\n    get_pay_links,\n    update_pay_link,\n    delete_pay_link,\n)\n\n\n@lnurlp_ext.route(\"/api/v1/currencies\", methods=[\"GET\"])\nasync def api_list_currencies_available():\n    return jsonify(list(currencies.keys()))\n\n\n@lnurlp_ext.route(\"/api/v1/links\", methods=[\"GET\"])\n@api_check_wallet_key(\"invoice\")\nasync def api_links():\n    wallet_ids = [g.wallet.id]\n\n    if \"all_wallets\" in request.args:\n        wallet_ids = (await get_user(g.wallet.user)).wallet_ids\n\n    try:\n        return (\n            jsonify(\n                [\n                    {**link._asdict(), **{\"lnurl\": link.lnurl}}\n                    for link in await get_pay_links(wallet_ids)\n                ]\n            ),\n            HTTPStatus.OK,\n        )\n    except LnurlInvalidUrl:\n        return (\n            jsonify(\n                {\n                    \"message\": \"LNURLs need to be delivered over a publically accessible `https` domain or Tor.\"\n                }\n            ),\n            HTTPStatus.UPGRADE_REQUIRED,\n        )\n\n\n@lnurlp_ext.route(\"/api/v1/links/<link_id>\", methods=[\"GET\"])\n@api_check_wallet_key(\"invoice\")\nasync def api_link_retrieve(link_id):\n    link = await get_pay_link(link_id)\n\n    if not link:\n        return jsonify({\"message\": \"Pay link does not exist.\"}), HTTPStatus.NOT_FOUND\n\n    if link.wallet != g.wallet.id:\n        return jsonify({\"message\": \"Not your pay link.\"}), HTTPStatus.FORBIDDEN\n\n    return jsonify({**link._asdict(), **{\"lnurl\": link.lnurl}}), HTTPStatus.OK\n\n\n@lnurlp_ext.route(\"/api/v1/links\", methods=[\"POST\"])\n@lnurlp_ext.route(\"/api/v1/links/<link_id>\", methods=[\"PUT\"])\n@api_check_wallet_key(\"invoice\")\n@api_validate_post_request(\n    schema={\n        \"description\": {\"type\": \"string\", \"empty\": False, \"required\": True},\n        \"min\": {\"type\": \"number\", \"min\": 0.01, \"required\": True},\n        \"max\": {\"type\": \"number\", \"min\": 0.01, \"required\": True},\n        \"currency\": {\"type\": \"string\", \"nullable\": True, \"required\": False},\n        \"comment_chars\": {\"type\": \"integer\", \"required\": True, \"min\": 0, \"max\": 800},\n        \"webhook_url\": {\"type\": \"string\", \"required\": False},\n        \"success_text\": {\"type\": \"string\", \"required\": False},\n        \"success_url\": {\"type\": \"string\", \"required\": False},\n    }\n)\nasync def api_link_create_or_update(link_id=None):\n    if g.data[\"min\"] > g.data[\"max\"]:\n        return jsonify({\"message\": \"Min is greater than max.\"}), HTTPStatus.BAD_REQUEST\n\n    if g.data.get(\"currency\") == None and (\n        round(g.data[\"min\"]) != g.data[\"min\"] or round(g.data[\"max\"]) != g.data[\"max\"]\n    ):\n        return jsonify({\"message\": \"Must use full satoshis.\"}), HTTPStatus.BAD_REQUEST\n    \n    if g.data[\"success_url\"][:8] != \"https://\":\n        return jsonify({\"message\": \"Success URL must be secure https://...\"}), HTTPStatus.BAD_REQUEST\n\n    if link_id:\n        link = await get_pay_link(link_id)\n\n        if not link:\n            return (\n                jsonify({\"message\": \"Pay link does not exist.\"}),\n                HTTPStatus.NOT_FOUND,\n            )\n\n        if link.wallet != g.wallet.id:\n            return jsonify({\"message\": \"Not your pay link.\"}), HTTPStatus.FORBIDDEN\n\n        link = await update_pay_link(link_id, **g.data)\n    else:\n        link = await create_pay_link(wallet_id=g.wallet.id, **g.data)\n\n    return (\n        jsonify({**link._asdict(), **{\"lnurl\": link.lnurl}}),\n        HTTPStatus.OK if link_id else HTTPStatus.CREATED,\n    )\n\n\n@lnurlp_ext.route(\"/api/v1/links/<link_id>\", methods=[\"DELETE\"])\n@api_check_wallet_key(\"invoice\")\nasync def api_link_delete(link_id):\n    link = await get_pay_link(link_id)\n\n    if not link:\n        return jsonify({\"message\": \"Pay link does not exist.\"}), HTTPStatus.NOT_FOUND\n\n    if link.wallet != g.wallet.id:\n        return jsonify({\"message\": \"Not your pay link.\"}), HTTPStatus.FORBIDDEN\n\n    await delete_pay_link(link_id)\n\n    return \"\", HTTPStatus.NO_CONTENT\n\n\n@lnurlp_ext.route(\"/api/v1/rate/<currency>\", methods=[\"GET\"])\nasync def api_check_fiat_rate(currency):\n    try:\n        rate = await get_fiat_rate_satoshis(currency)\n    except AssertionError:\n        rate = None\n\n    return jsonify({\"rate\": rate}), HTTPStatus.OK\n", "path": "lnbits/extensions/lnurlp/views_api.py"}]}