Adding qrcodes

This commit is contained in:
benarc 2024-01-17 12:22:26 +00:00
parent 0711f583d6
commit 044696ffce
14 changed files with 143 additions and 43 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

16
crud.py
View file

@ -1,7 +1,7 @@
from typing import List, Optional, Union
from lnbits.helpers import urlsafe_short_hash
from lnbits.lnurl import encode as lnurl_encode
from . import db
from .models import CreateMyExtensionData, MyExtension
from loguru import logger
@ -28,9 +28,14 @@ async def create_myextension(wallet_id: str, data: CreateMyExtensionData) -> MyE
return myextension
async def get_myextension(myextension_id: str) -> Optional[MyExtension]:
async def get_myextension(myextension_id: str, req: Request) -> Optional[MyExtension]:
row = await db.fetchone("SELECT * FROM myextension.maintable WHERE id = ?", (myextension_id,))
return MyExtension(**row) if row else None
if not row:
return None
rowAmended = MyExtension(**row)
rowAmended.lnurlpay = lnurl_encode(req.url_for("myextension.api_lnurl_pay", myextension_id=row.id)._url)
rowAmended.lnurlwithdraw = lnurl_encode(req.url_for("myextension.api_lnurl_withdraw", myextension_id=row.id)._url)
return rowAmended
async def get_myextensions(wallet_ids: Union[str, List[str]], req: Request) -> List[MyExtension]:
if isinstance(wallet_ids, str):
@ -41,10 +46,9 @@ async def get_myextensions(wallet_ids: Union[str, List[str]], req: Request) -> L
f"SELECT * FROM myextension.maintable WHERE wallet IN ({q})", (*wallet_ids,)
)
tempRows = [MyExtension(**row) for row in rows]
logger.debug(req.url_for("myextension.api_lnurl_pay", myextension_id=row.id))
for row in tempRows:
row.lnurlpay = req.url_for("myextension.api_lnurl_pay", myextension_id=row.id)
row.lnurlwithdraw = req.url_for("myextension.api_lnurl_withdraw", myextension_id=row.id)
row.lnurlpay = lnurl_encode(req.url_for("myextension.api_lnurl_pay", myextension_id=row.id)._url)
row.lnurlwithdraw = lnurl_encode(req.url_for("myextension.api_lnurl_withdraw", myextension_id=row.id)._url)
return tempRows
async def update_myextension(myextension_id: str, **kwargs) -> MyExtension:

View file

@ -1,5 +1,6 @@
# Maybe your extensions needs some LNURL stuff, if so checkout LNURLp/LNURLw extensions/lnurl library in LNbits (to keep things simple the below examples are raw LNURLs)
# Maybe your extensions needs some LNURL stuff.
# Here is a very simple example of how to do it.
# Feel free to delete this file if you don't need it.
from http import HTTPStatus
from fastapi import Depends, Query, Request

View file

@ -18,13 +18,13 @@ class CreateMyExtensionData(BaseModel):
class MyExtension(BaseModel):
id: str
wallet: str
name: str
wallet: Optional[str]
name: Optional[str]
total: Optional[int]
lnurlpayamount: Optional[int]
lnurlwithdrawamount: Optional[int]
lnurlpay: str
lnurlwithdraw: str
lnurlpay: Optional[str]
lnurlwithdraw: Optional[str]
@classmethod
def from_row(cls, row: Row) -> "MyExtension":

View file

