We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN 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 

--- 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 http import HTTPStatus
2 
3 from fastapi import Request
4 from fastapi.param_functions import Query
5 from fastapi.params import Depends
6 from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl  # type: ignore
7 from starlette.exceptions import HTTPException
8 
9 from lnbits.core.crud import get_user
10 from lnbits.decorators import WalletTypeInfo, get_key_type
11 from lnbits.utils.exchange_rates import currencies, get_fiat_rate_satoshis
12 
13 from . import lnurlp_ext
14 from .crud import (
15     create_pay_link,
16     delete_pay_link,
17     get_pay_link,
18     get_pay_links,
19     update_pay_link,
20 )
21 from .models import CreatePayLinkData
22 
23 
24 @lnurlp_ext.get("/api/v1/currencies")
25 async def api_list_currencies_available():
26     return list(currencies.keys())
27 
28 
29 @lnurlp_ext.get("/api/v1/links", status_code=HTTPStatus.OK)
30 async def api_links(
31     req: Request,
32     wallet: WalletTypeInfo = Depends(get_key_type),
33     all_wallets: bool = Query(False),
34 ):
35     wallet_ids = [wallet.wallet.id]
36 
37     if all_wallets:
38         wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids
39 
40     try:
41         return [
42             {**link.dict(), "lnurl": link.lnurl(req)}
43             for link in await get_pay_links(wallet_ids)
44         ]
45 
46     except LnurlInvalidUrl:
47         raise HTTPException(
48             status_code=HTTPStatus.UPGRADE_REQUIRED,
49             detail="LNURLs need to be delivered over a publically accessible `https` domain or Tor.",
50         )
51 
52 
53 @lnurlp_ext.get("/api/v1/links/{link_id}", status_code=HTTPStatus.OK)
54 async def api_link_retrieve(
55     r: Request, link_id, wallet: WalletTypeInfo = Depends(get_key_type)
56 ):
57     link = await get_pay_link(link_id)
58 
59     if not link:
60         raise HTTPException(
61             detail="Pay link does not exist.", status_code=HTTPStatus.NOT_FOUND
62         )
63 
64     if link.wallet != wallet.wallet.id:
65         raise HTTPException(
66             detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN
67         )
68 
69     return {**link.dict(), **{"lnurl": link.lnurl(r)}}
70 
71 
72 @lnurlp_ext.post("/api/v1/links", status_code=HTTPStatus.CREATED)
73 @lnurlp_ext.put("/api/v1/links/{link_id}", status_code=HTTPStatus.OK)
74 async def api_link_create_or_update(
75     data: CreatePayLinkData,
76     link_id=None,
77     wallet: WalletTypeInfo = Depends(get_key_type),
78 ):
79 
80     if data.min > data.max:
81         raise HTTPException(
82             detail="Min is greater than max.", status_code=HTTPStatus.BAD_REQUEST
83         )
84 
85     if data.currency == None and (
86         round(data.min) != data.min or round(data.max) != data.max or data.min < 1
87     ):
88         raise HTTPException(
89             detail="Must use full satoshis.", status_code=HTTPStatus.BAD_REQUEST
90         )
91 
92     if "success_url" in data and data.success_url[:8] != "https://":
93         raise HTTPException(
94             detail="Success URL must be secure https://...",
95             status_code=HTTPStatus.BAD_REQUEST,
96         )
97 
98     if link_id:
99         link = await get_pay_link(link_id)
100 
101         if not link:
102             raise HTTPException(
103                 detail="Pay link does not exist.", status_code=HTTPStatus.NOT_FOUND
104             )
105 
106         if link.wallet != wallet.wallet.id:
107             raise HTTPException(
108                 detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN
109             )
110 
111         link = await update_pay_link(**data.dict(), link_id=link_id)
112     else:
113         link = await create_pay_link(data, wallet_id=wallet.wallet.id)
114     return {**link.dict(), "lnurl": link.lnurl}
115 
116 
117 @lnurlp_ext.delete("/api/v1/links/{link_id}")
118 async def api_link_delete(link_id, wallet: WalletTypeInfo = Depends(get_key_type)):
119     link = await get_pay_link(link_id)
120 
121     if not link:
122         raise HTTPException(
123             detail="Pay link does not exist.", status_code=HTTPStatus.NOT_FOUND
124         )
125 
126     if link.wallet != wallet.wallet.id:
127         raise HTTPException(
128             detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN
129         )
130 
131     await delete_pay_link(link_id)
132     raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
133 
134 
135 @lnurlp_ext.get("/api/v1/rate/{currency}", status_code=HTTPStatus.OK)
136 async def api_check_fiat_rate(currency):
137     try:
138         rate = await get_fiat_rate_satoshis(currency)
139     except AssertionError:
140         rate = None
141 
142     return {"rate": rate}
143
```

Path: `lnbits/extensions/lnurlp/crud.py`
Content:
```
1 from typing import List, Optional, Union
2 
3 from lnbits.db import SQLITE
4 from . import db
5 from .models import PayLink, CreatePayLinkData
6 
7 
8 async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:
9 
10     returning = "" if db.type == SQLITE else "RETURNING ID"
11     method = db.execute if db.type == SQLITE else db.fetchone
12     # database only allows int4 entries for min and max. For fiat currencies,
13     # we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents.
14     if data.currency and data.fiat_base_multiplier:
15         data.min *= data.fiat_base_multiplier
16         data.max *= data.fiat_base_multiplier
17 
18     result = await (method)(
19         f"""
20         INSERT INTO lnurlp.pay_links (
21             wallet,
22             description,
23             min,
24             max,
25             served_meta,
26             served_pr,
27             webhook_url,
28             success_text,
29             success_url,
30             comment_chars,
31             currency,
32             fiat_base_multiplier
33         )
34         VALUES (?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?)
35         {returning}
36         """,
37         (
38             wallet_id,
39             data.description,
40             data.min,
41             data.max,
42             data.webhook_url,
43             data.success_text,
44             data.success_url,
45             data.comment_chars,
46             data.currency,
47             data.fiat_base_multiplier,
48         ),
49     )
50     if db.type == SQLITE:
51         link_id = result._result_proxy.lastrowid
52     else:
53         link_id = result[0]
54 
55     link = await get_pay_link(link_id)
56     assert link, "Newly created link couldn't be retrieved"
57     return link
58 
59 
60 async def get_pay_link(link_id: int) -> Optional[PayLink]:
61     row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,))
62     return PayLink.from_row(row) if row else None
63 
64 
65 async def get_pay_links(wallet_ids: Union[str, List[str]]) -> List[PayLink]:
66     if isinstance(wallet_ids, str):
67         wallet_ids = [wallet_ids]
68 
69     q = ",".join(["?"] * len(wallet_ids))
70     rows = await db.fetchall(
71         f"""
72         SELECT * FROM lnurlp.pay_links WHERE wallet IN ({q})
73         ORDER BY Id
74         """,
75         (*wallet_ids,),
76     )
77     return [PayLink.from_row(row) for row in rows]
78 
79 
80 async def update_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:
81     q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
82     await db.execute(
83         f"UPDATE lnurlp.pay_links SET {q} WHERE id = ?", (*kwargs.values(), link_id)
84     )
85     row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,))
86     return PayLink.from_row(row) if row else None
87 
88 
89 async def increment_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:
90     q = ", ".join([f"{field[0]} = {field[0]} + ?" for field in kwargs.items()])
91     await db.execute(
92         f"UPDATE lnurlp.pay_links SET {q} WHERE id = ?", (*kwargs.values(), link_id)
93     )
94     row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,))
95     return PayLink.from_row(row) if row else None
96 
97 
98 async def delete_pay_link(link_id: int) -> None:
99     await db.execute("DELETE FROM lnurlp.pay_links WHERE id = ?", (link_id,))
100
```
--- 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()

```

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 @@
 
     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 @@
             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://...",

