mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2025-03-11 17:57:53 +01:00
Added a switch
This commit is contained in:
parent
3222ae198d
commit
ff98b87eca
5 changed files with 102 additions and 7 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
import asyncio
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
|
|
||||||
from lnbits.db import Database
|
from lnbits.db import Database
|
||||||
|
|
|
@ -36,7 +36,7 @@ class lnurldevices(BaseModel):
|
||||||
|
|
||||||
def lnurl(self, req: Request) -> Lnurl:
|
def lnurl(self, req: Request) -> Lnurl:
|
||||||
url = req.url_for(
|
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)
|
return lnurl_encode(url)
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<p>
|
<p>
|
||||||
Register LNURLDevice devices to receive payments in your LNbits wallet.<br />
|
For LNURL based Points of Sale, ATMs, and relay devices<br />
|
||||||
Build your own here
|
Such as the LNPoS
|
||||||
<a href="https://github.com/arcbtc/bitcoinpos"
|
<a href="https://lnbits.github.io/lnpos"
|
||||||
>https://github.com/arcbtc/bitcoinpos</a
|
> https://lnbits.github.io/lnpos</a
|
||||||
><br />
|
><br />
|
||||||
<small>
|
<small>
|
||||||
Created by, <a href="https://github.com/benarc">Ben Arc</a></small
|
Created by, <a href="https://github.com/benarc">Ben Arc</a></small
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
<q-tr :props="props">
|
<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 style="width: 5%"></q-th>
|
||||||
|
<q-th style="width: 5%"></q-th>
|
||||||
|
|
||||||
<q-th
|
<q-th
|
||||||
v-for="col in props.cols"
|
v-for="col in props.cols"
|
||||||
|
@ -91,6 +92,21 @@
|
||||||
<q-tooltip> LNURLDevice Settings </q-tooltip>
|
<q-tooltip> LNURLDevice Settings </q-tooltip>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</q-td>
|
</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
|
<q-td
|
||||||
v-for="col in props.cols"
|
v-for="col in props.cols"
|
||||||
:key="col.name"
|
:key="col.name"
|
||||||
|
@ -132,7 +148,21 @@
|
||||||
class="q-pa-lg q-pt-xl lnbits__dialog-card"
|
class="q-pa-lg q-pt-xl lnbits__dialog-card"
|
||||||
>
|
>
|
||||||
<div class="text-h6">LNURLDevice device string</div>
|
<div class="text-h6">LNURLDevice device string</div>
|
||||||
|
<center>
|
||||||
<q-btn
|
<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
|
dense
|
||||||
outline
|
outline
|
||||||
unelevated
|
unelevated
|
||||||
|
@ -145,7 +175,7 @@
|
||||||
{{settingsDialog.data.key}}, {{settingsDialog.data.currency}}{% endraw
|
{{settingsDialog.data.key}}, {{settingsDialog.data.currency}}{% endraw
|
||||||
%}<q-tooltip> Click to copy URL </q-tooltip>
|
%}<q-tooltip> Click to copy URL </q-tooltip>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
|
</center>
|
||||||
<div class="text-subtitle2">
|
<div class="text-subtitle2">
|
||||||
<small> </small>
|
<small> </small>
|
||||||
</div>
|
</div>
|
||||||
|
@ -191,6 +221,7 @@
|
||||||
label="Type of device"
|
label="Type of device"
|
||||||
></q-option-group>
|
></q-option-group>
|
||||||
<q-input
|
<q-input
|
||||||
|
v-if="formDialoglnurldevice.data.device != 'switch'"
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model.trim="formDialoglnurldevice.data.profit"
|
v-model.trim="formDialoglnurldevice.data.profit"
|
||||||
|
@ -198,6 +229,29 @@
|
||||||
max="90"
|
max="90"
|
||||||
label="Profit margin (% added to invoices/deducted from faucets)"
|
label="Profit margin (% added to invoices/deducted from faucets)"
|
||||||
></q-input>
|
></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">
|
<div class="row q-mt-lg">
|
||||||
<q-btn
|
<q-btn
|
||||||
|
@ -253,6 +307,7 @@
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
location: window.location.hostname,
|
location: window.location.hostname,
|
||||||
|
wslocation: window.location.hostname,
|
||||||
filter: '',
|
filter: '',
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
lnurldeviceLinks: [],
|
lnurldeviceLinks: [],
|
||||||
|
@ -265,6 +320,10 @@
|
||||||
{
|
{
|
||||||
label: 'ATM',
|
label: 'ATM',
|
||||||
value: 'atm'
|
value: 'atm'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Switch',
|
||||||
|
value: 'switch'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
lnurldevicesTable: {
|
lnurldevicesTable: {
|
||||||
|
@ -334,6 +393,7 @@
|
||||||
show_price: 'None',
|
show_price: 'None',
|
||||||
device: 'pos',
|
device: 'pos',
|
||||||
profit: 2,
|
profit: 2,
|
||||||
|
amount: 1,
|
||||||
title: ''
|
title: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -519,6 +579,10 @@
|
||||||
'//',
|
'//',
|
||||||
window.location.host
|
window.location.host
|
||||||
].join('')
|
].join('')
|
||||||
|
self.wslocation = [
|
||||||
|
'ws://',
|
||||||
|
window.location.host
|
||||||
|
].join('')
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.request('GET', '/api/v1/currencies')
|
.request('GET', '/api/v1/currencies')
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
import pyqrcode
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
from fastapi.param_functions import Query
|
from fastapi.param_functions import Query
|
||||||
|
@ -14,6 +16,9 @@ from lnbits.decorators import check_user_exists
|
||||||
|
|
||||||
from . import lnurldevice_ext, lnurldevice_renderer
|
from . import lnurldevice_ext, lnurldevice_renderer
|
||||||
from .crud import get_lnurldevice, get_lnurldevicepayment
|
from .crud import get_lnurldevice, get_lnurldevicepayment
|
||||||
|
from fastapi import Request, WebSocket, WebSocketDisconnect
|
||||||
|
|
||||||
|
from starlette.responses import HTMLResponse, StreamingResponse
|
||||||
|
|
||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
|
||||||
|
@ -52,6 +57,30 @@ async def displaypin(request: Request, paymentid: str = Query(None)):
|
||||||
{"request": request, "pin": "filler", "not_paid": True},
|
{"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########################
|
##################WEBSOCKET ROUTES########################
|
||||||
|
|
||||||
|
@ -96,3 +125,4 @@ async def updater(lnurldevice_id):
|
||||||
if not lnurldevice:
|
if not lnurldevice:
|
||||||
return
|
return
|
||||||
await manager.send_personal_message(f"{lnurldevice.amount}", lnurldevice_id)
|
await manager.send_personal_message(f"{lnurldevice.amount}", lnurldevice_id)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue