changed name to myextension

This commit is contained in:
benarc 2024-01-16 16:38:53 +00:00
parent ba7e11e30d
commit 0711f583d6
16 changed files with 221 additions and 225 deletions

View file

@ -1,6 +1,6 @@
`The README.md typically serves as a guide for using the extension.`
# Temp - An [LNbits](https://github.com/lnbits/lnbits) Extension
# MyExtension - An [LNbits](https://github.com/lnbits/lnbits) Extension
## A Starter Template for Your Own Extension
@ -9,11 +9,11 @@ Ready to start hacking? Once you've forked this extension, you can incorporate f
### How to Use This Template
> This guide assumes you're using this extension as a base for a new one, and have installed LNbits using https://github.com/lnbits/lnbits/blob/main/docs/guide/installation.md#option-1-recommended-poetry.
1. Install and enable the extension either through the official LNbits manifest or by adding https://raw.githubusercontent.com/lnbits/temp/main/manifest.json to `"Server"/"Server"/"Extension Sources"`. ![Extension Sources](https://i.imgur.com/MUGwAU3.png) ![Extension Enable](https://i.imgur.com/hHXn6d2.png)
1. Install and enable the extension either through the official LNbits manifest or by adding https://raw.githubusercontent.com/lnbits/myextension/main/manifest.json to `"Server"/"Server"/"Extension Sources"`. ![Extension Sources](https://i.imgur.com/MUGwAU3.png) ![Extension Enable](https://i.imgur.com/hHXn6d2.png)
2. `Ctrl c` shut down your LNbits installation.
3. Download the extension files from https://github.com/lnbits/temp to a folder outside of `/lnbits`, and initialize the folder with `git`. Alternatively, create a repo, copy the temp extension files into it, then `git clone` the extension to a location outside of `/lnbits`.
3. Download the extension files from https://github.com/lnbits/myextension to a folder outside of `/lnbits`, and initialize the folder with `git`. Alternatively, create a repo, copy the myextension extension files into it, then `git clone` the extension to a location outside of `/lnbits`.
4. Remove the installed extension from `lnbits/lnbits/extensions`.
5. Create a symbolic link using `ln -s /home/ben/Projects/<name of your extension> /home/ben/Projects/lnbits/lnbits/extensions`.
6. Restart your LNbits installation. You can now modify your extension and `git push` changes to a repo.
7. When you're ready to share your manifest so others can install it, edit `/lnbits/temp/manifest.json` to include the git credentials of your extension.
7. When you're ready to share your manifest so others can install it, edit `/lnbits/myextension/manifest.json` to include the git credentials of your extension.
8. IMPORTANT: If you want your extension to be added to the official LNbits manifest, please follow the guidelines here: https://github.com/lnbits/lnbits-extensions#important

View file

