feat: add Breez *Liquid* SDK funding source (#2681)
Co-authored-by: Pavol Rusnak <pavol@rusnak.io>
Co-authored-by: dni ⚡ <office@dnilabs.com>
Co-authored-by: Vlad Stan <stan.v.vlad@gmail.com>
This commit is contained in:
parent
09b91f9f79
commit
0529ee2835
13 changed files with 385 additions and 6 deletions
|
|
@ -153,6 +153,12 @@ BREEZ_GREENLIGHT_DEVICE_KEY="/path/to/breezsdk/device.pem" # or BASE64/HEXSTRIN
|
|||
BREEZ_GREENLIGHT_DEVICE_CERT="/path/to/breezsdk/device.crt" # or BASE64/HEXSTRING
|
||||
# BREEZ_USE_TRAMPOLINE=true
|
||||
|
||||
# BreezLiquidSdkWallet
|
||||
# get your own api key here https://breez.technology/request-api-key/#contact-us-form-sdk
|
||||
# or keep the api key empty to use the LNbits key for referrals (API key is not a secret)
|
||||
# BREEZ_LIQUID_API_KEY=""
|
||||
BREEZ_LIQUID_SEED="MNEMONIC SEED PHRASE"
|
||||
# BREEZ_LIQUID_FEE_OFFSET_SAT=50
|
||||
|
||||
# Google OAuth Config
|
||||
# Make sure that the authorized redirect URIs contain https://{domain}/api/v1/auth/google/token
|
||||
|
|
|
|||
|
|
@ -135,6 +135,18 @@ A Greenlight invite code or Greenlight partner certificate/key can be used to re
|
|||
- `BREEZ_GREENLIGHT_DEVICE_KEY`: /path/to/breezsdk/device.pem or Base64/Hex
|
||||
- `BREEZ_GREENLIGHT_DEVICE_CERT`: /path/to/breezsdk/device.crt or Base64/Hex
|
||||
|
||||
### Breez Liquid SDK
|
||||
|
||||
This funding source leverages the [Breez SDK - Liquid](https://sdk-doc-liquid.breez.technology/) to manage all Lightning payments via submarine swaps on the Liquid network. To get started, simply provide a mnemonic seed phrase. The easiest way to generate one is by using a liquid wallet, such as [Blockstream Green](https://blockstream.com/green/). Once generated, you can copy the seed to your environment variable or enter it in the admin UI.
|
||||
|
||||
- `LNBITS_BACKEND_WALLET_CLASS`: **BreezLiquidSdkWallet**
|
||||
- `BREEZ_LIQUID_SEED`: ...
|
||||
|
||||
Each submarine swap incurs service and on-chain fees. To account for these, you may need to increase the reserve fee in the admin UI by navigating to **Settings -> Funding**, or by setting the following environment variables:
|
||||
|
||||
- `LNBITS_RESERVE_FEE_MIN`: ...
|
||||
- `LNBITS_RESERVE_FEE_PERCENT`: ...
|
||||
|
||||
### Cliche Wallet
|
||||
|
||||
- `CLICHE_ENDPOINT`: ws://127.0.0.1:12000
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ async def create_payment(
|
|||
preimage=data.preimage,
|
||||
expiry=data.expiry,
|
||||
webhook=data.webhook,
|
||||
fee=data.fee,
|
||||
fee=-abs(data.fee),
|
||||
tag=extra.get("tag", None),
|
||||
extra=extra,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ async def create_invoice(
|
|||
memo=memo,
|
||||
extra=extra,
|
||||
webhook=webhook,
|
||||
fee=payment_response.fee_msat or 0,
|
||||
)
|
||||
|
||||
payment = await create_payment(
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ class FeeSettings(LNbitsSettings):
|
|||
return 0
|
||||
reserve_min = self.lnbits_reserve_fee_min
|
||||
reserve_percent = self.lnbits_reserve_fee_percent
|
||||
return max(int(reserve_min), int(amount_msat * reserve_percent / 100.0))
|
||||
return max(int(reserve_min), int(abs(amount_msat) * reserve_percent / 100.0))
|
||||
|
||||
|
||||
class ExchangeProvidersSettings(LNbitsSettings):
|
||||
|
|
@ -549,6 +549,12 @@ class BreezSdkFundingSource(LNbitsSettings):
|
|||
breez_use_trampoline: bool = Field(default=True)
|
||||
|
||||
|
||||
class BreezLiquidSdkFundingSource(LNbitsSettings):
|
||||
breez_liquid_api_key: str | None = Field(default=None)
|
||||
breez_liquid_seed: str | None = Field(default=None)
|
||||
breez_liquid_fee_offset_sat: int = Field(default=50)
|
||||
|
||||
|
||||
class BoltzFundingSource(LNbitsSettings):
|
||||
boltz_client_endpoint: str | None = Field(default="127.0.0.1:9002")
|
||||
boltz_client_macaroon: str | None = Field(default=None)
|
||||
|
|
@ -618,6 +624,7 @@ class FundingSourcesSettings(
|
|||
NWCFundingSource,
|
||||
BreezSdkFundingSource,
|
||||
StrikeFundingSource,
|
||||
BreezLiquidSdkFundingSource,
|
||||
):
|
||||
lnbits_backend_wallet_class: str = Field(default="VoidWallet")
|
||||
# How long to wait for the payment to be confirmed before returning a pending status
|
||||
|
|
@ -924,6 +931,7 @@ class SuperUserSettings(LNbitsSettings):
|
|||
"BoltzWallet",
|
||||
"BlinkWallet",
|
||||
"BreezSdkWallet",
|
||||
"BreezLiquidSdkWallet",
|
||||
"CoreLightningRestWallet",
|
||||
"CoreLightningWallet",
|
||||
"EclairWallet",
|
||||
|
|
|
|||
2
lnbits/static/bundle-components.min.js
vendored
2
lnbits/static/bundle-components.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -219,6 +219,16 @@ window.app.component('lnbits-funding-sources', {
|
|||
strike_api_endpoint: 'API Endpoint',
|
||||
strike_api_key: 'API Key'
|
||||
}
|
||||
],
|
||||
[
|
||||
'BreezLiquidSdkWallet',
|
||||
'Breez Liquid SDK',
|
||||
{
|
||||
breez_liquid_api_key: 'Breez API Key (can be empty)',
|
||||
breez_liquid_seed: 'Liquid seed phrase',
|
||||
breez_liquid_fee_offset_sat:
|
||||
'Offset amount in sats to increase fee limit'
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
|
|
|||
1
lnbits/wallets/.breez
Normal file
1
lnbits/wallets/.breez
Normal file
|
|
@ -0,0 +1 @@
|
|||
MIIBYzCCARWgAwIBAgIHPjlTc1IbAzAFBgMrZXAwEDEOMAwGA1UEAxMFQnJlZXowHhcNMjUwNzAyMDkxODMzWhcNMzUwNjMwMDkxODMzWjAfMQ8wDQYDVQQKEwZsbmJpdHMxDDAKBgNVBAMTA2RuaTAqMAUGAytlcAMhANCD9cvfIDwcoiDKKYdT9BunHLS2/OuKzV8NS0SzqV13o38wfTAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU2jmj7l5rSw0yVb/vlWAYkK/YBwkwHwYDVR0jBBgwFoAU3qrWklbzjed0khb8TLYgsmsomGswHQYDVR0RBBYwFIESb2ZmaWNlQGRuaWxhYnMuY29tMAUGAytlcANBAMGS8jEfZbfNpv6mVrg328NXnjA/nG6TuGA0aAw0NyDz499aeu/0TURjF8FzmxzmdNOiffUZ6akPWCZUKFYuGgA=
|
||||
|
|
@ -10,6 +10,7 @@ from .alby import AlbyWallet
|
|||
from .blink import BlinkWallet
|
||||
from .boltz import BoltzWallet
|
||||
from .breez import BreezSdkWallet
|
||||
from .breez_liquid import BreezLiquidSdkWallet
|
||||
from .cliche import ClicheWallet
|
||||
from .corelightning import CoreLightningWallet
|
||||
|
||||
|
|
@ -57,6 +58,7 @@ __all__ = [
|
|||
"AlbyWallet",
|
||||
"BlinkWallet",
|
||||
"BoltzWallet",
|
||||
"BreezLiquidSdkWallet",
|
||||
"BreezSdkWallet",
|
||||
"CLightningWallet",
|
||||
"ClicheWallet",
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class InvoiceResponse(NamedTuple):
|
|||
payment_request: str | None = None
|
||||
error_message: str | None = None
|
||||
preimage: str | None = None
|
||||
fee_msat: int | None = None
|
||||
|
||||
@property
|
||||
def success(self) -> bool:
|
||||
|
|
|
|||
296
lnbits/wallets/breez_liquid.py
Normal file
296
lnbits/wallets/breez_liquid.py
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
# Based on breez.py
|
||||
|
||||
try:
|
||||
import breez_sdk_liquid as breez_sdk # type: ignore
|
||||
|
||||
BREEZ_SDK_INSTALLED = True
|
||||
except ImportError:
|
||||
BREEZ_SDK_INSTALLED = False
|
||||
|
||||
if not BREEZ_SDK_INSTALLED:
|
||||
|
||||
class BreezLiquidSdkWallet: # pyright: ignore
|
||||
def __init__(self):
|
||||
raise RuntimeError(
|
||||
"Breez Liquid SDK is not installed. "
|
||||
"Ask admin to run `poetry add -E breez` to install it."
|
||||
)
|
||||
|
||||
else:
|
||||
import asyncio
|
||||
from asyncio import Queue
|
||||
from collections.abc import AsyncGenerator
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import breez_sdk_liquid as breez_sdk # type: ignore
|
||||
from bolt11 import decode as bolt11_decode
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.settings import settings
|
||||
|
||||
from .base import (
|
||||
InvoiceResponse,
|
||||
PaymentFailedStatus,
|
||||
PaymentPendingStatus,
|
||||
PaymentResponse,
|
||||
PaymentStatus,
|
||||
PaymentSuccessStatus,
|
||||
StatusResponse,
|
||||
Wallet,
|
||||
)
|
||||
|
||||
breez_incoming_queue: Queue[breez_sdk.PaymentDetails.LIGHTNING] = Queue()
|
||||
breez_outgoing_queue: dict[str, Queue[breez_sdk.PaymentDetails.LIGHTNING]] = {}
|
||||
|
||||
class PaymentsListener(breez_sdk.EventListener):
|
||||
def on_event(self, e: breez_sdk.SdkEvent) -> None:
|
||||
logger.debug(f"received breez sdk event: {e}")
|
||||
# TODO: when this issue is fixed:
|
||||
# https://github.com/breez/breez-sdk-liquid/issues/961
|
||||
# use breez_sdk.SdkEvent.PAYMENT_WAITING_CONFIRMATION
|
||||
if not isinstance(
|
||||
e, breez_sdk.SdkEvent.PAYMENT_SUCCEEDED
|
||||
) or not isinstance(e.details.details, breez_sdk.PaymentDetails.LIGHTNING):
|
||||
return
|
||||
|
||||
payment = e.details
|
||||
payment_details = e.details.details
|
||||
|
||||
if payment.payment_type is breez_sdk.PaymentType.RECEIVE:
|
||||
breez_incoming_queue.put_nowait(payment_details)
|
||||
elif (
|
||||
payment.payment_type is breez_sdk.PaymentType.SEND
|
||||
and payment_details.payment_hash in breez_outgoing_queue
|
||||
):
|
||||
breez_outgoing_queue[payment_details.payment_hash].put_nowait(
|
||||
payment_details
|
||||
)
|
||||
|
||||
class BreezLiquidSdkWallet(Wallet): # type: ignore[no-redef]
|
||||
def __init__(self):
|
||||
if not settings.breez_liquid_seed:
|
||||
raise ValueError(
|
||||
"cannot initialize BreezLiquidSdkWallet: missing breez_liquid_seed"
|
||||
)
|
||||
|
||||
if not settings.breez_liquid_api_key:
|
||||
with open(Path("lnbits/wallets", ".breez")) as f:
|
||||
settings.breez_liquid_api_key = f.read().strip()
|
||||
|
||||
self.config = breez_sdk.default_config(
|
||||
breez_sdk.LiquidNetwork.MAINNET,
|
||||
breez_api_key=settings.breez_liquid_api_key,
|
||||
)
|
||||
|
||||
breez_sdk_working_dir = Path(
|
||||
settings.lnbits_data_folder, "breez-liquid-sdk"
|
||||
)
|
||||
breez_sdk_working_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.config.working_dir = breez_sdk_working_dir.absolute().as_posix()
|
||||
|
||||
try:
|
||||
mnemonic = settings.breez_liquid_seed
|
||||
connect_request = breez_sdk.ConnectRequest(
|
||||
config=self.config, mnemonic=mnemonic
|
||||
)
|
||||
self.sdk_services = breez_sdk.connect(connect_request)
|
||||
self.sdk_services.add_event_listener(PaymentsListener())
|
||||
except Exception as exc:
|
||||
logger.warning(exc)
|
||||
raise ValueError(
|
||||
f"cannot initialize BreezLiquidSdkWallet: {exc!s}"
|
||||
) from exc
|
||||
|
||||
async def cleanup(self):
|
||||
self.sdk_services.disconnect()
|
||||
|
||||
async def status(self) -> StatusResponse:
|
||||
try:
|
||||
info: breez_sdk.GetInfoResponse = self.sdk_services.get_info()
|
||||
except Exception as exc:
|
||||
logger.warning(exc)
|
||||
return StatusResponse(f"Failed to connect to breez, got: '{exc}...'", 0)
|
||||
return StatusResponse(None, int(info.wallet_info.balance_sat * 1000))
|
||||
|
||||
async def create_invoice(
|
||||
self,
|
||||
amount: int,
|
||||
memo: Optional[str] = None,
|
||||
description_hash: Optional[bytes] = None,
|
||||
unhashed_description: Optional[bytes] = None,
|
||||
**_,
|
||||
) -> InvoiceResponse:
|
||||
try:
|
||||
# issue with breez sdk, receive_amount is of type BITCOIN
|
||||
# not ReceiveAmount after initialisation
|
||||
receive_amount = breez_sdk.ReceiveAmount.BITCOIN(amount)
|
||||
req = self.sdk_services.prepare_receive_payment(
|
||||
breez_sdk.PrepareReceiveRequest(
|
||||
payment_method=breez_sdk.PaymentMethod.BOLT11_INVOICE,
|
||||
amount=receive_amount, # type: ignore
|
||||
)
|
||||
)
|
||||
receive_fees_sats = req.fees_sat
|
||||
|
||||
description = memo or (
|
||||
unhashed_description.decode() if unhashed_description else ""
|
||||
)
|
||||
|
||||
res = self.sdk_services.receive_payment(
|
||||
breez_sdk.ReceivePaymentRequest(
|
||||
prepare_response=req,
|
||||
description=description,
|
||||
use_description_hash=description_hash is not None,
|
||||
)
|
||||
)
|
||||
|
||||
bolt11 = res.destination
|
||||
invoice_data = bolt11_decode(bolt11)
|
||||
payment_hash = invoice_data.payment_hash
|
||||
|
||||
return InvoiceResponse(
|
||||
ok=True,
|
||||
checking_id=payment_hash,
|
||||
payment_request=bolt11,
|
||||
fee_msat=receive_fees_sats * 1000,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
return InvoiceResponse(ok=False, error_message=str(e))
|
||||
|
||||
async def pay_invoice(
|
||||
self, bolt11: str, fee_limit_msat: int
|
||||
) -> PaymentResponse:
|
||||
invoice_data = bolt11_decode(bolt11)
|
||||
|
||||
try:
|
||||
prepare_req = breez_sdk.PrepareSendRequest(destination=bolt11)
|
||||
req = self.sdk_services.prepare_send_payment(prepare_req)
|
||||
|
||||
fee_limit_sat = settings.breez_liquid_fee_offset_sat + int(
|
||||
fee_limit_msat / 1000
|
||||
)
|
||||
|
||||
if req.fees_sat and req.fees_sat > fee_limit_sat:
|
||||
return PaymentResponse(
|
||||
ok=False,
|
||||
error_message=(
|
||||
f"fee of {req.fees_sat} sat exceeds limit of "
|
||||
f"{fee_limit_sat} sat"
|
||||
),
|
||||
)
|
||||
|
||||
send_response = self.sdk_services.send_payment(
|
||||
breez_sdk.SendPaymentRequest(prepare_response=req)
|
||||
)
|
||||
|
||||
except Exception as exc:
|
||||
logger.warning(exc)
|
||||
return PaymentResponse(error_message=f"Exception while payment: {exc}")
|
||||
|
||||
payment: breez_sdk.Payment = send_response.payment
|
||||
logger.debug(f"pay invoice res: {payment}")
|
||||
checking_id = invoice_data.payment_hash
|
||||
|
||||
fees = req.fees_sat * 1000 if req.fees_sat and req.fees_sat > 0 else 0
|
||||
|
||||
if payment.status != breez_sdk.PaymentState.COMPLETE:
|
||||
return await self._wait_for_outgoing_payment(checking_id, fees, 5)
|
||||
|
||||
if not isinstance(payment.details, breez_sdk.PaymentDetails.LIGHTNING):
|
||||
return PaymentResponse(
|
||||
error_message="lightning payment details are not available"
|
||||
)
|
||||
|
||||
return PaymentResponse(
|
||||
ok=True,
|
||||
checking_id=checking_id,
|
||||
fee_msat=payment.fees_sat * 1000,
|
||||
preimage=payment.details.preimage,
|
||||
)
|
||||
|
||||
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
|
||||
try:
|
||||
req = breez_sdk.GetPaymentRequest.PAYMENT_HASH(checking_id)
|
||||
payment = self.sdk_services.get_payment(req=req) # type: ignore
|
||||
if payment is None:
|
||||
return PaymentPendingStatus()
|
||||
if payment.payment_type != breez_sdk.PaymentType.RECEIVE:
|
||||
logger.warning(f"unexpected payment type: {payment.status}")
|
||||
return PaymentPendingStatus()
|
||||
if payment.status == breez_sdk.PaymentState.FAILED:
|
||||
return PaymentFailedStatus()
|
||||
if payment.status == breez_sdk.PaymentState.COMPLETE:
|
||||
return PaymentSuccessStatus(
|
||||
paid=True, fee_msat=int(payment.fees_sat * 1000)
|
||||
)
|
||||
return PaymentPendingStatus()
|
||||
except Exception as exc:
|
||||
logger.warning(exc)
|
||||
return PaymentPendingStatus()
|
||||
|
||||
async def get_payment_status(self, checking_id: str) -> PaymentStatus:
|
||||
try:
|
||||
req = breez_sdk.GetPaymentRequest.PAYMENT_HASH(checking_id)
|
||||
payment = self.sdk_services.get_payment(req=req) # type: ignore
|
||||
if payment is None:
|
||||
return PaymentPendingStatus()
|
||||
if payment.payment_type != breez_sdk.PaymentType.SEND:
|
||||
logger.warning(f"unexpected payment type: {payment.status}")
|
||||
return PaymentPendingStatus()
|
||||
if payment.status == breez_sdk.PaymentState.COMPLETE:
|
||||
if not isinstance(
|
||||
payment.details, breez_sdk.PaymentDetails.LIGHTNING
|
||||
):
|
||||
logger.warning("payment details are not of type LIGHTNING")
|
||||
return PaymentPendingStatus()
|
||||
return PaymentSuccessStatus(
|
||||
fee_msat=int(payment.fees_sat * 1000),
|
||||
preimage=payment.details.preimage,
|
||||
)
|
||||
if payment.status == breez_sdk.PaymentState.FAILED:
|
||||
return PaymentFailedStatus()
|
||||
return PaymentPendingStatus()
|
||||
except Exception as exc:
|
||||
logger.warning(exc)
|
||||
return PaymentPendingStatus()
|
||||
|
||||
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
||||
while settings.lnbits_running:
|
||||
details = await breez_incoming_queue.get()
|
||||
logger.debug(f"breez invoice paid event: {details}")
|
||||
if not details.invoice:
|
||||
logger.warning(
|
||||
"Paid invoices stream expected bolt11 invoice, got None"
|
||||
)
|
||||
continue
|
||||
|
||||
invoice_data = bolt11_decode(details.invoice)
|
||||
yield invoice_data.payment_hash
|
||||
|
||||
async def _wait_for_outgoing_payment(
|
||||
self, checking_id: str, fees: int, timeout: int
|
||||
) -> PaymentResponse:
|
||||
try:
|
||||
breez_outgoing_queue[checking_id] = Queue()
|
||||
payment_details = await asyncio.wait_for(
|
||||
breez_outgoing_queue[checking_id].get(), timeout
|
||||
)
|
||||
return PaymentResponse(
|
||||
ok=True,
|
||||
preimage=payment_details.preimage,
|
||||
checking_id=checking_id,
|
||||
fee_msat=fees,
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
logger.debug(
|
||||
f"payment '{checking_id}' is still pending after {timeout} seconds"
|
||||
)
|
||||
return PaymentResponse(
|
||||
checking_id=checking_id,
|
||||
fee_msat=fees,
|
||||
error_message="payment is pending",
|
||||
)
|
||||
finally:
|
||||
breez_outgoing_queue.pop(checking_id, None)
|
||||
45
poetry.lock
generated
45
poetry.lock
generated
|
|
@ -656,6 +656,47 @@ files = [
|
|||
{file = "breez_sdk-0.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:e51689ed2f2c2d49bdb53f0ee26d0dc2109a50f15b8f2129a250db275eb994bf"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "breez-sdk-liquid"
|
||||
version = "0.9.1"
|
||||
description = "Python language bindings for the Breez Liquid SDK"
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "extra == \"breez\""
|
||||
files = [
|
||||
{file = "breez_sdk_liquid-0.9.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:414a7c04dbf869435fe234b3b9987699c15dc2f8d4660d9ca1a51af608331b45"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp310-cp310-manylinux_2_31_aarch64.whl", hash = "sha256:7f461b6b10ddfe9cfb58119e590e5f67da4d7c93fc580a84a0116ce9fd21dffa"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:c27efe35539e4092dddbe5315f5cefffccbdd699017ed8733611d11eb52f4ce0"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp310-cp310-win32.whl", hash = "sha256:375f6322c2552d15d6ba68302a85fdc345a7671eeda8fea92c013a16c5e96505"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:f28d107099fb7caaac4051d5950a4f11bf823e11b56e797976c5fa2a7280d597"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:acefa49896bdb4ca06d351faacbf075646d574dda5539033df11310ec5a94446"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp311-cp311-manylinux_2_31_aarch64.whl", hash = "sha256:d0e54fd5c8ce542dc2061d8a1ef46e6a1d430dbaea5eab369bb91ae2c4a1be7b"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp311-cp311-manylinux_2_31_x86_64.whl", hash = "sha256:a5d1bfd4d3286d57c110d925332416b0903dda076dadede02c4b7db67576f0bf"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp311-cp311-win32.whl", hash = "sha256:3ce2152f0a2ba65f4425fd22efb8e1dafb419e5fcf3b93dfe06fc061b1d1c0c6"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:8cdb4f247bccc0f4b9bbfff4451faa78d7b17e76a9dc918804880b600f1d4249"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:c463191a89a829afcae19c94f7683dac415667755d68c212afc60d8f2b21ba63"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp312-cp312-manylinux_2_31_aarch64.whl", hash = "sha256:52efaeae2c278b498b37de1090e80f73987ee943743e69a363877ed93cd7a31e"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp312-cp312-manylinux_2_31_x86_64.whl", hash = "sha256:68aebea98990319c677bcbd7d1de258627b85063a29720879986694b9d393adb"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp312-cp312-win32.whl", hash = "sha256:f53e4a1973dfd41df3ac3ecb42cf72acb71f49d5727a8acab25668b51a953bb2"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:6adb1f3f3ccd4b743a11dcc0b307db604c3424f42e2547f94fa939f0afb9bb85"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:f94432a75bc848e597fb9859a77bab6c703d5e423d470519f37c402fc3c5d79e"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp313-cp313-manylinux_2_31_aarch64.whl", hash = "sha256:8d6838e69620162c038d513f95ffade870e112ae5c6a0d713eaa2a3a31d6f212"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp313-cp313-manylinux_2_31_x86_64.whl", hash = "sha256:d6b9a8601cef5875447e10c75ca3e1579dd1e881ec57cabe9787616b8a6de263"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp313-cp313-win32.whl", hash = "sha256:d76fc905003ac5a0cfd2132df90ba6343b40b9948164a0be06a68f15b28789a2"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:d6b0fc1d77b7855d9a72799d65cdaaa0bd07a3999d6d4d27050d8ef174ce0fd3"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d0d560657c29d7e3b054ad4be07955fc41b63d4b93a2b51b29bb85d1d52341af"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp38-cp38-manylinux_2_31_aarch64.whl", hash = "sha256:2531f788eb15bb00f4b3b505ac5b8ee3de23161dd4f65768a4aa3255ea04d68e"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp38-cp38-manylinux_2_31_x86_64.whl", hash = "sha256:f9c9f6255999cf403bc07a9deed99f8c1625a0405ae9231e3dbecb3b6af0fdc7"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp38-cp38-win32.whl", hash = "sha256:5232b25b7e8583100ec54423e7568a305cac7778736adc9f8c735798110350c7"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:67d2b894b70ba9011fc98e04ed1ade2ff18f0413b6f2a0994747e71418d004e4"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:bd77d2ce43a2c0ad77a7f22226e373034ff57677338b38e4ebe3b77eb34fa224"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp39-cp39-manylinux_2_31_aarch64.whl", hash = "sha256:14092d9d65f1b0a9009e64630614e7b8b936e9d382d0f6415f023f0b192f6b45"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp39-cp39-manylinux_2_31_x86_64.whl", hash = "sha256:5faa4d5e9a2b47899783aa0c44ac2274d32f74a7f469506af14520deabaabf9f"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp39-cp39-win32.whl", hash = "sha256:b5b2c4bae13655d108475f4f22efdc2b07283f72d99b9c6f99166d9e41e62942"},
|
||||
{file = "breez_sdk_liquid-0.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:f3ad7c65582558031451538c8a03caa3486a2d2c8906f2fbbccce84e9357d1ea"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.6.15"
|
||||
|
|
@ -4373,10 +4414,10 @@ multidict = ">=4.0"
|
|||
propcache = ">=0.2.1"
|
||||
|
||||
[extras]
|
||||
breez = ["breez-sdk"]
|
||||
breez = ["breez-sdk", "breez-sdk-liquid"]
|
||||
liquid = ["wallycore"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = "~3.12 | ~3.11 | ~3.10"
|
||||
content-hash = "434e37e5aeb0eeb1a22e12fd1914b45f27195162ef4ebc1055071fd4718d85fc"
|
||||
content-hash = "53f582a8079540033939ccd1bbd93b8ec1e8190ee26be0c0b8d64d57edb5cdac"
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ python-crontab = "3.2.0"
|
|||
wallycore = {version = "1.4.0", optional = true}
|
||||
# needed for breez funding source
|
||||
breez-sdk = {version = "0.8.0", optional = true}
|
||||
breez-sdk-liquid = {version = "0.9.1", optional = true}
|
||||
|
||||
jsonpath-ng = "^1.7.0"
|
||||
pynostr = "^0.6.2"
|
||||
|
|
@ -65,7 +66,7 @@ filetype = "^1.2.0"
|
|||
nostr-sdk = "^0.42.1"
|
||||
|
||||
[tool.poetry.extras]
|
||||
breez = ["breez-sdk"]
|
||||
breez = ["breez-sdk", "breez-sdk-liquid"]
|
||||
liquid = ["wallycore"]
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue