[tool.poetry]
name = "lnbits"
version = "0.12.11"
description = "LNbits, free and open-source Lightning wallet and accounts system."
authors = ["Alan Bits <alan@lnbits.com>"]
readme = "README.md"
repository = "https://github.com/lnbits/lnbits"
homepage = "https://lnbits.com"
packages = [
  {include = "lnbits"},
  {include = "lnbits/py.typed"},
]

[tool.poetry.dependencies]
python = "^3.12 | ^3.11 | ^3.10 | ^3.9"
bech32 = "1.2.0"
click = "8.1.7"
ecdsa = "0.19.0"
fastapi = "0.112.0"
httpx = "0.27.0"
jinja2 = "3.1.4"
lnurl = "0.5.3"
psycopg2-binary = "2.9.9"
pydantic = "1.10.17"
pyqrcode = "1.2.1"
shortuuid = "1.0.13"
sqlalchemy = "1.3.24"
sqlalchemy-aio = "0.17.0"
sse-starlette = "1.8.2"
typing-extensions = "4.12.2"
uvicorn = "0.30.5"
uvloop = "0.19.0"
websockets = "11.0.3"
loguru = "0.7.2"
grpcio = "1.65.5"
protobuf = "5.27.3"
pyln-client = "24.5"
pywebpush = "1.14.1"
slowapi = "0.1.9"
websocket-client = "1.8.0"
pycryptodomex = "3.20.0"
packaging = "24.0"
bolt11 = "2.1.0"
# needed for new login methods: username-password, google-auth, github-auth
bcrypt = "4.2.0"
pyjwt = "2.9.0"
passlib = "1.7.4"
itsdangerous = "2.2.0"
fastapi-sso = "0.15.0"
# needed for boltz, lnurldevice, watchonly extensions
embit = "0.8.0"
# needed for cashu, lnurlp, nostrclient, nostrmarket, nostrrelay extensions
secp256k1 = "0.14.0"
# keep for backwards compatibility with lnurlp and cashu
environs = "9.5.0"
# needed for scheduler extension
python-crontab = "3.2.0"
# needed for liquid support boltz
wallycore = {version = "1.3.0", optional = true}
# needed for breez funding source
breez-sdk = {version = "0.5.2", optional = true}

[tool.poetry.extras]
breez = ["breez-sdk"]
liquid = ["wallycore"]

[tool.poetry.group.dev.dependencies]
black = "^24.8.0"
# we are stuck with pytest-asyncio 0.21.x because of https://github.com/pytest-dev/pytest-asyncio/issues/706
pytest-asyncio = "^0.21.2"
pytest = "^8.3.2"
pytest-cov = "^4.1.0"
mypy = "^1.11.1"
types-protobuf = "^5.27.0.20240626"
pre-commit = "^3.8.0"
openapi-spec-validator = "^0.7.1"
ruff = "^0.5.7"
types-passlib = "^1.7.7.20240327"
openai = "^1.39.0"
json5 = "^0.9.25"
asgi-lifespan = "^2.1.0"
pytest-md = "^0.2.0"
pytest-httpserver = "^1.1.0"
pytest-mock = "^3.14.0"
types-mock = "^5.1.0.20240425"
mock = "^5.1.0"
grpcio-tools = "^1.65.5"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
lnbits = "lnbits.server:main"
lnbits-cli = "lnbits.commands:main"

[tool.pyright]
include = [
  "lnbits",
  "tests",
  "tools",
]
exclude = [
  "lnbits/wallets/boltz_grpc_files",
  "lnbits/wallets/lnd_grpc_files",
  "lnbits/extensions",
  "lnbits/upgrades",
]

[tool.mypy]
files = [
  "lnbits",
  "tests",
  "tools",
]
exclude = [
  "^lnbits/wallets/boltz_grpc_files",
  "^lnbits/wallets/lnd_grpc_files",
  "^lnbits/extensions",
  "^lnbits/upgrades",
]

[[tool.mypy.overrides]]
module = [
  "embit.*",
  "secp256k1.*",
  "uvicorn.*",
  "sqlalchemy.*",
  "sqlalchemy_aio.*",
  "websocket.*",
  "websockets.*",
  "pyqrcode.*",
  "shortuuid.*",
  "grpc.*",
  "lnurl.*",
  "bolt11.*",
  "bitstring.*",
  "ecdsa.*",
  "psycopg2.*",
  "pyngrok.*",
  "pyln.client.*",
  "py_vapid.*",
  "pywebpush.*",
  "fastapi_sso.sso.*",
  "json5.*",
]
ignore_missing_imports = "True"

[tool.pytest.ini_options]
log_cli = false
addopts = "--durations=1 -s --cov=lnbits --cov-report=xml"
testpaths = [
  "tests"
]

[tool.black]
line-length = 88
# use upcoming new features
# preview = true
extend-exclude = """(
    lnbits/static
    | lnbits/extensions
    | lnbits/upgrades
    | lnbits/wallets/lnd_grpc_files
    | lnbits/wallets/boltz_grpc_files
)"""

[tool.ruff]
# Same as Black. + 10% rule of black
line-length = 88

# Exclude generated files.
extend-exclude = [
    "lnbits/wallets/lnd_grpc_files",
    "lnbits/wallets/boltz_grpc_files"
]

[tool.ruff.lint]
# Enable:
# F - pyflakes
# E - pycodestyle errors
# W - pycodestyle warnings
# I - isort
# A - flake8-builtins
# C - mccabe
# N - naming
# UP - pyupgrade
# RUF - ruff specific rules
# B - bugbear
select = ["F", "E", "W", "I", "A", "C", "N", "UP", "RUF", "B"]
# UP007: pyupgrade: use X | Y instead of Optional. (python3.10)
# RUF012: mutable-class-default
ignore = ["UP007", "RUF012"]

# Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

# needed for pydantic
[tool.ruff.lint.pep8-naming]
classmethod-decorators = [
    "root_validator",
]

[tool.ruff.lint.mccabe]
# TODO: Decrease this to 10.
max-complexity = 16

[tool.ruff.lint.flake8-bugbear]
# Allow default arguments like, e.g., `data: List[str] = fastapi.Query(None)`.
extend-immutable-calls = [
    "fastapi.Depends",
    "fastapi.Query",
    "fastapi.Body",
    "lnbits.decorators.parse_filters"
]