diff --git a/lnbits/extensions/lnurldevice/README.md b/lnbits/extensions/lnurldevice/README.md
deleted file mode 100644
index 01ce6382..00000000
--- a/lnbits/extensions/lnurldevice/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# LNURLDevice
-
-For offline LNURL devices
diff --git a/lnbits/extensions/lnurldevice/__init__.py b/lnbits/extensions/lnurldevice/__init__.py
deleted file mode 100644
index 56e9d8f7..00000000
--- a/lnbits/extensions/lnurldevice/__init__.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import asyncio
-
-from fastapi import APIRouter
-from starlette.staticfiles import StaticFiles
-
-from lnbits.db import Database
-from lnbits.helpers import template_renderer
-from lnbits.tasks import catch_everything_and_restart
-
-db = Database("ext_lnurldevice")
-
-lnurldevice_ext: APIRouter = APIRouter(prefix="/lnurldevice", tags=["lnurldevice"])
-
-lnurldevice_static_files = [
- {
- "path": "/lnurldevice/static",
- "app": StaticFiles(directory="lnbits/extensions/lnurldevice/static"),
- "name": "lnurldevice_static",
- }
-]
-
-
-def lnurldevice_renderer():
- return template_renderer(["lnbits/extensions/lnurldevice/templates"])
-
-
-from .lnurl import * # noqa: F401,F403
-from .tasks import wait_for_paid_invoices
-from .views import * # noqa: F401,F403
-from .views_api import * # noqa: F401,F403
-
-
-def lnurldevice_start():
- loop = asyncio.get_event_loop()
- loop.create_task(catch_everything_and_restart(wait_for_paid_invoices))
diff --git a/lnbits/extensions/lnurldevice/config.json b/lnbits/extensions/lnurldevice/config.json
deleted file mode 100644
index 0712d729..00000000
--- a/lnbits/extensions/lnurldevice/config.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "LNURLDevice",
- "short_description": "For offline LNURL devices",
- "tile": "/lnurldevice/static/image/lnurldevice.png",
- "contributors": ["arcbtc"]
-}
diff --git a/lnbits/extensions/lnurldevice/crud.py b/lnbits/extensions/lnurldevice/crud.py
deleted file mode 100644
index 8e15d4ec..00000000
--- a/lnbits/extensions/lnurldevice/crud.py
+++ /dev/null
@@ -1,177 +0,0 @@
-from typing import List, Optional
-
-import shortuuid
-
-from lnbits.helpers import urlsafe_short_hash
-
-from . import db
-from .models import createLnurldevice, lnurldevicepayment, lnurldevices
-
-
-async def create_lnurldevice(
- data: createLnurldevice,
-) -> lnurldevices:
- if data.device == "pos" or data.device == "atm":
- lnurldevice_id = shortuuid.uuid()[:5]
- else:
- lnurldevice_id = urlsafe_short_hash()
- lnurldevice_key = urlsafe_short_hash()
- await db.execute(
- """
- INSERT INTO lnurldevice.lnurldevices (
- id,
- key,
- title,
- wallet,
- currency,
- device,
- profit,
- amount,
- pin,
- profit1,
- amount1,
- pin1,
- profit2,
- amount2,
- pin2,
- profit3,
- amount3,
- pin3,
- profit4,
- amount4,
- pin4
- )
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- """,
- (
- lnurldevice_id,
- lnurldevice_key,
- data.title,
- data.wallet,
- data.currency,
- data.device,
- data.profit,
- data.amount,
- data.pin,
- data.profit1,
- data.amount1,
- data.pin1,
- data.profit2,
- data.amount2,
- data.pin2,
- data.profit3,
- data.amount3,
- data.pin3,
- data.profit4,
- data.amount4,
- data.pin4,
- ),
- )
- device = await get_lnurldevice(lnurldevice_id)
- assert device
- return device
-
-
-async def update_lnurldevice(lnurldevice_id: str, **kwargs) -> lnurldevices:
- q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
- await db.execute(
- f"UPDATE lnurldevice.lnurldevices SET {q} WHERE id = ?",
- (*kwargs.values(), lnurldevice_id),
- )
- row = await db.fetchone(
- "SELECT * FROM lnurldevice.lnurldevices WHERE id = ?", (lnurldevice_id,)
- )
- return lnurldevices(**row)
-
-
-async def get_lnurldevice(lnurldevice_id: str) -> Optional[lnurldevices]:
- row = await db.fetchone(
- "SELECT * FROM lnurldevice.lnurldevices WHERE id = ?", (lnurldevice_id,)
- )
- return lnurldevices(**row) if row else None
-
-
-async def get_lnurldevices(wallet_ids: List[str]) -> List[lnurldevices]:
- q = ",".join(["?"] * len(wallet_ids))
- rows = await db.fetchall(
- f"""
- SELECT * FROM lnurldevice.lnurldevices WHERE wallet IN ({q})
- ORDER BY id
- """,
- (*wallet_ids,),
- )
-
- return [lnurldevices(**row) for row in rows]
-
-
-async def delete_lnurldevice(lnurldevice_id: str) -> None:
- await db.execute(
- "DELETE FROM lnurldevice.lnurldevices WHERE id = ?", (lnurldevice_id,)
- )
-
-
-async def create_lnurldevicepayment(
- deviceid: str,
- payload: Optional[str] = None,
- pin: Optional[str] = None,
- payhash: Optional[str] = None,
- sats: Optional[int] = 0,
-) -> lnurldevicepayment:
- device = await get_lnurldevice(deviceid)
- assert device
- if device.device == "atm":
- lnurldevicepayment_id = shortuuid.uuid(name=payload)
- else:
- lnurldevicepayment_id = urlsafe_short_hash()
- await db.execute(
- """
- INSERT INTO lnurldevice.lnurldevicepayment (
- id,
- deviceid,
- payload,
- pin,
- payhash,
- sats
- )
- VALUES (?, ?, ?, ?, ?, ?)
- """,
- (lnurldevicepayment_id, deviceid, payload, pin, payhash, sats),
- )
- dpayment = await get_lnurldevicepayment(lnurldevicepayment_id)
- assert dpayment
- return dpayment
-
-
-async def update_lnurldevicepayment(
- lnurldevicepayment_id: str, **kwargs
-) -> Optional[lnurldevicepayment]:
- q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
- await db.execute(
- f"UPDATE lnurldevice.lnurldevicepayment SET {q} WHERE id = ?",
- (*kwargs.values(), lnurldevicepayment_id),
- )
- row = await db.fetchone(
- "SELECT * FROM lnurldevice.lnurldevicepayment WHERE id = ?",
- (lnurldevicepayment_id,),
- )
- return lnurldevicepayment(**row) if row else None
-
-
-async def get_lnurldevicepayment(
- lnurldevicepayment_id: str,
-) -> Optional[lnurldevicepayment]:
- row = await db.fetchone(
- "SELECT * FROM lnurldevice.lnurldevicepayment WHERE id = ?",
- (lnurldevicepayment_id,),
- )
- return lnurldevicepayment(**row) if row else None
-
-
-async def get_lnurlpayload(
- lnurldevicepayment_payload: str,
-) -> Optional[lnurldevicepayment]:
- row = await db.fetchone(
- "SELECT * FROM lnurldevice.lnurldevicepayment WHERE payload = ?",
- (lnurldevicepayment_payload,),
- )
- return lnurldevicepayment(**row) if row else None
diff --git a/lnbits/extensions/lnurldevice/lnurl.py b/lnbits/extensions/lnurldevice/lnurl.py
deleted file mode 100644
index 20e113d5..00000000
--- a/lnbits/extensions/lnurldevice/lnurl.py
+++ /dev/null
@@ -1,295 +0,0 @@
-import base64
-import hmac
-from http import HTTPStatus
-from io import BytesIO
-
-from embit import bech32, compact
-from fastapi import HTTPException, Query, Request
-
-from lnbits import bolt11
-from lnbits.core.services import create_invoice
-from lnbits.core.views.api import pay_invoice
-from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
-
-from . import lnurldevice_ext
-from .crud import (
- create_lnurldevicepayment,
- get_lnurldevice,
- get_lnurldevicepayment,
- update_lnurldevicepayment,
-)
-
-
-def bech32_decode(bech):
- """tweaked version of bech32_decode that ignores length limitations"""
- if (any(ord(x) < 33 or ord(x) > 126 for x in bech)) or (
- bech.lower() != bech and bech.upper() != bech
- ):
- return
- bech = bech.lower()
- device = bech.rfind("1")
- if device < 1 or device + 7 > len(bech):
- return
- if not all(x in bech32.CHARSET for x in bech[device + 1 :]):
- return
- hrp = bech[:device]
- data = [bech32.CHARSET.find(x) for x in bech[device + 1 :]]
- encoding = bech32.bech32_verify_checksum(hrp, data)
- if encoding is None:
- return
- bits = bech32.convertbits(data[:-6], 5, 8, False)
- assert bits
- return bytes(bits)
-
-
-def xor_decrypt(key, blob):
- s = BytesIO(blob)
- variant = s.read(1)[0]
- if variant != 1:
- raise RuntimeError("Not implemented")
- # reading nonce
- l = s.read(1)[0]
- nonce = s.read(l)
- if len(nonce) != l:
- raise RuntimeError("Missing nonce bytes")
- if l < 8:
- raise RuntimeError("Nonce is too short")
- # reading payload
- l = s.read(1)[0]
- payload = s.read(l)
- if len(payload) > 32:
- raise RuntimeError("Payload is too long for this encryption method")
- if len(payload) != l:
- raise RuntimeError("Missing payload bytes")
- hmacval = s.read()
- expected = hmac.new(
- key, b"Data:" + blob[: -len(hmacval)], digestmod="sha256"
- ).digest()
- if len(hmacval) < 8:
- raise RuntimeError("HMAC is too short")
- if hmacval != expected[: len(hmacval)]:
- raise RuntimeError("HMAC is invalid")
- secret = hmac.new(key, b"Round secret:" + nonce, digestmod="sha256").digest()
- payload = bytearray(payload)
- for i in range(len(payload)):
- payload[i] = payload[i] ^ secret[i]
- s = BytesIO(payload)
- pin = compact.read_from(s)
- amount_in_cent = compact.read_from(s)
- return pin, amount_in_cent
-
-
-@lnurldevice_ext.get(
- "/api/v1/lnurl/{device_id}",
- status_code=HTTPStatus.OK,
- name="lnurldevice.lnurl_v1_params",
-)
-async def lnurl_v1_params(
- request: Request,
- device_id: str = Query(None),
- p: str = Query(None),
- atm: str = Query(None),
- gpio: str = Query(None),
- profit: str = Query(None),
- amount: str = Query(None),
-):
- device = await get_lnurldevice(device_id)
- if not device:
- return {
- "status": "ERROR",
- "reason": f"lnurldevice {device_id} not found on this server",
- }
- if device.device == "switch":
- # TODO: AMOUNT IN CENT was never reference here
- amount_in_cent = 0
- price_msat = (
- await fiat_amount_as_satoshis(float(profit), device.currency)
- if device.currency != "sat"
- else amount_in_cent
- ) * 1000
-
- # Check they're not trying to trick the switch!
- check = False
- for switch in device.switches(request):
- if switch[0] == gpio and switch[1] == profit and switch[2] == amount:
- check = True
- if not check:
- return {"status": "ERROR", "reason": "Switch params wrong"}
-
- lnurldevicepayment = await create_lnurldevicepayment(
- deviceid=device.id,
- payload=amount,
- sats=price_msat,
- pin=gpio,
- payhash="bla",
- )
- if not lnurldevicepayment:
- return {"status": "ERROR", "reason": "Could not create payment."}
- return {
- "tag": "payRequest",
- "callback": request.url_for(
- "lnurldevice.lnurl_callback", paymentid=lnurldevicepayment.id
- ),
- "minSendable": price_msat,
- "maxSendable": price_msat,
- "metadata": device.lnurlpay_metadata,
- }
- if len(p) % 4 > 0:
- p += "=" * (4 - (len(p) % 4))
-
- data = base64.urlsafe_b64decode(p)
- pin = 0
- amount_in_cent = 0
- try:
- result = xor_decrypt(device.key.encode(), data)
- pin = result[0]
- amount_in_cent = result[1]
- except Exception as exc:
- return {"status": "ERROR", "reason": str(exc)}
-
- price_msat = (
- await fiat_amount_as_satoshis(float(amount_in_cent) / 100, device.currency)
- if device.currency != "sat"
- else amount_in_cent
- ) * 1000
-
- if atm:
- if device.device != "atm":
- return {"status": "ERROR", "reason": "Not ATM device."}
- price_msat = int(price_msat * (1 - (device.profit / 100)) / 1000)
- try:
- lnurldevicepayment = await create_lnurldevicepayment(
- deviceid=device.id,
- payload=p,
- sats=price_msat * 1000,
- pin=str(pin),
- payhash="payment_hash",
- )
- except:
- return {"status": "ERROR", "reason": "Could not create ATM payment."}
- if not lnurldevicepayment:
- return {"status": "ERROR", "reason": "Could not create ATM payment."}
- return {
- "tag": "withdrawRequest",
- "callback": request.url_for(
- "lnurldevice.lnurl_callback", paymentid=lnurldevicepayment.id
- ),
- "k1": p,
- "minWithdrawable": price_msat * 1000,
- "maxWithdrawable": price_msat * 1000,
- "defaultDescription": device.title,
- }
- price_msat = int(price_msat * ((device.profit / 100) + 1) / 1000)
-
- lnurldevicepayment = await create_lnurldevicepayment(
- deviceid=device.id,
- payload=p,
- sats=price_msat * 1000,
- pin=str(pin),
- payhash="payment_hash",
- )
- if not lnurldevicepayment:
- return {"status": "ERROR", "reason": "Could not create payment."}
- return {
- "tag": "payRequest",
- "callback": request.url_for(
- "lnurldevice.lnurl_callback", paymentid=lnurldevicepayment.id
- ),
- "minSendable": price_msat * 1000,
- "maxSendable": price_msat * 1000,
- "metadata": device.lnurlpay_metadata,
- }
-
-
-@lnurldevice_ext.get(
- "/api/v1/lnurl/cb/{paymentid}",
- status_code=HTTPStatus.OK,
- name="lnurldevice.lnurl_callback",
-)
-async def lnurl_callback(
- request: Request,
- paymentid: str = Query(None),
- pr: str = Query(None),
- k1: str = Query(None),
-):
- lnurldevicepayment = await get_lnurldevicepayment(paymentid)
- if not lnurldevicepayment:
- raise HTTPException(
- status_code=HTTPStatus.FORBIDDEN, detail="lnurldevicepayment not found."
- )
- device = await get_lnurldevice(lnurldevicepayment.deviceid)
- if not device:
- raise HTTPException(
- status_code=HTTPStatus.FORBIDDEN, detail="lnurldevice not found."
- )
- if device.device == "atm":
- if lnurldevicepayment.payload == lnurldevicepayment.payhash:
- return {"status": "ERROR", "reason": "Payment already claimed"}
- if not pr:
- raise HTTPException(
- status_code=HTTPStatus.FORBIDDEN, detail="No payment request"
- )
- invoice = bolt11.decode(pr)
- if not invoice.payment_hash:
- raise HTTPException(
- status_code=HTTPStatus.FORBIDDEN, detail="Not valid payment request"
- )
- else:
- if lnurldevicepayment.payload != k1:
- return {"status": "ERROR", "reason": "Bad K1"}
- if lnurldevicepayment.payhash != "payment_hash":
- return {"status": "ERROR", "reason": "Payment already claimed"}
-
- lnurldevicepayment_updated = await update_lnurldevicepayment(
- lnurldevicepayment_id=paymentid, payhash=lnurldevicepayment.payload
- )
- assert lnurldevicepayment_updated
- await pay_invoice(
- wallet_id=device.wallet,
- payment_request=pr,
- max_sat=int(lnurldevicepayment_updated.sats / 1000),
- extra={"tag": "withdraw"},
- )
- return {"status": "OK"}
- if device.device == "switch":
- payment_hash, payment_request = await create_invoice(
- wallet_id=device.wallet,
- amount=int(lnurldevicepayment.sats / 1000),
- memo=device.id + " PIN " + str(lnurldevicepayment.pin),
- unhashed_description=device.lnurlpay_metadata.encode(),
- extra={
- "tag": "Switch",
- "pin": str(lnurldevicepayment.pin),
- "amount": str(lnurldevicepayment.payload),
- "id": paymentid,
- },
- )
-
- lnurldevicepayment = await update_lnurldevicepayment(
- lnurldevicepayment_id=paymentid, payhash=payment_hash
- )
- return {
- "pr": payment_request,
- "routes": [],
- }
-
- payment_hash, payment_request = await create_invoice(
- wallet_id=device.wallet,
- amount=int(lnurldevicepayment.sats / 1000),
- memo=device.title,
- unhashed_description=device.lnurlpay_metadata.encode(),
- extra={"tag": "PoS"},
- )
- lnurldevicepayment = await update_lnurldevicepayment(
- lnurldevicepayment_id=paymentid, payhash=payment_hash
- )
-
- return {
- "pr": payment_request,
- "successAction": {
- "tag": "url",
- "description": "Check the attached link",
- "url": request.url_for("lnurldevice.displaypin", paymentid=paymentid),
- },
- "routes": [],
- }
diff --git a/lnbits/extensions/lnurldevice/migrations.py b/lnbits/extensions/lnurldevice/migrations.py
deleted file mode 100644
index 7fd7d6c4..00000000
--- a/lnbits/extensions/lnurldevice/migrations.py
+++ /dev/null
@@ -1,139 +0,0 @@
-from lnbits.db import Database
-
-db2 = Database("ext_lnurlpos")
-
-
-async def m001_initial(db):
- """
- Initial lnurldevice table.
- """
- await db.execute(
- f"""
- CREATE TABLE lnurldevice.lnurldevices (
- id TEXT NOT NULL PRIMARY KEY,
- key TEXT NOT NULL,
- title TEXT NOT NULL,
- wallet TEXT NOT NULL,
- currency TEXT NOT NULL,
- device TEXT NOT NULL,
- profit FLOAT NOT NULL,
- timestamp TIMESTAMP NOT NULL DEFAULT {db.timestamp_now}
- );
- """
- )
- await db.execute(
- f"""
- CREATE TABLE lnurldevice.lnurldevicepayment (
- id TEXT NOT NULL PRIMARY KEY,
- deviceid TEXT NOT NULL,
- payhash TEXT,
- payload TEXT NOT NULL,
- pin INT,
- sats {db.big_int},
- timestamp TIMESTAMP NOT NULL DEFAULT {db.timestamp_now}
- );
- """
- )
-
-
-async def m002_redux(db):
- """
- Moves everything from lnurlpos to lnurldevice
- """
- try:
- for row in [
- list(row) for row in await db2.fetchall("SELECT * FROM lnurlpos.lnurlposs")
- ]:
- await db.execute(
- """
- INSERT INTO lnurldevice.lnurldevices (
- id,
- key,
- title,
- wallet,
- currency,
- device,
- profit
- )
- VALUES (?, ?, ?, ?, ?, ?, ?)
- """,
- (row[0], row[1], row[2], row[3], row[4], "pos", 0),
- )
- for row in [
- list(row)
- for row in await db2.fetchall("SELECT * FROM lnurlpos.lnurlpospayment")
- ]:
- await db.execute(
- """
- INSERT INTO lnurldevice.lnurldevicepayment (
- id,
- deviceid,
- payhash,
- payload,
- pin,
- sats
- )
- VALUES (?, ?, ?, ?, ?, ?)
- """,
- (row[0], row[1], row[3], row[4], row[5], row[6]),
- )
- except:
- return
-
-
-async def m003_redux(db):
- """
- Add 'meta' for storing various metadata about the wallet
- """
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN amount INT DEFAULT 0;"
- )
-
-
-async def m004_redux(db):
- """
- Add 'meta' for storing various metadata about the wallet
- """
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN pin INT DEFAULT 0"
- )
-
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN profit1 FLOAT DEFAULT 0"
- )
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN amount1 INT DEFAULT 0"
- )
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN pin1 INT DEFAULT 0"
- )
-
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN profit2 FLOAT DEFAULT 0"
- )
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN amount2 INT DEFAULT 0"
- )
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN pin2 INT DEFAULT 0"
- )
-
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN profit3 FLOAT DEFAULT 0"
- )
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN amount3 INT DEFAULT 0"
- )
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN pin3 INT DEFAULT 0"
- )
-
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN profit4 FLOAT DEFAULT 0"
- )
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN amount4 INT DEFAULT 0"
- )
- await db.execute(
- "ALTER TABLE lnurldevice.lnurldevices ADD COLUMN pin4 INT DEFAULT 0"
- )
diff --git a/lnbits/extensions/lnurldevice/models.py b/lnbits/extensions/lnurldevice/models.py
deleted file mode 100644
index f9640de1..00000000
--- a/lnbits/extensions/lnurldevice/models.py
+++ /dev/null
@@ -1,171 +0,0 @@
-import json
-from sqlite3 import Row
-from typing import List, Optional
-
-from fastapi import Request
-from lnurl import encode as lnurl_encode
-from lnurl.types import LnurlPayMetadata
-from pydantic import BaseModel
-
-
-class createLnurldevice(BaseModel):
- title: str
- wallet: str
- currency: str
- device: str
- profit: float = 0
- amount: Optional[int] = 0
- pin: int = 0
- profit1: float = 0
- amount1: int = 0
- pin1: int = 0
- profit2: float = 0
- amount2: int = 0
- pin2: int = 0
- profit3: float = 0
- amount3: int = 0
- pin3: int = 0
- profit4: float = 0
- amount4: int = 0
- pin4: int = 0
-
-
-class lnurldevices(BaseModel):
- id: str
- key: str
- title: str
- wallet: str
- currency: str
- device: str
- profit: float
- amount: int
- pin: int
- profit1: float
- amount1: int
- pin1: int
- profit2: float
- amount2: int
- pin2: int
- profit3: float
- amount3: int
- pin3: int
- profit4: float
- amount4: int
- pin4: int
- timestamp: str
-
- @classmethod
- def from_row(cls, row: Row) -> "lnurldevices":
- return cls(**dict(row))
-
- @property
- def lnurlpay_metadata(self) -> LnurlPayMetadata:
- return LnurlPayMetadata(json.dumps([["text/plain", self.title]]))
-
- def switches(self, req: Request) -> List:
- switches = []
- if self.profit > 0:
- url = req.url_for("lnurldevice.lnurl_v1_params", device_id=self.id)
- switches.append(
- [
- str(self.pin),
- str(self.profit),
- str(self.amount),
- lnurl_encode(
- url
- + "?gpio="
- + str(self.pin)
- + "&profit="
- + str(self.profit)
- + "&amount="
- + str(self.amount)
- ),
- ]
- )
- if self.profit1 > 0:
- url = req.url_for("lnurldevice.lnurl_v1_params", device_id=self.id)
- switches.append(
- [
- str(self.pin1),
- str(self.profit1),
- str(self.amount1),
- lnurl_encode(
- url
- + "?gpio="
- + str(self.pin1)
- + "&profit="
- + str(self.profit1)
- + "&amount="
- + str(self.amount1)
- ),
- ]
- )
- if self.profit2 > 0:
- url = req.url_for("lnurldevice.lnurl_v1_params", device_id=self.id)
- switches.append(
- [
- str(self.pin2),
- str(self.profit2),
- str(self.amount2),
- lnurl_encode(
- url
- + "?gpio="
- + str(self.pin2)
- + "&profit="
- + str(self.profit2)
- + "&amount="
- + str(self.amount2)
- ),
- ]
- )
- if self.profit3 > 0:
- url = req.url_for("lnurldevice.lnurl_v1_params", device_id=self.id)
- switches.append(
- [
- str(self.pin3),
- str(self.profit3),
- str(self.amount3),
- lnurl_encode(
- url
- + "?gpio="
- + str(self.pin3)
- + "&profit="
- + str(self.profit3)
- + "&amount="
- + str(self.amount3)
- ),
- ]
- )
- if self.profit4 > 0:
- url = req.url_for("lnurldevice.lnurl_v1_params", device_id=self.id)
- switches.append(
- [
- str(self.pin4),
- str(self.profit4),
- str(self.amount4),
- lnurl_encode(
- url
- + "?gpio="
- + str(self.pin4)
- + "&profit="
- + str(self.profit4)
- + "&amount="
- + str(self.amount4)
- ),
- ]
- )
- return switches
-
-
-class lnurldevicepayment(BaseModel):
- id: str
- deviceid: str
- payhash: str
- payload: str
- pin: int
- sats: int
- timestamp: str
-
- @classmethod
- def from_row(cls, row: Row) -> "lnurldevicepayment":
- return cls(**dict(row))
diff --git a/lnbits/extensions/lnurldevice/static/image/lnurldevice.png b/lnbits/extensions/lnurldevice/static/image/lnurldevice.png
deleted file mode 100644
index 3a5304f6..00000000
Binary files a/lnbits/extensions/lnurldevice/static/image/lnurldevice.png and /dev/null differ
diff --git a/lnbits/extensions/lnurldevice/tasks.py b/lnbits/extensions/lnurldevice/tasks.py
deleted file mode 100644
index 9aec173e..00000000
--- a/lnbits/extensions/lnurldevice/tasks.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import asyncio
-
-from lnbits.core.models import Payment
-from lnbits.core.services import websocketUpdater
-from lnbits.helpers import get_current_extension_name
-from lnbits.tasks import register_invoice_listener
-
-from .crud import get_lnurldevicepayment, update_lnurldevicepayment
-
-
-async def wait_for_paid_invoices():
- invoice_queue = asyncio.Queue()
- register_invoice_listener(invoice_queue, get_current_extension_name())
-
- while True:
- payment = await invoice_queue.get()
- await on_invoice_paid(payment)
-
-
-async def on_invoice_paid(payment: Payment) -> None:
- # (avoid loops)
- if "Switch" == payment.extra.get("tag"):
- lnurldevicepayment = await get_lnurldevicepayment(payment.extra["id"])
- if not lnurldevicepayment:
- return
- if lnurldevicepayment.payhash == "used":
- return
- lnurldevicepayment = await update_lnurldevicepayment(
- lnurldevicepayment_id=payment.extra["id"], payhash="used"
- )
- assert lnurldevicepayment
- return await websocketUpdater(
- lnurldevicepayment.deviceid,
- str(lnurldevicepayment.pin) + "-" + str(lnurldevicepayment.payload),
- )
- return
diff --git a/lnbits/extensions/lnurldevice/templates/lnurldevice/_api_docs.html b/lnbits/extensions/lnurldevice/templates/lnurldevice/_api_docs.html
deleted file mode 100644
index 712f0e59..00000000
--- a/lnbits/extensions/lnurldevice/templates/lnurldevice/_api_docs.html
+++ /dev/null
@@ -1,190 +0,0 @@
-
- For LNURL based Points of Sale, ATMs, and relay devices
- Use with:
- LNPoS
-
- https://lnbits.github.io/lnpos
- bitcoinSwitch
-
- https://github.com/lnbits/bitcoinSwitch
- FOSSA
-
- https://github.com/lnbits/fossa
-
- Created by,
- Ben Arc,
- BC,
- Vlad Stan
- /lnurldevice/api/v1/lnurlpos
- Headers
- {"X-Api-Key": <admin_key>}
-
- Body (application/json)
-
-
- Returns 200 OK (application/json)
-
- [<lnurldevice_object>, ...]
- Curl example
- curl -X POST {{ request.base_url }}lnurldevice/api/v1/lnurlpos -d
- '{"title": <string>, "message":<string>, "currency":
- <integer>}' -H "Content-type: application/json" -H "X-Api-Key:
- {{user.wallets[0].adminkey }}"
-
- PUT
- /lnurldevice/api/v1/lnurlpos/<lnurldevice_id>
- Headers
- {"X-Api-Key": <admin_key>}
-
- Body (application/json)
-
-
- Returns 200 OK (application/json)
-
- [<lnurldevice_object>, ...]
- Curl example
- curl -X POST {{ request.base_url
- }}lnurldevice/api/v1/lnurlpos/<lnurldevice_id> -d ''{"title":
- <string>, "message":<string>, "currency":
- <integer>} -H "Content-type: application/json" -H "X-Api-Key:
- {{user.wallets[0].adminkey }}"
-
- GET
- /lnurldevice/api/v1/lnurlpos/<lnurldevice_id>
- Headers
- {"X-Api-Key": <invoice_key>}
-
- Body (application/json)
-
-
- Returns 200 OK (application/json)
-
- [<lnurldevice_object>, ...]
- Curl example
- curl -X GET {{ request.base_url
- }}lnurldevice/api/v1/lnurlpos/<lnurldevice_id> -H "X-Api-Key:
- {{ user.wallets[0].inkey }}"
-
- GET
- /lnurldevice/api/v1/lnurlpos
- Headers
- {"X-Api-Key": <invoice_key>}
-
- Body (application/json)
-
-
- Returns 200 OK (application/json)
-
- [<lnurldevice_object>, ...]
- Curl example
- curl -X GET {{ request.base_url }}lnurldevice/api/v1/lnurlpos -H
- "X-Api-Key: {{ user.wallets[0].inkey }}"
-
- DELETE
- /lnurldevice/api/v1/lnurlpos/<lnurldevice_id>
- Headers
- {"X-Api-Key": <admin_key>}
- Returns 204 NO CONTENT
-
- Curl example
- curl -X DELETE {{ request.base_url
- }}lnurldevice/api/v1/lnurlpos/<lnurldevice_id> -H "X-Api-Key:
- {{ user.wallets[0].adminkey }}"
-
-