diff --git a/README.md b/README.md
index 86d7656..c816895 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,4 @@
# Split Payments - [LNbits](https://github.com/lnbits/lnbits) extension
-
For more about LNBits extension check [this tutorial](https://github.com/lnbits/lnbits/wiki/LNbits-Documentation#use-cases-of-lnbits)
## Have payments split between multiple wallets
@@ -14,16 +13,16 @@ LNbits Split Payments extension allows for distributing payments across multiple
2. Add the wallet or wallets info to split payments to
- - get the LNURLp, a LNaddress, wallet id, or an invoice key from a different wallet. It can be a completely different user on another instance/domain. You can get the wallet information on the API Info section on every wallet page\
+ - get the LNURLp, a LNaddress, wallet id, or an invoice key from a different wallet. It can be a completely different user on another instance/domain. You can get the wallet information on the API Info section on every wallet page\
 - set a wallet _Alias_ for your own identification\
- set how much, in percentage, this wallet will receive from every payment sent to the source wallet
-3. When done with adding or deleting a set of targets, click "SAVE TARGETS" to make the splits effective.
+3. When done with adding or deleting a set of targets, click "SAVE TARGETS" to make the splits effective.
4. You can have several wallets to split to, as long as the sum of the percentages is under or equal to 100%. It can only reach 100% if the targets are all internal ones.
-5. When the source wallet receives a payment, the extension will automatically split the corresponding values to every wallet.
+5. When the source wallet receives a payment, the extension will automatically split the corresponding values to every wallet.
- on receiving a 20 sats payment\

- source wallet gets 18 sats\
@@ -34,12 +33,13 @@ LNbits Split Payments extension allows for distributing payments across multiple
IMPORTANT:
- If you split to a LNURLp or LNaddress through the LNURLp extension make sure your receipients allow comments ! Split&Scrub add a comment in your transaction - and if it is not allowed, the split/scrub will not take place.
-- Make sure the LNURLp / LNaddress of the receipient has its min-sats set very low (e.g. 1 sat). If the wallet does not belong to you you can [check with a Decoder](https://lightningdecoder.com/), if that is the case already
+- Make sure the LNURLp / LNaddress of the receipient has its min-sats set very low (e.g. 1 sat). If the wallet does not belong to you you can [check with a Decoder](https://lightningdecoder.com/), if that is the case already
- Yes, there is fees - internal and external! Updating your own wallets on your own instance will not cost any fees but sending to an external instance will. Please notice that you should therefore not split up to 100% if you send to a wallet that is external (leave 1-2% reserve for routing fees!). External fees are deducted from the individual payment percentage of the receipient
+
## Sponsored by
[](https://cryptograffiti.com/)
diff --git a/tasks.py b/tasks.py
index 13b1659..33fafb1 100644
--- a/tasks.py
+++ b/tasks.py
@@ -3,6 +3,10 @@
from math import floor
from typing import Optional
+import bech32
+import websockets
+import json
+
import httpx
from loguru import logger
@@ -16,7 +20,7 @@
from .crud import get_targets
-async def wait_for_paid_invoices():
+async def wait_for_paid_invoices():
invoice_queue = asyncio.Queue()
register_invoice_listener(invoice_queue, get_current_extension_name())
@@ -25,14 +29,13 @@ async def wait_for_paid_invoices():
await on_invoice_paid(payment)
-async def on_invoice_paid(payment: Payment) -> None:
-
+async def on_invoice_paid(payment: Payment) -> None:
if payment.extra.get("tag") == "splitpayments" or payment.extra.get("splitted"):
# already a splitted payment, ignore
return
-
+
targets = await get_targets(payment.wallet_id)
-
+
if not targets:
return
@@ -53,12 +56,24 @@ async def on_invoice_paid(payment: Payment) -> None:
f"Split payment: {target.percent}% for {target.alias or target.wallet}"
)
- if target.wallet.find("@") >= 0 or target.wallet.find("LNURL") >= 0:
+ npubWallet = ''
+ if target.wallet.find("npub") >= 0:
+ npubWallet = await get_npub_address(target.wallet)
+
+ # if npubWallet is not empty, use it as the target wallet
+ if npubWallet != '':
+ targetWallet = npubWallet
+ else:
+ targetWallet = target.wallet
+
+ print(targetWallet + " " + str(amount_msat) + " " + memo)
+
+ if targetWallet.find("@") >= 0 or targetWallet.find("LNURL") >= 0:
safe_amount_msat = amount_msat - fee_reserve(amount_msat)
payment_request = await get_lnurl_invoice(
- target.wallet, payment.wallet_id, safe_amount_msat, memo
+ targetWallet, payment.wallet_id, safe_amount_msat, memo
)
- else:
+ else:
_, payment_request = await create_invoice(
wallet_id=target.wallet,
amount=int(amount_msat / 1000),
@@ -76,6 +91,47 @@ async def on_invoice_paid(payment: Payment) -> None:
extra=extra,
)
+async def get_npub_address(
+ npub: str
+) -> Optional[str]:
+
+ hrp, data = bech32.bech32_decode(npub)
+ raw_secret = bech32.convertbits(data, 5, 8)
+ if raw_secret[-1] != 0x0:
+ pubkey = str(bytes(raw_secret).hex())
+ else:
+ pubkey = str(bytes(raw_secret[:-1]).hex())
+
+ print("trying to get npub: ", pubkey)
+ uri = "wss://nostr-pub.wellorder.net"
+ jsonOb = ''
+
+ # TODO utilize a try except and find out why websocket is not connecting
+ async with websockets.connect(uri) as websocket:
+ #websocket = websockets.connect(uri)
+ req = '["REQ", "a", {"kinds": [0], "limit": 10, "authors": ["'+ pubkey +'"]} ]'
+ ''' send req to websocket and print response'''
+ await websocket.send(req)
+ greeting = await websocket.recv()
+ output = json.loads(greeting)
+ jsonOb = json.loads(output[2]['content'])
+
+ #npubWallet06 = ''
+ #npubWallet16 = ''
+ npubWallet = ''
+ if "lud16" in jsonOb and npubWallet == '':
+ logger.info("we got a lud16: ", jsonOb["lud16"])
+ if len(jsonOb["lud16"]) > 1:
+ npubWallet = jsonOb["lud16"]
+ #if "lud06" in jsonOb:
+ # logger.info("we got a lud06: ", jsonOb["lud06"])
+ # if len(jsonOb["lud06"]) > 1:
+ # npubWallet = jsonOb["lud06"]
+
+ if npubWallet == '':
+ print("Failed to get npub wallet")
+
+ return npubWallet
async def get_lnurl_invoice(
payoraddress, wallet_id, amount_msat, memo
diff --git a/templates/splitpayments/index.html b/templates/splitpayments/index.html
index c4eb5ce..87f5af3 100644
--- a/templates/splitpayments/index.html
+++ b/templates/splitpayments/index.html
@@ -34,7 +34,7 @@
- Targets can be LNBits wallets from this LNBits instance or any valid - LNURL or LN Address. + Targets can be LNBits wallets from this LNBits instance or any valid LNURL or LN Address.
- LNURLp and LN Addresses must allow comments > 100 chars and also - have a flexible amount. + LNURLp and LN Addresses must allow comments > 100 chars and also have a flexible amount.
To remove a wallet from the targets list just press the X and save. diff --git a/views_api.py b/views_api.py index 48e5b31..90a2111 100644 --- a/views_api.py +++ b/views_api.py @@ -1,6 +1,7 @@ from http import HTTPStatus from typing import List + from fastapi import Depends from loguru import logger from starlette.exceptions import HTTPException @@ -12,29 +13,28 @@ from .crud import get_targets, set_targets from .models import Target, TargetPutList - @splitpayments_ext.get("/api/v1/targets") async def api_targets_get( wallet: WalletTypeInfo = Depends(require_admin_key), ) -> List[Target]: - targets = await get_targets(wallet.wallet.id) + targets = await get_targets(wallet.wallet.id) return targets or [] - @splitpayments_ext.put("/api/v1/targets", status_code=HTTPStatus.OK) async def api_targets_set( target_put: TargetPutList, source_wallet: WalletTypeInfo = Depends(require_admin_key), ) -> None: + try: targets: List[Target] = [] - for entry in target_put.targets: + for entry in target_put.targets: - if entry.wallet.find("@") < 0 and entry.wallet.find("LNURL") < 0: + if entry.wallet.find("@") < 0 and entry.wallet.find("LNURL") < 0 and entry.wallet.find("npub") < 0: wallet = await get_wallet(entry.wallet) if not wallet: wallet = await get_wallet_for_key(entry.wallet, "invoice") - if not wallet: + if not wallet: raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, detail=f"Invalid wallet '{entry.wallet}'.", @@ -43,20 +43,21 @@ async def api_targets_set( if wallet.id == source_wallet.wallet.id: raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, detail="Can't split to itself." - ) + ) if entry.percent <= 0: raise HTTPException( status_code=HTTPStatus.BAD_REQUEST, detail=f"Invalid percent '{entry.percent}'.", ) - + targets.append( Target( wallet=entry.wallet, source=source_wallet.wallet.id, percent=entry.percent, alias=entry.alias, + walletName=entry.wallet, ) )