Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update to lnbits 1.0.0 #10

Merged
merged 10 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"name": "Scrub",
"short_description": "Pass payments to LNURLp/LNaddress",
"tile": "/scrub/static/image/scrub.png",
"contributors": ["arcbtc", "talvasconcelos"],
"min_lnbits_version": "0.12.5"
"contributors": ["arcbtc", "talvasconcelos", "dni"],
"min_lnbits_version": "1.0.0"
}
77 changes: 27 additions & 50 deletions crud.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Optional, Union
from typing import Optional, Union

from lnbits.db import Database
from lnbits.helpers import urlsafe_short_hash
Expand All @@ -10,73 +10,50 @@

async def create_scrub_link(data: CreateScrubLink) -> ScrubLink:
scrub_id = urlsafe_short_hash()
await db.execute(
"""
INSERT INTO scrub.scrub_links (
id,
wallet,
description,
payoraddress
)
VALUES (?, ?, ?, ?)
""",
(
scrub_id,
data.wallet,
data.description,
data.payoraddress,
),
)
link = await get_scrub_link(scrub_id)
assert link, "Newly created link couldn't be retrieved"
return link
scrub = ScrubLink(id=scrub_id, **data.dict())
await db.insert("scrub.scrub_links", scrub)
return scrub


async def get_scrub_link(link_id: str) -> Optional[ScrubLink]:
row = await db.fetchone("SELECT * FROM scrub.scrub_links WHERE id = ?", (link_id,))
return ScrubLink(**row) if row else None
return await db.fetchone(
"SELECT * FROM scrub.scrub_links WHERE id = :id",
{"id": link_id},
ScrubLink,
)


async def get_scrub_links(wallet_ids: Union[str, List[str]]) -> List[ScrubLink]:
async def get_scrub_links(wallet_ids: Union[str, list[str]]) -> list[ScrubLink]:
if isinstance(wallet_ids, str):
wallet_ids = [wallet_ids]

