Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8c5e5d685 | ||
|
|
cf4a1daba4 | ||
|
|
1947030a4e | ||
|
|
24fa921258 | ||
|
|
51279d6738 | ||
|
|
24a2719e0e | ||
|
|
e4f6b0a50c | ||
|
|
5ed3e0a175 | ||
|
|
858ff9d186 | ||
|
|
cd7fcd1c71 | ||
|
|
9f60b14745 | ||
|
|
a838777d99 | ||
|
|
356e651675 | ||
|
|
5826e2cc2b | ||
|
|
499cfa002e | ||
|
|
835f56cee6 | ||
|
|
08ea83c28e | ||
|
|
a0646142e4 | ||
|
|
42e1f932ac | ||
|
|
c3169e4dcc |
+2
-2
@@ -226,12 +226,12 @@ LNBITS_HIDE_API=false
|
||||
LNBITS_EXTENSIONS_DEFAULT_INSTALL="tpos"
|
||||
|
||||
# Database: to use SQLite, specify LNBITS_DATA_FOLDER
|
||||
# to use PostgreSQL, specify LNBITS_DATABASE_URL=postgres://...
|
||||
# to use PostgreSQL, specify LNBITS_DATABASE_URL=postgresql+asyncpg://...
|
||||
# to use CockroachDB, specify LNBITS_DATABASE_URL=cockroachdb://...
|
||||
# for both PostgreSQL and CockroachDB, you'll need to install
|
||||
# psycopg2 as an additional dependency
|
||||
LNBITS_DATA_FOLDER="./data"
|
||||
# LNBITS_DATABASE_URL="postgres://user:password@host:port/databasename"
|
||||
# LNBITS_DATABASE_URL="postgresql+asyncpg://user:password@host:port/databasename"
|
||||
|
||||
# the service fee (in percent)
|
||||
LNBITS_SERVICE_FEE=0.0
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.9", "3.10"]
|
||||
db-url: ["", "postgres://lnbits:lnbits@0.0.0.0:5432/lnbits"]
|
||||
db-url: ["", "postgresql+asyncpg://lnbits:lnbits@0.0.0.0:5432/lnbits"]
|
||||
uses: ./.github/workflows/tests.yml
|
||||
with:
|
||||
custom-pytest: "poetry run pytest tests/api"
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.9", "3.10"]
|
||||
db-url: ["", "postgres://lnbits:lnbits@0.0.0.0:5432/lnbits"]
|
||||
db-url: ["", "postgresql+asyncpg://lnbits:lnbits@0.0.0.0:5432/lnbits"]
|
||||
uses: ./.github/workflows/tests.yml
|
||||
with:
|
||||
custom-pytest: "poetry run pytest tests/wallets"
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.9", "3.10"]
|
||||
db-url: ["", "postgres://lnbits:lnbits@0.0.0.0:5432/lnbits"]
|
||||
db-url: ["", "postgresql+asyncpg://lnbits:lnbits@0.0.0.0:5432/lnbits"]
|
||||
uses: ./.github/workflows/tests.yml
|
||||
with:
|
||||
custom-pytest: "poetry run pytest tests/unit"
|
||||
|
||||
+2
-3
@@ -35,7 +35,6 @@ __bundle__
|
||||
coverage.xml
|
||||
node_modules
|
||||
lnbits/static/bundle.js
|
||||
lnbits/static/bundle-components.js
|
||||
lnbits/static/bundle.css
|
||||
lnbits/static/bundle.min.js.old
|
||||
lnbits/static/bundle.min.css.old
|
||||
@@ -50,8 +49,8 @@ fly.toml
|
||||
lnbits-backup.zip
|
||||
|
||||
# Ignore extensions (post installable extension PR)
|
||||
/lnbits/extensions
|
||||
/upgrades/
|
||||
extensions
|
||||
upgrades/
|
||||
|
||||
# builded python package
|
||||
dist
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
**/lnbits/static/vendor
|
||||
**/lnbits/static/bundle.*
|
||||
**/lnbits/static/bundle-components.*
|
||||
**/lnbits/static/css/*
|
||||
|
||||
flake.lock
|
||||
|
||||
@@ -74,10 +74,10 @@ test-migration:
|
||||
timeout 5s poetry run lnbits --host 0.0.0.0 --port 5002 || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; fi
|
||||
HOST=0.0.0.0 \
|
||||
PORT=5002 \
|
||||
LNBITS_DATABASE_URL="postgres://lnbits:lnbits@localhost:5432/migration" \
|
||||
LNBITS_DATABASE_URL="postgresql+asyncpg://lnbits:lnbits@localhost:5432/migration" \
|
||||
timeout 5s poetry run lnbits --host 0.0.0.0 --port 5002 || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; fi
|
||||
LNBITS_DATA_FOLDER="./tests/data" \
|
||||
LNBITS_DATABASE_URL="postgres://lnbits:lnbits@localhost:5432/migration" \
|
||||
LNBITS_DATABASE_URL="postgresql+asyncpg://lnbits:lnbits@localhost:5432/migration" \
|
||||
poetry run python tools/conv.py
|
||||
|
||||
migration:
|
||||
@@ -103,21 +103,24 @@ sass:
|
||||
|
||||
bundle:
|
||||
npm install
|
||||
npm run bundle
|
||||
npm run sass
|
||||
npm run vendor_copy
|
||||
npm run vendor_json
|
||||
poetry run ./node_modules/.bin/prettier -w ./lnbits/static/vendor.json
|
||||
npm run vendor_bundle_css
|
||||
npm run vendor_minify_css
|
||||
npm run vendor_bundle_js
|
||||
npm run vendor_minify_js
|
||||
|
||||
checkbundle:
|
||||
cp lnbits/static/bundle.min.js lnbits/static/bundle.min.js.old
|
||||
cp lnbits/static/bundle.min.css lnbits/static/bundle.min.css.old
|
||||
cp lnbits/static/bundle-components.min.js lnbits/static/bundle-components.min.js.old
|
||||
make bundle
|
||||
diff -q lnbits/static/bundle.min.js lnbits/static/bundle.min.js.old || exit 1
|
||||
diff -q lnbits/static/bundle.min.css lnbits/static/bundle.min.css.old || exit 1
|
||||
diff -q lnbits/static/bundle-components.min.js lnbits/static/bundle-components.min.js.old || exit 1
|
||||
@echo "Bundle is OK"
|
||||
rm lnbits/static/bundle.min.js.old
|
||||
rm lnbits/static/bundle.min.css.old
|
||||
rm lnbits/static/bundle-components.min.js.old
|
||||
|
||||
install-pre-commit-hook:
|
||||
@echo "Installing pre-commit hook to git"
|
||||
|
||||
+17
-20
@@ -10,17 +10,22 @@ The following sections explain how to install LNbits using varions package manag
|
||||
|
||||
Note that by default LNbits uses SQLite as its database, which is simple and effective but you can configure it to use PostgreSQL instead which is also described in a section below.
|
||||
|
||||
## Option 1 (recommended): Poetry
|
||||
## Option 1 (recommended): poetry
|
||||
|
||||
It is recommended to use the latest version of Poetry. Make sure you have Python version 3.9 or higher installed.
|
||||
Mininum poetry version has is ^1.2, but it is recommended to use latest poetry. (including OSX)
|
||||
Make sure you have Python 3.9 or 3.10 installed.
|
||||
|
||||
### Verify Python version
|
||||
### install python on ubuntu
|
||||
|
||||
```sh
|
||||
python3 --version
|
||||
# for making sure python 3.9 is installed, skip if installed. To check your installed version: python3 --version
|
||||
sudo apt update
|
||||
sudo apt install software-properties-common
|
||||
sudo add-apt-repository ppa:deadsnakes/ppa
|
||||
sudo apt install python3.9 python3.9-distutils
|
||||
```
|
||||
|
||||
### Install Poetry
|
||||
### install poetry
|
||||
|
||||
```sh
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
@@ -33,6 +38,10 @@ git clone https://github.com/lnbits/lnbits.git
|
||||
cd lnbits
|
||||
git checkout main
|
||||
|
||||
# Next command, you can exchange with python3.10 or newer versions.
|
||||
# Identify your version with python3 --version and specify in the next line
|
||||
# command is only needed when your default python is not ^3.9 or ^3.10
|
||||
poetry env use python3.9
|
||||
poetry install --only main
|
||||
|
||||
cp .env.example .env
|
||||
@@ -60,19 +69,7 @@ poetry install --only main
|
||||
# Start LNbits with `poetry run lnbits`
|
||||
```
|
||||
|
||||
## Option 2: Install script (on Debian/Ubuntu)
|
||||
|
||||
```sh
|
||||
wget https://raw.githubusercontent.com/lnbits/lnbits/main/lnbits.sh &&
|
||||
chmod +x lnbits.sh &&
|
||||
./lnbits.sh
|
||||
```
|
||||
|
||||
Now visit `0.0.0.0:5000` to make a super-user account.
|
||||
|
||||
`export PATH="/home/$USER/.local/bin:$PATH"` then `./lnbits.sh` can be used to run, but for more control `cd lnbits` and use `poetry run lnbits` (see previous option).
|
||||
|
||||
## Option 3: Nix
|
||||
## Option 2: Nix
|
||||
|
||||
```sh
|
||||
# Install nix. If you have installed via another manager, remove and use this install (from https://nixos.org/download)
|
||||
@@ -110,7 +107,7 @@ LNBITS_ADMIN_UI=true ./result/bin/lnbits --port 9000
|
||||
SUPER_USER=be54db7f245346c8833eaa430e1e0405 LNBITS_ADMIN_UI=true ./result/bin/lnbits --port 9000
|
||||
```
|
||||
|
||||
## Option 4: Docker
|
||||
## Option 3: Docker
|
||||
|
||||
use latest version from docker hub
|
||||
|
||||
@@ -132,7 +129,7 @@ mkdir data
|
||||
docker run --detach --publish 5000:5000 --name lnbits --volume ${PWD}/.env:/app/.env --volume ${PWD}/data/:/app/data lnbits/lnbits
|
||||
```
|
||||
|
||||
## Option 5: Fly.io
|
||||
## Option 4: Fly.io
|
||||
|
||||
Fly.io is a docker container hosting platform that has a generous free tier. You can host LNbits for free on Fly.io for personal use.
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
meta.rev = self.dirtyRev or self.rev;
|
||||
meta.mainProgram = projectName;
|
||||
overrides = pkgs.poetry2nix.overrides.withDefaults (final: prev: {
|
||||
coincurve = prev.coincurve.override { preferWheel = true; };
|
||||
protobuf = prev.protobuf.override { preferWheel = true; };
|
||||
ruff = prev.ruff.override { preferWheel = true; };
|
||||
wallycore = prev.wallycore.override { preferWheel = true; };
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check install has not already run
|
||||
if [ ! -d lnbits/data ]; then
|
||||
|
||||
# Update package list and install prerequisites non-interactively
|
||||
sudo apt update -y
|
||||
sudo apt install -y software-properties-common
|
||||
|
||||
# Add the deadsnakes PPA repository non-interactively
|
||||
sudo add-apt-repository -y ppa:deadsnakes/ppa
|
||||
|
||||
# Install Python 3.9 and distutils non-interactively
|
||||
sudo apt install -y python3.9 python3.9-distutils
|
||||
|
||||
# Install Poetry
|
||||
curl -sSL https://install.python-poetry.org | python3.9 -
|
||||
|
||||
# Add Poetry to PATH for the current session
|
||||
export PATH="/home/$USER/.local/bin:$PATH"
|
||||
|
||||
if [ ! -d lnbits/wallets ]; then
|
||||
# Clone the LNbits repository
|
||||
git clone https://github.com/lnbits/lnbits.git
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to clone the repository ... FAIL"
|
||||
exit 1
|
||||
fi
|
||||
# Ensure we are in the lnbits directory
|
||||
cd lnbits || { echo "Failed to cd into lnbits ... FAIL"; exit 1; }
|
||||
fi
|
||||
|
||||
git checkout main
|
||||
# Make data folder
|
||||
mkdir data
|
||||
|
||||
# Copy the .env.example to .env
|
||||
cp .env.example .env
|
||||
|
||||
elif [ ! -d lnbits/wallets ]; then
|
||||
# cd into lnbits
|
||||
cd lnbits || { echo "Failed to cd into lnbits ... FAIL"; exit 1; }
|
||||
fi
|
||||
|
||||
# Set path for running after install
|
||||
export PATH="/home/$USER/.local/bin:$PATH"
|
||||
|
||||
# Install the dependencies using Poetry
|
||||
poetry env use python3.9
|
||||
poetry install --only main
|
||||
|
||||
# Set environment variables for LNbits
|
||||
export LNBITS_ADMIN_UI=true
|
||||
export HOST=0.0.0.0
|
||||
|
||||
# Run LNbits
|
||||
poetry run lnbits
|
||||
+18
-13
@@ -17,13 +17,10 @@ from slowapi.util import get_remote_address
|
||||
from starlette.middleware.sessions import SessionMiddleware
|
||||
|
||||
from lnbits.core.crud import (
|
||||
add_installed_extension,
|
||||
get_dbversions,
|
||||
get_installed_extensions,
|
||||
update_installed_extension_state,
|
||||
)
|
||||
from lnbits.core.extensions.extension_manager import deactivate_extension
|
||||
from lnbits.core.extensions.helpers import version_parse
|
||||
from lnbits.core.helpers import migrate_extension_database
|
||||
from lnbits.core.tasks import ( # watchdog_task
|
||||
killswitch_task,
|
||||
@@ -47,8 +44,14 @@ from lnbits.wallets import get_funding_source, set_funding_source
|
||||
from .commands import migrate_databases
|
||||
from .core import init_core_routers
|
||||
from .core.db import core_app_extra
|
||||
from .core.extensions.models import Extension, InstallableExtension
|
||||
from .core.services import check_admin_settings, check_webpush_settings
|
||||
from .core.views.extension_api import add_installed_extension
|
||||
from .extension_manager import (
|
||||
Extension,
|
||||
InstallableExtension,
|
||||
get_valid_extensions,
|
||||
version_parse,
|
||||
)
|
||||
from .middleware import (
|
||||
CustomGZipMiddleware,
|
||||
ExtensionsRedirectMiddleware,
|
||||
@@ -240,7 +243,6 @@ async def check_installed_extensions(app: FastAPI):
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
await deactivate_extension(ext.id)
|
||||
logger.warning(
|
||||
f"Failed to re-install extension: {ext.id} ({ext.installed_version})"
|
||||
)
|
||||
@@ -315,6 +317,7 @@ async def restore_installed_extension(app: FastAPI, ext: InstallableExtension):
|
||||
|
||||
# mount routes for the new version
|
||||
core_app_extra.register_new_ext_routes(extension)
|
||||
ext.notify_upgrade(extension.upgrade_hash)
|
||||
|
||||
|
||||
def register_custom_extensions_path():
|
||||
@@ -377,22 +380,24 @@ def register_ext_routes(app: FastAPI, ext: Extension) -> None:
|
||||
)
|
||||
app.mount(s["path"], StaticFiles(directory=static_dir), s["name"])
|
||||
|
||||
ext_redirects = (
|
||||
getattr(ext_module, f"{ext.code}_redirect_paths")
|
||||
if hasattr(ext_module, f"{ext.code}_redirect_paths")
|
||||
else []
|
||||
)
|
||||
if hasattr(ext_module, f"{ext.code}_redirect_paths"):
|
||||
ext_redirects = getattr(ext_module, f"{ext.code}_redirect_paths")
|
||||
settings.lnbits_extensions_redirects = [
|
||||
r for r in settings.lnbits_extensions_redirects if r["ext_id"] != ext.code
|
||||
]
|
||||
for r in ext_redirects:
|
||||
r["ext_id"] = ext.code
|
||||
settings.lnbits_extensions_redirects.append(r)
|
||||
|
||||
settings.activate_extension_paths(ext.code, ext.upgrade_hash, ext_redirects)
|
||||
logger.trace(f"adding route for extension {ext_module}")
|
||||
|
||||
logger.trace(f"Adding route for extension {ext_module}.")
|
||||
prefix = f"/upgrades/{ext.upgrade_hash}" if ext.upgrade_hash != "" else ""
|
||||
app.include_router(router=ext_route, prefix=prefix)
|
||||
|
||||
|
||||
async def check_and_register_extensions(app: FastAPI):
|
||||
await check_installed_extensions(app)
|
||||
for ext in Extension.get_valid_extensions(False):
|
||||
for ext in get_valid_extensions(False):
|
||||
try:
|
||||
register_ext_routes(app, ext)
|
||||
except Exception as exc:
|
||||
|
||||
+8
-8
@@ -25,18 +25,18 @@ from lnbits.core.crud import (
|
||||
remove_deleted_wallets,
|
||||
update_payment_status,
|
||||
)
|
||||
from lnbits.core.extensions.models import (
|
||||
CreateExtension,
|
||||
ExtensionRelease,
|
||||
InstallableExtension,
|
||||
)
|
||||
from lnbits.core.helpers import migrate_databases
|
||||
from lnbits.core.models import Payment, PaymentState
|
||||
from lnbits.core.models import Payment, PaymentState, User
|
||||
from lnbits.core.services import check_admin_settings
|
||||
from lnbits.core.views.extension_api import (
|
||||
api_install_extension,
|
||||
api_uninstall_extension,
|
||||
)
|
||||
from lnbits.extension_manager import (
|
||||
CreateExtension,
|
||||
ExtensionRelease,
|
||||
InstallableExtension,
|
||||
)
|
||||
from lnbits.settings import settings
|
||||
from lnbits.wallets.base import Wallet
|
||||
|
||||
@@ -611,7 +611,7 @@ async def _call_install_extension(
|
||||
)
|
||||
resp.raise_for_status()
|
||||
else:
|
||||
await api_install_extension(data)
|
||||
await api_install_extension(data, User(id="mock_id"))
|
||||
|
||||
|
||||
async def _call_uninstall_extension(
|
||||
@@ -625,7 +625,7 @@ async def _call_uninstall_extension(
|
||||
)
|
||||
resp.raise_for_status()
|
||||
else:
|
||||
await api_uninstall_extension(extension)
|
||||
await api_uninstall_extension(extension, User(id="mock_id"))
|
||||
|
||||
|
||||
async def _can_run_operation(url) -> bool:
|
||||
|
||||
+41
-28
@@ -1,20 +1,21 @@
|
||||
import datetime
|
||||
import json
|
||||
from time import time
|
||||
from typing import Literal, Optional
|
||||
from typing import Dict, List, Literal, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
import shortuuid
|
||||
from passlib.context import CryptContext
|
||||
|
||||
from lnbits.core.db import db
|
||||
from lnbits.core.extensions.models import (
|
||||
from lnbits.core.models import PaymentState
|
||||
from lnbits.db import DB_TYPE, SQLITE, Connection, Database, Filters, Page
|
||||
from lnbits.extension_manager import (
|
||||
InstallableExtension,
|
||||
PayToEnableInfo,
|
||||
UserExtension,
|
||||
UserExtensionInfo,
|
||||
)
|
||||
from lnbits.core.models import PaymentState
|
||||
from lnbits.db import DB_TYPE, SQLITE, Connection, Database, Filters, Page
|
||||
from lnbits.settings import (
|
||||
AdminSettings,
|
||||
EditableSettings,
|
||||
@@ -26,7 +27,6 @@ from lnbits.settings import (
|
||||
from .models import (
|
||||
Account,
|
||||
AccountFilters,
|
||||
CreatePayment,
|
||||
Payment,
|
||||
PaymentFilters,
|
||||
PaymentHistoryPoint,
|
||||
@@ -38,6 +38,9 @@ from .models import (
|
||||
WebPushSubscription,
|
||||
)
|
||||
|
||||
# accounts
|
||||
# --------
|
||||
|
||||
|
||||
async def create_account(
|
||||
user_id: Optional[str] = None,
|
||||
@@ -427,7 +430,7 @@ async def get_installed_extension(
|
||||
async def get_installed_extensions(
|
||||
active: Optional[bool] = None,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> list[InstallableExtension]:
|
||||
) -> List["InstallableExtension"]:
|
||||
rows = await (conn or db).fetchall(
|
||||
"SELECT * FROM installed_extensions",
|
||||
)
|
||||
@@ -453,7 +456,7 @@ async def get_user_extension(
|
||||
|
||||
async def get_user_extensions(
|
||||
user_id: str, conn: Optional[Connection] = None
|
||||
) -> list[UserExtension]:
|
||||
) -> List[UserExtension]:
|
||||
rows = await (conn or db).fetchall(
|
||||
"""
|
||||
SELECT extension, active, extra as _extra FROM extensions
|
||||
@@ -478,7 +481,7 @@ async def update_user_extension(
|
||||
|
||||
async def get_user_active_extensions_ids(
|
||||
user_id: str, conn: Optional[Connection] = None
|
||||
) -> list[str]:
|
||||
) -> List[str]:
|
||||
rows = await (conn or db).fetchall(
|
||||
"""
|
||||
SELECT extension FROM extensions WHERE "user" = :user AND active
|
||||
@@ -647,7 +650,7 @@ async def get_wallet(
|
||||
return Wallet(**row) if row else None
|
||||
|
||||
|
||||
async def get_wallets(user_id: str, conn: Optional[Connection] = None) -> list[Wallet]:
|
||||
async def get_wallets(user_id: str, conn: Optional[Connection] = None) -> List[Wallet]:
|
||||
rows = await (conn or db).fetchall(
|
||||
"""
|
||||
SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0)
|
||||
@@ -769,7 +772,7 @@ async def get_payments_paginated(
|
||||
"wallet": wallet_id,
|
||||
"time": since,
|
||||
}
|
||||
clause: list[str] = []
|
||||
clause: List[str] = []
|
||||
|
||||
if since is not None:
|
||||
clause.append(f"time > {db.timestamp_placeholder('time')}")
|
||||
@@ -879,13 +882,23 @@ async def delete_expired_invoices(
|
||||
|
||||
|
||||
async def create_payment(
|
||||
*,
|
||||
wallet_id: str,
|
||||
checking_id: str,
|
||||
data: CreatePayment,
|
||||
payment_request: str,
|
||||
payment_hash: str,
|
||||
amount: int,
|
||||
memo: str,
|
||||
fee: int = 0,
|
||||
status: PaymentState = PaymentState.PENDING,
|
||||
preimage: Optional[str] = None,
|
||||
expiry: Optional[datetime.datetime] = None,
|
||||
extra: Optional[Dict] = None,
|
||||
webhook: Optional[str] = None,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> Payment:
|
||||
# we don't allow the creation of the same invoice twice
|
||||
# note: this can be removed if the db uniqueness constraints are set appropriately
|
||||
# note: this can be removed if the db uniquess constarints are set appropriately
|
||||
previous_payment = await get_standalone_payment(checking_id, conn=conn)
|
||||
assert previous_payment is None, "Payment already exists"
|
||||
|
||||
@@ -899,27 +912,27 @@ async def create_payment(
|
||||
:amount, :status, :memo, :fee, :extra, :webhook, {expiry_ph}, :pending)
|
||||
""",
|
||||
{
|
||||
"wallet": data.wallet_id,
|
||||
"wallet": wallet_id,
|
||||
"checking_id": checking_id,
|
||||
"bolt11": data.payment_request,
|
||||
"hash": data.payment_hash,
|
||||
"preimage": data.preimage,
|
||||
"amount": data.amount,
|
||||
"bolt11": payment_request,
|
||||
"hash": payment_hash,
|
||||
"preimage": preimage,
|
||||
"amount": amount,
|
||||
"status": status.value,
|
||||
"memo": data.memo,
|
||||
"fee": data.fee,
|
||||
"memo": memo,
|
||||
"fee": fee,
|
||||
"extra": (
|
||||
json.dumps(data.extra)
|
||||
if data.extra and data.extra != {} and isinstance(data.extra, dict)
|
||||
json.dumps(extra)
|
||||
if extra and extra != {} and isinstance(extra, dict)
|
||||
else None
|
||||
),
|
||||
"webhook": data.webhook,
|
||||
"expiry": data.expiry if data.expiry else None,
|
||||
"webhook": webhook,
|
||||
"expiry": expiry if expiry else None,
|
||||
"pending": False, # TODO: remove this in next release
|
||||
},
|
||||
)
|
||||
|
||||
new_payment = await get_wallet_payment(data.wallet_id, data.payment_hash, conn=conn)
|
||||
new_payment = await get_wallet_payment(wallet_id, payment_hash, conn=conn)
|
||||
assert new_payment, "Newly created payment couldn't be retrieved"
|
||||
|
||||
return new_payment
|
||||
@@ -950,7 +963,7 @@ async def update_payment_details(
|
||||
"preimage": preimage,
|
||||
}
|
||||
|
||||
set_clause: list[str] = []
|
||||
set_clause: List[str] = []
|
||||
if new_checking_id is not None:
|
||||
set_clause.append("checking_id = :checking_id")
|
||||
if status is not None:
|
||||
@@ -1010,7 +1023,7 @@ async def get_payments_history(
|
||||
wallet_id: Optional[str] = None,
|
||||
group: DateTrunc = "day",
|
||||
filters: Optional[Filters] = None,
|
||||
) -> list[PaymentHistoryPoint]:
|
||||
) -> List[PaymentHistoryPoint]:
|
||||
if not filters:
|
||||
filters = Filters()
|
||||
|
||||
@@ -1236,7 +1249,7 @@ async def get_tinyurl(tinyurl_id: str) -> Optional[TinyURL]:
|
||||
return TinyURL.from_row(row) if row else None
|
||||
|
||||
|
||||
async def get_tinyurl_by_url(url: str) -> list[TinyURL]:
|
||||
async def get_tinyurl_by_url(url: str) -> List[TinyURL]:
|
||||
rows = await db.fetchall(
|
||||
"SELECT * FROM tiny_url WHERE url = :url",
|
||||
{"url": url},
|
||||
@@ -1288,7 +1301,7 @@ async def get_webpush_subscription(
|
||||
|
||||
async def get_webpush_subscriptions_for_user(
|
||||
user: str,
|
||||
) -> list[WebPushSubscription]:
|
||||
) -> List[WebPushSubscription]:
|
||||
rows = await db.fetchall(
|
||||
"""SELECT * FROM webpush_subscriptions WHERE "user" = :user""",
|
||||
{"user": user},
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
import asyncio
|
||||
import importlib
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core.crud import (
|
||||
add_installed_extension,
|
||||
delete_installed_extension,
|
||||
get_dbversions,
|
||||
get_installed_extension,
|
||||
update_installed_extension_state,
|
||||
)
|
||||
from lnbits.core.db import core_app_extra
|
||||
from lnbits.core.helpers import migrate_extension_database
|
||||
from lnbits.settings import settings
|
||||
|
||||
from .models import Extension, InstallableExtension
|
||||
|
||||
|
||||
async def install_extension(ext_info: InstallableExtension) -> Extension:
|
||||
extension = Extension.from_installable_ext(ext_info)
|
||||
installed_ext = await get_installed_extension(ext_info.id)
|
||||
ext_info.payments = installed_ext.payments if installed_ext else []
|
||||
|
||||
await ext_info.download_archive()
|
||||
|
||||
ext_info.extract_archive()
|
||||
|
||||
db_version = (await get_dbversions()).get(ext_info.id, 0)
|
||||
await migrate_extension_database(extension, db_version)
|
||||
|
||||
await add_installed_extension(ext_info)
|
||||
|
||||
if extension.is_upgrade_extension:
|
||||
# call stop while the old routes are still active
|
||||
await stop_extension_background_work(ext_info.id)
|
||||
|
||||
return extension
|
||||
|
||||
|
||||
async def uninstall_extension(ext_id: str):
|
||||
await stop_extension_background_work(ext_id)
|
||||
|
||||
settings.deactivate_extension_paths(ext_id)
|
||||
|
||||
extension = await get_installed_extension(ext_id)
|
||||
if extension:
|
||||
extension.clean_extension_files()
|
||||
await delete_installed_extension(ext_id=ext_id)
|
||||
|
||||
|
||||
async def activate_extension(ext: Extension):
|
||||
core_app_extra.register_new_ext_routes(ext)
|
||||
await update_installed_extension_state(ext_id=ext.code, active=True)
|
||||
|
||||
|
||||
async def deactivate_extension(ext_id: str):
|
||||
settings.deactivate_extension_paths(ext_id)
|
||||
await update_installed_extension_state(ext_id=ext_id, active=False)
|
||||
|
||||
|
||||
async def stop_extension_background_work(ext_id: str) -> bool:
|
||||
"""
|
||||
Stop background work for extension (like asyncio.Tasks, WebSockets, etc).
|
||||
Extensions SHOULD expose a `api_stop()` function.
|
||||
"""
|
||||
upgrade_hash = settings.lnbits_upgraded_extensions.get(ext_id, "")
|
||||
ext = Extension(ext_id, True, False, upgrade_hash=upgrade_hash)
|
||||
|
||||
try:
|
||||
logger.info(f"Stopping background work for extension '{ext.module_name}'.")
|
||||
old_module = importlib.import_module(ext.module_name)
|
||||
|
||||
# Extensions must expose an `{ext_id}_stop()` function at the module level
|
||||
# The `api_stop()` function is for backwards compatibility (will be deprecated)
|
||||
stop_fns = [f"{ext_id}_stop", "api_stop"]
|
||||
stop_fn_name = next((fn for fn in stop_fns if hasattr(old_module, fn)), None)
|
||||
assert stop_fn_name, "No stop function found for '{ext.module_name}'"
|
||||
|
||||
stop_fn = getattr(old_module, stop_fn_name)
|
||||
if stop_fn:
|
||||
if asyncio.iscoroutinefunction(stop_fn):
|
||||
await stop_fn()
|
||||
else:
|
||||
stop_fn()
|
||||
|
||||
logger.info(f"Stopped background work for extension '{ext.module_name}'.")
|
||||
except Exception as ex:
|
||||
logger.warning(f"Failed to stop background work for '{ext.module_name}'.")
|
||||
logger.warning(ex)
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -1,56 +0,0 @@
|
||||
import hashlib
|
||||
from typing import Any, Optional
|
||||
from urllib import request
|
||||
|
||||
import httpx
|
||||
from loguru import logger
|
||||
from packaging import version
|
||||
|
||||
from lnbits.settings import settings
|
||||
|
||||
|
||||
def version_parse(v: str):
|
||||
"""
|
||||
Wrapper for version.parse() that does not throw if the version is invalid.
|
||||
Instead it return the lowest possible version ("0.0.0")
|
||||
"""
|
||||
try:
|
||||
return version.parse(v)
|
||||
except Exception:
|
||||
return version.parse("0.0.0")
|
||||
|
||||
|
||||
async def github_api_get(url: str, error_msg: Optional[str]) -> Any:
|
||||
headers = {"User-Agent": settings.user_agent}
|
||||
if settings.lnbits_ext_github_token:
|
||||
headers["Authorization"] = f"Bearer {settings.lnbits_ext_github_token}"
|
||||
async with httpx.AsyncClient(headers=headers) as client:
|
||||
resp = await client.get(url)
|
||||
if resp.status_code != 200:
|
||||
logger.warning(f"{error_msg} ({url}): {resp.text}")
|
||||
resp.raise_for_status()
|
||||
return resp.json()
|
||||
|
||||
|
||||
def download_url(url, save_path):
|
||||
with request.urlopen(url, timeout=60) as dl_file:
|
||||
with open(save_path, "wb") as out_file:
|
||||
out_file.write(dl_file.read())
|
||||
|
||||
|
||||
def file_hash(filename):
|
||||
h = hashlib.sha256()
|
||||
b = bytearray(128 * 1024)
|
||||
mv = memoryview(b)
|
||||
with open(filename, "rb", buffering=0) as f:
|
||||
while n := f.readinto(mv):
|
||||
h.update(mv[:n])
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def icon_to_github_url(source_repo: str, path: Optional[str]) -> str:
|
||||
if not path:
|
||||
return ""
|
||||
_, _, *rest = path.split("/")
|
||||
tail = "/".join(rest)
|
||||
return f"https://github.com/{source_repo}/raw/main/{tail}"
|
||||
+69
-5
@@ -1,8 +1,9 @@
|
||||
import importlib
|
||||
import re
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
from uuid import UUID
|
||||
|
||||
import httpx
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core import migrations as core_migrations
|
||||
@@ -12,10 +13,11 @@ from lnbits.core.crud import (
|
||||
update_migration_version,
|
||||
)
|
||||
from lnbits.core.db import db as core_db
|
||||
from lnbits.core.extensions.models import (
|
||||
Extension,
|
||||
)
|
||||
from lnbits.db import COCKROACH, POSTGRES, SQLITE, Connection
|
||||
from lnbits.extension_manager import (
|
||||
Extension,
|
||||
get_valid_extensions,
|
||||
)
|
||||
from lnbits.settings import settings
|
||||
|
||||
|
||||
@@ -53,6 +55,68 @@ async def run_migration(
|
||||
await update_migration_version(conn, db_name, version)
|
||||
|
||||
|
||||
async def stop_extension_background_work(
|
||||
ext_id: str, user: str, access_token: Optional[str] = None
|
||||
):
|
||||
"""
|
||||
Stop background work for extension (like asyncio.Tasks, WebSockets, etc).
|
||||
Extensions SHOULD expose a `api_stop()` function and/or a DELETE enpoint
|
||||
at the root level of their API.
|
||||
"""
|
||||
stopped = await _stop_extension_background_work(ext_id)
|
||||
|
||||
if not stopped:
|
||||
# fallback to REST API call
|
||||
await _stop_extension_background_work_via_api(ext_id, user, access_token)
|
||||
|
||||
|
||||
async def _stop_extension_background_work(ext_id) -> bool:
|
||||
upgrade_hash = settings.extension_upgrade_hash(ext_id) or ""
|
||||
ext = Extension(ext_id, True, False, upgrade_hash=upgrade_hash)
|
||||
|
||||
try:
|
||||
logger.info(f"Stopping background work for extension '{ext.module_name}'.")
|
||||
old_module = importlib.import_module(ext.module_name)
|
||||
|
||||
# Extensions must expose an `{ext_id}_stop()` function at the module level
|
||||
# The `api_stop()` function is for backwards compatibility (will be deprecated)
|
||||
stop_fns = [f"{ext_id}_stop", "api_stop"]
|
||||
stop_fn_name = next((fn for fn in stop_fns if hasattr(old_module, fn)), None)
|
||||
assert stop_fn_name, "No stop function found for '{ext.module_name}'"
|
||||
|
||||
stop_fn = getattr(old_module, stop_fn_name)
|
||||
if stop_fn:
|
||||
await stop_fn()
|
||||
|
||||
logger.info(f"Stopped background work for extension '{ext.module_name}'.")
|
||||
except Exception as ex:
|
||||
logger.warning(f"Failed to stop background work for '{ext.module_name}'.")
|
||||
logger.warning(ex)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def _stop_extension_background_work_via_api(ext_id, user, access_token):
|
||||
logger.info(
|
||||
f"Stopping background work for extension '{ext_id}' using the REST API."
|
||||
)
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
url = f"http://{settings.host}:{settings.port}/{ext_id}/api/v1?usr={user}"
|
||||
headers = (
|
||||
{"Authorization": "Bearer " + access_token} if access_token else None
|
||||
)
|
||||
resp = await client.delete(url=url, headers=headers)
|
||||
resp.raise_for_status()
|
||||
logger.info(f"Stopped background work for extension '{ext_id}'.")
|
||||
except Exception as ex:
|
||||
logger.warning(
|
||||
f"Failed to stop background work for '{ext_id}' using the REST API."
|
||||
)
|
||||
logger.warning(ex)
|
||||
|
||||
|
||||
def to_valid_user_id(user_id: str) -> UUID:
|
||||
if len(user_id) < 32:
|
||||
raise ValueError("User ID must have at least 128 bits")
|
||||
@@ -97,7 +161,7 @@ async def migrate_databases():
|
||||
await load_disabled_extension_list()
|
||||
|
||||
# todo: revisit, use installed extensions
|
||||
for ext in Extension.get_valid_extensions(False):
|
||||
for ext in get_valid_extensions(False):
|
||||
current_version = current_versions.get(ext.code, 0)
|
||||
try:
|
||||
await migrate_extension_database(ext, current_version)
|
||||
|
||||
+3
-22
@@ -20,10 +20,8 @@ from lnbits.settings import settings
|
||||
from lnbits.utils.exchange_rates import allowed_currencies
|
||||
from lnbits.wallets import get_funding_source
|
||||
from lnbits.wallets.base import (
|
||||
PaymentFailedStatus,
|
||||
PaymentPendingStatus,
|
||||
PaymentStatus,
|
||||
PaymentSuccessStatus,
|
||||
)
|
||||
|
||||
|
||||
@@ -212,19 +210,6 @@ class PaymentState(str, Enum):
|
||||
return self.value
|
||||
|
||||
|
||||
class CreatePayment(BaseModel):
|
||||
wallet_id: str
|
||||
payment_request: str
|
||||
payment_hash: str
|
||||
amount: int
|
||||
memo: str
|
||||
preimage: Optional[str] = None
|
||||
expiry: Optional[datetime.datetime] = None
|
||||
extra: Optional[dict] = None
|
||||
webhook: Optional[str] = None
|
||||
fee: int = 0
|
||||
|
||||
|
||||
class Payment(FromRowModel):
|
||||
status: str
|
||||
# TODO should be removed in the future, backward compatibility
|
||||
@@ -238,7 +223,7 @@ class Payment(FromRowModel):
|
||||
preimage: str
|
||||
payment_hash: str
|
||||
expiry: Optional[float]
|
||||
extra: Optional[dict]
|
||||
extra: dict = {}
|
||||
wallet_id: str
|
||||
webhook: Optional[str]
|
||||
webhook_status: Optional[int]
|
||||
@@ -299,15 +284,11 @@ class Payment(FromRowModel):
|
||||
return self.expiry < time.time() if self.expiry else False
|
||||
|
||||
@property
|
||||
def is_internal(self) -> bool:
|
||||
def is_uncheckable(self) -> bool:
|
||||
return self.checking_id.startswith("internal_")
|
||||
|
||||
async def check_status(self) -> PaymentStatus:
|
||||
if self.is_internal:
|
||||
if self.success:
|
||||
return PaymentSuccessStatus()
|
||||
if self.failed:
|
||||
return PaymentFailedStatus()
|
||||
if self.is_uncheckable:
|
||||
return PaymentPendingStatus()
|
||||
funding_source = get_funding_source()
|
||||
if self.is_out:
|
||||
|
||||
+39
-45
@@ -1,9 +1,10 @@
|
||||
import asyncio
|
||||
import datetime
|
||||
import json
|
||||
import time
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from typing import Dict, List, Optional, Tuple, TypedDict
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
@@ -67,24 +68,16 @@ from .crud import (
|
||||
update_user_extension,
|
||||
)
|
||||
from .helpers import to_valid_user_id
|
||||
from .models import (
|
||||
BalanceDelta,
|
||||
CreatePayment,
|
||||
Payment,
|
||||
PaymentState,
|
||||
User,
|
||||
UserConfig,
|
||||
Wallet,
|
||||
)
|
||||
from .models import BalanceDelta, Payment, PaymentState, User, UserConfig, Wallet
|
||||
|
||||
|
||||
async def calculate_fiat_amounts(
|
||||
amount: float,
|
||||
wallet_id: str,
|
||||
currency: Optional[str] = None,
|
||||
extra: Optional[dict] = None,
|
||||
extra: Optional[Dict] = None,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> tuple[int, Optional[dict]]:
|
||||
) -> Tuple[int, Optional[Dict]]:
|
||||
wallet = await get_wallet(wallet_id, conn=conn)
|
||||
assert wallet, "invalid wallet_id"
|
||||
wallet_currency = wallet.currency or settings.lnbits_default_accounting_currency
|
||||
@@ -125,11 +118,11 @@ async def create_invoice(
|
||||
description_hash: Optional[bytes] = None,
|
||||
unhashed_description: Optional[bytes] = None,
|
||||
expiry: Optional[int] = None,
|
||||
extra: Optional[dict] = None,
|
||||
extra: Optional[Dict] = None,
|
||||
webhook: Optional[str] = None,
|
||||
internal: Optional[bool] = False,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> tuple[str, str]:
|
||||
) -> Tuple[str, str]:
|
||||
if not amount > 0:
|
||||
raise InvoiceError("Amountless invoices not supported.", status="failed")
|
||||
|
||||
@@ -174,20 +167,17 @@ async def create_invoice(
|
||||
|
||||
invoice = bolt11_decode(payment_request)
|
||||
|
||||
create_payment_model = CreatePayment(
|
||||
amount_msat = 1000 * amount_sat
|
||||
await create_payment(
|
||||
wallet_id=wallet_id,
|
||||
checking_id=checking_id,
|
||||
payment_request=payment_request,
|
||||
payment_hash=invoice.payment_hash,
|
||||
amount=amount_sat * 1000,
|
||||
amount=amount_msat,
|
||||
expiry=invoice.expiry_date,
|
||||
memo=memo,
|
||||
extra=extra,
|
||||
webhook=webhook,
|
||||
)
|
||||
|
||||
await create_payment(
|
||||
checking_id=checking_id,
|
||||
data=create_payment_model,
|
||||
conn=conn,
|
||||
)
|
||||
|
||||
@@ -199,7 +189,7 @@ async def pay_invoice(
|
||||
wallet_id: str,
|
||||
payment_request: str,
|
||||
max_sat: Optional[int] = None,
|
||||
extra: Optional[dict] = None,
|
||||
extra: Optional[Dict] = None,
|
||||
description: str = "",
|
||||
conn: Optional[Connection] = None,
|
||||
) -> str:
|
||||
@@ -233,7 +223,17 @@ async def pay_invoice(
|
||||
invoice.amount_msat / 1000, wallet_id, extra=extra, conn=conn
|
||||
)
|
||||
|
||||
create_payment_model = CreatePayment(
|
||||
# put all parameters that don't change here
|
||||
class PaymentKwargs(TypedDict):
|
||||
wallet_id: str
|
||||
payment_request: str
|
||||
payment_hash: str
|
||||
amount: int
|
||||
memo: str
|
||||
expiry: Optional[datetime.datetime]
|
||||
extra: Optional[Dict]
|
||||
|
||||
payment_kwargs: PaymentKwargs = PaymentKwargs(
|
||||
wallet_id=wallet_id,
|
||||
payment_request=payment_request,
|
||||
payment_hash=invoice.payment_hash,
|
||||
@@ -252,6 +252,9 @@ async def pay_invoice(
|
||||
# (pending only)
|
||||
internal_checking_id = await check_internal(invoice.payment_hash, conn=conn)
|
||||
if internal_checking_id:
|
||||
fee_reserve_total_msat = fee_reserve_total(
|
||||
invoice.amount_msat, internal=True
|
||||
)
|
||||
# perform additional checks on the internal payment
|
||||
# the payment hash is not enough to make sure that this is the same invoice
|
||||
internal_invoice = await get_standalone_payment(
|
||||
@@ -266,23 +269,16 @@ async def pay_invoice(
|
||||
|
||||
logger.debug(f"creating temporary internal payment with id {internal_id}")
|
||||
# create a new payment from this wallet
|
||||
|
||||
fee_reserve_total_msat = fee_reserve_total(
|
||||
invoice.amount_msat, internal=True
|
||||
)
|
||||
create_payment_model.fee = abs(fee_reserve_total_msat)
|
||||
new_payment = await create_payment(
|
||||
checking_id=internal_id,
|
||||
data=create_payment_model,
|
||||
fee=0 + abs(fee_reserve_total_msat),
|
||||
status=PaymentState.SUCCESS,
|
||||
conn=conn,
|
||||
**payment_kwargs,
|
||||
)
|
||||
else:
|
||||
new_payment = await _create_external_payment(
|
||||
temp_id=temp_id,
|
||||
amount_msat=invoice.amount_msat,
|
||||
data=create_payment_model,
|
||||
conn=conn,
|
||||
temp_id, invoice.amount_msat, conn=conn, **payment_kwargs
|
||||
)
|
||||
|
||||
# do the balance check
|
||||
@@ -381,16 +377,14 @@ async def pay_invoice(
|
||||
|
||||
# credit service fee wallet
|
||||
if settings.lnbits_service_fee_wallet and service_fee_msat:
|
||||
create_payment_model = CreatePayment(
|
||||
new_payment = await create_payment(
|
||||
wallet_id=settings.lnbits_service_fee_wallet,
|
||||
payment_request=payment_request,
|
||||
payment_hash=invoice.payment_hash,
|
||||
fee=0,
|
||||
amount=abs(service_fee_msat),
|
||||
memo="Service fee",
|
||||
)
|
||||
new_payment = await create_payment(
|
||||
checking_id=f"service_fee_{temp_id}",
|
||||
data=create_payment_model,
|
||||
checking_id="service_fee" + temp_id,
|
||||
payment_request=payment_request,
|
||||
payment_hash=invoice.payment_hash,
|
||||
status=PaymentState.SUCCESS,
|
||||
)
|
||||
return invoice.payment_hash
|
||||
@@ -399,8 +393,8 @@ async def pay_invoice(
|
||||
async def _create_external_payment(
|
||||
temp_id: str,
|
||||
amount_msat: MilliSatoshi,
|
||||
data: CreatePayment,
|
||||
conn: Optional[Connection],
|
||||
**payment_kwargs,
|
||||
) -> Payment:
|
||||
fee_reserve_total_msat = fee_reserve_total(amount_msat, internal=False)
|
||||
|
||||
@@ -434,11 +428,11 @@ async def _create_external_payment(
|
||||
# create a temporary payment here so we can check if
|
||||
# the balance is enough in the next step
|
||||
try:
|
||||
data.fee = -abs(fee_reserve_total_msat)
|
||||
new_payment = await create_payment(
|
||||
checking_id=temp_id,
|
||||
data=data,
|
||||
fee=-abs(fee_reserve_total_msat),
|
||||
conn=conn,
|
||||
**payment_kwargs,
|
||||
)
|
||||
return new_payment
|
||||
except Exception as exc:
|
||||
@@ -520,7 +514,7 @@ async def redeem_lnurl_withdraw(
|
||||
wallet_id: str,
|
||||
lnurl_request: str,
|
||||
memo: Optional[str] = None,
|
||||
extra: Optional[dict] = None,
|
||||
extra: Optional[Dict] = None,
|
||||
wait_seconds: int = 0,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
@@ -859,7 +853,7 @@ async def create_user_account(
|
||||
|
||||
class WebsocketConnectionManager:
|
||||
def __init__(self) -> None:
|
||||
self.active_connections: list[WebSocket] = []
|
||||
self.active_connections: List[WebSocket] = []
|
||||
|
||||
async def connect(self, websocket: WebSocket, item_id: str):
|
||||
logger.debug(f"Websocket connected to {item_id}")
|
||||
|
||||
@@ -901,7 +901,7 @@
|
||||
</q-dialog>
|
||||
{% endblock %} {% block scripts %} {{ window_vars(user) }}
|
||||
<script>
|
||||
window.app = Vue.createApp({
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
|
||||
data: function () {
|
||||
|
||||
@@ -154,10 +154,10 @@
|
||||
<q-card>
|
||||
<q-card-section class="text-center">
|
||||
<p v-text="$t('export_to_phone_desc')"></p>
|
||||
<qrcode-vue
|
||||
<qrcode
|
||||
:value="'{{request.base_url}}wallet?usr={{user.id}}&wal={{wallet.id}}'"
|
||||
:options="{ width: 256 }"
|
||||
></qrcode-vue>
|
||||
></qrcode>
|
||||
</q-card-section>
|
||||
<q-card-actions class="flex-center q-pb-md">
|
||||
<q-btn
|
||||
|
||||
@@ -51,11 +51,11 @@
|
||||
>
|
||||
<a :href="'lightning:' + transactionDetailsDialog.data.bolt11">
|
||||
<q-responsive :ratio="1" class="q-mx-xl">
|
||||
<qrcode-vue
|
||||
<qrcode
|
||||
:value="'lightning:' + transactionDetailsDialog.data.bolt11.toUpperCase()"
|
||||
:options="{width: 340}"
|
||||
class="rounded-borders"
|
||||
></qrcode-vue>
|
||||
></qrcode>
|
||||
</q-responsive>
|
||||
</a>
|
||||
<q-btn
|
||||
@@ -138,11 +138,11 @@
|
||||
>
|
||||
<a :href="'lightning:' + props.row.bolt11">
|
||||
<q-responsive :ratio="1" class="q-mx-xl">
|
||||
<qrcode-vue
|
||||
<qrcode
|
||||
:value="'lightning:' + props.row.bolt11.toUpperCase()"
|
||||
:options="{width: 340}"
|
||||
class="rounded-borders"
|
||||
></qrcode-vue>
|
||||
></qrcode>
|
||||
</q-responsive>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@ include "users/_createWalletDialog.html" %}
|
||||
|
||||
<div class="row q-col-gutter-md justify-center">
|
||||
<div class="col q-gutter-y-md" style="width: 300px">
|
||||
<div style="width: 100%; max-width: 2000px">
|
||||
<div style="width: 600px">
|
||||
<canvas ref="chart1"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,8 +24,8 @@ include "users/_createWalletDialog.html" %}
|
||||
</q-btn>
|
||||
</div>
|
||||
<q-table
|
||||
row-key="id"
|
||||
:rows="users"
|
||||
:data="users"
|
||||
:row-key="usersTableRowKey"
|
||||
:columns="usersTable.columns"
|
||||
:pagination.sync="usersTable.pagination"
|
||||
:no-data-label="$t('no_users')"
|
||||
@@ -70,7 +70,7 @@ include "users/_createWalletDialog.html" %}
|
||||
v-if="!props.row.is_super_user"
|
||||
icon="build"
|
||||
size="sm"
|
||||
:color="props.row.is_admin ? 'primary' : 'grey'"
|
||||
:color="props.row.is_admin ? 'primary' : ''"
|
||||
@click="toggleAdmin(props.row.id)"
|
||||
>
|
||||
<q-tooltip>Toggle Admin</q-tooltip>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import sys
|
||||
from http import HTTPStatus
|
||||
from typing import (
|
||||
List,
|
||||
Optional,
|
||||
)
|
||||
|
||||
from bolt11 import decode as bolt11_decode
|
||||
@@ -11,21 +13,10 @@ from fastapi import (
|
||||
)
|
||||
from loguru import logger
|
||||
|
||||
from lnbits.core.extensions.extension_manager import (
|
||||
activate_extension,
|
||||
deactivate_extension,
|
||||
install_extension,
|
||||
uninstall_extension,
|
||||
)
|
||||
from lnbits.core.extensions.models import (
|
||||
CreateExtension,
|
||||
Extension,
|
||||
ExtensionConfig,
|
||||
ExtensionRelease,
|
||||
InstallableExtension,
|
||||
PayToEnableInfo,
|
||||
ReleasePaymentInfo,
|
||||
UserExtensionInfo,
|
||||
from lnbits.core.db import core_app_extra
|
||||
from lnbits.core.helpers import (
|
||||
migrate_extension_database,
|
||||
stop_extension_background_work,
|
||||
)
|
||||
from lnbits.core.models import (
|
||||
SimpleStatus,
|
||||
@@ -33,18 +24,36 @@ from lnbits.core.models import (
|
||||
)
|
||||
from lnbits.core.services import check_transaction_status, create_invoice
|
||||
from lnbits.decorators import (
|
||||
check_access_token,
|
||||
check_admin,
|
||||
check_user_exists,
|
||||
)
|
||||
from lnbits.extension_manager import (
|
||||
CreateExtension,
|
||||
Extension,
|
||||
ExtensionRelease,
|
||||
InstallableExtension,
|
||||
PayToEnableInfo,
|
||||
ReleasePaymentInfo,
|
||||
UserExtensionInfo,
|
||||
fetch_github_release_config,
|
||||
fetch_release_details,
|
||||
fetch_release_payment_info,
|
||||
get_valid_extensions,
|
||||
)
|
||||
from lnbits.settings import settings
|
||||
|
||||
from ..crud import (
|
||||
add_installed_extension,
|
||||
delete_dbversion,
|
||||
delete_installed_extension,
|
||||
drop_extension_db,
|
||||
get_dbversions,
|
||||
get_installed_extension,
|
||||
get_installed_extensions,
|
||||
get_user_extension,
|
||||
update_extension_pay_to_enable,
|
||||
update_installed_extension_state,
|
||||
update_user_extension,
|
||||
update_user_extension_extra,
|
||||
)
|
||||
@@ -55,8 +64,12 @@ extension_router = APIRouter(
|
||||
)
|
||||
|
||||
|
||||
@extension_router.post("", dependencies=[Depends(check_admin)])
|
||||
async def api_install_extension(data: CreateExtension):
|
||||
@extension_router.post("")
|
||||
async def api_install_extension(
|
||||
data: CreateExtension,
|
||||
user: User = Depends(check_admin),
|
||||
access_token: Optional[str] = Depends(check_access_token),
|
||||
):
|
||||
release = await InstallableExtension.get_extension_release(
|
||||
data.ext_id, data.source_repo, data.archive, data.version
|
||||
)
|
||||
@@ -76,36 +89,43 @@ async def api_install_extension(data: CreateExtension):
|
||||
)
|
||||
|
||||
try:
|
||||
extension = await install_extension(ext_info)
|
||||
installed_ext = await get_installed_extension(data.ext_id)
|
||||
ext_info.payments = installed_ext.payments if installed_ext else []
|
||||
|
||||
await ext_info.download_archive()
|
||||
|
||||
ext_info.extract_archive()
|
||||
|
||||
extension = Extension.from_installable_ext(ext_info)
|
||||
|
||||
db_version = (await get_dbversions()).get(data.ext_id, 0)
|
||||
await migrate_extension_database(extension, db_version)
|
||||
|
||||
ext_info.active = True
|
||||
await add_installed_extension(ext_info)
|
||||
|
||||
if extension.is_upgrade_extension:
|
||||
# call stop while the old routes are still active
|
||||
await stop_extension_background_work(data.ext_id, user.id, access_token)
|
||||
|
||||
# mount routes for the new version
|
||||
core_app_extra.register_new_ext_routes(extension)
|
||||
|
||||
ext_info.notify_upgrade(extension.upgrade_hash)
|
||||
settings.lnbits_deactivated_extensions.discard(data.ext_id)
|
||||
|
||||
return extension
|
||||
except AssertionError as exc:
|
||||
raise HTTPException(HTTPStatus.BAD_REQUEST, str(exc)) from exc
|
||||
except Exception as exc:
|
||||
logger.warning(exc)
|
||||
ext_info.clean_extension_files()
|
||||
detail = (
|
||||
str(exc)
|
||||
if isinstance(exc, AssertionError)
|
||||
else f"Failed to install extension '{ext_info.id}'."
|
||||
f"({ext_info.installed_version})."
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
detail=detail,
|
||||
) from exc
|
||||
|
||||
try:
|
||||
await activate_extension(extension)
|
||||
return extension
|
||||
except Exception as exc:
|
||||
logger.warning(exc)
|
||||
await deactivate_extension(extension.code)
|
||||
detail = (
|
||||
str(exc)
|
||||
if isinstance(exc, AssertionError)
|
||||
else f"Extension `{extension.code}` installed, but activation failed."
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
detail=detail,
|
||||
detail=(
|
||||
f"Failed to install extension {ext_info.id} "
|
||||
f"({ext_info.installed_version})."
|
||||
),
|
||||
) from exc
|
||||
|
||||
|
||||
@@ -123,7 +143,7 @@ async def api_extension_details(
|
||||
)
|
||||
assert release, "Details not found for release"
|
||||
|
||||
release_details = await ExtensionRelease.fetch_release_details(details_link)
|
||||
release_details = await fetch_release_details(details_link)
|
||||
assert release_details, "Cannot fetch details for release"
|
||||
release_details["icon"] = release.icon
|
||||
release_details["repo"] = release.repo
|
||||
@@ -166,7 +186,7 @@ async def api_update_pay_to_enable(
|
||||
async def api_enable_extension(
|
||||
ext_id: str, user: User = Depends(check_user_exists)
|
||||
) -> SimpleStatus:
|
||||
if ext_id not in [e.code for e in Extension.get_valid_extensions()]:
|
||||
if ext_id not in [e.code for e in get_valid_extensions()]:
|
||||
raise HTTPException(
|
||||
HTTPStatus.NOT_FOUND, f"Extension '{ext_id}' doesn't exist."
|
||||
)
|
||||
@@ -229,7 +249,7 @@ async def api_enable_extension(
|
||||
async def api_disable_extension(
|
||||
ext_id: str, user: User = Depends(check_user_exists)
|
||||
) -> SimpleStatus:
|
||||
if ext_id not in [e.code for e in Extension.get_valid_extensions()]:
|
||||
if ext_id not in [e.code for e in get_valid_extensions()]:
|
||||
raise HTTPException(
|
||||
HTTPStatus.BAD_REQUEST, f"Extension '{ext_id}' doesn't exist."
|
||||
)
|
||||
@@ -250,14 +270,20 @@ async def api_activate_extension(ext_id: str) -> SimpleStatus:
|
||||
try:
|
||||
logger.info(f"Activating extension: '{ext_id}'.")
|
||||
|
||||
ext = Extension.get_valid_extension(ext_id)
|
||||
all_extensions = get_valid_extensions()
|
||||
ext = next((e for e in all_extensions if e.code == ext_id), None)
|
||||
assert ext, f"Extension '{ext_id}' doesn't exist."
|
||||
# if extension never loaded (was deactivated on server startup)
|
||||
if ext_id not in sys.modules.keys():
|
||||
# run extension start-up routine
|
||||
core_app_extra.register_new_ext_routes(ext)
|
||||
|
||||
await activate_extension(ext)
|
||||
settings.lnbits_deactivated_extensions.discard(ext_id)
|
||||
|
||||
await update_installed_extension_state(ext_id=ext_id, active=True)
|
||||
return SimpleStatus(success=True, message=f"Extension '{ext_id}' activated.")
|
||||
except Exception as exc:
|
||||
logger.warning(exc)
|
||||
await deactivate_extension(ext_id)
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
detail=(f"Failed to activate '{ext_id}'."),
|
||||
@@ -269,10 +295,13 @@ async def api_deactivate_extension(ext_id: str) -> SimpleStatus:
|
||||
try:
|
||||
logger.info(f"Deactivating extension: '{ext_id}'.")
|
||||
|
||||
ext = Extension.get_valid_extension(ext_id)
|
||||
all_extensions = get_valid_extensions()
|
||||
ext = next((e for e in all_extensions if e.code == ext_id), None)
|
||||
assert ext, f"Extension '{ext_id}' doesn't exist."
|
||||
|
||||
await deactivate_extension(ext_id)
|
||||
settings.lnbits_deactivated_extensions.add(ext_id)
|
||||
|
||||
await update_installed_extension_state(ext_id=ext_id, active=False)
|
||||
return SimpleStatus(success=True, message=f"Extension '{ext_id}' deactivated.")
|
||||
except Exception as exc:
|
||||
logger.warning(exc)
|
||||
@@ -282,19 +311,23 @@ async def api_deactivate_extension(ext_id: str) -> SimpleStatus:
|
||||
) from exc
|
||||
|
||||
|
||||
@extension_router.delete("/{ext_id}", dependencies=[Depends(check_admin)])
|
||||
async def api_uninstall_extension(ext_id: str) -> SimpleStatus:
|
||||
@extension_router.delete("/{ext_id}")
|
||||
async def api_uninstall_extension(
|
||||
ext_id: str,
|
||||
user: User = Depends(check_admin),
|
||||
access_token: Optional[str] = Depends(check_access_token),
|
||||
) -> SimpleStatus:
|
||||
installed_extensions = await get_installed_extensions()
|
||||
|
||||
extension = await get_installed_extension(ext_id)
|
||||
if not extension:
|
||||
extensions = [e for e in installed_extensions if e.id == ext_id]
|
||||
if len(extensions) == 0:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail=f"Unknown extension id: {ext_id}",
|
||||
)
|
||||
|
||||
installed_extensions = await get_installed_extensions()
|
||||
# check that other extensions do not depend on this one
|
||||
for valid_ext_id in [ext.code for ext in Extension.get_valid_extensions()]:
|
||||
for valid_ext_id in [ext.code for ext in get_valid_extensions()]:
|
||||
installed_ext = next(
|
||||
(ext for ext in installed_extensions if ext.id == valid_ext_id), None
|
||||
)
|
||||
@@ -308,7 +341,14 @@ async def api_uninstall_extension(ext_id: str) -> SimpleStatus:
|
||||
)
|
||||
|
||||
try:
|
||||
await uninstall_extension(ext_id)
|
||||
# call stop while the old routes are still active
|
||||
await stop_extension_background_work(ext_id, user.id, access_token)
|
||||
|
||||
settings.lnbits_deactivated_extensions.add(ext_id)
|
||||
|
||||
for ext_info in extensions:
|
||||
ext_info.clean_extension_files()
|
||||
await delete_installed_extension(ext_id=ext_info.id)
|
||||
|
||||
logger.success(f"Extension '{ext_id}' uninstalled.")
|
||||
return SimpleStatus(success=True, message=f"Extension '{ext_id}' uninstalled.")
|
||||
@@ -357,8 +397,9 @@ async def get_pay_to_install_invoice(
|
||||
assert release, "Release not found."
|
||||
assert release.pay_link, "Pay link not found for release."
|
||||
|
||||
payment_info = await release.fetch_release_payment_info(data.cost_sats)
|
||||
|
||||
payment_info = await fetch_release_payment_info(
|
||||
release.pay_link, data.cost_sats
|
||||
)
|
||||
assert payment_info and payment_info.payment_request, "Cannot request invoice."
|
||||
invoice = bolt11_decode(payment_info.payment_request)
|
||||
|
||||
@@ -433,7 +474,7 @@ async def get_pay_to_enable_invoice(
|
||||
)
|
||||
async def get_extension_release(org: str, repo: str, tag_name: str):
|
||||
try:
|
||||
config = await ExtensionConfig.fetch_github_release_config(org, repo, tag_name)
|
||||
config = await fetch_github_release_config(org, repo, tag_name)
|
||||
if not config:
|
||||
return {}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ from lnurl import decode as lnurl_decode
|
||||
from loguru import logger
|
||||
from pydantic.types import UUID4
|
||||
|
||||
from lnbits.core.extensions.models import Extension, InstallableExtension
|
||||
from lnbits.core.helpers import to_valid_user_id
|
||||
from lnbits.core.models import User
|
||||
from lnbits.core.services import create_invoice
|
||||
@@ -21,6 +20,7 @@ from lnbits.helpers import template_renderer
|
||||
from lnbits.settings import settings
|
||||
from lnbits.wallets import get_funding_source
|
||||
|
||||
from ...extension_manager import InstallableExtension, get_valid_extensions
|
||||
from ...utils.exchange_rates import allowed_currencies, currencies
|
||||
from ..crud import (
|
||||
create_account,
|
||||
@@ -104,7 +104,7 @@ async def extensions(request: Request, user: User = Depends(check_user_exists)):
|
||||
installed_exts_ids = []
|
||||
|
||||
try:
|
||||
all_ext_ids = [ext.code for ext in Extension.get_valid_extensions()]
|
||||
all_ext_ids = [ext.code for ext in get_valid_extensions()]
|
||||
inactive_extensions = [
|
||||
e.id for e in await get_installed_extensions(active=False)
|
||||
]
|
||||
|
||||
@@ -35,6 +35,7 @@ from lnbits.core.models import (
|
||||
from lnbits.db import Filters, Page
|
||||
from lnbits.decorators import (
|
||||
WalletTypeInfo,
|
||||
get_key_type,
|
||||
parse_filters,
|
||||
require_admin_key,
|
||||
require_invoice_key,
|
||||
@@ -72,12 +73,12 @@ payment_router = APIRouter(prefix="/api/v1/payments", tags=["Payments"])
|
||||
openapi_extra=generate_filter_params_openapi(PaymentFilters),
|
||||
)
|
||||
async def api_payments(
|
||||
key_info: WalletTypeInfo = Depends(require_invoice_key),
|
||||
wallet: WalletTypeInfo = Depends(get_key_type),
|
||||
filters: Filters = Depends(parse_filters(PaymentFilters)),
|
||||
):
|
||||
await update_pending_payments(key_info.wallet.id)
|
||||
await update_pending_payments(wallet.wallet.id)
|
||||
return await get_payments(
|
||||
wallet_id=key_info.wallet.id,
|
||||
wallet_id=wallet.wallet.id,
|
||||
pending=True,
|
||||
complete=True,
|
||||
filters=filters,
|
||||
@@ -91,12 +92,12 @@ async def api_payments(
|
||||
openapi_extra=generate_filter_params_openapi(PaymentFilters),
|
||||
)
|
||||
async def api_payments_history(
|
||||
key_info: WalletTypeInfo = Depends(require_invoice_key),
|
||||
wallet: WalletTypeInfo = Depends(get_key_type),
|
||||
group: DateTrunc = Query("day"),
|
||||
filters: Filters[PaymentFilters] = Depends(parse_filters(PaymentFilters)),
|
||||
):
|
||||
await update_pending_payments(key_info.wallet.id)
|
||||
return await get_payments_history(key_info.wallet.id, group, filters)
|
||||
await update_pending_payments(wallet.wallet.id)
|
||||
return await get_payments_history(wallet.wallet.id, group, filters)
|
||||
|
||||
|
||||
@payment_router.get(
|
||||
@@ -108,12 +109,12 @@ async def api_payments_history(
|
||||
openapi_extra=generate_filter_params_openapi(PaymentFilters),
|
||||
)
|
||||
async def api_payments_paginated(
|
||||
key_info: WalletTypeInfo = Depends(require_invoice_key),
|
||||
wallet: WalletTypeInfo = Depends(get_key_type),
|
||||
filters: Filters = Depends(parse_filters(PaymentFilters)),
|
||||
):
|
||||
await update_pending_payments(key_info.wallet.id)
|
||||
await update_pending_payments(wallet.wallet.id)
|
||||
page = await get_payments_paginated(
|
||||
wallet_id=key_info.wallet.id,
|
||||
wallet_id=wallet.wallet.id,
|
||||
pending=True,
|
||||
complete=True,
|
||||
filters=filters,
|
||||
@@ -377,10 +378,10 @@ async def subscribe_wallet_invoices(request: Request, wallet: Wallet):
|
||||
|
||||
@payment_router.get("/sse")
|
||||
async def api_payments_sse(
|
||||
request: Request, key_info: WalletTypeInfo = Depends(require_invoice_key)
|
||||
request: Request, wallet: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
return EventSourceResponse(
|
||||
subscribe_wallet_invoices(request, key_info.wallet),
|
||||
subscribe_wallet_invoices(request, wallet.wallet),
|
||||
ping=20,
|
||||
media_type="text/event-stream",
|
||||
)
|
||||
|
||||
@@ -13,8 +13,8 @@ from lnbits.core.models import (
|
||||
)
|
||||
from lnbits.decorators import (
|
||||
WalletTypeInfo,
|
||||
get_key_type,
|
||||
require_admin_key,
|
||||
require_invoice_key,
|
||||
)
|
||||
|
||||
from ..crud import (
|
||||
@@ -27,14 +27,15 @@ wallet_router = APIRouter(prefix="/api/v1/wallet", tags=["Wallet"])
|
||||
|
||||
|
||||
@wallet_router.get("")
|
||||
async def api_wallet(wallet: WalletTypeInfo = Depends(require_invoice_key)):
|
||||
res = {
|
||||
"name": wallet.wallet.name,
|
||||
"balance": wallet.wallet.balance_msat,
|
||||
}
|
||||
async def api_wallet(wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||
if wallet.key_type == KeyType.admin:
|
||||
res["id"] = wallet.wallet.id
|
||||
return res
|
||||
return {
|
||||
"id": wallet.wallet.id,
|
||||
"name": wallet.wallet.name,
|
||||
"balance": wallet.wallet.balance_msat,
|
||||
}
|
||||
else:
|
||||
return {"name": wallet.wallet.name, "balance": wallet.wallet.balance_msat}
|
||||
|
||||
|
||||
@wallet_router.put("/{new_name}")
|
||||
|
||||
+4
-5
@@ -26,9 +26,10 @@ if settings.lnbits_database_url:
|
||||
if database_uri.startswith("cockroachdb://"):
|
||||
DB_TYPE = COCKROACH
|
||||
else:
|
||||
if not database_uri.startswith("postgres://"):
|
||||
if not database_uri.startswith("postgresql+asyncpg://"):
|
||||
raise ValueError(
|
||||
"Please use the 'postgres://...' " "format for the database URL."
|
||||
"Please use the 'postgresql+asyncpg://...' "
|
||||
"format for the database URL."
|
||||
)
|
||||
DB_TYPE = POSTGRES
|
||||
|
||||
@@ -234,9 +235,7 @@ class Database(Compat):
|
||||
)
|
||||
database_uri = f"sqlite+aiosqlite:///{self.path}"
|
||||
else:
|
||||
database_uri = settings.lnbits_database_url.replace(
|
||||
"postgres://", "postgresql+asyncpg://"
|
||||
)
|
||||
database_uri = settings.lnbits_database_url
|
||||
|
||||
if self.name.startswith("ext_"):
|
||||
self.schema = self.name[4:]
|
||||
|
||||
@@ -95,6 +95,15 @@ class KeyChecker(SecurityBase):
|
||||
return WalletTypeInfo(key_type, wallet)
|
||||
|
||||
|
||||
async def get_key_type(
|
||||
request: Request,
|
||||
api_key_header: str = Security(api_key_header),
|
||||
api_key_query: str = Security(api_key_query),
|
||||
) -> WalletTypeInfo:
|
||||
check: KeyChecker = KeyChecker(api_key=api_key_header or api_key_query)
|
||||
return await check(request)
|
||||
|
||||
|
||||
async def require_admin_key(
|
||||
request: Request,
|
||||
api_key_header: str = Security(api_key_header),
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
@@ -8,22 +6,16 @@ import shutil
|
||||
import sys
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from typing import Any, NamedTuple, Optional
|
||||
from typing import Any, List, NamedTuple, Optional, Tuple
|
||||
from urllib import request
|
||||
|
||||
import httpx
|
||||
from loguru import logger
|
||||
from packaging import version
|
||||
from pydantic import BaseModel
|
||||
|
||||
from lnbits.settings import settings
|
||||
|
||||
from .helpers import (
|
||||
download_url,
|
||||
file_hash,
|
||||
github_api_get,
|
||||
icon_to_github_url,
|
||||
version_parse,
|
||||
)
|
||||
|
||||
|
||||
class ExplicitRelease(BaseModel):
|
||||
id: str
|
||||
@@ -31,7 +23,7 @@ class ExplicitRelease(BaseModel):
|
||||
version: str
|
||||
archive: str
|
||||
hash: str
|
||||
dependencies: list[str] = []
|
||||
dependencies: List[str] = []
|
||||
repo: Optional[str]
|
||||
icon: Optional[str]
|
||||
short_description: Optional[str]
|
||||
@@ -56,9 +48,9 @@ class GitHubRelease(BaseModel):
|
||||
|
||||
|
||||
class Manifest(BaseModel):
|
||||
featured: list[str] = []
|
||||
extensions: list[ExplicitRelease] = []
|
||||
repos: list[GitHubRelease] = []
|
||||
featured: List[str] = []
|
||||
extensions: List["ExplicitRelease"] = []
|
||||
repos: List["GitHubRelease"] = []
|
||||
|
||||
|
||||
class GitHubRepoRelease(BaseModel):
|
||||
@@ -89,17 +81,6 @@ class ExtensionConfig(BaseModel):
|
||||
return True
|
||||
return version_parse(self.min_lnbits_version) <= version_parse(settings.version)
|
||||
|
||||
@classmethod
|
||||
async def fetch_github_release_config(
|
||||
cls, org: str, repo: str, tag_name: str
|
||||
) -> Optional[ExtensionConfig]:
|
||||
config_url = (
|
||||
f"https://raw.githubusercontent.com/{org}/{repo}/{tag_name}/config.json"
|
||||
)
|
||||
error_msg = "Cannot fetch GitHub extension config"
|
||||
config = await github_api_get(config_url, error_msg)
|
||||
return ExtensionConfig.parse_obj(config)
|
||||
|
||||
|
||||
class ReleasePaymentInfo(BaseModel):
|
||||
amount: Optional[int] = None
|
||||
@@ -131,7 +112,7 @@ class UserExtension(BaseModel):
|
||||
return self.extra.paid_to_enable is True
|
||||
|
||||
@classmethod
|
||||
def from_row(cls, data: dict) -> UserExtension:
|
||||
def from_row(cls, data: dict) -> "UserExtension":
|
||||
ext = UserExtension(**data)
|
||||
ext.extra = (
|
||||
UserExtensionInfo(**json.loads(data["_extra"] or "{}"))
|
||||
@@ -141,6 +122,124 @@ class UserExtension(BaseModel):
|
||||
return ext
|
||||
|
||||
|
||||
def download_url(url, save_path):
|
||||
with request.urlopen(url, timeout=60) as dl_file:
|
||||
with open(save_path, "wb") as out_file:
|
||||
out_file.write(dl_file.read())
|
||||
|
||||
|
||||
def file_hash(filename):
|
||||
h = hashlib.sha256()
|
||||
b = bytearray(128 * 1024)
|
||||
mv = memoryview(b)
|
||||
with open(filename, "rb", buffering=0) as f:
|
||||
while n := f.readinto(mv):
|
||||
h.update(mv[:n])
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
async def fetch_github_repo_info(
|
||||
org: str, repository: str
|
||||
) -> Tuple[GitHubRepo, GitHubRepoRelease, ExtensionConfig]:
|
||||
repo_url = f"https://api.github.com/repos/{org}/{repository}"
|
||||
error_msg = "Cannot fetch extension repo"
|
||||
repo = await github_api_get(repo_url, error_msg)
|
||||
github_repo = GitHubRepo.parse_obj(repo)
|
||||
|
||||
lates_release_url = (
|
||||
f"https://api.github.com/repos/{org}/{repository}/releases/latest"
|
||||
)
|
||||
error_msg = "Cannot fetch extension releases"
|
||||
latest_release: Any = await github_api_get(lates_release_url, error_msg)
|
||||
|
||||
config_url = f"https://raw.githubusercontent.com/{org}/{repository}/{github_repo.default_branch}/config.json"
|
||||
error_msg = "Cannot fetch config for extension"
|
||||
config = await github_api_get(config_url, error_msg)
|
||||
|
||||
return (
|
||||
github_repo,
|
||||
GitHubRepoRelease.parse_obj(latest_release),
|
||||
ExtensionConfig.parse_obj(config),
|
||||
)
|
||||
|
||||
|
||||
async def fetch_manifest(url) -> Manifest:
|
||||
error_msg = "Cannot fetch extensions manifest"
|
||||
manifest = await github_api_get(url, error_msg)
|
||||
return Manifest.parse_obj(manifest)
|
||||
|
||||
|
||||
async def fetch_github_releases(org: str, repo: str) -> List[GitHubRepoRelease]:
|
||||
releases_url = f"https://api.github.com/repos/{org}/{repo}/releases"
|
||||
error_msg = "Cannot fetch extension releases"
|
||||
releases = await github_api_get(releases_url, error_msg)
|
||||
return [GitHubRepoRelease.parse_obj(r) for r in releases]
|
||||
|
||||
|
||||
async def fetch_github_release_config(
|
||||
org: str, repo: str, tag_name: str
|
||||
) -> Optional[ExtensionConfig]:
|
||||
config_url = (
|
||||
f"https://raw.githubusercontent.com/{org}/{repo}/{tag_name}/config.json"
|
||||
)
|
||||
error_msg = "Cannot fetch GitHub extension config"
|
||||
config = await github_api_get(config_url, error_msg)
|
||||
return ExtensionConfig.parse_obj(config)
|
||||
|
||||
|
||||
async def github_api_get(url: str, error_msg: Optional[str]) -> Any:
|
||||
headers = {"User-Agent": settings.user_agent}
|
||||
if settings.lnbits_ext_github_token:
|
||||
headers["Authorization"] = f"Bearer {settings.lnbits_ext_github_token}"
|
||||
async with httpx.AsyncClient(headers=headers) as client:
|
||||
resp = await client.get(url)
|
||||
if resp.status_code != 200:
|
||||
logger.warning(f"{error_msg} ({url}): {resp.text}")
|
||||
resp.raise_for_status()
|
||||
return resp.json()
|
||||
|
||||
|
||||
async def fetch_release_payment_info(
|
||||
url: str, amount: Optional[int] = None
|
||||
) -> Optional[ReleasePaymentInfo]:
|
||||
if amount:
|
||||
url = f"{url}?amount={amount}"
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
resp = await client.get(url)
|
||||
resp.raise_for_status()
|
||||
return ReleasePaymentInfo(**resp.json())
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
return None
|
||||
|
||||
|
||||
async def fetch_release_details(details_link: str) -> Optional[dict]:
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
resp = await client.get(details_link)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
if "description_md" in data:
|
||||
resp = await client.get(data["description_md"])
|
||||
if not resp.is_error:
|
||||
data["description_md"] = resp.text
|
||||
|
||||
return data
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
return None
|
||||
|
||||
|
||||
def icon_to_github_url(source_repo: str, path: Optional[str]) -> str:
|
||||
if not path:
|
||||
return ""
|
||||
_, _, *rest = path.split("/")
|
||||
tail = "/".join(rest)
|
||||
return f"https://github.com/{source_repo}/raw/main/{tail}"
|
||||
|
||||
|
||||
class Extension(NamedTuple):
|
||||
code: str
|
||||
is_valid: bool
|
||||
@@ -148,7 +247,7 @@ class Extension(NamedTuple):
|
||||
name: Optional[str] = None
|
||||
short_description: Optional[str] = None
|
||||
tile: Optional[str] = None
|
||||
contributors: Optional[list[str]] = None
|
||||
contributors: Optional[List[str]] = None
|
||||
hidden: bool = False
|
||||
migration_module: Optional[str] = None
|
||||
db_name: Optional[str] = None
|
||||
@@ -170,7 +269,7 @@ class Extension(NamedTuple):
|
||||
return self.upgrade_hash != ""
|
||||
|
||||
@classmethod
|
||||
def from_installable_ext(cls, ext_info: InstallableExtension) -> Extension:
|
||||
def from_installable_ext(cls, ext_info: "InstallableExtension") -> "Extension":
|
||||
return Extension(
|
||||
code=ext_info.id,
|
||||
is_valid=True,
|
||||
@@ -179,43 +278,22 @@ class Extension(NamedTuple):
|
||||
upgrade_hash=ext_info.hash if ext_info.module_installed else "",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_valid_extensions(
|
||||
cls, include_deactivated: Optional[bool] = True
|
||||
) -> list[Extension]:
|
||||
valid_extensions = [
|
||||
extension for extension in cls._extensions() if extension.is_valid
|
||||
]
|
||||
|
||||
if include_deactivated:
|
||||
return valid_extensions
|
||||
# All subdirectories in the current directory, not recursive.
|
||||
|
||||
if settings.lnbits_extensions_deactivate_all:
|
||||
return []
|
||||
|
||||
return [
|
||||
e
|
||||
for e in valid_extensions
|
||||
if e.code not in settings.lnbits_deactivated_extensions
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def get_valid_extension(
|
||||
cls, ext_id: str, include_deactivated: Optional[bool] = True
|
||||
) -> Optional[Extension]:
|
||||
all_extensions = cls.get_valid_extensions(include_deactivated)
|
||||
return next((e for e in all_extensions if e.code == ext_id), None)
|
||||
|
||||
@classmethod
|
||||
def _extensions(cls) -> list[Extension]:
|
||||
class ExtensionManager:
|
||||
def __init__(self) -> None:
|
||||
p = Path(settings.lnbits_extensions_path, "extensions")
|
||||
Path(p).mkdir(parents=True, exist_ok=True)
|
||||
extension_folders: list[Path] = [f for f in p.iterdir() if f.is_dir()]
|
||||
self._extension_folders: List[Path] = [f for f in p.iterdir() if f.is_dir()]
|
||||
|
||||
@property
|
||||
def extensions(self) -> List[Extension]:
|
||||
# todo: remove this property somehow, it is too expensive
|
||||
output: list[Extension] = []
|
||||
output: List[Extension] = []
|
||||
|
||||
for extension_folder in extension_folders:
|
||||
for extension_folder in self._extension_folders:
|
||||
extension_code = extension_folder.parts[-1]
|
||||
try:
|
||||
with open(extension_folder / "config.json") as json_file:
|
||||
@@ -278,27 +356,13 @@ class ExtensionRelease(BaseModel):
|
||||
if not self.pay_link:
|
||||
return
|
||||
|
||||
payment_info = await self.fetch_release_payment_info()
|
||||
payment_info = await fetch_release_payment_info(self.pay_link)
|
||||
self.cost_sats = payment_info.amount if payment_info else None
|
||||
|
||||
async def fetch_release_payment_info(
|
||||
self, amount: Optional[int] = None
|
||||
) -> Optional[ReleasePaymentInfo]:
|
||||
url = f"{self.pay_link}?amount={amount}" if amount else self.pay_link
|
||||
assert url, "Missing URL for payment info."
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
resp = await client.get(url)
|
||||
resp.raise_for_status()
|
||||
return ReleasePaymentInfo(**resp.json())
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def from_github_release(
|
||||
cls, source_repo: str, r: GitHubRepoRelease
|
||||
) -> ExtensionRelease:
|
||||
cls, source_repo: str, r: "GitHubRepoRelease"
|
||||
) -> "ExtensionRelease":
|
||||
return ExtensionRelease(
|
||||
name=r.name,
|
||||
description=r.name,
|
||||
@@ -313,8 +377,8 @@ class ExtensionRelease(BaseModel):
|
||||
|
||||
@classmethod
|
||||
def from_explicit_release(
|
||||
cls, source_repo: str, e: ExplicitRelease
|
||||
) -> ExtensionRelease:
|
||||
cls, source_repo: str, e: "ExplicitRelease"
|
||||
) -> "ExtensionRelease":
|
||||
return ExtensionRelease(
|
||||
name=e.name,
|
||||
version=e.version,
|
||||
@@ -333,9 +397,9 @@ class ExtensionRelease(BaseModel):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def get_github_releases(cls, org: str, repo: str) -> list[ExtensionRelease]:
|
||||
async def get_github_releases(cls, org: str, repo: str) -> List["ExtensionRelease"]:
|
||||
try:
|
||||
github_releases = await cls.fetch_github_releases(org, repo)
|
||||
github_releases = await fetch_github_releases(org, repo)
|
||||
return [
|
||||
ExtensionRelease.from_github_release(f"{org}/{repo}", r)
|
||||
for r in github_releases
|
||||
@@ -344,33 +408,6 @@ class ExtensionRelease(BaseModel):
|
||||
logger.warning(e)
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
async def fetch_github_releases(
|
||||
cls, org: str, repo: str
|
||||
) -> list[GitHubRepoRelease]:
|
||||
releases_url = f"https://api.github.com/repos/{org}/{repo}/releases"
|
||||
error_msg = "Cannot fetch extension releases"
|
||||
releases = await github_api_get(releases_url, error_msg)
|
||||
return [GitHubRepoRelease.parse_obj(r) for r in releases]
|
||||
|
||||
@classmethod
|
||||
async def fetch_release_details(cls, details_link: str) -> Optional[dict]:
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
resp = await client.get(details_link)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
if "description_md" in data:
|
||||
resp = await client.get(data["description_md"])
|
||||
if not resp.is_error:
|
||||
data["description_md"] = resp.text
|
||||
|
||||
return data
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
return None
|
||||
|
||||
|
||||
class InstallableExtension(BaseModel):
|
||||
id: str
|
||||
@@ -378,13 +415,13 @@ class InstallableExtension(BaseModel):
|
||||
active: Optional[bool] = False
|
||||
short_description: Optional[str] = None
|
||||
icon: Optional[str] = None
|
||||
dependencies: list[str] = []
|
||||
dependencies: List[str] = []
|
||||
is_admin_only: bool = False
|
||||
stars: int = 0
|
||||
featured = False
|
||||
latest_release: Optional[ExtensionRelease] = None
|
||||
installed_release: Optional[ExtensionRelease] = None
|
||||
payments: list[ReleasePaymentInfo] = []
|
||||
payments: List[ReleasePaymentInfo] = []
|
||||
pay_to_enable: Optional[PayToEnableInfo] = None
|
||||
archive: Optional[str] = None
|
||||
|
||||
@@ -509,6 +546,16 @@ class InstallableExtension(BaseModel):
|
||||
shutil.copytree(Path(self.ext_upgrade_dir), Path(self.ext_dir))
|
||||
logger.success(f"Extension {self.name} ({self.installed_version}) installed.")
|
||||
|
||||
def notify_upgrade(self, upgrade_hash: Optional[str]) -> None:
|
||||
"""
|
||||
Update the list of upgraded extensions. The middleware will perform
|
||||
redirects based on this
|
||||
"""
|
||||
if upgrade_hash:
|
||||
settings.lnbits_upgraded_extensions.add(f"{self.hash}/{self.id}")
|
||||
|
||||
settings.lnbits_all_extensions_ids.add(self.id)
|
||||
|
||||
def clean_extension_files(self):
|
||||
# remove downloaded archive
|
||||
if self.zip_path.is_file():
|
||||
@@ -563,7 +610,7 @@ class InstallableExtension(BaseModel):
|
||||
self.payments.append(payment_info)
|
||||
|
||||
@classmethod
|
||||
def from_row(cls, data: dict) -> InstallableExtension:
|
||||
def from_row(cls, data: dict) -> "InstallableExtension":
|
||||
meta = json.loads(data["meta"])
|
||||
ext = InstallableExtension(**data)
|
||||
if "installed_release" in meta:
|
||||
@@ -576,7 +623,9 @@ class InstallableExtension(BaseModel):
|
||||
return ext
|
||||
|
||||
@classmethod
|
||||
def from_rows(cls, rows: Optional[list[Any]] = None) -> list[InstallableExtension]:
|
||||
def from_rows(
|
||||
cls, rows: Optional[List[Any]] = None
|
||||
) -> List["InstallableExtension"]:
|
||||
if rows is None:
|
||||
rows = []
|
||||
return [InstallableExtension.from_row(row) for row in rows]
|
||||
@@ -584,9 +633,9 @@ class InstallableExtension(BaseModel):
|
||||
@classmethod
|
||||
async def from_github_release(
|
||||
cls, github_release: GitHubRelease
|
||||
) -> Optional[InstallableExtension]:
|
||||
) -> Optional["InstallableExtension"]:
|
||||
try:
|
||||
repo, latest_release, config = await cls.fetch_github_repo_info(
|
||||
repo, latest_release, config = await fetch_github_repo_info(
|
||||
github_release.organisation, github_release.repository
|
||||
)
|
||||
source_repo = f"{github_release.organisation}/{github_release.repository}"
|
||||
@@ -608,7 +657,7 @@ class InstallableExtension(BaseModel):
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def from_explicit_release(cls, e: ExplicitRelease) -> InstallableExtension:
|
||||
def from_explicit_release(cls, e: ExplicitRelease) -> "InstallableExtension":
|
||||
return InstallableExtension(
|
||||
id=e.id,
|
||||
name=e.name,
|
||||
@@ -621,13 +670,13 @@ class InstallableExtension(BaseModel):
|
||||
@classmethod
|
||||
async def get_installable_extensions(
|
||||
cls,
|
||||
) -> list[InstallableExtension]:
|
||||
extension_list: list[InstallableExtension] = []
|
||||
extension_id_list: list[str] = []
|
||||
) -> List["InstallableExtension"]:
|
||||
extension_list: List[InstallableExtension] = []
|
||||
extension_id_list: List[str] = []
|
||||
|
||||
for url in settings.lnbits_extensions_manifests:
|
||||
try:
|
||||
manifest = await cls.fetch_manifest(url)
|
||||
manifest = await fetch_manifest(url)
|
||||
|
||||
for r in manifest.repos:
|
||||
ext = await InstallableExtension.from_github_release(r)
|
||||
@@ -663,12 +712,12 @@ class InstallableExtension(BaseModel):
|
||||
return extension_list
|
||||
|
||||
@classmethod
|
||||
async def get_extension_releases(cls, ext_id: str) -> list[ExtensionRelease]:
|
||||
extension_releases: list[ExtensionRelease] = []
|
||||
async def get_extension_releases(cls, ext_id: str) -> List["ExtensionRelease"]:
|
||||
extension_releases: List[ExtensionRelease] = []
|
||||
|
||||
for url in settings.lnbits_extensions_manifests:
|
||||
try:
|
||||
manifest = await cls.fetch_manifest(url)
|
||||
manifest = await fetch_manifest(url)
|
||||
for r in manifest.repos:
|
||||
if r.id != ext_id:
|
||||
continue
|
||||
@@ -692,8 +741,8 @@ class InstallableExtension(BaseModel):
|
||||
@classmethod
|
||||
async def get_extension_release(
|
||||
cls, ext_id: str, source_repo: str, archive: str, version: str
|
||||
) -> Optional[ExtensionRelease]:
|
||||
all_releases: list[ExtensionRelease] = (
|
||||
) -> Optional["ExtensionRelease"]:
|
||||
all_releases: List[ExtensionRelease] = (
|
||||
await InstallableExtension.get_extension_releases(ext_id)
|
||||
)
|
||||
selected_release = [
|
||||
@@ -706,37 +755,6 @@ class InstallableExtension(BaseModel):
|
||||
|
||||
return selected_release[0] if len(selected_release) != 0 else None
|
||||
|
||||
@classmethod
|
||||
async def fetch_github_repo_info(
|
||||
cls, org: str, repository: str
|
||||
) -> tuple[GitHubRepo, GitHubRepoRelease, ExtensionConfig]:
|
||||
repo_url = f"https://api.github.com/repos/{org}/{repository}"
|
||||
error_msg = "Cannot fetch extension repo"
|
||||
repo = await github_api_get(repo_url, error_msg)
|
||||
github_repo = GitHubRepo.parse_obj(repo)
|
||||
|
||||
lates_release_url = (
|
||||
f"https://api.github.com/repos/{org}/{repository}/releases/latest"
|
||||
)
|
||||
error_msg = "Cannot fetch extension releases"
|
||||
latest_release: Any = await github_api_get(lates_release_url, error_msg)
|
||||
|
||||
config_url = f"https://raw.githubusercontent.com/{org}/{repository}/{github_repo.default_branch}/config.json"
|
||||
error_msg = "Cannot fetch config for extension"
|
||||
config = await github_api_get(config_url, error_msg)
|
||||
|
||||
return (
|
||||
github_repo,
|
||||
GitHubRepoRelease.parse_obj(latest_release),
|
||||
ExtensionConfig.parse_obj(config),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def fetch_manifest(cls, url) -> Manifest:
|
||||
error_msg = "Cannot fetch extensions manifest"
|
||||
manifest = await github_api_get(url, error_msg)
|
||||
return Manifest.parse_obj(manifest)
|
||||
|
||||
|
||||
class CreateExtension(BaseModel):
|
||||
ext_id: str
|
||||
@@ -751,3 +769,32 @@ class ExtensionDetailsRequest(BaseModel):
|
||||
ext_id: str
|
||||
source_repo: str
|
||||
version: str
|
||||
|
||||
|
||||
def get_valid_extensions(include_deactivated: Optional[bool] = True) -> List[Extension]:
|
||||
valid_extensions = [
|
||||
extension for extension in ExtensionManager().extensions if extension.is_valid
|
||||
]
|
||||
|
||||
if include_deactivated:
|
||||
return valid_extensions
|
||||
|
||||
if settings.lnbits_extensions_deactivate_all:
|
||||
return []
|
||||
|
||||
return [
|
||||
e
|
||||
for e in valid_extensions
|
||||
if e.code not in settings.lnbits_deactivated_extensions
|
||||
]
|
||||
|
||||
|
||||
def version_parse(v: str):
|
||||
"""
|
||||
Wrapper for version.parse() that does not throw if the version is invalid.
|
||||
Instead it return the lowest possible version ("0.0.0")
|
||||
"""
|
||||
try:
|
||||
return version.parse(v)
|
||||
except Exception:
|
||||
return version.parse("0.0.0")
|
||||
+2
-4
@@ -10,7 +10,6 @@ import shortuuid
|
||||
from pydantic import BaseModel
|
||||
from pydantic.schema import field_schema
|
||||
|
||||
from lnbits.core.extensions.models import Extension
|
||||
from lnbits.db import get_placeholder
|
||||
from lnbits.jinja2_templating import Jinja2Templates
|
||||
from lnbits.nodes import get_node_class
|
||||
@@ -19,6 +18,7 @@ from lnbits.settings import settings
|
||||
from lnbits.utils.crypto import AESCipher
|
||||
|
||||
from .db import FilterModel
|
||||
from .extension_manager import get_valid_extensions
|
||||
|
||||
|
||||
def get_db_vendor_name():
|
||||
@@ -93,21 +93,19 @@ def template_renderer(additional_folders: Optional[List] = None) -> Jinja2Templa
|
||||
settings.lnbits_node_ui and get_node_class() is not None
|
||||
)
|
||||
t.env.globals["LNBITS_NODE_UI_AVAILABLE"] = get_node_class() is not None
|
||||
t.env.globals["EXTENSIONS"] = Extension.get_valid_extensions(False)
|
||||
t.env.globals["EXTENSIONS"] = get_valid_extensions(False)
|
||||
if settings.lnbits_custom_logo:
|
||||
t.env.globals["USE_CUSTOM_LOGO"] = settings.lnbits_custom_logo
|
||||
|
||||
if settings.bundle_assets:
|
||||
t.env.globals["INCLUDED_JS"] = ["bundle.min.js"]
|
||||
t.env.globals["INCLUDED_CSS"] = ["bundle.min.css"]
|
||||
t.env.globals["INCLUDED_COMPONENTS"] = ["bundle-components.min.js"]
|
||||
else:
|
||||
vendor_filepath = Path(settings.lnbits_path, "static", "vendor.json")
|
||||
with open(vendor_filepath) as vendor_file:
|
||||
vendor_files = json.loads(vendor_file.read())
|
||||
t.env.globals["INCLUDED_JS"] = vendor_files["js"]
|
||||
t.env.globals["INCLUDED_CSS"] = vendor_files["css"]
|
||||
t.env.globals["INCLUDED_COMPONENTS"] = vendor_files["components"]
|
||||
|
||||
t.env.globals["WEBPUSH_PUBKEY"] = settings.lnbits_webpush_pubkey
|
||||
|
||||
|
||||
+72
-7
@@ -1,5 +1,5 @@
|
||||
from http import HTTPStatus
|
||||
from typing import Any, List, Union
|
||||
from typing import Any, List, Tuple, Union
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse
|
||||
@@ -45,11 +45,16 @@ class InstalledExtensionMiddleware:
|
||||
await self.app(scope, receive, send)
|
||||
return
|
||||
|
||||
upgrade_path = next(
|
||||
(
|
||||
e
|
||||
for e in settings.lnbits_upgraded_extensions
|
||||
if e.endswith(f"/{top_path}")
|
||||
),
|
||||
None,
|
||||
)
|
||||
# re-route all trafic if the extension has been upgraded
|
||||
if top_path in settings.lnbits_upgraded_extensions:
|
||||
upgrade_path = (
|
||||
f"""{settings.lnbits_upgraded_extensions[top_path]}/{top_path}"""
|
||||
)
|
||||
if upgrade_path:
|
||||
tail = "/".join(rest)
|
||||
scope["path"] = f"/upgrades/{upgrade_path}/{tail}"
|
||||
|
||||
@@ -113,12 +118,72 @@ class ExtensionsRedirectMiddleware:
|
||||
return
|
||||
|
||||
req_headers = scope["headers"] if "headers" in scope else []
|
||||
redirect = settings.find_extension_redirect(scope["path"], req_headers)
|
||||
redirect = self._find_redirect(scope["path"], req_headers)
|
||||
if redirect:
|
||||
scope["path"] = redirect.new_path_from(scope["path"])
|
||||
scope["path"] = self._new_path(redirect, scope["path"])
|
||||
|
||||
await self.app(scope, receive, send)
|
||||
|
||||
def _find_redirect(self, path: str, req_headers: List[Tuple[bytes, bytes]]):
|
||||
return next(
|
||||
(
|
||||
r
|
||||
for r in settings.lnbits_extensions_redirects
|
||||
if self._redirect_matches(r, path, req_headers)
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
def _redirect_matches(
|
||||
self, redirect: dict, path: str, req_headers: List[Tuple[bytes, bytes]]
|
||||
) -> bool:
|
||||
if "from_path" not in redirect:
|
||||
return False
|
||||
header_filters = (
|
||||
redirect["header_filters"] if "header_filters" in redirect else {}
|
||||
)
|
||||
return self._has_common_path(redirect["from_path"], path) and self._has_headers(
|
||||
header_filters, req_headers
|
||||
)
|
||||
|
||||
def _has_headers(
|
||||
self, filter_headers: dict, req_headers: List[Tuple[bytes, bytes]]
|
||||
) -> bool:
|
||||
for h in filter_headers:
|
||||
if not self._has_header(req_headers, (str(h), str(filter_headers[h]))):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _has_header(
|
||||
self, req_headers: List[Tuple[bytes, bytes]], header: Tuple[str, str]
|
||||
) -> bool:
|
||||
for h in req_headers:
|
||||
if (
|
||||
h[0].decode().lower() == header[0].lower()
|
||||
and h[1].decode() == header[1]
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _has_common_path(self, redirect_path: str, req_path: str) -> bool:
|
||||
redirect_path_elements = redirect_path.split("/")
|
||||
req_path_elements = req_path.split("/")
|
||||
if len(redirect_path) > len(req_path):
|
||||
return False
|
||||
sub_path = req_path_elements[: len(redirect_path_elements)]
|
||||
return redirect_path == "/".join(sub_path)
|
||||
|
||||
def _new_path(self, redirect: dict, req_path: str) -> str:
|
||||
from_path = redirect["from_path"].split("/")
|
||||
redirect_to = redirect["redirect_to_path"].split("/")
|
||||
req_tail_path = req_path.split("/")[len(from_path) :]
|
||||
|
||||
elements = [
|
||||
e for e in ([redirect["ext_id"], *redirect_to, *req_tail_path]) if e != ""
|
||||
]
|
||||
|
||||
return "/" + "/".join(elements)
|
||||
|
||||
|
||||
def add_ratelimit_middleware(app: FastAPI):
|
||||
core_app_extra.register_new_ratelimiter()
|
||||
|
||||
+7
-113
@@ -62,132 +62,26 @@ class ExtensionsInstallSettings(LNbitsSettings):
|
||||
lnbits_ext_github_token: str = Field(default="")
|
||||
|
||||
|
||||
class RedirectPath(BaseModel):
|
||||
ext_id: str
|
||||
from_path: str
|
||||
redirect_to_path: str
|
||||
header_filters: dict = {}
|
||||
|
||||
def in_conflict(self, other: RedirectPath) -> bool:
|
||||
if self.ext_id == other.ext_id:
|
||||
return False
|
||||
return self.redirect_matches(
|
||||
other.from_path, list(other.header_filters.items())
|
||||
) or other.redirect_matches(self.from_path, list(self.header_filters.items()))
|
||||
|
||||
def find_in_conflict(self, others: list[RedirectPath]) -> Optional[RedirectPath]:
|
||||
for other in others:
|
||||
if self.in_conflict(other):
|
||||
return other
|
||||
return None
|
||||
|
||||
def new_path_from(self, req_path: str) -> str:
|
||||
from_path = self.from_path.split("/")
|
||||
redirect_to = self.redirect_to_path.split("/")
|
||||
req_tail_path = req_path.split("/")[len(from_path) :]
|
||||
|
||||
elements = [e for e in ([self.ext_id, *redirect_to, *req_tail_path]) if e != ""]
|
||||
|
||||
return "/" + "/".join(elements)
|
||||
|
||||
def redirect_matches(self, path: str, req_headers: list[tuple[str, str]]) -> bool:
|
||||
return self._has_common_path(path) and self._has_headers(req_headers)
|
||||
|
||||
def _has_common_path(self, req_path: str) -> bool:
|
||||
if len(self.from_path) > len(req_path):
|
||||
return False
|
||||
|
||||
redirect_path_elements = self.from_path.split("/")
|
||||
req_path_elements = req_path.split("/")
|
||||
|
||||
sub_path = req_path_elements[: len(redirect_path_elements)]
|
||||
return self.from_path == "/".join(sub_path)
|
||||
|
||||
def _has_headers(self, req_headers: list[tuple[str, str]]) -> bool:
|
||||
for h in self.header_filters:
|
||||
if not self._has_header(req_headers, (str(h), str(self.header_filters[h]))):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _has_header(
|
||||
self, req_headers: list[tuple[str, str]], header: tuple[str, str]
|
||||
) -> bool:
|
||||
for h in req_headers:
|
||||
if h[0].lower() == header[0].lower() and h[1].lower() == header[1].lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class InstalledExtensionsSettings(LNbitsSettings):
|
||||
# installed extensions that have been deactivated
|
||||
lnbits_deactivated_extensions: set[str] = Field(default=[])
|
||||
# upgraded extensions that require API redirects
|
||||
lnbits_upgraded_extensions: dict[str, str] = Field(default={})
|
||||
lnbits_upgraded_extensions: set[str] = Field(default=[])
|
||||
# list of redirects that extensions want to perform
|
||||
lnbits_extensions_redirects: list[RedirectPath] = Field(default=[])
|
||||
lnbits_extensions_redirects: list[Any] = Field(default=[])
|
||||
|
||||
# list of all extension ids
|
||||
lnbits_all_extensions_ids: set[Any] = Field(default=[])
|
||||
|
||||
def find_extension_redirect(
|
||||
self, path: str, req_headers: list[tuple[bytes, bytes]]
|
||||
) -> Optional[RedirectPath]:
|
||||
headers = [(k.decode(), v.decode()) for k, v in req_headers]
|
||||
def extension_upgrade_path(self, ext_id: str) -> Optional[str]:
|
||||
return next(
|
||||
(
|
||||
r
|
||||
for r in self.lnbits_extensions_redirects
|
||||
if r.redirect_matches(path, headers)
|
||||
),
|
||||
(e for e in self.lnbits_upgraded_extensions if e.endswith(f"/{ext_id}")),
|
||||
None,
|
||||
)
|
||||
|
||||
def activate_extension_paths(
|
||||
self,
|
||||
ext_id: str,
|
||||
upgrade_hash: Optional[str] = None,
|
||||
ext_redirects: Optional[list[dict]] = None,
|
||||
):
|
||||
self.lnbits_deactivated_extensions.discard(ext_id)
|
||||
|
||||
"""
|
||||
Update the list of upgraded extensions. The middleware will perform
|
||||
redirects based on this
|
||||
"""
|
||||
if upgrade_hash:
|
||||
self.lnbits_upgraded_extensions[ext_id] = upgrade_hash
|
||||
|
||||
if ext_redirects:
|
||||
self._activate_extension_redirects(ext_id, ext_redirects)
|
||||
|
||||
self.lnbits_all_extensions_ids.add(ext_id)
|
||||
|
||||
def deactivate_extension_paths(self, ext_id: str):
|
||||
self.lnbits_deactivated_extensions.add(ext_id)
|
||||
self._remove_extension_redirects(ext_id)
|
||||
|
||||
def _activate_extension_redirects(self, ext_id: str, ext_redirects: list[dict]):
|
||||
ext_redirect_paths = [
|
||||
RedirectPath(**{"ext_id": ext_id, **er}) for er in ext_redirects
|
||||
]
|
||||
existing_redirects = {
|
||||
r.ext_id
|
||||
for r in self.lnbits_extensions_redirects
|
||||
if r.find_in_conflict(ext_redirect_paths)
|
||||
}
|
||||
|
||||
assert len(existing_redirects) == 0, (
|
||||
f"Cannot redirect for extension '{ext_id}'."
|
||||
f" Already mapped by {existing_redirects}."
|
||||
)
|
||||
|
||||
self._remove_extension_redirects(ext_id)
|
||||
self.lnbits_extensions_redirects += ext_redirect_paths
|
||||
|
||||
def _remove_extension_redirects(self, ext_id: str):
|
||||
self.lnbits_extensions_redirects = [
|
||||
er for er in self.lnbits_extensions_redirects if er.ext_id != ext_id
|
||||
]
|
||||
def extension_upgrade_hash(self, ext_id: str) -> Optional[str]:
|
||||
path = settings.extension_upgrade_path(ext_id)
|
||||
return path.split("/")[0] if path else None
|
||||
|
||||
|
||||
class ThemesSettings(LNbitsSettings):
|
||||
|
||||
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+41
-29
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
window.app = Vue.createApp({
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [window.windowMixin],
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
return {
|
||||
user: null,
|
||||
@@ -80,6 +80,20 @@ window.app = Vue.createApp({
|
||||
this.applyGradient()
|
||||
}
|
||||
},
|
||||
setColors: function () {
|
||||
this.$q.localStorage.set(
|
||||
'lnbits.primaryColor',
|
||||
LNbits.utils.getPaletteColor('primary')
|
||||
)
|
||||
this.$q.localStorage.set(
|
||||
'lnbits.secondaryColor',
|
||||
LNbits.utils.getPaletteColor('secondary')
|
||||
)
|
||||
this.$q.localStorage.set(
|
||||
'lnbits.darkBgColor',
|
||||
LNbits.utils.getPaletteColor('dark')
|
||||
)
|
||||
},
|
||||
updateAccount: async function () {
|
||||
try {
|
||||
const {data} = await LNbits.api.request(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
window.app = Vue.createApp({
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
|
||||
+18
-75
@@ -1,10 +1,15 @@
|
||||
/* globals crypto, moment, Vue, axios, Quasar, _ */
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
window.LOCALE = 'en'
|
||||
window.i18n = new VueI18n.createI18n({
|
||||
window.i18n = new VueI18n({
|
||||
locale: window.LOCALE,
|
||||
fallbackLocale: window.LOCALE,
|
||||
messages: window.localisation
|
||||
})
|
||||
|
||||
window.EventHub = new Vue()
|
||||
window.LNbits = {
|
||||
api: {
|
||||
request: function (method, url, apiKey, data) {
|
||||
@@ -259,12 +264,12 @@ window.LNbits = {
|
||||
fiat_currency: data.fiat_currency
|
||||
}
|
||||
|
||||
obj.date = Quasar.date.formatDate(
|
||||
obj.date = Quasar.utils.date.formatDate(
|
||||
new Date(obj.time * 1000),
|
||||
'YYYY-MM-DD HH:mm'
|
||||
)
|
||||
obj.dateFrom = moment(obj.date).fromNow()
|
||||
obj.expirydate = Quasar.date.formatDate(
|
||||
obj.expirydate = Quasar.utils.date.formatDate(
|
||||
new Date(obj.expiry * 1000),
|
||||
'YYYY-MM-DD HH:mm'
|
||||
)
|
||||
@@ -289,7 +294,7 @@ window.LNbits = {
|
||||
},
|
||||
utils: {
|
||||
confirmDialog: function (msg) {
|
||||
return Quasar.Dialog.create({
|
||||
return Quasar.plugins.Dialog.create({
|
||||
message: msg,
|
||||
ok: {
|
||||
flat: true,
|
||||
@@ -406,14 +411,14 @@ window.LNbits = {
|
||||
)
|
||||
.join('\r\n')
|
||||
|
||||
var status = Quasar.exportFile(
|
||||
var status = Quasar.utils.exportFile(
|
||||
`${fileName || 'table-export'}.csv`,
|
||||
content,
|
||||
'text/csv'
|
||||
)
|
||||
|
||||
if (status !== true) {
|
||||
Quasar.Notify.create({
|
||||
Quasar.plugins.Notify.create({
|
||||
message: 'Browser denied file download...',
|
||||
color: 'negative',
|
||||
icon: null
|
||||
@@ -427,16 +432,16 @@ window.LNbits = {
|
||||
return converter.makeHtml(text)
|
||||
},
|
||||
hexToRgb: function (hex) {
|
||||
return Quasar.colors.hexToRgb(hex)
|
||||
return Quasar.utils.colors.hexToRgb(hex)
|
||||
},
|
||||
hexDarken: function (hex, percent) {
|
||||
return Quasar.colors.lighten(hex, percent)
|
||||
return Quasar.utils.colors.lighten(hex, percent)
|
||||
},
|
||||
hexAlpha: function (hex, alpha) {
|
||||
return Quasar.colors.changeAlpha(hex, alpha)
|
||||
return Quasar.utils.colors.changeAlpha(hex, alpha)
|
||||
},
|
||||
getPaletteColor: function (color) {
|
||||
return Quasar.colors.getPaletteColor(color)
|
||||
return Quasar.utils.colors.getPaletteColor(color)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -470,7 +475,6 @@ window.windowMixin = {
|
||||
},
|
||||
applyGradient: function () {
|
||||
if (this.$q.localStorage.getItem('lnbits.gradientBg')) {
|
||||
this.setColors()
|
||||
darkBgColor = this.$q.localStorage.getItem('lnbits.darkBgColor')
|
||||
primaryColor = this.$q.localStorage.getItem('lnbits.primaryColor')
|
||||
const gradientStyle = `linear-gradient(to bottom right, ${LNbits.utils.hexDarken(String(primaryColor), -70)}, #0a0a0a)`
|
||||
@@ -488,23 +492,9 @@ window.windowMixin = {
|
||||
document.head.appendChild(style)
|
||||
}
|
||||
},
|
||||
setColors: function () {
|
||||
this.$q.localStorage.set(
|
||||
'lnbits.primaryColor',
|
||||
LNbits.utils.getPaletteColor('primary')
|
||||
)
|
||||
this.$q.localStorage.set(
|
||||
'lnbits.secondaryColor',
|
||||
LNbits.utils.getPaletteColor('secondary')
|
||||
)
|
||||
this.$q.localStorage.set(
|
||||
'lnbits.darkBgColor',
|
||||
LNbits.utils.getPaletteColor('dark')
|
||||
)
|
||||
},
|
||||
copyText: function (text, message, position) {
|
||||
var notify = this.$q.notify
|
||||
Quasar.copyToClipboard(text).then(function () {
|
||||
Quasar.utils.copyToClipboard(text).then(function () {
|
||||
notify({
|
||||
message: message || 'Copied to clipboard!',
|
||||
position: position || 'bottom'
|
||||
@@ -551,52 +541,6 @@ window.windowMixin = {
|
||||
LNbits.utils.notifyApiError(e)
|
||||
}
|
||||
})
|
||||
},
|
||||
themeParams() {
|
||||
const url = new URL(window.location.href)
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const fields = ['theme', 'dark', 'gradient']
|
||||
const toBoolean = value =>
|
||||
value.trim().toLowerCase() === 'true' || value === '1'
|
||||
|
||||
// Check if any of the relevant parameters ('theme', 'dark', 'gradient') are present in the URL.
|
||||
if (fields.some(param => params.has(param))) {
|
||||
const theme = params.get('theme')
|
||||
const darkMode = params.get('dark')
|
||||
const gradient = params.get('gradient')
|
||||
|
||||
if (
|
||||
theme &&
|
||||
this.g.allowedThemes.includes(theme.trim().toLowerCase())
|
||||
) {
|
||||
const normalizedTheme = theme.trim().toLowerCase()
|
||||
document.body.setAttribute('data-theme', normalizedTheme)
|
||||
this.$q.localStorage.set('lnbits.theme', normalizedTheme)
|
||||
}
|
||||
|
||||
if (darkMode) {
|
||||
const isDark = toBoolean(darkMode)
|
||||
this.$q.localStorage.set('lnbits.darkMode', isDark)
|
||||
if (!isDark) {
|
||||
this.$q.localStorage.set('lnbits.gradientBg', false)
|
||||
}
|
||||
}
|
||||
|
||||
if (gradient) {
|
||||
const isGradient = toBoolean(gradient)
|
||||
this.$q.localStorage.set('lnbits.gradientBg', isGradient)
|
||||
if (isGradient) {
|
||||
this.$q.localStorage.set('lnbits.darkMode', true)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove processed parameters
|
||||
fields.forEach(param => params.delete(param))
|
||||
|
||||
window.history.replaceState(null, null, url.pathname)
|
||||
}
|
||||
|
||||
this.setColors()
|
||||
}
|
||||
},
|
||||
created: async function () {
|
||||
@@ -611,6 +555,8 @@ window.windowMixin = {
|
||||
this.reactionChoice =
|
||||
this.$q.localStorage.getItem('lnbits.reactions') || 'confettiBothSides'
|
||||
|
||||
this.applyGradient()
|
||||
|
||||
this.g.allowedThemes = window.allowedThemes ?? ['bitcoin']
|
||||
|
||||
let locale = this.$q.localStorage.getItem('lnbits.lang')
|
||||
@@ -649,8 +595,6 @@ window.windowMixin = {
|
||||
)
|
||||
}
|
||||
|
||||
this.applyGradient()
|
||||
|
||||
if (window.user) {
|
||||
this.g.user = Object.freeze(window.LNbits.map.user(window.user))
|
||||
}
|
||||
@@ -689,7 +633,6 @@ window.windowMixin = {
|
||||
this.g.extensions = extensions
|
||||
}
|
||||
await this.checkUsrInUrl()
|
||||
this.themeParams()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
window.app.component(QrcodeVue)
|
||||
/* global _, Vue, moment, LNbits, EventHub, decryptLnurlPayAES */
|
||||
|
||||
window.app.component('lnbits-fsat', {
|
||||
Vue.component('lnbits-fsat', {
|
||||
props: {
|
||||
amount: {
|
||||
type: Number,
|
||||
@@ -15,13 +15,12 @@ window.app.component('lnbits-fsat', {
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-wallet-list', {
|
||||
props: ['balance'],
|
||||
Vue.component('lnbits-wallet-list', {
|
||||
data: function () {
|
||||
return {
|
||||
user: null,
|
||||
activeWallet: null,
|
||||
balance: 0,
|
||||
activeBalance: [],
|
||||
showForm: false,
|
||||
walletName: '',
|
||||
LNBITS_DENOMINATION: LNBITS_DENOMINATION
|
||||
@@ -75,7 +74,7 @@ window.app.component('lnbits-wallet-list', {
|
||||
`,
|
||||
computed: {
|
||||
wallets: function () {
|
||||
var bal = this.balance
|
||||
var bal = this.activeBalance
|
||||
return this.user.wallets.map(function (obj) {
|
||||
obj.live_fsat =
|
||||
bal.length && bal[0] === obj.id
|
||||
@@ -88,6 +87,9 @@ window.app.component('lnbits-wallet-list', {
|
||||
methods: {
|
||||
createWallet: function () {
|
||||
LNbits.api.createWallet(this.user.wallets[0], this.walletName)
|
||||
},
|
||||
updateWalletBalance: function (payload) {
|
||||
this.activeBalance = payload
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
@@ -97,11 +99,11 @@ window.app.component('lnbits-wallet-list', {
|
||||
if (window.wallet) {
|
||||
this.activeWallet = LNbits.map.wallet(window.wallet)
|
||||
}
|
||||
document.addEventListener('updateWalletBalance', this.updateWalletBalance)
|
||||
EventHub.$on('update-wallet-balance', this.updateWalletBalance)
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-extension-list', {
|
||||
Vue.component('lnbits-extension-list', {
|
||||
data: function () {
|
||||
return {
|
||||
extensions: [],
|
||||
@@ -167,7 +169,7 @@ window.app.component('lnbits-extension-list', {
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-manage', {
|
||||
Vue.component('lnbits-manage', {
|
||||
props: ['showAdmin', 'showNode', 'showExtensions', 'showUsers'],
|
||||
methods: {
|
||||
isActive: function (path) {
|
||||
@@ -227,9 +229,9 @@ window.app.component('lnbits-manage', {
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-payment-details', {
|
||||
Vue.component('lnbits-payment-details', {
|
||||
props: ['payment'],
|
||||
mixins: [window.windowMixin],
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
return {
|
||||
LNBITS_DENOMINATION: LNBITS_DENOMINATION
|
||||
@@ -343,7 +345,7 @@ window.app.component('lnbits-payment-details', {
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-lnurlpay-success-action', {
|
||||
Vue.component('lnbits-lnurlpay-success-action', {
|
||||
props: ['payment', 'success_action'],
|
||||
data() {
|
||||
return {
|
||||
@@ -372,12 +374,10 @@ window.app.component('lnbits-lnurlpay-success-action', {
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-qrcode', {
|
||||
mixins: [window.windowMixin],
|
||||
components: {
|
||||
QrcodeVue
|
||||
},
|
||||
Vue.component('lnbits-qrcode', {
|
||||
mixins: [windowMixin],
|
||||
props: ['value'],
|
||||
components: {[VueQrcode.name]: VueQrcode},
|
||||
data() {
|
||||
return {
|
||||
logo: LNBITS_QR_LOGO
|
||||
@@ -385,14 +385,15 @@ window.app.component('lnbits-qrcode', {
|
||||
},
|
||||
template: `
|
||||
<div class="qrcode__wrapper">
|
||||
<qrcode-vue :value="value" size="350" class="rounded-borders"></qrcode-vue>
|
||||
<qrcode :value="value"
|
||||
:options="{errorCorrectionLevel: 'Q', width: 800}" class="rounded-borders"></qrcode>
|
||||
<img class="qrcode__image" :src="logo" alt="..." />
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-notifications-btn', {
|
||||
mixins: [window.windowMixin],
|
||||
Vue.component('lnbits-notifications-btn', {
|
||||
mixins: [windowMixin],
|
||||
props: ['pubkey'],
|
||||
data() {
|
||||
return {
|
||||
@@ -604,8 +605,8 @@ window.app.component('lnbits-notifications-btn', {
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-dynamic-fields', {
|
||||
mixins: [window.windowMixin],
|
||||
Vue.component('lnbits-dynamic-fields', {
|
||||
mixins: [windowMixin],
|
||||
props: ['options', 'value'],
|
||||
data() {
|
||||
return {
|
||||
@@ -741,8 +742,8 @@ window.app.component('lnbits-dynamic-fields', {
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-update-balance', {
|
||||
mixins: [window.windowMixin],
|
||||
Vue.component('lnbits-update-balance', {
|
||||
mixins: [windowMixin],
|
||||
props: ['wallet_id', 'callback'],
|
||||
computed: {
|
||||
denomination() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
window.app.component('lnbits-extension-rating', {
|
||||
Vue.component('lnbits-extension-rating', {
|
||||
name: 'lnbits-extension-rating',
|
||||
props: ['rating'],
|
||||
template: `
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
window.app.component('lnbits-extension-settings-form', {
|
||||
Vue.component('lnbits-extension-settings-form', {
|
||||
name: 'lnbits-extension-settings-form',
|
||||
props: ['options', 'adminkey', 'endpoint'],
|
||||
methods: {
|
||||
async updateSettings() {
|
||||
updateSettings: async function () {
|
||||
if (!this.settings) {
|
||||
return this.$q.notify({
|
||||
return Quasar.plugins.Notify.create({
|
||||
message: 'No settings to update',
|
||||
type: 'negative'
|
||||
})
|
||||
@@ -66,7 +66,7 @@ window.app.component('lnbits-extension-settings-form', {
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-extension-settings-btn-dialog', {
|
||||
Vue.component('lnbits-extension-settings-btn-dialog', {
|
||||
name: 'lnbits-extension-settings-btn-dialog',
|
||||
props: ['options', 'adminkey', 'endpoint'],
|
||||
template: `
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
window.app.component('lnbits-funding-sources', {
|
||||
mixins: [window.windowMixin],
|
||||
Vue.component('lnbits-funding-sources', {
|
||||
mixins: [windowMixin],
|
||||
props: ['form-data', 'allowed-funding-sources'],
|
||||
methods: {
|
||||
getFundingSourceLabel(item) {
|
||||
|
||||
@@ -80,10 +80,10 @@ function generateChart(canvas, rawData) {
|
||||
})
|
||||
}
|
||||
|
||||
window.app.component('payment-chart', {
|
||||
Vue.component('payment-chart', {
|
||||
name: 'payment-chart',
|
||||
props: ['wallet'],
|
||||
mixins: [window.windowMixin],
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
return {
|
||||
paymentsChart: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
window.app.component('payment-list', {
|
||||
Vue.component('payment-list', {
|
||||
name: 'payment-list',
|
||||
props: ['update', 'wallet', 'mobileSimple', 'lazy'],
|
||||
mixins: [window.windowMixin],
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
return {
|
||||
denomination: LNBITS_DENOMINATION,
|
||||
@@ -313,7 +313,7 @@ window.app.component('payment-list', {
|
||||
<q-table
|
||||
dense
|
||||
flat
|
||||
:rows="paymentsOmitter"
|
||||
:data="paymentsOmitter"
|
||||
:row-key="paymentTableRowKey"
|
||||
:columns="paymentsTable.columns"
|
||||
:pagination.sync="paymentsTable.pagination"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
window.app = Vue.createApp({
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [window.windowMixin],
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
return {
|
||||
disclaimerDialog: {
|
||||
@@ -93,6 +93,7 @@ window.app = Vue.createApp({
|
||||
},
|
||||
created() {
|
||||
this.description = SITE_DESCRIPTION
|
||||
|
||||
this.isUserAuthorized = !!this.$q.cookies.get('is_lnbits_user_authorized')
|
||||
if (this.isUserAuthorized) {
|
||||
window.location.href = '/wallet'
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
window.app.use(VueQrcodeReader)
|
||||
window.app.use(Quasar)
|
||||
window.app.use(window.i18n)
|
||||
window.app.mount('#vue')
|
||||
+12
-12
@@ -4,7 +4,7 @@ function shortenNodeId(nodeId) {
|
||||
: '...'
|
||||
}
|
||||
|
||||
window.app.component('lnbits-node-ranks', {
|
||||
Vue.component('lnbits-node-ranks', {
|
||||
props: ['ranks'],
|
||||
data: function () {
|
||||
return {
|
||||
@@ -35,7 +35,7 @@ window.app.component('lnbits-node-ranks', {
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-channel-stats', {
|
||||
Vue.component('lnbits-channel-stats', {
|
||||
props: ['stats'],
|
||||
data: function () {
|
||||
return {
|
||||
@@ -71,7 +71,7 @@ window.app.component('lnbits-channel-stats', {
|
||||
}
|
||||
})
|
||||
|
||||
window.app.component('lnbits-stat', {
|
||||
Vue.component('lnbits-stat', {
|
||||
props: ['title', 'amount', 'msat', 'btc'],
|
||||
computed: {
|
||||
value: function () {
|
||||
@@ -99,20 +99,20 @@ window.app.component('lnbits-stat', {
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-node-qrcode', {
|
||||
Vue.component('lnbits-node-qrcode', {
|
||||
props: ['info'],
|
||||
mixins: [window.windowMixin],
|
||||
mixins: [windowMixin],
|
||||
template: `
|
||||
<q-card class="my-card">
|
||||
<q-card-section>
|
||||
<div class="text-h6">
|
||||
<div style="text-align: center">
|
||||
<vue-qrcode
|
||||
<qrcode
|
||||
:value="info.addresses[0]"
|
||||
:options="{width: 250}"
|
||||
v-if='info.addresses[0]'
|
||||
class="rounded-borders"
|
||||
></vue-qrcode>
|
||||
></qrcode>
|
||||
<div v-else class='text-subtitle1'>
|
||||
No addresses available
|
||||
</div>
|
||||
@@ -132,14 +132,14 @@ window.app.component('lnbits-node-qrcode', {
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-node-info', {
|
||||
Vue.component('lnbits-node-info', {
|
||||
props: ['info'],
|
||||
data() {
|
||||
return {
|
||||
showDialog: false
|
||||
}
|
||||
},
|
||||
mixins: [window.windowMixin],
|
||||
mixins: [windowMixin],
|
||||
methods: {
|
||||
shortenNodeId
|
||||
},
|
||||
@@ -177,7 +177,7 @@ window.app.component('lnbits-node-info', {
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-stat', {
|
||||
Vue.component('lnbits-stat', {
|
||||
props: ['title', 'amount', 'msat', 'btc'],
|
||||
computed: {
|
||||
value: function () {
|
||||
@@ -205,7 +205,7 @@ window.app.component('lnbits-stat', {
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-channel-balance', {
|
||||
Vue.component('lnbits-channel-balance', {
|
||||
props: ['balance', 'color'],
|
||||
methods: {
|
||||
formatMsat: function (msat) {
|
||||
@@ -246,7 +246,7 @@ window.app.component('lnbits-channel-balance', {
|
||||
`
|
||||
})
|
||||
|
||||
window.app.component('lnbits-date', {
|
||||
Vue.component('lnbits-date', {
|
||||
props: ['ts'],
|
||||
computed: {
|
||||
date: function () {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
window.app = Vue.createApp({
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [window.windowMixin],
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
return {
|
||||
isSuperUser: false,
|
||||
@@ -164,41 +164,6 @@ window.app = Vue.createApp({
|
||||
this.chart1 = new Chart(this.$refs.chart1.getContext('2d'), {
|
||||
type: 'bubble',
|
||||
options: {
|
||||
scales: {
|
||||
xAxes: [
|
||||
{
|
||||
type: 'linear',
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
},
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
labelString: 'Tx count'
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxes: [
|
||||
{
|
||||
type: 'linear',
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
},
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
labelString: 'User balance in million sats'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function (tooltipItem, data) {
|
||||
const dataset = data.datasets[tooltipItem.datasetIndex]
|
||||
const dataPoint = dataset.data[tooltipItem.index]
|
||||
return dataPoint.customLabel || ''
|
||||
}
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
padding: 10
|
||||
}
|
||||
@@ -206,7 +171,7 @@ window.app = Vue.createApp({
|
||||
data: {
|
||||
datasets: [
|
||||
{
|
||||
label: 'Wallet balance vs transaction count',
|
||||
label: 'Balance - TX Count in million sats',
|
||||
backgroundColor: 'rgb(255, 99, 132)',
|
||||
data: []
|
||||
}
|
||||
@@ -218,6 +183,9 @@ window.app = Vue.createApp({
|
||||
formatSat: function (value) {
|
||||
return LNbits.utils.formatSat(Math.floor(value / 1000))
|
||||
},
|
||||
usersTableRowKey: function (row) {
|
||||
return row.id
|
||||
},
|
||||
createUser() {
|
||||
LNbits.api
|
||||
.request('POST', '/users/api/v1/user', null, this.createUserDialog.data)
|
||||
@@ -323,20 +291,10 @@ window.app = Vue.createApp({
|
||||
})
|
||||
|
||||
const data = filtered.map(user => {
|
||||
const labelUsername = `${user.username ? 'User: ' + user.username + '. ' : ''}`
|
||||
const userBalanceSats = Math.floor(
|
||||
user.balance_msat / 1000
|
||||
).toLocaleString()
|
||||
return {
|
||||
x: user.transaction_count,
|
||||
y: user.balance_msat / 1000000000,
|
||||
r: 4,
|
||||
customLabel:
|
||||
labelUsername +
|
||||
'Balance: ' +
|
||||
userBalanceSats +
|
||||
' sats. Tx count: ' +
|
||||
user.transaction_count
|
||||
r: 3
|
||||
}
|
||||
})
|
||||
this.chart1.data.datasets[0].data = data
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
window.app = Vue.createApp({
|
||||
/* globals windowMixin, decode, Vue, VueQrcodeReader, VueQrcode, Quasar, LNbits, _, EventHub, decryptLnurlPayAES */
|
||||
|
||||
Vue.component(VueQrcode.name, VueQrcode)
|
||||
Vue.use(VueQrcodeReader)
|
||||
|
||||
new Vue({
|
||||
el: '#vue',
|
||||
mixins: [window.windowMixin],
|
||||
mixins: [windowMixin],
|
||||
data: function () {
|
||||
return {
|
||||
updatePayments: false,
|
||||
@@ -316,7 +321,7 @@ window.app = Vue.createApp({
|
||||
var expireDate = new Date(
|
||||
(invoice.data.time_stamp + tag.value) * 1000
|
||||
)
|
||||
cleanInvoice.expireDate = this.$q.utils.date.formatDate(
|
||||
cleanInvoice.expireDate = Quasar.utils.date.formatDate(
|
||||
expireDate,
|
||||
'YYYY-MM-DDTHH:mm:ss.SSSZ'
|
||||
)
|
||||
@@ -509,11 +514,10 @@ window.app = Vue.createApp({
|
||||
fetchBalance: function () {
|
||||
LNbits.api.getWallet(this.g.wallet).then(response => {
|
||||
this.balance = Math.floor(response.data.balance / 1000)
|
||||
document.dispatchEvent(
|
||||
new CustomEvent('updateWalletBalance', {
|
||||
detail: [this.g.wallet.id, this.balance]
|
||||
})
|
||||
)
|
||||
EventHub.$emit('update-wallet-balance', [
|
||||
this.g.wallet.id,
|
||||
this.balance
|
||||
])
|
||||
})
|
||||
if (this.g.wallet.currency) {
|
||||
this.updateFiatBalance()
|
||||
|
||||
+13
-15
@@ -3,14 +3,15 @@
|
||||
"vendor/moment.js",
|
||||
"vendor/underscore.js",
|
||||
"vendor/axios.js",
|
||||
"vendor/vue.global.prod.js",
|
||||
"vendor/quasar.umd.prod.js",
|
||||
"vendor/vuex.global.js",
|
||||
"vendor/vue-i18n.global.prod.js",
|
||||
"vendor/vue-router.global.js",
|
||||
"vendor/vue-qrcode-reader.umd.js",
|
||||
"vendor/qrcode.vue.browser.js",
|
||||
"vendor/chart.umd.js",
|
||||
"vendor/vue.js",
|
||||
"vendor/vue-router.js",
|
||||
"vendor/VueQrcodeReader.umd.js",
|
||||
"vendor/vue-qrcode.js",
|
||||
"vendor/vuex.js",
|
||||
"vendor/quasar.ie.polyfills.umd.min.js",
|
||||
"vendor/quasar.umd.js",
|
||||
"vendor/Chart.bundle.js",
|
||||
"vendor/vue-i18n.js",
|
||||
"vendor/showdown.js",
|
||||
"i18n/i18n.js",
|
||||
"i18n/de.js",
|
||||
@@ -33,17 +34,14 @@
|
||||
"i18n/kr.js",
|
||||
"i18n/fi.js",
|
||||
"js/base.js",
|
||||
"js/event-reactions.js",
|
||||
"js/bolt11-decoder.js"
|
||||
],
|
||||
"components": [
|
||||
"js/components.js",
|
||||
"js/components/lnbits-funding-sources.js",
|
||||
"js/components/extension-settings.js",
|
||||
"js/components/extension-rating.js",
|
||||
"js/components/payment-list.js",
|
||||
"js/components/payment-chart.js",
|
||||
"js/components.js",
|
||||
"js/init-app.js"
|
||||
"js/event-reactions.js",
|
||||
"js/bolt11-decoder.js"
|
||||
],
|
||||
"css": ["vendor/quasar.css", "css/base.css"]
|
||||
"css": ["vendor/quasar.css", "vendor/Chart.css", "css/base.css"]
|
||||
}
|
||||
|
||||
Vendored
+131
-179
@@ -1,4 +1,4 @@
|
||||
// Axios v1.7.7 Copyright (c) 2024 Matt Zabriskie and contributors
|
||||
// Axios v1.7.5 Copyright (c) 2024 Matt Zabriskie and contributors
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
@@ -3093,42 +3093,38 @@
|
||||
};
|
||||
|
||||
var composeSignals = function composeSignals(signals, timeout) {
|
||||
var _signals = signals = signals ? signals.filter(Boolean) : [],
|
||||
length = _signals.length;
|
||||
if (timeout || length) {
|
||||
var controller = new AbortController();
|
||||
var aborted;
|
||||
var onabort = function onabort(reason) {
|
||||
if (!aborted) {
|
||||
aborted = true;
|
||||
unsubscribe();
|
||||
var err = reason instanceof Error ? reason : this.reason;
|
||||
controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));
|
||||
}
|
||||
};
|
||||
var timer = timeout && setTimeout(function () {
|
||||
var controller = new AbortController();
|
||||
var aborted;
|
||||
var onabort = function onabort(cancel) {
|
||||
if (!aborted) {
|
||||
aborted = true;
|
||||
unsubscribe();
|
||||
var err = cancel instanceof Error ? cancel : this.reason;
|
||||
controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));
|
||||
}
|
||||
};
|
||||
var timer = timeout && setTimeout(function () {
|
||||
onabort(new AxiosError("timeout ".concat(timeout, " of ms exceeded"), AxiosError.ETIMEDOUT));
|
||||
}, timeout);
|
||||
var unsubscribe = function unsubscribe() {
|
||||
if (signals) {
|
||||
timer && clearTimeout(timer);
|
||||
timer = null;
|
||||
onabort(new AxiosError("timeout ".concat(timeout, " of ms exceeded"), AxiosError.ETIMEDOUT));
|
||||
}, timeout);
|
||||
var unsubscribe = function unsubscribe() {
|
||||
if (signals) {
|
||||
timer && clearTimeout(timer);
|
||||
timer = null;
|
||||
signals.forEach(function (signal) {
|
||||
signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);
|
||||
});
|
||||
signals = null;
|
||||
}
|
||||
};
|
||||
signals.forEach(function (signal) {
|
||||
return signal.addEventListener('abort', onabort);
|
||||
});
|
||||
var signal = controller.signal;
|
||||
signal.unsubscribe = function () {
|
||||
return utils$1.asap(unsubscribe);
|
||||
};
|
||||
return signal;
|
||||
}
|
||||
signals.forEach(function (signal) {
|
||||
signal && (signal.removeEventListener ? signal.removeEventListener('abort', onabort) : signal.unsubscribe(onabort));
|
||||
});
|
||||
signals = null;
|
||||
}
|
||||
};
|
||||
signals.forEach(function (signal) {
|
||||
return signal && signal.addEventListener && signal.addEventListener('abort', onabort);
|
||||
});
|
||||
var signal = controller.signal;
|
||||
signal.unsubscribe = unsubscribe;
|
||||
return [signal, function () {
|
||||
timer && clearTimeout(timer);
|
||||
timer = null;
|
||||
}];
|
||||
};
|
||||
var composeSignals$1 = composeSignals;
|
||||
|
||||
@@ -3167,7 +3163,7 @@
|
||||
}, streamChunk);
|
||||
});
|
||||
var readBytes = /*#__PURE__*/function () {
|
||||
var _ref = _wrapAsyncGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(iterable, chunkSize) {
|
||||
var _ref = _wrapAsyncGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(iterable, chunkSize, encode) {
|
||||
var _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, chunk;
|
||||
return _regeneratorRuntime().wrap(function _callee$(_context2) {
|
||||
while (1) switch (_context2.prev = _context2.next) {
|
||||
@@ -3175,111 +3171,82 @@
|
||||
_iteratorAbruptCompletion = false;
|
||||
_didIteratorError = false;
|
||||
_context2.prev = 2;
|
||||
_iterator = _asyncIterator(readStream(iterable));
|
||||
_iterator = _asyncIterator(iterable);
|
||||
case 4:
|
||||
_context2.next = 6;
|
||||
return _awaitAsyncGenerator(_iterator.next());
|
||||
case 6:
|
||||
if (!(_iteratorAbruptCompletion = !(_step = _context2.sent).done)) {
|
||||
_context2.next = 12;
|
||||
_context2.next = 27;
|
||||
break;
|
||||
}
|
||||
chunk = _step.value;
|
||||
return _context2.delegateYield(_asyncGeneratorDelegate(_asyncIterator(streamChunk(chunk, chunkSize))), "t0", 9);
|
||||
case 9:
|
||||
_context2.t0 = _asyncGeneratorDelegate;
|
||||
_context2.t1 = _asyncIterator;
|
||||
_context2.t2 = streamChunk;
|
||||
if (!ArrayBuffer.isView(chunk)) {
|
||||
_context2.next = 15;
|
||||
break;
|
||||
}
|
||||
_context2.t3 = chunk;
|
||||
_context2.next = 18;
|
||||
break;
|
||||
case 15:
|
||||
_context2.next = 17;
|
||||
return _awaitAsyncGenerator(encode(String(chunk)));
|
||||
case 17:
|
||||
_context2.t3 = _context2.sent;
|
||||
case 18:
|
||||
_context2.t4 = _context2.t3;
|
||||
_context2.t5 = chunkSize;
|
||||
_context2.t6 = (0, _context2.t2)(_context2.t4, _context2.t5);
|
||||
_context2.t7 = (0, _context2.t1)(_context2.t6);
|
||||
_context2.t8 = _awaitAsyncGenerator;
|
||||
return _context2.delegateYield((0, _context2.t0)(_context2.t7, _context2.t8), "t9", 24);
|
||||
case 24:
|
||||
_iteratorAbruptCompletion = false;
|
||||
_context2.next = 4;
|
||||
break;
|
||||
case 12:
|
||||
_context2.next = 18;
|
||||
case 27:
|
||||
_context2.next = 33;
|
||||
break;
|
||||
case 14:
|
||||
_context2.prev = 14;
|
||||
_context2.t1 = _context2["catch"](2);
|
||||
case 29:
|
||||
_context2.prev = 29;
|
||||
_context2.t10 = _context2["catch"](2);
|
||||
_didIteratorError = true;
|
||||
_iteratorError = _context2.t1;
|
||||
case 18:
|
||||
_context2.prev = 18;
|
||||
_context2.prev = 19;
|
||||
_iteratorError = _context2.t10;
|
||||
case 33:
|
||||
_context2.prev = 33;
|
||||
_context2.prev = 34;
|
||||
if (!(_iteratorAbruptCompletion && _iterator["return"] != null)) {
|
||||
_context2.next = 23;
|
||||
_context2.next = 38;
|
||||
break;
|
||||
}
|
||||
_context2.next = 23;
|
||||
_context2.next = 38;
|
||||
return _awaitAsyncGenerator(_iterator["return"]());
|
||||
case 23:
|
||||
_context2.prev = 23;
|
||||
case 38:
|
||||
_context2.prev = 38;
|
||||
if (!_didIteratorError) {
|
||||
_context2.next = 26;
|
||||
_context2.next = 41;
|
||||
break;
|
||||
}
|
||||
throw _iteratorError;
|
||||
case 26:
|
||||
return _context2.finish(23);
|
||||
case 27:
|
||||
return _context2.finish(18);
|
||||
case 28:
|
||||
case 41:
|
||||
return _context2.finish(38);
|
||||
case 42:
|
||||
return _context2.finish(33);
|
||||
case 43:
|
||||
case "end":
|
||||
return _context2.stop();
|
||||
}
|
||||
}, _callee, null, [[2, 14, 18, 28], [19,, 23, 27]]);
|
||||
}, _callee, null, [[2, 29, 33, 43], [34,, 38, 42]]);
|
||||
}));
|
||||
return function readBytes(_x, _x2) {
|
||||
return function readBytes(_x, _x2, _x3) {
|
||||
return _ref.apply(this, arguments);
|
||||
};
|
||||
}();
|
||||
var readStream = /*#__PURE__*/function () {
|
||||
var _ref2 = _wrapAsyncGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(stream) {
|
||||
var reader, _yield$_awaitAsyncGen, done, value;
|
||||
return _regeneratorRuntime().wrap(function _callee2$(_context3) {
|
||||
while (1) switch (_context3.prev = _context3.next) {
|
||||
case 0:
|
||||
if (!stream[Symbol.asyncIterator]) {
|
||||
_context3.next = 3;
|
||||
break;
|
||||
}
|
||||
return _context3.delegateYield(_asyncGeneratorDelegate(_asyncIterator(stream)), "t0", 2);
|
||||
case 2:
|
||||
return _context3.abrupt("return");
|
||||
case 3:
|
||||
reader = stream.getReader();
|
||||
_context3.prev = 4;
|
||||
case 5:
|
||||
_context3.next = 7;
|
||||
return _awaitAsyncGenerator(reader.read());
|
||||
case 7:
|
||||
_yield$_awaitAsyncGen = _context3.sent;
|
||||
done = _yield$_awaitAsyncGen.done;
|
||||
value = _yield$_awaitAsyncGen.value;
|
||||
if (!done) {
|
||||
_context3.next = 12;
|
||||
break;
|
||||
}
|
||||
return _context3.abrupt("break", 16);
|
||||
case 12:
|
||||
_context3.next = 14;
|
||||
return value;
|
||||
case 14:
|
||||
_context3.next = 5;
|
||||
break;
|
||||
case 16:
|
||||
_context3.prev = 16;
|
||||
_context3.next = 19;
|
||||
return _awaitAsyncGenerator(reader.cancel());
|
||||
case 19:
|
||||
return _context3.finish(16);
|
||||
case 20:
|
||||
case "end":
|
||||
return _context3.stop();
|
||||
}
|
||||
}, _callee2, null, [[4,, 16, 20]]);
|
||||
}));
|
||||
return function readStream(_x3) {
|
||||
return _ref2.apply(this, arguments);
|
||||
};
|
||||
}();
|
||||
var trackStream = function trackStream(stream, chunkSize, onProgress, onFinish) {
|
||||
var iterator = readBytes(stream, chunkSize);
|
||||
var trackStream = function trackStream(stream, chunkSize, onProgress, onFinish, encode) {
|
||||
var iterator = readBytes(stream, chunkSize, encode);
|
||||
var bytes = 0;
|
||||
var done;
|
||||
var _onFinish = function _onFinish(e) {
|
||||
@@ -3290,25 +3257,25 @@
|
||||
};
|
||||
return new ReadableStream({
|
||||
pull: function pull(controller) {
|
||||
return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
||||
return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
||||
var _yield$iterator$next, _done, value, len, loadedBytes;
|
||||
return _regeneratorRuntime().wrap(function _callee3$(_context4) {
|
||||
while (1) switch (_context4.prev = _context4.next) {
|
||||
return _regeneratorRuntime().wrap(function _callee2$(_context3) {
|
||||
while (1) switch (_context3.prev = _context3.next) {
|
||||
case 0:
|
||||
_context4.prev = 0;
|
||||
_context4.next = 3;
|
||||
_context3.prev = 0;
|
||||
_context3.next = 3;
|
||||
return iterator.next();
|
||||
case 3:
|
||||
_yield$iterator$next = _context4.sent;
|
||||
_yield$iterator$next = _context3.sent;
|
||||
_done = _yield$iterator$next.done;
|
||||
value = _yield$iterator$next.value;
|
||||
if (!_done) {
|
||||
_context4.next = 10;
|
||||
_context3.next = 10;
|
||||
break;
|
||||
}
|
||||
_onFinish();
|
||||
controller.close();
|
||||
return _context4.abrupt("return");
|
||||
return _context3.abrupt("return");
|
||||
case 10:
|
||||
len = value.byteLength;
|
||||
if (onProgress) {
|
||||
@@ -3316,18 +3283,18 @@
|
||||
onProgress(loadedBytes);
|
||||
}
|
||||
controller.enqueue(new Uint8Array(value));
|
||||
_context4.next = 19;
|
||||
_context3.next = 19;
|
||||
break;
|
||||
case 15:
|
||||
_context4.prev = 15;
|
||||
_context4.t0 = _context4["catch"](0);
|
||||
_onFinish(_context4.t0);
|
||||
throw _context4.t0;
|
||||
_context3.prev = 15;
|
||||
_context3.t0 = _context3["catch"](0);
|
||||
_onFinish(_context3.t0);
|
||||
throw _context3.t0;
|
||||
case 19:
|
||||
case "end":
|
||||
return _context4.stop();
|
||||
return _context3.stop();
|
||||
}
|
||||
}, _callee3, null, [[0, 15]]);
|
||||
}, _callee2, null, [[0, 15]]);
|
||||
}))();
|
||||
},
|
||||
cancel: function cancel(reason) {
|
||||
@@ -3410,7 +3377,6 @@
|
||||
}(new Response());
|
||||
var getBodyLength = /*#__PURE__*/function () {
|
||||
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(body) {
|
||||
var _request;
|
||||
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
||||
while (1) switch (_context2.prev = _context2.next) {
|
||||
case 0:
|
||||
@@ -3427,36 +3393,32 @@
|
||||
return _context2.abrupt("return", body.size);
|
||||
case 4:
|
||||
if (!utils$1.isSpecCompliantForm(body)) {
|
||||
_context2.next = 9;
|
||||
_context2.next = 8;
|
||||
break;
|
||||
}
|
||||
_request = new Request(platform.origin, {
|
||||
method: 'POST',
|
||||
body: body
|
||||
});
|
||||
_context2.next = 8;
|
||||
return _request.arrayBuffer();
|
||||
case 8:
|
||||
_context2.next = 7;
|
||||
return new Request(body).arrayBuffer();
|
||||
case 7:
|
||||
return _context2.abrupt("return", _context2.sent.byteLength);
|
||||
case 9:
|
||||
case 8:
|
||||
if (!(utils$1.isArrayBufferView(body) || utils$1.isArrayBuffer(body))) {
|
||||
_context2.next = 11;
|
||||
_context2.next = 10;
|
||||
break;
|
||||
}
|
||||
return _context2.abrupt("return", body.byteLength);
|
||||
case 11:
|
||||
case 10:
|
||||
if (utils$1.isURLSearchParams(body)) {
|
||||
body = body + '';
|
||||
}
|
||||
if (!utils$1.isString(body)) {
|
||||
_context2.next = 16;
|
||||
_context2.next = 15;
|
||||
break;
|
||||
}
|
||||
_context2.next = 15;
|
||||
_context2.next = 14;
|
||||
return encodeText(body);
|
||||
case 15:
|
||||
case 14:
|
||||
return _context2.abrupt("return", _context2.sent.byteLength);
|
||||
case 16:
|
||||
case 15:
|
||||
case "end":
|
||||
return _context2.stop();
|
||||
}
|
||||
@@ -3486,15 +3448,18 @@
|
||||
}();
|
||||
var fetchAdapter = isFetchSupported && ( /*#__PURE__*/function () {
|
||||
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(config) {
|
||||
var _resolveConfig, url, method, data, signal, cancelToken, timeout, onDownloadProgress, onUploadProgress, responseType, headers, _resolveConfig$withCr, withCredentials, fetchOptions, composedSignal, request, unsubscribe, requestContentLength, _request, contentTypeHeader, _progressEventDecorat, _progressEventDecorat2, onProgress, flush, isCredentialsSupported, response, isStreamResponse, options, responseContentLength, _ref5, _ref6, _onProgress, _flush, responseData;
|
||||
var _resolveConfig, url, method, data, signal, cancelToken, timeout, onDownloadProgress, onUploadProgress, responseType, headers, _resolveConfig$withCr, withCredentials, fetchOptions, _ref5, _ref6, composedSignal, stopTimeout, finished, request, onFinish, requestContentLength, _request, contentTypeHeader, _progressEventDecorat, _progressEventDecorat2, onProgress, flush, isCredentialsSupported, response, isStreamResponse, options, responseContentLength, _ref7, _ref8, _onProgress, _flush, responseData;
|
||||
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
||||
while (1) switch (_context4.prev = _context4.next) {
|
||||
case 0:
|
||||
_resolveConfig = resolveConfig(config), url = _resolveConfig.url, method = _resolveConfig.method, data = _resolveConfig.data, signal = _resolveConfig.signal, cancelToken = _resolveConfig.cancelToken, timeout = _resolveConfig.timeout, onDownloadProgress = _resolveConfig.onDownloadProgress, onUploadProgress = _resolveConfig.onUploadProgress, responseType = _resolveConfig.responseType, headers = _resolveConfig.headers, _resolveConfig$withCr = _resolveConfig.withCredentials, withCredentials = _resolveConfig$withCr === void 0 ? 'same-origin' : _resolveConfig$withCr, fetchOptions = _resolveConfig.fetchOptions;
|
||||
responseType = responseType ? (responseType + '').toLowerCase() : 'text';
|
||||
composedSignal = composeSignals$1([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
|
||||
unsubscribe = composedSignal && composedSignal.unsubscribe && function () {
|
||||
composedSignal.unsubscribe();
|
||||
_ref5 = signal || cancelToken || timeout ? composeSignals$1([signal, cancelToken], timeout) : [], _ref6 = _slicedToArray(_ref5, 2), composedSignal = _ref6[0], stopTimeout = _ref6[1];
|
||||
onFinish = function onFinish() {
|
||||
!finished && setTimeout(function () {
|
||||
composedSignal && composedSignal.unsubscribe();
|
||||
});
|
||||
finished = true;
|
||||
};
|
||||
_context4.prev = 4;
|
||||
_context4.t0 = onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head';
|
||||
@@ -3522,7 +3487,7 @@
|
||||
}
|
||||
if (_request.body) {
|
||||
_progressEventDecorat = progressEventDecorator(requestContentLength, progressEventReducer(asyncDecorator(onUploadProgress))), _progressEventDecorat2 = _slicedToArray(_progressEventDecorat, 2), onProgress = _progressEventDecorat2[0], flush = _progressEventDecorat2[1];
|
||||
data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
|
||||
data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush, encodeText);
|
||||
}
|
||||
case 15:
|
||||
if (!utils$1.isString(withCredentials)) {
|
||||
@@ -3545,25 +3510,26 @@
|
||||
case 20:
|
||||
response = _context4.sent;
|
||||
isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');
|
||||
if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) {
|
||||
if (supportsResponseStream && (onDownloadProgress || isStreamResponse)) {
|
||||
options = {};
|
||||
['status', 'statusText', 'headers'].forEach(function (prop) {
|
||||
options[prop] = response[prop];
|
||||
});
|
||||
responseContentLength = utils$1.toFiniteNumber(response.headers.get('content-length'));
|
||||
_ref5 = onDownloadProgress && progressEventDecorator(responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true)) || [], _ref6 = _slicedToArray(_ref5, 2), _onProgress = _ref6[0], _flush = _ref6[1];
|
||||
_ref7 = onDownloadProgress && progressEventDecorator(responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true)) || [], _ref8 = _slicedToArray(_ref7, 2), _onProgress = _ref8[0], _flush = _ref8[1];
|
||||
response = new Response(trackStream(response.body, DEFAULT_CHUNK_SIZE, _onProgress, function () {
|
||||
_flush && _flush();
|
||||
unsubscribe && unsubscribe();
|
||||
}), options);
|
||||
isStreamResponse && onFinish();
|
||||
}, encodeText), options);
|
||||
}
|
||||
responseType = responseType || 'text';
|
||||
_context4.next = 26;
|
||||
return resolvers[utils$1.findKey(resolvers, responseType) || 'text'](response, config);
|
||||
case 26:
|
||||
responseData = _context4.sent;
|
||||
!isStreamResponse && unsubscribe && unsubscribe();
|
||||
_context4.next = 30;
|
||||
!isStreamResponse && onFinish();
|
||||
stopTimeout && stopTimeout();
|
||||
_context4.next = 31;
|
||||
return new Promise(function (resolve, reject) {
|
||||
settle(resolve, reject, {
|
||||
data: responseData,
|
||||
@@ -3574,26 +3540,26 @@
|
||||
request: request
|
||||
});
|
||||
});
|
||||
case 30:
|
||||
case 31:
|
||||
return _context4.abrupt("return", _context4.sent);
|
||||
case 33:
|
||||
_context4.prev = 33;
|
||||
case 34:
|
||||
_context4.prev = 34;
|
||||
_context4.t2 = _context4["catch"](4);
|
||||
unsubscribe && unsubscribe();
|
||||
onFinish();
|
||||
if (!(_context4.t2 && _context4.t2.name === 'TypeError' && /fetch/i.test(_context4.t2.message))) {
|
||||
_context4.next = 38;
|
||||
_context4.next = 39;
|
||||
break;
|
||||
}
|
||||
throw Object.assign(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request), {
|
||||
cause: _context4.t2.cause || _context4.t2
|
||||
});
|
||||
case 38:
|
||||
throw AxiosError.from(_context4.t2, _context4.t2 && _context4.t2.code, config, request);
|
||||
case 39:
|
||||
throw AxiosError.from(_context4.t2, _context4.t2 && _context4.t2.code, config, request);
|
||||
case 40:
|
||||
case "end":
|
||||
return _context4.stop();
|
||||
}
|
||||
}, _callee4, null, [[4, 33]]);
|
||||
}, _callee4, null, [[4, 34]]);
|
||||
}));
|
||||
return function (_x5) {
|
||||
return _ref4.apply(this, arguments);
|
||||
@@ -3717,7 +3683,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
var VERSION = "1.7.7";
|
||||
var VERSION = "1.7.5";
|
||||
|
||||
var validators$1 = {};
|
||||
|
||||
@@ -4098,20 +4064,6 @@
|
||||
this._listeners.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "toAbortSignal",
|
||||
value: function toAbortSignal() {
|
||||
var _this = this;
|
||||
var controller = new AbortController();
|
||||
var abort = function abort(err) {
|
||||
controller.abort(err);
|
||||
};
|
||||
this.subscribe(abort);
|
||||
controller.signal.unsubscribe = function () {
|
||||
return _this.unsubscribe(abort);
|
||||
};
|
||||
return controller.signal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object that contains a new `CancelToken` and a function that, when called,
|
||||
|
||||
Vendored
-14
File diff suppressed because one or more lines are too long
-1099
File diff suppressed because it is too large
Load Diff
Vendored
+3146
-3105
File diff suppressed because it is too large
Load Diff
-127
File diff suppressed because one or more lines are too long
Vendored
+8
-13
@@ -7,13 +7,13 @@
|
||||
exports.noConflict = function () { global._ = current; return exports; };
|
||||
}()));
|
||||
}(this, (function () {
|
||||
// Underscore.js 1.13.7
|
||||
// Underscore.js 1.13.6
|
||||
// https://underscorejs.org
|
||||
// (c) 2009-2024 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
|
||||
// (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
|
||||
// Underscore may be freely distributed under the MIT license.
|
||||
|
||||
// Current version.
|
||||
var VERSION = '1.13.7';
|
||||
var VERSION = '1.13.6';
|
||||
|
||||
// Establish the root object, `window` (`self`) in the browser, `global`
|
||||
// on the server, or `this` in some virtual machines. We use `self`
|
||||
@@ -150,11 +150,8 @@
|
||||
// In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.
|
||||
// In IE 11, the most common among them, this problem also applies to
|
||||
// `Map`, `WeakMap` and `Set`.
|
||||
// Also, there are cases where an application can override the native
|
||||
// `DataView` object, in cases like that we can't use the constructor
|
||||
// safely and should just rely on alternate `DataView` checks
|
||||
var hasDataViewBug = (
|
||||
supportsDataView && (!/\[native code\]/.test(String(DataView)) || hasObjectTag(new DataView(new ArrayBuffer(8))))
|
||||
var hasStringTagBug = (
|
||||
supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))
|
||||
),
|
||||
isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));
|
||||
|
||||
@@ -162,13 +159,11 @@
|
||||
|
||||
// In IE 10 - Edge 13, we need a different heuristic
|
||||
// to determine whether an object is a `DataView`.
|
||||
// Also, in cases where the native `DataView` is
|
||||
// overridden we can't rely on the tag itself.
|
||||
function alternateIsDataView(obj) {
|
||||
function ie10IsDataView(obj) {
|
||||
return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);
|
||||
}
|
||||
|
||||
var isDataView$1 = (hasDataViewBug ? alternateIsDataView : isDataView);
|
||||
var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);
|
||||
|
||||
// Is a given value an array?
|
||||
// Delegates to ECMA5's native `Array.isArray`.
|
||||
@@ -381,7 +376,7 @@
|
||||
var className = toString.call(a);
|
||||
if (className !== toString.call(b)) return false;
|
||||
// Work around a bug in IE 10 - Edge 13.
|
||||
if (hasDataViewBug && className == '[object Object]' && isDataView$1(a)) {
|
||||
if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {
|
||||
if (!isDataView$1(b)) return false;
|
||||
className = tagDataView;
|
||||
}
|
||||
|
||||
-6690
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+5505
-109
File diff suppressed because it is too large
Load Diff
-3916
File diff suppressed because it is too large
Load Diff
-9
File diff suppressed because one or more lines are too long
Vendored
-1514
File diff suppressed because it is too large
Load Diff
+184
-188
@@ -32,198 +32,196 @@
|
||||
</head>
|
||||
|
||||
<body data-theme="bitcoin">
|
||||
<div id="vue">
|
||||
<q-layout view="hHh lpR lfr" v-cloak>
|
||||
<q-header bordered class="bg-marginal-bg">
|
||||
<q-toolbar>
|
||||
{% block drawer_toggle %}
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
round
|
||||
icon="menu"
|
||||
@click="g.visibleDrawer = !g.visibleDrawer"
|
||||
></q-btn>
|
||||
{% endblock %}
|
||||
<q-toolbar-title>
|
||||
{% block toolbar_title %}
|
||||
<q-btn flat no-caps dense size="lg" type="a" href="/"
|
||||
>{% if USE_CUSTOM_LOGO %}
|
||||
<img height="30px" alt="Logo" src="{{ USE_CUSTOM_LOGO }}" />
|
||||
{%else%} {% if SITE_TITLE != 'LNbits' %} {{ SITE_TITLE }} {%
|
||||
else %}
|
||||
<span><strong>LN</strong>bits</span> {% endif %} {%endif%} </q-btn
|
||||
>{% endblock %} {% block toolbar_subtitle %}{%if user and
|
||||
user.super_user%}
|
||||
<q-badge align="middle">Super User</q-badge>
|
||||
{% elif user and user.admin %}
|
||||
<q-badge align="middle">Admin User</q-badge>
|
||||
{%endif%}{% endblock %}
|
||||
</q-toolbar-title>
|
||||
{% block beta %} {% if VOIDWALLET %}
|
||||
<q-badge
|
||||
v-text="$t('voidwallet_active')"
|
||||
color="red"
|
||||
class="q-mr-md gt-md"
|
||||
>
|
||||
</q-badge>
|
||||
<q-layout id="vue" view="hHh lpR lfr" v-cloak>
|
||||
<q-header bordered class="bg-marginal-bg">
|
||||
<q-toolbar>
|
||||
{% block drawer_toggle %}
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
round
|
||||
icon="menu"
|
||||
@click="g.visibleDrawer = !g.visibleDrawer"
|
||||
></q-btn>
|
||||
{% endblock %}
|
||||
<q-toolbar-title>
|
||||
{% block toolbar_title %}
|
||||
<q-btn flat no-caps dense size="lg" type="a" href="/"
|
||||
>{% if USE_CUSTOM_LOGO %}
|
||||
<img height="30px" alt="Logo" src="{{ USE_CUSTOM_LOGO }}" />
|
||||
{%else%} {% if SITE_TITLE != 'LNbits' %} {{ SITE_TITLE }} {% else
|
||||
%}
|
||||
<span><strong>LN</strong>bits</span> {% endif %} {%endif%} </q-btn
|
||||
>{% endblock %} {% block toolbar_subtitle %}{%if user and
|
||||
user.super_user%}
|
||||
<q-badge align="middle">Super User</q-badge>
|
||||
{% elif user and user.admin %}
|
||||
<q-badge align="middle">Admin User</q-badge>
|
||||
{%endif%}{% endblock %}
|
||||
</q-toolbar-title>
|
||||
{% block beta %} {% if VOIDWALLET %}
|
||||
<q-badge
|
||||
v-text="$t('voidwallet_active')"
|
||||
color="red"
|
||||
class="q-mr-md gt-md"
|
||||
>
|
||||
</q-badge>
|
||||
{%endif%}
|
||||
<q-badge
|
||||
v-if="'{{LNBITS_CUSTOM_BADGE}}' && '{{LNBITS_CUSTOM_BADGE}}' != 'None'"
|
||||
v-show="$q.screen.gt.sm"
|
||||
color="{{ LNBITS_CUSTOM_BADGE_COLOR }}"
|
||||
class="q-mr-md"
|
||||
label="{{LNBITS_CUSTOM_BADGE}}"
|
||||
>
|
||||
</q-badge>
|
||||
{% if LNBITS_SERVICE_FEE > 0 %}
|
||||
<q-badge
|
||||
v-show="$q.screen.gt.sm"
|
||||
v-if="g.user"
|
||||
color="green"
|
||||
class="q-mr-md"
|
||||
>
|
||||
{% if LNBITS_SERVICE_FEE_MAX > 0 %}
|
||||
<span
|
||||
v-text='$t("service_fee_max", { amount: "{{ LNBITS_SERVICE_FEE }}", max: "{{ LNBITS_SERVICE_FEE_MAX }}"})'
|
||||
></span>
|
||||
{%else%}
|
||||
<span
|
||||
v-text='$t("service_fee", { amount: "{{ LNBITS_SERVICE_FEE }}" })'
|
||||
></span>
|
||||
{%endif%}
|
||||
<q-badge
|
||||
v-if="'{{LNBITS_CUSTOM_BADGE}}' && '{{LNBITS_CUSTOM_BADGE}}' != 'None'"
|
||||
v-show="$q.screen.gt.sm"
|
||||
color="{{ LNBITS_CUSTOM_BADGE_COLOR }}"
|
||||
class="q-mr-md"
|
||||
label="{{LNBITS_CUSTOM_BADGE}}"
|
||||
>
|
||||
</q-badge>
|
||||
{% if LNBITS_SERVICE_FEE > 0 %}
|
||||
<q-badge
|
||||
v-show="$q.screen.gt.sm"
|
||||
v-if="g.user"
|
||||
color="green"
|
||||
class="q-mr-md"
|
||||
>
|
||||
{% if LNBITS_SERVICE_FEE_MAX > 0 %}
|
||||
<span
|
||||
v-text='$t("service_fee_max", { amount: "{{ LNBITS_SERVICE_FEE }}", max: "{{ LNBITS_SERVICE_FEE_MAX }}"})'
|
||||
></span>
|
||||
{%else%}
|
||||
<span
|
||||
v-text='$t("service_fee", { amount: "{{ LNBITS_SERVICE_FEE }}" })'
|
||||
></span>
|
||||
{%endif%}
|
||||
<q-tooltip
|
||||
><span v-text='$t("service_fee_tooltip")'></span
|
||||
></q-tooltip>
|
||||
</q-badge>
|
||||
<q-tooltip
|
||||
><span v-text='$t("service_fee_tooltip")'></span
|
||||
></q-tooltip>
|
||||
</q-badge>
|
||||
|
||||
{%endif%} {% endblock %}
|
||||
<q-badge v-if="g.offline" color="red" class="q-mr-md">
|
||||
<span>OFFLINE</span>
|
||||
</q-badge>
|
||||
{%endif%} {% endblock %}
|
||||
<q-badge v-if="g.offline" color="red" class="q-mr-md">
|
||||
<span>OFFLINE</span>
|
||||
</q-badge>
|
||||
|
||||
<q-btn-dropdown
|
||||
v-if="isUserAuthorized"
|
||||
dense
|
||||
flat
|
||||
round
|
||||
size="sm"
|
||||
class="q-pl-sm"
|
||||
>
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
{%if user and user.config and user.config.picture%}
|
||||
<img src="{{user.config.picture}}" style="max-width: 32px" />
|
||||
{%else%}
|
||||
<q-icon name="account_circle" />
|
||||
{%endif%}
|
||||
</div>
|
||||
</template>
|
||||
<q-list>
|
||||
<q-item tag="a" href="/account" clickable v-close-popup
|
||||
><q-item-section>
|
||||
<q-icon name="person" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
<span v-text="$t('my_account')"></span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label> </q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator></q-separator>
|
||||
<q-item clickable v-close-popup @click="logout"
|
||||
><q-item-section>
|
||||
<q-icon name="logout" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
<span v-text="$t('logout')"></span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label> </q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-btn-dropdown>
|
||||
</q-toolbar>
|
||||
</q-header>
|
||||
<q-btn-dropdown
|
||||
v-if="isUserAuthorized"
|
||||
dense
|
||||
flat
|
||||
round
|
||||
size="sm"
|
||||
class="q-pl-sm"
|
||||
>
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
{%if user and user.config and user.config.picture%}
|
||||
<img src="{{user.config.picture}}" style="max-width: 32px" />
|
||||
{%else%}
|
||||
<q-icon name="account_circle" />
|
||||
{%endif%}
|
||||
</div>
|
||||
</template>
|
||||
<q-list>
|
||||
<q-item tag="a" href="/account" clickable v-close-popup
|
||||
><q-item-section>
|
||||
<q-icon name="person" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
<span v-text="$t('my_account')"></span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label> </q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator></q-separator>
|
||||
<q-item clickable v-close-popup @click="logout"
|
||||
><q-item-section>
|
||||
<q-icon name="logout" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
<span v-text="$t('logout')"></span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label> </q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-btn-dropdown>
|
||||
</q-toolbar>
|
||||
</q-header>
|
||||
|
||||
{% block drawer %}
|
||||
<q-drawer
|
||||
v-model="g.visibleDrawer"
|
||||
side="left"
|
||||
:width="($q.screen.lt.md) ? 260 : 230"
|
||||
show-if-above
|
||||
:elevated="$q.screen.lt.md"
|
||||
>
|
||||
<lnbits-wallet-list :balance="balance"></lnbits-wallet-list>
|
||||
{% block drawer %}
|
||||
<q-drawer
|
||||
v-model="g.visibleDrawer"
|
||||
side="left"
|
||||
:width="($q.screen.lt.md) ? 260 : 230"
|
||||
show-if-above
|
||||
:elevated="$q.screen.lt.md"
|
||||
>
|
||||
<lnbits-wallet-list></lnbits-wallet-list>
|
||||
|
||||
<lnbits-manage
|
||||
:show-admin="'{{LNBITS_ADMIN_UI}}' == 'True'"
|
||||
:show-users="'{{LNBITS_ADMIN_UI}}' == 'True'"
|
||||
:show-node="'{{LNBITS_NODE_UI}}' == 'True'"
|
||||
:show-extensions="'{{LNBITS_EXTENSIONS_DEACTIVATE_ALL}}' == 'False'"
|
||||
></lnbits-manage>
|
||||
<lnbits-extension-list class="q-pb-xl"></lnbits-extension-list>
|
||||
</q-drawer>
|
||||
{% endblock %} {% block page_container %}
|
||||
<q-page-container>
|
||||
<q-page class="q-px-md q-py-lg" :class="{'q-px-lg': $q.screen.gt.xs}">
|
||||
{% block page %}{% endblock %}
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
{% endblock %} {% block footer %}
|
||||
<lnbits-manage
|
||||
:show-admin="'{{LNBITS_ADMIN_UI}}' == 'True'"
|
||||
:show-users="'{{LNBITS_ADMIN_UI}}' == 'True'"
|
||||
:show-node="'{{LNBITS_NODE_UI}}' == 'True'"
|
||||
:show-extensions="'{{LNBITS_EXTENSIONS_DEACTIVATE_ALL}}' == 'False'"
|
||||
></lnbits-manage>
|
||||
<lnbits-extension-list class="q-pb-xl"></lnbits-extension-list>
|
||||
</q-drawer>
|
||||
{% endblock %} {% block page_container %}
|
||||
<q-page-container>
|
||||
<q-page class="q-px-md q-py-lg" :class="{'q-px-lg': $q.screen.gt.xs}">
|
||||
{% block page %}{% endblock %}
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
{% endblock %} {% block footer %}
|
||||
|
||||
<q-footer
|
||||
class="bg-transparent q-px-lg q-py-md"
|
||||
:class="{'text-dark': !$q.dark.isActive}"
|
||||
>
|
||||
<q-space class="q-py-lg lt-md"></q-space>
|
||||
<q-toolbar class="gt-sm">
|
||||
<q-toolbar-title class="text-caption">
|
||||
{{ SITE_TITLE }}, {{SITE_TAGLINE}}
|
||||
<br />
|
||||
<small
|
||||
v-text="$t('lnbits_version') + ': {{LNBITS_VERSION}}'"
|
||||
></small>
|
||||
</q-toolbar-title>
|
||||
<q-space></q-space>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
:color="($q.dark.isActive) ? 'white' : 'primary'"
|
||||
type="a"
|
||||
href="/docs"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span v-text="$t('api_docs')"></span>
|
||||
<q-tooltip
|
||||
><span v-text="$t('view_swagger_docs')"></span
|
||||
></q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
:color="($q.dark.isActive) ? 'white' : 'primary'"
|
||||
icon="code"
|
||||
type="a"
|
||||
href="https://github.com/lnbits/lnbits"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<q-tooltip><span v-text="$t('view_github')"></span></q-tooltip>
|
||||
</q-btn>
|
||||
</q-toolbar>
|
||||
</q-footer>
|
||||
<q-footer
|
||||
class="bg-transparent q-px-lg q-py-md"
|
||||
:class="{'text-dark': !$q.dark.isActive}"
|
||||
>
|
||||
<q-space class="q-py-lg lt-md"></q-space>
|
||||
<q-toolbar class="gt-sm">
|
||||
<q-toolbar-title class="text-caption">
|
||||
{{ SITE_TITLE }}, {{SITE_TAGLINE}}
|
||||
<br />
|
||||
<small
|
||||
v-text="$t('lnbits_version') + ': {{LNBITS_VERSION}}'"
|
||||
></small>
|
||||
</q-toolbar-title>
|
||||
<q-space></q-space>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
:color="($q.dark.isActive) ? 'white' : 'primary'"
|
||||
type="a"
|
||||
href="/docs"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span v-text="$t('api_docs')"></span>
|
||||
<q-tooltip
|
||||
><span v-text="$t('view_swagger_docs')"></span
|
||||
></q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
:color="($q.dark.isActive) ? 'white' : 'primary'"
|
||||
icon="code"
|
||||
type="a"
|
||||
href="https://github.com/lnbits/lnbits"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<q-tooltip><span v-text="$t('view_github')"></span></q-tooltip>
|
||||
</q-btn>
|
||||
</q-toolbar>
|
||||
</q-footer>
|
||||
|
||||
{% endblock %}
|
||||
</q-layout>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</q-layout>
|
||||
|
||||
{% block vue_templates %}{% endblock %}
|
||||
<!---->
|
||||
@@ -260,8 +258,6 @@
|
||||
{ value: 'fi', label: 'Suomi', display: '🇫🇮 FI' }
|
||||
]
|
||||
</script>
|
||||
{% block scripts %}{% endblock %} {% for url in INCLUDED_COMPONENTS %}
|
||||
<script src="{{ static_url_for('static', url) }}"></script>
|
||||
{% endfor %}
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Generated
+418
-409
File diff suppressed because it is too large
Load Diff
+35
-37
@@ -6,46 +6,45 @@
|
||||
"vendor_json": "node -e \"require('fs').writeFileSync('./lnbits/static/vendor.json', JSON.stringify(require('./package.json').bundle))\"",
|
||||
"vendor_bundle_css": "node -e \"require('concat')(require('./package.json').bundle.css.map(a => 'lnbits/static/'+a), './lnbits/static/bundle.css')\"",
|
||||
"vendor_bundle_js": "node -e \"require('concat')(require('./package.json').bundle.js.map(a => 'lnbits/static/'+a),'./lnbits/static/bundle.js')\"",
|
||||
"vendor_bundle_components": "node -e \"require('concat')(require('./package.json').bundle.components.map(a => 'lnbits/static/'+a), './lnbits/static/bundle-components.js')\"",
|
||||
"vendor_minify_css": "./node_modules/.bin/minify ./lnbits/static/bundle.css > ./lnbits/static/bundle.min.css",
|
||||
"vendor_minify_js": "./node_modules/.bin/minify ./lnbits/static/bundle.js > ./lnbits/static/bundle.min.js",
|
||||
"vendor_minify_components": "./node_modules/.bin/minify ./lnbits/static/bundle-components.js > ./lnbits/static/bundle-components.min.js",
|
||||
"bundle": "npm run sass && npm run vendor_copy && npm run vendor_json && npm run vendor_bundle_css && npm run vendor_bundle_js && npm run vendor_bundle_components && npm run vendor_minify_css && npm run vendor_minify_js && npm run vendor_minify_components"
|
||||
"vendor_minify_js": "./node_modules/.bin/minify ./lnbits/static/bundle.js > ./lnbits/static/bundle.min.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concat": "^1.0.3",
|
||||
"minify": "^9.2.0",
|
||||
"prettier": "^3.3.3",
|
||||
"pyright": "1.1.289",
|
||||
"sass": "^1.78.0"
|
||||
"sass": "^1.60.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.7",
|
||||
"chart.js": "^4.4.4",
|
||||
"@chenfengyuan/vue-qrcode": "1.0.2",
|
||||
"axios": "^1.7.5",
|
||||
"chart.js": "^2.9.4",
|
||||
"moment": "^2.30.1",
|
||||
"qrcode.vue": "^3.4.1",
|
||||
"quasar": "2.16.10",
|
||||
"quasar": "1.13.2",
|
||||
"showdown": "^2.1.0",
|
||||
"underscore": "^1.13.7",
|
||||
"vue": "3.5.2",
|
||||
"vue-i18n": "^9.14.0",
|
||||
"vue-qrcode-reader": "^5.5.7",
|
||||
"vue-router": "4.4.3",
|
||||
"vuex": "4.1.0"
|
||||
"underscore": "^1.13.6",
|
||||
"vue": "2.6.12",
|
||||
"vue-i18n": "^8.28.2",
|
||||
"vue-qrcode-reader": "^2.3.18",
|
||||
"vue-router": "3.4.3",
|
||||
"vuex": "3.5.1"
|
||||
},
|
||||
"vendor": [
|
||||
"./node_modules/moment/moment.js",
|
||||
"./node_modules/underscore/underscore.js",
|
||||
"./node_modules/axios/dist/axios.js",
|
||||
"./node_modules/vue/dist/vue.global.prod.js",
|
||||
"./node_modules/quasar/dist/quasar.umd.prod.js",
|
||||
"./node_modules/vuex/dist/vuex.global.js",
|
||||
"./node_modules/vue-i18n/dist/vue-i18n.global.prod.js",
|
||||
"./node_modules/vue-router/dist/vue-router.global.js",
|
||||
"./node_modules/vue-qrcode-reader/dist/vue-qrcode-reader.umd.js",
|
||||
"./node_modules/qrcode.vue/dist/qrcode.vue.browser.js",
|
||||
"./node_modules/chart.js/dist/chart.umd.js",
|
||||
"./node_modules/vue/dist/vue.js",
|
||||
"./node_modules/vue-router/dist/vue-router.js",
|
||||
"./node_modules/vue-qrcode-reader/dist/VueQrcodeReader.umd.js",
|
||||
"./node_modules/@chenfengyuan/vue-qrcode/dist/vue-qrcode.js",
|
||||
"./node_modules/vuex/dist/vuex.js",
|
||||
"./node_modules/quasar/dist/quasar.ie.polyfills.umd.min.js",
|
||||
"./node_modules/quasar/dist/quasar.umd.js",
|
||||
"./node_modules/chart.js/dist/Chart.bundle.js",
|
||||
"./node_modules/quasar/dist/quasar.css",
|
||||
"./node_modules/chart.js/dist/Chart.css",
|
||||
"./node_modules/vue-i18n/dist/vue-i18n.js",
|
||||
"./node_modules/showdown/dist/showdown.js"
|
||||
],
|
||||
"bundle": {
|
||||
@@ -53,14 +52,15 @@
|
||||
"vendor/moment.js",
|
||||
"vendor/underscore.js",
|
||||
"vendor/axios.js",
|
||||
"vendor/vue.global.prod.js",
|
||||
"vendor/quasar.umd.prod.js",
|
||||
"vendor/vuex.global.js",
|
||||
"vendor/vue-i18n.global.prod.js",
|
||||
"vendor/vue-router.global.js",
|
||||
"vendor/vue-qrcode-reader.umd.js",
|
||||
"vendor/qrcode.vue.browser.js",
|
||||
"vendor/chart.umd.js",
|
||||
"vendor/vue.js",
|
||||
"vendor/vue-router.js",
|
||||
"vendor/VueQrcodeReader.umd.js",
|
||||
"vendor/vue-qrcode.js",
|
||||
"vendor/vuex.js",
|
||||
"vendor/quasar.ie.polyfills.umd.min.js",
|
||||
"vendor/quasar.umd.js",
|
||||
"vendor/Chart.bundle.js",
|
||||
"vendor/vue-i18n.js",
|
||||
"vendor/showdown.js",
|
||||
"i18n/i18n.js",
|
||||
"i18n/de.js",
|
||||
@@ -83,20 +83,18 @@
|
||||
"i18n/kr.js",
|
||||
"i18n/fi.js",
|
||||
"js/base.js",
|
||||
"js/event-reactions.js",
|
||||
"js/bolt11-decoder.js"
|
||||
],
|
||||
"components": [
|
||||
"js/components.js",
|
||||
"js/components/lnbits-funding-sources.js",
|
||||
"js/components/extension-settings.js",
|
||||
"js/components/extension-rating.js",
|
||||
"js/components/payment-list.js",
|
||||
"js/components/payment-chart.js",
|
||||
"js/components.js",
|
||||
"js/init-app.js"
|
||||
"js/event-reactions.js",
|
||||
"js/bolt11-decoder.js"
|
||||
],
|
||||
"css": [
|
||||
"vendor/quasar.css",
|
||||
"vendor/Chart.css",
|
||||
"css/base.css"
|
||||
]
|
||||
}
|
||||
|
||||
Generated
+334
-353
@@ -659,70 +659,59 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
|
||||
[[package]]
|
||||
name = "coincurve"
|
||||
version = "20.0.0"
|
||||
version = "18.0.0"
|
||||
description = "Cross-platform Python CFFI bindings for libsecp256k1"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "coincurve-20.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d559b22828638390118cae9372a1bb6f6594f5584c311deb1de6a83163a0919b"},
|
||||
{file = "coincurve-20.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33d7f6ebd90fcc550f819f7f2cce2af525c342aac07f0ccda46ad8956ad9d99b"},
|
||||
{file = "coincurve-20.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22d70dd55d13fd427418eb41c20fde0a20a5e5f016e2b1bb94710701e759e7e0"},
|
||||
{file = "coincurve-20.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46f18d481eaae72c169f334cde1fd22011a884e0c9c6adc3fdc1fd13df8236a3"},
|
||||
{file = "coincurve-20.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9de1ec57f43c3526bc462be58fb97910dc1fdd5acab6c71eda9f9719a5bd7489"},
|
||||
{file = "coincurve-20.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a6f007c44c726b5c0b3724093c0d4fb8e294f6b6869beb02d7473b21777473a3"},
|
||||
{file = "coincurve-20.0.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0ff1f3b81330db5092c24da2102e4fcba5094f14945b3eb40746456ceabdd6d9"},
|
||||
{file = "coincurve-20.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82f7de97694d9343f26bd1c8e081b168e5f525894c12445548ce458af227f536"},
|
||||
{file = "coincurve-20.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:e905b4b084b4f3b61e5a5d58ac2632fd1d07b7b13b4c6d778335a6ca1dafd7a3"},
|
||||
{file = "coincurve-20.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:3657bb5ed0baf1cf8cf356e7d44aa90a7902cc3dd4a435c6d4d0bed0553ad4f7"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:44087d1126d43925bf9a2391ce5601bf30ce0dba4466c239172dc43226696018"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ccf0ba38b0f307a9b3ce28933f6c71dc12ef3a0985712ca09f48591afd597c8"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:566bc5986debdf8572b6be824fd4de03d533c49f3de778e29f69017ae3fe82d8"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4d70283168e146f025005c15406086513d5d35e89a60cf4326025930d45013a"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:763c6122dd7d5e7a81c86414ce360dbe9a2d4afa1ca6c853ee03d63820b3d0c5"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f00c361c356bcea386d47a191bb8ac60429f4b51c188966a201bfecaf306ff7f"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4af57bdadd2e64d117dd0b33cfefe76e90c7a6c496a7b034fc65fd01ec249b15"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a26437b7cbde13fb6e09261610b788ca2a0ca2195c62030afd1e1e0d1a62e035"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ed51f8bba35e6c7676ad65539c3dbc35acf014fc402101fa24f6b0a15a74ab9e"},
|
||||
{file = "coincurve-20.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:594b840fc25d74118407edbbbc754b815f1bba9759dbf4f67f1c2b78396df2d3"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4df4416a6c0370d777aa725a25b14b04e45aa228da1251c258ff91444643f688"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1ccc3e4db55abf3fc0e604a187fdb05f0702bc5952e503d9a75f4ae6eeb4cb3a"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8335b1658a2ef5b3eb66d52647742fe8c6f413ad5b9d5310d7ea6d8060d40f"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ac025e485a0229fd5394e0bf6b4a75f8a4f6cee0dcf6f0b01a2ef05c5210ff"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e46e3f1c21b3330857bcb1a3a5b942f645c8bce912a8a2b252216f34acfe4195"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:df9ff9b17a1d27271bf476cf3fa92df4c151663b11a55d8cea838b8f88d83624"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4155759f071375699282e03b3d95fb473ee05c022641c077533e0d906311e57a"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0530b9dd02fc6f6c2916716974b79bdab874227f560c422801ade290e3fc5013"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:eacf9c0ce8739c84549a89c083b1f3526c8780b84517ee75d6b43d276e55f8a0"},
|
||||
{file = "coincurve-20.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:52a67bfddbd6224dfa42085c88ad176559801b57d6a8bd30d92ee040de88b7b3"},
|
||||
{file = "coincurve-20.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:61e951b1d695b62376f60519a84c4facaf756eeb9c5aff975bea0942833f185d"},
|
||||
{file = "coincurve-20.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e9e548db77f4ea34c0d748dddefc698adb0ee3fab23ed19f80fb2118dac70f6"},
|
||||
{file = "coincurve-20.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cdbf0da0e0809366fdfff236b7eb6e663669c7b1f46361a4c4d05f5b7e94c57"},
|
||||
{file = "coincurve-20.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d72222b4ecd3952e8ffcbf59bc7e0d1b181161ba170b60e5c8e1f359a43bbe7e"},
|
||||
{file = "coincurve-20.0.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9add43c4807f0c17a940ce4076334c28f51d09c145cd478400e89dcfb83fb59d"},
|
||||
{file = "coincurve-20.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bcc94cceea6ec8863815134083e6221a034b1ecef822d0277cf6ad2e70009b7f"},
|
||||
{file = "coincurve-20.0.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ffbdfef6a6d147988eabaed681287a9a7e6ba45ecc0a8b94ba62ad0a7656d97"},
|
||||
{file = "coincurve-20.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13335c19c7e5f36eaba2a53c68073d981980d7dc7abfee68d29f2da887ccd24e"},
|
||||
{file = "coincurve-20.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:7fbfb8d16cf2bea2cf48fc5246d4cb0a06607d73bb5c57c007c9aed7509f855e"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4870047704cddaae7f0266a549c927407c2ba0ec92d689e3d2b511736812a905"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81ce41263517b0a9f43cd570c87720b3c13324929584fa28d2e4095969b6015d"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:572083ccce6c7b514d482f25f394368f4ae888f478bd0b067519d33160ea2fcc"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee5bc78a31a2f1370baf28aaff3949bc48f940a12b0359d1cd2c4115742874e6"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2895d032e281c4e747947aae4bcfeef7c57eabfd9be22886c0ca4e1365c7c1f"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d3e2f21957ada0e1742edbde117bb41758fa8691b69c8d186c23e9e522ea71cd"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c2baa26b1aad1947ca07b3aa9e6a98940c5141c6bdd0f9b44d89e36da7282ffa"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7eacc7944ddf9e2b7448ecbe84753841ab9874b8c332a4f5cc3b2f184db9f4a2"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:c293c095dc690178b822cadaaeb81de3cc0d28f8bdf8216ed23551dcce153a26"},
|
||||
{file = "coincurve-20.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:11a47083a0b7092d3eb50929f74ffd947c4a5e7035796b81310ea85289088c7a"},
|
||||
{file = "coincurve-20.0.0.tar.gz", hash = "sha256:872419e404300302e938849b6b92a196fabdad651060b559dc310e52f8392829"},
|
||||
{file = "coincurve-18.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b1a42eba91b9e4f833309e94bc6a270b1700cb4567d4809ef91f00968b57925"},
|
||||
{file = "coincurve-18.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:116bf1b60a6e72e23c6b153d7c79f0e565d82973d917a3cecf655ffb29263163"},
|
||||
{file = "coincurve-18.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d53e2a268142924c24e9b786b3e6c3603fae54bb8211560036b0e9ce6a9f2dbc"},
|
||||
{file = "coincurve-18.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b31ab366fadff16ecfdde96ffc07e70fee83850f88bd1f985a8b4977a68bbfb"},
|
||||
{file = "coincurve-18.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e3c37cfadac6896668a130ea46296a3dfdeea0160fd66a51e377ad00795269"},
|
||||
{file = "coincurve-18.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f3e5f2a2d774050b3ea8bf2167f2d598fde58d7690779931516714d98b65d884"},
|
||||
{file = "coincurve-18.0.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:83379dd70291480df2052554851bfd17444c003aef7c4bb02d96d73eec69fe28"},
|
||||
{file = "coincurve-18.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:33678f6b43edbeab6605584c725305f4f814239780c53eba0f8e4bc4a52b1d1a"},
|
||||
{file = "coincurve-18.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f40646d5f29ac9026f8cc1b368bc9ab68710fad055b64fbec020f9bbfc99b242"},
|
||||
{file = "coincurve-18.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:779da694dea1b1d09e16b00e079f6a1195290ce9568f39c95cddf35f1f49ec49"},
|
||||
{file = "coincurve-18.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7844f01904e32317a00696a27fd771860e53a2fa62e5c66eace9337d2742c9e6"},
|
||||
{file = "coincurve-18.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257c6171cd0301c119ef41360f0d0c2fb5cc288717b33d3bd5482a4c9ae04551"},
|
||||
{file = "coincurve-18.0.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f8bcb9c40fd730cf377fa448f1304355d6497fb3d00b7b0a69a10dfcc14a6d28"},
|
||||
{file = "coincurve-18.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e3abb7f65e2b5fb66a15e374faeaafe6700fdb83fb66d1873ddff91c395a3b74"},
|
||||
{file = "coincurve-18.0.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f44b9ba588b34795d1b4074f9a9fa372adef3fde58300bf32f40a69e8cd72a23"},
|
||||
{file = "coincurve-18.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:908467330cd3047c71105a08394c4f3e7dce76e4371b030ba8b0ef863013e3ca"},
|
||||
{file = "coincurve-18.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:599b1b3cf097cae920d97f31a5b8e8aff185ca8fa5d8a785b2edf7b199fb9731"},
|
||||
{file = "coincurve-18.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d2c20d108580bce5efedb980688031462168f4de2446de95898b48a249127a2"},
|
||||
{file = "coincurve-18.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eba563f7f70c10323227d1890072172bd84df6f814c9a6b012033b214426b6cf"},
|
||||
{file = "coincurve-18.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:412a06b7d1b8229f25318f05e76310298da5ad55d73851eabac7ddfdcdc5bff4"},
|
||||
{file = "coincurve-18.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:286969b6f789bbd9d744d28350a3630c1cb3ee045263469a28892f70a4a6654a"},
|
||||
{file = "coincurve-18.0.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:14700463009c7d799a746929728223aa53ff1ece394ea408516d98d637434883"},
|
||||
{file = "coincurve-18.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7f1142252e870f091b2c2c21cc1fadfdd29af23d02e99f29add0f14d1ba94b4c"},
|
||||
{file = "coincurve-18.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cd11d2ca5b7e989c5ce1af217a2ad78c19c21afca786f198d1b1a408d6f408dc"},
|
||||
{file = "coincurve-18.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1bce17d7475cee9db2c2fa7af07eaab582732b378acf6dcaee417de1df2d8661"},
|
||||
{file = "coincurve-18.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ab662b67454fea7f0a5ae855ba6ad9410bcaebe68b97f4dade7b5944dec3a11"},
|
||||
{file = "coincurve-18.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23b9ced9cce32dabb4bc15fa6449252fa51efddf0268481973e4c3772a5a68c6"},
|
||||
{file = "coincurve-18.0.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d05641cf31d68514c47cb54105d20acbae79fc3ee3942454eaaf411babb3f880"},
|
||||
{file = "coincurve-18.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a7b31efe56b3f6434828ad5f6ecde4a95747bb69b59032746482eebb8f3456a4"},
|
||||
{file = "coincurve-18.0.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2d95103ed43df855121cd925869ae2589360a8d94fcd61b236958deacfb9a359"},
|
||||
{file = "coincurve-18.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:abeb4c1d78e1a81a3f1c99a406cd858669582ada2d976e876ef694f57dec95ca"},
|
||||
{file = "coincurve-18.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fceca9d6ecaa1e8f891675e4f4ff530d54e41c648fc6e8a816835ffa640fa899"},
|
||||
{file = "coincurve-18.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e009f06287507158f16c82cc313c0f3bfd0e9ec1e82d1a4d5fa1c5b6c0060f69"},
|
||||
{file = "coincurve-18.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a0c0c1e492ef08efe99d25a23d535e2bff667bbef43d71a6f8893ae811b3d81"},
|
||||
{file = "coincurve-18.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3caf58877bcf41eb4c1be7a2d54317f0b31541d99ba248dae28821b19c52a0db"},
|
||||
{file = "coincurve-18.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8964e680c622a2b5eea940abdf51c77c1bd3d4fde2a04cec2420bf91981b198a"},
|
||||
{file = "coincurve-18.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:73e464e0ace77c686fdc54590e5592905b6802f9fc20a0c023f0b1585669d6a3"},
|
||||
{file = "coincurve-18.0.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ba9eaddd50a2ce0d891af7cee11c2e048d1f0f44bf87db00a5c4b1eee7e3391b"},
|
||||
{file = "coincurve-18.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8290903d4629f27f9f3cdeec72ffa97536c5a6ed5ba7e3413b2707991c650fbe"},
|
||||
{file = "coincurve-18.0.0-py3-none-win32.whl", hash = "sha256:c60690bd7704d8563968d2dded33eb514875a52b5964f085409965ad041b2555"},
|
||||
{file = "coincurve-18.0.0-py3-none-win_amd64.whl", hash = "sha256:704d1abf2e78def33988368592233a8ec9b98bfc45dfa2ec9e898adfad46e5ad"},
|
||||
{file = "coincurve-18.0.0.tar.gz", hash = "sha256:c86626afe417a09d8e80e56780efcae3ae516203b23b5ade84813916e1c94fc1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
asn1crypto = "*"
|
||||
cffi = ">=1.3.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["coverage", "pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
@@ -803,56 +792,47 @@ toml = ["tomli"]
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "42.0.8"
|
||||
version = "41.0.7"
|
||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"},
|
||||
{file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"},
|
||||
{file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"},
|
||||
{file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"},
|
||||
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"},
|
||||
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"},
|
||||
{file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"},
|
||||
{file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"},
|
||||
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"},
|
||||
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"},
|
||||
{file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"},
|
||||
{file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-win32.whl", hash = "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d"},
|
||||
{file = "cryptography-41.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2"},
|
||||
{file = "cryptography-41.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960"},
|
||||
{file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003"},
|
||||
{file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7"},
|
||||
{file = "cryptography-41.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec"},
|
||||
{file = "cryptography-41.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be"},
|
||||
{file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a"},
|
||||
{file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c"},
|
||||
{file = "cryptography-41.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a"},
|
||||
{file = "cryptography-41.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39"},
|
||||
{file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a"},
|
||||
{file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248"},
|
||||
{file = "cryptography-41.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309"},
|
||||
{file = "cryptography-41.0.7.tar.gz", hash = "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""}
|
||||
cffi = ">=1.12"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
|
||||
docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"]
|
||||
docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
|
||||
nox = ["nox"]
|
||||
pep8test = ["check-sdist", "click", "mypy", "ruff"]
|
||||
pep8test = ["black", "check-sdist", "mypy", "ruff"]
|
||||
sdist = ["build"]
|
||||
ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
|
||||
test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
|
||||
test-randomorder = ["pytest-randomly"]
|
||||
|
||||
[[package]]
|
||||
@@ -997,23 +977,23 @@ test = ["pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "fastapi"
|
||||
version = "0.113.0"
|
||||
version = "0.112.0"
|
||||
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "fastapi-0.113.0-py3-none-any.whl", hash = "sha256:c8d364485b6361fb643d53920a18d58a696e189abcb901ec03b487e35774c476"},
|
||||
{file = "fastapi-0.113.0.tar.gz", hash = "sha256:b7cf9684dc154dfc93f8b718e5850577b529889096518df44defa41e73caf50f"},
|
||||
{file = "fastapi-0.112.0-py3-none-any.whl", hash = "sha256:3487ded9778006a45834b8c816ec4a48d522e2631ca9e75ec5a774f1b052f821"},
|
||||
{file = "fastapi-0.112.0.tar.gz", hash = "sha256:d262bc56b7d101d1f4e8fc0ad2ac75bb9935fec504d2b7117686cec50710cf05"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
|
||||
starlette = ">=0.37.2,<0.39.0"
|
||||
starlette = ">=0.37.2,<0.38.0"
|
||||
typing-extensions = ">=4.8.0"
|
||||
|
||||
[package.extras]
|
||||
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
|
||||
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"]
|
||||
all = ["email_validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
|
||||
standard = ["email_validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "fastapi-sso"
|
||||
@@ -1121,119 +1101,119 @@ test = ["objgraph", "psutil"]
|
||||
|
||||
[[package]]
|
||||
name = "grpcio"
|
||||
version = "1.66.1"
|
||||
version = "1.65.5"
|
||||
description = "HTTP/2-based RPC framework"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "grpcio-1.66.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:4877ba180591acdf127afe21ec1c7ff8a5ecf0fe2600f0d3c50e8c4a1cbc6492"},
|
||||
{file = "grpcio-1.66.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:3750c5a00bd644c75f4507f77a804d0189d97a107eb1481945a0cf3af3e7a5ac"},
|
||||
{file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:a013c5fbb12bfb5f927444b477a26f1080755a931d5d362e6a9a720ca7dbae60"},
|
||||
{file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1b24c23d51a1e8790b25514157d43f0a4dce1ac12b3f0b8e9f66a5e2c4c132f"},
|
||||
{file = "grpcio-1.66.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7ffb8ea674d68de4cac6f57d2498fef477cef582f1fa849e9f844863af50083"},
|
||||
{file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:307b1d538140f19ccbd3aed7a93d8f71103c5d525f3c96f8616111614b14bf2a"},
|
||||
{file = "grpcio-1.66.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c17ebcec157cfb8dd445890a03e20caf6209a5bd4ac5b040ae9dbc59eef091d"},
|
||||
{file = "grpcio-1.66.1-cp310-cp310-win32.whl", hash = "sha256:ef82d361ed5849d34cf09105d00b94b6728d289d6b9235513cb2fcc79f7c432c"},
|
||||
{file = "grpcio-1.66.1-cp310-cp310-win_amd64.whl", hash = "sha256:292a846b92cdcd40ecca46e694997dd6b9be6c4c01a94a0dfb3fcb75d20da858"},
|
||||
{file = "grpcio-1.66.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:c30aeceeaff11cd5ddbc348f37c58bcb96da8d5aa93fed78ab329de5f37a0d7a"},
|
||||
{file = "grpcio-1.66.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8a1e224ce6f740dbb6b24c58f885422deebd7eb724aff0671a847f8951857c26"},
|
||||
{file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a66fe4dc35d2330c185cfbb42959f57ad36f257e0cc4557d11d9f0a3f14311df"},
|
||||
{file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ba04659e4fce609de2658fe4dbf7d6ed21987a94460f5f92df7579fd5d0e22"},
|
||||
{file = "grpcio-1.66.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4573608e23f7e091acfbe3e84ac2045680b69751d8d67685ffa193a4429fedb1"},
|
||||
{file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7e06aa1f764ec8265b19d8f00140b8c4b6ca179a6dc67aa9413867c47e1fb04e"},
|
||||
{file = "grpcio-1.66.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3885f037eb11f1cacc41f207b705f38a44b69478086f40608959bf5ad85826dd"},
|
||||
{file = "grpcio-1.66.1-cp311-cp311-win32.whl", hash = "sha256:97ae7edd3f3f91480e48ede5d3e7d431ad6005bfdbd65c1b56913799ec79e791"},
|
||||
{file = "grpcio-1.66.1-cp311-cp311-win_amd64.whl", hash = "sha256:cfd349de4158d797db2bd82d2020554a121674e98fbe6b15328456b3bf2495bb"},
|
||||
{file = "grpcio-1.66.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:a92c4f58c01c77205df6ff999faa008540475c39b835277fb8883b11cada127a"},
|
||||
{file = "grpcio-1.66.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fdb14bad0835914f325349ed34a51940bc2ad965142eb3090081593c6e347be9"},
|
||||
{file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:f03a5884c56256e08fd9e262e11b5cfacf1af96e2ce78dc095d2c41ccae2c80d"},
|
||||
{file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ca2559692d8e7e245d456877a85ee41525f3ed425aa97eb7a70fc9a79df91a0"},
|
||||
{file = "grpcio-1.66.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ca1be089fb4446490dd1135828bd42a7c7f8421e74fa581611f7afdf7ab761"},
|
||||
{file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d639c939ad7c440c7b2819a28d559179a4508783f7e5b991166f8d7a34b52815"},
|
||||
{file = "grpcio-1.66.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b9feb4e5ec8dc2d15709f4d5fc367794d69277f5d680baf1910fc9915c633524"},
|
||||
{file = "grpcio-1.66.1-cp312-cp312-win32.whl", hash = "sha256:7101db1bd4cd9b880294dec41a93fcdce465bdbb602cd8dc5bd2d6362b618759"},
|
||||
{file = "grpcio-1.66.1-cp312-cp312-win_amd64.whl", hash = "sha256:b0aa03d240b5539648d996cc60438f128c7f46050989e35b25f5c18286c86734"},
|
||||
{file = "grpcio-1.66.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:ecfe735e7a59e5a98208447293ff8580e9db1e890e232b8b292dc8bd15afc0d2"},
|
||||
{file = "grpcio-1.66.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4825a3aa5648010842e1c9d35a082187746aa0cdbf1b7a2a930595a94fb10fce"},
|
||||
{file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:f517fd7259fe823ef3bd21e508b653d5492e706e9f0ef82c16ce3347a8a5620c"},
|
||||
{file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1fe60d0772831d96d263b53d83fb9a3d050a94b0e94b6d004a5ad111faa5b5b"},
|
||||
{file = "grpcio-1.66.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31a049daa428f928f21090403e5d18ea02670e3d5d172581670be006100db9ef"},
|
||||
{file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f914386e52cbdeb5d2a7ce3bf1fdfacbe9d818dd81b6099a05b741aaf3848bb"},
|
||||
{file = "grpcio-1.66.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bff2096bdba686019fb32d2dde45b95981f0d1490e054400f70fc9a8af34b49d"},
|
||||
{file = "grpcio-1.66.1-cp38-cp38-win32.whl", hash = "sha256:aa8ba945c96e73de29d25331b26f3e416e0c0f621e984a3ebdb2d0d0b596a3b3"},
|
||||
{file = "grpcio-1.66.1-cp38-cp38-win_amd64.whl", hash = "sha256:161d5c535c2bdf61b95080e7f0f017a1dfcb812bf54093e71e5562b16225b4ce"},
|
||||
{file = "grpcio-1.66.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:d0cd7050397b3609ea51727b1811e663ffda8bda39c6a5bb69525ef12414b503"},
|
||||
{file = "grpcio-1.66.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0e6c9b42ded5d02b6b1fea3a25f036a2236eeb75d0579bfd43c0018c88bf0a3e"},
|
||||
{file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:c9f80f9fad93a8cf71c7f161778ba47fd730d13a343a46258065c4deb4b550c0"},
|
||||
{file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dd67ed9da78e5121efc5c510f0122a972216808d6de70953a740560c572eb44"},
|
||||
{file = "grpcio-1.66.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48b0d92d45ce3be2084b92fb5bae2f64c208fea8ceed7fccf6a7b524d3c4942e"},
|
||||
{file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d813316d1a752be6f5c4360c49f55b06d4fe212d7df03253dfdae90c8a402bb"},
|
||||
{file = "grpcio-1.66.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9c9bebc6627873ec27a70fc800f6083a13c70b23a5564788754b9ee52c5aef6c"},
|
||||
{file = "grpcio-1.66.1-cp39-cp39-win32.whl", hash = "sha256:30a1c2cf9390c894c90bbc70147f2372130ad189cffef161f0432d0157973f45"},
|
||||
{file = "grpcio-1.66.1-cp39-cp39-win_amd64.whl", hash = "sha256:17663598aadbedc3cacd7bbde432f541c8e07d2496564e22b214b22c7523dac8"},
|
||||
{file = "grpcio-1.66.1.tar.gz", hash = "sha256:35334f9c9745add3e357e3372756fd32d925bd52c41da97f4dfdafbde0bf0ee2"},
|
||||
{file = "grpcio-1.65.5-cp310-cp310-linux_armv7l.whl", hash = "sha256:b67d450f1e008fedcd81e097a3a400a711d8be1a8b20f852a7b8a73fead50fe3"},
|
||||
{file = "grpcio-1.65.5-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:a70a20eed87bba647a38bedd93b3ce7db64b3f0e8e0952315237f7f5ca97b02d"},
|
||||
{file = "grpcio-1.65.5-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f79c87c114bf37adf408026b9e2e333fe9ff31dfc9648f6f80776c513145c813"},
|
||||
{file = "grpcio-1.65.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f17f9fa2d947dbfaca01b3ab2c62eefa8240131fdc67b924eb42ce6032e3e5c1"},
|
||||
{file = "grpcio-1.65.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32d60e18ff7c34fe3f6db3d35ad5c6dc99f5b43ff3982cb26fad4174462d10b1"},
|
||||
{file = "grpcio-1.65.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fe6505376f5b00bb008e4e1418152e3ad3d954b629da286c7913ff3cfc0ff740"},
|
||||
{file = "grpcio-1.65.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:33158e56c6378063923c417e9fbdb28660b6e0e2835af42e67f5a7793f587af7"},
|
||||
{file = "grpcio-1.65.5-cp310-cp310-win32.whl", hash = "sha256:1cbc208edb9acf1cc339396a1a36b83796939be52f34e591c90292045b579fbf"},
|
||||
{file = "grpcio-1.65.5-cp310-cp310-win_amd64.whl", hash = "sha256:bc74f3f745c37e2c5685c9d2a2d5a94de00f286963f5213f763ae137bf4f2358"},
|
||||
{file = "grpcio-1.65.5-cp311-cp311-linux_armv7l.whl", hash = "sha256:3207ae60d07e5282c134b6e02f9271a2cb523c6d7a346c6315211fe2bf8d61ed"},
|
||||
{file = "grpcio-1.65.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a2f80510f99f82d4eb825849c486df703f50652cea21c189eacc2b84f2bde764"},
|
||||
{file = "grpcio-1.65.5-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a80e9a5e3f93c54f5eb82a3825ea1fc4965b2fa0026db2abfecb139a5c4ecdf1"},
|
||||
{file = "grpcio-1.65.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b2944390a496567de9e70418f3742b477d85d8ca065afa90432edc91b4bb8ad"},
|
||||
{file = "grpcio-1.65.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3655139d7be213c32c79ef6fb2367cae28e56ef68e39b1961c43214b457f257"},
|
||||
{file = "grpcio-1.65.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05f02d68fc720e085f061b704ee653b181e6d5abfe315daef085719728d3d1fd"},
|
||||
{file = "grpcio-1.65.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1c4caafe71aef4dabf53274bbf4affd6df651e9f80beedd6b8e08ff438ed3260"},
|
||||
{file = "grpcio-1.65.5-cp311-cp311-win32.whl", hash = "sha256:84c901cdec16a092099f251ef3360d15e29ef59772150fa261d94573612539b5"},
|
||||
{file = "grpcio-1.65.5-cp311-cp311-win_amd64.whl", hash = "sha256:11f8b16121768c1cb99d7dcb84e01510e60e6a206bf9123e134118802486f035"},
|
||||
{file = "grpcio-1.65.5-cp312-cp312-linux_armv7l.whl", hash = "sha256:ee6ed64a27588a2c94e8fa84fe8f3b5c89427d4d69c37690903d428ec61ca7e4"},
|
||||
{file = "grpcio-1.65.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:76991b7a6fb98630a3328839755181ce7c1aa2b1842aa085fd4198f0e5198960"},
|
||||
{file = "grpcio-1.65.5-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:89c00a18801b1ed9cc441e29b521c354725d4af38c127981f2c950c796a09b6e"},
|
||||
{file = "grpcio-1.65.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:078038e150a897e5e402ed3d57f1d31ebf604cbed80f595bd281b5da40762a92"},
|
||||
{file = "grpcio-1.65.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97962720489ef31b5ad8a916e22bc31bba3664e063fb9f6702dce056d4aa61b"},
|
||||
{file = "grpcio-1.65.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b8270b15b99781461b244f5c81d5c2bc9696ab9189fb5ff86c841417fb3b39fe"},
|
||||
{file = "grpcio-1.65.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8e5c4c15ac3fe1eb68e46bc51e66ad29be887479f231f8237cf8416058bf0cc1"},
|
||||
{file = "grpcio-1.65.5-cp312-cp312-win32.whl", hash = "sha256:f5b5970341359341d0e4c789da7568264b2a89cd976c05ea476036852b5950cd"},
|
||||
{file = "grpcio-1.65.5-cp312-cp312-win_amd64.whl", hash = "sha256:238a625f391a1b9f5f069bdc5930f4fd71b74426bea52196fc7b83f51fa97d34"},
|
||||
{file = "grpcio-1.65.5-cp38-cp38-linux_armv7l.whl", hash = "sha256:6c4e62bcf297a1568f627f39576dbfc27f1e5338a691c6dd5dd6b3979da51d1c"},
|
||||
{file = "grpcio-1.65.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d7df567b67d16d4177835a68d3f767bbcbad04da9dfb52cbd19171f430c898bd"},
|
||||
{file = "grpcio-1.65.5-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:b7ca419f1462390851eec395b2089aad1e49546b52d4e2c972ceb76da69b10f8"},
|
||||
{file = "grpcio-1.65.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa36dd8496d3af0d40165252a669fa4f6fd2db4b4026b9a9411cbf060b9d6a15"},
|
||||
{file = "grpcio-1.65.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a101696f9ece90a0829988ff72f1b1ea2358f3df035bdf6d675dd8b60c2c0894"},
|
||||
{file = "grpcio-1.65.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2a6d8169812932feac514b420daffae8ab8e36f90f3122b94ae767e633296b17"},
|
||||
{file = "grpcio-1.65.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:47d0aaaab82823f0aa6adea5184350b46e2252e13a42a942db84da5b733f2e05"},
|
||||
{file = "grpcio-1.65.5-cp38-cp38-win32.whl", hash = "sha256:85ae8f8517d5bcc21fb07dbf791e94ed84cc28f84c903cdc2bd7eaeb437c8f45"},
|
||||
{file = "grpcio-1.65.5-cp38-cp38-win_amd64.whl", hash = "sha256:770bd4bd721961f6dd8049bc27338564ba8739913f77c0f381a9815e465ff965"},
|
||||
{file = "grpcio-1.65.5-cp39-cp39-linux_armv7l.whl", hash = "sha256:ab5ec837d8cee8dbce9ef6386125f119b231e4333cc6b6d57b6c5c7c82a72331"},
|
||||
{file = "grpcio-1.65.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cabd706183ee08d8026a015af5819a0b3a8959bdc9d1f6fdacd1810f09200f2a"},
|
||||
{file = "grpcio-1.65.5-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:ec71fc5b39821ad7d80db7473c8f8c2910f3382f0ddadfbcfc2c6c437107eb67"},
|
||||
{file = "grpcio-1.65.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a9e35bcb045e39d7cac30464c285389b9a816ac2067e4884ad2c02e709ef8e"},
|
||||
{file = "grpcio-1.65.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d750e9330eb14236ca11b78d0c494eed13d6a95eb55472298f0e547c165ee324"},
|
||||
{file = "grpcio-1.65.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2b91ce647b6307f25650872454a4d02a2801f26a475f90d0b91ed8110baae589"},
|
||||
{file = "grpcio-1.65.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8da58ff80bc4556cf29bc03f5fff1f03b8387d6aaa7b852af9eb65b2cf833be4"},
|
||||
{file = "grpcio-1.65.5-cp39-cp39-win32.whl", hash = "sha256:7a412959aa5f08c5ac04aa7b7c3c041f5e4298cadd4fcc2acff195b56d185ebc"},
|
||||
{file = "grpcio-1.65.5-cp39-cp39-win_amd64.whl", hash = "sha256:55714ea852396ec9568f45f487639945ab674de83c12bea19d5ddbc3ae41ada3"},
|
||||
{file = "grpcio-1.65.5.tar.gz", hash = "sha256:ec6f219fb5d677a522b0deaf43cea6697b16f338cb68d009e30930c4aa0d2209"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
protobuf = ["grpcio-tools (>=1.66.1)"]
|
||||
protobuf = ["grpcio-tools (>=1.65.5)"]
|
||||
|
||||
[[package]]
|
||||
name = "grpcio-tools"
|
||||
version = "1.66.1"
|
||||
version = "1.65.5"
|
||||
description = "Protobuf code generator for gRPC"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "grpcio_tools-1.66.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:e0c71405399ef59782600b1f0bdebc69ba12d7c9527cd268162a86273971d294"},
|
||||
{file = "grpcio_tools-1.66.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:df1a174a6f9d3b4c380f005f33352d2e95464f33f021fb08084735a2eb6e23b1"},
|
||||
{file = "grpcio_tools-1.66.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:7d789bfe53fce9e87aa80c3694a366258ce4c41b706258e9228ed4994832b780"},
|
||||
{file = "grpcio_tools-1.66.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95c44a265ff01fd05166edae9350bc2e7d1d9a95e8f53b8cd04d2ae0a588c583"},
|
||||
{file = "grpcio_tools-1.66.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b962a8767c3c0f9afe92e0dd6bb0b2305d35195a1053f84d4d31f585b87557ed"},
|
||||
{file = "grpcio_tools-1.66.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d8616773126ec3cdf747b06a12e957b43ac15c34e4728def91fa67249a7c689a"},
|
||||
{file = "grpcio_tools-1.66.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0067e79b6001560ac6acc78cca11fd3504fa27f8af46e3cdbac2f4998505e597"},
|
||||
{file = "grpcio_tools-1.66.1-cp310-cp310-win32.whl", hash = "sha256:fa4f95a79a34afc3b5464895d091cd1911227fc3ab0441b9a37cd1817cf7db86"},
|
||||
{file = "grpcio_tools-1.66.1-cp310-cp310-win_amd64.whl", hash = "sha256:3acce426f5e643de63019311171f4d31131da8149de518716a95c29a2c12dd38"},
|
||||
{file = "grpcio_tools-1.66.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:9a07e24feb7472419cf70ebbb38dd4299aea696f91f191b62a99b3ee9ff03f89"},
|
||||
{file = "grpcio_tools-1.66.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:097a069e7c640043921ecaf3e88d7af78ccd40c25dbddc91db2a4a2adbd0393d"},
|
||||
{file = "grpcio_tools-1.66.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:016fa273dc696c9d8045091ac50e000bce766183a6b150801f51c2946e33dbe3"},
|
||||
{file = "grpcio_tools-1.66.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ec9f4f964f8e8ed5e9cc13deb678c83d5597074c256805373220627833bc5ad"},
|
||||
{file = "grpcio_tools-1.66.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3198815814cdd12bdb69b7580d7770a4ad4c8b2093e0bd6b987bc817618e3eec"},
|
||||
{file = "grpcio_tools-1.66.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:796620fc41d3fbb566d9614ef22bc55df67fac1f1e19c1e0fb6ec48bc9b6a44b"},
|
||||
{file = "grpcio_tools-1.66.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:222d8dc218560698e1abf652fb47e4015994ec7a265ef46e012fd9c9e77a4d6b"},
|
||||
{file = "grpcio_tools-1.66.1-cp311-cp311-win32.whl", hash = "sha256:56e17a11f34df252b4c6fb8aa8cd7b44d162dba9f3333be87ddf7c8bf496622a"},
|
||||
{file = "grpcio_tools-1.66.1-cp311-cp311-win_amd64.whl", hash = "sha256:edd52d667f2aa3c73233be0a821596937f24536647c12d96bfc54aa4cb04747d"},
|
||||
{file = "grpcio_tools-1.66.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:869b6960d5daffda0dac1a474b44144f0dace0d4336394e499c4f400c5e2f8d9"},
|
||||
{file = "grpcio_tools-1.66.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:68d9390bf9ba863ac147fc722d6548caa587235e887cac1bc2438212e89d1de7"},
|
||||
{file = "grpcio_tools-1.66.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:b8660401beca7e3af28722439e07b0bcdca80b4a68f5a5a1138ae7b7780a6abf"},
|
||||
{file = "grpcio_tools-1.66.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb67b9aa9cd69468bceb933e8e0f89fd13695746c018c4d2e6b3b84e73f3ad97"},
|
||||
{file = "grpcio_tools-1.66.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5daceb9716e31edc0e1ba0f93303785211438c43502edddad7a919fc4cb3d664"},
|
||||
{file = "grpcio_tools-1.66.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0a86398a4cd0665bc7f09fa90b89bac592c959d2c895bf3cf5d47a98c0f2d24c"},
|
||||
{file = "grpcio_tools-1.66.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1b4acb53338072ab3023e418a5c7059cb15686abd1607516fa1453406dd5f69d"},
|
||||
{file = "grpcio_tools-1.66.1-cp312-cp312-win32.whl", hash = "sha256:88e04b7546101bc79c868c941777efd5088063a9e4f03b4d7263dde796fbabf7"},
|
||||
{file = "grpcio_tools-1.66.1-cp312-cp312-win_amd64.whl", hash = "sha256:5b4fc56abeafae74140f5da29af1093e88ce64811d77f1a81c3146e9e996fb6a"},
|
||||
{file = "grpcio_tools-1.66.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:d4dd2ff982c1aa328ef47ce34f07af82f1f13599912fb1618ebc5fe1e14dddb8"},
|
||||
{file = "grpcio_tools-1.66.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:066648543f786cb74b1fef5652359952455dbba37e832642026fd9fd8a219b5f"},
|
||||
{file = "grpcio_tools-1.66.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:d19d47744c30e6bafa76b3113740e71f382d75ebb2918c1efd62ebe6ba7e20f9"},
|
||||
{file = "grpcio_tools-1.66.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:739c53571130b359b738ac7d6d0a1f772e15779b66df7e6764bee4071cd38689"},
|
||||
{file = "grpcio_tools-1.66.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2226ff8d3ecba83b7622946df19d6e8e15cb52f761b8d9e2f807b228db5f1b1e"},
|
||||
{file = "grpcio_tools-1.66.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2f4b1498cb8b422fbae32a491c9154e8d47650caf5852fbe6b3b34253e824343"},
|
||||
{file = "grpcio_tools-1.66.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:93d2d9e14e81affdc63d67c42eb16a8da1b6fecc16442a703ca60eb0e7591691"},
|
||||
{file = "grpcio_tools-1.66.1-cp38-cp38-win32.whl", hash = "sha256:d761dfd97a10e4aae73628b5120c64e56f0cded88651d0003d2d80e678c3e7c9"},
|
||||
{file = "grpcio_tools-1.66.1-cp38-cp38-win_amd64.whl", hash = "sha256:e1c2ac0955f5fb87b8444316e475242d194c3f3cd0b7b6e54b889a7b6f05156f"},
|
||||
{file = "grpcio_tools-1.66.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:5f1f04578b72c281e39274348a61d240c48d5321ba8d7a8838e194099ecbc322"},
|
||||
{file = "grpcio_tools-1.66.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:da9b0c08dbbf07535ee1b75a22d0acc5675a808a3a3df9f9b21e0e73ddfbb3a9"},
|
||||
{file = "grpcio_tools-1.66.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:e302b4e1fa856d74ff65c65888b3a37153287ce6ad5bad80b2fdf95130accec2"},
|
||||
{file = "grpcio_tools-1.66.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fc3f62494f238774755ff90f0e66a93ac7972ea1eb7180c45acf4fd53b25cca"},
|
||||
{file = "grpcio_tools-1.66.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23cad65ff22459aa387f543d293f54834c9aac8f76fb7416a7046556df75b567"},
|
||||
{file = "grpcio_tools-1.66.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3d17a27c567a5e4d18f487368215cb51b43e2499059fd6113b92f7ae1fee48be"},
|
||||
{file = "grpcio_tools-1.66.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4df167e67b083f96bc277032a526f6186e98662aaa49baea1dfb8ecfe26ce117"},
|
||||
{file = "grpcio_tools-1.66.1-cp39-cp39-win32.whl", hash = "sha256:f94d5193b2f2a9595795b83e7978b2bee1c0399da66f2f24d179c388f81fb99c"},
|
||||
{file = "grpcio_tools-1.66.1-cp39-cp39-win_amd64.whl", hash = "sha256:66f527a1e3f063065e29cf6f3e55892434d13a5a51e3b22402e09da9521e98a3"},
|
||||
{file = "grpcio_tools-1.66.1.tar.gz", hash = "sha256:5055ffe840ea8f505c30378be02afb4dbecb33480e554debe10b63d6b2f641c3"},
|
||||
{file = "grpcio_tools-1.65.5-cp310-cp310-linux_armv7l.whl", hash = "sha256:f141f247a93e4c7faf33ac683a9cab93bb6570946a219260d33e2e62079db6e8"},
|
||||
{file = "grpcio_tools-1.65.5-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:a6d05950c62024ac54dfb7b7987fd45e22e832143aa88768439aa12073e9d035"},
|
||||
{file = "grpcio_tools-1.65.5-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:675df59961e2ab7808a3c0222ad995d8886bbbb7e77000fba1059214c9ce3e09"},
|
||||
{file = "grpcio_tools-1.65.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe5a21e4970cc2555066ba37c7c743749ccd0bd056d4262e97678927c586def8"},
|
||||
{file = "grpcio_tools-1.65.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d0d7d34b4b3fba78075a923de2f962b33bcc04926569966c00219d5f41f2589"},
|
||||
{file = "grpcio_tools-1.65.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:474d5905ee0700662b42f71ce2fc5901786c88d5a54c08749fa5bccae1db27af"},
|
||||
{file = "grpcio_tools-1.65.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0f698f34be22a89426f986310ee866b8faa812355aab5d241fdaf742b546c36c"},
|
||||
{file = "grpcio_tools-1.65.5-cp310-cp310-win32.whl", hash = "sha256:3d8cee4c1f0bca80115cfa99f25ab6e6c6797b4443b1f0d5fa949bf2e9ac5af9"},
|
||||
{file = "grpcio_tools-1.65.5-cp310-cp310-win_amd64.whl", hash = "sha256:ac013d5d118dfafc887c3da1649dbd5087a7161d969dab236050e54c55fa0725"},
|
||||
{file = "grpcio_tools-1.65.5-cp311-cp311-linux_armv7l.whl", hash = "sha256:553b3f406a681719f6c11e70c993fe77383ab6adead9173ad1c6a611e5aaaf48"},
|
||||
{file = "grpcio_tools-1.65.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2a520fbb9be5a05b5a0cdb5c5d481f63fea5db2f048f47f19b613685009890f2"},
|
||||
{file = "grpcio_tools-1.65.5-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:eca7be231ba6de3ac38556dcba1f94c05422e7cc62341bc2787ac9881aed3026"},
|
||||
{file = "grpcio_tools-1.65.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd1e9134e266fefdd49e1c9989d1bdf74578a9f237d7d9df01d871d898deda9b"},
|
||||
{file = "grpcio_tools-1.65.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:777243e4f7152da9d226d9cc1e6d7c2b94335e267c618260e6255a063bb7dfcb"},
|
||||
{file = "grpcio_tools-1.65.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a2e63bf9b6444f28ec684faf3c5fc8394b035fe221842186c3b9ff0121c20534"},
|
||||
{file = "grpcio_tools-1.65.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:969c0b5079beb08ae0a22237652289bfc0e34602403e040bab419f46cb775e50"},
|
||||
{file = "grpcio_tools-1.65.5-cp311-cp311-win32.whl", hash = "sha256:b9aefd9dc742c20bc5fb16f497f6d04b4f4f5c7d44cc86654a334ce7ea9c8021"},
|
||||
{file = "grpcio_tools-1.65.5-cp311-cp311-win_amd64.whl", hash = "sha256:ba27d67421dad33cbb42cdcd144dabed0516f0a5ee48d37250dd1b37c97cca72"},
|
||||
{file = "grpcio_tools-1.65.5-cp312-cp312-linux_armv7l.whl", hash = "sha256:b48943492a7c00a3ce6d7159c37761d006085f7dcd4a13931dcc74ecb8a24b56"},
|
||||
{file = "grpcio_tools-1.65.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ef44822eee4834158eb03cd432e4cf7e716d7d03051cc8314be4956ee9e9da3f"},
|
||||
{file = "grpcio_tools-1.65.5-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:6077a87bb3028797175dd437e08ff42b559045f9588a14eb9c943dd8bde32dcc"},
|
||||
{file = "grpcio_tools-1.65.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ee220c430f87378c598b7217c8c32ce7aeab3d8a93bc92cee92ce6940d870dd"},
|
||||
{file = "grpcio_tools-1.65.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c86a003bfcbf98b6261a89c2aad97197672c99d057fe441440210f052c9b54f1"},
|
||||
{file = "grpcio_tools-1.65.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:475ef5e8d91cbcf9bd9edbf51ac135931853d1c2fe6f8ae0c496b9ef422b41e4"},
|
||||
{file = "grpcio_tools-1.65.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e680b32e90c42d08363a02e9971e690bcf2509cb7bf647e232113b3e777eac9a"},
|
||||
{file = "grpcio_tools-1.65.5-cp312-cp312-win32.whl", hash = "sha256:cc6b010bc26566ca35e858a94daa18992a02e7b70f688a78f3308dada54fc063"},
|
||||
{file = "grpcio_tools-1.65.5-cp312-cp312-win_amd64.whl", hash = "sha256:3ddce72654ce415cbe36561b5e124fc0fcb461582e829016b7aa726824bcadc9"},
|
||||
{file = "grpcio_tools-1.65.5-cp38-cp38-linux_armv7l.whl", hash = "sha256:e5ae4a000c3344c32c1fa63e137ef42e65eae9adb5576dab636e3bc092653ae6"},
|
||||
{file = "grpcio_tools-1.65.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:23bce4fcee7cad2e085923fdfd65ed2bd2173bfc298c8c8964d3dddaef1f49ae"},
|
||||
{file = "grpcio_tools-1.65.5-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:56617905a4e478132b3732fd9dda71e35f1e7adedd34c92248c9a04a3892cb01"},
|
||||
{file = "grpcio_tools-1.65.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c38a8dc81900b7211fc5b1a14ace7f4ffd8cfbfd17e504f40044f0918b99825"},
|
||||
{file = "grpcio_tools-1.65.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b4f00f66a3f024e9bfaf535e2be8a373ada199eb928507945685208bf29536"},
|
||||
{file = "grpcio_tools-1.65.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b2072ad56bec624d0190e605c6b56205a6336f31a35617b90d927791c14aa4ad"},
|
||||
{file = "grpcio_tools-1.65.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c8f8241b859413b8f0c5c8cfd4d9021862d29cf090e60fb8b30968737b575b52"},
|
||||
{file = "grpcio_tools-1.65.5-cp38-cp38-win32.whl", hash = "sha256:e099bff2328931064aef565e811a7ce6ecbe7359c4d377534eee12dc6c35deb8"},
|
||||
{file = "grpcio_tools-1.65.5-cp38-cp38-win_amd64.whl", hash = "sha256:bf78ed1cfc9304dca4d1a5ec578a91b65a5946bf4ee923358a721fb47e35ffdf"},
|
||||
{file = "grpcio_tools-1.65.5-cp39-cp39-linux_armv7l.whl", hash = "sha256:02ed771ce6aea1a5620d818ae41380a7fcf65c6d499c53d1ddaf6ded882640a9"},
|
||||
{file = "grpcio_tools-1.65.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5b6a50253f950fd02caff90a021d6564731a86ffad38b7c0a76423f6ed58e779"},
|
||||
{file = "grpcio_tools-1.65.5-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:8848d509b88631be77b4c40119c02a37d0e884d10b10f0ddb1e3e551d7023b0d"},
|
||||
{file = "grpcio_tools-1.65.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:853ebfa33ed5336b51d0fa5d068bd5b42cb84d09077670ffa6b2dc7980f000cd"},
|
||||
{file = "grpcio_tools-1.65.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:221fd8f4c3f54ced15d9dac2b8800fd1b254bf9cd29414d500ce6f7ddb59be25"},
|
||||
{file = "grpcio_tools-1.65.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:b6b33e23bfc6919c71329dabec632e7693de62efbed24b3e34616c09827909d8"},
|
||||
{file = "grpcio_tools-1.65.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:21122fa43c48e15ff0d656258f942fdf7c3ed2b7ab1530c7d37d3027b71a5872"},
|
||||
{file = "grpcio_tools-1.65.5-cp39-cp39-win32.whl", hash = "sha256:0e092c51089251f41e6e2c03519311509162be3aba2c71a91983d7d86ed300f3"},
|
||||
{file = "grpcio_tools-1.65.5-cp39-cp39-win_amd64.whl", hash = "sha256:2819a3a50c61306074cc95938db97e365acfca873b2cce986ad2d1f519d51f2f"},
|
||||
{file = "grpcio_tools-1.65.5.tar.gz", hash = "sha256:7c3a47ad0070bc907c7818caf55aa1948e9282d24e27afd21015872a25594bc7"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
grpcio = ">=1.66.1"
|
||||
grpcio = ">=1.65.5"
|
||||
protobuf = ">=5.26.1,<6.0dev"
|
||||
setuptools = "*"
|
||||
|
||||
@@ -1658,38 +1638,38 @@ test = ["pytest", "pytest-cov"]
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "1.11.2"
|
||||
version = "1.11.1"
|
||||
description = "Optional static typing for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "mypy-1.11.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a"},
|
||||
{file = "mypy-1.11.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef"},
|
||||
{file = "mypy-1.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383"},
|
||||
{file = "mypy-1.11.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8"},
|
||||
{file = "mypy-1.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7"},
|
||||
{file = "mypy-1.11.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385"},
|
||||
{file = "mypy-1.11.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca"},
|
||||
{file = "mypy-1.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104"},
|
||||
{file = "mypy-1.11.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4"},
|
||||
{file = "mypy-1.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6"},
|
||||
{file = "mypy-1.11.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318"},
|
||||
{file = "mypy-1.11.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36"},
|
||||
{file = "mypy-1.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987"},
|
||||
{file = "mypy-1.11.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca"},
|
||||
{file = "mypy-1.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70"},
|
||||
{file = "mypy-1.11.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b"},
|
||||
{file = "mypy-1.11.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86"},
|
||||
{file = "mypy-1.11.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce"},
|
||||
{file = "mypy-1.11.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1"},
|
||||
{file = "mypy-1.11.2-cp38-cp38-win_amd64.whl", hash = "sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b"},
|
||||
{file = "mypy-1.11.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6"},
|
||||
{file = "mypy-1.11.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70"},
|
||||
{file = "mypy-1.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d"},
|
||||
{file = "mypy-1.11.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d"},
|
||||
{file = "mypy-1.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24"},
|
||||
{file = "mypy-1.11.2-py3-none-any.whl", hash = "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12"},
|
||||
{file = "mypy-1.11.2.tar.gz", hash = "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79"},
|
||||
{file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"},
|
||||
{file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"},
|
||||
{file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"},
|
||||
{file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"},
|
||||
{file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"},
|
||||
{file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"},
|
||||
{file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"},
|
||||
{file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"},
|
||||
{file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"},
|
||||
{file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"},
|
||||
{file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"},
|
||||
{file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"},
|
||||
{file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"},
|
||||
{file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"},
|
||||
{file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"},
|
||||
{file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"},
|
||||
{file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"},
|
||||
{file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"},
|
||||
{file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"},
|
||||
{file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"},
|
||||
{file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"},
|
||||
{file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"},
|
||||
{file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"},
|
||||
{file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"},
|
||||
{file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"},
|
||||
{file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"},
|
||||
{file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1900,22 +1880,22 @@ virtualenv = ">=20.10.0"
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "5.28.0"
|
||||
version = "5.27.3"
|
||||
description = ""
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "protobuf-5.28.0-cp310-abi3-win32.whl", hash = "sha256:66c3edeedb774a3508ae70d87b3a19786445fe9a068dd3585e0cefa8a77b83d0"},
|
||||
{file = "protobuf-5.28.0-cp310-abi3-win_amd64.whl", hash = "sha256:6d7cc9e60f976cf3e873acb9a40fed04afb5d224608ed5c1a105db4a3f09c5b6"},
|
||||
{file = "protobuf-5.28.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:532627e8fdd825cf8767a2d2b94d77e874d5ddb0adefb04b237f7cc296748681"},
|
||||
{file = "protobuf-5.28.0-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:018db9056b9d75eb93d12a9d35120f97a84d9a919bcab11ed56ad2d399d6e8dd"},
|
||||
{file = "protobuf-5.28.0-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:6206afcb2d90181ae8722798dcb56dc76675ab67458ac24c0dd7d75d632ac9bd"},
|
||||
{file = "protobuf-5.28.0-cp38-cp38-win32.whl", hash = "sha256:eef7a8a2f4318e2cb2dee8666d26e58eaf437c14788f3a2911d0c3da40405ae8"},
|
||||
{file = "protobuf-5.28.0-cp38-cp38-win_amd64.whl", hash = "sha256:d001a73c8bc2bf5b5c1360d59dd7573744e163b3607fa92788b7f3d5fefbd9a5"},
|
||||
{file = "protobuf-5.28.0-cp39-cp39-win32.whl", hash = "sha256:dde9fcaa24e7a9654f4baf2a55250b13a5ea701493d904c54069776b99a8216b"},
|
||||
{file = "protobuf-5.28.0-cp39-cp39-win_amd64.whl", hash = "sha256:853db610214e77ee817ecf0514e0d1d052dff7f63a0c157aa6eabae98db8a8de"},
|
||||
{file = "protobuf-5.28.0-py3-none-any.whl", hash = "sha256:510ed78cd0980f6d3218099e874714cdf0d8a95582e7b059b06cabad855ed0a0"},
|
||||
{file = "protobuf-5.28.0.tar.gz", hash = "sha256:dde74af0fa774fa98892209992295adbfb91da3fa98c8f67a88afe8f5a349add"},
|
||||
{file = "protobuf-5.27.3-cp310-abi3-win32.whl", hash = "sha256:dcb307cd4ef8fec0cf52cb9105a03d06fbb5275ce6d84a6ae33bc6cf84e0a07b"},
|
||||
{file = "protobuf-5.27.3-cp310-abi3-win_amd64.whl", hash = "sha256:16ddf3f8c6c41e1e803da7abea17b1793a97ef079a912e42351eabb19b2cffe7"},
|
||||
{file = "protobuf-5.27.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:68248c60d53f6168f565a8c76dc58ba4fa2ade31c2d1ebdae6d80f969cdc2d4f"},
|
||||
{file = "protobuf-5.27.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:b8a994fb3d1c11156e7d1e427186662b64694a62b55936b2b9348f0a7c6625ce"},
|
||||
{file = "protobuf-5.27.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:a55c48f2a2092d8e213bd143474df33a6ae751b781dd1d1f4d953c128a415b25"},
|
||||
{file = "protobuf-5.27.3-cp38-cp38-win32.whl", hash = "sha256:043853dcb55cc262bf2e116215ad43fa0859caab79bb0b2d31b708f128ece035"},
|
||||
{file = "protobuf-5.27.3-cp38-cp38-win_amd64.whl", hash = "sha256:c2a105c24f08b1e53d6c7ffe69cb09d0031512f0b72f812dd4005b8112dbe91e"},
|
||||
{file = "protobuf-5.27.3-cp39-cp39-win32.whl", hash = "sha256:c84eee2c71ed83704f1afbf1a85c3171eab0fd1ade3b399b3fad0884cbcca8bf"},
|
||||
{file = "protobuf-5.27.3-cp39-cp39-win_amd64.whl", hash = "sha256:af7c0b7cfbbb649ad26132e53faa348580f844d9ca46fd3ec7ca48a1ea5db8a1"},
|
||||
{file = "protobuf-5.27.3-py3-none-any.whl", hash = "sha256:8572c6533e544ebf6899c360e91d6bcbbee2549251643d32c52cf8a5de295ba5"},
|
||||
{file = "protobuf-5.27.3.tar.gz", hash = "sha256:82460903e640f2b7e34ee81a947fdaad89de796d324bcbc38ff5430bcdead82c"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1985,54 +1965,54 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "1.10.18"
|
||||
version = "1.10.17"
|
||||
description = "Data validation and settings management using python type hints"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pydantic-1.10.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e405ffcc1254d76bb0e760db101ee8916b620893e6edfbfee563b3c6f7a67c02"},
|
||||
{file = "pydantic-1.10.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e306e280ebebc65040034bff1a0a81fd86b2f4f05daac0131f29541cafd80b80"},
|
||||
{file = "pydantic-1.10.18-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11d9d9b87b50338b1b7de4ebf34fd29fdb0d219dc07ade29effc74d3d2609c62"},
|
||||
{file = "pydantic-1.10.18-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b661ce52c7b5e5f600c0c3c5839e71918346af2ef20062705ae76b5c16914cab"},
|
||||
{file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c20f682defc9ef81cd7eaa485879ab29a86a0ba58acf669a78ed868e72bb89e0"},
|
||||
{file = "pydantic-1.10.18-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ae6b7c8483b1e0bf59e5f1843e4fd8fd405e11df7de217ee65b98eb5462861"},
|
||||
{file = "pydantic-1.10.18-cp310-cp310-win_amd64.whl", hash = "sha256:74fe19dda960b193b0eb82c1f4d2c8e5e26918d9cda858cbf3f41dd28549cb70"},
|
||||
{file = "pydantic-1.10.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72fa46abace0a7743cc697dbb830a41ee84c9db8456e8d77a46d79b537efd7ec"},
|
||||
{file = "pydantic-1.10.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef0fe7ad7cbdb5f372463d42e6ed4ca9c443a52ce544472d8842a0576d830da5"},
|
||||
{file = "pydantic-1.10.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a00e63104346145389b8e8f500bc6a241e729feaf0559b88b8aa513dd2065481"},
|
||||
{file = "pydantic-1.10.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae6fa2008e1443c46b7b3a5eb03800121868d5ab6bc7cda20b5df3e133cde8b3"},
|
||||
{file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9f463abafdc92635da4b38807f5b9972276be7c8c5121989768549fceb8d2588"},
|
||||
{file = "pydantic-1.10.18-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3445426da503c7e40baccefb2b2989a0c5ce6b163679dd75f55493b460f05a8f"},
|
||||
{file = "pydantic-1.10.18-cp311-cp311-win_amd64.whl", hash = "sha256:467a14ee2183bc9c902579bb2f04c3d3dac00eff52e252850509a562255b2a33"},
|
||||
{file = "pydantic-1.10.18-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:efbc8a7f9cb5fe26122acba1852d8dcd1e125e723727c59dcd244da7bdaa54f2"},
|
||||
{file = "pydantic-1.10.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:24a4a159d0f7a8e26bf6463b0d3d60871d6a52eac5bb6a07a7df85c806f4c048"},
|
||||
{file = "pydantic-1.10.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b74be007703547dc52e3c37344d130a7bfacca7df112a9e5ceeb840a9ce195c7"},
|
||||
{file = "pydantic-1.10.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcb20d4cb355195c75000a49bb4a31d75e4295200df620f454bbc6bdf60ca890"},
|
||||
{file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:46f379b8cb8a3585e3f61bf9ae7d606c70d133943f339d38b76e041ec234953f"},
|
||||
{file = "pydantic-1.10.18-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cbfbca662ed3729204090c4d09ee4beeecc1a7ecba5a159a94b5a4eb24e3759a"},
|
||||
{file = "pydantic-1.10.18-cp312-cp312-win_amd64.whl", hash = "sha256:c6d0a9f9eccaf7f438671a64acf654ef0d045466e63f9f68a579e2383b63f357"},
|
||||
{file = "pydantic-1.10.18-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d5492dbf953d7d849751917e3b2433fb26010d977aa7a0765c37425a4026ff1"},
|
||||
{file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe734914977eed33033b70bfc097e1baaffb589517863955430bf2e0846ac30f"},
|
||||
{file = "pydantic-1.10.18-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15fdbe568beaca9aacfccd5ceadfb5f1a235087a127e8af5e48df9d8a45ae85c"},
|
||||
{file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c3e742f62198c9eb9201781fbebe64533a3bbf6a76a91b8d438d62b813079dbc"},
|
||||
{file = "pydantic-1.10.18-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:19a3bd00b9dafc2cd7250d94d5b578edf7a0bd7daf102617153ff9a8fa37871c"},
|
||||
{file = "pydantic-1.10.18-cp37-cp37m-win_amd64.whl", hash = "sha256:2ce3fcf75b2bae99aa31bd4968de0474ebe8c8258a0110903478bd83dfee4e3b"},
|
||||
{file = "pydantic-1.10.18-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:335a32d72c51a313b33fa3a9b0fe283503272ef6467910338e123f90925f0f03"},
|
||||
{file = "pydantic-1.10.18-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:34a3613c7edb8c6fa578e58e9abe3c0f5e7430e0fc34a65a415a1683b9c32d9a"},
|
||||
{file = "pydantic-1.10.18-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ee4e6ca1d9616797fa2e9c0bfb8815912c7d67aca96f77428e316741082a1b"},
|
||||
{file = "pydantic-1.10.18-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23e8ec1ce4e57b4f441fc91e3c12adba023fedd06868445a5b5f1d48f0ab3682"},
|
||||
{file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:44ae8a3e35a54d2e8fa88ed65e1b08967a9ef8c320819a969bfa09ce5528fafe"},
|
||||
{file = "pydantic-1.10.18-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5389eb3b48a72da28c6e061a247ab224381435256eb541e175798483368fdd3"},
|
||||
{file = "pydantic-1.10.18-cp38-cp38-win_amd64.whl", hash = "sha256:069b9c9fc645474d5ea3653788b544a9e0ccd3dca3ad8c900c4c6eac844b4620"},
|
||||
{file = "pydantic-1.10.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80b982d42515632eb51f60fa1d217dfe0729f008e81a82d1544cc392e0a50ddf"},
|
||||
{file = "pydantic-1.10.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aad8771ec8dbf9139b01b56f66386537c6fe4e76c8f7a47c10261b69ad25c2c9"},
|
||||
{file = "pydantic-1.10.18-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941a2eb0a1509bd7f31e355912eb33b698eb0051730b2eaf9e70e2e1589cae1d"},
|
||||
{file = "pydantic-1.10.18-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65f7361a09b07915a98efd17fdec23103307a54db2000bb92095457ca758d485"},
|
||||
{file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6951f3f47cb5ca4da536ab161ac0163cab31417d20c54c6de5ddcab8bc813c3f"},
|
||||
{file = "pydantic-1.10.18-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7a4c5eec138a9b52c67f664c7d51d4c7234c5ad65dd8aacd919fb47445a62c86"},
|
||||
{file = "pydantic-1.10.18-cp39-cp39-win_amd64.whl", hash = "sha256:49e26c51ca854286bffc22b69787a8d4063a62bf7d83dc21d44d2ff426108518"},
|
||||
{file = "pydantic-1.10.18-py3-none-any.whl", hash = "sha256:06a189b81ffc52746ec9c8c007f16e5167c8b0a696e1a726369327e3db7b2a82"},
|
||||
{file = "pydantic-1.10.18.tar.gz", hash = "sha256:baebdff1907d1d96a139c25136a9bb7d17e118f133a76a2ef3b845e831e3403a"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"},
|
||||
{file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"},
|
||||
{file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"},
|
||||
{file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"},
|
||||
{file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"},
|
||||
{file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"},
|
||||
{file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"},
|
||||
{file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"},
|
||||
{file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -2073,13 +2053,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "pyln-client"
|
||||
version = "24.8.1"
|
||||
version = "24.5"
|
||||
description = "Client library and plugin library for Core Lightning"
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.8"
|
||||
files = [
|
||||
{file = "pyln_client-24.8.1-py3-none-any.whl", hash = "sha256:4a389de96813a23b587007f181a5d4ba37bb8a4ac6bed7074a591b6b710e4615"},
|
||||
{file = "pyln_client-24.8.1.tar.gz", hash = "sha256:47e1bcadc91df511b7dbd66059d25a6c67fb0d49953291762272abf151fe8846"},
|
||||
{file = "pyln_client-24.5-py3-none-any.whl", hash = "sha256:b1c7fc8644c0668472ba9cc5d45b6fe88f44bae396f624f0b1a09695011fce0d"},
|
||||
{file = "pyln_client-24.5.tar.gz", hash = "sha256:642af007f4b0ea75f7c1771b7a4563acf858e0e761023d84b7f61fef13cf3888"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -2088,20 +2068,20 @@ pyln-proto = ">=23"
|
||||
|
||||
[[package]]
|
||||
name = "pyln-proto"
|
||||
version = "24.8"
|
||||
version = "24.5"
|
||||
description = "This package implements some of the Lightning Network protocol in pure python. It is intended for protocol testing and some minor tooling only. It is not deemed secure enough to handle any amount of real funds (you have been warned!)."
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.8"
|
||||
files = [
|
||||
{file = "pyln_proto-24.8-py3-none-any.whl", hash = "sha256:7e4076b01b7c6c580e21f74c5be0d425ca014120db3151527c5d9cc600953944"},
|
||||
{file = "pyln_proto-24.8.tar.gz", hash = "sha256:90bfc72198fe3deccb834538f0c73153ed650280e9c2a2a2c55ad9b4f4c256cc"},
|
||||
{file = "pyln_proto-24.5-py3-none-any.whl", hash = "sha256:78b9982412cfea8172dfafe217001bdf3d6ee8d585f138b8868925e47a8c54b2"},
|
||||
{file = "pyln_proto-24.5.tar.gz", hash = "sha256:b6e7a0cd5bd3905d743ec2c3ef93233271062e0abf0b7647a449ff71c0f20074"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
base58 = ">=2.1.1,<3.0.0"
|
||||
bitstring = ">=4.1.0,<5.0.0"
|
||||
coincurve = ">=20,<21"
|
||||
cryptography = ">=42,<43"
|
||||
coincurve = ">=18,<19"
|
||||
cryptography = ">=41,<42"
|
||||
PySocks = ">=1,<2"
|
||||
|
||||
[[package]]
|
||||
@@ -2510,29 +2490,29 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.6.4"
|
||||
version = "0.5.7"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.6.4-py3-none-linux_armv6l.whl", hash = "sha256:c4b153fc152af51855458e79e835fb6b933032921756cec9af7d0ba2aa01a258"},
|
||||
{file = "ruff-0.6.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:bedff9e4f004dad5f7f76a9d39c4ca98af526c9b1695068198b3bda8c085ef60"},
|
||||
{file = "ruff-0.6.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d02a4127a86de23002e694d7ff19f905c51e338c72d8e09b56bfb60e1681724f"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7862f42fc1a4aca1ea3ffe8a11f67819d183a5693b228f0bb3a531f5e40336fc"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eebe4ff1967c838a1a9618a5a59a3b0a00406f8d7eefee97c70411fefc353617"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:932063a03bac394866683e15710c25b8690ccdca1cf192b9a98260332ca93408"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:50e30b437cebef547bd5c3edf9ce81343e5dd7c737cb36ccb4fe83573f3d392e"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c44536df7b93a587de690e124b89bd47306fddd59398a0fb12afd6133c7b3818"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ea086601b22dc5e7693a78f3fcfc460cceabfdf3bdc36dc898792aba48fbad6"},
|
||||
{file = "ruff-0.6.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b52387d3289ccd227b62102c24714ed75fbba0b16ecc69a923a37e3b5e0aaaa"},
|
||||
{file = "ruff-0.6.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0308610470fcc82969082fc83c76c0d362f562e2f0cdab0586516f03a4e06ec6"},
|
||||
{file = "ruff-0.6.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:803b96dea21795a6c9d5bfa9e96127cc9c31a1987802ca68f35e5c95aed3fc0d"},
|
||||
{file = "ruff-0.6.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:66dbfea86b663baab8fcae56c59f190caba9398df1488164e2df53e216248baa"},
|
||||
{file = "ruff-0.6.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:34d5efad480193c046c86608dbba2bccdc1c5fd11950fb271f8086e0c763a5d1"},
|
||||
{file = "ruff-0.6.4-py3-none-win32.whl", hash = "sha256:f0f8968feea5ce3777c0d8365653d5e91c40c31a81d95824ba61d871a11b8523"},
|
||||
{file = "ruff-0.6.4-py3-none-win_amd64.whl", hash = "sha256:549daccee5227282289390b0222d0fbee0275d1db6d514550d65420053021a58"},
|
||||
{file = "ruff-0.6.4-py3-none-win_arm64.whl", hash = "sha256:ac4b75e898ed189b3708c9ab3fc70b79a433219e1e87193b4f2b77251d058d14"},
|
||||
{file = "ruff-0.6.4.tar.gz", hash = "sha256:ac3b5bfbee99973f80aa1b7cbd1c9cbce200883bdd067300c22a6cc1c7fba212"},
|
||||
{file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"},
|
||||
{file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"},
|
||||
{file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"},
|
||||
{file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"},
|
||||
{file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"},
|
||||
{file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"},
|
||||
{file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"},
|
||||
{file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"},
|
||||
{file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"},
|
||||
{file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"},
|
||||
{file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"},
|
||||
{file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"},
|
||||
{file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"},
|
||||
{file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"},
|
||||
{file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"},
|
||||
{file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"},
|
||||
{file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"},
|
||||
{file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2637,54 +2617,55 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlalchemy"
|
||||
version = "1.4.54"
|
||||
version = "1.4.53"
|
||||
description = "Database Abstraction Library"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
|
||||
files = [
|
||||
{file = "SQLAlchemy-1.4.54-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:af00236fe21c4d4f4c227b6ccc19b44c594160cc3ff28d104cdce85855369277"},
|
||||
{file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1183599e25fa38a1a322294b949da02b4f0da13dbc2688ef9dbe746df573f8a6"},
|
||||
{file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1990d5a6a5dc358a0894c8ca02043fb9a5ad9538422001fb2826e91c50f1d539"},
|
||||
{file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:14b3f4783275339170984cadda66e3ec011cce87b405968dc8d51cf0f9997b0d"},
|
||||
{file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b24364150738ce488333b3fb48bfa14c189a66de41cd632796fbcacb26b4585"},
|
||||
{file = "SQLAlchemy-1.4.54-cp310-cp310-win32.whl", hash = "sha256:a8a72259a1652f192c68377be7011eac3c463e9892ef2948828c7d58e4829988"},
|
||||
{file = "SQLAlchemy-1.4.54-cp310-cp310-win_amd64.whl", hash = "sha256:b67589f7955924865344e6eacfdcf70675e64f36800a576aa5e961f0008cde2a"},
|
||||
{file = "SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13e91d6892b5fcb94a36ba061fb7a1f03d0185ed9d8a77c84ba389e5bb05e936"},
|
||||
{file = "SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb59a11689ff3c58e7652260127f9e34f7f45478a2f3ef831ab6db7bcd72108f"},
|
||||
{file = "SQLAlchemy-1.4.54-cp311-cp311-win32.whl", hash = "sha256:1390ca2d301a2708fd4425c6d75528d22f26b8f5cbc9faba1ddca136671432bc"},
|
||||
{file = "SQLAlchemy-1.4.54-cp311-cp311-win_amd64.whl", hash = "sha256:2b37931eac4b837c45e2522066bda221ac6d80e78922fb77c75eb12e4dbcdee5"},
|
||||
{file = "SQLAlchemy-1.4.54-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3f01c2629a7d6b30d8afe0326b8c649b74825a0e1ebdcb01e8ffd1c920deb07d"},
|
||||
{file = "SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c24dd161c06992ed16c5e528a75878edbaeced5660c3db88c820f1f0d3fe1f4"},
|
||||
{file = "SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5e0d47d619c739bdc636bbe007da4519fc953393304a5943e0b5aec96c9877c"},
|
||||
{file = "SQLAlchemy-1.4.54-cp312-cp312-win32.whl", hash = "sha256:12bc0141b245918b80d9d17eca94663dbd3f5266ac77a0be60750f36102bbb0f"},
|
||||
{file = "SQLAlchemy-1.4.54-cp312-cp312-win_amd64.whl", hash = "sha256:f941aaf15f47f316123e1933f9ea91a6efda73a161a6ab6046d1cde37be62c88"},
|
||||
{file = "SQLAlchemy-1.4.54-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:a41611835010ed4ea4c7aed1da5b58aac78ee7e70932a91ed2705a7b38e40f52"},
|
||||
{file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e8c1b9ecaf9f2590337d5622189aeb2f0dbc54ba0232fa0856cf390957584a9"},
|
||||
{file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de620f978ca273ce027769dc8db7e6ee72631796187adc8471b3c76091b809e"},
|
||||
{file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5a2530400a6e7e68fd1552a55515de6a4559122e495f73554a51cedafc11669"},
|
||||
{file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cf7076c8578b3de4e43a046cc7a1af8466e1c3f5e64167189fe8958a4f9c02"},
|
||||
{file = "SQLAlchemy-1.4.54-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:f1e1b92ee4ee9ffc68624ace218b89ca5ca667607ccee4541a90cc44999b9aea"},
|
||||
{file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41cffc63c7c83dfc30c4cab5b4308ba74440a9633c4509c51a0c52431fb0f8ab"},
|
||||
{file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5933c45d11cbd9694b1540aa9076816cc7406964c7b16a380fd84d3a5fe3241"},
|
||||
{file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cafe0ba3a96d0845121433cffa2b9232844a2609fce694fcc02f3f31214ece28"},
|
||||
{file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a19f816f4702d7b1951d7576026c7124b9bfb64a9543e571774cf517b7a50b29"},
|
||||
{file = "SQLAlchemy-1.4.54-cp37-cp37m-win32.whl", hash = "sha256:76c2ba7b5a09863d0a8166fbc753af96d561818c572dbaf697c52095938e7be4"},
|
||||
{file = "SQLAlchemy-1.4.54-cp37-cp37m-win_amd64.whl", hash = "sha256:a86b0e4be775902a5496af4fb1b60d8a2a457d78f531458d294360b8637bb014"},
|
||||
{file = "SQLAlchemy-1.4.54-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:a49730afb716f3f675755afec109895cab95bc9875db7ffe2e42c1b1c6279482"},
|
||||
{file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26e78444bc77d089e62874dc74df05a5c71f01ac598010a327881a48408d0064"},
|
||||
{file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02d2ecb9508f16ab9c5af466dfe5a88e26adf2e1a8d1c56eb616396ccae2c186"},
|
||||
{file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:394b0135900b62dbf63e4809cdc8ac923182af2816d06ea61cd6763943c2cc05"},
|
||||
{file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed3576675c187e3baa80b02c4c9d0edfab78eff4e89dd9da736b921333a2432"},
|
||||
{file = "SQLAlchemy-1.4.54-cp38-cp38-win32.whl", hash = "sha256:fc9ffd9a38e21fad3e8c5a88926d57f94a32546e937e0be46142b2702003eba7"},
|
||||
{file = "SQLAlchemy-1.4.54-cp38-cp38-win_amd64.whl", hash = "sha256:a01bc25eb7a5688656c8770f931d5cb4a44c7de1b3cec69b84cc9745d1e4cc10"},
|
||||
{file = "SQLAlchemy-1.4.54-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:0b76bbb1cbae618d10679be8966f6d66c94f301cfc15cb49e2f2382563fb6efb"},
|
||||
{file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdb2886c0be2c6c54d0651d5a61c29ef347e8eec81fd83afebbf7b59b80b7393"},
|
||||
{file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:954816850777ac234a4e32b8c88ac1f7847088a6e90cfb8f0e127a1bf3feddff"},
|
||||
{file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1d83cd1cc03c22d922ec94d0d5f7b7c96b1332f5e122e81b1a61fb22da77879a"},
|
||||
{file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1576fba3616f79496e2f067262200dbf4aab1bb727cd7e4e006076686413c80c"},
|
||||
{file = "SQLAlchemy-1.4.54-cp39-cp39-win32.whl", hash = "sha256:3112de9e11ff1957148c6de1df2bc5cc1440ee36783412e5eedc6f53638a577d"},
|
||||
{file = "SQLAlchemy-1.4.54-cp39-cp39-win_amd64.whl", hash = "sha256:6da60fb24577f989535b8fc8b2ddc4212204aaf02e53c4c7ac94ac364150ed08"},
|
||||
{file = "sqlalchemy-1.4.54.tar.gz", hash = "sha256:4470fbed088c35dc20b78a39aaf4ae54fe81790c783b3264872a0224f437c31a"},
|
||||
{file = "SQLAlchemy-1.4.53-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:b61ac5457d91b5629a3dea2b258deb4cdd35ac8f6fa2031d2b9b2fff5b3396da"},
|
||||
{file = "SQLAlchemy-1.4.53-cp310-cp310-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a96aa8d425047551676b0e178ddb0683421e78eda879ab55775128b2e612cae"},
|
||||
{file = "SQLAlchemy-1.4.53-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e10ac36f0b994235c13388b39598bf27219ec8bdea5be99bdac612b01cbe525"},
|
||||
{file = "SQLAlchemy-1.4.53-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:437592b341a3229dd0443c9c803b0bf0a466f8f539014fef6cdb9c06b7edb7f9"},
|
||||
{file = "SQLAlchemy-1.4.53-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:784272ceb5eb71421fea9568749bcbe8bd019261a0e2e710a7efa76057af2499"},
|
||||
{file = "SQLAlchemy-1.4.53-cp310-cp310-win32.whl", hash = "sha256:122d7b5722df1a24402c6748bbb04687ef981493bb559d0cc0beffe722e0e6ed"},
|
||||
{file = "SQLAlchemy-1.4.53-cp310-cp310-win_amd64.whl", hash = "sha256:4604d42b2abccba266d3f5bbe883684b5df93e74054024c70d3fbb5eea45e530"},
|
||||
{file = "SQLAlchemy-1.4.53-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fb8e15dfa47f5de11ab073e12aadd6b502cfb7ac4bafd18bd18cfd1c7d13dbbc"},
|
||||
{file = "SQLAlchemy-1.4.53-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8be4df55e8fde3006d9cb1f6b3df2ba26db613855dc4df2c0fcd5ec15cb3b7"},
|
||||
{file = "SQLAlchemy-1.4.53-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86b11640251f9a9789fd96cd6e5d176b1c230230c70ad40299bcbcc568451b4c"},
|
||||
{file = "SQLAlchemy-1.4.53-cp311-cp311-win32.whl", hash = "sha256:cd534c716f86bdf95b7b984a34ee278c91d1b1d7d183e7e5ff878600b1696046"},
|
||||
{file = "SQLAlchemy-1.4.53-cp311-cp311-win_amd64.whl", hash = "sha256:6dd06572872ca13ef5a90306a3e5af787498ddaa17fb00109b1243642646cd69"},
|
||||
{file = "SQLAlchemy-1.4.53-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:2774c24c405136c3ef472e2352bdca7330659d481fbf2283f996c0ef9eb90f22"},
|
||||
{file = "SQLAlchemy-1.4.53-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68a614765197b3d13a730d631a78c3bb9b3b72ba58ed7ab295d58d517464e315"},
|
||||
{file = "SQLAlchemy-1.4.53-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d13d4dfbc6e52363886b47cf02cf68c5d2a37c468626694dc210d7e97d4ad330"},
|
||||
{file = "SQLAlchemy-1.4.53-cp312-cp312-win32.whl", hash = "sha256:197065b91456574d70b6459bfa62bc0b52a4960a29ef923c375ec427274a3e05"},
|
||||
{file = "SQLAlchemy-1.4.53-cp312-cp312-win_amd64.whl", hash = "sha256:421306c4b936b0271a3ce2dc074928d5ece4a36f9c482daa5770f44ecfc3a883"},
|
||||
{file = "SQLAlchemy-1.4.53-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:13fc34b35d8ddb3fbe3f8fcfdf6c2546e676187f0fb20f5774da362ddaf8fa2d"},
|
||||
{file = "SQLAlchemy-1.4.53-cp36-cp36m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626be971ff89541cfd3e70b54be00b57a7f8557204decb6223ce0428fec058f3"},
|
||||
{file = "SQLAlchemy-1.4.53-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:991e42fdfec561ebc6a4fae7161a86d129d6069fa14210b96b8dd752afa7059c"},
|
||||
{file = "SQLAlchemy-1.4.53-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:95123f3a1e0e8020848fd32ba751db889a01a44e4e4fef7e58c87ddd0b2fca59"},
|
||||
{file = "SQLAlchemy-1.4.53-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c58e011e9e6373b3a091d83f20601fb335a3b4bace80bfcb914ac168aad3b70d"},
|
||||
{file = "SQLAlchemy-1.4.53-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:670c7769bf5dcae9aff331247b5d82fe635c63731088a46ce68ba2ba519ef36e"},
|
||||
{file = "SQLAlchemy-1.4.53-cp37-cp37m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07ba54f09033d387ae9df8d62cbe211ed7304e0bfbece1f8c55e21db9fae5c11"},
|
||||
{file = "SQLAlchemy-1.4.53-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a38834b4c183c33daf58544281395aad2e985f0b47cca1e88ea5ada88344e63"},
|
||||
{file = "SQLAlchemy-1.4.53-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:616492f5315128a847f293a7c552f3561ac7e996d2aa5dc46bef4fb0d3781f1d"},
|
||||
{file = "SQLAlchemy-1.4.53-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0cf8c0af9563892c6632f7343bc393dfce6eeef8e4d10c5fadba9c0390520bd"},
|
||||
{file = "SQLAlchemy-1.4.53-cp37-cp37m-win32.whl", hash = "sha256:c05fe05941424c2f3747a8952381b7725e24cba2ca00141380e54789d5b616b6"},
|
||||
{file = "SQLAlchemy-1.4.53-cp37-cp37m-win_amd64.whl", hash = "sha256:93e90aa3e3b2f8e8cbae4d5509f8e0cf82972378d323c740a8df1c1e9f484172"},
|
||||
{file = "SQLAlchemy-1.4.53-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:9d7368df54d3ed45a18955f6cec38ebe075290594ac0d5c87a8ddaff7e10de27"},
|
||||
{file = "SQLAlchemy-1.4.53-cp38-cp38-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89d8ac4158ef68eea8bb0f6dd0583127d9aa8720606964ba8eee20b254f9c83a"},
|
||||
{file = "SQLAlchemy-1.4.53-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16bb9fa4d00b4581b14d9f0e2224dc7745b854aa4687738279af0f48f7056c98"},
|
||||
{file = "SQLAlchemy-1.4.53-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4fe5168d0249c23f537950b6d75935ff2709365a113e29938a979aec36668ecf"},
|
||||
{file = "SQLAlchemy-1.4.53-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b8608d162d3bd29d807aab32c3fb6e2f8e225a43d1c54c917fed38513785380"},
|
||||
{file = "SQLAlchemy-1.4.53-cp38-cp38-win32.whl", hash = "sha256:a9d4d132198844bd6828047135ce7b887687c92925049a2468a605fc775c7a1a"},
|
||||
{file = "SQLAlchemy-1.4.53-cp38-cp38-win_amd64.whl", hash = "sha256:c15d1f1fcf1f9bec0499ae1d9132b950fcc7730f2d26d10484c8808b4e077816"},
|
||||
{file = "SQLAlchemy-1.4.53-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:edf094a20a386ff2ec73de65ef18014b250259cb860edc61741e240ca22d6981"},
|
||||
{file = "SQLAlchemy-1.4.53-cp39-cp39-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83a9c3514ff19d9d30d8a8d378b24cd1dfa5528d20891481cb5f196117db6a48"},
|
||||
{file = "SQLAlchemy-1.4.53-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaaeedbceb4dfd688fff2faf25a9a87a391f548811494f7bff7fa701b639abc3"},
|
||||
{file = "SQLAlchemy-1.4.53-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d021699b9007deb7aa715629078830c99a5fec2753d9bdd5ff33290d363ef755"},
|
||||
{file = "SQLAlchemy-1.4.53-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0465b8a68f8f4de754c1966c45b187ac784ad97bc9747736f913130f0e1adea0"},
|
||||
{file = "SQLAlchemy-1.4.53-cp39-cp39-win32.whl", hash = "sha256:5f67b9e9dcac3241781e96575468d55a42332157dee04bdbf781df573dff5f85"},
|
||||
{file = "SQLAlchemy-1.4.53-cp39-cp39-win_amd64.whl", hash = "sha256:a8c2f2a0b2c4e3b86eb58c9b6bb98548205eea2fba9dae4edfd29dc6aebbe95a"},
|
||||
{file = "SQLAlchemy-1.4.53.tar.gz", hash = "sha256:5e6ab710c4c064755fd92d1a417bef360228a19bdf0eee32b03aa0f5f8e9fe0d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -2840,13 +2821,13 @@ zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.30.6"
|
||||
version = "0.30.5"
|
||||
description = "The lightning-fast ASGI server."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "uvicorn-0.30.6-py3-none-any.whl", hash = "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5"},
|
||||
{file = "uvicorn-0.30.6.tar.gz", hash = "sha256:4b15decdda1e72be08209e860a1e10e92439ad5b97cf44cc945fcbee66fc5788"},
|
||||
{file = "uvicorn-0.30.5-py3-none-any.whl", hash = "sha256:b2d86de274726e9878188fa07576c9ceeff90a839e2b6e25c917fe05f5a6c835"},
|
||||
{file = "uvicorn-0.30.5.tar.gz", hash = "sha256:ac6fdbd4425c5fd17a9fe39daf4d4d075da6fdc80f653e5894cdc2fd98752bee"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -3193,4 +3174,4 @@ liquid = ["wallycore"]
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12 | ^3.11 | ^3.10 | ^3.9"
|
||||
content-hash = "f9f70d510dbe30a94f68fc12fcf1d11c6fb754367e9f36e6167be2ca19e28495"
|
||||
content-hash = "f207ace63f63160eaab19e8cf98069320edb8c8d8dd56078b013871ff1f76076"
|
||||
|
||||
+11
-11
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "lnbits"
|
||||
version = "1.0.0-rc2"
|
||||
version = "1.0.0-rc1"
|
||||
description = "LNbits, free and open-source Lightning wallet and accounts system."
|
||||
authors = ["Alan Bits <alan@lnbits.com>"]
|
||||
readme = "README.md"
|
||||
@@ -16,25 +16,25 @@ python = "^3.12 | ^3.11 | ^3.10 | ^3.9"
|
||||
bech32 = "1.2.0"
|
||||
click = "8.1.7"
|
||||
ecdsa = "0.19.0"
|
||||
fastapi = "0.113.0"
|
||||
fastapi = "0.112.0"
|
||||
httpx = "0.27.0"
|
||||
jinja2 = "3.1.4"
|
||||
lnurl = "0.5.3"
|
||||
pydantic = "1.10.18"
|
||||
pydantic = "1.10.17"
|
||||
pyqrcode = "1.2.1"
|
||||
shortuuid = "1.0.13"
|
||||
sse-starlette = "1.8.2"
|
||||
typing-extensions = "4.12.2"
|
||||
uvicorn = "0.30.6"
|
||||
sqlalchemy = "1.4.54"
|
||||
uvicorn = "0.30.5"
|
||||
sqlalchemy = "1.4.53"
|
||||
aiosqlite = "0.20.0"
|
||||
asyncpg = "0.29.0"
|
||||
uvloop = "0.19.0"
|
||||
websockets = "11.0.3"
|
||||
loguru = "0.7.2"
|
||||
grpcio = "1.66.1"
|
||||
protobuf = "5.28.0"
|
||||
pyln-client = "24.8.1"
|
||||
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"
|
||||
@@ -70,11 +70,11 @@ black = "^24.8.0"
|
||||
pytest-asyncio = "^0.21.2"
|
||||
pytest = "^8.3.2"
|
||||
pytest-cov = "^4.1.0"
|
||||
mypy = "^1.11.2"
|
||||
mypy = "^1.11.1"
|
||||
types-protobuf = "^5.27.0.20240626"
|
||||
pre-commit = "^3.8.0"
|
||||
openapi-spec-validator = "^0.7.1"
|
||||
ruff = "^0.6.4"
|
||||
ruff = "^0.5.7"
|
||||
types-passlib = "^1.7.7.20240327"
|
||||
openai = "^1.39.0"
|
||||
json5 = "^0.9.25"
|
||||
@@ -84,7 +84,7 @@ pytest-httpserver = "^1.1.0"
|
||||
pytest-mock = "^3.14.0"
|
||||
types-mock = "^5.1.0.20240425"
|
||||
mock = "^5.1.0"
|
||||
grpcio-tools = "^1.66.1"
|
||||
grpcio-tools = "^1.65.5"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
import pytest
|
||||
|
||||
from lnbits.settings import RedirectPath
|
||||
|
||||
lnurlp_redirect_path = {
|
||||
"from_path": "/.well-known/lnurlp",
|
||||
"redirect_to_path": "/api/v1/well-known",
|
||||
}
|
||||
lnurlp_redirect_path_with_headers = {
|
||||
"from_path": "/.well-known/lnurlp",
|
||||
"redirect_to_path": "/api/v1/well-known",
|
||||
"header_filters": {"accept": "application/nostr+json"},
|
||||
}
|
||||
|
||||
lnaddress_redirect_path = {
|
||||
"from_path": "/.well-known/lnurlp",
|
||||
"redirect_to_path": "/api/v1/well-known",
|
||||
}
|
||||
|
||||
nostrrelay_redirect_path = {
|
||||
"from_path": "/",
|
||||
"redirect_to_path": "/api/v1/relay-info",
|
||||
"header_filters": {"accept": "application/nostr+json"},
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def lnurlp():
|
||||
return RedirectPath(ext_id="lnurlp", **lnurlp_redirect_path)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def lnurlp_with_headers():
|
||||
return RedirectPath(
|
||||
ext_id="lnurlp_with_headers", **lnurlp_redirect_path_with_headers
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def lnaddress():
|
||||
return RedirectPath(ext_id="lnaddress", **lnaddress_redirect_path)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def nostrrelay():
|
||||
return RedirectPath(ext_id="nostrrelay", **nostrrelay_redirect_path)
|
||||
|
||||
|
||||
def test_redirect_path_self_not_in_conflict(
|
||||
lnurlp: RedirectPath, lnaddress: RedirectPath, nostrrelay: RedirectPath
|
||||
):
|
||||
assert not lnurlp.in_conflict(lnurlp), "Path is not in conflict with itself."
|
||||
assert not lnaddress.in_conflict(lnaddress), "Path is not in conflict with itself."
|
||||
assert not nostrrelay.in_conflict(
|
||||
nostrrelay
|
||||
), "Path is not in conflict with itself."
|
||||
|
||||
assert not lnurlp.in_conflict(nostrrelay)
|
||||
|
||||
assert not nostrrelay.in_conflict(lnurlp)
|
||||
|
||||
|
||||
def test_redirect_path_not_in_conflict(
|
||||
lnurlp: RedirectPath, lnaddress: RedirectPath, nostrrelay: RedirectPath
|
||||
):
|
||||
|
||||
assert not lnurlp.in_conflict(nostrrelay)
|
||||
|
||||
assert not nostrrelay.in_conflict(lnurlp)
|
||||
|
||||
assert not lnaddress.in_conflict(nostrrelay)
|
||||
|
||||
assert not nostrrelay.in_conflict(lnaddress)
|
||||
|
||||
|
||||
def test_redirect_path_in_conflict(lnurlp: RedirectPath, lnaddress: RedirectPath):
|
||||
assert lnurlp.in_conflict(lnaddress)
|
||||
assert lnaddress.in_conflict(lnurlp)
|
||||
|
||||
|
||||
def test_redirect_path_find_conflict(
|
||||
lnurlp: RedirectPath, lnaddress: RedirectPath, nostrrelay: RedirectPath
|
||||
):
|
||||
assert lnurlp.find_in_conflict([nostrrelay, lnaddress])
|
||||
assert lnurlp.find_in_conflict([lnaddress, nostrrelay])
|
||||
assert lnaddress.find_in_conflict([nostrrelay, lnurlp])
|
||||
assert lnaddress.find_in_conflict([lnurlp, nostrrelay])
|
||||
|
||||
|
||||
def test_redirect_path_find_no_conflict(
|
||||
lnurlp: RedirectPath, lnaddress: RedirectPath, nostrrelay: RedirectPath
|
||||
):
|
||||
assert not nostrrelay.find_in_conflict([lnurlp, lnaddress])
|
||||
assert not lnurlp.find_in_conflict([nostrrelay])
|
||||
assert not lnaddress.find_in_conflict([nostrrelay])
|
||||
|
||||
|
||||
def test_redirect_path_in_conflict_with_headers(
|
||||
lnurlp: RedirectPath, lnurlp_with_headers: RedirectPath
|
||||
):
|
||||
assert lnurlp.in_conflict(lnurlp_with_headers)
|
||||
assert lnurlp_with_headers.in_conflict(lnurlp)
|
||||
|
||||
|
||||
def test_redirect_path_matches_with_headers(
|
||||
lnurlp: RedirectPath, lnurlp_with_headers: RedirectPath
|
||||
):
|
||||
headers_list = list(lnurlp_with_headers.header_filters.items())
|
||||
assert lnurlp.redirect_matches(
|
||||
path=lnurlp_with_headers.from_path,
|
||||
req_headers=headers_list,
|
||||
)
|
||||
assert lnurlp_with_headers.redirect_matches(
|
||||
path=lnurlp_redirect_path["from_path"],
|
||||
req_headers=[("ACCEPT", "APPlication/nostr+json")],
|
||||
)
|
||||
assert lnurlp_with_headers.redirect_matches(
|
||||
path=lnurlp_redirect_path["from_path"],
|
||||
req_headers=[("accept", "application/nostr+json"), ("my_header", "my_value")],
|
||||
)
|
||||
|
||||
assert not lnurlp_with_headers.redirect_matches(
|
||||
path=lnurlp_redirect_path["from_path"], req_headers=[]
|
||||
)
|
||||
assert not lnurlp_with_headers.redirect_matches(
|
||||
path=lnurlp_redirect_path["from_path"],
|
||||
req_headers=[("accept", "application/json")],
|
||||
)
|
||||
assert not lnurlp_with_headers.redirect_matches(path="/random/path", req_headers=[])
|
||||
assert not lnurlp_with_headers.redirect_matches(path="/random_path", req_headers=[])
|
||||
assert not lnurlp_with_headers.redirect_matches(
|
||||
path="/.well-known/lnurlp", req_headers=[]
|
||||
)
|
||||
assert lnurlp.redirect_matches(path="/.well-known/lnurlp", req_headers=[])
|
||||
assert lnurlp.redirect_matches(
|
||||
path="/.well-known/lnurlp/some/other/path", req_headers=[]
|
||||
)
|
||||
assert lnurlp.redirect_matches(
|
||||
path="/.well-known/lnurlp/some/other/path",
|
||||
req_headers=headers_list,
|
||||
)
|
||||
assert not lnurlp_with_headers.redirect_matches(
|
||||
path="/.well-known/lnurlp", req_headers=[]
|
||||
)
|
||||
assert not lnurlp_with_headers.redirect_matches(
|
||||
path="/.well-known/lnurlp/some/other/path", req_headers=[]
|
||||
)
|
||||
assert lnurlp_with_headers.redirect_matches(
|
||||
path="/.well-known/lnurlp/some/other/path",
|
||||
req_headers=headers_list,
|
||||
)
|
||||
|
||||
|
||||
def test_redirect_path_new_path_from(lnurlp: RedirectPath):
|
||||
assert lnurlp.new_path_from("") == "/lnurlp/api/v1/well-known"
|
||||
assert lnurlp.new_path_from("/") == "/lnurlp/api/v1/well-known"
|
||||
assert lnurlp.new_path_from("/path") == "/lnurlp/api/v1/well-known"
|
||||
assert lnurlp.new_path_from("/path/more") == "/lnurlp/api/v1/well-known"
|
||||
|
||||
assert lnurlp.new_path_from("/.well-known/lnurlp") == "/lnurlp/api/v1/well-known"
|
||||
assert (
|
||||
lnurlp.new_path_from("/.well-known/lnurlp/path")
|
||||
== "/lnurlp/api/v1/well-known/path"
|
||||
)
|
||||
assert (
|
||||
lnurlp.new_path_from("/.well-known/lnurlp/path/more")
|
||||
== "/lnurlp/api/v1/well-known/path/more"
|
||||
)
|
||||
Reference in New Issue
Block a user