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.` `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 ## 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 ### 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. > 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. 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`. 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`. 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. 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 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.helpers import template_renderer
from lnbits.tasks import catch_everything_and_restart from lnbits.tasks import catch_everything_and_restart
db = Database("ext_tempextension") db = Database("ext_myextension")
temp_ext: APIRouter = APIRouter( myextension_ext: APIRouter = APIRouter(
prefix="/temp", tags=["Temp"] prefix="/myextension", tags=["MyExtension"]
) )
temp_static_files = [ temp_static_files = [
{ {
"path": "/temp/static", "path": "/myextension/static",
"name": "temp_static", "name": "temp_static",
} }
] ]
def temp_renderer(): def myextension_renderer():
return template_renderer(["temp/templates"]) return template_renderer(["myextension/templates"])
from .lnurl import * from .lnurl import *
from .tasks import wait_for_paid_invoices from .tasks import wait_for_paid_invoices
from .views import * from .views import *
from .views_api import * from .views_api import *
def temp_start(): def temp_start():
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
loop.create_task(catch_everything_and_restart(wait_for_paid_invoices)) 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", "short_description": "Minimal extension to build on",
"tile": "/temp/static/image/temp.png", "tile": "/myextension/static/image/myextension.png",
"contributors": ["arcbtc"], "contributors": ["arcbtc"],
"min_lnbits_version": "0.0.1" "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 lnbits.helpers import urlsafe_short_hash
from . import db from . import db
from .models import CreateTempData, Temp from .models import CreateMyExtensionData, MyExtension
from loguru import logger from loguru import logger
from fastapi import Request from fastapi import Request
from lnurl import encode as lnurl_encode from lnurl import encode as lnurl_encode
async def create_temp(wallet_id: str, data: CreateTempData) -> Temp: async def create_myextension(wallet_id: str, data: CreateMyExtensionData) -> MyExtension:
temp_id = urlsafe_short_hash() myextension_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO tempextension.temp (id, wallet, name, lnurlpayamount, lnurlwithdrawamount) INSERT INTO myextension.maintable (id, wallet, name, lnurlpayamount, lnurlwithdrawamount)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?)
""", """,
( (
temp_id, myextension_id,
wallet_id, wallet_id,
data.name, data.name,
data.lnurlpayamount, data.lnurlpayamount,
data.lnurlwithdrawamount data.lnurlwithdrawamount
), ),
) )
temp = await get_temp(temp_id) myextension = await get_myextension(myextension_id)
assert temp, "Newly created temp couldn't be retrieved" assert myextension, "Newly created table couldn't be retrieved"
return temp return myextension
async def get_temp(temp_id: str) -> Optional[Temp]: async def get_myextension(myextension_id: str) -> Optional[MyExtension]:
row = await db.fetchone("SELECT * FROM tempextension.temp WHERE id = ?", (temp_id,)) row = await db.fetchone("SELECT * FROM myextension.maintable WHERE id = ?", (myextension_id,))
return Temp(**row) if row else None 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): if isinstance(wallet_ids, str):
wallet_ids = [wallet_ids] wallet_ids = [wallet_ids]
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( 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] tempRows = [MyExtension(**row) for row in rows]
logger.debug(req.url_for("temp.api_lnurl_pay", temp_id=row.id)) logger.debug(req.url_for("myextension.api_lnurl_pay", myextension_id=row.id))
for row in tempRows: for row in tempRows:
row.lnurlpay = req.url_for("temp.api_lnurl_pay", temp_id=row.id) row.lnurlpay = req.url_for("myextension.api_lnurl_pay", myextension_id=row.id)
row.lnurlwithdraw = req.url_for("temp.api_lnurl_withdraw", temp_id=row.id) row.lnurlwithdraw = req.url_for("myextension.api_lnurl_withdraw", myextension_id=row.id)
return tempRows 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()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( 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) myextension = await get_myextension(myextension_id)
assert temp, "Newly updated temp couldn't be retrieved" assert myextension, "Newly updated myextension couldn't be retrieved"
return temp return myextension
async def delete_temp(temp_id: str) -> None: async def delete_myextension(myextension_id: str) -> None:
await db.execute("DELETE FROM tempextension.temp WHERE id = ?", (temp_id,)) await db.execute("DELETE FROM myextension.maintable WHERE id = ?", (myextension_id,))

