mirror of
https://github.com/lnbits/lnbits.git
synced 2025-04-10 12:59:43 +02:00
lnurlp: support success_text and success_url.
This commit is contained in:
parent
f6bcff01f4
commit
ea3418c21d
@ -7,7 +7,13 @@ from .models import PayLink
|
||||
|
||||
|
||||
def create_pay_link(
|
||||
*, wallet_id: str, description: str, amount: int, webhook_url: Optional[str] = None
|
||||
*,
|
||||
wallet_id: str,
|
||||
description: str,
|
||||
amount: int,
|
||||
webhook_url: Optional[str] = None,
|
||||
success_text: Optional[str] = None,
|
||||
success_url: Optional[str] = None,
|
||||
) -> Optional[PayLink]:
|
||||
with open_ext_db("lnurlp") as db:
|
||||
db.execute(
|
||||
@ -18,11 +24,13 @@ def create_pay_link(
|
||||
amount,
|
||||
served_meta,
|
||||
served_pr,
|
||||
webhook_url
|
||||
webhook_url,
|
||||
success_text,
|
||||
success_url
|
||||
)
|
||||
VALUES (?, ?, ?, 0, 0, ?)
|
||||
VALUES (?, ?, ?, 0, 0, ?, ?, ?)
|
||||
""",
|
||||
(wallet_id, description, amount, webhook_url),
|
||||
(wallet_id, description, amount, webhook_url, success_text, success_url),
|
||||
)
|
||||
link_id = db.cursor.lastrowid
|
||||
return get_pay_link(link_id)
|
||||
@ -57,7 +65,13 @@ def get_pay_links(wallet_ids: Union[str, List[str]]) -> List[PayLink]:
|
||||
|
||||
with open_ext_db("lnurlp") as db:
|
||||
q = ",".join(["?"] * len(wallet_ids))
|
||||
rows = db.fetchall(f"SELECT * FROM pay_links WHERE wallet IN ({q})", (*wallet_ids,))
|
||||
rows = db.fetchall(
|
||||
f"""
|
||||
SELECT * FROM pay_links WHERE wallet IN ({q})
|
||||
ORDER BY Id
|
||||
""",
|
||||
(*wallet_ids,),
|
||||
)
|
||||
|
||||
return [PayLink.from_row(row) for row in rows]
|
||||
|
||||
|
@ -33,7 +33,7 @@ async def api_lnurl_callback(link_id):
|
||||
if not link:
|
||||
return jsonify({"status": "ERROR", "reason": "LNURL-pay not found."}), HTTPStatus.OK
|
||||
|
||||
_, payment_request = create_invoice(
|
||||
payment_hash, payment_request = create_invoice(
|
||||
wallet_id=link.wallet,
|
||||
amount=link.amount,
|
||||
memo=link.description,
|
||||
@ -43,6 +43,10 @@ async def api_lnurl_callback(link_id):
|
||||
|
||||
save_link_invoice(link_id, payment_request)
|
||||
|
||||
resp = LnurlPayActionResponse(pr=payment_request, success_action=None, routes=[])
|
||||
resp = LnurlPayActionResponse(
|
||||
pr=payment_request,
|
||||
success_action=link.success_action(payment_hash),
|
||||
routes=[],
|
||||
)
|
||||
|
||||
return jsonify(resp.dict()), HTTPStatus.OK
|
||||
|
@ -1,9 +1,11 @@
|
||||
import json
|
||||
from urllib.parse import urlparse, urlunparse, parse_qs, urlencode, ParseResult
|
||||
from quart import url_for
|
||||
from typing import NamedTuple, Optional, Dict
|
||||
from sqlite3 import Row
|
||||
from lnurl import Lnurl, encode as lnurl_encode
|
||||
from lnurl.types import LnurlPayMetadata
|
||||
from sqlite3 import Row
|
||||
from typing import NamedTuple
|
||||
from lnurl.models import LnurlPaySuccessAction, MessageAction, UrlAction
|
||||
|
||||
|
||||
class PayLink(NamedTuple):
|
||||
@ -31,6 +33,18 @@ class PayLink(NamedTuple):
|
||||
def lnurlpay_metadata(self) -> LnurlPayMetadata:
|
||||
return LnurlPayMetadata(json.dumps([["text/plain", self.description]]))
|
||||
|
||||
def success_action(self, payment_hash: str) -> Optional[LnurlPaySuccessAction]:
|
||||
if self.success_url:
|
||||
url: ParseResult = urlparse(self.success_url)
|
||||
qs: Dict = parse_qs(url.query)
|
||||
qs["payment_hash"] = payment_hash
|
||||
url = url._replace(query=urlencode(qs))
|
||||
return UrlAction(url=urlunparse(url), description=self.success_text)
|
||||
elif self.success_text:
|
||||
return MessageAction(message=self.success_text)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class Invoice(NamedTuple):
|
||||
payment_hash: str
|
||||
|
@ -27,7 +27,7 @@
|
||||
<q-card-section>
|
||||
<h6 class="text-subtitle1 q-mb-sm q-mt-none">LNbits LNURL-pay link</h6>
|
||||
<p class="q-my-none">
|
||||
Use a LNURL compatible bitcoin wallet to claim the sats.
|
||||
Use an LNURL compatible bitcoin wallet to pay.
|
||||
</p>
|
||||
</q-card-section>
|
||||
<q-card-section class="q-pa-none">
|
||||
|
@ -137,6 +137,23 @@
|
||||
v-model="formDialog.data.webhook_url"
|
||||
type="text"
|
||||
label="Webhook URL (optional)"
|
||||
hint="An URL to be called whenever this link receives a payment."
|
||||
></q-input>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model="formDialog.data.success_text"
|
||||
type="text"
|
||||
label="Success message (optional)"
|
||||
hint="Will be shown to the user in his wallet after a successful payment."
|
||||
></q-input>
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model="formDialog.data.success_url"
|
||||
type="text"
|
||||
label="Success URL (optional)"
|
||||
hint="Will be shown as a clickable link to the user in his wallet after a successful payment, appended by the payment_hash as a query string."
|
||||
></q-input>
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn
|
||||
@ -183,6 +200,9 @@
|
||||
<strong>ID:</strong> {{ qrCodeDialog.data.id }}<br />
|
||||
<strong>Amount:</strong> {{ qrCodeDialog.data.amount }} sat<br />
|
||||
<strong>Webhook:</strong> {{ qrCodeDialog.data.webhook_url }}<br />
|
||||
<strong>Success Message:</strong> {{ qrCodeDialog.data.success_text
|
||||
}}<br />
|
||||
<strong>Success URL:</strong> {{ qrCodeDialog.data.success_url }}<br />
|
||||
</p>
|
||||
{% endraw %}
|
||||
<div class="row q-mt-lg q-gutter-sm">
|
||||
@ -263,6 +283,13 @@
|
||||
align: 'left',
|
||||
label: 'Webhook URL',
|
||||
field: 'webhook_url'
|
||||
},
|
||||
{
|
||||
name: 'success_action',
|
||||
align: 'center',
|
||||
label: '',
|
||||
format: (_, row) =>
|
||||
row.success_text || row.success_url ? '💬' : ''
|
||||
}
|
||||
],
|
||||
pagination: {
|
||||
@ -341,12 +368,28 @@
|
||||
updatePayLink: function (wallet, data) {
|
||||
var self = this
|
||||
|
||||
let values = _.omit(
|
||||
_.pick(
|
||||
data,
|
||||
'description',
|
||||
'amount',
|
||||
'webhook_url',
|
||||
'success_text',
|
||||
'success_url'
|
||||
),
|
||||
(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,
|
||||
_.pick(data, 'description', 'amount', 'webhook_url')
|
||||
values
|
||||
)
|
||||
.then(function (response) {
|
||||
self.payLinks = _.reject(self.payLinks, function (obj) {
|
||||
|
@ -57,6 +57,8 @@ async def api_link_retrieve(link_id):
|
||||
"description": {"type": "string", "empty": False, "required": True},
|
||||
"amount": {"type": "integer", "min": 1, "required": True},
|
||||
"webhook_url": {"type": "string", "required": False},
|
||||
"success_text": {"type": "string", "required": False},
|
||||
"success_url": {"type": "string", "required": False},
|
||||
}
|
||||
)
|
||||
async def api_link_create_or_update(link_id=None):
|
||||
|
Loading…
x
Reference in New Issue
Block a user