{"golden_diff": "diff --git a/lnbits/extensions/lnurlp/crud.py b/lnbits/extensions/lnurlp/crud.py\n--- a/lnbits/extensions/lnurlp/crud.py\n+++ b/lnbits/extensions/lnurlp/crud.py\n@@ -9,11 +9,6 @@\n \n     returning = \"\" if db.type == SQLITE else \"RETURNING ID\"\n     method = db.execute if db.type == SQLITE else db.fetchone\n-    # database only allows int4 entries for min and max. For fiat currencies,\n-    # we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents.\n-    if data.currency and data.fiat_base_multiplier:\n-        data.min *= data.fiat_base_multiplier\n-        data.max *= data.fiat_base_multiplier\n \n     result = await (method)(\n         f\"\"\"\ndiff --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@@ -89,6 +89,12 @@\n             detail=\"Must use full satoshis.\", status_code=HTTPStatus.BAD_REQUEST\n         )\n \n+    # database only allows int4 entries for min and max. For fiat currencies,\n+    # we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents.\n+    if data.currency and data.fiat_base_multiplier:\n+        data.min *= data.fiat_base_multiplier\n+        data.max *= data.fiat_base_multiplier\n+\n     if \"success_url\" in data and data.success_url[:8] != \"https://\":\n         raise HTTPException(\n             detail=\"Success URL must be secure https://...\",\n", "issue": "LNURLp: Edit existing LNURLP from sat to fiat currency unintentionally divides value by 100 \nReproduce: \r\n* Create 100 sat link, save\r\n* Edit link, change price to 5\u20ac, save\r\n* Observe that amount is now 0.05\u20ac instead of 5\u20ac\r\n\r\nMost likely cause by PR #663 \n", "before_files": [{"content": "from http import HTTPStatus\n\nfrom fastapi import Request\nfrom fastapi.param_functions import Query\nfrom fastapi.params import Depends\nfrom lnurl.exceptions import InvalidUrl as LnurlInvalidUrl  # type: ignore\nfrom starlette.exceptions import HTTPException\n\nfrom lnbits.core.crud import get_user\nfrom lnbits.decorators import WalletTypeInfo, get_key_type\nfrom lnbits.utils.exchange_rates import currencies, get_fiat_rate_satoshis\n\nfrom . import lnurlp_ext\nfrom .crud import (\n    create_pay_link,\n    delete_pay_link,\n    get_pay_link,\n    get_pay_links,\n    update_pay_link,\n)\nfrom .models import CreatePayLinkData\n\n\n@lnurlp_ext.get(\"/api/v1/currencies\")\nasync def api_list_currencies_available():\n    return list(currencies.keys())\n\n\n@lnurlp_ext.get(\"/api/v1/links\", status_code=HTTPStatus.OK)\nasync def api_links(\n    req: Request,\n    wallet: WalletTypeInfo = Depends(get_key_type),\n    all_wallets: bool = Query(False),\n):\n    wallet_ids = [wallet.wallet.id]\n\n    if all_wallets:\n        wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids\n\n    try:\n        return [\n            {**link.dict(), \"lnurl\": link.lnurl(req)}\n            for link in await get_pay_links(wallet_ids)\n        ]\n\n    except LnurlInvalidUrl:\n        raise HTTPException(\n            status_code=HTTPStatus.UPGRADE_REQUIRED,\n            detail=\"LNURLs need to be delivered over a publically accessible `https` domain or Tor.\",\n        )\n\n\n@lnurlp_ext.get(\"/api/v1/links/{link_id}\", status_code=HTTPStatus.OK)\nasync def api_link_retrieve(\n    r: Request, link_id, wallet: WalletTypeInfo = Depends(get_key_type)\n):\n    link = await get_pay_link(link_id)\n\n    if not link:\n        raise HTTPException(\n            detail=\"Pay link does not exist.\", status_code=HTTPStatus.NOT_FOUND\n        )\n\n    if link.wallet != wallet.wallet.id:\n        raise HTTPException(\n            detail=\"Not your pay link.\", status_code=HTTPStatus.FORBIDDEN\n        )\n\n    return {**link.dict(), **{\"lnurl\": link.lnurl(r)}}\n\n\n@lnurlp_ext.post(\"/api/v1/links\", status_code=HTTPStatus.CREATED)\n@lnurlp_ext.put(\"/api/v1/links/{link_id}\", status_code=HTTPStatus.OK)\nasync def api_link_create_or_update(\n    data: CreatePayLinkData,\n    link_id=None,\n    wallet: WalletTypeInfo = Depends(get_key_type),\n):\n\n    if data.min > data.max:\n        raise HTTPException(\n            detail=\"Min is greater than max.\", status_code=HTTPStatus.BAD_REQUEST\n        )\n\n    if data.currency == None and (\n        round(data.min) != data.min or round(data.max) != data.max or data.min < 1\n    ):\n        raise HTTPException(\n            detail=\"Must use full satoshis.\", status_code=HTTPStatus.BAD_REQUEST\n        )\n\n    if \"success_url\" in data and data.success_url[:8] != \"https://\":\n        raise HTTPException(\n            detail=\"Success URL must be secure https://...\",\n            status_code=HTTPStatus.BAD_REQUEST,\n        )\n\n    if link_id:\n        link = await get_pay_link(link_id)\n\n        if not link:\n            raise HTTPException(\n                detail=\"Pay link does not exist.\", status_code=HTTPStatus.NOT_FOUND\n            )\n\n        if link.wallet != wallet.wallet.id:\n            raise HTTPException(\n                detail=\"Not your pay link.\", status_code=HTTPStatus.FORBIDDEN\n            )\n\n        link = await update_pay_link(**data.dict(), link_id=link_id)\n    else:\n        link = await create_pay_link(data, wallet_id=wallet.wallet.id)\n    return {**link.dict(), \"lnurl\": link.lnurl}\n\n\n@lnurlp_ext.delete(\"/api/v1/links/{link_id}\")\nasync def api_link_delete(link_id, wallet: WalletTypeInfo = Depends(get_key_type)):\n    link = await get_pay_link(link_id)\n\n    if not link:\n        raise HTTPException(\n            detail=\"Pay link does not exist.\", status_code=HTTPStatus.NOT_FOUND\n        )\n\n    if link.wallet != wallet.wallet.id:\n        raise HTTPException(\n            detail=\"Not your pay link.\", status_code=HTTPStatus.FORBIDDEN\n        )\n\n    await delete_pay_link(link_id)\n    raise HTTPException(status_code=HTTPStatus.NO_CONTENT)\n\n\n@lnurlp_ext.get(\"/api/v1/rate/{currency}\", status_code=HTTPStatus.OK)\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 {\"rate\": rate}\n", "path": "lnbits/extensions/lnurlp/views_api.py"}, {"content": "from typing import List, Optional, Union\n\nfrom lnbits.db import SQLITE\nfrom . import db\nfrom .models import PayLink, CreatePayLinkData\n\n\nasync def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:\n\n    returning = \"\" if db.type == SQLITE else \"RETURNING ID\"\n    method = db.execute if db.type == SQLITE else db.fetchone\n    # database only allows int4 entries for min and max. For fiat currencies,\n    # we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents.\n    if data.currency and data.fiat_base_multiplier:\n        data.min *= data.fiat_base_multiplier\n        data.max *= data.fiat_base_multiplier\n\n    result = await (method)(\n        f\"\"\"\n        INSERT INTO lnurlp.pay_links (\n            wallet,\n            description,\n            min,\n            max,\n            served_meta,\n            served_pr,\n            webhook_url,\n            success_text,\n            success_url,\n            comment_chars,\n            currency,\n            fiat_base_multiplier\n        )\n        VALUES (?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?)\n        {returning}\n        \"\"\",\n        (\n            wallet_id,\n            data.description,\n            data.min,\n            data.max,\n            data.webhook_url,\n            data.success_text,\n            data.success_url,\n            data.comment_chars,\n            data.currency,\n            data.fiat_base_multiplier,\n        ),\n    )\n    if db.type == SQLITE:\n        link_id = result._result_proxy.lastrowid\n    else:\n        link_id = result[0]\n\n    link = await get_pay_link(link_id)\n    assert link, \"Newly created link couldn't be retrieved\"\n    return link\n\n\nasync def get_pay_link(link_id: int) -> Optional[PayLink]:\n    row = await db.fetchone(\"SELECT * FROM lnurlp.pay_links WHERE id = ?\", (link_id,))\n    return PayLink.from_row(row) if row else None\n\n\nasync def get_pay_links(wallet_ids: Union[str, List[str]]) -> List[PayLink]:\n    if isinstance(wallet_ids, str):\n        wallet_ids = [wallet_ids]\n\n    q = \",\".join([\"?\"] * len(wallet_ids))\n    rows = await db.fetchall(\n        f\"\"\"\n        SELECT * FROM lnurlp.pay_links WHERE wallet IN ({q})\n        ORDER BY Id\n        \"\"\",\n        (*wallet_ids,),\n    )\n    return [PayLink.from_row(row) for row in rows]\n\n\nasync def update_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:\n    q = \", \".join([f\"{field[0]} = ?\" for field in kwargs.items()])\n    await db.execute(\n        f\"UPDATE lnurlp.pay_links SET {q} WHERE id = ?\", (*kwargs.values(), link_id)\n    )\n    row = await db.fetchone(\"SELECT * FROM lnurlp.pay_links WHERE id = ?\", (link_id,))\n    return PayLink.from_row(row) if row else None\n\n\nasync def increment_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:\n    q = \", \".join([f\"{field[0]} = {field[0]} + ?\" for field in kwargs.items()])\n    await db.execute(\n        f\"UPDATE lnurlp.pay_links SET {q} WHERE id = ?\", (*kwargs.values(), link_id)\n    )\n    row = await db.fetchone(\"SELECT * FROM lnurlp.pay_links WHERE id = ?\", (link_id,))\n    return PayLink.from_row(row) if row else None\n\n\nasync def delete_pay_link(link_id: int) -> None:\n    await db.execute(\"DELETE FROM lnurlp.pay_links WHERE id = ?\", (link_id,))\n", "path": "lnbits/extensions/lnurlp/crud.py"}], "after_files": [{"content": "from http import HTTPStatus\n\nfrom fastapi import Request\nfrom fastapi.param_functions import Query\nfrom fastapi.params import Depends\nfrom lnurl.exceptions import InvalidUrl as LnurlInvalidUrl  # type: ignore\nfrom starlette.exceptions import HTTPException\n\nfrom lnbits.core.crud import get_user\nfrom lnbits.decorators import WalletTypeInfo, get_key_type\nfrom lnbits.utils.exchange_rates import currencies, get_fiat_rate_satoshis\n\nfrom . import lnurlp_ext\nfrom .crud import (\n    create_pay_link,\n    delete_pay_link,\n    get_pay_link,\n    get_pay_links,\n    update_pay_link,\n)\nfrom .models import CreatePayLinkData\n\n\n@lnurlp_ext.get(\"/api/v1/currencies\")\nasync def api_list_currencies_available():\n    return list(currencies.keys())\n\n\n@lnurlp_ext.get(\"/api/v1/links\", status_code=HTTPStatus.OK)\nasync def api_links(\n    req: Request,\n    wallet: WalletTypeInfo = Depends(get_key_type),\n    all_wallets: bool = Query(False),\n):\n    wallet_ids = [wallet.wallet.id]\n\n    if all_wallets:\n        wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids\n\n    try:\n        return [\n            {**link.dict(), \"lnurl\": link.lnurl(req)}\n            for link in await get_pay_links(wallet_ids)\n        ]\n\n    except LnurlInvalidUrl:\n        raise HTTPException(\n            status_code=HTTPStatus.UPGRADE_REQUIRED,\n            detail=\"LNURLs need to be delivered over a publically accessible `https` domain or Tor.\",\n        )\n\n\n@lnurlp_ext.get(\"/api/v1/links/{link_id}\", status_code=HTTPStatus.OK)\nasync def api_link_retrieve(\n    r: Request, link_id, wallet: WalletTypeInfo = Depends(get_key_type)\n):\n    link = await get_pay_link(link_id)\n\n    if not link:\n        raise HTTPException(\n            detail=\"Pay link does not exist.\", status_code=HTTPStatus.NOT_FOUND\n        )\n\n    if link.wallet != wallet.wallet.id:\n        raise HTTPException(\n            detail=\"Not your pay link.\", status_code=HTTPStatus.FORBIDDEN\n        )\n\n    return {**link.dict(), **{\"lnurl\": link.lnurl(r)}}\n\n\n@lnurlp_ext.post(\"/api/v1/links\", status_code=HTTPStatus.CREATED)\n@lnurlp_ext.put(\"/api/v1/links/{link_id}\", status_code=HTTPStatus.OK)\nasync def api_link_create_or_update(\n    data: CreatePayLinkData,\n    link_id=None,\n    wallet: WalletTypeInfo = Depends(get_key_type),\n):\n\n    if data.min > data.max:\n        raise HTTPException(\n            detail=\"Min is greater than max.\", status_code=HTTPStatus.BAD_REQUEST\n        )\n\n    if data.currency == None and (\n        round(data.min) != data.min or round(data.max) != data.max or data.min < 1\n    ):\n        raise HTTPException(\n            detail=\"Must use full satoshis.\", status_code=HTTPStatus.BAD_REQUEST\n        )\n\n    # database only allows int4 entries for min and max. For fiat currencies,\n    # we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents.\n    if data.currency and data.fiat_base_multiplier:\n        data.min *= data.fiat_base_multiplier\n        data.max *= data.fiat_base_multiplier\n\n    if \"success_url\" in data and data.success_url[:8] != \"https://\":\n        raise HTTPException(\n            detail=\"Success URL must be secure https://...\",\n            status_code=HTTPStatus.BAD_REQUEST,\n        )\n\n    if link_id:\n        link = await get_pay_link(link_id)\n\n        if not link:\n            raise HTTPException(\n                detail=\"Pay link does not exist.\", status_code=HTTPStatus.NOT_FOUND\n            )\n\n        if link.wallet != wallet.wallet.id:\n            raise HTTPException(\n                detail=\"Not your pay link.\", status_code=HTTPStatus.FORBIDDEN\n            )\n\n        link = await update_pay_link(**data.dict(), link_id=link_id)\n    else:\n        link = await create_pay_link(data, wallet_id=wallet.wallet.id)\n    return {**link.dict(), \"lnurl\": link.lnurl}\n\n\n@lnurlp_ext.delete(\"/api/v1/links/{link_id}\")\nasync def api_link_delete(link_id, wallet: WalletTypeInfo = Depends(get_key_type)):\n    link = await get_pay_link(link_id)\n\n    if not link:\n        raise HTTPException(\n            detail=\"Pay link does not exist.\", status_code=HTTPStatus.NOT_FOUND\n        )\n\n    if link.wallet != wallet.wallet.id:\n        raise HTTPException(\n            detail=\"Not your pay link.\", status_code=HTTPStatus.FORBIDDEN\n        )\n\n    await delete_pay_link(link_id)\n    raise HTTPException(status_code=HTTPStatus.NO_CONTENT)\n\n\n@lnurlp_ext.get(\"/api/v1/rate/{currency}\", status_code=HTTPStatus.OK)\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 {\"rate\": rate}\n", "path": "lnbits/extensions/lnurlp/views_api.py"}, {"content": "from typing import List, Optional, Union\n\nfrom lnbits.db import SQLITE\nfrom . import db\nfrom .models import PayLink, CreatePayLinkData\n\n\nasync def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:\n\n    returning = \"\" if db.type == SQLITE else \"RETURNING ID\"\n    method = db.execute if db.type == SQLITE else db.fetchone\n\n    result = await (method)(\n        f\"\"\"\n        INSERT INTO lnurlp.pay_links (\n            wallet,\n            description,\n            min,\n            max,\n            served_meta,\n            served_pr,\n            webhook_url,\n            success_text,\n            success_url,\n            comment_chars,\n            currency,\n            fiat_base_multiplier\n        )\n        VALUES (?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?)\n        {returning}\n        \"\"\",\n        (\n            wallet_id,\n            data.description,\n            data.min,\n            data.max,\n            data.webhook_url,\n            data.success_text,\n            data.success_url,\n            data.comment_chars,\n            data.currency,\n            data.fiat_base_multiplier,\n        ),\n    )\n    if db.type == SQLITE:\n        link_id = result._result_proxy.lastrowid\n    else:\n        link_id = result[0]\n\n    link = await get_pay_link(link_id)\n    assert link, \"Newly created link couldn't be retrieved\"\n    return link\n\n\nasync def get_pay_link(link_id: int) -> Optional[PayLink]:\n    row = await db.fetchone(\"SELECT * FROM lnurlp.pay_links WHERE id = ?\", (link_id,))\n    return PayLink.from_row(row) if row else None\n\n\nasync def get_pay_links(wallet_ids: Union[str, List[str]]) -> List[PayLink]:\n    if isinstance(wallet_ids, str):\n        wallet_ids = [wallet_ids]\n\n    q = \",\".join([\"?\"] * len(wallet_ids))\n    rows = await db.fetchall(\n        f\"\"\"\n        SELECT * FROM lnurlp.pay_links WHERE wallet IN ({q})\n        ORDER BY Id\n        \"\"\",\n        (*wallet_ids,),\n    )\n    return [PayLink.from_row(row) for row in rows]\n\n\nasync def update_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:\n    q = \", \".join([f\"{field[0]} = ?\" for field in kwargs.items()])\n    await db.execute(\n        f\"UPDATE lnurlp.pay_links SET {q} WHERE id = ?\", (*kwargs.values(), link_id)\n    )\n    row = await db.fetchone(\"SELECT * FROM lnurlp.pay_links WHERE id = ?\", (link_id,))\n    return PayLink.from_row(row) if row else None\n\n\nasync def increment_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:\n    q = \", \".join([f\"{field[0]} = {field[0]} + ?\" for field in kwargs.items()])\n    await db.execute(\n        f\"UPDATE lnurlp.pay_links SET {q} WHERE id = ?\", (*kwargs.values(), link_id)\n    )\n    row = await db.fetchone(\"SELECT * FROM lnurlp.pay_links WHERE id = ?\", (link_id,))\n    return PayLink.from_row(row) if row else None\n\n\nasync def delete_pay_link(link_id: int) -> None:\n    await db.execute(\"DELETE FROM lnurlp.pay_links WHERE id = ?\", (link_id,))\n", "path": "lnbits/extensions/lnurlp/crud.py"}]}