mirror of
https://github.com/lnbits/lnbits.git
synced 2025-06-21 14:22:52 +02:00
add zbd to settings
update api methods add zbd as funding source to settings and js fix statuses cast str into int for status method fix outbound payment hash issue restore create_invoice remove print stmts
This commit is contained in:
parent
d69946db8a
commit
d20a35eddc
@ -210,6 +210,7 @@ class ZBDFundingSource(LNbitsSettings):
|
|||||||
zbd_api_endpoint: Optional[str] = Field(default="https://api.zebedee.io/v0/")
|
zbd_api_endpoint: Optional[str] = Field(default="https://api.zebedee.io/v0/")
|
||||||
zbd_api_key: Optional[str] = Field(default=None)
|
zbd_api_key: Optional[str] = Field(default=None)
|
||||||
|
|
||||||
|
|
||||||
class AlbyFundingSource(LNbitsSettings):
|
class AlbyFundingSource(LNbitsSettings):
|
||||||
alby_api_endpoint: Optional[str] = Field(default="https://api.getalby.com/")
|
alby_api_endpoint: Optional[str] = Field(default="https://api.getalby.com/")
|
||||||
alby_access_token: Optional[str] = Field(default=None)
|
alby_access_token: Optional[str] = Field(default=None)
|
||||||
@ -249,6 +250,7 @@ class FundingSourcesSettings(
|
|||||||
LndGrpcFundingSource,
|
LndGrpcFundingSource,
|
||||||
LnPayFundingSource,
|
LnPayFundingSource,
|
||||||
AlbyFundingSource,
|
AlbyFundingSource,
|
||||||
|
ZBDFundingSource,
|
||||||
OpenNodeFundingSource,
|
OpenNodeFundingSource,
|
||||||
SparkFundingSource,
|
SparkFundingSource,
|
||||||
LnTipsFundingSource,
|
LnTipsFundingSource,
|
||||||
@ -403,6 +405,7 @@ class SuperUserSettings(LNbitsSettings):
|
|||||||
"LnTipsWallet",
|
"LnTipsWallet",
|
||||||
"LNPayWallet",
|
"LNPayWallet",
|
||||||
"AlbyWallet",
|
"AlbyWallet",
|
||||||
|
"ZBDWallet",
|
||||||
"LNbitsWallet",
|
"LNbitsWallet",
|
||||||
"OpenNodeWallet",
|
"OpenNodeWallet",
|
||||||
]
|
]
|
||||||
|
@ -110,7 +110,7 @@ Vue.component('lnbits-funding-sources', {
|
|||||||
'ZBD',
|
'ZBD',
|
||||||
{
|
{
|
||||||
zbd_api_endpoint: 'Endpoint',
|
zbd_api_endpoint: 'Endpoint',
|
||||||
zbd_access_token: 'Key'
|
zbd_api_key: 'Key'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
@ -8,7 +8,6 @@ from lnbits.settings import settings
|
|||||||
from lnbits.wallets.base import Wallet
|
from lnbits.wallets.base import Wallet
|
||||||
|
|
||||||
from .alby import AlbyWallet
|
from .alby import AlbyWallet
|
||||||
from .zbd import ZBDWallet
|
|
||||||
from .cliche import ClicheWallet
|
from .cliche import ClicheWallet
|
||||||
from .corelightning import CoreLightningWallet
|
from .corelightning import CoreLightningWallet
|
||||||
|
|
||||||
@ -26,6 +25,7 @@ from .lntips import LnTipsWallet
|
|||||||
from .opennode import OpenNodeWallet
|
from .opennode import OpenNodeWallet
|
||||||
from .spark import SparkWallet
|
from .spark import SparkWallet
|
||||||
from .void import VoidWallet
|
from .void import VoidWallet
|
||||||
|
from .zbd import ZBDWallet
|
||||||
|
|
||||||
|
|
||||||
def set_wallet_class(class_name: Optional[str] = None):
|
def set_wallet_class(class_name: Optional[str] = None):
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import hashlib
|
|
||||||
from typing import AsyncGenerator, Dict, Optional
|
from typing import AsyncGenerator, Dict, Optional
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from lnbits.settings import settings
|
from lnbits.settings import settings
|
||||||
|
from lnbits.wallets.base import PaymentStatus
|
||||||
|
|
||||||
from .base import (
|
from .base import (
|
||||||
InvoiceResponse,
|
InvoiceResponse,
|
||||||
PaymentResponse,
|
PaymentResponse,
|
||||||
PaymentStatus,
|
PaymentStatus,
|
||||||
StatusResponse,
|
StatusResponse,
|
||||||
|
Unsupported,
|
||||||
Wallet,
|
Wallet,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ class ZBDWallet(Wallet):
|
|||||||
|
|
||||||
self.endpoint = self.normalize_endpoint(settings.zbd_api_endpoint)
|
self.endpoint = self.normalize_endpoint(settings.zbd_api_endpoint)
|
||||||
self.auth = {
|
self.auth = {
|
||||||
"Authorization": "Bearer " + settings.zbd_api_key,
|
"apikey": settings.zbd_api_key,
|
||||||
"User-Agent": settings.user_agent,
|
"User-Agent": settings.user_agent,
|
||||||
}
|
}
|
||||||
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.auth)
|
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.auth)
|
||||||
@ -40,16 +41,18 @@ class ZBDWallet(Wallet):
|
|||||||
|
|
||||||
async def status(self) -> StatusResponse:
|
async def status(self) -> StatusResponse:
|
||||||
try:
|
try:
|
||||||
r = await self.client.get("/balance", timeout=10)
|
r = await self.client.get("wallet", timeout=10)
|
||||||
except (httpx.ConnectError, httpx.RequestError):
|
except (httpx.ConnectError, httpx.RequestError):
|
||||||
return StatusResponse(f"Unable to connect to '{self.endpoint}'", 0)
|
return StatusResponse(f"Unable to connect to '{self.endpoint}'", 0)
|
||||||
|
|
||||||
if r.is_error:
|
if r.is_error:
|
||||||
error_message = r.json()["message"]
|
error_message = r.json()["message"]
|
||||||
return StatusResponse(error_message, 0)
|
return StatusResponse(error_message, 0)
|
||||||
data = r.json()["balance"]
|
|
||||||
# if no error, multiply balance by 1000 for msats representation in lnbits
|
data = int(r.json()["data"]["balance"])
|
||||||
return StatusResponse(None, data * 1000)
|
# ZBD returns everything as a str not int
|
||||||
|
# balance is returned in msats already in ZBD
|
||||||
|
return StatusResponse(None, data)
|
||||||
|
|
||||||
async def create_invoice(
|
async def create_invoice(
|
||||||
self,
|
self,
|
||||||
@ -60,16 +63,20 @@ class ZBDWallet(Wallet):
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
) -> InvoiceResponse:
|
) -> InvoiceResponse:
|
||||||
# https://api.zebedee.io/v0/charges
|
# https://api.zebedee.io/v0/charges
|
||||||
data: Dict = {"amount": f"{amount}"}
|
if description_hash or unhashed_description:
|
||||||
if description_hash:
|
raise Unsupported("description_hash")
|
||||||
data["description_hash"] = description_hash.hex()
|
|
||||||
elif unhashed_description:
|
msats_amount = amount * 1000
|
||||||
data["description_hash"] = hashlib.sha256(unhashed_description).hexdigest()
|
data: Dict = {
|
||||||
else:
|
"amount": f"{msats_amount}",
|
||||||
data["memo"] = memo or ""
|
"description": memo,
|
||||||
|
"expiresIn": 3600,
|
||||||
|
"callbackUrl": "",
|
||||||
|
"internalId": "",
|
||||||
|
}
|
||||||
|
|
||||||
r = await self.client.post(
|
r = await self.client.post(
|
||||||
"/invoices",
|
"charges",
|
||||||
json=data,
|
json=data,
|
||||||
timeout=40,
|
timeout=40,
|
||||||
)
|
)
|
||||||
@ -78,16 +85,22 @@ class ZBDWallet(Wallet):
|
|||||||
error_message = r.json()["message"]
|
error_message = r.json()["message"]
|
||||||
return InvoiceResponse(False, None, None, error_message)
|
return InvoiceResponse(False, None, None, error_message)
|
||||||
|
|
||||||
data = r.json()
|
data = r.json()["data"]
|
||||||
checking_id = data["payment_hash"]
|
checking_id = data["id"] # this is a zbd id
|
||||||
payment_request = data["payment_request"]
|
payment_request = data["invoice"]["request"]
|
||||||
return InvoiceResponse(True, checking_id, payment_request, None)
|
return InvoiceResponse(True, checking_id, payment_request, None)
|
||||||
|
|
||||||
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
|
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
|
||||||
# https://api.zebedee.io/v0/payments
|
# https://api.zebedee.io/v0/payments
|
||||||
r = await self.client.post(
|
r = await self.client.post(
|
||||||
"/payments/bolt11",
|
"payments",
|
||||||
json={"invoice": bolt11}, # assume never need amount in body
|
json={
|
||||||
|
"invoice": bolt11,
|
||||||
|
"description": "",
|
||||||
|
"amount": "",
|
||||||
|
"internalId": "",
|
||||||
|
"callbackUrl": "",
|
||||||
|
},
|
||||||
timeout=None,
|
timeout=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -96,28 +109,57 @@ class ZBDWallet(Wallet):
|
|||||||
return PaymentResponse(False, None, None, None, error_message)
|
return PaymentResponse(False, None, None, None, error_message)
|
||||||
|
|
||||||
data = r.json()
|
data = r.json()
|
||||||
checking_id = data["payment_hash"]
|
|
||||||
fee_msat = -data["fee"]
|
# get the payment hash from the zbd api
|
||||||
preimage = data["payment_preimage"]
|
decoded_request = await self.client.post(
|
||||||
|
"decode-invoice",
|
||||||
|
json={"invoice": bolt11},
|
||||||
|
timeout=40,
|
||||||
|
)
|
||||||
|
if decoded_request.is_error:
|
||||||
|
error_message = decoded_request.json()["message"]
|
||||||
|
return InvoiceResponse(False, None, None, error_message)
|
||||||
|
|
||||||
|
decoded_data = decoded_request.json()
|
||||||
|
|
||||||
|
checking_id = decoded_data["data"]["paymentHash"]
|
||||||
|
fee_msat = -int(data["data"]["fee"])
|
||||||
|
preimage = data["data"]["preimage"]
|
||||||
|
|
||||||
return PaymentResponse(True, checking_id, fee_msat, preimage, None)
|
return PaymentResponse(True, checking_id, fee_msat, preimage, None)
|
||||||
|
|
||||||
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||||
return await self.get_payment_status(checking_id)
|
r = await self.client.get(f"charges/{checking_id}")
|
||||||
|
if r.is_error:
|
||||||
|
return PaymentStatus(None)
|
||||||
|
data = r.json()["data"]
|
||||||
|
|
||||||
|
statuses = {
|
||||||
|
"pending": None,
|
||||||
|
"paid": True,
|
||||||
|
"unpaid": None,
|
||||||
|
"expired": False,
|
||||||
|
"completed": True,
|
||||||
|
}
|
||||||
|
return PaymentStatus(statuses[data.get("status")])
|
||||||
|
|
||||||
async def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
async def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||||
r = await self.client.get(f"/invoices/{checking_id}")
|
r = await self.client.get(f"payments/{checking_id}")
|
||||||
|
|
||||||
if r.is_error:
|
if r.is_error:
|
||||||
return PaymentStatus(None)
|
return PaymentStatus(None)
|
||||||
|
|
||||||
data = r.json()
|
data = r.json()["data"]
|
||||||
|
|
||||||
statuses = {
|
statuses = {
|
||||||
"CREATED": None,
|
"initial": None,
|
||||||
"SETTLED": True,
|
"pending": None,
|
||||||
|
"completed": True,
|
||||||
|
"error": None,
|
||||||
|
"expired": False,
|
||||||
|
"failed": False,
|
||||||
}
|
}
|
||||||
return PaymentStatus(statuses[data.get("state")], fee_msat=None, preimage=None)
|
|
||||||
|
return PaymentStatus(statuses[data.get("status")], fee_msat=None, preimage=None)
|
||||||
|
|
||||||
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
||||||
self.queue: asyncio.Queue = asyncio.Queue(0)
|
self.queue: asyncio.Queue = asyncio.Queue(0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user