mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2024-11-19 01:43:42 +01:00
simplify environment variables required.
instead of multiple keys/macaroons with different permissions we request only one. if someone wants to use lnbits with an invoice macaroon they're free to do it and we will just fail on 'pay' methods, as before. this also grandfathers the previous environment variables names so everything keeps working without people having to change their setups. in the meantime some bugs with lntxbot and c-lightning were fixed and the `requests` dependency was eliminated because I can't organize myself into meaningful chunks of changes.
This commit is contained in:
parent
fc6e49b821
commit
9185342c72
18
.env.example
18
.env.example
@ -29,34 +29,28 @@ CLIGHTNING_RPC="/home/bob/.lightning/bitcoin/lightning-rpc"
|
||||
|
||||
# LnbitsWallet
|
||||
LNBITS_ENDPOINT=http://127.0.0.1:5000
|
||||
LNBITS_INVOICE_KEY=LNBITS_INVOICE_KEY
|
||||
LNBITS_ADMIN_KEY=LNBITS_ADMIN_KEY
|
||||
LNBITS_KEY=LNBITS_ADMIN_KEY
|
||||
|
||||
# LndWallet
|
||||
LND_GRPC_ENDPOINT=127.0.0.1
|
||||
LND_GRPC_PORT=11009
|
||||
LND_GRPC_CERT="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/tls.cert"
|
||||
LND_GRPC_ADMIN_MACAROON="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/admin.macaroon"
|
||||
LND_GRPC_INVOICE_MACAROON="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/invoice.macaroon"
|
||||
LND_GRPC_MACAROON="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/admin.macaroon"
|
||||
|
||||
# LndRestWallet
|
||||
LND_REST_ENDPOINT=https://127.0.0.1:8080/
|
||||
LND_REST_CERT="/home/bob/.config/Zap/lnd/bitcoin/mainnet/wallet-1/data/chain/bitcoin/mainnet/tls.cert"
|
||||
LND_REST_ADMIN_MACAROON="HEXSTRING"
|
||||
LND_REST_INVOICE_MACAROON="HEXSTRING"
|
||||
LND_REST_MACAROON="HEXSTRING"
|
||||
|
||||
# LNPayWallet
|
||||
LNPAY_API_ENDPOINT=https://lnpay.co/v1/
|
||||
LNPAY_API_KEY=LNPAY_API_KEY
|
||||
LNPAY_ADMIN_KEY=LNPAY_ADMIN_KEY
|
||||
LNPAY_INVOICE_KEY=LNPAY_INVOICE_KEY
|
||||
LNPAY_WALLET_KEY=LNPAY_ADMIN_KEY
|
||||
|
||||
# LntxbotWallet
|
||||
LNTXBOT_API_ENDPOINT=https://lntxbot.bigsun.xyz/
|
||||
LNTXBOT_ADMIN_KEY=LNTXBOT_ADMIN_KEY
|
||||
LNTXBOT_INVOICE_KEY=LNTXBOT_INVOICE_KEY
|
||||
LNTXBOT_KEY=LNTXBOT_ADMIN_KEY
|
||||
|
||||
# OpenNodeWallet
|
||||
OPENNODE_API_ENDPOINT=https://api.opennode.com/
|
||||
OPENNODE_ADMIN_KEY=OPENNODE_ADMIN_KEY
|
||||
OPENNODE_INVOICE_KEY=OPENNODE_INVOICE_KEY
|
||||
OPENNODE_KEY=OPENNODE_ADMIN_KEY
|
||||
|
1
Pipfile
1
Pipfile
@ -13,7 +13,6 @@ ecdsa = "*"
|
||||
environs = "*"
|
||||
lnurl = "*"
|
||||
pyscss = "*"
|
||||
requests = "*"
|
||||
shortuuid = "*"
|
||||
quart = "*"
|
||||
quart-cors = "*"
|
||||
|
55
Pipfile.lock
generated
55
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "76a3823f58d720ea680fdcd246f2a8b5fa16ce0a87a650e5e9fff5559dca7309"
|
||||
"sha256": "193ef930ac0906127fd292b2fc7ba5b4d786227b6795d182dad9b57448fca75e"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@ -106,13 +106,6 @@
|
||||
],
|
||||
"version": "==2020.6.20"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
],
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
|
||||
@ -139,10 +132,10 @@
|
||||
},
|
||||
"h11": {
|
||||
"hashes": [
|
||||
"sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1",
|
||||
"sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"
|
||||
"sha256:3c6c61d69c6f13d41f1b80ab0322f1872702a3ba26e12aa864c928f6a43fbaab",
|
||||
"sha256:ab6c335e1b6ef34b205d5ca3e228c9299cc7218b049819ec84a388c2525e5d87"
|
||||
],
|
||||
"version": "==0.9.0"
|
||||
"version": "==0.11.0"
|
||||
},
|
||||
"h2": {
|
||||
"hashes": [
|
||||
@ -162,30 +155,30 @@
|
||||
},
|
||||
"httpcore": {
|
||||
"hashes": [
|
||||
"sha256:72cfaa461dbdc262943ff4c9abf5b195391a03cdcc152e636adb4239b15e77e1",
|
||||
"sha256:a35dddd1f4cc34ff37788337ef507c0ad0276241ece6daf663ac9e77c0b87232"
|
||||
"sha256:18c4afcbfe884b635e59739105aed1692e132bc5d31597109f3c1c97e4ec1cac",
|
||||
"sha256:2526a38f31ac5967d38b7f593b5d8c4bd3fa82c21400402f866ba3312946acbf"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.11.1"
|
||||
"version": "==0.12.0"
|
||||
},
|
||||
"httpx": {
|
||||
"hashes": [
|
||||
"sha256:02326f2d3c61133db31e4b88dd3432479b434e52a68d813eab6db930f13611ea",
|
||||
"sha256:254b371e3880a8e2387bf9ead6949bac797bd557fda26eba19a6153a0c06bd2b"
|
||||
"sha256:126424c279c842738805974687e0518a94c7ae8d140cd65b9c4f77ac46ffa537",
|
||||
"sha256:9cffb8ba31fac6536f2c8cde30df859013f59e4bcc5b8d43901cb3654a8e0a5b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.15.5"
|
||||
"version": "==0.16.1"
|
||||
},
|
||||
"hypercorn": {
|
||||
"extras": [
|
||||
"trio"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:6540faeba9dd44f7e74c7cc1beae3a438a7efb5f77323d1199457da46d32c2c2",
|
||||
"sha256:b5c479023757e279f954b46a4ec9dd85e58a2bcbf4d959d5601cbced593e711d"
|
||||
"sha256:81c69dd84a87b8e8b3ebf06ef5dd92836a8238f0ac65ded3d86befb8ba9acfeb",
|
||||
"sha256:e3f317d6d64d15ce589f49e4f5057947259fa35332d169e62cb060e9997189e4"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.11.0"
|
||||
"version": "==0.11.1"
|
||||
},
|
||||
"hyperframe": {
|
||||
"hashes": [
|
||||
@ -356,14 +349,6 @@
|
||||
"index": "pypi",
|
||||
"version": "==0.5.1"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b",
|
||||
"sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.24.0"
|
||||
},
|
||||
"rfc3986": {
|
||||
"extras": [
|
||||
"idna2008"
|
||||
@ -437,14 +422,6 @@
|
||||
"index": "pypi",
|
||||
"version": "==3.7.4.3"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a",
|
||||
"sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
|
||||
"version": "==1.25.10"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43",
|
||||
@ -657,12 +634,17 @@
|
||||
"hashes": [
|
||||
"sha256:088afc8c63e7bd187a3c70a94b9e50ab3f17e1d3f52a32750b5b77dbe99ef5ef",
|
||||
"sha256:1fe0a41437bbd06063aa184c34804efa886bcc128222e9916310c92cd54c3b4c",
|
||||
"sha256:3d20024a70b97b4f9546696cbf2fd30bae5f42229fbddf8661261b1eaff0deb7",
|
||||
"sha256:41bb65f54bba392643557e617316d0d899ed5b4946dccee1cb6696152b29844b",
|
||||
"sha256:4318d56bccfe7d43e5addb272406ade7a2274da4b70eb15922a071c58ab0108c",
|
||||
"sha256:4707f3695b34335afdfb09be3802c87fa0bc27030471dbc082f815f23688bc63",
|
||||
"sha256:49f23ebd5ac073765ecbcf046edc10d63dcab2f4ae2bce160982cb30df0c0302",
|
||||
"sha256:5533a959a1748a5c042a6da71fe9267a908e21eded7a4f373efd23a2cbdb0ecc",
|
||||
"sha256:5d892a4f1c999834eaa3c32bc9e8b976c5825116cde553928c4c8e7e48ebda67",
|
||||
"sha256:5f18875ac23d9aa2f060838e8b79093e8bb2313dbaaa9f54c6d8e52a5df097be",
|
||||
"sha256:60b0e9e6dc45683e569ec37c55ac20c582973841927a85f2d8a7d20ee80216ab",
|
||||
"sha256:816064fc915796ea1f26966163f6845de5af78923dfcecf6551e095f00983650",
|
||||
"sha256:84cada8effefe9a9f53f9b0d2ba9b7b6f5edf8d2155f9fdbe34616e06ececf81",
|
||||
"sha256:84e9407db1b2eb368b7ecc283121b5e592c9aaedbe8c78b1a2f1102eb2e21d19",
|
||||
"sha256:8d69cef61fa50c8133382e61fd97439de1ae623fe943578e477e76a9d9471637",
|
||||
"sha256:9a02d0ae31d35e1ec12a4ea4d4cca990800f66a917d0fb997b20fbc13f5321fc",
|
||||
@ -670,6 +652,7 @@
|
||||
"sha256:a6f32aea4260dfe0e55dc9733ea162ea38f0ea86aa7d0f77b15beac5bf7b369d",
|
||||
"sha256:ae91972f8ac958039920ef6e8769277c084971a142ce2b660691793ae44aae6b",
|
||||
"sha256:c570f6fa14b9c4c8a4924aaad354652366577b4f98213cf76305067144f7b100",
|
||||
"sha256:c9443124c67b1515e4fe0bb0aa18df640965e1030f468a2a5dc2589b26d130ad",
|
||||
"sha256:d23a18037313714fb3bb5a94434d3151ee4300bae631894b1ac08111abeaa4a3",
|
||||
"sha256:eaf548d117b6737df379fdd53bdde4f08870e66d7ea653e230477f071f861121",
|
||||
"sha256:ebbe29186a3d9b0c591e71b7393f1ae08c83cb2d8e517d2a822b8f7ec99dfd8b",
|
||||
|
@ -1,5 +1,6 @@
|
||||
import trio # type: ignore
|
||||
import json
|
||||
import traceback
|
||||
from quart import g, jsonify, request, make_response
|
||||
from http import HTTPStatus
|
||||
from binascii import unhexlify
|
||||
@ -87,10 +88,10 @@ async def api_payments_pay_invoice():
|
||||
return jsonify({"message": str(e)}), HTTPStatus.BAD_REQUEST
|
||||
except PermissionError as e:
|
||||
return jsonify({"message": str(e)}), HTTPStatus.FORBIDDEN
|
||||
except Exception as e:
|
||||
print(e)
|
||||
except Exception as exc:
|
||||
traceback.print_exc(7)
|
||||
g.db.rollback()
|
||||
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR
|
||||
return jsonify({"message": str(exc)}), HTTPStatus.INTERNAL_SERVER_ERROR
|
||||
|
||||
return (
|
||||
jsonify(
|
||||
|
@ -1,4 +1,4 @@
|
||||
import requests
|
||||
import httpx
|
||||
from quart import g, jsonify, request, abort
|
||||
from http import HTTPStatus
|
||||
from lnurl import LnurlWithdrawResponse, handle as handle_lnurl
|
||||
@ -38,12 +38,12 @@ async def api_amilkit(amilk_id):
|
||||
wallet_id=milk.wallet, amount=withdraw_res.max_sats, memo=memo, extra={"tag": "amilk"}
|
||||
)
|
||||
|
||||
r = requests.get(
|
||||
r = httpx.get(
|
||||
withdraw_res.callback.base,
|
||||
params={**withdraw_res.callback.query_params, **{"k1": withdraw_res.k1, "pr": payment_request}},
|
||||
)
|
||||
|
||||
if not r.ok:
|
||||
if r.is_error:
|
||||
abort(HTTPStatus.INTERNAL_SERVER_ERROR, "Could not process withdraw LNURL.")
|
||||
|
||||
for i in range(10):
|
||||
|
@ -1,7 +1,7 @@
|
||||
from base64 import urlsafe_b64encode
|
||||
from uuid import uuid4
|
||||
from typing import List, Optional, Union
|
||||
import requests
|
||||
import httpx
|
||||
from lnbits.db import open_ext_db
|
||||
from lnbits.settings import WALLET
|
||||
from .models import Products, Orders, Indexers
|
||||
@ -120,7 +120,7 @@ def get_diagonalleys_indexer(indexer_id: str) -> Optional[Indexers]:
|
||||
with open_ext_db("diagonalley") as db:
|
||||
roww = db.fetchone("SELECT * FROM indexers WHERE id = ?", (indexer_id,))
|
||||
try:
|
||||
x = requests.get(roww["indexeraddress"] + "/" + roww["ratingkey"])
|
||||
x = httpx.get(roww["indexeraddress"] + "/" + roww["ratingkey"])
|
||||
if x.status_code == 200:
|
||||
print(x)
|
||||
print("poo")
|
||||
@ -158,7 +158,7 @@ def get_diagonalleys_indexers(wallet_ids: Union[str, List[str]]) -> List[Indexer
|
||||
|
||||
for r in rows:
|
||||
try:
|
||||
x = requests.get(r["indexeraddress"] + "/" + r["ratingkey"])
|
||||
x = httpx.get(r["indexeraddress"] + "/" + r["ratingkey"])
|
||||
if x.status_code == 200:
|
||||
with open_ext_db("diagonalley") as db:
|
||||
db.execute(
|
||||
|
@ -3,7 +3,9 @@
|
||||
# add your dependencies here
|
||||
|
||||
# import json
|
||||
# import requests
|
||||
# import httpx
|
||||
# (use httpx just like requests, except instead of response.ok there's only the
|
||||
# response.is_error that is its inverse)
|
||||
|
||||
from quart import jsonify
|
||||
from http import HTTPStatus
|
||||
|
@ -73,7 +73,7 @@ class CLightningWallet(Wallet):
|
||||
raise KeyError("supplied an invalid checking_id")
|
||||
|
||||
def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||
r = self.ln.listpays(payment_hash=checking_id)
|
||||
r = self.ln.call("listpays", {"payment_hash": checking_id})
|
||||
if not r["pays"]:
|
||||
return PaymentStatus(False)
|
||||
if r["pays"][0]["payment_hash"] == checking_id:
|
||||
|
@ -1,7 +1,7 @@
|
||||
import trio # type: ignore
|
||||
import httpx
|
||||
from os import getenv
|
||||
from typing import Optional, Dict, AsyncGenerator
|
||||
from requests import get, post
|
||||
|
||||
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet
|
||||
|
||||
@ -11,8 +11,9 @@ class LNbitsWallet(Wallet):
|
||||
|
||||
def __init__(self):
|
||||
self.endpoint = getenv("LNBITS_ENDPOINT")
|
||||
self.auth_admin = {"X-Api-Key": getenv("LNBITS_ADMIN_KEY")}
|
||||
self.auth_invoice = {"X-Api-Key": getenv("LNBITS_INVOICE_KEY")}
|
||||
|
||||
key = getenv("LNBITS_KEY") or getenv("LNBITS_ADMIN_KEY") or getenv("LNBITS_INVOICE_KEY")
|
||||
self.key = {"X-Api-Key": key}
|
||||
|
||||
def create_invoice(
|
||||
self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
|
||||
@ -23,45 +24,45 @@ class LNbitsWallet(Wallet):
|
||||
else:
|
||||
data["memo"] = memo or ""
|
||||
|
||||
r = post(
|
||||
r = httpx.post(
|
||||
url=f"{self.endpoint}/api/v1/payments",
|
||||
headers=self.auth_invoice,
|
||||
headers=self.key,
|
||||
json=data,
|
||||
)
|
||||
ok, checking_id, payment_request, error_message = r.ok, None, None, None
|
||||
ok, checking_id, payment_request, error_message = not r.is_error, None, None, None
|
||||
|
||||
if r.ok:
|
||||
if r.is_error:
|
||||
error_message = r.json()["message"]
|
||||
else:
|
||||
data = r.json()
|
||||
checking_id, payment_request = data["checking_id"], data["payment_request"]
|
||||
else:
|
||||
error_message = r.json()["message"]
|
||||
|
||||
return InvoiceResponse(ok, checking_id, payment_request, error_message)
|
||||
|
||||
def pay_invoice(self, bolt11: str) -> PaymentResponse:
|
||||
r = post(url=f"{self.endpoint}/api/v1/payments", headers=self.auth_admin, json={"out": True, "bolt11": bolt11})
|
||||
ok, checking_id, fee_msat, error_message = True, None, 0, None
|
||||
r = httpx.post(url=f"{self.endpoint}/api/v1/payments", headers=self.key, json={"out": True, "bolt11": bolt11})
|
||||
ok, checking_id, fee_msat, error_message = not r.is_error, None, 0, None
|
||||
|
||||
if r.ok:
|
||||
if r.is_error:
|
||||
error_message = r.json()["message"]
|
||||
else:
|
||||
data = r.json()
|
||||
checking_id = data["checking_id"]
|
||||
else:
|
||||
error_message = r.json()["message"]
|
||||
|
||||
return PaymentResponse(ok, checking_id, fee_msat, error_message)
|
||||
|
||||
def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||
r = get(url=f"{self.endpoint}/api/v1/payments/{checking_id}", headers=self.auth_invoice)
|
||||
r = httpx.get(url=f"{self.endpoint}/api/v1/payments/{checking_id}", headers=self.key)
|
||||
|
||||
if not r.ok:
|
||||
if r.is_error:
|
||||
return PaymentStatus(None)
|
||||
|
||||
return PaymentStatus(r.json()["paid"])
|
||||
|
||||
def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||
r = get(url=f"{self.endpoint}/api/v1/payments/{checking_id}", headers=self.auth_invoice)
|
||||
r = httpx.get(url=f"{self.endpoint}/api/v1/payments/{checking_id}", headers=self.key)
|
||||
|
||||
if not r.ok:
|
||||
if r.is_error:
|
||||
return PaymentStatus(None)
|
||||
|
||||
return PaymentStatus(r.json()["paid"])
|
||||
|
@ -46,22 +46,28 @@ class LndWallet(Wallet):
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
self.port = int(getenv("LND_GRPC_PORT"))
|
||||
self.cert_path = getenv("LND_GRPC_CERT") or getenv("LND_CERT")
|
||||
self.auth_admin = getenv("LND_GRPC_ADMIN_MACAROON") or getenv("LND_ADMIN_MACAROON")
|
||||
self.auth_invoices = getenv("LND_GRPC_INVOICE_MACAROON") or getenv("LND_INVOICE_MACAROON")
|
||||
|
||||
self.macaroon_path = (
|
||||
getenv("LND_GRPC_MACAROON")
|
||||
or getenv("LND_GRPC_ADMIN_MACAROON")
|
||||
or getenv("LND_ADMIN_MACAROON")
|
||||
or getenv("LND_GRPC_INVOICE_MACAROON")
|
||||
or getenv("LND_INVOICE_MACAROON")
|
||||
)
|
||||
network = getenv("LND_GRPC_NETWORK", "mainnet")
|
||||
|
||||
self.admin_rpc = lndgrpc.LNDClient(
|
||||
f"{self.endpoint}:{self.port}",
|
||||
cert_filepath=self.cert_path,
|
||||
network=network,
|
||||
macaroon_filepath=self.auth_admin,
|
||||
macaroon_filepath=self.macaroon_path,
|
||||
)
|
||||
|
||||
self.invoices_rpc = lndgrpc.LNDClient(
|
||||
f"{self.endpoint}:{self.port}",
|
||||
cert_filepath=self.cert_path,
|
||||
network=network,
|
||||
macaroon_filepath=self.auth_invoices,
|
||||
macaroon_filepath=self.macaroon_path,
|
||||
)
|
||||
|
||||
def create_invoice(
|
||||
@ -129,7 +135,7 @@ class LndWallet(Wallet):
|
||||
ln.Invoice,
|
||||
),
|
||||
)
|
||||
macaroon = load_macaroon(self.auth_admin)
|
||||
macaroon = load_macaroon(self.macaroon_path)
|
||||
|
||||
async for inv in subscribe_invoices(
|
||||
ln.InvoiceSubscription(),
|
||||
|
@ -11,19 +11,20 @@ class LndRestWallet(Wallet):
|
||||
"""https://api.lightning.community/rest/index.html#lnd-rest-api-reference"""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
endpoint = getenv("LND_REST_ENDPOINT")
|
||||
endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
endpoint = "https://" + endpoint if not endpoint.startswith("http") else endpoint
|
||||
self.endpoint = endpoint
|
||||
|
||||
self.auth_admin = {
|
||||
"Grpc-Metadata-macaroon": getenv("LND_ADMIN_MACAROON") or getenv("LND_REST_ADMIN_MACAROON"),
|
||||
}
|
||||
self.auth_invoice = {
|
||||
"Grpc-Metadata-macaroon": getenv("LND_INVOICE_MACAROON") or getenv("LND_REST_INVOICE_MACAROON")
|
||||
}
|
||||
self.auth_cert = getenv("LND_REST_CERT")
|
||||
macaroon = (
|
||||
getenv("LND_MACAROON")
|
||||
or getenv("LND_ADMIN_MACAROON")
|
||||
or getenv("LND_REST_ADMIN_MACAROON")
|
||||
or getenv("LND_INVOICE_MACAROON")
|
||||
or getenv("LND_REST_INVOICE_MACAROON")
|
||||
)
|
||||
self.auth = {"Grpc-Metadata-macaroon": macaroon}
|
||||
self.cert = getenv("LND_REST_CERT")
|
||||
|
||||
def create_invoice(
|
||||
self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
|
||||
@ -39,8 +40,8 @@ class LndRestWallet(Wallet):
|
||||
|
||||
r = httpx.post(
|
||||
url=f"{self.endpoint}/v1/invoices",
|
||||
headers=self.auth_invoice,
|
||||
verify=self.auth_cert,
|
||||
headers=self.auth,
|
||||
verify=self.cert,
|
||||
json=data,
|
||||
)
|
||||
|
||||
@ -62,8 +63,8 @@ class LndRestWallet(Wallet):
|
||||
def pay_invoice(self, bolt11: str) -> PaymentResponse:
|
||||
r = httpx.post(
|
||||
url=f"{self.endpoint}/v1/channels/transactions",
|
||||
headers=self.auth_admin,
|
||||
verify=self.auth_cert,
|
||||
headers=self.auth,
|
||||
verify=self.cert,
|
||||
json={"payment_request": bolt11},
|
||||
)
|
||||
|
||||
@ -84,8 +85,8 @@ class LndRestWallet(Wallet):
|
||||
checking_id = checking_id.replace("_", "/")
|
||||
r = httpx.get(
|
||||
url=f"{self.endpoint}/v1/invoice/{checking_id}",
|
||||
headers=self.auth_invoice,
|
||||
verify=self.auth_cert,
|
||||
headers=self.auth,
|
||||
verify=self.cert,
|
||||
)
|
||||
|
||||
if r.is_error or not r.json().get("settled"):
|
||||
@ -98,8 +99,8 @@ class LndRestWallet(Wallet):
|
||||
def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||
r = httpx.get(
|
||||
url=f"{self.endpoint}/v1/payments",
|
||||
headers=self.auth_admin,
|
||||
verify=self.auth_cert,
|
||||
headers=self.auth,
|
||||
verify=self.cert,
|
||||
params={"include_incomplete": "True", "max_payments": "20"},
|
||||
)
|
||||
|
||||
@ -118,7 +119,7 @@ class LndRestWallet(Wallet):
|
||||
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
||||
url = self.endpoint + "/v1/invoices/subscribe"
|
||||
|
||||
async with httpx.AsyncClient(timeout=None, headers=self.auth_admin, verify=self.auth_cert) as client:
|
||||
async with httpx.AsyncClient(timeout=None, headers=self.auth, verify=self.cert) as client:
|
||||
async with client.stream("GET", url) as r:
|
||||
async for line in r.aiter_lines():
|
||||
try:
|
||||
|
@ -15,8 +15,8 @@ class LNPayWallet(Wallet):
|
||||
def __init__(self):
|
||||
endpoint = getenv("LNPAY_API_ENDPOINT", "https://lnpay.co/v1")
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
self.auth_admin = getenv("LNPAY_ADMIN_KEY")
|
||||
self.auth_api = {"X-Api-Key": getenv("LNPAY_API_KEY")}
|
||||
self.wallet_key = getenv("LNPAY_WALLET_KEY") or getenv("LNPAY_ADMIN_KEY")
|
||||
self.auth = {"X-Api-Key": getenv("LNPAY_API_KEY")}
|
||||
|
||||
def create_invoice(
|
||||
self,
|
||||
@ -31,8 +31,8 @@ class LNPayWallet(Wallet):
|
||||
data["memo"] = memo or ""
|
||||
|
||||
r = httpx.post(
|
||||
url=f"{self.endpoint}/user/wallet/{self.auth_admin}/invoice",
|
||||
headers=self.auth_api,
|
||||
url=f"{self.endpoint}/user/wallet/{self.wallet_key}/invoice",
|
||||
headers=self.auth,
|
||||
json=data,
|
||||
)
|
||||
ok, checking_id, payment_request, error_message = (
|
||||
@ -50,8 +50,8 @@ class LNPayWallet(Wallet):
|
||||
|
||||
def pay_invoice(self, bolt11: str) -> PaymentResponse:
|
||||
r = httpx.post(
|
||||
url=f"{self.endpoint}/user/wallet/{self.auth_admin}/withdraw",
|
||||
headers=self.auth_api,
|
||||
url=f"{self.endpoint}/user/wallet/{self.wallet_key}/withdraw",
|
||||
headers=self.auth,
|
||||
json={"payment_request": bolt11},
|
||||
)
|
||||
ok, checking_id, fee_msat, error_message = r.status_code == 201, None, 0, None
|
||||
@ -67,7 +67,7 @@ class LNPayWallet(Wallet):
|
||||
def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||
r = httpx.get(
|
||||
url=f"{self.endpoint}/user/lntx/{checking_id}?fields=settled",
|
||||
headers=self.auth_api,
|
||||
headers=self.auth,
|
||||
)
|
||||
|
||||
if r.is_error:
|
||||
@ -91,7 +91,7 @@ class LNPayWallet(Wallet):
|
||||
async with httpx.AsyncClient() as client:
|
||||
r = await client.get(
|
||||
f"{self.endpoint}/user/lntx/{lntx_id}?fields=settled",
|
||||
headers=self.auth_api,
|
||||
headers=self.auth,
|
||||
)
|
||||
data = r.json()
|
||||
if data["settled"]:
|
||||
|
@ -1,7 +1,7 @@
|
||||
import trio # type: ignore
|
||||
import httpx
|
||||
from os import getenv
|
||||
from typing import Optional, Dict, AsyncGenerator
|
||||
from requests import post
|
||||
|
||||
from .base import InvoiceResponse, PaymentResponse, PaymentStatus, Wallet
|
||||
|
||||
@ -12,8 +12,9 @@ class LntxbotWallet(Wallet):
|
||||
def __init__(self):
|
||||
endpoint = getenv("LNTXBOT_API_ENDPOINT")
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
self.auth_admin = {"Authorization": f"Basic {getenv('LNTXBOT_ADMIN_KEY')}"}
|
||||
self.auth_invoice = {"Authorization": f"Basic {getenv('LNTXBOT_INVOICE_KEY')}"}
|
||||
|
||||
key = getenv("LNTXBOT_KEY") or getenv("LNTXBOT_ADMIN_KEY") or getenv("LNTXBOT_INVOICE_KEY")
|
||||
self.auth = {"Authorization": f"Basic {key}"}
|
||||
|
||||
def create_invoice(
|
||||
self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
|
||||
@ -24,44 +25,47 @@ class LntxbotWallet(Wallet):
|
||||
else:
|
||||
data["memo"] = memo or ""
|
||||
|
||||
r = post(
|
||||
r = httpx.post(
|
||||
url=f"{self.endpoint}/addinvoice",
|
||||
headers=self.auth_invoice,
|
||||
headers=self.auth,
|
||||
json=data,
|
||||
)
|
||||
ok, checking_id, payment_request, error_message = r.ok, None, None, None
|
||||
|
||||
if r.ok:
|
||||
data = r.json()
|
||||
checking_id, payment_request = data["payment_hash"], data["pay_req"]
|
||||
|
||||
if "error" in data and data["error"]:
|
||||
ok = False
|
||||
if r.is_error:
|
||||
try:
|
||||
data = r.json()
|
||||
error_message = data["message"]
|
||||
except:
|
||||
error_message = r.text
|
||||
pass
|
||||
|
||||
return InvoiceResponse(ok, checking_id, payment_request, error_message)
|
||||
|
||||
def pay_invoice(self, bolt11: str) -> PaymentResponse:
|
||||
r = post(url=f"{self.endpoint}/payinvoice", headers=self.auth_admin, json={"invoice": bolt11})
|
||||
ok, checking_id, fee_msat, error_message = r.ok, None, 0, None
|
||||
|
||||
if r.ok:
|
||||
data = r.json()
|
||||
|
||||
if "payment_hash" in data:
|
||||
checking_id, fee_msat = data["decoded"]["payment_hash"], data["fee_msat"]
|
||||
elif "error" in data and data["error"]:
|
||||
ok, error_message = False, data["message"]
|
||||
|
||||
return PaymentResponse(ok, checking_id, fee_msat, error_message)
|
||||
|
||||
def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||
r = post(url=f"{self.endpoint}/invoicestatus/{checking_id}?wait=false", headers=self.auth_invoice)
|
||||
|
||||
if not r.ok or "error" in r.json():
|
||||
return PaymentStatus(None)
|
||||
return InvoiceResponse(False, None, None, error_message)
|
||||
|
||||
data = r.json()
|
||||
return InvoiceResponse(True, data["payment_hash"], data["pay_req"], None)
|
||||
|
||||
def pay_invoice(self, bolt11: str) -> PaymentResponse:
|
||||
r = httpx.post(url=f"{self.endpoint}/payinvoice", headers=self.auth, json={"invoice": bolt11})
|
||||
|
||||
if r.is_error:
|
||||
try:
|
||||
data = r.json()
|
||||
error_message = data["message"]
|
||||
except:
|
||||
error_message = r.text
|
||||
pass
|
||||
|
||||
return PaymentResponse(False, None, 0, error_message)
|
||||
|
||||
data = r.json()
|
||||
return PaymentResponse(True, data["decoded"]["payment_hash"], data["fee_msat"], None)
|
||||
|
||||
def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||
r = httpx.post(url=f"{self.endpoint}/invoicestatus/{checking_id}?wait=false", headers=self.auth)
|
||||
|
||||
data = r.json()
|
||||
if r.is_error or "error" in data:
|
||||
return PaymentStatus(None)
|
||||
|
||||
if "preimage" not in data:
|
||||
return PaymentStatus(False)
|
||||
@ -69,13 +73,14 @@ class LntxbotWallet(Wallet):
|
||||
return PaymentStatus(True)
|
||||
|
||||
def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||
r = post(url=f"{self.endpoint}/paymentstatus/{checking_id}", headers=self.auth_invoice)
|
||||
r = httpx.post(url=f"{self.endpoint}/paymentstatus/{checking_id}", headers=self.auth)
|
||||
|
||||
if not r.ok or "error" in r.json():
|
||||
data = r.json()
|
||||
if r.is_error or "error" in data:
|
||||
return PaymentStatus(None)
|
||||
|
||||
statuses = {"complete": True, "failed": False, "pending": None, "unknown": None}
|
||||
return PaymentStatus(statuses[r.json().get("status", "unknown")])
|
||||
return PaymentStatus(statuses[data.get("status", "unknown")])
|
||||
|
||||
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
||||
print("lntxbot does not support paid invoices stream yet")
|
||||
|
@ -16,8 +16,9 @@ class OpenNodeWallet(Wallet):
|
||||
def __init__(self):
|
||||
endpoint = getenv("OPENNODE_API_ENDPOINT")
|
||||
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
||||
self.auth_admin = {"Authorization": getenv("OPENNODE_ADMIN_KEY")}
|
||||
self.auth_invoice = {"Authorization": getenv("OPENNODE_INVOICE_KEY")}
|
||||
|
||||
key = getenv("OPENNODE_KEY") or getenv("OPENNODE_ADMIN_KEY") or getenv("OPENNODE_INVOICE_KEY")
|
||||
self.auth = {"Authorization": key}
|
||||
|
||||
def create_invoice(
|
||||
self, amount: int, memo: Optional[str] = None, description_hash: Optional[bytes] = None
|
||||
@ -45,9 +46,7 @@ class OpenNodeWallet(Wallet):
|
||||
return InvoiceResponse(True, checking_id, payment_request, None)
|
||||
|
||||
def pay_invoice(self, bolt11: str) -> PaymentResponse:
|
||||
r = httpx.post(
|
||||
f"{self.endpoint}/v2/withdrawals", headers=self.auth_admin, json={"type": "ln", "address": bolt11}
|
||||
)
|
||||
r = httpx.post(f"{self.endpoint}/v2/withdrawals", headers=self.auth, json={"type": "ln", "address": bolt11})
|
||||
|
||||
if r.is_error:
|
||||
error_message = r.json()["message"]
|
||||
@ -68,7 +67,7 @@ class OpenNodeWallet(Wallet):
|
||||
return PaymentStatus(statuses[r.json()["data"]["status"]])
|
||||
|
||||
def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||
r = httpx.get(f"{self.endpoint}/v1/withdrawal/{checking_id}", headers=self.auth_admin)
|
||||
r = httpx.get(f"{self.endpoint}/v1/withdrawal/{checking_id}", headers=self.auth)
|
||||
|
||||
if r.is_error:
|
||||
return PaymentStatus(None)
|
||||
|
@ -7,16 +7,15 @@ blinker==1.4
|
||||
brotli==1.0.9
|
||||
cerberus==1.3.2
|
||||
certifi==2020.6.20
|
||||
chardet==3.0.4
|
||||
click==7.1.2
|
||||
ecdsa==0.16.0
|
||||
environs==8.0.0
|
||||
h11==0.9.0
|
||||
h11==0.11.0
|
||||
h2==4.0.0
|
||||
hpack==4.0.0
|
||||
httpcore==0.11.1
|
||||
httpx==0.15.5
|
||||
hypercorn==0.11.0
|
||||
httpcore==0.12.0
|
||||
httpx==0.16.1
|
||||
hypercorn==0.11.1
|
||||
hyperframe==6.0.0
|
||||
idna==2.10
|
||||
itsdangerous==1.1.0
|
||||
@ -33,7 +32,6 @@ quart==0.13.1
|
||||
quart-compress==0.2.1
|
||||
quart-cors==0.3.0
|
||||
quart-trio==0.5.1
|
||||
requests==2.24.0
|
||||
rfc3986==1.4.0
|
||||
secure==0.2.1
|
||||
shortuuid==1.0.1
|
||||
@ -43,6 +41,5 @@ sortedcontainers==2.2.2
|
||||
toml==0.10.1
|
||||
trio==0.17.0
|
||||
typing-extensions==3.7.4.3
|
||||
urllib3==1.25.10
|
||||
werkzeug==1.0.1
|
||||
wsproto==0.15.0
|
||||
|
Loading…
Reference in New Issue
Block a user