Added a switch

This commit is contained in:
ben 2022-10-06 22:19:30 +01:00
parent 3222ae198d
commit ff98b87eca
5 changed files with 102 additions and 7 deletions

View file

@ -1,3 +1,4 @@
import asyncio
from fastapi import APIRouter
from lnbits.db import Database

View file

@ -36,7 +36,7 @@ class lnurldevices(BaseModel):
def lnurl(self, req: Request) -> Lnurl:
url = req.url_for(
"lnurldevice.lnurl_response", device_id=self.id, _external=True
"lnurldevice.lnurl_v1_params", device_id=self.id
)
return lnurl_encode(url)

View file

@ -1,10 +1,10 @@
<q-card>
<q-card-section>
<p>
Register LNURLDevice devices to receive payments in your LNbits wallet.<br />
Build your own here
<a href="https://github.com/arcbtc/bitcoinpos"
>https://github.com/arcbtc/bitcoinpos</a
For LNURL based Points of Sale, ATMs, and relay devices<br />
Such as the LNPoS
<a href="https://lnbits.github.io/lnpos"
> https://lnbits.github.io/lnpos</a
><br />
<small>
Created by, <a href="https://github.com/benarc">Ben Arc</a></small

View file

@ -51,6 +51,7 @@
<q-tr :props="props">
<q-th style="width: 5%"></q-th>
<q-th style="width: 5%"></q-th>
<q-th style="width: 5%"></q-th>
<q-th
v-for="col in props.cols"
@ -91,6 +92,21 @@
<q-tooltip> LNURLDevice Settings </q-tooltip>
</q-btn>
</q-td>
<q-td>
<q-btn
v-if="props.row.device == 'switch'"
flat
dense
size="xs"
icon="qr_code"
color="grey"
type="a"
:href="'/lnurldevice/img/' + props.row.id"
target="_blank"
>
<q-tooltip> bitcoinSwitch embeddable QRCode </q-tooltip>
</q-btn>
</q-td>
<q-td
v-for="col in props.cols"
:key="col.name"
@ -132,7 +148,21 @@
class="q-pa-lg q-pt-xl lnbits__dialog-card"
>
<div class="text-h6">LNURLDevice device string</div>
<center>
<q-btn
v-if="settingsDialog.data.device == 'switch'"
dense
outline
unelevated
color="primary"
size="md"
@click="copyText(wslocation + '/lnurldevice/ws/' + settingsDialog.data.id, 'Link copied to clipboard!')"
>{% raw
%}{{wslocation}}/lnurldevice/ws/{{settingsDialog.data.id}}{% endraw
%}<q-tooltip> Click to copy URL </q-tooltip>
</q-btn>
<q-btn
v-else
dense
outline
unelevated
@ -145,7 +175,7 @@
{{settingsDialog.data.key}}, {{settingsDialog.data.currency}}{% endraw
%}<q-tooltip> Click to copy URL </q-tooltip>
</q-btn>
</center>
<div class="text-subtitle2">
<small> </small>
</div>
@ -191,6 +221,7 @@
label="Type of device"
></q-option-group>
<q-input
v-if="formDialoglnurldevice.data.device != 'switch'"
filled
dense
v-model.trim="formDialoglnurldevice.data.profit"
@ -198,6 +229,29 @@
max="90"
label="Profit margin (% added to invoices/deducted from faucets)"
></q-input>
<div v-else>
<q-input
ref="setAmount"
filled
dense
v-model.trim="formDialoglnurldevice.data.profit"
class="q-pb-md"
:label="'Amount (' + formDialoglnurldevice.data.currency + ') *'"
:mask="'#.##'"
fill-mask="0"
reverse-fill-mask
:step="'0.01'"
></q-input>
<q-input
filled
dense
v-model.trim="formDialoglnurldevice.data.amount"
type="number"
value="1000"
label="milesecs to turn Switch on for (1sec = 1000ms)"
></q-input>
</div>
<div class="row q-mt-lg">
<q-btn
@ -253,6 +307,7 @@
data: function () {
return {
location: window.location.hostname,
wslocation: window.location.hostname,
filter: '',
currency: 'USD',
lnurldeviceLinks: [],
@ -265,6 +320,10 @@
{
label: 'ATM',
value: 'atm'
},
{
label: 'Switch',
value: 'switch'
}
],
lnurldevicesTable: {
@ -334,6 +393,7 @@
show_price: 'None',
device: 'pos',
profit: 2,
amount: 1,
title: ''
}
},
@ -519,6 +579,10 @@
'//',
window.location.host
].join('')
self.wslocation = [
'ws://',
window.location.host
].join('')
LNbits.api
.request('GET', '/api/v1/currencies')
.then(response => {

View file

@ -1,4 +1,6 @@
from http import HTTPStatus
import pyqrcode
from io import BytesIO
from fastapi import Request
from fastapi.param_functions import Query
@ -14,6 +16,9 @@ from lnbits.decorators import check_user_exists
from . import lnurldevice_ext, lnurldevice_renderer
from .crud import get_lnurldevice, get_lnurldevicepayment
from fastapi import Request, WebSocket, WebSocketDisconnect
from starlette.responses import HTMLResponse, StreamingResponse
templates = Jinja2Templates(directory="templates")
@ -52,6 +57,30 @@ async def displaypin(request: Request, paymentid: str = Query(None)):
{"request": request, "pin": "filler", "not_paid": True},
)
@lnurldevice_ext.get("/img/{lnurldevice_id}", response_class=StreamingResponse)
async def img(request: Request, lnurldevice_id):
lnurldevice = await get_lnurldevice(lnurldevice_id)
if not lnurldevice:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="LNURLDevice does not exist."
)
qr = pyqrcode.create(lnurldevice.lnurl(request))
stream = BytesIO()
qr.svg(stream, scale=3)
stream.seek(0)
async def _generator(stream: BytesIO):
yield stream.getvalue()
return StreamingResponse(
_generator(stream),
headers={
"Content-Type": "image/svg+xml",
"Cache-Control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0",
},
)
##################WEBSOCKET ROUTES########################
@ -95,4 +124,5 @@ async def updater(lnurldevice_id):
lnurldevice = await get_lnurldevice(lnurldevice_id)
if not lnurldevice:
return
await manager.send_personal_message(f"{lnurldevice.amount}", lnurldevice_id)
await manager.send_personal_message(f"{lnurldevice.amount}", lnurldevice_id)