q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall(
f"""
SELECT * FROM scrub.scrub_links WHERE wallet IN ({q})
ORDER BY id
""",
(*wallet_ids,),
q = ",".join([f"'{wallet_id}'" for wallet_id in wallet_ids])
return await db.fetchall(
f"SELECT * FROM scrub.scrub_links WHERE wallet IN ({q})", model=ScrubLink
)
return [ScrubLink(**row) for row in rows]


async def update_scrub_link(link_id: int, **kwargs) -> Optional[ScrubLink]:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute(
f"UPDATE scrub.scrub_links SET {q} WHERE id = ?",
(*kwargs.values(), link_id),
)
row = await db.fetchone("SELECT * FROM scrub.scrub_links WHERE id = ?", (link_id,))
return ScrubLink(**row) if row else None
async def update_scrub_link(link: ScrubLink) -> ScrubLink:
await db.update("scrub.scrub_links", link)
return link


async def delete_scrub_link(link_id: int) -> None:
await db.execute("DELETE FROM scrub.scrub_links WHERE id = ?", (link_id,))
async def delete_scrub_link(link_id: str) -> None:
await db.execute("DELETE FROM scrub.scrub_links WHERE id = :id", {"id": link_id})


async def get_scrub_by_wallet(wallet_id) -> Optional[ScrubLink]:
row = await db.fetchone(
"SELECT * from scrub.scrub_links WHERE wallet = ?",
(wallet_id,),
return await db.fetchone(
"SELECT * from scrub.scrub_links WHERE wallet = :wallet",
{"wallet": wallet_id},
ScrubLink,
)
return ScrubLink(**row) if row else None


async def unique_scrubed_wallet(wallet_id):
(row,) = await db.fetchone(
"SELECT COUNT(wallet) FROM scrub.scrub_links WHERE wallet = ?",
(wallet_id,),
result = await db.execute(
"SELECT COUNT(wallet) FROM scrub.scrub_links WHERE wallet = :wallet",
{"wallet": wallet_id},
)
return row
count = result.fetchone()[0]
return count
2,184 changes: 1,151 additions & 1,033 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = ["Alan Bits <alan@lnbits.com>"]

[tool.poetry.dependencies]
python = "^3.10 | ^3.9"
lnbits = "*"
lnbits = {version = "*", allow-prereleases = true}

[tool.poetry.group.dev.dependencies]
black = "^24.3.0"
Expand Down
16 changes: 6 additions & 10 deletions static/js/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
/* globals Quasar, Vue, _, VueQrcode, windowMixin, LNbits, LOCALE */

Vue.component(VueQrcode.name, VueQrcode)

var locationPath = [
const locationPath = [
window.location.protocol,
'//',
window.location.host,
window.location.pathname
].join('')

var mapScrubLink = obj => {
const mapScrubLink = obj => {
obj._data = _.clone(obj)
obj.date = Quasar.utils.date.formatDate(
obj.date = Quasar.date.formatDate(
new Date(obj.time * 1000),
'YYYY-MM-DD HH:mm'
)
Expand All @@ -21,7 +17,7 @@ var mapScrubLink = obj => {
return obj
}

new Vue({
window.app = Vue.createApp({
el: '#vue',
mixins: [windowMixin],
data() {
Expand Down Expand Up @@ -114,7 +110,7 @@ new Vue({
})
},
deleteScrubLink(linkId) {
var link = _.findWhere(this.payLinks, {id: linkId})
const link = _.findWhere(this.payLinks, {id: linkId})

LNbits.utils
.confirmDialog('Are you sure you want to delete this pay link?')
Expand All @@ -136,7 +132,7 @@ new Vue({
},
created() {
if (this.g.user.wallets.length) {
var getScrubLinks = this.getScrubLinks
const getScrubLinks = this.getScrubLinks
getScrubLinks()
}
}
Expand Down
16 changes: 3 additions & 13 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,25 @@
from lnbits.core.crud import get_standalone_payment
from lnbits.core.models import Payment
from lnbits.core.services import pay_invoice
from lnbits.helpers import get_current_extension_name
from lnbits.tasks import register_invoice_listener

from .crud import get_scrub_by_wallet


async def wait_for_paid_invoices():
invoice_queue = asyncio.Queue()
register_invoice_listener(invoice_queue, get_current_extension_name())
register_invoice_listener(invoice_queue, "ext_scrub")

while True:
payment = await invoice_queue.get()
await on_invoice_paid(payment)


async def on_invoice_paid(payment: Payment):
# (avoid loops)
if payment.extra.get("tag") == "scrubed":
# already scrubbed
if payment.extra and payment.extra.get("tag") == "scrubed":
return

scrub_link = await get_scrub_by_wallet(payment.wallet_id)

if not scrub_link:
return

Expand Down Expand Up @@ -84,15 +80,9 @@ async def on_invoice_paid(payment: Payment):
""",
)

payment_hash = await pay_invoice(
await pay_invoice(
wallet_id=payment.wallet_id,
payment_request=params["pr"],
description=data["description"],
extra={"tag": "scrubed"},
)

return {
"payment_hash": payment_hash,
# maintain backwards compatibility with API clients:
"checking_id": payment_hash,
}
14 changes: 7 additions & 7 deletions templates/scrub/_api_docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ <h5 class="text-caption q-mt-sm q-mb-none">
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X GET {{ request.base_url }}scrub/api/v1/links?all_wallets=true
-H "X-Api-Key: {{ user.wallets[0].inkey }}"
-H "X-Api-Key: <span v-text="g.user.wallets[0].inkey"></span>"
</code>
</q-card-section>
</q-card>
Expand All @@ -43,7 +43,7 @@ <h5 class="text-caption q-mt-sm q-mb-none">
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X GET {{ request.base_url }}scrub/api/v1/links/&lt;pay_id&gt;
-H "X-Api-Key: {{ user.wallets[0].inkey }}"
-H "X-Api-Key: <span v-text="g.user.wallets[0].inkey"></span>"
</code>
</q-card-section>
</q-card>
Expand All @@ -70,8 +70,8 @@ <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X POST {{ request.base_url }}scrub/api/v1/links -d '{"wallet":
&lt;string&gt;, "description": &lt;string&gt;, "payoraddress":
&lt;string&gt;}' -H "Content-type: application/json" -H "X-Api-Key: {{
user.wallets[0].adminkey }}"
&lt;string&gt;}' -H "Content-type: application/json" -H "X-Api-Key:
<span v-text="g.user.wallets[0].adminkey"></span>"
</code>
</q-card-section>
</q-card>
Expand Down Expand Up @@ -102,7 +102,7 @@ <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
>curl -X PUT {{ request.base_url }}scrub/api/v1/links/&lt;pay_id&gt;
-d '{"wallet": &lt;string&gt;, "description": &lt;string&gt;,
"payoraddress": &lt;string&gt;}' -H "Content-type: application/json"
-H "X-Api-Key: {{ user.wallets[0].adminkey }}"
-H "X-Api-Key: <span v-text="g.user.wallets[0].adminkey"></span>"
</code>
</q-card-section>
</q-card>
Expand All @@ -127,8 +127,8 @@ <h5 class="text-caption q-mt-sm q-mb-none">Returns 204 NO CONTENT</h5>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X DELETE {{ request.base_url
}}scrub/api/v1/links/&lt;pay_id&gt; -H "X-Api-Key: {{
user.wallets[0].adminkey }}"
}}scrub/api/v1/links/&lt;pay_id&gt; -H "X-Api-Key:
<span v-text="g.user.wallets[0].adminkey"></span>"
</code>
</q-card-section>
</q-card>
Expand Down
14 changes: 6 additions & 8 deletions templates/scrub/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ <h5 class="text-subtitle1 q-my-none">Scrub links</h5>
<q-table
dense
flat
:data="payLinks"
:rows="payLinks"
row-key="id"
:pagination.sync="payLinksTable.pagination"
v-model.pagination="payLinksTable.pagination"
>
{% raw %}
<template v-slot:header="props">
<q-tr :props="props" style="text-align: left">
<q-th>Wallet</q-th>
Expand All @@ -35,9 +34,9 @@ <h5 class="text-subtitle1 q-my-none">Scrub links</h5>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td>{{ props.row.wallet }}</q-td>
<q-td>{{ props.row.description }}</q-td>
<q-td>{{ props.row.payoraddress }}</q-td>
<q-td v-text="props.row.wallet"></q-td>
<q-td v-text="props.row.description"></q-td>
<q-td v-text="props.row.payoraddress"></q-td>
<q-td auto-width>
<q-btn
flat
Expand All @@ -58,7 +57,6 @@ <h5 class="text-subtitle1 q-my-none">Scrub links</h5>
</q-td>
</q-tr>
</template>
{% endraw %}
</q-table>
</q-card-section>
</q-card>
Expand Down Expand Up @@ -152,5 +150,5 @@ <h6 class="text-subtitle1 q-my-none">{{SITE_TITLE}} Scrub extension</h6>
</q-dialog>
</div>
{% endblock %} {% block scripts %} {{ window_vars(user) }}
<script src="/scrub/static/js/index.js"></script>
<script src="{{ static_url_for('scrub/static', path='js/index.js') }}"></script>
{% endblock %}
6 changes: 2 additions & 4 deletions views.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from fastapi import APIRouter, Depends, Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
from lnbits.core.models import User
from lnbits.decorators import check_user_exists
from lnbits.helpers import template_renderer
from starlette.responses import HTMLResponse

templates = Jinja2Templates(directory="templates")
scrub_generic_router = APIRouter()


Expand All @@ -16,5 +14,5 @@ def scrub_renderer():
@scrub_generic_router.get("/", response_class=HTMLResponse)
async def index(request: Request, user: User = Depends(check_user_exists)):
return scrub_renderer().TemplateResponse(
"scrub/index.html", {"request": request, "user": user.dict()}
"scrub/index.html", {"request": request, "user": user.json()}
)
Loading