fix: description_hash as an optional param to create_invoice.
fixes https://github.com/lnbits/lnbits/issues/74
This commit is contained in:
parent
660d56d400
commit
68b0adfe66
11 changed files with 77 additions and 50 deletions
2
Makefile
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
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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,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")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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…
Add table
Add a link
Reference in a new issue