@ -6,28 +6,27 @@ from lnbits.db import Database
from lnbits.helpers import template_renderer
from lnbits.tasks import catch_everything_and_restart
db = Database("ext_tempextension")
db = Database("ext_myextension")
temp_ext: APIRouter = APIRouter(
prefix="/temp", tags=["Temp"]
myextension_ext: APIRouter = APIRouter(
prefix="/myextension", tags=["MyExtension"]
)
temp_static_files = [
{
"path": "/temp/static",
"path": "/myextension/static",
"name": "temp_static",
}
]
def temp_renderer():
return template_renderer(["temp/templates"])
def myextension_renderer():
return template_renderer(["myextension/templates"])
from .lnurl import *
from .tasks import wait_for_paid_invoices
from .views import *
from .views_api import *
def temp_start():
loop = asyncio.get_event_loop()
loop.create_task(catch_everything_and_restart(wait_for_paid_invoices))

View file

@ -1,7 +1,7 @@
{
"name": "Temp",
"name": "MyExtension",
"short_description": "Minimal extension to build on",
"tile": "/temp/static/image/temp.png",
"tile": "/myextension/static/image/myextension.png",
"contributors": ["arcbtc"],
"min_lnbits_version": "0.0.1"
}

48
crud.py
View file

@ -3,58 +3,58 @@ from typing import List, Optional, Union
from lnbits.helpers import urlsafe_short_hash
from . import db
from .models import CreateTempData, Temp
from .models import CreateMyExtensionData, MyExtension
from loguru import logger
from fastapi import Request
from lnurl import encode as lnurl_encode
async def create_temp(wallet_id: str, data: CreateTempData) -> Temp:
temp_id = urlsafe_short_hash()
async def create_myextension(wallet_id: str, data: CreateMyExtensionData) -> MyExtension:
myextension_id = urlsafe_short_hash()
await db.execute(
"""
INSERT INTO tempextension.temp (id, wallet, name, lnurlpayamount, lnurlwithdrawamount)
INSERT INTO myextension.maintable (id, wallet, name, lnurlpayamount, lnurlwithdrawamount)
VALUES (?, ?, ?, ?, ?)
""",
(
temp_id,
myextension_id,
wallet_id,
data.name,
data.lnurlpayamount,
data.lnurlwithdrawamount
),
)
temp = await get_temp(temp_id)
assert temp, "Newly created temp couldn't be retrieved"
return temp
myextension = await get_myextension(myextension_id)
assert myextension, "Newly created table couldn't be retrieved"
return myextension
async def get_temp(temp_id: str) -> Optional[Temp]:
row = await db.fetchone("SELECT * FROM tempextension.temp WHERE id = ?", (temp_id,))
return Temp(**row) if row else None
async def get_myextension(myextension_id: str) -> Optional[MyExtension]:
row = await db.fetchone("SELECT * FROM myextension.maintable WHERE id = ?", (myextension_id,))
return MyExtension(**row) if row else None
async def get_temps(wallet_ids: Union[str, List[str]], req: Request) -> List[Temp]:
async def get_myextensions(wallet_ids: Union[str, List[str]], req: Request) -> List[MyExtension]:
if isinstance(wallet_ids, str):
wallet_ids = [wallet_ids]
q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall(
f"SELECT * FROM tempextension.temp WHERE wallet IN ({q})", (*wallet_ids,)
f"SELECT * FROM myextension.maintable WHERE wallet IN ({q})", (*wallet_ids,)
)
tempRows = [Temp(**row) for row in rows]
logger.debug(req.url_for("temp.api_lnurl_pay", temp_id=row.id))
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("temp.api_lnurl_pay", temp_id=row.id)
row.lnurlwithdraw = req.url_for("temp.api_lnurl_withdraw", temp_id=row.id)
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)
return tempRows
async def update_temp(temp_id: str, **kwargs) -> Temp:
async def update_myextension(myextension_id: str, **kwargs) -> MyExtension:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute(
f"UPDATE tempextension.temp SET {q} WHERE id = ?", (*kwargs.values(), temp_id)
f"UPDATE myextension.maintable SET {q} WHERE id = ?", (*kwargs.values(), myextension_id)
)
temp = await get_temp(temp_id)
assert temp, "Newly updated temp couldn't be retrieved"
return temp
myextension = await get_myextension(myextension_id)
assert myextension, "Newly updated myextension couldn't be retrieved"
return myextension
async def delete_temp(temp_id: str) -> None:
await db.execute("DELETE FROM tempextension.temp WHERE id = ?", (temp_id,))
async def delete_myextension(myextension_id: str) -> None:
await db.execute("DELETE FROM myextension.maintable WHERE id = ?", (myextension_id,))

View file

