diff --git a/lnbits/extensions/boltcards/crud.py b/lnbits/extensions/boltcards/crud.py index cc5d5193..9c7d299d 100644 --- a/lnbits/extensions/boltcards/crud.py +++ b/lnbits/extensions/boltcards/crud.py @@ -1,6 +1,6 @@ import secrets from datetime import datetime -from typing import List, Optional, Union +from typing import List, Optional from lnbits.helpers import urlsafe_short_hash @@ -66,9 +66,9 @@ async def update_card(card_id: str, **kwargs) -> Optional[Card]: return Card(**row) if row else None -async def get_cards(wallet_ids: Union[str, List[str]]) -> List[Card]: - if isinstance(wallet_ids, str): - wallet_ids = [wallet_ids] +async def get_cards(wallet_ids: List[str]) -> List[Card]: + if len(wallet_ids) == 0: + return [] q = ",".join(["?"] * len(wallet_ids)) rows = await db.fetchall( @@ -130,7 +130,7 @@ async def delete_card(card_id: str) -> None: for hit in hits: await db.execute("DELETE FROM boltcards.hits WHERE id = ?", (hit.id,)) # Delete refunds - refunds = await get_refunds([hit]) + refunds = await get_refunds([hit.id]) for refund in refunds: await db.execute( "DELETE FROM boltcards.refunds WHERE id = ?", (refund.hit_id,) @@ -169,7 +169,7 @@ async def get_hit(hit_id: str) -> Optional[Hit]: return Hit.parse_obj(hit) -async def get_hits(cards_ids: Union[str, List[str]]) -> List[Hit]: +async def get_hits(cards_ids: List[str]) -> List[Hit]: if len(cards_ids) == 0: return [] @@ -266,7 +266,7 @@ async def get_refund(refund_id: str) -> Optional[Refund]: return Refund.parse_obj(refund) -async def get_refunds(hits_ids: List[Hit]) -> List[Refund]: +async def get_refunds(hits_ids: List[str]) -> List[Refund]: if len(hits_ids) == 0: return [] diff --git a/lnbits/extensions/boltcards/views_api.py b/lnbits/extensions/boltcards/views_api.py index feca12e0..d2427834 100644 --- a/lnbits/extensions/boltcards/views_api.py +++ b/lnbits/extensions/boltcards/views_api.py @@ -158,5 +158,8 @@ async def api_refunds( for card in cards: cards_ids.append(card.id) hits = await get_hits(cards_ids) + hits_ids = [] + for hit in hits: + hits_ids.append(hit.id) - return [refund.dict() for refund in await get_refunds(hits)] + return [refund.dict() for refund in await get_refunds(hits_ids)] diff --git a/lnbits/extensions/example/__init__.py b/lnbits/extensions/example/__init__.py index 96cc6428..8cd9211b 100644 --- a/lnbits/extensions/example/__init__.py +++ b/lnbits/extensions/example/__init__.py @@ -1,16 +1,34 @@ +import asyncio + from fastapi import APIRouter +from fastapi.staticfiles import StaticFiles from lnbits.db import Database from lnbits.helpers import template_renderer +from lnbits.tasks import catch_everything_and_restart db = Database("ext_example") example_ext: APIRouter = APIRouter(prefix="/example", tags=["example"]) +example_static_files = [ + { + "path": "/example/static", + "app": StaticFiles(packages=[("lnbits", "extensions/example/static")]), + "name": "example_static", + } +] + def example_renderer(): return template_renderer(["lnbits/extensions/example/templates"]) -from .views import * # noqa -from .views_api import * # noqa +from .tasks import wait_for_paid_invoices +from .views import * +from .views_api import * + + +def tpos_start(): + loop = asyncio.get_event_loop() + loop.create_task(catch_everything_and_restart(wait_for_paid_invoices)) diff --git a/lnbits/extensions/example/config.json b/lnbits/extensions/example/config.json new file mode 100644 index 00000000..46e84ce4 --- /dev/null +++ b/lnbits/extensions/example/config.json @@ -0,0 +1,6 @@ +{ + "name": "Build your own!", + "short_description": "Extension building guide", + "tile": "/example/static/bitcoin-extension.png", + "contributors": ["github_username"] +} diff --git a/lnbits/extensions/example/crud.py b/lnbits/extensions/example/crud.py new file mode 100644 index 00000000..8e5508fb --- /dev/null +++ b/lnbits/extensions/example/crud.py @@ -0,0 +1,5 @@ +# crud.py is for communication with your extensions database + +# add your dependencies here + +# add your fnctions here diff --git a/lnbits/extensions/example/example.config.json b/lnbits/extensions/example/example.config.json deleted file mode 100644 index 14848443..00000000 --- a/lnbits/extensions/example/example.config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Build your own!!", - "short_description": "Join us, make an extension", - "tile": "/cashu/static/image/tile.png", - "contributors": ["github_username"] -} diff --git a/lnbits/extensions/example/migrations.py b/lnbits/extensions/example/migrations.py index 99d7c362..9d37d977 100644 --- a/lnbits/extensions/example/migrations.py +++ b/lnbits/extensions/example/migrations.py @@ -1,3 +1,5 @@ +# migrations.py is for building your database + # async def m001_initial(db): # await db.execute( # f""" diff --git a/lnbits/extensions/example/static/bitcoin-extension.png b/lnbits/extensions/example/static/bitcoin-extension.png new file mode 100644 index 00000000..8366c0c2 Binary files /dev/null and b/lnbits/extensions/example/static/bitcoin-extension.png differ diff --git a/lnbits/extensions/example/static/conversion-example.png b/lnbits/extensions/example/static/conversion-example.png new file mode 100644 index 00000000..544e6335 Binary files /dev/null and b/lnbits/extensions/example/static/conversion-example.png differ diff --git a/lnbits/extensions/example/static/conversion-example2.png b/lnbits/extensions/example/static/conversion-example2.png new file mode 100644 index 00000000..7543fdc9 Binary files /dev/null and b/lnbits/extensions/example/static/conversion-example2.png differ diff --git a/lnbits/extensions/example/static/fastapi-example.png b/lnbits/extensions/example/static/fastapi-example.png new file mode 100644 index 00000000..ed309bbe Binary files /dev/null and b/lnbits/extensions/example/static/fastapi-example.png differ diff --git a/lnbits/extensions/example/static/fastapi-example2.png b/lnbits/extensions/example/static/fastapi-example2.png new file mode 100644 index 00000000..ceacf494 Binary files /dev/null and b/lnbits/extensions/example/static/fastapi-example2.png differ diff --git a/lnbits/extensions/example/static/fastapi-framework.png b/lnbits/extensions/example/static/fastapi-framework.png new file mode 100644 index 00000000..b446ce25 Binary files /dev/null and b/lnbits/extensions/example/static/fastapi-framework.png differ diff --git a/lnbits/extensions/example/static/fastapilogo.png b/lnbits/extensions/example/static/fastapilogo.png new file mode 100644 index 00000000..57eb6a80 Binary files /dev/null and b/lnbits/extensions/example/static/fastapilogo.png differ diff --git a/lnbits/extensions/example/static/quasar-example.png b/lnbits/extensions/example/static/quasar-example.png new file mode 100644 index 00000000..64da65ab Binary files /dev/null and b/lnbits/extensions/example/static/quasar-example.png differ diff --git a/lnbits/extensions/example/static/quasar-framework.png b/lnbits/extensions/example/static/quasar-framework.png new file mode 100644 index 00000000..c06e8cfa Binary files /dev/null and b/lnbits/extensions/example/static/quasar-framework.png differ diff --git a/lnbits/extensions/example/static/quasarlogo.png b/lnbits/extensions/example/static/quasarlogo.png new file mode 100644 index 00000000..69228f86 Binary files /dev/null and b/lnbits/extensions/example/static/quasarlogo.png differ diff --git a/lnbits/extensions/example/static/script-example.png b/lnbits/extensions/example/static/script-example.png new file mode 100644 index 00000000..813a4254 Binary files /dev/null and b/lnbits/extensions/example/static/script-example.png differ diff --git a/lnbits/extensions/example/static/vif-example.png b/lnbits/extensions/example/static/vif-example.png new file mode 100644 index 00000000..3e6cfa11 Binary files /dev/null and b/lnbits/extensions/example/static/vif-example.png differ diff --git a/lnbits/extensions/example/static/vuejs-framework.png b/lnbits/extensions/example/static/vuejs-framework.png new file mode 100644 index 00000000..eb634533 Binary files /dev/null and b/lnbits/extensions/example/static/vuejs-framework.png differ diff --git a/lnbits/extensions/example/static/vuejslogo.png b/lnbits/extensions/example/static/vuejslogo.png new file mode 100644 index 00000000..065c4a89 Binary files /dev/null and b/lnbits/extensions/example/static/vuejslogo.png differ diff --git a/lnbits/extensions/example/tasks.py b/lnbits/extensions/example/tasks.py new file mode 100644 index 00000000..92319421 --- /dev/null +++ b/lnbits/extensions/example/tasks.py @@ -0,0 +1,29 @@ +# tasks.py is for asynchronous when invoices get paid + +# add your dependencies here + +import asyncio + +from loguru import logger + +from lnbits.core.models import Payment +from lnbits.helpers import get_current_extension_name +from lnbits.tasks import register_invoice_listener + + +async def wait_for_paid_invoices(): + invoice_queue = asyncio.Queue() + register_invoice_listener(invoice_queue, get_current_extension_name()) + + while True: + payment = await invoice_queue.get() + await on_invoice_paid(payment) + + +async def on_invoice_paid(payment: Payment) -> None: + if ( + payment.extra.get("tag") != "example" + ): # Will grab any payment with the tag "example" + logger.debug(payment) + # Do something + return diff --git a/lnbits/extensions/example/templates/example/index.html b/lnbits/extensions/example/templates/example/index.html index d732ef37..03f66b5f 100644 --- a/lnbits/extensions/example/templates/example/index.html +++ b/lnbits/extensions/example/templates/example/index.html @@ -1,58 +1,338 @@ {% extends "base.html" %} {% from "macros.jinja" import window_vars with context %} {% block page %} - + + + + + + + +
+ Update thing + Create thing + Cancel +
+
+
+
+ + -
- Frameworks used by {{SITE_TITLE}} -
- - + {{SITE_TITLE}} Extension Development Guide + (Collection of resources for extension developers) + + + + - {% raw %} - - - {{ tool.name }} - {{ tool.language }} - - {% endraw %} - - - -

- A magical "g" is always available, with info about the user, wallets and - extensions: -

- {% raw %}{{ g }}{% endraw %} + + + + + + + + + + + +
Frameworks
+ +
+ + + +
+
+ + +
Useful Tools
+
+ + + +
+
+ + +
Good Practice
+ Coming soon... +
+ + +
Dev Enviroment
+ Coming soon... +
+ + +
Submission
+ Coming soon... +
+
+
{% endblock %} {% block scripts %} {{ window_vars(user) }} + diff --git a/lnbits/extensions/example/views_api.py b/lnbits/extensions/example/views_api.py index 5b702717..556096ce 100644 --- a/lnbits/extensions/example/views_api.py +++ b/lnbits/extensions/example/views_api.py @@ -2,34 +2,12 @@ # add your dependencies here -# import httpx -# (use httpx just like requests, except instead of response.ok there's only the -# response.is_error that is its inverse) - from . import example_ext # add your endpoints here -@example_ext.get("/api/v1/tools") -async def api_example(): - """Try to add descriptions for others.""" - tools = [ - { - "name": "fastAPI", - "url": "https://fastapi.tiangolo.com/", - "language": "Python", - }, - { - "name": "Vue.js", - "url": "https://vuejs.org/", - "language": "JavaScript", - }, - { - "name": "Quasar Framework", - "url": "https://quasar.dev/", - "language": "JavaScript", - }, - ] - - return tools +@example_ext.get("/api/v1/test/{test_data}") +async def api_example(test_data): + # Do some python things and return the data + return test_data diff --git a/lnbits/extensions/livestream/lnurl.py b/lnbits/extensions/livestream/lnurl.py index 89e431e5..63523f33 100644 --- a/lnbits/extensions/livestream/lnurl.py +++ b/lnbits/extensions/livestream/lnurl.py @@ -86,12 +86,19 @@ async def lnurl_callback( ls = await get_livestream_by_track(track_id) + extra_amount = amount_received - int(amount_received * (100 - ls.fee_pct) / 100) + payment_hash, payment_request = await create_invoice( wallet_id=ls.wallet, amount=int(amount_received / 1000), memo=await track.fullname(), unhashed_description=(await track.lnurlpay_metadata()).encode(), - extra={"tag": "livestream", "track": track.id, "comment": comment}, + extra={ + "tag": "livestream", + "track": track.id, + "comment": comment, + "amount": int(extra_amount / 1000), + }, ) if amount_received < track.price_msat: diff --git a/lnbits/extensions/livestream/tasks.py b/lnbits/extensions/livestream/tasks.py index d081332f..9837654e 100644 --- a/lnbits/extensions/livestream/tasks.py +++ b/lnbits/extensions/livestream/tasks.py @@ -22,6 +22,7 @@ async def wait_for_paid_invoices(): async def on_invoice_paid(payment: Payment) -> None: + if payment.extra.get("tag") != "livestream": # not a livestream invoice return @@ -41,21 +42,26 @@ async def on_invoice_paid(payment: Payment) -> None: ls = await get_livestream_by_track(track.id) assert ls, f"track {track.id} is not associated with a livestream" - # now we make a special kind of internal transfer amount = int(payment.amount * (100 - ls.fee_pct) / 100) payment_hash, payment_request = await create_invoice( - wallet_id=tpos.tip_wallet, - amount=amount, # sats + wallet_id=producer.wallet, + amount=int(amount / 1000), internal=True, memo=f"Revenue from '{track.name}'.", ) - logger.debug(f"livestream: producer invoice created: {payment_hash}") + logger.debug( + f"livestream: producer invoice created: {payment_hash}, {amount} msats" + ) checking_id = await pay_invoice( payment_request=payment_request, wallet_id=payment.wallet_id, - extra={"tag": "livestream"}, + extra={ + **payment.extra, + "shared_with": f"Producer ID: {producer.id}", + "received": payment.amount, + }, ) logger.debug(f"livestream: producer invoice paid: {checking_id}") diff --git a/lnbits/extensions/lnurlp/crud.py b/lnbits/extensions/lnurlp/crud.py index d02ae80e..d5963b95 100644 --- a/lnbits/extensions/lnurlp/crud.py +++ b/lnbits/extensions/lnurlp/crud.py @@ -1,19 +1,18 @@ from typing import List, Optional, Union -from lnbits.db import SQLITE +from lnbits.helpers import urlsafe_short_hash from . import db from .models import CreatePayLinkData, PayLink async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink: + link_id = urlsafe_short_hash()[:6] - returning = "" if db.type == SQLITE else "RETURNING ID" - method = db.execute if db.type == SQLITE else db.fetchone - - result = await (method)( + result = await db.execute( f""" INSERT INTO lnurlp.pay_links ( + id, wallet, description, min, @@ -29,10 +28,10 @@ async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink: currency, fiat_base_multiplier ) - VALUES (?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?, ?, ?) - {returning} + VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?, ?, ?) """, ( + link_id, wallet_id, data.description, data.min, @@ -47,17 +46,13 @@ async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink: data.fiat_base_multiplier, ), ) - if db.type == SQLITE: - link_id = result._result_proxy.lastrowid - else: - link_id = result[0] link = await get_pay_link(link_id) assert link, "Newly created link couldn't be retrieved" return link -async def get_pay_link(link_id: int) -> Optional[PayLink]: +async def get_pay_link(link_id: str) -> Optional[PayLink]: row = await db.fetchone("SELECT * FROM lnurlp.pay_links WHERE id = ?", (link_id,)) return PayLink.from_row(row) if row else None diff --git a/lnbits/extensions/lnurlp/lnurl.py b/lnbits/extensions/lnurlp/lnurl.py index 3f7df926..8f6aa623 100644 --- a/lnbits/extensions/lnurlp/lnurl.py +++ b/lnbits/extensions/lnurlp/lnurl.py @@ -18,7 +18,12 @@ from .crud import increment_pay_link @lnurlp_ext.get( - "/api/v1/lnurl/{link_id}", + "/api/v1/lnurl/{link_id}", # Backwards compatibility for old LNURLs / QR codes (with long URL) + status_code=HTTPStatus.OK, + name="lnurlp.api_lnurl_response.deprecated", +) +@lnurlp_ext.get( + "/{link_id}", status_code=HTTPStatus.OK, name="lnurlp.api_lnurl_response", ) diff --git a/lnbits/extensions/lnurlp/migrations.py b/lnbits/extensions/lnurlp/migrations.py index c4edd3aa..1ec85eb0 100644 --- a/lnbits/extensions/lnurlp/migrations.py +++ b/lnbits/extensions/lnurlp/migrations.py @@ -68,3 +68,81 @@ async def m005_webhook_headers_and_body(db): """ await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN webhook_headers TEXT;") await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN webhook_body TEXT;") + + +async def m006_redux(db): + """ + Migrate ID column type to string for UUIDs and migrate existing data + """ + # we can simply change the column type for postgres + if db.type != "SQLITE": + await db.execute("ALTER TABLE lnurlp.pay_links ALTER COLUMN id TYPE TEXT;") + else: + # but we have to do this for sqlite + await db.execute("ALTER TABLE lnurlp.pay_links RENAME TO pay_links_old") + await db.execute( + f""" + CREATE TABLE lnurlp.pay_links ( + id TEXT PRIMARY KEY, + wallet TEXT NOT NULL, + description TEXT NOT NULL, + min {db.big_int} NOT NULL, + max {db.big_int}, + currency TEXT, + fiat_base_multiplier INTEGER DEFAULT 1, + served_meta INTEGER NOT NULL, + served_pr INTEGER NOT NULL, + webhook_url TEXT, + success_text TEXT, + success_url TEXT, + comment_chars INTEGER DEFAULT 0, + webhook_headers TEXT, + webhook_body TEXT + ); + """ + ) + + for row in [ + list(row) for row in await db.fetchall("SELECT * FROM lnurlp.pay_links_old") + ]: + await db.execute( + """ + INSERT INTO lnurlp.pay_links ( + id, + wallet, + description, + min, + served_meta, + served_pr, + webhook_url, + success_text, + success_url, + currency, + comment_chars, + max, + fiat_base_multiplier, + webhook_headers, + webhook_body + ) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + """, + ( + row[0], + row[1], + row[2], + row[3], + row[4], + row[5], + row[6], + row[7], + row[8], + row[9], + row[10], + row[11], + row[12], + row[13], + row[14], + ), + ) + + await db.execute("DROP TABLE lnurlp.pay_links_old") diff --git a/lnbits/extensions/lnurlp/models.py b/lnbits/extensions/lnurlp/models.py index 2cb4d0ab..42ea2926 100644 --- a/lnbits/extensions/lnurlp/models.py +++ b/lnbits/extensions/lnurlp/models.py @@ -26,7 +26,7 @@ class CreatePayLinkData(BaseModel): class PayLink(BaseModel): - id: int + id: str wallet: str description: str min: float diff --git a/lnbits/extensions/lnurlp/static/js/index.js b/lnbits/extensions/lnurlp/static/js/index.js index 1713e77f..c1372bec 100644 --- a/lnbits/extensions/lnurlp/static/js/index.js +++ b/lnbits/extensions/lnurlp/static/js/index.js @@ -17,7 +17,7 @@ var mapPayLink = obj => { ) obj.amount = new Intl.NumberFormat(LOCALE).format(obj.amount) obj.print_url = [locationPath, 'print/', obj.id].join('') - obj.pay_url = [locationPath, obj.id].join('') + obj.pay_url = [locationPath, 'link/', obj.id].join('') return obj } diff --git a/lnbits/extensions/lnurlp/views.py b/lnbits/extensions/lnurlp/views.py index 9bc78056..c5fa3582 100644 --- a/lnbits/extensions/lnurlp/views.py +++ b/lnbits/extensions/lnurlp/views.py @@ -21,7 +21,7 @@ async def index(request: Request, user: User = Depends(check_user_exists)): ) -@lnurlp_ext.get("/{link_id}", response_class=HTMLResponse) +@lnurlp_ext.get("/link/{link_id}", response_class=HTMLResponse) async def display(request: Request, link_id): link = await get_pay_link(link_id) if not link: diff --git a/lnbits/extensions/splitpayments/tasks.py b/lnbits/extensions/splitpayments/tasks.py index 33768805..59aa8e05 100644 --- a/lnbits/extensions/splitpayments/tasks.py +++ b/lnbits/extensions/splitpayments/tasks.py @@ -20,60 +20,57 @@ async def wait_for_paid_invoices(): async def on_invoice_paid(payment: Payment) -> None: - if payment.extra.get("tag") == "splitpayments": + + if payment.extra.get("tag") == "splitpayments" or payment.extra.get("splitted"): # already a splitted payment, ignore return targets = await get_targets(payment.wallet_id) - logger.debug(targets) + if not targets: return + # validate target percentages total_percent = sum([target.percent for target in targets]) if total_percent > 100: - logger.error("splitpayment failure: total percent adds up to more than 100%") + logger.error("splitpayment: total percent adds up to more than 100%") + return + + logger.trace(f"splitpayments: performing split payments to {len(targets)} targets") + + if payment.extra.get("amount"): + amount_to_split = (payment.extra.get("amount") or 0) * 1000 + else: + amount_to_split = payment.amount + + if not amount_to_split: + logger.error("splitpayments: no amount to split") return - logger.debug(f"checking if tagged for {len(targets)} targets") - tagged = False for target in targets: - if target.tag in payment.extra: - tagged = True + tagged = target.tag in payment.extra + + if tagged or target.percent > 0: + + if tagged: + memo = f"Pushed tagged payment to {target.alias}" + amount_msat = int(amount_to_split) + else: + amount_msat = int(amount_to_split * target.percent / 100) + memo = f"Split payment: {target.percent}% for {target.alias or target.wallet}" + payment_hash, payment_request = await create_invoice( wallet_id=target.wallet, - amount=int(payment.amount / 1000), # sats + amount=int(amount_msat / 1000), internal=True, - memo=f"Pushed tagged payment to {target.alias}", - extra={"tag": "splitpayments"}, + memo=memo, ) - logger.debug(f"created split invoice: {payment_hash}") - checking_id = await pay_invoice( + extra = {**payment.extra, "tag": "splitpayments", "splitted": True} + + await pay_invoice( payment_request=payment_request, wallet_id=payment.wallet_id, - extra={"tag": "splitpayments"}, + extra=extra, ) - logger.debug(f"paid split invoice: {checking_id}") - - logger.debug(f"performing split to {len(targets)} targets") - - if tagged == False: - for target in targets: - if target.percent > 0: - amount = int(payment.amount * target.percent / 100) # msats - payment_hash, payment_request = await create_invoice( - wallet_id=target.wallet, - amount=int(amount / 1000), # sats - internal=True, - memo=f"split payment: {target.percent}% for {target.alias or target.wallet}", - extra={"tag": "splitpayments"}, - ) - logger.debug(f"created split invoice: {payment_hash}") - - checking_id = await pay_invoice( - payment_request=payment_request, - wallet_id=payment.wallet_id, - extra={"tag": "splitpayments"}, - ) - logger.debug(f"paid split invoice: {checking_id}") diff --git a/lnbits/extensions/tpos/tasks.py b/lnbits/extensions/tpos/tasks.py index 9a405540..80ee1085 100644 --- a/lnbits/extensions/tpos/tasks.py +++ b/lnbits/extensions/tpos/tasks.py @@ -20,6 +20,9 @@ async def wait_for_paid_invoices(): async def on_invoice_paid(payment: Payment) -> None: + if not payment.extra: + return + if payment.extra.get("tag") != "tpos": return @@ -50,7 +53,7 @@ async def on_invoice_paid(payment: Payment) -> None: payment_hash, payment_request = await create_invoice( wallet_id=wallet_id, - amount=int(tipAmount), # sats + amount=int(tipAmount), internal=True, memo=f"tpos tip", ) @@ -59,6 +62,6 @@ async def on_invoice_paid(payment: Payment) -> None: checking_id = await pay_invoice( payment_request=payment_request, wallet_id=payment.wallet_id, - extra={"tag": "tpos"}, + extra={**payment.extra, "tipSplitted": True}, ) logger.debug(f"tpos: tip invoice paid: {checking_id}") diff --git a/lnbits/extensions/tpos/views_api.py b/lnbits/extensions/tpos/views_api.py index 05537f84..ada54b3f 100644 --- a/lnbits/extensions/tpos/views_api.py +++ b/lnbits/extensions/tpos/views_api.py @@ -76,7 +76,12 @@ async def api_tpos_create_invoice( wallet_id=tpos.wallet, amount=amount, memo=f"{tpos.name}", - extra={"tag": "tpos", "tipAmount": tipAmount, "tposId": tpos_id}, + extra={ + "tag": "tpos", + "tipAmount": tipAmount, + "tposId": tpos_id, + "amount": amount - tipAmount if tipAmount else False, + }, ) except Exception as e: raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)) diff --git a/lnbits/extensions/withdraw/crud.py b/lnbits/extensions/withdraw/crud.py index 68603f0a..83dd0593 100644 --- a/lnbits/extensions/withdraw/crud.py +++ b/lnbits/extensions/withdraw/crud.py @@ -12,7 +12,7 @@ from .models import CreateWithdrawData, HashCheck, WithdrawLink async def create_withdraw_link( data: CreateWithdrawData, wallet_id: str ) -> WithdrawLink: - link_id = urlsafe_short_hash() + link_id = urlsafe_short_hash()[:6] available_links = ",".join([str(i) for i in range(data.uses)]) await db.execute( """ diff --git a/lnbits/wallets/spark.py b/lnbits/wallets/spark.py index 98227175..5f5a00fe 100644 --- a/lnbits/wallets/spark.py +++ b/lnbits/wallets/spark.py @@ -200,8 +200,9 @@ class SparkWallet(Wallet): if r["pays"][0]["payment_hash"] == checking_id: status = r["pays"][0]["status"] if status == "complete": - fee_msat = -int( - r["pays"][0]["amount_sent_msat"] - r["pays"][0]["amount_msat"] + fee_msat = -( + int(r["pays"][0]["amount_sent_msat"][0:-4]) + - int(r["pays"][0]["amount_msat"][0:-4]) ) return PaymentStatus(True, fee_msat, r["pays"][0]["preimage"]) elif status == "failed":