View file

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

View file

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

View file

@ -6,7 +6,7 @@ async def m001_initial(db):
""" """
await db.execute( await db.execute(
""" """
CREATE TABLE tempextension.temp ( CREATE TABLE myextension.maintable (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
wallet TEXT NOT NULL, wallet TEXT NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
@ -24,7 +24,7 @@ async def m002_addtip_wallet(db):
""" """
await db.execute( 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( 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( 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 lnbits.lnurl import encode as lnurl_encode
from urllib.parse import urlparse from urllib.parse import urlparse
class CreateTempData(BaseModel): class CreateMyExtensionData(BaseModel):
wallet: Optional[str] wallet: Optional[str]
name: Optional[str] name: Optional[str]
total: Optional[int] total: Optional[int]
lnurlpayamount: Optional[int] lnurlpayamount: Optional[int]
lnurlwithdrawamount: Optional[int] lnurlwithdrawamount: Optional[int]
class Temp(BaseModel): class MyExtension(BaseModel):
id: str id: str
wallet: str wallet: str
name: str name: str
@ -27,8 +27,5 @@ class Temp(BaseModel):
lnurlwithdraw: str lnurlwithdraw: str
@classmethod @classmethod
def from_row(cls, row: Row) -> "Temp": def from_row(cls, row: Row) -> "MyExtension":
return cls(**dict(row)) 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.helpers import get_current_extension_name
from lnbits.tasks import register_invoice_listener 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 # do somethhing when an invoice related top this extension is paid
async def on_invoice_paid(payment: Payment) -> None: async def on_invoice_paid(payment: Payment) -> None:
if payment.extra.get("tag") != "temp": if payment.extra.get("tag") != "myextension":
return return
temp_id = payment.extra.get("tempId") myextension_id = payment.extra.get("tempId")
assert temp_id assert myextension_id
temp = await get_temp(temp_id) myextension = await get_myextension(myextension_id)
assert temp assert myextension
# update something # update something
data_to_update = { 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 = { some_payment_data = {
"name": temp.name, "name": myextension.name,
"amount": payment.amount, "amount": payment.amount,
"fee": payment.fee, "fee": payment.fee,
"checking_id": payment.checking_id "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" label="API info"
:content-inset-level="0.5" :content-inset-level="0.5"
> >
<q-btn flat label="Swagger API" type="a" href="../docs#/temp"></q-btn> <q-btn flat label="Swagger API" type="a" href="../docs#/myextension"></q-btn>
<q-expansion-item group="api" dense expand-separator label="List Temp"> <q-expansion-item group="api" dense expand-separator label="List MyExtension">
<q-card> <q-card>
<q-card-section> <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> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br /> <code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5> <h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
@ -18,16 +18,16 @@
<code>[&lt;temp_object&gt;, ...]</code> <code>[&lt;temp_object&gt;, ...]</code>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <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;" &lt;invoice_key&gt;"
</code> </code>
</q-card-section> </q-card-section>
</q-card> </q-card>
</q-expansion-item> </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>
<q-card-section> <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> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br /> <code>{"X-Api-Key": &lt;invoice_key&gt;}</code><br />
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5> <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> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <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: &lt;string&gt;, "currency": &lt;string&gt;}' -H "Content-type:
application/json" -H "X-Api-Key: &lt;admin_key&gt;" application/json" -H "X-Api-Key: &lt;admin_key&gt;"
</code> </code>
@ -55,14 +55,14 @@
group="api" group="api"
dense dense
expand-separator expand-separator
label="Delete a Temp" label="Delete a MyExtension"
class="q-pb-md" class="q-pb-md"
> >
<q-card> <q-card>
<q-card-section> <q-card-section>
<code <code
><span class="text-pink">DELETE</span> ><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> <h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<code>{"X-Api-Key": &lt;admin_key&gt;}</code><br /> <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> <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code <code
>curl -X DELETE {{ request.base_url >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> </code>
</q-card-section> </q-card-section>
</q-card> </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>
<q-card-section> <q-card-section>
<p> <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> </p>
<small <small
>Created by >Created by

View file

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

View file

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

View file

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