@ -3,8 +3,8 @@
from http import HTTPStatus
from fastapi import Depends, Query, Request
from . import temp_ext
from .crud import get_temp
from . import myextension_ext
from .crud import get_myextension
from lnbits.core.services import create_invoice
@ -14,48 +14,48 @@ from lnbits.core.services import create_invoice
#################################################
#################################################
@temp_ext.get(
"/api/v1/lnurl/pay/{temp_id}",
@myextension_ext.get(
"/api/v1/lnurl/pay/{myextension_id}",
status_code=HTTPStatus.OK,
name="temp.api_lnurl_pay",
name="myextension.api_lnurl_pay",
)
async def api_lnurl_pay(
request: Request,
temp_id: str,
myextension_id: str,
):
temp = await get_temp(temp_id)
if not temp:
return {"status": "ERROR", "reason": "No temp found"}
myextension = await get_myextension(myextension_id)
if not myextension:
return {"status": "ERROR", "reason": "No myextension found"}
return {
"callback": str(request.url_for("temp.api_lnurl_pay_callback", temp_id=temp_id)),
"maxSendable": temp.lnurlpayamount,
"minSendable": temp.lnurlpayamount,
"metadata":"[[\"text/plain\", \"" + temp.name + "\"]]",
"callback": str(request.url_for("myextension.api_lnurl_pay_callback", myextension_id=myextension_id)),
"maxSendable": myextension.lnurlpayamount,
"minSendable": myextension.lnurlpayamount,
"metadata":"[[\"text/plain\", \"" + myextension.name + "\"]]",
"tag": "payRequest"
}
@temp_ext.get(
"/api/v1/lnurl/pay/cb/{temp_id}",
@myextension_ext.get(
"/api/v1/lnurl/pay/cb/{myextension_id}",
status_code=HTTPStatus.OK,
name="temp.api_lnurl_pay_callback",
name="myextension.api_lnurl_pay_callback",
)
async def api_lnurl_pay_cb(
request: Request,
temp_id: str,
myextension_id: str,
amount: int = Query(...),
):
temp = await get_temp(temp_id)
if not temp:
return {"status": "ERROR", "reason": "No temp found"}
myextension = await get_myextension(myextension_id)
if not myextension:
return {"status": "ERROR", "reason": "No myextension found"}
payment_request = await create_invoice(
wallet_id=temp.wallet,
wallet_id=myextension.wallet,
amount=int(amount / 1000),
memo=temp.name,
unhashed_description="[[\"text/plain\", \"" + temp.name + "\"]]".encode(),
memo=myextension.name,
unhashed_description="[[\"text/plain\", \"" + myextension.name + "\"]]".encode(),
extra= {
"tag": "temp",
"link": temp_id,
"tag": "myextension",
"link": myextension_id,
"extra": request.query_params.get("amount"),
},
)
@ -68,50 +68,50 @@ async def api_lnurl_pay_cb(
#################################################
@temp_ext.get(
"/api/v1/lnurl/withdraw/{temp_id}",
@myextension_ext.get(
"/api/v1/lnurl/withdraw/{myextension_id}",
status_code=HTTPStatus.OK,
name="temp.api_lnurl_withdraw",
name="myextension.api_lnurl_withdraw",
)
async def api_lnurl_pay(
request: Request,
temp_id: str,
myextension_id: str,
):
temp = await get_temp(temp_id)
if not temp:
return {"status": "ERROR", "reason": "No temp found"}
myextension = await get_myextension(myextension_id)
if not myextension:
return {"status": "ERROR", "reason": "No myextension found"}
return {
"callback": str(request.url_for("temp.api_lnurl_withdraw_callback", temp_id=temp_id)),
"maxSendable": temp.lnurlwithdrawamount,
"minSendable": temp.lnurlwithdrawamount,
"callback": str(request.url_for("myextension.api_lnurl_withdraw_callback", myextension_id=myextension_id)),
"maxSendable": myextension.lnurlwithdrawamount,
"minSendable": myextension.lnurlwithdrawamount,
"k1": "",
"defaultDescription": temp.name,
"metadata":"[[\"text/plain\", \"" + temp.name + "\"]]",
"defaultDescription": myextension.name,
"metadata":"[[\"text/plain\", \"" + myextension.name + "\"]]",
"tag": "withdrawRequest"
}
@temp_ext.get(
"/api/v1/lnurl/pay/cb/{temp_id}",
@myextension_ext.get(
"/api/v1/lnurl/pay/cb/{myextension_id}",
status_code=HTTPStatus.OK,
name="temp.api_lnurl_withdraw_callback",
name="myextension.api_lnurl_withdraw_callback",
)
async def api_lnurl_pay_cb(
request: Request,
temp_id: str,
myextension_id: str,
amount: int = Query(...),
):
temp = await get_temp(temp_id)
if not temp:
return {"status": "ERROR", "reason": "No temp found"}
myextension = await get_myextension(myextension_id)
if not myextension:
return {"status": "ERROR", "reason": "No myextension found"}
payment_request = await create_invoice(
wallet_id=temp.wallet,
wallet_id=myextension.wallet,
amount=int(amount / 1000),
memo=temp.name,
unhashed_description="[[\"text/plain\", \"" + temp.name + "\"]]".encode(),
memo=myextension.name,
unhashed_description="[[\"text/plain\", \"" + myextension.name + "\"]]".encode(),
extra= {
"tag": "temp",
"link": temp_id,
"tag": "myextension",
"link": myextension_id,
"extra": request.query_params.get("amount"),
},
)

View file

@ -1,9 +1,9 @@
{
"repos": [
{
"id": "temp",
"id": "myextension",
"organisation": "lnbits",
"repository": "temp"
"repository": "myextension"
}
]
}

View file

@ -6,7 +6,7 @@ async def m001_initial(db):
"""
await db.execute(
"""
CREATE TABLE tempextension.temp (
CREATE TABLE myextension.maintable (
id TEXT PRIMARY KEY,
wallet TEXT NOT NULL,
name TEXT NOT NULL,
@ -24,7 +24,7 @@ async def m002_addtip_wallet(db):
"""
await db.execute(
"""
ALTER TABLE tempextension.temp ADD lnurlwithdrawamount INTEGER DEFAULT 0;
ALTER TABLE myextension.maintable ADD lnurlwithdrawamount INTEGER DEFAULT 0;
"""
)
@ -36,7 +36,7 @@ async def m004_addtip_wallet(db):
"""
await db.execute(
"""
ALTER TABLE tempextension.temp ADD lnurlwithdraw TEXT;
ALTER TABLE myextension.maintable ADD lnurlwithdraw TEXT;
"""
)
@ -48,6 +48,6 @@ async def m005_addtip_wallet(db):
"""
await db.execute(
"""
ALTER TABLE tempextension.temp ADD lnurlpay TEXT;
ALTER TABLE myextension.maintable ADD lnurlpay TEXT;
"""
)

View file

@ -9,14 +9,14 @@ from fastapi import Request
from lnbits.lnurl import encode as lnurl_encode
from urllib.parse import urlparse
class CreateTempData(BaseModel):
class CreateMyExtensionData(BaseModel):
wallet: Optional[str]
name: Optional[str]
total: Optional[int]
lnurlpayamount: Optional[int]
lnurlwithdrawamount: Optional[int]
class Temp(BaseModel):
class MyExtension(BaseModel):
id: str
wallet: str
name: str
@ -27,8 +27,5 @@ class Temp(BaseModel):
lnurlwithdraw: str
@classmethod
def from_row(cls, row: Row) -> "Temp":
def from_row(cls, row: Row) -> "MyExtension":
return cls(**dict(row))
class CreateUpdateTempData(BaseModel):
items: List[Temp]

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

View file

@ -7,7 +7,7 @@ from lnbits.core.services import create_invoice, pay_invoice, websocketUpdater
from lnbits.helpers import get_current_extension_name
from lnbits.tasks import register_invoice_listener
from .crud import get_temp
from .crud import get_myextension
#######################################
@ -29,31 +29,31 @@ async def wait_for_paid_invoices():
# do somethhing when an invoice related top this extension is paid
async def on_invoice_paid(payment: Payment) -> None:
if payment.extra.get("tag") != "temp":
if payment.extra.get("tag") != "myextension":
return
temp_id = payment.extra.get("tempId")
assert temp_id
myextension_id = payment.extra.get("tempId")
assert myextension_id
temp = await get_temp(temp_id)
assert temp
myextension = await get_myextension(myextension_id)
assert myextension
# update something
data_to_update = {
"total": temp.total + payment.amount
"total": myextension.total + payment.amount
}
await update_temp(temp_id=temp_id, **data_to_update.dict())
await update_myextension(myextension_id=myextension_id, **data_to_update.dict())
# here we could send some data to a websocket on wss://<your-lnbits>/api/v1/ws/<temp_id>
# here we could send some data to a websocket on wss://<your-lnbits>/api/v1/ws/<myextension_id>
some_payment_data = {
"name": temp.name,
"name": myextension.name,
"amount": payment.amount,
"fee": payment.fee,
"checking_id": payment.checking_id
}
await websocketUpdater(temp_id, str(some_payment_data))
await websocketUpdater(myextension_id, str(some_payment_data))

View file

@ -4,11 +4,11 @@
label="API info"
:content-inset-level="0.5"
>
<q-btn flat label="Swagger API" type="a" href="../docs#/temp"></q-btn>
<q-expansion-item group="api" dense expand-separator label="List Temp">
<q-btn flat label="Swagger API" type="a" href="../docs#/myextension"></q-btn>
<q-expansion-item group="api" dense expand-separator label="List MyExtension">
<q-card>
<q-card-section>
<code><span class="text-blue">GET</span> /temp/api/v1/temps</code>
<code><span class="text-blue">GET</span> /myextension/api/v1/temps</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
@ -18,16 +18,16 @@
<code>[&lt;temp_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X GET {{ request.base_url }}temp/api/v1/temps -H "X-Api-Key:
>curl -X GET {{ request.base_url }}myextension/api/v1/temps -H "X-Api-Key:
&lt;invoice_key&gt;"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
<q-expansion-item group="api" dense expand-separator label="Create a Temp">
<q-expansion-item group="api" dense expand-separator label="Create a MyExtension">
<q-card>
<q-card-section>
<code><span class="text-green">POST</span> /temp/api/v1/temps</code>
<code><span class="text-green">POST</span> /myextension/api/v1/temps</code>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
@ -43,7 +43,7 @@
>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X POST {{ request.base_url }}temp/api/v1/temps -d '{"name":
>curl -X POST {{ request.base_url }}myextension/api/v1/temps -d '{"name":
&lt;string&gt;, "currency": &lt;string&gt;}' -H "Content-type:
application/json" -H "X-Api-Key: &lt;admin_key&gt;"
</code>
@ -55,14 +55,14 @@
group="api"
dense
expand-separator
label="Delete a Temp"
label="Delete a MyExtension"
class="q-pb-md"
>
<q-card>
<q-card-section>
<code
><span class="text-pink">DELETE</span>
/temp/api/v1/temps/&lt;temp_id&gt;</code
/myextension/api/v1/temps/&lt;myextension_id&gt;</code
>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br />
@ -71,7 +71,7 @@
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X DELETE {{ request.base_url
}}temp/api/v1/temps/&lt;temp_id&gt; -H "X-Api-Key: &lt;admin_key&gt;"
}}myextension/api/v1/temps/&lt;myextension_id&gt; -H "X-Api-Key: &lt;admin_key&gt;"
</code>
</q-card-section>
</q-card>

View file

@ -1,8 +1,8 @@
<q-expansion-item group="extras" icon="info" label="About Temp">
<q-expansion-item group="extras" icon="info" label="About MyExtension">
<q-card>
<q-card-section>
<p>
Temp extension is a basic extension that you can use to get started building your own extension
MyExtension extension is a basic extension that you can use to get started building your own extension
</p>
<small
>Created by

View file

@ -5,7 +5,7 @@
<q-card>
<q-card-section>
<q-btn unelevated color="primary" @click="formDialog.show = true"
>New Temp</q-btn
>New MyExtension</q-btn
>
</q-card-section>
</q-card>
@ -14,7 +14,7 @@
<q-card-section>
<div class="row items-center no-wrap q-mb-md">
<div class="col">
<h5 class="text-subtitle1 q-my-none">Temp</h5>
<h5 class="text-subtitle1 q-my-none">MyExtension</h5>
</div>
<div class="col-auto">
<q-btn flat color="grey" @click="exportCSV">Export to CSV</q-btn>
@ -28,13 +28,13 @@
:columns="tempsTable.columns"
:pagination.sync="tempsTable.pagination"
>
<temp v-slot:header="props">
<myextension v-slot:header="props">
<q-tr :props="props">
<q-th v-for="col in props.cols" :key="col.name" :props="props">
${ col.label }
</q-th>
</q-tr>
</temp>
</myextension>
<template v-slot:body="props">
<q-tr :props="props">
@ -63,7 +63,7 @@
icon="launch"
:color="($q.dark.isActive) ? 'grey-7' : 'grey-5'"
type="a"
:href="props.row.temp"
:href="props.row.myextension"
target="_blank"
><q-tooltip>Open public page</q-tooltip></q-btn
></q-td>
@ -91,15 +91,15 @@
<div class="col-12 col-md-4 col-lg-5 q-gutter-y-md">
<q-card>
<q-card-section>
<h6 class="text-subtitle1 q-my-none">{{SITE_TITLE}} Temp extension</h6>
<h6 class="text-subtitle1 q-my-none">{{SITE_TITLE}} MyExtension extension</h6>
<p>Simple extension you can use as a base for your own extension. <br/> Includes very simple LNURL-pay and LNURL-withdraw example.</p>
</q-card-section>
<q-card-section class="q-pa-none">
<q-separator></q-separator>
<q-list>
{% include "temp/_api_docs.html" %}
{% include "myextension/_api_docs.html" %}
<q-separator></q-separator>
{% include "temp/_temp.html" %}
{% include "myextension/_myextension.html" %}
</q-list>
</q-card-section>
</q-card>
@ -143,7 +143,7 @@
unelevated
color="primary"
type="submit"
>Update Temp</q-btn
>Update MyExtension</q-btn
>
<q-btn
v-else
@ -151,7 +151,7 @@
color="primary"
:disable="formDialog.data.name == null || formDialog.data.wallet == null || formDialog.data.lnurlwithdrawamount == null || formDialog.data.lnurlpayamount == null"
type="submit"
>Create Temp</q-btn
>Create MyExtension</q-btn
>
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
>Cancel</q-btn
@ -176,7 +176,7 @@
<q-btn
outline
color="grey"
@click="copyText(urlDialog.data.lnurlpay, 'Temp URL copied to clipboard!')"
@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>
@ -192,7 +192,7 @@
new Date(obj.time * 1000),
'YYYY-MM-DD HH:mm'
)
obj.temp = ['/temp/', obj.id].join('')
obj.myextension = ['/myextension/', obj.id].join('')
return obj
}
@ -251,7 +251,7 @@
LNbits.api
.request(
'GET',
'/temp/api/v1/temps?all_wallets=true',
'/myextension/api/v1/temps?all_wallets=true',
this.g.user.wallets[0].inkey
)
.then(function (response) {
@ -278,10 +278,10 @@
}
},
updateTPosForm(tempId) {
const temp = _.findWhere(this.temps, {id: tempId})
const myextension = _.findWhere(this.temps, {id: tempId})
this.formDialog.data = {
...temp,
tip_options: JSON.parse(temp.tip_options)
...myextension,
tip_options: JSON.parse(myextension.tip_options)
}
if (this.formDialog.data.tip_wallet != '') {
this.formDialog.advanced.tips = true
@ -293,7 +293,7 @@
},
createTemp(wallet, data) {
LNbits.api
.request('POST', '/temp/api/v1/temps', wallet.inkey, data)
.request('POST', '/myextension/api/v1/temps', wallet.inkey, data)
.then(response => {
this.temps.push(mapTemp(response.data))
this.closeFormDialog()
@ -306,7 +306,7 @@
LNbits.api
.request(
'PUT',
`/temp/api/v1/temps/${data.id}`,
`/myextension/api/v1/temps/${data.id}`,
wallet.adminkey,
data
)
@ -323,16 +323,16 @@
},
deleteTemp: function (tempId) {
var self = this
var temp = _.findWhere(this.temps, {id: tempId})
var myextension = _.findWhere(this.temps, {id: tempId})
LNbits.utils
.confirmDialog('Are you sure you want to delete this Temp?')
.confirmDialog('Are you sure you want to delete this MyExtension?')
.onOk(function () {
LNbits.api
.request(
'DELETE',
'/temp/api/v1/temps/' + tempId,
_.findWhere(self.g.user.wallets, {id: temp.wallet}).adminkey
'/myextension/api/v1/temps/' + tempId,
_.findWhere(self.g.user.wallets, {id: myextension.wallet}).adminkey
)
.then(function (response) {
self.temps = _.reject(self.temps, function (obj) {
@ -348,27 +348,27 @@
LNbits.utils.exportCSV(this.tempsTable.columns, this.temps)
},
itemsArray(tempId) {
const temp = _.findWhere(this.temps, {id: tempId})
return [...temp.itemsMap.values()]
const myextension = _.findWhere(this.temps, {id: tempId})
return [...myextension.itemsMap.values()]
},
itemFormatPrice(price, id) {
const temp = id.split(':')[0]
const currency = _.findWhere(this.temps, {id: temp}).currency
const myextension = id.split(':')[0]
const currency = _.findWhere(this.temps, {id: myextension}).currency
return LNbits.utils.formatCurrency(Number(price).toFixed(2), currency)
},
openformDialog(id) {
const [tempId, itemId] = id.split(':')
const temp = _.findWhere(this.temps, {id: tempId})
const myextension = _.findWhere(this.temps, {id: tempId})
if (itemId) {
const item = temp.itemsMap.get(id)
const item = myextension.itemsMap.get(id)
this.formDialog.data = {
...item,
temp: tempId
myextension: tempId
}
} else {
this.formDialog.data.temp = tempId
this.formDialog.data.myextension = tempId
}
this.formDialog.data.currency = temp.currency
this.formDialog.data.currency = myextension.currency
this.formDialog.show = true
},
closeformDialog() {

View file

@ -9,8 +9,8 @@ from lnbits.core.models import User
from lnbits.decorators import check_user_exists
from lnbits.settings import settings
from . import temp_ext, temp_renderer
from .crud import get_temp
from . import myextension_ext, myextension_renderer
from .crud import get_myextension
temps = Jinja2Templates(directory="temps")
@ -22,47 +22,47 @@ temps = Jinja2Templates(directory="temps")
# Backend admin page
@temp_ext.get("/", response_class=HTMLResponse)
@myextension_ext.get("/", response_class=HTMLResponse)
async def index(request: Request, user: User = Depends(check_user_exists)):
return temp_renderer().TemplateResponse(
"temp/index.html", {"request": request, "user": user.dict()}
return myextension_renderer().TemplateResponse(
"myextension/index.html", {"request": request, "user": user.dict()}
)
# Frontend shareable page
@temp_ext.get("/{temp_id}")
async def temp(request: Request, temp_id):
temp = await get_temp(temp_id)
if not temp:
@myextension_ext.get("/{myextension_id}")
async def myextension(request: Request, myextension_id):
myextension = await get_myextension(myextension_id)
if not myextension:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Temp does not exist."
status_code=HTTPStatus.NOT_FOUND, detail="MyExtension does not exist."
)
return temp_renderer().TemplateResponse(
"temp/temp.html",
return myextension_renderer().TemplateResponse(
"myextension/myextension.html",
{
"request": request,
"temp_id": temp_id,
"lnurlpay": temp.lnurlpayamount,
"lnurlwithdraw": temp.lnurlwithdrawamount,
"web_manifest": f"/temp/manifest/{temp_id}.webmanifest",
"myextension_id": myextension_id,
"lnurlpay": myextension.lnurlpayamount,
"lnurlwithdraw": myextension.lnurlwithdrawamount,
"web_manifest": f"/myextension/manifest/{myextension_id}.webmanifest",
},
)
# Manifest for public page, customise or remove manifest completely
@temp_ext.get("/manifest/{temp_id}.webmanifest")
async def manifest(temp_id: str):
temp= await get_temp(temp_id)
if not temp:
@myextension_ext.get("/manifest/{myextension_id}.webmanifest")
async def manifest(myextension_id: str):
myextension= await get_myextension(myextension_id)
if not myextension:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Temp does not exist."
status_code=HTTPStatus.NOT_FOUND, detail="MyExtension does not exist."
)
return {
"short_name": settings.lnbits_site_title,
"name": temp.name + " - " + settings.lnbits_site_title,
"name": myextension.name + " - " + settings.lnbits_site_title,
"icons": [
{
"src": settings.lnbits_custom_logo
@ -72,18 +72,18 @@ async def manifest(temp_id: str):
"sizes": "900x900",
}
],
"start_url": "/temp/" + temp_id,
"start_url": "/myextension/" + myextension_id,
"background_color": "#1F2234",
"description": "Minimal extension to build on",
"display": "standalone",
"scope": "/temp/" + temp_id,
"scope": "/myextension/" + myextension_id,
"theme_color": "#1F2234",
"shortcuts": [
{
"name": temp.name + " - " + settings.lnbits_site_title,
"short_name": temp.name,
"description": temp.name + " - " + settings.lnbits_site_title,
"url": "/temp/" + temp_id,
"name": myextension.name + " - " + settings.lnbits_site_title,
"short_name": myextension.name,
"description": myextension.name + " - " + settings.lnbits_site_title,
"url": "/myextension/" + myextension_id,
}
],
}

View file

@ -19,15 +19,15 @@ from lnbits.decorators import (
require_invoice_key,
)
from . import temp_ext
from . import myextension_ext
from .crud import (
create_temp,
update_temp,
delete_temp,
get_temp,
get_temps
create_myextension,
update_myextension,
delete_myextension,
get_myextension,
get_myextensions
)
from .models import CreateTempData
from .models import CreateMyExtensionData
#######################################
@ -36,65 +36,65 @@ from .models import CreateTempData
## Get all the records belonging to the user
@temp_ext.get("/api/v1/temps", status_code=HTTPStatus.OK)
async def api_temps(
@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)
):
wallet_ids = [wallet.wallet.id]
if all_wallets:
user = await get_user(wallet.wallet.user)
wallet_ids = user.wallet_ids if user else []
return [temp.dict() for temp in await get_temps(wallet_ids, req)]
return [myextension.dict() for myextension in await get_myextensions(wallet_ids, req)]
## Get a specific record belonging to a user
@temp_ext.put("/api/v1/temps/{temp_id}")
async def api_temp_update(
data: CreateTempData,
temp_id: str,
@myextension_ext.put("/api/v1/temps/{myextension_id}")
async def api_myextension_update(
data: CreateMyExtensionData,
myextension_id: str,
wallet: WalletTypeInfo = Depends(require_admin_key),
):
if not temp_id:
if not myextension_id:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Temp does not exist."
status_code=HTTPStatus.NOT_FOUND, detail="MyExtension does not exist."
)
temp = await get_temp(temp_id)
assert temp, "Temp couldn't be retrieved"
myextension = await get_myextension(myextension_id)
assert myextension, "MyExtension couldn't be retrieved"
if wallet.wallet.id != temp.wallet:
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your Temp.")
temp = await update_temp(temp_id=temp_id, **data.dict())
return temp.dict()
if wallet.wallet.id != myextension.wallet:
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your MyExtension.")
myextension = await update_myextension(myextension_id=myextension_id, **data.dict())
return myextension.dict()
## Create a new record
@temp_ext.post("/api/v1/temps", status_code=HTTPStatus.CREATED)
async def api_temp_create(
data: CreateTempData, wallet: WalletTypeInfo = Depends(get_key_type)
@myextension_ext.post("/api/v1/temps", status_code=HTTPStatus.CREATED)
async def api_myextension_create(
data: CreateMyExtensionData, wallet: WalletTypeInfo = Depends(get_key_type)
):
temp = await create_temp(wallet_id=wallet.wallet.id, data=data)
return temp.dict()
myextension = await create_myextension(wallet_id=wallet.wallet.id, data=data)
return myextension.dict()
## Delete a record
@temp_ext.delete("/api/v1/temps/{temp_id}")
async def api_temp_delete(
temp_id: str, wallet: WalletTypeInfo = Depends(require_admin_key)
@myextension_ext.delete("/api/v1/temps/{myextension_id}")
async def api_myextension_delete(
myextension_id: str, wallet: WalletTypeInfo = Depends(require_admin_key)
):
temp = await get_temp(temp_id)
myextension = await get_myextension(myextension_id)
if not temp:
if not myextension:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Temp does not exist."
status_code=HTTPStatus.NOT_FOUND, detail="MyExtension does not exist."
)
if temp.wallet != wallet.wallet.id:
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your Temp.")
if myextension.wallet != wallet.wallet.id:
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your MyExtension.")
await delete_temp(temp_id)
await delete_myextension(myextension_id)
return "", HTTPStatus.NO_CONTENT
@ -102,26 +102,26 @@ async def api_temp_delete(
## This endpoint creates a payment
@temp_ext.post("/api/v1/temps/payment/{temp_id}", status_code=HTTPStatus.CREATED)
@myextension_ext.post("/api/v1/temps/payment/{myextension_id}", status_code=HTTPStatus.CREATED)
async def api_tpos_create_invoice(
temp_id: str, amount: int = Query(..., ge=1), memo: str = ""
myextension_id: str, amount: int = Query(..., ge=1), memo: str = ""
) -> dict:
temp = await get_temp(temp_id)
myextension = await get_myextension(myextension_id)
if not temp:
if not myextension:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Temp does not exist."
status_code=HTTPStatus.NOT_FOUND, detail="MyExtension does not exist."
)
# we create a payment and add some tags, so tasks.py can grab the payment once its paid
try:
payment_hash, payment_request = await create_invoice(
wallet_id=temp.wallet,
wallet_id=myextension.wallet,
amount=amount,
memo=f"{memo} to {temp.name}" if memo else f"{temp.name}",
memo=f"{memo} to {myextension.name}" if memo else f"{myextension.name}",
extra={
"tag": "temp",
"tag": "myextension",
"tipAmount": tipAmount,
"tempId": tempId,
"amount": amount,