mirror of
https://github.com/lnbits/lnbits.git
synced 2025-10-11 04:52:34 +02:00
Added wallet, lnurl generation should work
This commit is contained in:
@@ -9,19 +9,19 @@ from . import copilot_ext
|
|||||||
from .crud import get_copilot
|
from .crud import get_copilot
|
||||||
|
|
||||||
|
|
||||||
@copilot_ext.route("/lnurl/<copilot_id>", methods=["GET"])
|
@copilot_ext.route("/lnurl/<cp_id>", methods=["GET"])
|
||||||
async def lnurl_response(copilot_id):
|
async def lnurl_response(cp_id):
|
||||||
copilot = await get_copilot(copilot_id)
|
cp = await get_copilot(cp_id)
|
||||||
if not copilot:
|
if not cp:
|
||||||
return jsonify({"status": "ERROR", "reason": "Copilot not found."})
|
return jsonify({"status": "ERROR", "reason": "Copilot not found."})
|
||||||
|
|
||||||
resp = LnurlPayResponse(
|
resp = LnurlPayResponse(
|
||||||
callback=url_for(
|
callback=url_for(
|
||||||
"copilot.lnurl_callback", _external=True
|
"copilot.lnurl_callback", track_id=track.id, _external=True
|
||||||
),
|
),
|
||||||
min_sendable=copilot.amount,
|
min_sendable=10,
|
||||||
max_sendable=copilot.amount,
|
max_sendable=50000,
|
||||||
metadata=copilot.lnurl_title,
|
metadata=await cp.lnurl_title,
|
||||||
)
|
)
|
||||||
|
|
||||||
params = resp.dict()
|
params = resp.dict()
|
||||||
@@ -30,24 +30,27 @@ async def lnurl_response(copilot_id):
|
|||||||
return jsonify(params)
|
return jsonify(params)
|
||||||
|
|
||||||
|
|
||||||
@copilot_ext.route("/lnurl/cb", methods=["GET"])
|
@copilot_ext.route("/lnurl/cb/<cp_id>", methods=["GET"])
|
||||||
async def lnurl_callback():
|
async def lnurl_callback(cp_id):
|
||||||
|
cp = await get_copilot(cp_id)
|
||||||
|
if not cp:
|
||||||
|
return jsonify({"status": "ERROR", "reason": "Copilot not found."})
|
||||||
|
|
||||||
amount_received = int(request.args.get("amount"))
|
amount_received = int(request.args.get("amount"))
|
||||||
|
|
||||||
if amount_received < track.amount:
|
if amount_received < 10:
|
||||||
return (
|
return (
|
||||||
jsonify(
|
jsonify(
|
||||||
LnurlErrorResponse(
|
LnurlErrorResponse(
|
||||||
reason=f"Amount {round(amount_received / 1000)} is smaller than minimum {math.floor(track.min_sendable)}."
|
reason=f"Amount {round(amount_received / 1000)} is smaller than minimum 10 sats."
|
||||||
).dict()
|
).dict()
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
elif track.max_sendable < amount_received:
|
elif 50000 > amount_received/1000:
|
||||||
return (
|
return (
|
||||||
jsonify(
|
jsonify(
|
||||||
LnurlErrorResponse(
|
LnurlErrorResponse(
|
||||||
reason=f"Amount {round(amount_received / 1000)} is greater than maximum {math.floor(track.max_sendable)}."
|
reason=f"Amount {round(amount_received / 1000)} is greater than maximum 50000."
|
||||||
).dict()
|
).dict()
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -60,21 +63,19 @@ async def lnurl_callback():
|
|||||||
).dict()
|
).dict()
|
||||||
)
|
)
|
||||||
|
|
||||||
copilot = await get_copilot_by_track(track_id)
|
|
||||||
|
|
||||||
payment_hash, payment_request = await create_invoice(
|
payment_hash, payment_request = await create_invoice(
|
||||||
wallet_id=copilot.wallet,
|
wallet_id=cp.wallet,
|
||||||
amount=int(amount_received / 1000),
|
amount=int(amount_received / 1000),
|
||||||
memo=await track.fullname(),
|
memo=cp.lnurl_title,
|
||||||
description_hash=hashlib.sha256(
|
description_hash=hashlib.sha256(
|
||||||
(await track.lnurlpay_metadata()).encode("utf-8")
|
(cp.lnurl_title).encode("utf-8")
|
||||||
).digest(),
|
).digest(),
|
||||||
extra={"tag": "copilot", "track": track.id, "comment": comment},
|
extra={"tag": "copilot", "comment": comment},
|
||||||
)
|
)
|
||||||
|
|
||||||
if amount_received < track.price_msat:
|
if amount_received < track.price_msat:
|
||||||
success_action = None
|
success_action = None
|
||||||
ecopilote:
|
else:
|
||||||
success_action = track.success_action(payment_hash)
|
success_action = track.success_action(payment_hash)
|
||||||
|
|
||||||
resp = LnurlPayActionResponse(
|
resp = LnurlPayActionResponse(
|
||||||
@@ -82,5 +83,8 @@ async def lnurl_callback():
|
|||||||
success_action=success_action,
|
success_action=success_action,
|
||||||
routes=[],
|
routes=[],
|
||||||
)
|
)
|
||||||
|
socket_sendererer = app.socket_sendererer()
|
||||||
return jsonify(resp.dict())
|
async with socket_sendererer.websocket('/ws') as the_websocket:
|
||||||
|
await the_websocket.send("pay{payment_hash}")
|
||||||
|
|
||||||
|
return jsonify(resp.dict())
|
@@ -9,6 +9,7 @@ async def m001_initial(db):
|
|||||||
id TEXT NOT NULL PRIMARY KEY,
|
id TEXT NOT NULL PRIMARY KEY,
|
||||||
user TEXT,
|
user TEXT,
|
||||||
title TEXT,
|
title TEXT,
|
||||||
|
wallet TEXT,
|
||||||
animation1 TEXT,
|
animation1 TEXT,
|
||||||
animation2 TEXT,
|
animation2 TEXT,
|
||||||
animation3 TEXT,
|
animation3 TEXT,
|
||||||
|
@@ -2,11 +2,15 @@ from sqlite3 import Row
|
|||||||
from typing import NamedTuple
|
from typing import NamedTuple
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from lnurl import Lnurl, encode as lnurl_encode # type: ignore
|
||||||
|
from lnurl.types import LnurlPayMetadata # type: ignore
|
||||||
|
from lnurl.models import LnurlPaySuccessAction, UrlAction # type: ignore
|
||||||
|
|
||||||
class Copilots(NamedTuple):
|
class Copilots(NamedTuple):
|
||||||
id: str
|
id: str
|
||||||
user: str
|
user: str
|
||||||
title: str
|
title: str
|
||||||
|
wallet: str
|
||||||
animation1: str
|
animation1: str
|
||||||
animation2: str
|
animation2: str
|
||||||
animation3: str
|
animation3: str
|
||||||
@@ -28,3 +32,8 @@ class Copilots(NamedTuple):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_row(cls, row: Row) -> "Copilots":
|
def from_row(cls, row: Row) -> "Copilots":
|
||||||
return cls(**dict(row))
|
return cls(**dict(row))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lnurl(self) -> Lnurl:
|
||||||
|
url = url_for("copilots.lnurl_response", ls_id=self.id, _external=True)
|
||||||
|
return lnurl_encode(url)
|
@@ -147,6 +147,14 @@
|
|||||||
type="text"
|
type="text"
|
||||||
label="Title"
|
label="Title"
|
||||||
></q-input>
|
></q-input>
|
||||||
|
<q-select
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
emit-value
|
||||||
|
v-model="formDialogCopilot.data.wallet"
|
||||||
|
:options="g.user.walletOptions"
|
||||||
|
label="Wallet *"
|
||||||
|
></q-select>
|
||||||
|
|
||||||
<q-expansion-item
|
<q-expansion-item
|
||||||
group="api"
|
group="api"
|
||||||
@@ -182,7 +190,7 @@
|
|||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model.trim="formDialogCopilot.data.animation1webhook"
|
v-model.trim="formDialogCopilot.data.animation1webhook"
|
||||||
type="number"
|
type="text"
|
||||||
label="Webhook"
|
label="Webhook"
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
@@ -218,6 +226,7 @@
|
|||||||
v-model.trim="formDialogCopilot.data.animation2threshold"
|
v-model.trim="formDialogCopilot.data.animation2threshold"
|
||||||
type="number"
|
type="number"
|
||||||
label="From *sats"
|
label="From *sats"
|
||||||
|
:rules="[ val <= formDialogCopilot.data.animation1threshold || 'Must be higher than last']"
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
</div>
|
</div>
|
||||||
@@ -226,7 +235,7 @@
|
|||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model.trim="formDialogCopilot.data.animation2webhook"
|
v-model.trim="formDialogCopilot.data.animation2webhook"
|
||||||
type="number"
|
type="text"
|
||||||
label="Webhook"
|
label="Webhook"
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
@@ -262,6 +271,7 @@
|
|||||||
v-model.trim="formDialogCopilot.data.animation3threshold"
|
v-model.trim="formDialogCopilot.data.animation3threshold"
|
||||||
type="number"
|
type="number"
|
||||||
label="From *sats"
|
label="From *sats"
|
||||||
|
:rules="[ val <= formDialogCopilot.data.animation2threshold || 'Must be higher than last']"
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
</div>
|
</div>
|
||||||
@@ -270,7 +280,7 @@
|
|||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model.trim="formDialogCopilot.data.animation3webhook"
|
v-model.trim="formDialogCopilot.data.animation3webhook"
|
||||||
type="number"
|
type="text"
|
||||||
label="Webhook"
|
label="Webhook"
|
||||||
>
|
>
|
||||||
</q-input>
|
</q-input>
|
||||||
@@ -409,20 +419,14 @@
|
|||||||
data: {
|
data: {
|
||||||
show_message: false,
|
show_message: false,
|
||||||
show_ack: true,
|
show_ack: true,
|
||||||
title: '',
|
title: ''
|
||||||
animation1threshold: 0,
|
|
||||||
animation2threshold: 0,
|
|
||||||
animation3threshold: 0,
|
|
||||||
animation1webhook: '',
|
|
||||||
animation2webhook: '',
|
|
||||||
animation3webhook: ''
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
qrCodeDialog: {
|
qrCodeDialog: {
|
||||||
show: false,
|
show: false,
|
||||||
data: null
|
data: null
|
||||||
},
|
},
|
||||||
options: ['moon_rocket', 'confetti', 'roller_coaster']
|
options: ['bitcoin', 'confetti', 'rocket', 'face', 'martijn', 'rick']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -437,19 +441,15 @@
|
|||||||
},
|
},
|
||||||
sendFormDataCopilot: function () {
|
sendFormDataCopilot: function () {
|
||||||
var self = this
|
var self = this
|
||||||
var wallet = this.g.user.wallets[0].adminkey
|
console.log(self.formDialogCopilot.data.animation1threshold)
|
||||||
var data = this.formDialogCopilot.data
|
this.createCopilot(
|
||||||
console.log(data)
|
self.g.user.wallets[0].adminkey,
|
||||||
data.animation1threshold = parseInt(data.animation1threshold)
|
self.formDialogCopilot.data
|
||||||
data.animation1threshold = parseInt(data.animation2threshold)
|
)
|
||||||
data.animation1threshold = parseInt(data.animation3threshold)
|
|
||||||
|
|
||||||
this.createCopilot(wallet, data)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
createCopilot: function (wallet, data) {
|
createCopilot: function (wallet, data) {
|
||||||
var self = this
|
var self = this
|
||||||
|
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.request('POST', '/copilot/api/v1/copilot', wallet, data)
|
.request('POST', '/copilot/api/v1/copilot', wallet, data)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
|
@@ -24,12 +24,13 @@ from .crud import (
|
|||||||
@api_validate_post_request(
|
@api_validate_post_request(
|
||||||
schema={
|
schema={
|
||||||
"title": {"type": "string", "empty": False, "required": True},
|
"title": {"type": "string", "empty": False, "required": True},
|
||||||
|
"wallet": {"type": "string", "empty": False, "required": True},
|
||||||
"animation1": {"type": "string", "required": False},
|
"animation1": {"type": "string", "required": False},
|
||||||
"animation2": {"type": "string", "required": False},
|
"animation2": {"type": "string", "required": False},
|
||||||
"animation3": {"type": "string", "required": False},
|
"animation3": {"type": "string", "required": False},
|
||||||
"animation1threshold": {"type": "integer", "required": False},
|
"animation1threshold": {"type": "string", "required": False},
|
||||||
"animation2threshold": {"type": "integer", "required": False},
|
"animation2threshold": {"type": "string", "required": False},
|
||||||
"animation3threshold": {"type": "integer", "required": False},
|
"animation3threshold": {"type": "string", "required": False},
|
||||||
"animation1webhook": {"type": "string", "required": False},
|
"animation1webhook": {"type": "string", "required": False},
|
||||||
"animation2webhook": {"type": "string", "required": False},
|
"animation2webhook": {"type": "string", "required": False},
|
||||||
"animation3webhook": {"type": "string", "required": False},
|
"animation3webhook": {"type": "string", "required": False},
|
||||||
|
Reference in New Issue
Block a user