diff --git a/lnbits/extensions/lndhub/README.md b/lnbits/extensions/lndhub/README.md
deleted file mode 100644
index ddd2020a..00000000
--- a/lnbits/extensions/lndhub/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-
lndhub Extension
-*connect to your lnbits wallet from BlueWallet or Zeus*
-
-Lndhub has nothing to do with lnd, it is just the name of the HTTP/JSON protocol https://bluewallet.io/ uses to talk to their Lightning custodian server at https://lndhub.io/.
-
-Despite not having been planned to this, Lndhub because somewhat a standard for custodian wallet communication when https://t.me/lntxbot and https://zeusln.app/ implemented the same interface. And with this extension LNbits joins the same club.
diff --git a/lnbits/extensions/lndhub/__init__.py b/lnbits/extensions/lndhub/__init__.py
deleted file mode 100644
index 344e91c6..00000000
--- a/lnbits/extensions/lndhub/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from fastapi import APIRouter
-from starlette.staticfiles import StaticFiles
-
-from lnbits.db import Database
-from lnbits.helpers import template_renderer
-
-db = Database("ext_lndhub")
-
-lndhub_ext: APIRouter = APIRouter(prefix="/lndhub", tags=["lndhub"])
-
-lndhub_static_files = [
- {
- "path": "/lndhub/static",
- "app": StaticFiles(directory="lnbits/extensions/lndhub/static"),
- "name": "lndhub_static",
- }
-]
-
-
-def lndhub_renderer():
- return template_renderer(["lnbits/extensions/lndhub/templates"])
-
-
-from .decorators import * # noqa: F401,F403
-from .utils import * # noqa: F401,F403
-from .views import * # noqa: F401,F403
-from .views_api import * # noqa: F401,F403
diff --git a/lnbits/extensions/lndhub/config.json b/lnbits/extensions/lndhub/config.json
deleted file mode 100644
index 30a2ce59..00000000
--- a/lnbits/extensions/lndhub/config.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "name": "LndHub",
- "short_description": "Access lnbits from BlueWallet or Zeus",
- "tile": "/lndhub/static/image/lndhub.png",
- "contributors": ["fiatjaf"]
-}
diff --git a/lnbits/extensions/lndhub/decorators.py b/lnbits/extensions/lndhub/decorators.py
deleted file mode 100644
index 48118087..00000000
--- a/lnbits/extensions/lndhub/decorators.py
+++ /dev/null
@@ -1,42 +0,0 @@
-from base64 import b64decode
-
-from fastapi import Request, status
-from fastapi.param_functions import Security
-from fastapi.security.api_key import APIKeyHeader
-from starlette.exceptions import HTTPException
-
-from lnbits.decorators import WalletTypeInfo, get_key_type
-
-api_key_header_auth = APIKeyHeader(
- name="AUTHORIZATION",
- auto_error=False,
- description="Admin or Invoice key for LNDHub API's",
-)
-
-
-async def check_wallet(
- r: Request, api_key_header_auth: str = Security(api_key_header_auth)
-) -> WalletTypeInfo:
- if not api_key_header_auth:
- raise HTTPException(
- status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid auth key"
- )
-
- t = api_key_header_auth.split(" ")[1]
- _, token = b64decode(t).decode().split(":")
-
- return await get_key_type(r, api_key_header=token)
-
-
-async def require_admin_key(
- r: Request, api_key_header_auth: str = Security(api_key_header_auth)
-):
- wallet = await check_wallet(r, api_key_header_auth)
- if wallet.wallet_type != 0:
- # If wallet type is not admin then return the unauthorized status
- # This also covers when the user passes an invalid key type
- raise HTTPException(
- status_code=status.HTTP_401_UNAUTHORIZED, detail="Admin key required."
- )
- else:
- return wallet
diff --git a/lnbits/extensions/lndhub/migrations.py b/lnbits/extensions/lndhub/migrations.py
deleted file mode 100644
index d6ea5fde..00000000
--- a/lnbits/extensions/lndhub/migrations.py
+++ /dev/null
@@ -1,2 +0,0 @@
-async def migrate():
- pass
diff --git a/lnbits/extensions/lndhub/static/image/lndhub.png b/lnbits/extensions/lndhub/static/image/lndhub.png
deleted file mode 100644
index f5e95a6e..00000000
Binary files a/lnbits/extensions/lndhub/static/image/lndhub.png and /dev/null differ
diff --git a/lnbits/extensions/lndhub/templates/lndhub/_instructions.html b/lnbits/extensions/lndhub/templates/lndhub/_instructions.html
deleted file mode 100644
index a5eba8a2..00000000
--- a/lnbits/extensions/lndhub/templates/lndhub/_instructions.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
- To access an LNbits wallet from a mobile phone,
-
- -
- Install either
- Zeus or
- BlueWallet;
-
- -
- Go to
Add a wallet / Import wallet on BlueWallet or
- Settings / Add a new node on Zeus.
-
- - Select the desired wallet on this page;
- - Scan one of the two QR codes from the mobile wallet.
-
-
- -
- Invoice URLs mean the mobile wallet will only have the
- authorization to read your payments and invoices and generate new
- invoices.
-
- -
- Admin URLs mean the mobile wallet will be able to pay
- invoices..
-
-
-
-
-
-
diff --git a/lnbits/extensions/lndhub/templates/lndhub/_lndhub.html b/lnbits/extensions/lndhub/templates/lndhub/_lndhub.html
deleted file mode 100644
index 73097dbf..00000000
--- a/lnbits/extensions/lndhub/templates/lndhub/_lndhub.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- LndHub is a protocol invented by
- BlueWallet
- that allows mobile wallets to query payments and balances, generate
- invoices and make payments from accounts that exist on a server. The
- protocol is a collection of HTTP endpoints exposed through the internet.
-
-
- For a wallet that supports it, reading a QR code that contains the URL
- along with secret access credentials should enable access. Currently it
- is supported by
- Zeus and
- BlueWallet.
-
-
-
-
diff --git a/lnbits/extensions/lndhub/templates/lndhub/index.html b/lnbits/extensions/lndhub/templates/lndhub/index.html
deleted file mode 100644
index fc666da9..00000000
--- a/lnbits/extensions/lndhub/templates/lndhub/index.html
+++ /dev/null
@@ -1,94 +0,0 @@
-{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
-%} {% block page %} {% raw %}
-
-
-
-
-
-
-
- Copy LndHub {{type}} URL
-
-
-
-
-
-
-
-
-
-
-
-
-
- {% endraw %}
-
-
-
-
-
- {{SITE_TITLE}} LndHub extension
-
-
-
-
-
- {% include "lndhub/_instructions.html" %}
-
- {% include "lndhub/_lndhub.html" %}
-
-
-
-
-
-
-{% endblock %} {% block scripts %} {{ window_vars(user) }}
-
-{% endblock %}
diff --git a/lnbits/extensions/lndhub/utils.py b/lnbits/extensions/lndhub/utils.py
deleted file mode 100644
index 00865080..00000000
--- a/lnbits/extensions/lndhub/utils.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from lnbits.bolt11 import Invoice
-
-
-def to_buffer(payment_hash: str):
- return {"type": "Buffer", "data": [b for b in bytes.fromhex(payment_hash)]}
-
-
-def decoded_as_lndhub(invoice: Invoice):
- return {
- "destination": invoice.payee,
- "payment_hash": invoice.payment_hash,
- "num_satoshis": invoice.amount_msat / 1000,
- "timestamp": str(invoice.date),
- "expiry": str(invoice.expiry),
- "description": invoice.description,
- "fallback_addr": "",
- "cltv_expiry": invoice.min_final_cltv_expiry,
- "route_hints": "",
- }
diff --git a/lnbits/extensions/lndhub/views.py b/lnbits/extensions/lndhub/views.py
deleted file mode 100644
index b216f8b1..00000000
--- a/lnbits/extensions/lndhub/views.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from fastapi import Depends, Request
-
-from lnbits.core.models import User
-from lnbits.decorators import check_user_exists
-
-from . import lndhub_ext, lndhub_renderer
-
-
-@lndhub_ext.get("/")
-async def lndhub_index(request: Request, user: User = Depends(check_user_exists)):
- return lndhub_renderer().TemplateResponse(
- "lndhub/index.html", {"request": request, "user": user.dict()}
- )
diff --git a/lnbits/extensions/lndhub/views_api.py b/lnbits/extensions/lndhub/views_api.py
deleted file mode 100644
index 059604f2..00000000
--- a/lnbits/extensions/lndhub/views_api.py
+++ /dev/null
@@ -1,230 +0,0 @@
-import time
-from base64 import urlsafe_b64encode
-from http import HTTPStatus
-
-from fastapi import Depends, Query
-from pydantic import BaseModel
-from starlette.exceptions import HTTPException
-
-from lnbits import bolt11
-from lnbits.core.crud import get_payments
-from lnbits.core.services import create_invoice, pay_invoice
-from lnbits.decorators import WalletTypeInfo
-from lnbits.settings import get_wallet_class, settings
-
-from . import lndhub_ext
-from .decorators import check_wallet, require_admin_key
-from .utils import decoded_as_lndhub, to_buffer
-
-
-@lndhub_ext.get("/ext/getinfo")
-async def lndhub_getinfo():
- return {"alias": settings.lnbits_site_title}
-
-
-class AuthData(BaseModel):
- login: str = Query(None)
- password: str = Query(None)
- refresh_token: str = Query(None)
-
-
-@lndhub_ext.post("/ext/auth")
-async def lndhub_auth(data: AuthData):
- token = (
- data.refresh_token
- if data.refresh_token
- else urlsafe_b64encode((data.login + ":" + data.password).encode()).decode(
- "ascii"
- )
- )
- return {"refresh_token": token, "access_token": token}
-
-
-class AddInvoice(BaseModel):
- amt: str = Query(...)
- memo: str = Query(...)
- preimage: str = Query(None)
-
-
-@lndhub_ext.post("/ext/addinvoice")
-async def lndhub_addinvoice(
- data: AddInvoice, wallet: WalletTypeInfo = Depends(check_wallet)
-):
- try:
- _, pr = await create_invoice(
- wallet_id=wallet.wallet.id,
- amount=int(data.amt),
- memo=data.memo or settings.lnbits_site_title,
- extra={"tag": "lndhub"},
- )
- except:
- raise HTTPException(
- status_code=HTTPStatus.NOT_FOUND, detail="Failed to create invoice"
- )
- invoice = bolt11.decode(pr)
- return {
- "pay_req": pr,
- "payment_request": pr,
- "add_index": "500",
- "r_hash": to_buffer(invoice.payment_hash),
- "hash": invoice.payment_hash,
- }
-
-
-class CreateInvoice(BaseModel):
- invoice: str = Query(...)
-
-
-@lndhub_ext.post("/ext/payinvoice")
-async def lndhub_payinvoice(
- r_invoice: CreateInvoice, wallet: WalletTypeInfo = Depends(require_admin_key)
-):
- try:
- await pay_invoice(
- wallet_id=wallet.wallet.id,
- payment_request=r_invoice.invoice,
- extra={"tag": "lndhub"},
- )
- except:
- raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Payment failed")
-
- invoice: bolt11.Invoice = bolt11.decode(r_invoice.invoice)
-
- return {
- "payment_error": "",
- "payment_preimage": "0" * 64,
- "route": {},
- "payment_hash": invoice.payment_hash,
- "decoded": decoded_as_lndhub(invoice),
- "fee_msat": 0,
- "type": "paid_invoice",
- "fee": 0,
- "value": invoice.amount_msat / 1000,
- "timestamp": int(time.time()),
- "memo": invoice.description,
- }
-
-
-@lndhub_ext.get("/ext/balance")
-async def lndhub_balance(
- wallet: WalletTypeInfo = Depends(check_wallet),
-):
- return {"BTC": {"AvailableBalance": wallet.wallet.balance}}
-
-
-@lndhub_ext.get("/ext/gettxs")
-async def lndhub_gettxs(
- wallet: WalletTypeInfo = Depends(check_wallet),
- limit: int = Query(20, ge=1, le=20),
- offset: int = Query(0, ge=0),
-):
- for payment in await get_payments(
- wallet_id=wallet.wallet.id,
- complete=False,
- pending=True,
- outgoing=True,
- incoming=False,
- limit=limit,
- offset=offset,
- exclude_uncheckable=True,
- ):
- await payment.check_status()
-
- return [
- {
- "payment_preimage": payment.preimage,
- "payment_hash": payment.payment_hash,
- "fee_msat": payment.fee * 1000,
- "type": "paid_invoice",
- "fee": payment.fee,
- "value": int(payment.amount / 1000),
- "timestamp": payment.time,
- "memo": payment.memo if not payment.pending else "Payment in transition",
- }
- for payment in reversed(
- (
- await get_payments(
- wallet_id=wallet.wallet.id,
- pending=True,
- complete=True,
- outgoing=True,
- incoming=False,
- limit=limit,
- offset=offset,
- )
- )
- )
- ]
-
-
-@lndhub_ext.get("/ext/getuserinvoices")
-async def lndhub_getuserinvoices(
- wallet: WalletTypeInfo = Depends(check_wallet),
- limit: int = Query(20, ge=1, le=20),
- offset: int = Query(0, ge=0),
-):
- WALLET = get_wallet_class()
- for invoice in await get_payments(
- wallet_id=wallet.wallet.id,
- complete=False,
- pending=True,
- outgoing=False,
- incoming=True,
- limit=limit,
- offset=offset,
- exclude_uncheckable=True,
- ):
- await invoice.set_pending(
- (await WALLET.get_invoice_status(invoice.checking_id)).pending
- )
-
- return [
- {
- "r_hash": to_buffer(invoice.payment_hash),
- "payment_request": invoice.bolt11,
- "add_index": "500",
- "description": invoice.memo,
- "payment_hash": invoice.payment_hash,
- "ispaid": not invoice.pending,
- "amt": int(invoice.amount / 1000),
- "expire_time": int(time.time() + 1800),
- "timestamp": invoice.time,
- "type": "user_invoice",
- }
- for invoice in reversed(
- (
- await get_payments(
- wallet_id=wallet.wallet.id,
- pending=True,
- complete=True,
- incoming=True,
- outgoing=False,
- limit=limit,
- offset=offset,
- )
- )
- )
- ]
-
-
-@lndhub_ext.get("/ext/getbtc")
-async def lndhub_getbtc(wallet: WalletTypeInfo = Depends(check_wallet)):
- "load an address for incoming onchain btc"
- return []
-
-
-@lndhub_ext.get("/ext/getpending")
-async def lndhub_getpending(wallet: WalletTypeInfo = Depends(check_wallet)):
- "pending onchain transactions"
- return []
-
-
-@lndhub_ext.get("/ext/decodeinvoice")
-async def lndhub_decodeinvoice(invoice: str = Query(None)):
- inv = bolt11.decode(invoice)
- return decoded_as_lndhub(inv)
-
-
-@lndhub_ext.get("/ext/checkrouteinvoice")
-async def lndhub_checkrouteinvoice():
- "not implemented on canonical lndhub"