Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed Description Hash Issue on Opennode #56

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lnurl.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from lnbits.core.services import create_invoice
from lnbits.utils.exchange_rates import get_fiat_rate_satoshis

from lnbits.wallets import get_funding_source
from . import lnurlp_ext
from .crud import (
get_or_create_lnurlp_settings,
Expand Down Expand Up @@ -92,7 +92,7 @@ async def api_lnurl_callback(
wallet_id=link.wallet,
amount=int(amount / 1000),
memo=link.description,
unhashed_description=unhashed_description,
unhashed_description=None if get_funding_source().__class__.__name__ == "OpenNodeWallet" else unhashed_description,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an ugly hack and a layering violation - maybe there is a better way how to fix the issue?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about adding a member for each wallet class like is_deschash_required and checking it here ?

extra=extra,
)

Expand Down
5 changes: 5 additions & 0 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,8 @@ def lnurlpay_metadata(self) -> LnurlPayMetadata:
metadata = [["text/plain", self.description]]

return LnurlPayMetadata(json.dumps(metadata))



class PayLnurlWData(BaseModel):
lnurl: str
2 changes: 2 additions & 0 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ async def wait_for_paid_invoices():

while True:
payment = await invoice_queue.get()

await on_invoice_paid(payment)


async def on_invoice_paid(payment: Payment):

if payment.extra.get("tag") != "lnurlp":
return

Expand Down
69 changes: 66 additions & 3 deletions views_api.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import json
from http import HTTPStatus
from typing import Optional

import httpx
from fastapi import Depends, Query, Request
from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl
from starlette.exceptions import HTTPException

from lnbits.core.crud import get_user, get_wallet
from lnbits.decorators import WalletTypeInfo, check_admin, get_key_type, require_admin_key, require_invoice_key
from lnbits.utils.exchange_rates import currencies, get_fiat_rate_satoshis

from lnurl import decode as decode_lnurl
from . import lnurlp_ext
from .crud import (
create_pay_link,
Expand All @@ -26,7 +26,7 @@
from .services import check_lnaddress_format
from .helpers import parse_nostr_private_key
from .lnurl import api_lnurl_response
from .models import CreatePayLinkData, LnurlpSettings
from .models import CreatePayLinkData, LnurlpSettings, PayLnurlWData


# redirected from /.well-known/lnurlp
Expand Down Expand Up @@ -238,3 +238,66 @@ async def api_update_settings(data: LnurlpSettings) -> LnurlpSettings:
@lnurlp_ext.delete("/api/v1/settings", dependencies=[Depends(check_admin)])
async def api_delete_settings() -> None:
await delete_lnurlp_settings()



@lnurlp_ext.post(
"/api/v1/links/{link_id}/invoices/{payment_request}/pay", status_code=HTTPStatus.OK
)
async def api_link_pay_invoice(
lnurl_data: PayLnurlWData, payment_request: str, link_id: str
):
tpos = await get_pay_link(link_id)

if not tpos:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Link does not exist."
)

lnurl = (
lnurl_data.lnurl.replace("lnurlw://", "")
.replace("lightning://", "")
.replace("LIGHTNING://", "")
.replace("lightning:", "")
.replace("LIGHTNING:", "")
)

if lnurl.lower().startswith("lnurl"):
lnurl = decode_lnurl(lnurl)
else:
lnurl = "https://" + lnurl

async with httpx.AsyncClient() as client:
try:
headers = {"user-agent": "lnbits/lnurlp"}
r = await client.get(lnurl, follow_redirects=True, headers=headers)
if r.is_error:
lnurl_response = {"success": False, "detail": "Error loading"}
else:
resp = r.json()
if resp["tag"] != "withdrawRequest":
lnurl_response = {"success": False, "detail": "Wrong tag type"}
else:
r2 = await client.get(
resp["callback"],
follow_redirects=True,
headers=headers,
params={
"k1": resp["k1"],
"pr": payment_request,
},
)
resp2 = r2.json()
if r2.is_error:
lnurl_response = {
"success": False,
"detail": "Error loading callback",
}
elif resp2["status"] == "ERROR":
lnurl_response = {"success": False, "detail": resp2["reason"]}
else:
lnurl_response = {"success": True, "detail": resp2}
except (httpx.ConnectError, httpx.RequestError):
lnurl_response = {"success": False, "detail": "Unexpected error occurred"}

return lnurl_response