diff --git a/templates/lnurldevice/atm.html b/templates/lnurldevice/atm.html index a0e80b1..c7fbedb 100644 --- a/templates/lnurldevice/atm.html +++ b/templates/lnurldevice/atm.html @@ -29,26 +29,26 @@ > - Amount is too small to send over onchain, needs to be 10000+ + Amount is too small to send over onchain, needs to be 50000+ sats Onchain not available - Amount is too small to send over liquid, needs to be 2000+ + Amount is too small to send over liquid, needs to be 10000+ sats Onchain not available @@ -232,11 +232,11 @@

this.tab = val.name }, sendOnchainAddress() { - this.onchain_liquid = 'BTC-BTC' + this.onchain_liquid = 'BTCtempBTC' this.sendAddress() }, sendLiquidAddress() { - this.onchain_liquid = 'L-BTC-BTC' + this.onchain_liquid = 'L-BTCtempBTC' this.sendAddress() }, async sendAddress() { @@ -247,8 +247,8 @@

'' ) if (response.data) { + this.ln = '' this.notifyUser('Payment should be with you shortly', 'positive') - this.connectWebsocket(payment_id) } } catch (error) { this.notifyApiError(error) diff --git a/views_api.py b/views_api.py index 38e1c68..71a8b28 100644 --- a/views_api.py +++ b/views_api.py @@ -1,5 +1,6 @@ from http import HTTPStatus +import bolt11 import httpx from fastapi import APIRouter, Depends, HTTPException, Request from lnbits.core.crud import get_user, get_wallet @@ -29,7 +30,7 @@ ) from .helpers import register_atm_payment from .models import CreateLnurldevice, Lnurlencode - +from loguru import logger lnurldevice_api_router = APIRouter() @@ -158,12 +159,6 @@ async def get_lnurldevice_payment_lightning( status_code=HTTPStatus.NOT_FOUND, detail="Payment already claimed." ) - # If its an invoice check its a legit invoice - if ln[:4] == "lnbc": - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="Invoices not supported." - ) - # If its an lnaddress or lnurlp get the request from callback elif ln[:5] == "lnurl" or "@" in ln and "." in ln.split("@")[-1]: data = await api_lnurlscan(ln) @@ -183,6 +178,10 @@ async def get_lnurldevice_payment_lightning( ) ln = response.json()["pr"] + # If just an invoice + elif ln[:4] == "lnbc": + ln = ln + # If ln is gibberish, return an error else: raise HTTPException( @@ -193,6 +192,22 @@ async def get_lnurldevice_payment_lightning( """, ) + # If its an invoice check its a legit invoice + if ln[:4] == "lnbc": + invoice = bolt11.decode(ln) + if not invoice.payment_hash: + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, detail="Not valid payment request" + ) + if not invoice.payment_hash: + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, detail="Not valid payment request" + ) + if int(invoice.amount_msat / 1000) != lnurldevicepayment.sats: + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, detail="Request is not the same as withdraw amount" + ) + # Finally log the payment and make the payment try: lnurldevicepayment, price_msat = await register_atm_payment(lnurldevice, p) @@ -215,7 +230,7 @@ async def get_lnurldevice_payment_lightning( @lnurldevice_api_router.get( - "'/api/v1/boltz/{lnurldevice_id}/{payload}/{onchain_liquid}/{address}" + "/api/v1/boltz/{lnurldevice_id}/{payload}/{onchain_liquid}/{address}" ) async def get_lnurldevice_payment_boltz( req: Request, lnurldevice_id: str, payload: str, onchain_liquid: str, address: str @@ -246,11 +261,15 @@ async def get_lnurldevice_payment_boltz( data = { "wallet": lnurldevice.wallet, - "asset": onchain_liquid.replace("-", "/"), - "amount": price_msat, + "asset": onchain_liquid.replace("temp", "/"), + "amount": lnurldevicepayment.sats, + "direction": "send", "instant_settlement": True, "onchain_address": address, + "feerate": False, + "feerate_value": 0, } + try: lnurldevicepayment.payload = payload await update_lnurldevicepayment(lnurldevicepayment) @@ -258,8 +277,9 @@ async def get_lnurldevice_payment_boltz( response = await client.post( url=f"http://{settings.host}:{settings.port}/boltz/api/v1/swap/reverse", headers={"X-API-KEY": wallet.adminkey}, - data=data, + json=data, ) - return response.json() + resp = response.json() + return resp except Exception as exc: return {"status": "ERROR", "reason": str(exc)} diff --git a/views_lnurl.py b/views_lnurl.py index 3453983..fc51100 100644 --- a/views_lnurl.py +++ b/views_lnurl.py @@ -16,6 +16,8 @@ ) from .helpers import register_atm_payment, xor_decrypt +from loguru import logger + lnurldevice_lnurl_router = APIRouter() @@ -219,39 +221,46 @@ async def lnurl_callback( raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="Not valid payment request" ) + if not invoice.payment_hash: + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, detail="Not valid payment request" + ) + if int(invoice.amount_msat / 1000) != lnurldevicepayment.sats: + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, detail="Request is not the same as withdraw amount" + ) wallet = await get_wallet(device.wallet) assert wallet if wallet.balance_msat < (int(lnurldevicepayment.sats / 1000) + 100): raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="Not enough funds" ) - else: - if lnurldevicepayment.payload != k1: - return {"status": "ERROR", "reason": "Bad K1"} - if lnurldevicepayment.payhash != "payment_hash": - return {"status": "ERROR", "reason": "Payment already claimed"} - try: - lnurldevicepayment.payhash = lnurldevicepayment.payload - lnurldevicepayment_updated = await update_lnurldevicepayment( - lnurldevicepayment - ) - assert lnurldevicepayment_updated - await pay_invoice( - wallet_id=device.wallet, - payment_request=pr, - max_sat=int(lnurldevicepayment_updated.sats / 1000), - extra={"tag": "withdraw"}, - ) - except Exception as exc: - lnurldevicepayment.payhash = "payment_hash" - lnurldevicepayment_updated = await update_lnurldevicepayment( - lnurldevicepayment - ) - assert lnurldevicepayment_updated - raise HTTPException( - status_code=HTTPStatus.FORBIDDEN, detail="Failed to make payment" - ) from exc - return {"status": "OK"} + if lnurldevicepayment.payload != k1: + return {"status": "ERROR", "reason": "Bad K1"} + if lnurldevicepayment.payhash != "payment_hash": + return {"status": "ERROR", "reason": "Payment already claimed"} + try: + lnurldevicepayment.payhash = lnurldevicepayment.payload + lnurldevicepayment_updated = await update_lnurldevicepayment( + lnurldevicepayment + ) + assert lnurldevicepayment_updated + await pay_invoice( + wallet_id=device.wallet, + payment_request=pr, + max_sat=int(lnurldevicepayment_updated.sats / 1000), + extra={"tag": "lnurldevice_withdraw"}, + ) + except Exception as exc: + lnurldevicepayment.payhash = "payment_hash" + lnurldevicepayment_updated = await update_lnurldevicepayment( + lnurldevicepayment + ) + assert lnurldevicepayment_updated + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, detail="Failed to make payment" + ) from exc + return {"status": "OK"} if device.device == "switch": if not amount: return {"status": "ERROR", "reason": "No amount"}