diff --git a/.env.example b/.env.example
index dd85b655c..4b7cfabfe 100644
--- a/.env.example
+++ b/.env.example
@@ -111,10 +111,6 @@ LNPAY_API_KEY=LNPAY_API_KEY
# Wallet Admin in Wallet Access Keys
LNPAY_WALLET_KEY=LNPAY_ADMIN_KEY
-# LntxbotWallet
-LNTXBOT_API_ENDPOINT=https://lntxbot.com/
-LNTXBOT_KEY=LNTXBOT_ADMIN_KEY
-
# OpenNodeWallet
OPENNODE_API_ENDPOINT=https://api.opennode.com/
OPENNODE_KEY=OPENNODE_ADMIN_KEY
diff --git a/README.md b/README.md
index 0f81b99f2..4727cad49 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ LNbits is a Python server that sits on top of any funding source. It can be used
* Fallback wallet for the LNURL scheme
* Instant wallet for LN demonstrations
-LNbits can run on top of any Lightning funding source. It supports LND, CLN, Eclair, Spark, LNpay, OpenNode, lntxbot, LightningTipBot, and with more being added regularly.
+LNbits can run on top of any Lightning funding source. It supports LND, CLN, Eclair, Spark, LNpay, OpenNode, LightningTipBot, and with more being added regularly.
See [docs.lnbits.org](https://docs.lnbits.org) for more detailed documentation.
diff --git a/docs/guide/wallets.md b/docs/guide/wallets.md
index 10724f34b..a10e09a9a 100644
--- a/docs/guide/wallets.md
+++ b/docs/guide/wallets.md
@@ -8,7 +8,7 @@ nav_order: 3
Backend wallets
===============
-LNbits can run on top of many lightning-network funding sources. Currently there is support for CoreLightning, LND, LNbits, LNPay, lntxbot and OpenNode, with more being added regularly.
+LNbits can run on top of many lightning-network funding sources. Currently there is support for CoreLightning, LND, LNbits, LNPay and OpenNode, with more being added regularly.
A backend wallet can be configured using the following LNbits environment variables:
@@ -65,13 +65,6 @@ For the invoice listener to work you have a publicly accessible URL in your LNbi
- `LNPAY_WALLET_KEY`: waka_apiKey
-### lntxbot
-
-- `LNBITS_BACKEND_WALLET_CLASS`: **LntxbotWallet**
-- `LNTXBOT_API_ENDPOINT`: https://lntxbot.com/
-- `LNTXBOT_KEY`: lntxbotAdminApiKey
-
-
### OpenNode
For the invoice to work you must have a publicly accessible URL in your LNbits. No manual webhook setting is necessary.
diff --git a/lnbits/core/templates/core/index.html b/lnbits/core/templates/core/index.html
index 104dccd94..e23f5ca44 100644
--- a/lnbits/core/templates/core/index.html
+++ b/lnbits/core/templates/core/index.html
@@ -43,7 +43,7 @@
Easy to set up and lightweight, LNbits can run on any
lightning-network funding source, currently supporting LND,
- c-lightning, OpenNode, lntxbot, LNPay and even LNbits itself!
+ c-lightning, OpenNode, LNPay and even LNbits itself!
You can run LNbits for yourself, or easily offer a custodian
@@ -135,24 +135,6 @@
-
+
{% if AD_SPACE %} {% for ADS in AD_SPACE %} {% set AD = ADS.split(';') %}
diff --git a/lnbits/settings.py b/lnbits/settings.py
index 0f1036825..3934c18e2 100644
--- a/lnbits/settings.py
+++ b/lnbits/settings.py
@@ -147,11 +147,6 @@ class LnPayFundingSource(LNbitsSettings):
lnpay_wallet_key: Optional[str] = Field(default=None)
-class LnTxtBotFundingSource(LNbitsSettings):
- lntxbot_api_endpoint: Optional[str] = Field(default=None)
- lntxbot_key: Optional[str] = Field(default=None)
-
-
class OpenNodeFundingSource(LNbitsSettings):
opennode_api_endpoint: Optional[str] = Field(default=None)
opennode_key: Optional[str] = Field(default=None)
diff --git a/lnbits/wallets/__init__.py b/lnbits/wallets/__init__.py
index 76c47c048..c16fb42e3 100644
--- a/lnbits/wallets/__init__.py
+++ b/lnbits/wallets/__init__.py
@@ -11,7 +11,6 @@ from .lndgrpc import LndWallet
from .lndrest import LndRestWallet
from .lnpay import LNPayWallet
from .lntips import LnTipsWallet
-from .lntxbot import LntxbotWallet
from .opennode import OpenNodeWallet
from .spark import SparkWallet
from .void import VoidWallet
diff --git a/lnbits/wallets/lntxbot.py b/lnbits/wallets/lntxbot.py
deleted file mode 100644
index a1e41bd22..000000000
--- a/lnbits/wallets/lntxbot.py
+++ /dev/null
@@ -1,156 +0,0 @@
-import asyncio
-import hashlib
-import json
-from typing import AsyncGenerator, Dict, Optional
-
-import httpx
-from loguru import logger
-
-from lnbits.settings import settings
-
-from .base import (
- InvoiceResponse,
- PaymentResponse,
- PaymentStatus,
- StatusResponse,
- Wallet,
-)
-
-
-class LntxbotWallet(Wallet):
- """https://github.com/fiatjaf/lntxbot/blob/master/api.go"""
-
- def __init__(self):
- endpoint = settings.lntxbot_api_endpoint
- self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
-
- key = (
- settings.lntxbot_key
- or settings.lntxbot_admin_key
- or settings.lntxbot_invoice_key
- )
- self.auth = {"Authorization": f"Basic {key}"}
-
- async def status(self) -> StatusResponse:
- async with httpx.AsyncClient() as client:
- r = await client.get(
- f"{self.endpoint}/balance", headers=self.auth, timeout=40
- )
- try:
- data = r.json()
- except:
- return StatusResponse(
- f"Failed to connect to {self.endpoint}, got: '{r.text[:200]}...'", 0
- )
-
- if data.get("error"):
- return StatusResponse(data["message"], 0)
-
- return StatusResponse(None, data["BTC"]["AvailableBalance"] * 1000)
-
- async def create_invoice(
- self,
- amount: int,
- memo: Optional[str] = None,
- description_hash: Optional[bytes] = None,
- unhashed_description: Optional[bytes] = None,
- **kwargs,
- ) -> InvoiceResponse:
- data: Dict = {"amt": str(amount)}
- if description_hash:
- data["description_hash"] = description_hash.hex()
- elif unhashed_description:
- data["description_hash"] = hashlib.sha256(unhashed_description).hexdigest()
- else:
- data["memo"] = memo or ""
-
- async with httpx.AsyncClient() as client:
- r = await client.post(
- f"{self.endpoint}/addinvoice", headers=self.auth, json=data, timeout=40
- )
-
- if r.is_error:
- try:
- data = r.json()
- error_message = data["message"]
- except:
- error_message = r.text
-
- return InvoiceResponse(False, None, None, error_message)
-
- data = r.json()
- return InvoiceResponse(True, data["payment_hash"], data["pay_req"], None)
-
- async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
- async with httpx.AsyncClient() as client:
- r = await client.post(
- f"{self.endpoint}/payinvoice",
- headers=self.auth,
- json={"invoice": bolt11},
- timeout=None,
- )
-
- if "error" in r.json():
- try:
- data = r.json()
- error_message = data["message"]
- except:
- error_message = r.text
- return PaymentResponse(False, None, None, None, error_message)
-
- data = r.json()
- if data.get("type") != "paid_invoice":
- return PaymentResponse(None)
- checking_id = data["payment_hash"]
- fee_msat = -data["fee_msat"]
- preimage = data["payment_preimage"]
- return PaymentResponse(True, checking_id, fee_msat, preimage, None)
-
- async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
- async with httpx.AsyncClient() as client:
- r = await client.post(
- 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)
-
- return PaymentStatus(True)
-
- async def get_payment_status(self, checking_id: str) -> PaymentStatus:
- async with httpx.AsyncClient() as client:
- r = await client.post(
- url=f"{self.endpoint}/paymentstatus/{checking_id}", headers=self.auth
- )
-
- 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[data.get("status", "unknown")])
-
- async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
- url = f"{self.endpoint}/payments/stream"
-
- while True:
- try:
- async with httpx.AsyncClient(timeout=None, headers=self.auth) as client:
- async with client.stream("GET", url) as r:
- async for line in r.aiter_lines():
- if line.startswith("data:"):
- data = json.loads(line[5:])
- if "payment_hash" in data and data.get("msatoshi") > 0:
- yield data["payment_hash"]
- except (OSError, httpx.ReadError, httpx.ReadTimeout, httpx.ConnectError):
- pass
-
- logger.error(
- "lost connection to lntxbot /payments/stream, retrying in 5 seconds"
- )
- await asyncio.sleep(5)