@ -67,17 +67,6 @@
target="_blank"
><q-tooltip>Open public page</q-tooltip></q-btn
></q-td>
<q-td auto-width>
<q-btn
unelevated
dense
size="md"
copy="copy"
@click="copyText(props.row.id)"
><q-tooltip>Click to copy</q-tooltip
>${props.row.id.substring(0,6)}...</q-btn
>
</q-td>
</q-tr>
@ -163,22 +152,42 @@
<q-dialog v-model="urlDialog.show" position="top">
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
<q-responsive :ratio="1" class="q-mx-xl q-mb-md">
<lnbits-qrcode :value="urlDialog.data.lnurlpay"></lnbits-qrcode>
</q-responsive>
<div class="text-center q-mb-xl">
<p style="word-break: break-all">
<strong>${ urlDialog.data.lnurlpay }</strong><br />${
urlDialog.data.shareUrl }
</p>
<lnbits-qrcode
:value="qrValue"
></lnbits-qrcode>
</q-responsive>
<center><q-btn label="copy" @click="copyText(qrValue)"></q-btn>
</center>
<q-separator></q-separator>
<div class="row justify-start q-mt-lg">
<div class="col col-md-auto">
<q-btn outline style="color: primmary;" @click="qrValue = urlDialog.data.lnurlpay">lnurlpay</q-btn>
</div>
<div class="col col-md-auto">
<q-btn outline style="color: primmary;" @click="qrValue = urlDialog.data.lnurlwithdraw">lnurlwithdraw</q-btn>
</div>
<div class="col q-pl-md">
<q-input filled bottom-slots dense v-model="invoiceAmount">
<template v-slot:append>
<q-btn round @click="createInvoice(urlDialog.data.wallet)" color="primary" flat icon="add_circle" />
</template>
<template v-slot:hint>
Create an invoice
</template>
</q-input>
</div>
</div>
<div class="row q-mt-lg">
<q-btn
outline
color="grey"
@click="copyText(urlDialog.data.lnurlpay, 'MyExtension URL copied to clipboard!')"
>Copy URL</q-btn
>
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
</div>
</q-card>
@ -186,6 +195,7 @@
</div>
{% endblock %} {% block scripts %} {{ window_vars(user) }}
<script>
// The object returned here will be merged with the data object of the Vue instance
const mapTemp = obj => {
obj.date = Quasar.utils.date.formatDate(
@ -202,6 +212,8 @@
delimiters: ['${', '}'],
data: function () {
return {
invoiceAmount: 10,
qrValue: 'lnurlpay',
temps: [],
tempsTable: {
columns: [
@ -382,8 +394,32 @@
},
openUrlDialog(id) {
this.urlDialog.data = _.findWhere(this.temps, {id})
this.qrValue = this.urlDialog.data.lnurlpay
this.urlDialog.show = true
}
},
createInvoice(walletId) {
console.log(walletId)
const wallet = _.findWhere(this.g.user.wallets, {
id: walletId
})
console.log(wallet.inkey)
LNbits.api
.request(
'POST',
`/api/v1/payments`,
wallet.inkey,
{
out: false,
amount: this.invoiceAmount,
}
)
.then(response => {
this.qrValue = response.data.payment_request
})
.catch(error => {
LNbits.utils.notifyApiError(error)
})
},
},
created: function () {
if (this.g.user.wallets.length) {

View file

@ -51,15 +51,59 @@
mixins: [windowMixin],
data: function () {
return {
lnurlpay: "",
lnurlwithdraw: "",
lnurlpay: "{{ lnurlpay|tojson }}",
lnurlwithdraw: "{{ lnurlwithdraw|tojson }}",
}
},
created: function () {
if (this.g.user.wallets.length) {
this.getTemps()
}
}
},
methods: {
copyText: function (text) {
var self = this
navigator.clipboard.writeText(text).then(
function () {
self.$q.notify({
message: 'LNURL copied to clipboard',
color: 'positive',
icon: 'done',
})
},
function (err) {
self.$q.notify({
message: 'LNURL copy failed',
color: 'negative',
icon: 'error',
})
}
)
},
createInvoice(walletId) {
console.log(walletId)
const wallet = _.findWhere(this.g.user.wallets, {
id: walletId
})
console.log(wallet.inkey)
LNbits.api
.request(
'POST',
`/api/v1/payments`,
wallet.inkey,
{
out: false,
amount: this.invoiceAmount,
}
)
.then(response => {
this.qrValue = response.data.payment_request
})
.catch(error => {
LNbits.utils.notifyApiError(error)
})
},
},
})
</script>
{% endblock %}

View file

@ -38,7 +38,9 @@ from .models import CreateMyExtensionData
@myextension_ext.get("/api/v1/temps", status_code=HTTPStatus.OK)
async def api_myextensions(
req: Request, all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type)
req: Request, all_wallets:
bool = Query(False),
wallet: WalletTypeInfo = Depends(get_key_type)
):
wallet_ids = [wallet.wallet.id]
if all_wallets:
@ -46,14 +48,27 @@ async def api_myextensions(
wallet_ids = user.wallet_ids if user else []
return [myextension.dict() for myextension in await get_myextensions(wallet_ids, req)]
## Get a single record
## Get a specific record belonging to a user
@myextension_ext.get("/api/v1/temps/{myextension_id}", status_code=HTTPStatus.OK)
async def api_myextension(
req: Request,
myextension_id: str,
WalletTypeInfo = Depends(get_key_type)):
myextension = await get_myextension(myextension_id, req)
if not myextension:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="MyExtension does not exist."
)
return myextension.dict()
## update a record
@myextension_ext.put("/api/v1/temps/{myextension_id}")
async def api_myextension_update(
data: CreateMyExtensionData,
myextension_id: str,
wallet: WalletTypeInfo = Depends(require_admin_key),
wallet: WalletTypeInfo = Depends(get_key_type),
):
if not myextension_id:
raise HTTPException(