Browse Source

fix: description_hash as an optional param to create_invoice.

fixes https://github.com/lnbits/lnbits/issues/74
aiosqlite
fiatjaf 4 years ago
parent
commit
68b0adfe66
  1. 2
      Makefile
  2. 2
      lnbits/core/services.py
  3. 4
      lnbits/wallets/base.py
  4. 6
      lnbits/wallets/clightning.py
  5. 17
      lnbits/wallets/lnbits.py
  6. 21
      lnbits/wallets/lndgrpc.py
  7. 27
      lnbits/wallets/lndrest.py
  8. 17
      lnbits/wallets/lnpay.py
  9. 17
      lnbits/wallets/lntxbot.py
  10. 5
      lnbits/wallets/opennode.py
  11. 9
      lnbits/wallets/spark.py

2
Makefile

@ -6,5 +6,5 @@ prettier: $(shell find lnbits -name "*.js" -name ".html")
mypy: $(shell find lnbits -name "*.py") mypy: $(shell find lnbits -name "*.py")
mypy lnbits mypy lnbits
mypy: $(shell find lnbits -name "*.py") black: $(shell find lnbits -name "*.py")
black lnbits black lnbits

2
lnbits/core/services.py

@ -7,7 +7,7 @@ from lnbits.settings import WALLET
from .crud import get_wallet, create_payment, delete_payment from .crud import get_wallet, create_payment, delete_payment
def create_invoice(*, wallet_id: str, amount: int, memo: str, description_hash: bytes) -> Tuple[str, str]: def create_invoice(*, wallet_id: str, amount: int, memo: str, description_hash: bytes = None) -> Tuple[str, str]:
try: try:
ok, checking_id, payment_request, error_message = WALLET.create_invoice( ok, checking_id, payment_request, error_message = WALLET.create_invoice(

4
lnbits/wallets/base.py

@ -26,7 +26,9 @@ class PaymentStatus(NamedTuple):
class Wallet(ABC): class Wallet(ABC):
@abstractmethod @abstractmethod
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse: def create_invoice(
self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
) -> InvoiceResponse:
pass pass
@abstractmethod @abstractmethod

6
lnbits/wallets/clightning.py

@ -6,7 +6,7 @@ except ImportError: # pragma: nocover
import random import random
from os import getenv from os import getenv
from typing import Optional
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet, Unsupported from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet, Unsupported
@ -17,7 +17,9 @@ class CLightningWallet(Wallet):
self.l1 = LightningRpc(getenv("CLIGHTNING_RPC")) self.l1 = LightningRpc(getenv("CLIGHTNING_RPC"))
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse: def create_invoice(
self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
) -> InvoiceResponse:
if description_hash: if description_hash:
raise Unsupported("description_hash") raise Unsupported("description_hash")

17
lnbits/wallets/lnbits.py

@ -1,4 +1,5 @@
from os import getenv from os import getenv
from typing import Optional, Dict
from requests import get, post from requests import get, post
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet
@ -12,12 +13,16 @@ class LNbitsWallet(Wallet):
self.auth_admin = {"X-Api-Key": getenv("LNBITS_ADMIN_KEY")} self.auth_admin = {"X-Api-Key": getenv("LNBITS_ADMIN_KEY")}
self.auth_invoice = {"X-Api-Key": getenv("LNBITS_INVOICE_KEY")} self.auth_invoice = {"X-Api-Key": getenv("LNBITS_INVOICE_KEY")}
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse: def create_invoice(
r = post( self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
url=f"{self.endpoint}/api/v1/payments", ) -> InvoiceResponse:
headers=self.auth_invoice, data: Dict = {"out": False, "amount": amount}
json={"out": False, "amount": amount, "memo": memo, "description_hash": description_hash.hex(),}, if description_hash:
) data["description_hash"] = description_hash.hex()
else:
data["memo"] = memo or ""
r = post(url=f"{self.endpoint}/api/v1/payments", headers=self.auth_invoice, json=data,)
ok, checking_id, payment_request, error_message = r.ok, None, None, None ok, checking_id, payment_request, error_message = r.ok, None, None, None
if r.ok: if r.ok:

21
lnbits/wallets/lndgrpc.py

@ -4,8 +4,8 @@ except ImportError: # pragma: nocover
lnd_grpc = None lnd_grpc = None
import base64 import base64
from os import getenv from os import getenv
from typing import Optional, Dict
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet
@ -23,7 +23,9 @@ class LndWallet(Wallet):
self.auth_read = getenv("LND_READ_MACAROON") self.auth_read = getenv("LND_READ_MACAROON")
self.auth_cert = getenv("LND_CERT") self.auth_cert = getenv("LND_CERT")
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse: def create_invoice(
self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
) -> InvoiceResponse:
lnd_rpc = lnd_grpc.Client( lnd_rpc = lnd_grpc.Client(
lnd_dir=None, lnd_dir=None,
macaroon_path=self.auth_invoice, macaroon_path=self.auth_invoice,
@ -33,20 +35,17 @@ class LndWallet(Wallet):
grpc_port=self.port, grpc_port=self.port,
) )
lndResponse = lnd_rpc.add_invoice( params: Dict = {"value": amount, "expiry": 600, "private": True}
memo=memo, if description_hash:
description_hash=base64.b64encode(description_hash).decode("ascii"), params["description_hash"] = description_hash # as bytes directly
value=amount, else:
expiry=600, params["memo"] = memo or ""
private=True, lndResponse = lnd_rpc.add_invoice(**params)
)
decoded_hash = base64.b64encode(lndResponse.r_hash).decode("utf-8").replace("/", "_") decoded_hash = base64.b64encode(lndResponse.r_hash).decode("utf-8").replace("/", "_")
print(lndResponse.r_hash)
ok, checking_id, payment_request, error_message = True, decoded_hash, str(lndResponse.payment_request), None ok, checking_id, payment_request, error_message = True, decoded_hash, str(lndResponse.payment_request), None
return InvoiceResponse(ok, checking_id, payment_request, error_message) return InvoiceResponse(ok, checking_id, payment_request, error_message)
def pay_invoice(self, bolt11: str) -> PaymentResponse: def pay_invoice(self, bolt11: str) -> PaymentResponse:
lnd_rpc = lnd_grpc.Client( lnd_rpc = lnd_grpc.Client(
lnd_dir=None, lnd_dir=None,
macaroon_path=self.auth_admin, macaroon_path=self.auth_admin,

27
lnbits/wallets/lndrest.py

@ -1,4 +1,5 @@
from os import getenv from os import getenv
from typing import Optional, Dict
import base64 import base64
from requests import get, post from requests import get, post
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet
@ -17,19 +18,19 @@ class LndRestWallet(Wallet):
self.auth_read = {"Grpc-Metadata-macaroon": getenv("LND_REST_READ_MACAROON")} self.auth_read = {"Grpc-Metadata-macaroon": getenv("LND_REST_READ_MACAROON")}
self.auth_cert = getenv("LND_REST_CERT") self.auth_cert = getenv("LND_REST_CERT")
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse: def create_invoice(
r = post( self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
url=f"{self.endpoint}/v1/invoices", ) -> InvoiceResponse:
headers=self.auth_invoice, data: Dict = {
verify=self.auth_cert, "value": amount,
json={ "private": True,
"value": amount, }
"memo": memo, if description_hash:
"description_hash": base64.b64encode(description_hash).decode("ascii"), data["description_hash"] = base64.b64encode(description_hash).decode("ascii")
"private": True, else:
}, data["memo"] = memo or ""
)
print(self.auth_invoice) r = post(url=f"{self.endpoint}/v1/invoices", headers=self.auth_invoice, verify=self.auth_cert, json=data,)
ok, checking_id, payment_request, error_message = r.ok, None, None, None ok, checking_id, payment_request, error_message = r.ok, None, None, None

17
lnbits/wallets/lnpay.py

@ -1,4 +1,5 @@
from os import getenv from os import getenv
from typing import Optional, Dict
from requests import get, post from requests import get, post
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet
@ -15,12 +16,16 @@ class LNPayWallet(Wallet):
self.auth_read = getenv("LNPAY_READ_KEY") self.auth_read = getenv("LNPAY_READ_KEY")
self.auth_api = {"X-Api-Key": getenv("LNPAY_API_KEY")} self.auth_api = {"X-Api-Key": getenv("LNPAY_API_KEY")}
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse: def create_invoice(
r = post( self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
url=f"{self.endpoint}/user/wallet/{self.auth_invoice}/invoice", ) -> InvoiceResponse:
headers=self.auth_api, data: Dict = {"num_satoshis": f"{amount}"}
json={"num_satoshis": f"{amount}", "memo": memo, "description_hash": description_hash.hex(),}, if description_hash:
) data["description_hash"] = description_hash.hex()
else:
data["memo"] = memo or ""
r = post(url=f"{self.endpoint}/user/wallet/{self.auth_invoice}/invoice", headers=self.auth_api, json=data,)
ok, checking_id, payment_request, error_message = r.status_code == 201, None, None, r.text ok, checking_id, payment_request, error_message = r.status_code == 201, None, None, r.text
if ok: if ok:

17
lnbits/wallets/lntxbot.py

@ -1,4 +1,5 @@
from os import getenv from os import getenv
from typing import Optional, Dict
from requests import post from requests import post
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet
@ -13,12 +14,16 @@ class LntxbotWallet(Wallet):
self.auth_admin = {"Authorization": f"Basic {getenv('LNTXBOT_ADMIN_KEY')}"} self.auth_admin = {"Authorization": f"Basic {getenv('LNTXBOT_ADMIN_KEY')}"}
self.auth_invoice = {"Authorization": f"Basic {getenv('LNTXBOT_INVOICE_KEY')}"} self.auth_invoice = {"Authorization": f"Basic {getenv('LNTXBOT_INVOICE_KEY')}"}
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse: def create_invoice(
r = post( self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
url=f"{self.endpoint}/addinvoice", ) -> InvoiceResponse:
headers=self.auth_invoice, data: Dict = {"amt": str(amount)}
json={"amt": str(amount), "memo": memo, "description_hash": description_hash.hex()}, if description_hash:
) data["description_hash"] = description_hash.hex()
else:
data["memo"] = memo or ""
r = post(url=f"{self.endpoint}/addinvoice", headers=self.auth_invoice, json=data,)
ok, checking_id, payment_request, error_message = r.ok, None, None, None ok, checking_id, payment_request, error_message = r.ok, None, None, None
if r.ok: if r.ok:

5
lnbits/wallets/opennode.py

@ -1,4 +1,5 @@
from os import getenv from os import getenv
from typing import Optional
from requests import get, post from requests import get, post
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet, Unsupported from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet, Unsupported
@ -13,7 +14,9 @@ class OpenNodeWallet(Wallet):
self.auth_admin = {"Authorization": getenv("OPENNODE_ADMIN_KEY")} self.auth_admin = {"Authorization": getenv("OPENNODE_ADMIN_KEY")}
self.auth_invoice = {"Authorization": getenv("OPENNODE_INVOICE_KEY")} self.auth_invoice = {"Authorization": getenv("OPENNODE_INVOICE_KEY")}
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse: def create_invoice(
self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
) -> InvoiceResponse:
if description_hash: if description_hash:
raise Unsupported("description_hash") raise Unsupported("description_hash")

9
lnbits/wallets/spark.py

@ -1,6 +1,7 @@
import random import random
import requests import requests
from os import getenv from os import getenv
from typing import Optional
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet
@ -38,7 +39,9 @@ class SparkWallet(Wallet):
return call return call
def create_invoice(self, amount: int, memo: str = "", description_hash: bytes = b"") -> InvoiceResponse: def create_invoice(
self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
) -> InvoiceResponse:
label = "lbs{}".format(random.random()) label = "lbs{}".format(random.random())
checking_id = label checking_id = label
@ -48,7 +51,9 @@ class SparkWallet(Wallet):
msatoshi=amount * 1000, label=label, description_hash=description_hash.hex(), msatoshi=amount * 1000, label=label, description_hash=description_hash.hex(),
) )
else: else:
r = self.invoice(msatoshi=amount * 1000, label=label, description=memo, exposeprivatechannels=True) r = self.invoice(
msatoshi=amount * 1000, label=label, description=memo or "", exposeprivatechannels=True
)
ok, payment_request, error_message = True, r["bolt11"], "" ok, payment_request, error_message = True, r["bolt11"], ""
except (SparkError, UnknownError) as e: except (SparkError, UnknownError) as e:
ok, payment_request, error_message = False, None, str(e) ok, payment_request, error_message = False, None, str(e)

Loading…
Cancel
Save