diff --git a/crud.py b/crud.py
index 202f0c8..af52485 100644
--- a/crud.py
+++ b/crud.py
@@ -216,7 +216,9 @@ async def get_lnurldevicepayment(
async def get_lnurldevicepayments(
lnurldevice_ids: List[str],
-) -> List[LnurldevicePayment]:
+) -> Optional[List[LnurldevicePayment]]:
+ if not lnurldevice_ids:
+ return []
q = ",".join(["?"] * len(lnurldevice_ids))
rows = await db.fetchall(
f"""
diff --git a/helpers.py b/helpers.py
index 31eb92f..fdc8f96 100644
--- a/helpers.py
+++ b/helpers.py
@@ -16,17 +16,7 @@ async def register_atm_payment(
"""
Register an ATM payment to avoid double pull.
"""
- lnurldevicepayment = await get_recent_lnurldevicepayment(payload)
- # If the payment is already registered and been paid, return None
- if lnurldevicepayment and lnurldevicepayment.payload == lnurldevicepayment.payhash:
- return None, None
- # If the payment is already registered and not been paid, return lnurlpayment record
- elif (
- lnurldevicepayment and lnurldevicepayment.payload != lnurldevicepayment.payhash
- ):
- return lnurldevicepayment, None
-
- # else create a new lnurlpayment record
+ # create a new lnurlpayment record
data = base64.urlsafe_b64decode(payload)
decrypted = xor_decrypt(device.key.encode(), data)
price_msat = (
@@ -34,7 +24,16 @@ async def register_atm_payment(
if device.currency != "sat"
else decrypted[1] * 1000
)
- price_msat = int(price_msat * ((device.profit / 100) + 1))
+ price_msat = int(price_msat - ((price_msat / 100) * device.profit))
+
+ lnurldevicepayment = await get_recent_lnurldevicepayment(payload)
+ # If the payment is already registered and been paid, return None
+ if lnurldevicepayment and lnurldevicepayment.payload == lnurldevicepayment.payhash:
+ return None, price_msat
+ # If the payment is already registered and not been paid, return lnurlpayment record
+ if lnurldevicepayment and lnurldevicepayment.payload != lnurldevicepayment.payhash:
+ return lnurldevicepayment, price_msat
+
lnurldevicepayment = await create_lnurldevicepayment(
deviceid=device.id,
payload=payload,
diff --git a/models.py b/models.py
index ff6d6ab..b280a7a 100644
--- a/models.py
+++ b/models.py
@@ -32,7 +32,6 @@ class Lnurldevice(BaseModel):
currency: str
device: str
extra: Optional[Union[Json[List[LnurldeviceExtra]], str]]
- timestamp: str
@property
def lnurlpay_metadata(self) -> LnurlPayMetadata:
@@ -46,7 +45,6 @@ class LnurldevicePayment(BaseModel):
payload: str
pin: int
sats: int
- timestamp: str
class Lnurlencode(BaseModel):
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..e312ef7 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,6 +30,7 @@
)
from .helpers import register_atm_payment
from .models import CreateLnurldevice, Lnurlencode
+from loguru import logger
lnurldevice_api_router = APIRouter()
@@ -158,12 +160,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 +179,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 +193,23 @@ 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 +232,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 +263,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 +279,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..9d0454d 100644
--- a/views_lnurl.py
+++ b/views_lnurl.py
@@ -12,6 +12,7 @@
create_lnurldevicepayment,
get_lnurldevice,
get_lnurldevicepayment,
+ delete_atm_payment_link,
update_lnurldevicepayment,
)
from .helpers import register_atm_payment, xor_decrypt
@@ -199,59 +200,56 @@ async def lnurl_callback(
):
lnurldevicepayment = await get_lnurldevicepayment(paymentid)
if not lnurldevicepayment:
- raise HTTPException(
- status_code=HTTPStatus.NOT_FOUND, detail="lnurldevicepayment not found."
- )
+ return {"status": "ERROR", "reason": "lnurldevicepayment not found."}
device = await get_lnurldevice(lnurldevicepayment.deviceid, request)
if not device:
- raise HTTPException(
- status_code=HTTPStatus.NOT_FOUND, detail="lnurldevice not found."
- )
+ await delete_atm_payment_link(paymentid)
+ return {"status": "ERROR", "reason": "lnurldevice not found."}
if device.device == "atm":
if lnurldevicepayment.payload == lnurldevicepayment.payhash:
+ await delete_atm_payment_link(paymentid)
return {"status": "ERROR", "reason": "Payment already claimed"}
if not pr:
- raise HTTPException(
- status_code=HTTPStatus.FORBIDDEN, detail="No payment request"
- )
+ await delete_atm_payment_link(paymentid)
+ return {"status": "ERROR", "reason": "No payment request."}
invoice = bolt11.decode(pr)
if not invoice.payment_hash:
- raise HTTPException(
- status_code=HTTPStatus.FORBIDDEN, detail="Not valid payment request"
- )
+ await delete_atm_payment_link(paymentid)
+ return {"status": "ERROR", "reason": "Not valid payment request."}
+ if not invoice.payment_hash:
+ await delete_atm_payment_link(paymentid)
+ return {"status": "ERROR", "reason": "Not valid payment request."}
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"
+ await delete_atm_payment_link(paymentid)
+ return {"status": "ERROR", "reason": "Not enough funds."}
+ if lnurldevicepayment.payload != k1:
+ await delete_atm_payment_link(paymentid)
+ return {"status": "ERROR", "reason": "Bad K1"}
+ if lnurldevicepayment.payhash != "payment_hash":
+ await delete_atm_payment_link(paymentid)
+ return {"status": "ERROR", "reason": "Payment already claimed"}
+ try:
+ lnurldevicepayment.payhash = lnurldevicepayment.payload
+ lnurldevicepayment_updated = await update_lnurldevicepayment(
+ lnurldevicepayment
)
- 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"}
+ 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:
+ lnurldevicepayment.payhash = "payment_hash"
+ lnurldevicepayment_updated = await update_lnurldevicepayment(
+ lnurldevicepayment
+ )
+ assert lnurldevicepayment_updated
+ return {"status": "ERROR", "reason": "Failed to make payment."}
+ return {"status": "OK"}
if device.device == "switch":
if not amount:
return {"status": "ERROR", "reason": "No amount"}