diff --git a/lnbits/extensions/lnurlp/README.md b/lnbits/extensions/lnurlp/README.md
deleted file mode 100644
index 0832bfb7..00000000
--- a/lnbits/extensions/lnurlp/README.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# LNURLp
-
-## Create a static QR code people can use to pay over Lightning Network
-
-LNURL is a range of lightning-network standards that allow us to use lightning-network differently. An LNURL-pay is a link that wallets use to fetch an invoice from a server on-demand. The link or QR code is fixed, but each time it is read by a compatible wallet a new invoice is issued by the service and sent to the wallet.
-
-[**Wallets supporting LNURL**](https://github.com/fiatjaf/awesome-lnurl#wallets)
-
-## Usage
-
-1. Create an LNURLp (New Pay link)\
- 
-
- - select your wallets
- - make a small description
- - enter amount
- - if _Fixed amount_ is unchecked you'll have the option to configure a Max and Min amount
- - you can set the currency to something different than sats. For example if you choose EUR, the satoshi amount will be calculated when a user scans the LNURLp
- - You can ask the user to send a comment that will be sent along with the payment (for example a comment to a blog post)
- - Webhook URL allows to call an URL when the LNURLp is paid
- - Success mesage, will send a message back to the user after a successful payment, for example a thank you note
- - Success URL, will send back a clickable link to the user. Access to some hidden content, or a download link
-
-2. Use the shareable link or view the LNURLp you just created\
- 
- - you can now open your LNURLp and copy the LNURL, get the shareable link or print it\
- 
diff --git a/lnbits/extensions/lnurlp/__init__.py b/lnbits/extensions/lnurlp/__init__.py
deleted file mode 100644
index aa13bb92..00000000
--- a/lnbits/extensions/lnurlp/__init__.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import asyncio
-from typing import List
-
-from fastapi import APIRouter
-from fastapi.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_lnurlp")
-
-lnurlp_static_files = [
- {
- "path": "/lnurlp/static",
- "app": StaticFiles(packages=[("lnbits", "extensions/lnurlp/static")]),
- "name": "lnurlp_static",
- }
-]
-scheduled_tasks: List[asyncio.Task] = []
-
-lnurlp_ext: APIRouter = APIRouter(prefix="/lnurlp", tags=["lnurlp"])
-
-
-def lnurlp_renderer():
- return template_renderer(["lnbits/extensions/lnurlp/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 lnurlp_start():
- loop = asyncio.get_event_loop()
- task = loop.create_task(catch_everything_and_restart(wait_for_paid_invoices))
- scheduled_tasks.append(task)
diff --git a/lnbits/extensions/lnurlp/config.json b/lnbits/extensions/lnurlp/config.json
deleted file mode 100644
index d3e046de..00000000
--- a/lnbits/extensions/lnurlp/config.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "LNURLp",
- "short_description": "Make reusable LNURL pay links",
- "tile": "/lnurlp/static/image/lnurl-pay.png",
- "contributors": [
- "arcbtc",
- "eillarra",
- "fiatjaf"
- ]
-}
diff --git a/lnbits/extensions/lnurlp/crud.py b/lnbits/extensions/lnurlp/crud.py
deleted file mode 100644
index 4acb4a41..00000000
--- a/lnbits/extensions/lnurlp/crud.py
+++ /dev/null
@@ -1,95 +0,0 @@
-from typing import List, Optional, Union
-
-from lnbits.helpers import urlsafe_short_hash
-
-from . import db
-from .models import CreatePayLinkData, PayLink
-
-
-async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:
- link_id = urlsafe_short_hash()[:6]
-
- result = await db.execute(
- """
- INSERT INTO lnurlp.pay_links (
- id,
- wallet,
- description,
- min,
- max,
- served_meta,
- served_pr,
- webhook_url,
- webhook_headers,
- webhook_body,
- success_text,
- success_url,
- comment_chars,
- currency,
- fiat_base_multiplier
- )
- VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?, ?, ?)
- """,
- (
- link_id,
- wallet_id,
- data.description,
- data.min,
- data.max,
- data.webhook_url,
- data.webhook_headers,
- data.webhook_body,
- data.success_text,
- data.success_url,
- data.comment_chars,
- data.currency,
- data.fiat_base_multiplier,
- ),
- )
- assert result
-
- link = await get_pay_link(link_id)
- assert link, "Newly created link couldn't be retrieved"
- return link
-
-
-async def get_pay_link(link_id: str) -> Optional[PayLink]:
- row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,))
- return PayLink.from_row(row) if row else None
-
-
-async def get_pay_links(wallet_ids: Union[str, List[str]]) -> List[PayLink]:
- if isinstance(wallet_ids, str):
- wallet_ids = [wallet_ids]
-
- q = ",".join(["?"] * len(wallet_ids))
- rows = await db.fetchall(
- f"""
- SELECT * FROM lnurlp.pay_links WHERE wallet IN ({q})
- ORDER BY Id
- """,
- (*wallet_ids,),
- )
- return [PayLink.from_row(row) for row in rows]
-
-
-async def update_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:
- q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
- await db.execute(
- f"UPDATE lnurlp.pay_links SET {q} WHERE id = ?", (*kwargs.values(), link_id)
- )
- row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,))
- return PayLink.from_row(row) if row else None
-
-
-async def increment_pay_link(link_id: int, **kwargs) -> Optional[PayLink]:
- q = ", ".join([f"{field[0]} = {field[0]} + ?" for field in kwargs.items()])
- await db.execute(
- f"UPDATE lnurlp.pay_links SET {q} WHERE id = ?", (*kwargs.values(), link_id)
- )
- row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,))
- return PayLink.from_row(row) if row else None
-
-
-async def delete_pay_link(link_id: int) -> None:
- await db.execute("DELETE FROM lnurlp.pay_links WHERE id = ?", (link_id,))
diff --git a/lnbits/extensions/lnurlp/lnurl.py b/lnbits/extensions/lnurlp/lnurl.py
deleted file mode 100644
index 918a5bd3..00000000
--- a/lnbits/extensions/lnurlp/lnurl.py
+++ /dev/null
@@ -1,106 +0,0 @@
-from http import HTTPStatus
-
-from fastapi import Request
-from lnurl import LnurlErrorResponse, LnurlPayActionResponse, LnurlPayResponse
-from starlette.exceptions import HTTPException
-
-from lnbits.core.services import create_invoice
-from lnbits.utils.exchange_rates import get_fiat_rate_satoshis
-
-from . import lnurlp_ext
-from .crud import increment_pay_link
-
-
-@lnurlp_ext.get(
- "/api/v1/lnurl/{link_id}", # Backwards compatibility for old LNURLs / QR codes (with long URL)
- status_code=HTTPStatus.OK,
- name="lnurlp.api_lnurl_response.deprecated",
-)
-@lnurlp_ext.get(
- "/{link_id}",
- status_code=HTTPStatus.OK,
- name="lnurlp.api_lnurl_response",
-)
-async def api_lnurl_response(request: Request, link_id):
- link = await increment_pay_link(link_id, served_meta=1)
- if not link:
- raise HTTPException(
- status_code=HTTPStatus.NOT_FOUND, detail="Pay link does not exist."
- )
-
- rate = await get_fiat_rate_satoshis(link.currency) if link.currency else 1
-
- resp = LnurlPayResponse(
- callback=request.url_for("lnurlp.api_lnurl_callback", link_id=link.id),
- min_sendable=round(link.min * rate) * 1000,
- max_sendable=round(link.max * rate) * 1000,
- metadata=link.lnurlpay_metadata,
- )
- params = resp.dict()
-
- if link.comment_chars > 0:
- params["commentAllowed"] = link.comment_chars
-
- return params
-
-
-@lnurlp_ext.get(
- "/api/v1/lnurl/cb/{link_id}",
- status_code=HTTPStatus.OK,
- name="lnurlp.api_lnurl_callback",
-)
-async def api_lnurl_callback(request: Request, link_id):
- link = await increment_pay_link(link_id, served_pr=1)
- if not link:
- raise HTTPException(
- status_code=HTTPStatus.NOT_FOUND, detail="Pay link does not exist."
- )
- min, max = link.min, link.max
- rate = await get_fiat_rate_satoshis(link.currency) if link.currency else 1
- if link.currency:
- # allow some fluctuation (as the fiat price may have changed between the calls)
- min = rate * 995 * link.min
- max = rate * 1010 * link.max
- else:
- min = link.min * 1000
- max = link.max * 1000
-
- amount_received = int(request.query_params.get("amount") or 0)
- if amount_received < min:
- return LnurlErrorResponse(
- reason=f"Amount {amount_received} is smaller than minimum {min}."
- ).dict()
-
- elif amount_received > max:
- return LnurlErrorResponse(
- reason=f"Amount {amount_received} is greater than maximum {max}."
- ).dict()
-
- comment = request.query_params.get("comment")
- if len(comment or "") > link.comment_chars:
- return LnurlErrorResponse(
- reason=f"Got a comment with {len(comment)} characters, but can only accept {link.comment_chars}"
- ).dict()
-
- payment_hash, payment_request = await create_invoice(
- wallet_id=link.wallet,
- amount=int(amount_received / 1000),
- memo=link.description,
- unhashed_description=link.lnurlpay_metadata.encode(),
- extra={
- "tag": "lnurlp",
- "link": link.id,
- "comment": comment,
- "extra": request.query_params.get("amount"),
- },
- )
-
- success_action = link.success_action(payment_hash)
- if success_action:
- resp = LnurlPayActionResponse(
- pr=payment_request, success_action=success_action, routes=[]
- )
- else:
- resp = LnurlPayActionResponse(pr=payment_request, routes=[])
-
- return resp.dict()
diff --git a/lnbits/extensions/lnurlp/migrations.py b/lnbits/extensions/lnurlp/migrations.py
deleted file mode 100644
index 1ec85eb0..00000000
--- a/lnbits/extensions/lnurlp/migrations.py
+++ /dev/null
@@ -1,148 +0,0 @@
-async def m001_initial(db):
- """
- Initial pay table.
- """
- await db.execute(
- f"""
- CREATE TABLE lnurlp.pay_links (
- id {db.serial_primary_key},
- wallet TEXT NOT NULL,
- description TEXT NOT NULL,
- amount {db.big_int} NOT NULL,
- served_meta INTEGER NOT NULL,
- served_pr INTEGER NOT NULL
- );
- """
- )
-
-
-async def m002_webhooks_and_success_actions(db):
- """
- Webhooks and success actions.
- """
- await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN webhook_url TEXT;")
- await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN success_text TEXT;")
- await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN success_url TEXT;")
- await db.execute(
- f"""
- CREATE TABLE lnurlp.invoices (
- pay_link INTEGER NOT NULL REFERENCES {db.references_schema}pay_links (id),
- payment_hash TEXT NOT NULL,
- webhook_sent INT, -- null means not sent, otherwise store status
- expiry INT
- );
- """
- )
-
-
-async def m003_min_max_comment_fiat(db):
- """
- Support for min/max amounts, comments and fiat prices that get
- converted automatically to satoshis based on some API.
- """
- await db.execute(
- "ALTER TABLE lnurlp.pay_links ADD COLUMN currency TEXT;"
- ) # null = satoshis
- await db.execute(
- "ALTER TABLE lnurlp.pay_links ADD COLUMN comment_chars INTEGER DEFAULT 0;"
- )
- await db.execute("ALTER TABLE lnurlp.pay_links RENAME COLUMN amount TO min;")
- await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN max INTEGER;")
- await db.execute("UPDATE lnurlp.pay_links SET max = min;")
- await db.execute("DROP TABLE lnurlp.invoices")
-
-
-async def m004_fiat_base_multiplier(db):
- """
- Store the multiplier for fiat prices. We store the price in cents and
- remember to multiply by 100 when we use it to convert to Dollars.
- """
- await db.execute(
- "ALTER TABLE lnurlp.pay_links ADD COLUMN fiat_base_multiplier INTEGER DEFAULT 1;"
- )
-
-
-async def m005_webhook_headers_and_body(db):
- """
- Add headers and body to webhooks
- """
- await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN webhook_headers TEXT;")
- await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN webhook_body TEXT;")
-
-
-async def m006_redux(db):
- """
- Migrate ID column type to string for UUIDs and migrate existing data
- """
- # we can simply change the column type for postgres
- if db.type != "SQLITE":
- await db.execute("ALTER TABLE lnurlp.pay_links ALTER COLUMN id TYPE TEXT;")
- else:
- # but we have to do this for sqlite
- await db.execute("ALTER TABLE lnurlp.pay_links RENAME TO pay_links_old")
- await db.execute(
- f"""
- CREATE TABLE lnurlp.pay_links (
- id TEXT PRIMARY KEY,
- wallet TEXT NOT NULL,
- description TEXT NOT NULL,
- min {db.big_int} NOT NULL,
- max {db.big_int},
- currency TEXT,
- fiat_base_multiplier INTEGER DEFAULT 1,
- served_meta INTEGER NOT NULL,
- served_pr INTEGER NOT NULL,
- webhook_url TEXT,
- success_text TEXT,
- success_url TEXT,
- comment_chars INTEGER DEFAULT 0,
- webhook_headers TEXT,
- webhook_body TEXT
- );
- """
- )
-
- for row in [
- list(row) for row in await db.fetchall("SELECT * FROM lnurlp.pay_links_old")
- ]:
- await db.execute(
- """
- INSERT INTO lnurlp.pay_links (
- id,
- wallet,
- description,
- min,
- served_meta,
- served_pr,
- webhook_url,
- success_text,
- success_url,
- currency,
- comment_chars,
- max,
- fiat_base_multiplier,
- webhook_headers,
- webhook_body
- )
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- """,
- (
- row[0],
- row[1],
- row[2],
- row[3],
- row[4],
- row[5],
- row[6],
- row[7],
- row[8],
- row[9],
- row[10],
- row[11],
- row[12],
- row[13],
- row[14],
- ),
- )
-
- await db.execute("DROP TABLE lnurlp.pay_links_old")
diff --git a/lnbits/extensions/lnurlp/models.py b/lnbits/extensions/lnurlp/models.py
deleted file mode 100644
index de66d406..00000000
--- a/lnbits/extensions/lnurlp/models.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import json
-from sqlite3 import Row
-from typing import Dict, Optional
-from urllib.parse import ParseResult, urlparse, urlunparse
-
-from fastapi.param_functions import Query
-from lnurl.types import LnurlPayMetadata
-from pydantic import BaseModel
-from starlette.requests import Request
-
-from lnbits.lnurl import encode as lnurl_encode
-
-
-class CreatePayLinkData(BaseModel):
- description: str
- min: float = Query(1, ge=0.01)
- max: float = Query(1, ge=0.01)
- currency: str = Query(None)
- comment_chars: int = Query(0, ge=0, lt=800)
- webhook_url: str = Query(None)
- webhook_headers: str = Query(None)
- webhook_body: str = Query(None)
- success_text: str = Query(None)
- success_url: str = Query(None)
- fiat_base_multiplier: int = Query(100, ge=1)
-
-
-class PayLink(BaseModel):
- id: str
- wallet: str
- description: str
- min: float
- served_meta: int
- served_pr: int
- webhook_url: Optional[str]
- webhook_headers: Optional[str]
- webhook_body: Optional[str]
- success_text: Optional[str]
- success_url: Optional[str]
- currency: Optional[str]
- comment_chars: int
- max: float
- fiat_base_multiplier: int
-
- @classmethod
- def from_row(cls, row: Row) -> "PayLink":
- data = dict(row)
- if data["currency"] and data["fiat_base_multiplier"]:
- data["min"] /= data["fiat_base_multiplier"]
- data["max"] /= data["fiat_base_multiplier"]
- return cls(**data)
-
- def lnurl(self, req: Request) -> str:
- url = req.url_for("lnurlp.api_lnurl_response", link_id=self.id)
- return lnurl_encode(url)
-
- @property
- def lnurlpay_metadata(self) -> LnurlPayMetadata:
- return LnurlPayMetadata(json.dumps([["text/plain", self.description]]))
-
- def success_action(self, payment_hash: str) -> Optional[Dict]:
- if self.success_url:
- url: ParseResult = urlparse(self.success_url)
- # qs = parse_qs(url.query)
- # setattr(qs, "payment_hash", payment_hash)
- # url = url._replace(query=urlencode(qs, doseq=True))
- return {
- "tag": "url",
- "description": self.success_text or "~",
- "url": urlunparse(url),
- }
- elif self.success_text:
- return {"tag": "message", "message": self.success_text}
- else:
- return None
diff --git a/lnbits/extensions/lnurlp/static/image/lnurl-pay.png b/lnbits/extensions/lnurlp/static/image/lnurl-pay.png
deleted file mode 100644
index 36af81a7..00000000
Binary files a/lnbits/extensions/lnurlp/static/image/lnurl-pay.png and /dev/null differ
diff --git a/lnbits/extensions/lnurlp/static/js/index.js b/lnbits/extensions/lnurlp/static/js/index.js
deleted file mode 100644
index c1372bec..00000000
--- a/lnbits/extensions/lnurlp/static/js/index.js
+++ /dev/null
@@ -1,264 +0,0 @@
-/* globals Quasar, Vue, _, VueQrcode, windowMixin, LNbits, LOCALE */
-
-Vue.component(VueQrcode.name, VueQrcode)
-
-var locationPath = [
- window.location.protocol,
- '//',
- window.location.host,
- window.location.pathname
-].join('')
-
-var mapPayLink = obj => {
- obj._data = _.clone(obj)
- obj.date = Quasar.utils.date.formatDate(
- new Date(obj.time * 1000),
- 'YYYY-MM-DD HH:mm'
- )
- obj.amount = new Intl.NumberFormat(LOCALE).format(obj.amount)
- obj.print_url = [locationPath, 'print/', obj.id].join('')
- obj.pay_url = [locationPath, 'link/', obj.id].join('')
- return obj
-}
-
-new Vue({
- el: '#vue',
- mixins: [windowMixin],
- data() {
- return {
- currencies: [],
- fiatRates: {},
- checker: null,
- payLinks: [],
- payLinksTable: {
- pagination: {
- rowsPerPage: 10
- }
- },
- nfcTagWriting: false,
- formDialog: {
- show: false,
- fixedAmount: true,
- data: {}
- },
- qrCodeDialog: {
- show: false,
- data: null
- }
- }
- },
- methods: {
- getPayLinks() {
- LNbits.api
- .request(
- 'GET',
- '/lnurlp/api/v1/links?all_wallets=true',
- this.g.user.wallets[0].inkey
- )
- .then(response => {
- this.payLinks = response.data.map(mapPayLink)
- })
- .catch(err => {
- clearInterval(this.checker)
- LNbits.utils.notifyApiError(err)
- })
- },
- closeFormDialog() {
- this.resetFormData()
- },
- openQrCodeDialog(linkId) {
- var link = _.findWhere(this.payLinks, {id: linkId})
- if (link.currency) this.updateFiatRate(link.currency)
-
- this.qrCodeDialog.data = {
- id: link.id,
- amount:
- (link.min === link.max ? link.min : `${link.min} - ${link.max}`) +
- ' ' +
- (link.currency || 'sat'),
- currency: link.currency,
- comments: link.comment_chars
- ? `${link.comment_chars} characters`
- : 'no',
- webhook: link.webhook_url || 'nowhere',
- success:
- link.success_text || link.success_url
- ? 'Display message "' +
- link.success_text +
- '"' +
- (link.success_url ? ' and URL "' + link.success_url + '"' : '')
- : 'do nothing',
- lnurl: link.lnurl,
- pay_url: link.pay_url,
- print_url: link.print_url
- }
- this.qrCodeDialog.show = true
- },
- openUpdateDialog(linkId) {
- const link = _.findWhere(this.payLinks, {id: linkId})
- if (link.currency) this.updateFiatRate(link.currency)
-
- this.formDialog.data = _.clone(link._data)
- this.formDialog.show = true
- this.formDialog.fixedAmount =
- this.formDialog.data.min === this.formDialog.data.max
- },
- sendFormData() {
- const wallet = _.findWhere(this.g.user.wallets, {
- id: this.formDialog.data.wallet
- })
- var data = _.omit(this.formDialog.data, 'wallet')
-
- if (this.formDialog.fixedAmount) data.max = data.min
- if (data.currency === 'satoshis') data.currency = null
- if (isNaN(parseInt(data.comment_chars))) data.comment_chars = 0
-
- if (data.id) {
- this.updatePayLink(wallet, data)
- } else {
- this.createPayLink(wallet, data)
- }
- },
- resetFormData() {
- this.formDialog = {
- show: false,
- fixedAmount: true,
- data: {}
- }
- },
- updatePayLink(wallet, data) {
- let values = _.omit(
- _.pick(
- data,
- 'description',
- 'min',
- 'max',
- 'webhook_url',
- 'success_text',
- 'success_url',
- 'comment_chars',
- 'currency'
- ),
- (value, key) =>
- (key === 'webhook_url' ||
- key === 'success_text' ||
- key === 'success_url') &&
- (value === null || value === '')
- )
-
- LNbits.api
- .request(
- 'PUT',
- '/lnurlp/api/v1/links/' + data.id,
- wallet.adminkey,
- values
- )
- .then(response => {
- this.payLinks = _.reject(this.payLinks, obj => obj.id === data.id)
- this.payLinks.push(mapPayLink(response.data))
- this.formDialog.show = false
- this.resetFormData()
- })
- .catch(err => {
- LNbits.utils.notifyApiError(err)
- })
- },
- createPayLink(wallet, data) {
- LNbits.api
- .request('POST', '/lnurlp/api/v1/links', wallet.adminkey, data)
- .then(response => {
- this.getPayLinks()
- this.formDialog.show = false
- this.resetFormData()
- })
- .catch(err => {
- LNbits.utils.notifyApiError(err)
- })
- },
- deletePayLink(linkId) {
- var link = _.findWhere(this.payLinks, {id: linkId})
-
- LNbits.utils
- .confirmDialog('Are you sure you want to delete this pay link?')
- .onOk(() => {
- LNbits.api
- .request(
- 'DELETE',
- '/lnurlp/api/v1/links/' + linkId,
- _.findWhere(this.g.user.wallets, {id: link.wallet}).adminkey
- )
- .then(response => {
- this.payLinks = _.reject(this.payLinks, obj => obj.id === linkId)
- })
- .catch(err => {
- LNbits.utils.notifyApiError(err)
- })
- })
- },
- updateFiatRate(currency) {
- LNbits.api
- .request('GET', '/lnurlp/api/v1/rate/' + currency, null)
- .then(response => {
- let rates = _.clone(this.fiatRates)
- rates[currency] = response.data.rate
- this.fiatRates = rates
- })
- .catch(err => {
- LNbits.utils.notifyApiError(err)
- })
- },
- writeNfcTag: async function (lnurl) {
- try {
- if (typeof NDEFReader == 'undefined') {
- throw {
- toString: function () {
- return 'NFC not supported on this device or browser.'
- }
- }
- }
-
- const ndef = new NDEFReader()
-
- this.nfcTagWriting = true
- this.$q.notify({
- message: 'Tap your NFC tag to write the LNURL-pay link to it.'
- })
-
- await ndef.write({
- records: [{recordType: 'url', data: 'lightning:' + lnurl, lang: 'en'}]
- })
-
- this.nfcTagWriting = false
- this.$q.notify({
- type: 'positive',
- message: 'NFC tag written successfully.'
- })
- } catch (error) {
- this.nfcTagWriting = false
- this.$q.notify({
- type: 'negative',
- message: error
- ? error.toString()
- : 'An unexpected error has occurred.'
- })
- }
- }
- },
- created() {
- if (this.g.user.wallets.length) {
- var getPayLinks = this.getPayLinks
- getPayLinks()
- this.checker = setInterval(() => {
- getPayLinks()
- }, 20000)
- }
- LNbits.api
- .request('GET', '/lnurlp/api/v1/currencies')
- .then(response => {
- this.currencies = ['satoshis', ...response.data]
- })
- .catch(err => {
- LNbits.utils.notifyApiError(err)
- })
- }
-})
diff --git a/lnbits/extensions/lnurlp/tasks.py b/lnbits/extensions/lnurlp/tasks.py
deleted file mode 100644
index ea01e04f..00000000
--- a/lnbits/extensions/lnurlp/tasks.py
+++ /dev/null
@@ -1,79 +0,0 @@
-import asyncio
-import json
-
-import httpx
-from loguru import logger
-
-from lnbits.core.crud import update_payment_extra
-from lnbits.core.models import Payment
-from lnbits.helpers import get_current_extension_name
-from lnbits.tasks import register_invoice_listener
-
-from .crud import get_pay_link
-
-
-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):
- if payment.extra.get("tag") != "lnurlp":
- return
-
- if payment.extra.get("wh_status"):
- # this webhook has already been sent
- return
-
- pay_link = await get_pay_link(payment.extra.get("link", -1))
- if pay_link and pay_link.webhook_url:
- async with httpx.AsyncClient() as client:
- try:
- r: httpx.Response = await client.post(
- pay_link.webhook_url,
- json={
- "payment_hash": payment.payment_hash,
- "payment_request": payment.bolt11,
- "amount": payment.amount,
- "comment": payment.extra.get("comment"),
- "lnurlp": pay_link.id,
- "body": json.loads(pay_link.webhook_body)
- if pay_link.webhook_body
- else "",
- },
- headers=json.loads(pay_link.webhook_headers)
- if pay_link.webhook_headers
- else None,
- timeout=40,
- )
- await mark_webhook_sent(
- payment.payment_hash,
- r.status_code,
- r.is_success,
- r.reason_phrase,
- r.text,
- )
- except Exception as ex:
- logger.error(ex)
- await mark_webhook_sent(
- payment.payment_hash, -1, False, "Unexpected Error", str(ex)
- )
-
-
-async def mark_webhook_sent(
- payment_hash: str, status: int, is_success: bool, reason_phrase="", text=""
-) -> None:
-
- await update_payment_extra(
- payment_hash,
- {
- "wh_status": status, # keep for backwards compability
- "wh_success": is_success,
- "wh_message": reason_phrase,
- "wh_response": text,
- },
- )
diff --git a/lnbits/extensions/lnurlp/templates/lnurlp/_api_docs.html b/lnbits/extensions/lnurlp/templates/lnurlp/_api_docs.html
deleted file mode 100644
index abb37e90..00000000
--- a/lnbits/extensions/lnurlp/templates/lnurlp/_api_docs.html
+++ /dev/null
@@ -1,138 +0,0 @@
-
- WARNING: LNURL must be used over https or TOR
- Exploring LNURL and finding use cases, is really helping inform
- lightning protocol development, rather than the protocol dictating how
- lightning-network should be engaged with.
- GET /lnurlp/api/v1/links
- Headers
- {"X-Api-Key": <invoice_key>}
- Body (application/json)
-
- Returns 200 OK (application/json)
-
- [<pay_link_object>, ...]
- Curl example
- curl -X GET {{ request.base_url }}lnurlp/api/v1/links -H "X-Api-Key:
- {{ user.wallets[0].inkey }}"
-
- GET
- /lnurlp/api/v1/links/<pay_id>
- Headers
- {"X-Api-Key": <invoice_key>}
- Body (application/json)
-
- Returns 201 CREATED (application/json)
-
- {"lnurl": <string>}
- Curl example
- curl -X GET {{ request.base_url }}lnurlp/api/v1/links/<pay_id>
- -H "X-Api-Key: {{ user.wallets[0].inkey }}"
-
- POST /lnurlp/api/v1/links
- Headers
- {"X-Api-Key": <admin_key>}
- Body (application/json)
- {"description": <string> "amount": <integer> "max":
- <integer> "min": <integer> "comment_chars":
- <integer>}
-
- Returns 201 CREATED (application/json)
-
- {"lnurl": <string>}
- Curl example
- curl -X POST {{ request.base_url }}lnurlp/api/v1/links -d
- '{"description": <string>, "amount": <integer>, "max":
- <integer>, "min": <integer>, "comment_chars":
- <integer>}' -H "Content-type: application/json" -H "X-Api-Key:
- {{ user.wallets[0].adminkey }}"
-
- PUT
- /lnurlp/api/v1/links/<pay_id>
- Headers
- {"X-Api-Key": <admin_key>}
- Body (application/json)
- {"description": <string>, "amount": <integer>}
-
- Returns 200 OK (application/json)
-
- {"lnurl": <string>}
- Curl example
- curl -X PUT {{ request.base_url }}lnurlp/api/v1/links/<pay_id>
- -d '{"description": <string>, "amount": <integer>}' -H
- "Content-type: application/json" -H "X-Api-Key: {{
- user.wallets[0].adminkey }}"
-
- DELETE
- /lnurlp/api/v1/links/<pay_id>
- Headers
- {"X-Api-Key": <admin_key>}
- Returns 204 NO CONTENT
-
- Curl example
- curl -X DELETE {{ request.base_url
- }}lnurlp/api/v1/links/<pay_id> -H "X-Api-Key: {{
- user.wallets[0].adminkey }}"
-
-
- LNURL is a range of lightning-network standards that allow us to use
- lightning-network differently. An LNURL-pay is a link that wallets use
- to fetch an invoice from a server on-demand. The link or QR code is
- fixed, but each time it is read by a compatible wallet a new QR code is
- issued by the service. It can be used to activate machines without them
- having to maintain an electronic screen to generate and show invoices
- locally, or to sell any predefined good or service automatically.
-
Use an LNURL compatible bitcoin wallet to pay.
-
- ID: {{ qrCodeDialog.data.id }}
- Amount: {{ qrCodeDialog.data.amount }}
- {{ qrCodeDialog.data.currency }} price: {{
- fiatRates[qrCodeDialog.data.currency] ?
- fiatRates[qrCodeDialog.data.currency] + ' sat' : 'Loading...' }}
- Accepts comments: {{ qrCodeDialog.data.comments }}
- Dispatches webhook to: {{ qrCodeDialog.data.webhook
- }}
- On success: {{ qrCodeDialog.data.success }}
-