diff --git a/tasks.py b/tasks.py index 13b1659..a3640b5 100644 --- a/tasks.py +++ b/tasks.py @@ -77,10 +77,57 @@ async def on_invoice_paid(payment: Payment) -> None: ) +async def execute_split(wallet_id, amount): + + targets = await get_targets(wallet_id) + + if not targets: + return + + total_percent = sum([target.percent for target in targets]) + + if total_percent > 100: + logger.error("splitpayment: total percent adds up to more than 100%") + return + + logger.trace(f"splitpayments: performing split payments to {len(targets)} targets") + + for target in targets: + + if target.percent > 0: + + amount_msat = int(amount * target.percent / 100) + memo = ( + f"Split payment: {target.percent}% for {target.alias or target.wallet}" + ) + + if target.wallet.find("@") >= 0 or target.wallet.find("LNURL") >= 0: + safe_amount_msat = amount_msat - fee_reserve(amount_msat) + payment_request = await get_lnurl_invoice( + target.wallet, wallet_id, safe_amount_msat, memo + ) + else: + _, payment_request = await create_invoice( + wallet_id=target.wallet, + amount=int(amount_msat / 1000), + internal=True, + memo=memo, + ) + + extra = {"tag": "splitpayments", "splitted": True} + + if payment_request: + await pay_invoice( + payment_request=payment_request, + wallet_id=wallet_id, + description=memo, + extra=extra, + ) + + async def get_lnurl_invoice( - payoraddress, wallet_id, amount_msat, memo + payoraddress, wallet_id, amount_msat, memo ) -> Optional[str]: - from lnbits.core.views.api import api_lnurlscan data = await api_lnurlscan(payoraddress) diff --git a/views_api.py b/views_api.py index 48e5b31..d79cadc 100644 --- a/views_api.py +++ b/views_api.py @@ -8,6 +8,7 @@ from lnbits.core.crud import get_wallet, get_wallet_for_key from lnbits.decorators import WalletTypeInfo, check_admin, require_admin_key +from .tasks import execute_split from . import scheduled_tasks, splitpayments_ext from .crud import get_targets, set_targets from .models import Target, TargetPutList @@ -21,6 +22,11 @@ async def api_targets_get( return targets or [] +@splitpayments_ext.post("/api/v1/execute_split", status_code=HTTPStatus.OK) +async def api_execute_split(wallet_id: str, amount: int) -> None: + result = await execute_split(wallet_id, amount) + return result + @splitpayments_ext.put("/api/v1/targets", status_code=HTTPStatus.OK) async def api_targets_set( target_put: TargetPutList,