diff --git a/.env.example b/.env.example
index 3e7ca311..daad78fd 100644
--- a/.env.example
+++ b/.env.example
@@ -17,7 +17,7 @@ TOR=TRUE
# NOSTR
# nostr private key to which to receive tokens to
-NOSTR_PRIVATE_KEY=nostr_privatekey_here_hex_or_bech32_nsec
+# NOSTR_PRIVATE_KEY=nostr_privatekey_here_hex_or_bech32_nsec
# nostr relays (comma separated list)
NOSTR_RELAYS=["wss://nostr-pub.wellorder.net"]
@@ -38,7 +38,6 @@ MINT_INFO_CONTACT=[["email","contact@me.com"], ["twitter","@me"], ["nostr", "np
MINT_INFO_MOTD="Message to users"
MINT_PRIVATE_KEY=supersecretprivatekey
-MINT_DATABASE=data/mint
# increment derivation path to rotate to a new keyset
MINT_DERIVATION_PATH="0/0/0/0"
diff --git a/.flake8 b/.flake8
deleted file mode 100644
index c64e6e91..00000000
--- a/.flake8
+++ /dev/null
@@ -1,8 +0,0 @@
-[flake8]
-max-line-length = 150
-exclude = cashu/nostr, cashu/core/bolt11.py
-ignore =
- # E203 whitespace before ':' black does not like it
- E203,
- # W503: line break before binary operator
- W503,
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index 8ba2d5c4..e001f35e 100644
--- a/.github/workflows/checks.yml
+++ b/.github/workflows/checks.yml
@@ -24,9 +24,7 @@ jobs:
run: poetry install
- name: Check black
run: make black-check
- - name: Check isort
- run: make isort-check
- linting:
+ mypy:
runs-on: ubuntu-latest
strategy:
matrix:
@@ -49,5 +47,8 @@ jobs:
run: yes | poetry run mypy cashu --install-types || true
- name: Run mypy
run: poetry run mypy cashu --ignore-missing
- - name: Run flake8
- run: poetry run flake8
+ ruff:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: chartboost/ruff-action@v1
diff --git a/.gitignore b/.gitignore
index c8945098..21e0d774 100644
--- a/.gitignore
+++ b/.gitignore
@@ -133,6 +133,7 @@ tor.pid
# Default data directory
/data
+/test_data
# MacOS
.DS_Store
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 8bba7a27..22f30900 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,5 +1,4 @@
exclude: '^cashu/nostr/.*'
-
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
@@ -14,16 +13,11 @@ repos:
- id: mixed-line-ending
- id: check-case-conflict
- repo: https://github.com/psf/black
- rev: 22.6.0
+ rev: 23.7.0
hooks:
- id: black
- - repo: https://github.com/pycqa/isort
- rev: 5.12.0
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.0.283
hooks:
- - id: isort
- args: ['--profile', 'black']
- - repo: https://github.com/pycqa/flake8
- rev: 6.0.0
- hooks:
- - id: flake8
- entry: poetry run flake8
+ - id: ruff
+ args: [ --fix, --exit-non-zero-on-fix ]
diff --git a/Makefile b/Makefile
index cc809a1d..8ca5fd9d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
-isort:
- poetry run isort --profile black . --skip cashu/nostr
+ruff:
+ poetry run ruff check . --fix
-isort-check:
- poetry run isort --profile black --check-only . --skip cashu/nostr
+ruff-check:
+ poetry run ruff check .
black:
poetry run black . --exclude cashu/nostr
@@ -13,12 +13,9 @@ black-check:
mypy:
poetry run mypy cashu tests --ignore-missing
-flake8:
- poetry run flake8 cashu tests
+format: black ruff
-format: isort black
-
-check: isort-check black-check flake8 mypy
+check: black-check ruff-check mypy
clean:
rm -r cashu.egg-info/ || true
@@ -32,8 +29,6 @@ package:
python setup.py sdist bdist_wheel
test:
- LIGHTNING=false \
- TOR=false \
poetry run pytest tests --cov-report xml --cov cashu
install:
diff --git a/cashu/core/base.py b/cashu/core/base.py
index 5d23ab55..85931e51 100644
--- a/cashu/core/base.py
+++ b/cashu/core/base.py
@@ -22,8 +22,8 @@ class SecretKind:
class SigFlags:
- SIG_INPUTS = (
- "SIG_INPUTS" # require signatures only on the inputs (default signature flag)
+ SIG_INPUTS = ( # require signatures only on the inputs (default signature flag)
+ "SIG_INPUTS"
)
SIG_ALL = "SIG_ALL" # require signatures on inputs and outputs
@@ -180,10 +180,8 @@ class Proof(BaseModel):
Value token
"""
- id: Union[
- None, str
- ] = "" # NOTE: None for backwards compatibility for old clients that do not include the keyset id < 0.3
-
+ # NOTE: None for backwards compatibility for old clients that do not include the keyset id < 0.3
+ id: Union[None, str] = ""
amount: int = 0
secret: str = "" # secret or message to be blinded and signed
C: str = "" # signature on secret, unblinded by wallet
@@ -191,12 +189,10 @@ class Proof(BaseModel):
p2pksigs: Union[List[str], None] = [] # P2PK signature
p2shscript: Union[P2SHScript, None] = None # P2SH spending condition
- reserved: Union[
- None, bool
- ] = False # whether this proof is reserved for sending, used for coin management in the wallet
- send_id: Union[
- None, str
- ] = "" # unique ID of send attempt, used for grouping pending tokens in the wallet
+ # whether this proof is reserved for sending, used for coin management in the wallet
+ reserved: Union[None, bool] = False
+ # unique ID of send attempt, used for grouping pending tokens in the wallet
+ send_id: Union[None, str] = ""
time_created: Union[None, str] = ""
time_reserved: Union[None, str] = ""
derivation_path: Union[None, str] = "" # derivation path of the proof
@@ -377,9 +373,9 @@ class CheckSpendableRequest(BaseModel):
class CheckSpendableResponse(BaseModel):
spendable: List[bool]
- pending: Optional[
- List[bool]
- ] = None # TODO: Uncomment when all mints are updated to 0.12.3 and support /check
+ pending: Optional[List[bool]] = (
+ None # TODO: Uncomment when all mints are updated to 0.12.3 and support /check
+ )
# with pending tokens (kept for backwards compatibility of new wallets with old mints)
@@ -460,9 +456,11 @@ def deserialize(serialized: str):
return cls(
id=row["id"],
- public_keys=deserialize(str(row["public_keys"]))
- if dict(row).get("public_keys")
- else {},
+ public_keys=(
+ deserialize(str(row["public_keys"]))
+ if dict(row).get("public_keys")
+ else {}
+ ),
mint_url=row["mint_url"],
valid_from=row["valid_from"],
valid_to=row["valid_to"],
@@ -528,7 +526,8 @@ def generate_keys(self, seed):
self.id = derive_keyset_id(self.public_keys) # type: ignore
if backwards_compatibility_pre_0_12:
logger.warning(
- f"WARNING: Using weak key derivation for keyset {self.id} (backwards compatibility < 0.12)"
+ f"WARNING: Using weak key derivation for keyset {self.id} (backwards"
+ " compatibility < 0.12)"
)
diff --git a/cashu/core/bolt11.py b/cashu/core/bolt11.py
index 962581d7..3c59fbb5 100644
--- a/cashu/core/bolt11.py
+++ b/cashu/core/bolt11.py
@@ -184,7 +184,6 @@ def lnencode(addr, privkey):
tags_set = set()
for k, v in addr.tags:
-
# BOLT #11:
#
# A writer MUST NOT include more than one `d`, `h`, `n` or `x` fields,
diff --git a/cashu/core/crypto/keys.py b/cashu/core/crypto/keys.py
index 9993a91b..fcf8c9f0 100644
--- a/cashu/core/crypto/keys.py
+++ b/cashu/core/crypto/keys.py
@@ -58,5 +58,5 @@ def derive_keyset_id(keys: Dict[int, PublicKey]):
def random_hash() -> str:
"""Returns a base64-urlsafe encoded random hash."""
return base64.urlsafe_b64encode(
- bytes([random.getrandbits(8) for i in range(32)])
+ bytes([random.getrandbits(8) for i in range(30)])
).decode()
diff --git a/cashu/core/db.py b/cashu/core/db.py
index 0af326a2..60873862 100644
--- a/cashu/core/db.py
+++ b/cashu/core/db.py
@@ -117,9 +117,9 @@ def _parse_timestamp(value, _):
psycopg2.extensions.new_type( # type: ignore
(1082, 1083, 1266),
"DATE2INT",
- lambda value, curs: time.mktime(value.timetuple())
- if value is not None
- else None,
+ lambda value, curs: (
+ time.mktime(value.timetuple()) if value is not None else None
+ ),
)
)
diff --git a/cashu/core/migrations.py b/cashu/core/migrations.py
index 37a697c3..ce3e2bfe 100644
--- a/cashu/core/migrations.py
+++ b/cashu/core/migrations.py
@@ -37,11 +37,13 @@ async def run_migration(db, migrations_module):
exists = None
if conn.type == SQLITE:
exists = await conn.fetchone(
- f"SELECT * FROM sqlite_master WHERE type='table' AND name='{table_with_schema(db, 'dbversions')}'"
+ "SELECT * FROM sqlite_master WHERE type='table' AND"
+ f" name='{table_with_schema(db, 'dbversions')}'"
)
elif conn.type in {POSTGRES, COCKROACH}:
exists = await conn.fetchone(
- f"SELECT * FROM information_schema.tables WHERE table_name = '{table_with_schema(db, 'dbversions')}'"
+ "SELECT * FROM information_schema.tables WHERE table_name ="
+ f" '{table_with_schema(db, 'dbversions')}'"
)
if not exists:
diff --git a/cashu/core/script.py b/cashu/core/script.py
index ff471d14..0fc2a8ea 100644
--- a/cashu/core/script.py
+++ b/cashu/core/script.py
@@ -134,7 +134,8 @@ def verify_bitcoin_script(txin_redeemScript_b64, txin_signature_b64):
txin_redeemScript_b64 = base64.urlsafe_b64encode(txin_redeemScript).decode()
txin_signature_b64 = base64.urlsafe_b64encode(txin_signature).decode()
print(
- f"Carol to Bob:\nscript: {txin_redeemScript.__repr__()}\nscript: {txin_redeemScript_b64}\nsignature: {txin_signature_b64}\n"
+ f"Carol to Bob:\nscript: {txin_redeemScript.__repr__()}\nscript:"
+ f" {txin_redeemScript_b64}\nsignature: {txin_signature_b64}\n"
)
print("")
# ---------
@@ -155,7 +156,8 @@ def verify_bitcoin_script(txin_redeemScript_b64, txin_signature_b64):
tx, _ = step1_bob_carol_create_tx(txin_p2sh_address)
print(
- f"Bob verifies:\nscript: {txin_redeemScript_b64}\nsignature: {txin_signature_b64}\n"
+ f"Bob verifies:\nscript: {txin_redeemScript_b64}\nsignature:"
+ f" {txin_signature_b64}\n"
)
script_valid = step3_bob_verify_script(txin_signature, txin_redeemScript, tx)
# MINT redeems tokens and stores P2SH:txin_p2sh_address
diff --git a/cashu/mint/app.py b/cashu/mint/app.py
index 3b4ef326..895945e8 100644
--- a/cashu/mint/app.py
+++ b/cashu/mint/app.py
@@ -3,6 +3,10 @@
from traceback import print_exception
from fastapi import FastAPI, status
+from fastapi.exception_handlers import (
+ request_validation_exception_handler as _request_validation_exception_handler,
+)
+from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
# from fastapi_profiler import PyInstrumentProfilerMiddleware
@@ -36,14 +40,19 @@ def configure_logger() -> None:
class Formatter:
def __init__(self):
self.padding = 0
- self.minimal_fmt: str = "{time:YYYY-MM-DD HH:mm:ss.SS} | {level} | {message}\n"
+ self.minimal_fmt = (
+ "{time:YYYY-MM-DD HH:mm:ss.SS} |"
+ " {level} | {message}\n"
+ )
if settings.debug:
- self.fmt: str = (
- "{time:YYYY-MM-DD HH:mm:ss.SS} | {level: <4} | {name}:"
- "{function}:{line} | {message}\n"
+ self.fmt = (
+ "{time:YYYY-MM-DD HH:mm:ss.SS} | {level:"
+ " <4} |"
+ " {name}:{function}:{line}"
+ " | {message}\n"
)
else:
- self.fmt: str = self.minimal_fmt
+ self.fmt = self.minimal_fmt
def format(self, record):
function = "{function}".format(**record)
@@ -109,6 +118,12 @@ def emit(self, record):
@app.middleware("http")
async def catch_exceptions(request: Request, call_next):
+ CORS_HEADERS = {
+ "Access-Control-Allow-Origin": "*",
+ "Access-Control-Allow-Methods": "*",
+ "Access-Control-Allow-Headers": "*",
+ "Access-Control-Allow-Credentials": "true",
+ }
try:
return await call_next(request)
except Exception as e:
@@ -119,22 +134,44 @@ async def catch_exceptions(request: Request, call_next):
if isinstance(e, CashuError):
logger.error(f"CashuError: {err_message}")
+ # return with cors headers
return JSONResponse(
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ status_code=status.HTTP_400_BAD_REQUEST,
content={"detail": err_message, "code": e.code},
+ headers=CORS_HEADERS,
)
logger.error(f"Exception: {err_message}")
if settings.debug:
print_exception(*sys.exc_info())
return JSONResponse(
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ status_code=status.HTTP_400_BAD_REQUEST,
content={"detail": err_message, "code": 0},
+ headers=CORS_HEADERS,
)
+async def request_validation_exception_handler(
+ request: Request, exc: RequestValidationError
+) -> JSONResponse:
+ """
+ This is a wrapper to the default RequestValidationException handler of FastAPI.
+ This function will be called when client input is not valid.
+ """
+ query_params = request.query_params._dict
+ detail = {
+ "errors": exc.errors(),
+ "query_params": query_params,
+ }
+ # log the error
+ logger.error(detail)
+ # pass on
+ return await _request_validation_exception_handler(request, exc)
+
+
@app.on_event("startup")
async def startup_mint():
await start_mint_init()
app.include_router(router=router)
+app.add_exception_handler(RequestValidationError, request_validation_exception_handler)
diff --git a/cashu/mint/crud.py b/cashu/mint/crud.py
index 004666a9..5759ccfc 100644
--- a/cashu/mint/crud.py
+++ b/cashu/mint/crud.py
@@ -95,11 +95,9 @@ async def get_proofs_used(
db: Database,
conn: Optional[Connection] = None,
):
- rows = await (conn or db).fetchall(
- f"""
+ rows = await (conn or db).fetchall(f"""
SELECT secret from {table_with_schema(db, 'proofs_used')}
- """
- )
+ """)
return [row[0] for row in rows]
@@ -128,11 +126,9 @@ async def get_proofs_pending(
db: Database,
conn: Optional[Connection] = None,
):
- rows = await (conn or db).fetchall(
- f"""
+ rows = await (conn or db).fetchall(f"""
SELECT * from {table_with_schema(db, 'proofs_pending')}
- """
- )
+ """)
return [Proof(**r) for r in rows]
diff --git a/cashu/mint/ledger.py b/cashu/mint/ledger.py
index 3519646c..9e42a2ea 100644
--- a/cashu/mint/ledger.py
+++ b/cashu/mint/ledger.py
@@ -283,9 +283,10 @@ def _verify_input_spending_conditions(self, proof: Proof) -> bool:
if not valid:
raise TransactionError("script invalid.")
# check if secret commits to script address
- assert secret.data == str(
- txin_p2sh_address
- ), f"secret does not contain correct P2SH address: {secret.data} is not {txin_p2sh_address}."
+ assert secret.data == str(txin_p2sh_address), (
+ f"secret does not contain correct P2SH address: {secret.data} is not"
+ f" {txin_p2sh_address}."
+ )
return True
# P2PK
@@ -317,9 +318,10 @@ def _verify_input_spending_conditions(self, proof: Proof) -> bool:
assert n_sigs_required > 0, "n_sigs must be positive."
# check if enough signatures are present
- assert (
- len(proof.p2pksigs) >= n_sigs_required
- ), f"not enough signatures provided: {len(proof.p2pksigs)} < {n_sigs_required}."
+ assert len(proof.p2pksigs) >= n_sigs_required, (
+ f"not enough signatures provided: {len(proof.p2pksigs)} <"
+ f" {n_sigs_required}."
+ )
n_valid_sigs_per_output = 0
# loop over all signatures in output
@@ -334,20 +336,24 @@ def _verify_input_spending_conditions(self, proof: Proof) -> bool:
):
n_valid_sigs_per_output += 1
logger.trace(
- f"p2pk signature on input is valid: {input_sig} on {pubkey}."
+ f"p2pk signature on input is valid: {input_sig} on"
+ f" {pubkey}."
)
continue
else:
logger.trace(
- f"p2pk signature on input is invalid: {input_sig} on {pubkey}."
+ f"p2pk signature on input is invalid: {input_sig} on"
+ f" {pubkey}."
)
# check if we have enough valid signatures
assert n_valid_sigs_per_output, "no valid signature provided for input."
- assert (
- n_valid_sigs_per_output >= n_sigs_required
- ), f"signature threshold not met. {n_valid_sigs_per_output} < {n_sigs_required}."
+ assert n_valid_sigs_per_output >= n_sigs_required, (
+ f"signature threshold not met. {n_valid_sigs_per_output} <"
+ f" {n_sigs_required}."
+ )
logger.trace(
- f"{n_valid_sigs_per_output} of {n_sigs_required} valid signatures found."
+ f"{n_valid_sigs_per_output} of {n_sigs_required} valid signatures"
+ " found."
)
logger.trace(proof.p2pksigs)
@@ -431,11 +437,13 @@ def _verify_output_spending_conditions(
):
n_valid_sigs_per_output += 1
assert n_valid_sigs_per_output, "no valid signature provided for output."
- assert (
- n_valid_sigs_per_output >= n_sigs_required
- ), f"signature threshold not met. {n_valid_sigs_per_output} < {n_sigs_required}."
+ assert n_valid_sigs_per_output >= n_sigs_required, (
+ f"signature threshold not met. {n_valid_sigs_per_output} <"
+ f" {n_sigs_required}."
+ )
logger.trace(
- f"{n_valid_sigs_per_output} of {n_sigs_required} valid signatures found."
+ f"{n_valid_sigs_per_output} of {n_sigs_required} valid signatures"
+ " found."
)
logger.trace(output.p2pksigs)
logger.trace("p2pk signatures on output is valid.")
@@ -499,7 +507,8 @@ async def _request_lightning_invoice(self, amount: int):
Tuple[str, str]: Bolt11 invoice and payment hash (for lookup)
"""
logger.trace(
- f"_request_lightning_invoice: Requesting Lightning invoice for {amount} satoshis."
+ "_request_lightning_invoice: Requesting Lightning invoice for"
+ f" {amount} satoshis."
)
error, balance = await self.lightning.status()
logger.trace(f"_request_lightning_invoice: Lightning wallet balance: {balance}")
@@ -556,14 +565,16 @@ async def _check_lightning_invoice(
try:
if amount > invoice.amount:
raise LightningError(
- f"requested amount too high: {amount}. Invoice amount: {invoice.amount}"
+ f"requested amount too high: {amount}. Invoice amount:"
+ f" {invoice.amount}"
)
logger.trace(
f"_check_lightning_invoice: checking invoice {invoice.payment_hash}"
)
status = await self.lightning.get_invoice_status(invoice.payment_hash)
logger.trace(
- f"_check_lightning_invoice: invoice {invoice.payment_hash} status: {status}"
+ f"_check_lightning_invoice: invoice {invoice.payment_hash} status:"
+ f" {status}"
)
if status.paid:
return status.paid
@@ -665,7 +676,8 @@ async def _unset_proofs_pending(
try:
for p in proofs:
logger.trace(
- f"crud: _unset_proofs_pending unsetting proof {p.secret} as pending"
+ f"crud: _unset_proofs_pending unsetting proof {p.secret} as"
+ " pending"
)
await self.crud.unset_proof_pending(proof=p, db=self.db, conn=conn)
logger.trace(
@@ -1012,7 +1024,8 @@ async def check_fees(self, pr: str):
decoded_invoice = bolt11.decode(pr)
amount = math.ceil(decoded_invoice.amount_msat / 1000)
logger.trace(
- f"check_fees: checking lightning invoice: {decoded_invoice.payment_hash}"
+ "check_fees: checking lightning invoice:"
+ f" {decoded_invoice.payment_hash}"
)
paid = await self.lightning.get_invoice_status(decoded_invoice.payment_hash)
logger.trace(f"check_fees: paid: {paid}")
@@ -1078,7 +1091,8 @@ async def split(
# BEGIN backwards compatibility < 0.13.0
if amount is not None:
logger.debug(
- "Split: Client provided `amount` - backwards compatibility response pre 0.13.0"
+ "Split: Client provided `amount` - backwards compatibility response pre"
+ " 0.13.0"
)
# split outputs according to amount
total = sum_proofs(proofs)
diff --git a/cashu/mint/migrations.py b/cashu/mint/migrations.py
index bb25b59b..0d4df023 100644
--- a/cashu/mint/migrations.py
+++ b/cashu/mint/migrations.py
@@ -2,19 +2,16 @@
async def m000_create_migrations_table(db: Database):
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS {table_with_schema(db, 'dbversions')} (
db TEXT PRIMARY KEY,
version INT NOT NULL
)
- """
- )
+ """)
async def m001_initial(db: Database):
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS {table_with_schema(db, 'promises')} (
amount {db.big_int} NOT NULL,
B_b TEXT NOT NULL,
@@ -23,11 +20,9 @@ async def m001_initial(db: Database):
UNIQUE (B_b)
);
- """
- )
+ """)
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS {table_with_schema(db, 'proofs_used')} (
amount {db.big_int} NOT NULL,
C TEXT NOT NULL,
@@ -36,11 +31,9 @@ async def m001_initial(db: Database):
UNIQUE (secret)
);
- """
- )
+ """)
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS {table_with_schema(db, 'invoices')} (
amount {db.big_int} NOT NULL,
pr TEXT NOT NULL,
@@ -50,49 +43,41 @@ async def m001_initial(db: Database):
UNIQUE (hash)
);
- """
- )
+ """)
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE VIEW {table_with_schema(db, 'balance_issued')} AS
SELECT COALESCE(SUM(s), 0) AS balance FROM (
SELECT SUM(amount)
FROM {table_with_schema(db, 'promises')}
WHERE amount > 0
) AS s;
- """
- )
+ """)
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE VIEW {table_with_schema(db, 'balance_redeemed')} AS
SELECT COALESCE(SUM(s), 0) AS balance FROM (
SELECT SUM(amount)
FROM {table_with_schema(db, 'proofs_used')}
WHERE amount > 0
) AS s;
- """
- )
+ """)
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE VIEW {table_with_schema(db, 'balance')} AS
SELECT s_issued - s_used FROM (
SELECT bi.balance AS s_issued, bu.balance AS s_used
FROM {table_with_schema(db, 'balance_issued')} bi
CROSS JOIN {table_with_schema(db, 'balance_redeemed')} bu
) AS balance;
- """
- )
+ """)
async def m003_mint_keysets(db: Database):
"""
Stores mint keysets from different mints and epochs.
"""
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS {table_with_schema(db, 'keysets')} (
id TEXT NOT NULL,
derivation_path TEXT,
@@ -104,10 +89,8 @@ async def m003_mint_keysets(db: Database):
UNIQUE (derivation_path)
);
- """
- )
- await db.execute(
- f"""
+ """)
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS {table_with_schema(db, 'mint_pubkeys')} (
id TEXT NOT NULL,
amount INTEGER NOT NULL,
@@ -116,8 +99,7 @@ async def m003_mint_keysets(db: Database):
UNIQUE (id, pubkey)
);
- """
- )
+ """)
async def m004_keysets_add_version(db: Database):
@@ -133,8 +115,7 @@ async def m005_pending_proofs_table(db: Database) -> None:
"""
Store pending proofs.
"""
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS {table_with_schema(db, 'proofs_pending')} (
amount INTEGER NOT NULL,
C TEXT NOT NULL,
@@ -143,8 +124,7 @@ async def m005_pending_proofs_table(db: Database) -> None:
UNIQUE (secret)
);
- """
- )
+ """)
async def m006_invoices_add_payment_hash(db: Database):
diff --git a/cashu/mint/router.py b/cashu/mint/router.py
index 2fbb8336..3ede2c6b 100644
--- a/cashu/mint/router.py
+++ b/cashu/mint/router.py
@@ -59,7 +59,10 @@ async def info() -> GetInfoResponse:
"/keys",
name="Mint public keys",
summary="Get the public keys of the newest mint keyset",
- response_description="A dictionary of all supported token values of the mint and their associated public key of the current keyset.",
+ response_description=(
+ "A dictionary of all supported token values of the mint and their associated"
+ " public key of the current keyset."
+ ),
response_model=KeysResponse,
)
async def keys():
@@ -74,7 +77,10 @@ async def keys():
"/keys/{idBase64Urlsafe}",
name="Keyset public keys",
summary="Public keys of a specific keyset",
- response_description="A dictionary of all supported token values of the mint and their associated public key for a specific keyset.",
+ response_description=(
+ "A dictionary of all supported token values of the mint and their associated"
+ " public key for a specific keyset."
+ ),
response_model=KeysResponse,
)
async def keyset_keys(idBase64Urlsafe: str):
@@ -109,7 +115,10 @@ async def keysets() -> KeysetsResponse:
name="Request mint",
summary="Request minting of new tokens",
response_model=GetMintResponse,
- response_description="A Lightning invoice to be paid and a hash to request minting of new tokens after payment.",
+ response_description=(
+ "A Lightning invoice to be paid and a hash to request minting of new tokens"
+ " after payment."
+ ),
)
async def request_mint(amount: int = 0) -> GetMintResponse:
"""
@@ -135,7 +144,9 @@ async def request_mint(amount: int = 0) -> GetMintResponse:
name="Mint tokens",
summary="Mint tokens in exchange for a Bitcoin paymemt that the user has made",
response_model=PostMintResponse,
- response_description="A list of blinded signatures that can be used to create proofs.",
+ response_description=(
+ "A list of blinded signatures that can be used to create proofs."
+ ),
)
async def mint(
payload: PostMintRequest,
@@ -163,9 +174,15 @@ async def mint(
@router.post(
"/melt",
name="Melt tokens",
- summary="Melt tokens for a Bitcoin payment that the mint will make for the user in exchange",
+ summary=(
+ "Melt tokens for a Bitcoin payment that the mint will make for the user in"
+ " exchange"
+ ),
response_model=GetMeltResponse,
- response_description="The state of the payment, a preimage as proof of payment, and a list of promises for change.",
+ response_description=(
+ "The state of the payment, a preimage as proof of payment, and a list of"
+ " promises for change."
+ ),
)
async def melt(payload: PostMeltRequest) -> GetMeltResponse:
"""
@@ -225,7 +242,9 @@ async def check_fees(payload: CheckFeesRequest) -> CheckFeesResponse:
name="Split",
summary="Split proofs at a specified amount",
response_model=Union[PostSplitResponse, PostSplitResponse_Deprecated],
- response_description="A list of blinded signatures that can be used to create proofs.",
+ response_description=(
+ "A list of blinded signatures that can be used to create proofs."
+ ),
)
async def split(
payload: PostSplitRequest,
@@ -259,8 +278,9 @@ async def split(
else:
frst_promises.insert(0, promise) # and insert at the beginning
logger.trace(
- f"Split into keep: {len(frst_promises)}: {sum([p.amount for p in frst_promises])} "
- f"sat and send: {len(scnd_promises)}: {sum([p.amount for p in scnd_promises])} sat"
+ f"Split into keep: {len(frst_promises)}:"
+ f" {sum([p.amount for p in frst_promises])} sat and send:"
+ f" {len(scnd_promises)}: {sum([p.amount for p in scnd_promises])} sat"
)
return PostSplitResponse_Deprecated(fst=frst_promises, snd=scnd_promises)
# END backwards compatibility < 0.13
diff --git a/cashu/mint/startup.py b/cashu/mint/startup.py
index f4c8de70..735f59e9 100644
--- a/cashu/mint/startup.py
+++ b/cashu/mint/startup.py
@@ -53,7 +53,8 @@ async def start_mint_init():
error_message, balance = await ledger.lightning.status()
if error_message:
logger.warning(
- f"The backend for {ledger.lightning.__class__.__name__} isn't working properly: '{error_message}'",
+ f"The backend for {ledger.lightning.__class__.__name__} isn't working"
+ f" properly: '{error_message}'",
RuntimeWarning,
)
logger.info(f"Lightning balance: {balance} msat")
diff --git a/cashu/wallet/api/responses.py b/cashu/wallet/api/responses.py
index 931aa56d..625a78af 100644
--- a/cashu/wallet/api/responses.py
+++ b/cashu/wallet/api/responses.py
@@ -74,7 +74,7 @@ class InfoResponse(BaseModel):
wallet: str
debug: bool
cashu_dir: str
- mint_url: str
+ mint_urls: List[str] = []
settings: Optional[str]
tor: bool
nostr_public_key: Optional[str] = None
diff --git a/cashu/wallet/api/router.py b/cashu/wallet/api/router.py
index 80ac0d6e..d3e60936 100644
--- a/cashu/wallet/api/router.py
+++ b/cashu/wallet/api/router.py
@@ -14,7 +14,13 @@
from ...nostr.nostr.client.client import NostrClient
from ...tor.tor import TorProxy
from ...wallet.crud import get_lightning_invoices, get_reserved_proofs, get_unused_locks
-from ...wallet.helpers import deserialize_token_from_string, init_wallet, receive, send
+from ...wallet.helpers import (
+ deserialize_token_from_string,
+ init_wallet,
+ list_mints,
+ receive,
+ send,
+)
from ...wallet.nostr import receive_nostr, send_nostr
from ...wallet.wallet import Wallet as Wallet
from .api_helpers import verify_mints
@@ -38,32 +44,35 @@
router: APIRouter = APIRouter()
-def create_wallet(
- url=settings.mint_url, dir=settings.cashu_dir, name=settings.wallet_name
-):
- return Wallet(
- url=url,
- db=os.path.join(dir, name),
- name=name,
+async def mint_wallet(mint_url: Optional[str] = None):
+ wallet: Wallet = await Wallet.with_db(
+ mint_url or settings.mint_url,
+ db=os.path.join(settings.cashu_dir, settings.wallet_name),
+ name=settings.wallet_name,
)
-
-
-async def load_mint(wallet: Wallet, mint: Optional[str] = None):
- if mint:
- wallet = create_wallet(mint)
- await init_wallet(wallet)
await wallet.load_mint()
return wallet
-wallet = create_wallet()
+wallet: Wallet = Wallet(
+ settings.mint_url,
+ db=os.path.join(settings.cashu_dir, settings.wallet_name),
+ name=settings.wallet_name,
+)
@router.on_event("startup")
async def start_wallet():
+ global wallet
+ wallet = await Wallet.with_db(
+ settings.mint_url,
+ db=os.path.join(settings.cashu_dir, settings.wallet_name),
+ name=settings.wallet_name,
+ )
+
if settings.tor and not TorProxy().check_platform():
raise Exception("tor not working.")
- await init_wallet(wallet)
+ await wallet.load_mint()
@router.post("/pay", name="Pay lightning invoice", response_model=PayResponse)
@@ -78,7 +87,8 @@ async def pay(
raise Exception("lightning not enabled.")
global wallet
- wallet = await load_mint(wallet, mint)
+ wallet = await mint_wallet(mint)
+ await wallet.load_proofs(reload=True)
total_amount, fee_reserve_sat = await wallet.get_pay_amount_with_fees(invoice)
assert total_amount > 0, "amount has to be larger than zero."
@@ -116,7 +126,7 @@ async def invoice(
print(f"Requesting split with {n_splits}*{split} sat tokens.")
global wallet
- wallet = await load_mint(wallet, mint)
+ wallet = await mint_wallet(mint)
if not settings.lightning:
await wallet.mint(amount, split=optional_split)
return InvoiceResponse(
@@ -150,8 +160,8 @@ async def swap(
):
if not settings.lightning:
raise Exception("lightning not supported")
- incoming_wallet = await load_mint(wallet, mint=incoming_mint)
- outgoing_wallet = await load_mint(wallet, mint=outgoing_mint)
+ incoming_wallet = await mint_wallet(incoming_mint)
+ outgoing_wallet = await mint_wallet(outgoing_mint)
if incoming_wallet.url == outgoing_wallet.url:
raise Exception("mints for swap have to be different")
@@ -159,7 +169,7 @@ async def swap(
invoice = await incoming_wallet.request_mint(amount)
# pay invoice from outgoing mint
- await outgoing_wallet.load_proofs()
+ await outgoing_wallet.load_proofs(reload=True)
total_amount, fee_reserve_sat = await outgoing_wallet.get_pay_amount_with_fees(
invoice.pr
)
@@ -174,7 +184,7 @@ async def swap(
# mint token in incoming mint
await incoming_wallet.mint(amount, hash=invoice.hash)
- await incoming_wallet.load_proofs()
+ await incoming_wallet.load_proofs(reload=True)
mint_balances = await incoming_wallet.balance_per_minturl()
return SwapResponse(
outgoing_mint=outgoing_mint,
@@ -191,7 +201,7 @@ async def swap(
response_model=BalanceResponse,
)
async def balance():
- await wallet.load_proofs()
+ await wallet.load_proofs(reload=True)
keyset_balances = wallet.balance_per_keyset()
mint_balances = await wallet.balance_per_minturl()
return BalanceResponse(
@@ -229,6 +239,7 @@ async def receive_command(
nostr: bool = Query(default=False, description="Receive tokens via nostr"),
all: bool = Query(default=False, description="Receive all pending tokens"),
):
+ wallet = await mint_wallet()
initial_balance = wallet.available_balance
if token:
tokenObj: TokenV3 = deserialize_token_from_string(token)
@@ -269,11 +280,12 @@ async def burn(
):
global wallet
if not delete:
- wallet = await load_mint(wallet, mint)
+ wallet = await mint_wallet(mint)
if not (all or token or force or delete) or (token and all):
raise Exception(
- "enter a token or use --all to burn all pending tokens, --force to check all tokens"
- "or --delete with send ID to force-delete pending token from list if mint is unavailable.",
+ "enter a token or use --all to burn all pending tokens, --force to"
+ " check all tokensor --delete with send ID to force-delete pending"
+ " token from list if mint is unavailable.",
)
if all:
# check only those who are flagged as reserved
@@ -403,7 +415,7 @@ async def restore(
if to < 0:
raise Exception("Counter must be positive")
await wallet.load_mint()
- await wallet.restore_promises(0, to)
+ await wallet.restore_promises_from_to(0, to)
await wallet.invalidate(wallet.proofs)
wallet.status()
return RestoreResponse(balance=wallet.available_balance)
@@ -422,12 +434,13 @@ async def info():
else:
nostr_public_key = None
nostr_relays = []
+ mint_list = await list_mints(wallet)
return InfoResponse(
version=settings.version,
wallet=wallet.name,
debug=settings.debug,
cashu_dir=settings.cashu_dir,
- mint_url=settings.mint_url,
+ mint_urls=mint_list,
settings=settings.env_file,
tor=settings.tor,
nostr_public_key=nostr_public_key,
diff --git a/cashu/wallet/cli/cli.py b/cashu/wallet/cli/cli.py
index 3d5803a9..fb4d654f 100644
--- a/cashu/wallet/cli/cli.py
+++ b/cashu/wallet/cli/cli.py
@@ -28,7 +28,13 @@
from ...wallet.wallet import Wallet as Wallet
from ..api.api_server import start_api_server
from ..cli.cli_helpers import get_mint_wallet, print_mint_balances, verify_mint
-from ..helpers import deserialize_token_from_string, init_wallet, receive, send
+from ..helpers import (
+ deserialize_token_from_string,
+ init_wallet,
+ list_mints,
+ receive,
+ send,
+)
from ..nostr import receive_nostr, send_nostr
@@ -90,18 +96,27 @@ def wrapper(*args, **kwargs):
async def cli(ctx: Context, host: str, walletname: str, tests: bool):
if settings.tor and not TorProxy().check_platform():
error_str = (
- "Your settings say TOR=true but the built-in Tor bundle is not supported on your system. You have two options: Either install"
- " Tor manually and set TOR=FALSE and SOCKS_HOST=localhost and SOCKS_PORT=9050 in your Cashu config (recommended). Or turn off Tor by "
- "setting TOR=false (not recommended). Cashu will not work until you edit your config file accordingly."
+ "Your settings say TOR=true but the built-in Tor bundle is not supported on"
+ " your system. You have two options: Either install Tor manually and set"
+ " TOR=FALSE and SOCKS_HOST=localhost and SOCKS_PORT=9050 in your Cashu"
+ " config (recommended). Or turn off Tor by setting TOR=false (not"
+ " recommended). Cashu will not work until you edit your config file"
+ " accordingly."
)
error_str += "\n\n"
if settings.env_file:
error_str += f"Edit your Cashu config file here: {settings.env_file}"
env_path = settings.env_file
else:
- error_str += f"Ceate a new Cashu config file here: {os.path.join(settings.cashu_dir, '.env')}"
+ error_str += (
+ "Ceate a new Cashu config file here:"
+ f" {os.path.join(settings.cashu_dir, '.env')}"
+ )
env_path = os.path.join(settings.cashu_dir, ".env")
- error_str += f'\n\nYou can turn off Tor with this command: echo "TOR=FALSE" >> {env_path}'
+ error_str += (
+ '\n\nYou can turn off Tor with this command: echo "TOR=FALSE" >>'
+ f" {env_path}"
+ )
raise Exception(error_str)
ctx.ensure_object(dict)
@@ -155,7 +170,8 @@ async def pay(ctx: Context, invoice: str, yes: bool):
total_amount, fee_reserve_sat = await wallet.get_pay_amount_with_fees(invoice)
if not yes:
click.confirm(
- f"Pay {total_amount - fee_reserve_sat} sat ({total_amount} sat with potential fees)?",
+ f"Pay {total_amount - fee_reserve_sat} sat ({total_amount} sat with"
+ " potential fees)?",
abort=True,
default=True,
)
@@ -206,7 +222,8 @@ async def invoice(ctx: Context, amount: int, hash: str, split: int):
print(f"Invoice: {invoice.pr}")
print("")
print(
- f"If you abort this you can use this command to recheck the invoice:\ncashu invoice {amount} --hash {invoice.hash}"
+ "If you abort this you can use this command to recheck the"
+ f" invoice:\ncashu invoice {amount} --hash {invoice.hash}"
)
check_until = time.time() + 5 * 60 # check for five minutes
print("")
@@ -232,7 +249,8 @@ async def invoice(ctx: Context, amount: int, hash: str, split: int):
if not paid:
print("\n")
print(
- "Invoice is not paid yet, stopping check. Use the command above to recheck after the invoice has been paid."
+ "Invoice is not paid yet, stopping check. Use the command above to"
+ " recheck after the invoice has been paid."
)
# user paid invoice and want to check it
@@ -306,7 +324,8 @@ async def balance(ctx: Context, verbose):
print("")
for k, v in keyset_balances.items():
print(
- f"Keyset: {k} - Balance: {v['available']} sat (pending: {v['balance']-v['available']} sat)"
+ f"Keyset: {k} - Balance: {v['available']} sat (pending:"
+ f" {v['balance']-v['available']} sat)"
)
print("")
@@ -314,8 +333,9 @@ async def balance(ctx: Context, verbose):
if verbose:
print(
- f"Balance: {wallet.available_balance} sat (pending: {wallet.balance-wallet.available_balance} sat) "
- f"in {len([p for p in wallet.proofs if not p.reserved])} tokens"
+ f"Balance: {wallet.available_balance} sat (pending:"
+ f" {wallet.balance-wallet.available_balance} sat) in"
+ f" {len([p for p in wallet.proofs if not p.reserved])} tokens"
)
else:
print(f"Balance: {wallet.available_balance} sat")
@@ -404,7 +424,7 @@ async def send_command(
"-n",
default=False,
is_flag=True,
- help="Receive tokens via nostr." "receive",
+ help="Receive tokens via nostr.receive",
)
@click.option(
"--all", "-a", default=False, is_flag=True, help="Receive all pending tokens."
@@ -472,8 +492,9 @@ async def burn(ctx: Context, token: str, all: bool, force: bool, delete: str):
await wallet.load_mint()
if not (all or token or force or delete) or (token and all):
print(
- "Error: enter a token or use --all to burn all pending tokens, --force to check all tokens "
- "or --delete with send ID to force-delete pending token from list if mint is unavailable."
+ "Error: enter a token or use --all to burn all pending tokens, --force to"
+ " check all tokens or --delete with send ID to force-delete pending token"
+ " from list if mint is unavailable."
)
return
if all:
@@ -546,7 +567,8 @@ async def pending(ctx: Context, legacy, number: int, offset: int):
int(grouped_proofs[0].time_reserved)
).strftime("%Y-%m-%d %H:%M:%S")
print(
- f"#{i} Amount: {sum_proofs(grouped_proofs)} sat Time: {reserved_date} ID: {key} Mint: {mint}\n"
+ f"#{i} Amount: {sum_proofs(grouped_proofs)} sat Time:"
+ f" {reserved_date} ID: {key} Mint: {mint}\n"
)
print(f"{token}\n")
@@ -676,7 +698,8 @@ async def wallets(ctx):
if w == ctx.obj["WALLET_NAME"]:
active_wallet = True
print(
- f"Wallet: {w}\tBalance: {sum_proofs(wallet.proofs)} sat (available: "
+ f"Wallet: {w}\tBalance: {sum_proofs(wallet.proofs)} sat"
+ " (available: "
f"{sum_proofs([p for p in wallet.proofs if not p.reserved])} sat){' *' if active_wallet else ''}"
)
except Exception:
@@ -710,26 +733,30 @@ async def info(ctx: Context, mint: bool, mnemonic: bool):
print(f"Socks proxy: {settings.socks_proxy}")
if settings.http_proxy:
print(f"HTTP proxy: {settings.http_proxy}")
- print(f"Mint URL: {ctx.obj['HOST']}")
+ mint_list = await list_mints(wallet)
+ print(f"Mint URLs: {mint_list}")
if mint:
- mint_info: dict = (await wallet._load_mint_info()).dict()
- print("")
- print("Mint information:")
- print("")
- if mint_info:
- print(f"Mint name: {mint_info['name']}")
- if mint_info["description"]:
- print(f"Description: {mint_info['description']}")
- if mint_info["description_long"]:
- print(f"Long description: {mint_info['description_long']}")
- if mint_info["contact"]:
- print(f"Contact: {mint_info['contact']}")
- if mint_info["version"]:
- print(f"Version: {mint_info['version']}")
- if mint_info["motd"]:
- print(f"Message of the day: {mint_info['motd']}")
- if mint_info["parameter"]:
- print(f"Parameter: {mint_info['parameter']}")
+ for mint_url in mint_list:
+ wallet.url = mint_url
+ mint_info: dict = (await wallet._load_mint_info()).dict()
+ print("")
+ print("Mint information:")
+ print("")
+ print(f"Mint URL: {mint_url}")
+ if mint_info:
+ print(f"Mint name: {mint_info['name']}")
+ if mint_info["description"]:
+ print(f"Description: {mint_info['description']}")
+ if mint_info["description_long"]:
+ print(f"Long description: {mint_info['description_long']}")
+ if mint_info["contact"]:
+ print(f"Contact: {mint_info['contact']}")
+ if mint_info["version"]:
+ print(f"Version: {mint_info['version']}")
+ if mint_info["motd"]:
+ print(f"Message of the day: {mint_info['motd']}")
+ if mint_info["parameter"]:
+ print(f"Parameter: {mint_info['parameter']}")
if mnemonic:
assert wallet.mnemonic
@@ -760,12 +787,14 @@ async def restore(ctx: Context, to: int, batch: int):
ret = await get_seed_and_mnemonic(wallet.db)
if ret:
print(
- "Wallet already has a mnemonic. You can't restore an already initialized wallet."
+ "Wallet already has a mnemonic. You can't restore an already initialized"
+ " wallet."
)
print("To restore a wallet, please delete the wallet directory and try again.")
print("")
print(
- f"The wallet directory is: {os.path.join(settings.cashu_dir, ctx.obj['WALLET_NAME'])}"
+ "The wallet directory is:"
+ f" {os.path.join(settings.cashu_dir, ctx.obj['WALLET_NAME'])}"
)
return
# ask the user for a mnemonic but allow also no input
diff --git a/cashu/wallet/cli/cli_helpers.py b/cashu/wallet/cli/cli_helpers.py
index 068d2443..e7d12b21 100644
--- a/cashu/wallet/cli/cli_helpers.py
+++ b/cashu/wallet/cli/cli_helpers.py
@@ -78,7 +78,8 @@ async def print_mint_balances(wallet, show_mints=False):
print("")
for i, (k, v) in enumerate(mint_balances.items()):
print(
- f"Mint {i+1}: Balance: {v['available']} sat (pending: {v['balance']-v['available']} sat) URL: {k}"
+ f"Mint {i+1}: Balance: {v['available']} sat (pending:"
+ f" {v['balance']-v['available']} sat) URL: {k}"
)
print("")
diff --git a/cashu/wallet/crud.py b/cashu/wallet/crud.py
index 887db759..e229ccf1 100644
--- a/cashu/wallet/crud.py
+++ b/cashu/wallet/crud.py
@@ -31,11 +31,9 @@ async def get_proofs(
db: Database,
conn: Optional[Connection] = None,
):
- rows = await (conn or db).fetchall(
- """
+ rows = await (conn or db).fetchall("""
SELECT * from proofs
- """
- )
+ """)
return [Proof(**dict(r)) for r in rows]
@@ -43,12 +41,10 @@ async def get_reserved_proofs(
db: Database,
conn: Optional[Connection] = None,
):
- rows = await (conn or db).fetchall(
- """
+ rows = await (conn or db).fetchall("""
SELECT * from proofs
WHERE reserved
- """
- )
+ """)
return [Proof(**r) for r in rows]
diff --git a/cashu/wallet/helpers.py b/cashu/wallet/helpers.py
index 508c951c..be3950b4 100644
--- a/cashu/wallet/helpers.py
+++ b/cashu/wallet/helpers.py
@@ -26,6 +26,15 @@ async def init_wallet(wallet: Wallet, load_proofs: bool = True):
await wallet.load_proofs(reload=True)
+async def list_mints(wallet: Wallet):
+ await wallet.load_proofs()
+ balances = await wallet.balance_per_minturl()
+ mints = list(balances.keys())
+ if wallet.url not in mints:
+ mints.append(wallet.url)
+ return mints
+
+
async def redeem_TokenV3_multimint(wallet: Wallet, token: TokenV3):
"""
Helper function to iterate thruogh a token with multiple mints and redeem them from
@@ -201,7 +210,8 @@ async def send(
send_proofs = [p]
break
assert send_proofs, Exception(
- f"No proof with this amount found. Available amounts: {set([p.amount for p in wallet.proofs])}"
+ "No proof with this amount found. Available amounts:"
+ f" {set([p.amount for p in wallet.proofs])}"
)
await wallet.set_reserved(send_proofs, reserved=True)
diff --git a/cashu/wallet/migrations.py b/cashu/wallet/migrations.py
index 810def7e..061b31c5 100644
--- a/cashu/wallet/migrations.py
+++ b/cashu/wallet/migrations.py
@@ -2,19 +2,16 @@
async def m000_create_migrations_table(db: Database):
- await db.execute(
- """
+ await db.execute("""
CREATE TABLE IF NOT EXISTS dbversions (
db TEXT PRIMARY KEY,
version INT NOT NULL
)
- """
- )
+ """)
async def m001_initial(db: Database):
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS proofs (
amount {db.big_int} NOT NULL,
C TEXT NOT NULL,
@@ -23,11 +20,9 @@ async def m001_initial(db: Database):
UNIQUE (secret)
);
- """
- )
+ """)
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS proofs_used (
amount {db.big_int} NOT NULL,
C TEXT NOT NULL,
@@ -36,30 +31,25 @@ async def m001_initial(db: Database):
UNIQUE (secret)
);
- """
- )
+ """)
- await db.execute(
- """
+ await db.execute("""
CREATE VIEW IF NOT EXISTS balance AS
SELECT COALESCE(SUM(s), 0) AS balance FROM (
SELECT SUM(amount) AS s
FROM proofs
WHERE amount > 0
);
- """
- )
+ """)
- await db.execute(
- """
+ await db.execute("""
CREATE VIEW IF NOT EXISTS balance_used AS
SELECT COALESCE(SUM(s), 0) AS used FROM (
SELECT SUM(amount) AS s
FROM proofs_used
WHERE amount > 0
);
- """
- )
+ """)
async def m002_add_proofs_reserved(db: Database):
@@ -85,8 +75,7 @@ async def m004_p2sh_locks(db: Database):
"""
Stores P2SH addresses and unlock scripts.
"""
- await db.execute(
- """
+ await db.execute("""
CREATE TABLE IF NOT EXISTS p2sh (
address TEXT NOT NULL,
script TEXT NOT NULL,
@@ -96,16 +85,14 @@ async def m004_p2sh_locks(db: Database):
UNIQUE (address, script, signature)
);
- """
- )
+ """)
async def m005_wallet_keysets(db: Database):
"""
Stores mint keysets from different mints and epochs.
"""
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS keysets (
id TEXT,
mint_url TEXT,
@@ -117,8 +104,7 @@ async def m005_wallet_keysets(db: Database):
UNIQUE (id, mint_url)
);
- """
- )
+ """)
await db.execute("ALTER TABLE proofs ADD COLUMN id TEXT")
await db.execute("ALTER TABLE proofs_used ADD COLUMN id TEXT")
@@ -128,8 +114,7 @@ async def m006_invoices(db: Database):
"""
Stores Lightning invoices.
"""
- await db.execute(
- f"""
+ await db.execute(f"""
CREATE TABLE IF NOT EXISTS invoices (
amount INTEGER NOT NULL,
pr TEXT NOT NULL,
@@ -142,22 +127,19 @@ async def m006_invoices(db: Database):
UNIQUE (hash)
);
- """
- )
+ """)
async def m007_nostr(db: Database):
"""
Stores timestamps of nostr operations.
"""
- await db.execute(
- """
+ await db.execute("""
CREATE TABLE IF NOT EXISTS nostr (
type TEXT NOT NULL,
last TIMESTAMP DEFAULT NULL
)
- """
- )
+ """)
await db.execute(
"""
INSERT INTO nostr
@@ -182,14 +164,12 @@ async def m009_privatekey_and_determinstic_key_derivation(db: Database):
await db.execute("ALTER TABLE keysets ADD COLUMN counter INTEGER DEFAULT 0")
await db.execute("ALTER TABLE proofs ADD COLUMN derivation_path TEXT")
await db.execute("ALTER TABLE proofs_used ADD COLUMN derivation_path TEXT")
- await db.execute(
- """
+ await db.execute("""
CREATE TABLE IF NOT EXISTS seed (
seed TEXT NOT NULL,
mnemonic TEXT NOT NULL,
UNIQUE (seed, mnemonic)
);
- """
- )
+ """)
# await db.execute("INSERT INTO secret_derivation (counter) VALUES (0)")
diff --git a/cashu/wallet/nostr.py b/cashu/wallet/nostr.py
index 64cf5f51..69ac6534 100644
--- a/cashu/wallet/nostr.py
+++ b/cashu/wallet/nostr.py
@@ -101,8 +101,9 @@ async def receive_nostr(
):
if settings.nostr_private_key is None:
print(
- "Warning: No nostr private key set! You don't have NOSTR_PRIVATE_KEY set in your .env file. "
- "I will create a random private key for this session but I will not remember it."
+ "Warning: No nostr private key set! You don't have NOSTR_PRIVATE_KEY set in"
+ " your .env file. I will create a random private key for this session but I"
+ " will not remember it."
)
print("")
client = NostrClient(
diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py
index 1cebed7f..e3f52ae6 100644
--- a/cashu/wallet/wallet.py
+++ b/cashu/wallet/wallet.py
@@ -737,7 +737,8 @@ async def _init_private_key(self, from_mnemonic: Optional[str] = None) -> None:
else ""
)
print(
- f'Generated a new mnemonic{wallet_name}. To view it, run "cashu{wallet_command_prefix_str} info --mnemonic".'
+ f"Generated a new mnemonic{wallet_name}. To view it, run"
+ f' "cashu{wallet_command_prefix_str} info --mnemonic".'
)
elif from_mnemonic:
# or use the one provided
@@ -1465,7 +1466,8 @@ async def invalidate(
if invalidated_proofs:
logger.debug(
- f"Invalidating {len(invalidated_proofs)} proofs worth {sum_proofs(invalidated_proofs)} sat."
+ f"Invalidating {len(invalidated_proofs)} proofs worth"
+ f" {sum_proofs(invalidated_proofs)} sat."
)
async with self.db.connect() as conn:
@@ -1599,7 +1601,8 @@ async def sign_p2pk_proofs(self, proofs: List[Proof]) -> List[str]:
private_key = self.private_key
assert private_key.pubkey
logger.trace(
- f"Signing with private key: {private_key.serialize()} public key: {private_key.pubkey.serialize().hex()}"
+ f"Signing with private key: {private_key.serialize()} public key:"
+ f" {private_key.pubkey.serialize().hex()}"
)
for proof in proofs:
logger.trace(f"Signing proof: {proof}")
@@ -1692,7 +1695,7 @@ async def restore_wallet_from_mnemonic(
n_last_restored_proofs = 0
while stop_counter < to:
print(f"Restoring token {i} to {i + batch}...")
- restored_proofs = await self.restore_promises(i, i + batch - 1)
+ restored_proofs = await self.restore_promises_from_to(i, i + batch - 1)
if len(restored_proofs) == 0:
stop_counter += 1
spendable_proofs = await self.invalidate(restored_proofs)
@@ -1716,7 +1719,9 @@ async def restore_wallet_from_mnemonic(
print("No tokens restored.")
return
- async def restore_promises(self, from_counter: int, to_counter: int) -> List[Proof]:
+ async def restore_promises_from_to(
+ self, from_counter: int, to_counter: int
+ ) -> List[Proof]:
"""Restores promises from a given range of counters. This is for restoring a wallet from a mnemonic.
Args:
@@ -1735,14 +1740,42 @@ async def restore_promises(self, from_counter: int, to_counter: int) -> List[Pro
# we generate outptus from deterministic secrets and rs
regenerated_outputs, _ = self._construct_outputs(amounts_dummy, secrets, rs)
# we ask the mint to reissue the promises
- # restored_outputs is there so we can match the promises to the secrets and rs
- restored_outputs, restored_promises = await super().restore_promises(
- regenerated_outputs
+ proofs = await self.restore_promises(
+ outputs=regenerated_outputs,
+ secrets=secrets,
+ rs=rs,
+ derivation_paths=derivation_paths,
+ )
+
+ await set_secret_derivation(
+ db=self.db, keyset_id=self.keyset_id, counter=to_counter + 1
)
+ return proofs
+
+ async def restore_promises(
+ self,
+ outputs: List[BlindedMessage],
+ secrets: List[str],
+ rs: List[PrivateKey],
+ derivation_paths: List[str],
+ ) -> List[Proof]:
+ """Restores proofs from a list of outputs, secrets, rs and derivation paths.
+
+ Args:
+ outputs (List[BlindedMessage]): Outputs for which we request promises
+ secrets (List[str]): Secrets generated for the outputs
+ rs (List[PrivateKey]): Random blinding factors generated for the outputs
+ derivation_paths (List[str]): Derivation paths for the secrets
+
+ Returns:
+ List[Proof]: List of restored proofs
+ """
+ # restored_outputs is there so we can match the promises to the secrets and rs
+ restored_outputs, restored_promises = await super().restore_promises(outputs)
# now we need to filter out the secrets and rs that had a match
matching_indices = [
idx
- for idx, val in enumerate(regenerated_outputs)
+ for idx, val in enumerate(outputs)
if val.B_ in [o.B_ for o in restored_outputs]
]
secrets = [secrets[i] for i in matching_indices]
@@ -1758,8 +1791,4 @@ async def restore_promises(self, from_counter: int, to_counter: int) -> List[Pro
for proof in proofs:
if proof.secret not in [p.secret for p in self.proofs]:
self.proofs.append(proof)
-
- await set_secret_derivation(
- db=self.db, keyset_id=self.keyset_id, counter=to_counter + 1
- )
return proofs
diff --git a/poetry.lock b/poetry.lock
index ccdf37d7..33e4df0c 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -104,31 +104,42 @@ files = [
[[package]]
name = "black"
-version = "22.12.0"
+version = "23.7.0"
description = "The uncompromising code formatter."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"},
- {file = "black-22.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351"},
- {file = "black-22.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f"},
- {file = "black-22.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4"},
- {file = "black-22.12.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2"},
- {file = "black-22.12.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350"},
- {file = "black-22.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d"},
- {file = "black-22.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc"},
- {file = "black-22.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320"},
- {file = "black-22.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148"},
- {file = "black-22.12.0-py3-none-any.whl", hash = "sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf"},
- {file = "black-22.12.0.tar.gz", hash = "sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f"},
+ {file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"},
+ {file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"},
+ {file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"},
+ {file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"},
+ {file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"},
+ {file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"},
+ {file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"},
+ {file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"},
+ {file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"},
+ {file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"},
+ {file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"},
+ {file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"},
+ {file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"},
+ {file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"},
+ {file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"},
+ {file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"},
+ {file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"},
+ {file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"},
+ {file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"},
+ {file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"},
+ {file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"},
+ {file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"},
]
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
+packaging = ">=22.0"
pathspec = ">=0.9.0"
platformdirs = ">=2"
-tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""}
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
[package.extras]
@@ -226,13 +237,13 @@ pycparser = "*"
[[package]]
name = "cfgv"
-version = "3.3.1"
+version = "3.4.0"
description = "Validate configuration and produce human readable error messages."
optional = false
-python-versions = ">=3.6.1"
+python-versions = ">=3.8"
files = [
- {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
- {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"},
+ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
+ {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
]
[[package]]
@@ -321,13 +332,13 @@ files = [
[[package]]
name = "click"
-version = "8.1.6"
+version = "8.1.7"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
- {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"},
- {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"},
+ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
+ {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[package.dependencies]
@@ -401,71 +412,63 @@ files = [
[[package]]
name = "coverage"
-version = "7.2.7"
+version = "7.3.0"
description = "Code coverage measurement for Python"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"},
- {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"},
- {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"},
- {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"},
- {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"},
- {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"},
- {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"},
- {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"},
- {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"},
- {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"},
- {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"},
- {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"},
- {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"},
- {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"},
- {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"},
- {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"},
- {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"},
- {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"},
- {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"},
- {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"},
- {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"},
- {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"},
- {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"},
- {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"},
- {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"},
- {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"},
- {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"},
- {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"},
- {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"},
- {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"},
- {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"},
- {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"},
- {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"},
- {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"},
- {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"},
- {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"},
- {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"},
- {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"},
- {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"},
- {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"},
- {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"},
- {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"},
- {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"},
- {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"},
- {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"},
- {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"},
- {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"},
- {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"},
- {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"},
- {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"},
- {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"},
- {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"},
- {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"},
- {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"},
- {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"},
- {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"},
- {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"},
- {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"},
- {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"},
- {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"},
+ {file = "coverage-7.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5"},
+ {file = "coverage-7.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637"},
+ {file = "coverage-7.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af"},
+ {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1"},
+ {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12"},
+ {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689"},
+ {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977"},
+ {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51"},
+ {file = "coverage-7.3.0-cp310-cp310-win32.whl", hash = "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527"},
+ {file = "coverage-7.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1"},
+ {file = "coverage-7.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f"},
+ {file = "coverage-7.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d"},
+ {file = "coverage-7.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd"},
+ {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7"},
+ {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a"},
+ {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74"},
+ {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214"},
+ {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f"},
+ {file = "coverage-7.3.0-cp311-cp311-win32.whl", hash = "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482"},
+ {file = "coverage-7.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70"},
+ {file = "coverage-7.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b"},
+ {file = "coverage-7.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446"},
+ {file = "coverage-7.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071"},
+ {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe"},
+ {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a"},
+ {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873"},
+ {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2"},
+ {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b"},
+ {file = "coverage-7.3.0-cp312-cp312-win32.whl", hash = "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321"},
+ {file = "coverage-7.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479"},
+ {file = "coverage-7.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1"},
+ {file = "coverage-7.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd"},
+ {file = "coverage-7.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e"},
+ {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54"},
+ {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254"},
+ {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0"},
+ {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84"},
+ {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985"},
+ {file = "coverage-7.3.0-cp38-cp38-win32.whl", hash = "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9"},
+ {file = "coverage-7.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543"},
+ {file = "coverage-7.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba"},
+ {file = "coverage-7.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393"},
+ {file = "coverage-7.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28"},
+ {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95"},
+ {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a"},
+ {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34"},
+ {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e"},
+ {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54"},
+ {file = "coverage-7.3.0-cp39-cp39-win32.whl", hash = "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3"},
+ {file = "coverage-7.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e"},
+ {file = "coverage-7.3.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0"},
+ {file = "coverage-7.3.0.tar.gz", hash = "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865"},
]
[package.dependencies]
@@ -476,43 +479,48 @@ toml = ["tomli"]
[[package]]
name = "cryptography"
-version = "36.0.2"
+version = "41.0.3"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
files = [
- {file = "cryptography-36.0.2-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:4e2dddd38a5ba733be6a025a1475a9f45e4e41139d1321f412c6b360b19070b6"},
- {file = "cryptography-36.0.2-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:4881d09298cd0b669bb15b9cfe6166f16fc1277b4ed0d04a22f3d6430cb30f1d"},
- {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea634401ca02367c1567f012317502ef3437522e2fc44a3ea1844de028fa4b84"},
- {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7be666cc4599b415f320839e36367b273db8501127b38316f3b9f22f17a0b815"},
- {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8241cac0aae90b82d6b5c443b853723bcc66963970c67e56e71a2609dc4b5eaf"},
- {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b2d54e787a884ffc6e187262823b6feb06c338084bbe80d45166a1cb1c6c5bf"},
- {file = "cryptography-36.0.2-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:c2c5250ff0d36fd58550252f54915776940e4e866f38f3a7866d92b32a654b86"},
- {file = "cryptography-36.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ec6597aa85ce03f3e507566b8bcdf9da2227ec86c4266bd5e6ab4d9e0cc8dab2"},
- {file = "cryptography-36.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ca9f686517ec2c4a4ce930207f75c00bf03d94e5063cbc00a1dc42531511b7eb"},
- {file = "cryptography-36.0.2-cp36-abi3-win32.whl", hash = "sha256:f64b232348ee82f13aac22856515ce0195837f6968aeaa94a3d0353ea2ec06a6"},
- {file = "cryptography-36.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:53e0285b49fd0ab6e604f4c5d9c5ddd98de77018542e88366923f152dbeb3c29"},
- {file = "cryptography-36.0.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:32db5cc49c73f39aac27574522cecd0a4bb7384e71198bc65a0d23f901e89bb7"},
- {file = "cryptography-36.0.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b3d199647468d410994dbeb8cec5816fb74feb9368aedf300af709ef507e3e"},
- {file = "cryptography-36.0.2-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:da73d095f8590ad437cd5e9faf6628a218aa7c387e1fdf67b888b47ba56a17f0"},
- {file = "cryptography-36.0.2-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:0a3bf09bb0b7a2c93ce7b98cb107e9170a90c51a0162a20af1c61c765b90e60b"},
- {file = "cryptography-36.0.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8897b7b7ec077c819187a123174b645eb680c13df68354ed99f9b40a50898f77"},
- {file = "cryptography-36.0.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82740818f2f240a5da8dfb8943b360e4f24022b093207160c77cadade47d7c85"},
- {file = "cryptography-36.0.2-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:1f64a62b3b75e4005df19d3b5235abd43fa6358d5516cfc43d87aeba8d08dd51"},
- {file = "cryptography-36.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e167b6b710c7f7bc54e67ef593f8731e1f45aa35f8a8a7b72d6e42ec76afd4b3"},
- {file = "cryptography-36.0.2.tar.gz", hash = "sha256:70f8f4f7bb2ac9f340655cbac89d68c527af5bb4387522a8413e841e3e6628c9"},
+ {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:652627a055cb52a84f8c448185922241dd5217443ca194d5739b44612c5e6507"},
+ {file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8f09daa483aedea50d249ef98ed500569841d6498aa9c9f4b0531b9964658922"},
+ {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fd871184321100fb400d759ad0cddddf284c4b696568204d281c902fc7b0d81"},
+ {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84537453d57f55a50a5b6835622ee405816999a7113267739a1b4581f83535bd"},
+ {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3fb248989b6363906827284cd20cca63bb1a757e0a2864d4c1682a985e3dca47"},
+ {file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:42cb413e01a5d36da9929baa9d70ca90d90b969269e5a12d39c1e0d475010116"},
+ {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:aeb57c421b34af8f9fe830e1955bf493a86a7996cc1338fe41b30047d16e962c"},
+ {file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6af1c6387c531cd364b72c28daa29232162010d952ceb7e5ca8e2827526aceae"},
+ {file = "cryptography-41.0.3-cp37-abi3-win32.whl", hash = "sha256:0d09fb5356f975974dbcb595ad2d178305e5050656affb7890a1583f5e02a306"},
+ {file = "cryptography-41.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:a983e441a00a9d57a4d7c91b3116a37ae602907a7618b882c8013b5762e80574"},
+ {file = "cryptography-41.0.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5259cb659aa43005eb55a0e4ff2c825ca111a0da1814202c64d28a985d33b087"},
+ {file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:67e120e9a577c64fe1f611e53b30b3e69744e5910ff3b6e97e935aeb96005858"},
+ {file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7efe8041897fe7a50863e51b77789b657a133c75c3b094e51b5e4b5cec7bf906"},
+ {file = "cryptography-41.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce785cf81a7bdade534297ef9e490ddff800d956625020ab2ec2780a556c313e"},
+ {file = "cryptography-41.0.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:57a51b89f954f216a81c9d057bf1a24e2f36e764a1ca9a501a6964eb4a6800dd"},
+ {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c2f0d35703d61002a2bbdcf15548ebb701cfdd83cdc12471d2bae80878a4207"},
+ {file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:23c2d778cf829f7d0ae180600b17e9fceea3c2ef8b31a99e3c694cbbf3a24b84"},
+ {file = "cryptography-41.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:95dd7f261bb76948b52a5330ba5202b91a26fbac13ad0e9fc8a3ac04752058c7"},
+ {file = "cryptography-41.0.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:41d7aa7cdfded09b3d73a47f429c298e80796c8e825ddfadc84c8a7f12df212d"},
+ {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d0d651aa754ef58d75cec6edfbd21259d93810b73f6ec246436a21b7841908de"},
+ {file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ab8de0d091acbf778f74286f4989cf3d1528336af1b59f3e5d2ebca8b5fe49e1"},
+ {file = "cryptography-41.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a74fbcdb2a0d46fe00504f571a2a540532f4c188e6ccf26f1f178480117b33c4"},
+ {file = "cryptography-41.0.3.tar.gz", hash = "sha256:6d192741113ef5e30d89dcb5b956ef4e1578f304708701b8b73d38e3e1461f34"},
]
[package.dependencies]
cffi = ">=1.12"
[package.extras]
-docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"]
+docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
-pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
-sdist = ["setuptools-rust (>=0.11.4)"]
+nox = ["nox"]
+pep8test = ["black", "check-sdist", "mypy", "ruff"]
+sdist = ["build"]
ssh = ["bcrypt (>=3.1.5)"]
-test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"]
+test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
+test-randomorder = ["pytest-randomly"]
[[package]]
name = "distlib"
@@ -566,13 +574,13 @@ tests = ["dj-database-url", "dj-email-url", "django-cache-url", "pytest"]
[[package]]
name = "exceptiongroup"
-version = "1.1.2"
+version = "1.1.3"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
- {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"},
- {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"},
+ {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"},
+ {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"},
]
[package.extras]
@@ -580,24 +588,22 @@ test = ["pytest (>=6)"]
[[package]]
name = "fastapi"
-version = "0.83.0"
+version = "0.101.1"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
optional = false
-python-versions = ">=3.6.1"
+python-versions = ">=3.7"
files = [
- {file = "fastapi-0.83.0-py3-none-any.whl", hash = "sha256:694a2b6c2607a61029a4be1c6613f84d74019cb9f7a41c7a475dca8e715f9368"},
- {file = "fastapi-0.83.0.tar.gz", hash = "sha256:96eb692350fe13d7a9843c3c87a874f0d45102975257dd224903efd6c0fde3bd"},
+ {file = "fastapi-0.101.1-py3-none-any.whl", hash = "sha256:aef5f8676eb1b8389952e1fe734abe20f04b71f6936afcc53b320ba79b686a4b"},
+ {file = "fastapi-0.101.1.tar.gz", hash = "sha256:7b32000d14ca9992f7461117b81e4ef9ff0c07936af641b4fe40e67d5f9d63cb"},
]
[package.dependencies]
-pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0"
-starlette = "0.19.1"
+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.27.0,<0.28.0"
+typing-extensions = ">=4.5.0"
[package.extras]
-all = ["email_validator (>=1.1.1,<2.0.0)", "itsdangerous (>=1.1.0,<3.0.0)", "jinja2 (>=2.11.2,<4.0.0)", "orjson (>=3.2.1,<4.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "pyyaml (>=5.3.1,<7.0.0)", "requests (>=2.24.0,<3.0.0)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)", "uvicorn[standard] (>=0.12.0,<0.18.0)"]
-dev = ["autoflake (>=1.4.0,<2.0.0)", "flake8 (>=3.8.3,<6.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "pre-commit (>=2.17.0,<3.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "uvicorn[standard] (>=0.12.0,<0.18.0)"]
-doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer (>=0.4.1,<0.5.0)"]
-test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==22.3.0)", "databases[sqlite] (>=0.3.2,<0.6.0)", "email_validator (>=1.1.1,<2.0.0)", "flake8 (>=3.8.3,<6.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.14.0,<0.19.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "orjson (>=3.2.1,<4.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=6.2.4,<7.0.0)", "pytest-cov (>=2.12.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "requests (>=2.24.0,<3.0.0)", "sqlalchemy (>=1.3.18,<1.5.0)", "types-dataclasses (==0.6.5)", "types-orjson (==3.6.2)", "types-ujson (==4.2.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"]
+all = ["email-validator (>=2.0.0)", "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.5)", "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)"]
[[package]]
name = "filelock"
@@ -614,48 +620,32 @@ files = [
docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"]
-[[package]]
-name = "flake8"
-version = "6.0.0"
-description = "the modular source code checker: pep8 pyflakes and co"
-optional = false
-python-versions = ">=3.8.1"
-files = [
- {file = "flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"},
- {file = "flake8-6.0.0.tar.gz", hash = "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"},
-]
-
-[package.dependencies]
-mccabe = ">=0.7.0,<0.8.0"
-pycodestyle = ">=2.10.0,<2.11.0"
-pyflakes = ">=3.0.0,<3.1.0"
-
[[package]]
name = "h11"
-version = "0.12.0"
+version = "0.14.0"
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
files = [
- {file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"},
- {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"},
+ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
+ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
]
[[package]]
name = "httpcore"
-version = "0.15.0"
+version = "0.17.3"
description = "A minimal low-level HTTP client."
optional = false
python-versions = ">=3.7"
files = [
- {file = "httpcore-0.15.0-py3-none-any.whl", hash = "sha256:1105b8b73c025f23ff7c36468e4432226cbb959176eab66864b8e31c4ee27fa6"},
- {file = "httpcore-0.15.0.tar.gz", hash = "sha256:18b68ab86a3ccf3e7dc0f43598eaddcf472b602aba29f9aa6ab85fe2ada3980b"},
+ {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"},
+ {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"},
]
[package.dependencies]
-anyio = "==3.*"
+anyio = ">=3.0,<5.0"
certifi = "*"
-h11 = ">=0.11,<0.13"
+h11 = ">=0.13,<0.15"
sniffio = "==1.*"
[package.extras]
@@ -664,36 +654,36 @@ socks = ["socksio (==1.*)"]
[[package]]
name = "httpx"
-version = "0.23.0"
+version = "0.24.1"
description = "The next generation HTTP client."
optional = false
python-versions = ">=3.7"
files = [
- {file = "httpx-0.23.0-py3-none-any.whl", hash = "sha256:42974f577483e1e932c3cdc3cd2303e883cbfba17fe228b0f63589764d7b9c4b"},
- {file = "httpx-0.23.0.tar.gz", hash = "sha256:f28eac771ec9eb4866d3fb4ab65abd42d38c424739e80c08d8d20570de60b0ef"},
+ {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"},
+ {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"},
]
[package.dependencies]
certifi = "*"
-httpcore = ">=0.15.0,<0.16.0"
-rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]}
+httpcore = ">=0.15.0,<0.18.0"
+idna = "*"
sniffio = "*"
[package.extras]
brotli = ["brotli", "brotlicffi"]
-cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<13)"]
+cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"]
[[package]]
name = "identify"
-version = "2.5.26"
+version = "2.5.27"
description = "File identification library for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "identify-2.5.26-py2.py3-none-any.whl", hash = "sha256:c22a8ead0d4ca11f1edd6c9418c3220669b3b7533ada0a0ffa6cc0ef85cf9b54"},
- {file = "identify-2.5.26.tar.gz", hash = "sha256:7243800bce2f58404ed41b7c002e53d4d22bcf3ae1b7900c2d7aefd95394bf7f"},
+ {file = "identify-2.5.27-py2.py3-none-any.whl", hash = "sha256:fdb527b2dfe24602809b2201e033c2a113d7bdf716db3ca8e3243f735dcecaba"},
+ {file = "identify-2.5.27.tar.gz", hash = "sha256:287b75b04a0e22d727bc9a41f0d4f3c1bcada97490fa6eabb5b28f0e9097e733"},
]
[package.extras]
@@ -712,13 +702,13 @@ files = [
[[package]]
name = "importlib-metadata"
-version = "5.2.0"
+version = "6.8.0"
description = "Read metadata from Python packages"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "importlib_metadata-5.2.0-py3-none-any.whl", hash = "sha256:0eafa39ba42bf225fc00e67f701d71f85aead9f878569caf13c3724f704b970f"},
- {file = "importlib_metadata-5.2.0.tar.gz", hash = "sha256:404d48d62bba0b7a77ff9d405efd91501bef2e67ff4ace0bed40a0cf28c3c7cd"},
+ {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"},
+ {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"},
]
[package.dependencies]
@@ -727,7 +717,7 @@ zipp = ">=0.5"
[package.extras]
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
perf = ["ipython"]
-testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
+testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"]
[[package]]
name = "iniconfig"
@@ -740,32 +730,15 @@ files = [
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
]
-[[package]]
-name = "isort"
-version = "5.12.0"
-description = "A Python utility / library to sort Python imports."
-optional = false
-python-versions = ">=3.8.0"
-files = [
- {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"},
- {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"},
-]
-
-[package.extras]
-colors = ["colorama (>=0.4.3)"]
-pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"]
-plugins = ["setuptools"]
-requirements-deprecated-finder = ["pip-api", "pipreqs"]
-
[[package]]
name = "loguru"
-version = "0.6.0"
+version = "0.7.0"
description = "Python logging made (stupidly) simple"
optional = false
python-versions = ">=3.5"
files = [
- {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
- {file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
+ {file = "loguru-0.7.0-py3-none-any.whl", hash = "sha256:b93aa30099fa6860d4727f1b81f8718e965bb96253fa190fab2077aaad6d15d3"},
+ {file = "loguru-0.7.0.tar.gz", hash = "sha256:1612053ced6ae84d7959dd7d5e431a0532642237ec21f7fd83ac73fe539e03e1"},
]
[package.dependencies]
@@ -773,7 +746,7 @@ colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
[package.extras]
-dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "isort (>=5.1.1)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.9.0)"]
+dev = ["Sphinx (==5.3.0)", "colorama (==0.4.5)", "colorama (==0.4.6)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v0.990)", "pre-commit (==3.2.1)", "pytest (==6.1.2)", "pytest (==7.2.1)", "pytest-cov (==2.12.1)", "pytest-cov (==4.0.0)", "pytest-mypy-plugins (==1.10.1)", "pytest-mypy-plugins (==1.9.3)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.2.0)", "tox (==3.27.1)", "tox (==4.4.6)"]
[[package]]
name = "marshmallow"
@@ -795,17 +768,6 @@ docs = ["alabaster (==0.7.13)", "autodocsumm (==0.2.11)", "sphinx (==7.0.1)", "s
lint = ["flake8 (==6.0.0)", "flake8-bugbear (==23.7.10)", "mypy (==1.4.1)", "pre-commit (>=2.4,<4.0)"]
tests = ["pytest", "pytz", "simplejson"]
-[[package]]
-name = "mccabe"
-version = "0.7.0"
-description = "McCabe checker, plugin for flake8"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
- {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
-]
-
[[package]]
name = "mnemonic"
version = "0.20"
@@ -819,44 +781,48 @@ files = [
[[package]]
name = "mypy"
-version = "0.971"
+version = "1.5.1"
description = "Optional static typing for Python"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
files = [
- {file = "mypy-0.971-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2899a3cbd394da157194f913a931edfd4be5f274a88041c9dc2d9cdcb1c315c"},
- {file = "mypy-0.971-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:98e02d56ebe93981c41211c05adb630d1d26c14195d04d95e49cd97dbc046dc5"},
- {file = "mypy-0.971-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:19830b7dba7d5356d3e26e2427a2ec91c994cd92d983142cbd025ebe81d69cf3"},
- {file = "mypy-0.971-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02ef476f6dcb86e6f502ae39a16b93285fef97e7f1ff22932b657d1ef1f28655"},
- {file = "mypy-0.971-cp310-cp310-win_amd64.whl", hash = "sha256:25c5750ba5609a0c7550b73a33deb314ecfb559c350bb050b655505e8aed4103"},
- {file = "mypy-0.971-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d3348e7eb2eea2472db611486846742d5d52d1290576de99d59edeb7cd4a42ca"},
- {file = "mypy-0.971-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3fa7a477b9900be9b7dd4bab30a12759e5abe9586574ceb944bc29cddf8f0417"},
- {file = "mypy-0.971-cp36-cp36m-win_amd64.whl", hash = "sha256:2ad53cf9c3adc43cf3bea0a7d01a2f2e86db9fe7596dfecb4496a5dda63cbb09"},
- {file = "mypy-0.971-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:855048b6feb6dfe09d3353466004490b1872887150c5bb5caad7838b57328cc8"},
- {file = "mypy-0.971-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:23488a14a83bca6e54402c2e6435467a4138785df93ec85aeff64c6170077fb0"},
- {file = "mypy-0.971-cp37-cp37m-win_amd64.whl", hash = "sha256:4b21e5b1a70dfb972490035128f305c39bc4bc253f34e96a4adf9127cf943eb2"},
- {file = "mypy-0.971-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9796a2ba7b4b538649caa5cecd398d873f4022ed2333ffde58eaf604c4d2cb27"},
- {file = "mypy-0.971-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a361d92635ad4ada1b1b2d3630fc2f53f2127d51cf2def9db83cba32e47c856"},
- {file = "mypy-0.971-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b793b899f7cf563b1e7044a5c97361196b938e92f0a4343a5d27966a53d2ec71"},
- {file = "mypy-0.971-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d1ea5d12c8e2d266b5fb8c7a5d2e9c0219fedfeb493b7ed60cd350322384ac27"},
- {file = "mypy-0.971-cp38-cp38-win_amd64.whl", hash = "sha256:23c7ff43fff4b0df93a186581885c8512bc50fc4d4910e0f838e35d6bb6b5e58"},
- {file = "mypy-0.971-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1f7656b69974a6933e987ee8ffb951d836272d6c0f81d727f1d0e2696074d9e6"},
- {file = "mypy-0.971-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d2022bfadb7a5c2ef410d6a7c9763188afdb7f3533f22a0a32be10d571ee4bbe"},
- {file = "mypy-0.971-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef943c72a786b0f8d90fd76e9b39ce81fb7171172daf84bf43eaf937e9f220a9"},
- {file = "mypy-0.971-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d744f72eb39f69312bc6c2abf8ff6656973120e2eb3f3ec4f758ed47e414a4bf"},
- {file = "mypy-0.971-cp39-cp39-win_amd64.whl", hash = "sha256:77a514ea15d3007d33a9e2157b0ba9c267496acf12a7f2b9b9f8446337aac5b0"},
- {file = "mypy-0.971-py3-none-any.whl", hash = "sha256:0d054ef16b071149917085f51f89555a576e2618d5d9dd70bd6eea6410af3ac9"},
- {file = "mypy-0.971.tar.gz", hash = "sha256:40b0f21484238269ae6a57200c807d80debc6459d444c0489a102d7c6a75fa56"},
+ {file = "mypy-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f33592ddf9655a4894aef22d134de7393e95fcbdc2d15c1ab65828eee5c66c70"},
+ {file = "mypy-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:258b22210a4a258ccd077426c7a181d789d1121aca6db73a83f79372f5569ae0"},
+ {file = "mypy-1.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9ec1f695f0c25986e6f7f8778e5ce61659063268836a38c951200c57479cc12"},
+ {file = "mypy-1.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:abed92d9c8f08643c7d831300b739562b0a6c9fcb028d211134fc9ab20ccad5d"},
+ {file = "mypy-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a156e6390944c265eb56afa67c74c0636f10283429171018446b732f1a05af25"},
+ {file = "mypy-1.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6ac9c21bfe7bc9f7f1b6fae441746e6a106e48fc9de530dea29e8cd37a2c0cc4"},
+ {file = "mypy-1.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51cb1323064b1099e177098cb939eab2da42fea5d818d40113957ec954fc85f4"},
+ {file = "mypy-1.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:596fae69f2bfcb7305808c75c00f81fe2829b6236eadda536f00610ac5ec2243"},
+ {file = "mypy-1.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:32cb59609b0534f0bd67faebb6e022fe534bdb0e2ecab4290d683d248be1b275"},
+ {file = "mypy-1.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:159aa9acb16086b79bbb0016145034a1a05360626046a929f84579ce1666b315"},
+ {file = "mypy-1.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f6b0e77db9ff4fda74de7df13f30016a0a663928d669c9f2c057048ba44f09bb"},
+ {file = "mypy-1.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:26f71b535dfc158a71264e6dc805a9f8d2e60b67215ca0bfa26e2e1aa4d4d373"},
+ {file = "mypy-1.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc3a600f749b1008cc75e02b6fb3d4db8dbcca2d733030fe7a3b3502902f161"},
+ {file = "mypy-1.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:26fb32e4d4afa205b24bf645eddfbb36a1e17e995c5c99d6d00edb24b693406a"},
+ {file = "mypy-1.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:82cb6193de9bbb3844bab4c7cf80e6227d5225cc7625b068a06d005d861ad5f1"},
+ {file = "mypy-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4a465ea2ca12804d5b34bb056be3a29dc47aea5973b892d0417c6a10a40b2d65"},
+ {file = "mypy-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9fece120dbb041771a63eb95e4896791386fe287fefb2837258925b8326d6160"},
+ {file = "mypy-1.5.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d28ddc3e3dfeab553e743e532fb95b4e6afad51d4706dd22f28e1e5e664828d2"},
+ {file = "mypy-1.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:57b10c56016adce71fba6bc6e9fd45d8083f74361f629390c556738565af8eeb"},
+ {file = "mypy-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:ff0cedc84184115202475bbb46dd99f8dcb87fe24d5d0ddfc0fe6b8575c88d2f"},
+ {file = "mypy-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8f772942d372c8cbac575be99f9cc9d9fb3bd95c8bc2de6c01411e2c84ebca8a"},
+ {file = "mypy-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5d627124700b92b6bbaa99f27cbe615c8ea7b3402960f6372ea7d65faf376c14"},
+ {file = "mypy-1.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:361da43c4f5a96173220eb53340ace68cda81845cd88218f8862dfb0adc8cddb"},
+ {file = "mypy-1.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:330857f9507c24de5c5724235e66858f8364a0693894342485e543f5b07c8693"},
+ {file = "mypy-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:c543214ffdd422623e9fedd0869166c2f16affe4ba37463975043ef7d2ea8770"},
+ {file = "mypy-1.5.1-py3-none-any.whl", hash = "sha256:f757063a83970d67c444f6e01d9550a7402322af3557ce7630d3c957386fa8f5"},
+ {file = "mypy-1.5.1.tar.gz", hash = "sha256:b031b9601f1060bf1281feab89697324726ba0c0bae9d7cd7ab4b690940f0b92"},
]
[package.dependencies]
-mypy-extensions = ">=0.4.3"
+mypy-extensions = ">=1.0.0"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-typing-extensions = ">=3.10"
+typing-extensions = ">=4.1.0"
[package.extras]
dmypy = ["psutil (>=4.0)"]
-python2 = ["typed-ast (>=1.4.0,<2)"]
+install-types = ["pip"]
reports = ["lxml"]
[[package]]
@@ -911,29 +877,29 @@ files = [
[[package]]
name = "pathspec"
-version = "0.11.1"
+version = "0.11.2"
description = "Utility library for gitignore style pattern matching of file paths."
optional = false
python-versions = ">=3.7"
files = [
- {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"},
- {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"},
+ {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"},
+ {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"},
]
[[package]]
name = "platformdirs"
-version = "3.9.1"
+version = "3.10.0"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
optional = false
python-versions = ">=3.7"
files = [
- {file = "platformdirs-3.9.1-py3-none-any.whl", hash = "sha256:ad8291ae0ae5072f66c16945166cb11c63394c7a3ad1b1bc9828ca3162da8c2f"},
- {file = "platformdirs-3.9.1.tar.gz", hash = "sha256:1b42b450ad933e981d56e59f1b97495428c9bd60698baab9f3eb3d00d5822421"},
+ {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"},
+ {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"},
]
[package.extras]
-docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"]
+docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"]
[[package]]
name = "pluggy"
@@ -970,84 +936,71 @@ virtualenv = ">=20.10.0"
[[package]]
name = "psycopg2-binary"
-version = "2.9.6"
+version = "2.9.7"
description = "psycopg2 - Python-PostgreSQL Database Adapter"
optional = true
python-versions = ">=3.6"
files = [
- {file = "psycopg2-binary-2.9.6.tar.gz", hash = "sha256:1f64dcfb8f6e0c014c7f55e51c9759f024f70ea572fbdef123f85318c297947c"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d26e0342183c762de3276cca7a530d574d4e25121ca7d6e4a98e4f05cb8e4df7"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c48d8f2db17f27d41fb0e2ecd703ea41984ee19362cbce52c097963b3a1b4365"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffe9dc0a884a8848075e576c1de0290d85a533a9f6e9c4e564f19adf8f6e54a7"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a76e027f87753f9bd1ab5f7c9cb8c7628d1077ef927f5e2446477153a602f2c"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6460c7a99fc939b849431f1e73e013d54aa54293f30f1109019c56a0b2b2ec2f"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae102a98c547ee2288637af07393dd33f440c25e5cd79556b04e3fca13325e5f"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9972aad21f965599ed0106f65334230ce826e5ae69fda7cbd688d24fa922415e"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7a40c00dbe17c0af5bdd55aafd6ff6679f94a9be9513a4c7e071baf3d7d22a70"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:cacbdc5839bdff804dfebc058fe25684cae322987f7a38b0168bc1b2df703fb1"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f0438fa20fb6c7e202863e0d5ab02c246d35efb1d164e052f2f3bfe2b152bd0"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-win32.whl", hash = "sha256:b6c8288bb8a84b47e07013bb4850f50538aa913d487579e1921724631d02ea1b"},
- {file = "psycopg2_binary-2.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:61b047a0537bbc3afae10f134dc6393823882eb263088c271331602b672e52e9"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:964b4dfb7c1c1965ac4c1978b0f755cc4bd698e8aa2b7667c575fb5f04ebe06b"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afe64e9b8ea66866a771996f6ff14447e8082ea26e675a295ad3bdbffdd72afb"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15e2ee79e7cf29582ef770de7dab3d286431b01c3bb598f8e05e09601b890081"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa74c903a3c1f0d9b1c7e7b53ed2d929a4910e272add6700c38f365a6002820"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b83456c2d4979e08ff56180a76429263ea254c3f6552cd14ada95cff1dec9bb8"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0645376d399bfd64da57148694d78e1f431b1e1ee1054872a5713125681cf1be"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e99e34c82309dd78959ba3c1590975b5d3c862d6f279f843d47d26ff89d7d7e1"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4ea29fc3ad9d91162c52b578f211ff1c931d8a38e1f58e684c45aa470adf19e2"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4ac30da8b4f57187dbf449294d23b808f8f53cad6b1fc3623fa8a6c11d176dd0"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e78e6e2a00c223e164c417628572a90093c031ed724492c763721c2e0bc2a8df"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-win32.whl", hash = "sha256:1876843d8e31c89c399e31b97d4b9725a3575bb9c2af92038464231ec40f9edb"},
- {file = "psycopg2_binary-2.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:b4b24f75d16a89cc6b4cdff0eb6a910a966ecd476d1e73f7ce5985ff1328e9a6"},
- {file = "psycopg2_binary-2.9.6-cp36-cp36m-win32.whl", hash = "sha256:498807b927ca2510baea1b05cc91d7da4718a0f53cb766c154c417a39f1820a0"},
- {file = "psycopg2_binary-2.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0d236c2825fa656a2d98bbb0e52370a2e852e5a0ec45fc4f402977313329174d"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:34b9ccdf210cbbb1303c7c4db2905fa0319391bd5904d32689e6dd5c963d2ea8"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d2222e61f313c4848ff05353653bf5f5cf6ce34df540e4274516880d9c3763"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30637a20623e2a2eacc420059be11527f4458ef54352d870b8181a4c3020ae6b"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8122cfc7cae0da9a3077216528b8bb3629c43b25053284cc868744bfe71eb141"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38601cbbfe600362c43714482f43b7c110b20cb0f8172422c616b09b85a750c5"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c7e62ab8b332147a7593a385d4f368874d5fe4ad4e341770d4983442d89603e3"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2ab652e729ff4ad76d400df2624d223d6e265ef81bb8aa17fbd63607878ecbee"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c83a74b68270028dc8ee74d38ecfaf9c90eed23c8959fca95bd703d25b82c88e"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d4e6036decf4b72d6425d5b29bbd3e8f0ff1059cda7ac7b96d6ac5ed34ffbacd"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-win32.whl", hash = "sha256:a8c28fd40a4226b4a84bdf2d2b5b37d2c7bd49486b5adcc200e8c7ec991dfa7e"},
- {file = "psycopg2_binary-2.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:51537e3d299be0db9137b321dfb6a5022caaab275775680e0c3d281feefaca6b"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf4499e0a83b7b7edcb8dabecbd8501d0d3a5ef66457200f77bde3d210d5debb"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7e13a5a2c01151f1208d5207e42f33ba86d561b7a89fca67c700b9486a06d0e2"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e0f754d27fddcfd74006455b6e04e6705d6c31a612ec69ddc040a5468e44b4e"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d57c3fd55d9058645d26ae37d76e61156a27722097229d32a9e73ed54819982a"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:71f14375d6f73b62800530b581aed3ada394039877818b2d5f7fc77e3bb6894d"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:441cc2f8869a4f0f4bb408475e5ae0ee1f3b55b33f350406150277f7f35384fc"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:65bee1e49fa6f9cf327ce0e01c4c10f39165ee76d35c846ade7cb0ec6683e303"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:af335bac6b666cc6aea16f11d486c3b794029d9df029967f9938a4bed59b6a19"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cfec476887aa231b8548ece2e06d28edc87c1397ebd83922299af2e051cf2827"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:65c07febd1936d63bfde78948b76cd4c2a411572a44ac50719ead41947d0f26b"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-win32.whl", hash = "sha256:4dfb4be774c4436a4526d0c554af0cc2e02082c38303852a36f6456ece7b3503"},
- {file = "psycopg2_binary-2.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:02c6e3cf3439e213e4ee930308dc122d6fb4d4bea9aef4a12535fbd605d1a2fe"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9182eb20f41417ea1dd8e8f7888c4d7c6e805f8a7c98c1081778a3da2bee3e4"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8a6979cf527e2603d349a91060f428bcb135aea2be3201dff794813256c274f1"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8338a271cb71d8da40b023a35d9c1e919eba6cbd8fa20a54b748a332c355d896"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3ed340d2b858d6e6fb5083f87c09996506af483227735de6964a6100b4e6a54"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f81e65376e52f03422e1fb475c9514185669943798ed019ac50410fb4c4df232"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfb13af3c5dd3a9588000910178de17010ebcccd37b4f9794b00595e3a8ddad3"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4c727b597c6444a16e9119386b59388f8a424223302d0c06c676ec8b4bc1f963"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4d67fbdaf177da06374473ef6f7ed8cc0a9dc640b01abfe9e8a2ccb1b1402c1f"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0892ef645c2fabb0c75ec32d79f4252542d0caec1d5d949630e7d242ca4681a3"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:02c0f3757a4300cf379eb49f543fb7ac527fb00144d39246ee40e1df684ab514"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-win32.whl", hash = "sha256:c3dba7dab16709a33a847e5cd756767271697041fbe3fe97c215b1fc1f5c9848"},
- {file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"},
-]
-
-[[package]]
-name = "pycodestyle"
-version = "2.10.0"
-description = "Python style guide checker"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"},
- {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"},
+ {file = "psycopg2-binary-2.9.7.tar.gz", hash = "sha256:1b918f64a51ffe19cd2e230b3240ba481330ce1d4b7875ae67305bd1d37b041c"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ea5f8ee87f1eddc818fc04649d952c526db4426d26bab16efbe5a0c52b27d6ab"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2993ccb2b7e80844d534e55e0f12534c2871952f78e0da33c35e648bf002bbff"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbbc3c5d15ed76b0d9db7753c0db40899136ecfe97d50cbde918f630c5eb857a"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:692df8763b71d42eb8343f54091368f6f6c9cfc56dc391858cdb3c3ef1e3e584"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dcfd5d37e027ec393a303cc0a216be564b96c80ba532f3d1e0d2b5e5e4b1e6e"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17cc17a70dfb295a240db7f65b6d8153c3d81efb145d76da1e4a096e9c5c0e63"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e5666632ba2b0d9757b38fc17337d84bdf932d38563c5234f5f8c54fd01349c9"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7db7b9b701974c96a88997d458b38ccb110eba8f805d4b4f74944aac48639b42"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c82986635a16fb1fa15cd5436035c88bc65c3d5ced1cfaac7f357ee9e9deddd4"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4fe13712357d802080cfccbf8c6266a3121dc0e27e2144819029095ccf708372"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-win32.whl", hash = "sha256:122641b7fab18ef76b18860dd0c772290566b6fb30cc08e923ad73d17461dc63"},
+ {file = "psycopg2_binary-2.9.7-cp310-cp310-win_amd64.whl", hash = "sha256:f8651cf1f144f9ee0fa7d1a1df61a9184ab72962531ca99f077bbdcba3947c58"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4ecc15666f16f97709106d87284c136cdc82647e1c3f8392a672616aed3c7151"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3fbb1184c7e9d28d67671992970718c05af5f77fc88e26fd7136613c4ece1f89"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a7968fd20bd550431837656872c19575b687f3f6f98120046228e451e4064df"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:094af2e77a1976efd4956a031028774b827029729725e136514aae3cdf49b87b"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26484e913d472ecb6b45937ea55ce29c57c662066d222fb0fbdc1fab457f18c5"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f309b77a7c716e6ed9891b9b42953c3ff7d533dc548c1e33fddc73d2f5e21f9"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6d92e139ca388ccfe8c04aacc163756e55ba4c623c6ba13d5d1595ed97523e4b"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2df562bb2e4e00ee064779902d721223cfa9f8f58e7e52318c97d139cf7f012d"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4eec5d36dbcfc076caab61a2114c12094c0b7027d57e9e4387b634e8ab36fd44"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1011eeb0c51e5b9ea1016f0f45fa23aca63966a4c0afcf0340ccabe85a9f65bd"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-win32.whl", hash = "sha256:ded8e15f7550db9e75c60b3d9fcbc7737fea258a0f10032cdb7edc26c2a671fd"},
+ {file = "psycopg2_binary-2.9.7-cp311-cp311-win_amd64.whl", hash = "sha256:8a136c8aaf6615653450817a7abe0fc01e4ea720ae41dfb2823eccae4b9062a3"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2dec5a75a3a5d42b120e88e6ed3e3b37b46459202bb8e36cd67591b6e5feebc1"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc10da7e7df3380426521e8c1ed975d22df678639da2ed0ec3244c3dc2ab54c8"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee919b676da28f78f91b464fb3e12238bd7474483352a59c8a16c39dfc59f0c5"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb1c0e682138f9067a58fc3c9a9bf1c83d8e08cfbee380d858e63196466d5c86"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00d8db270afb76f48a499f7bb8fa70297e66da67288471ca873db88382850bf4"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:9b0c2b466b2f4d89ccc33784c4ebb1627989bd84a39b79092e560e937a11d4ac"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:51d1b42d44f4ffb93188f9b39e6d1c82aa758fdb8d9de65e1ddfe7a7d250d7ad"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:11abdbfc6f7f7dea4a524b5f4117369b0d757725798f1593796be6ece20266cb"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f02f4a72cc3ab2565c6d9720f0343cb840fb2dc01a2e9ecb8bc58ccf95dc5c06"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-win32.whl", hash = "sha256:81d5dd2dd9ab78d31a451e357315f201d976c131ca7d43870a0e8063b6b7a1ec"},
+ {file = "psycopg2_binary-2.9.7-cp37-cp37m-win_amd64.whl", hash = "sha256:62cb6de84d7767164a87ca97e22e5e0a134856ebcb08f21b621c6125baf61f16"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:59f7e9109a59dfa31efa022e94a244736ae401526682de504e87bd11ce870c22"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:95a7a747bdc3b010bb6a980f053233e7610276d55f3ca506afff4ad7749ab58a"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c721ee464e45ecf609ff8c0a555018764974114f671815a0a7152aedb9f3343"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4f37bbc6588d402980ffbd1f3338c871368fb4b1cfa091debe13c68bb3852b3"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac83ab05e25354dad798401babaa6daa9577462136ba215694865394840e31f8"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:024eaeb2a08c9a65cd5f94b31ace1ee3bb3f978cd4d079406aef85169ba01f08"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1c31c2606ac500dbd26381145684d87730a2fac9a62ebcfbaa2b119f8d6c19f4"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:42a62ef0e5abb55bf6ffb050eb2b0fcd767261fa3faf943a4267539168807522"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:7952807f95c8eba6a8ccb14e00bf170bb700cafcec3924d565235dffc7dc4ae8"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e02bc4f2966475a7393bd0f098e1165d470d3fa816264054359ed4f10f6914ea"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-win32.whl", hash = "sha256:fdca0511458d26cf39b827a663d7d87db6f32b93efc22442a742035728603d5f"},
+ {file = "psycopg2_binary-2.9.7-cp38-cp38-win_amd64.whl", hash = "sha256:d0b16e5bb0ab78583f0ed7ab16378a0f8a89a27256bb5560402749dbe8a164d7"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6822c9c63308d650db201ba22fe6648bd6786ca6d14fdaf273b17e15608d0852"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f94cb12150d57ea433e3e02aabd072205648e86f1d5a0a692d60242f7809b15"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5ee89587696d808c9a00876065d725d4ae606f5f7853b961cdbc348b0f7c9a1"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad5ec10b53cbb57e9a2e77b67e4e4368df56b54d6b00cc86398578f1c635f329"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:642df77484b2dcaf87d4237792246d8068653f9e0f5c025e2c692fc56b0dda70"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6a8b575ac45af1eaccbbcdcf710ab984fd50af048fe130672377f78aaff6fc1"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f955aa50d7d5220fcb6e38f69ea126eafecd812d96aeed5d5f3597f33fad43bb"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ad26d4eeaa0d722b25814cce97335ecf1b707630258f14ac4d2ed3d1d8415265"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ced63c054bdaf0298f62681d5dcae3afe60cbae332390bfb1acf0e23dcd25fc8"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2b04da24cbde33292ad34a40db9832a80ad12de26486ffeda883413c9e1b1d5e"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-win32.whl", hash = "sha256:18f12632ab516c47c1ac4841a78fddea6508a8284c7cf0f292cb1a523f2e2379"},
+ {file = "psycopg2_binary-2.9.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb3b8d55924a6058a26db69fb1d3e7e32695ff8b491835ba9f479537e14dcf9f"},
]
[[package]]
@@ -1154,17 +1107,6 @@ typing-extensions = ">=4.2.0"
dotenv = ["python-dotenv (>=0.10.4)"]
email = ["email-validator (>=1.0.3)"]
-[[package]]
-name = "pyflakes"
-version = "3.0.1"
-description = "passive checker of Python programs"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"},
- {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"},
-]
-
[[package]]
name = "pysocks"
version = "1.7.1"
@@ -1201,19 +1143,20 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no
[[package]]
name = "pytest-asyncio"
-version = "0.19.0"
+version = "0.21.1"
description = "Pytest support for asyncio"
optional = false
python-versions = ">=3.7"
files = [
- {file = "pytest-asyncio-0.19.0.tar.gz", hash = "sha256:ac4ebf3b6207259750bc32f4c1d8fcd7e79739edbc67ad0c58dd150b1d072fed"},
- {file = "pytest_asyncio-0.19.0-py3-none-any.whl", hash = "sha256:7a97e37cfe1ed296e2e84941384bdd37c376453912d397ed39293e0916f521fa"},
+ {file = "pytest-asyncio-0.21.1.tar.gz", hash = "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d"},
+ {file = "pytest_asyncio-0.21.1-py3-none-any.whl", hash = "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b"},
]
[package.dependencies]
-pytest = ">=6.1.0"
+pytest = ">=7.0.0"
[package.extras]
+docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"]
testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"]
[[package]]
@@ -1236,13 +1179,13 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale
[[package]]
name = "python-bitcoinlib"
-version = "0.11.2"
+version = "0.12.2"
description = "The Swiss Army Knife of the Bitcoin protocol."
optional = false
python-versions = "*"
files = [
- {file = "python-bitcoinlib-0.11.2.tar.gz", hash = "sha256:61ba514e0d232cc84741e49862dcedaf37199b40bba252a17edc654f63d13f39"},
- {file = "python_bitcoinlib-0.11.2-py3-none-any.whl", hash = "sha256:78bd4ee717fe805cd760dfdd08765e77b7c7dbef4627f8596285e84953756508"},
+ {file = "python-bitcoinlib-0.12.2.tar.gz", hash = "sha256:c65ab61427c77c38d397bfc431f71d86fd355b453a536496ec3fcb41bd10087d"},
+ {file = "python_bitcoinlib-0.12.2-py3-none-any.whl", hash = "sha256:2f29a9f475f21c12169b3a6cc8820f34f11362d7ff1200a5703dce3e4e903a44"},
]
[[package]]
@@ -1347,22 +1290,31 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
-name = "rfc3986"
-version = "1.5.0"
-description = "Validating URI References per RFC 3986"
+name = "ruff"
+version = "0.0.284"
+description = "An extremely fast Python linter, written in Rust."
optional = false
-python-versions = "*"
+python-versions = ">=3.7"
files = [
- {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"},
- {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"},
+ {file = "ruff-0.0.284-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:8b949084941232e2c27f8d12c78c5a6a010927d712ecff17231ee1a8371c205b"},
+ {file = "ruff-0.0.284-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:a3930d66b35e4dc96197422381dff2a4e965e9278b5533e71ae8474ef202fab0"},
+ {file = "ruff-0.0.284-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d1f7096038961d8bc3b956ee69d73826843eb5b39a5fa4ee717ed473ed69c95"},
+ {file = "ruff-0.0.284-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bcaf85907fc905d838f46490ee15f04031927bbea44c478394b0bfdeadc27362"},
+ {file = "ruff-0.0.284-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3660b85a9d84162a055f1add334623ae2d8022a84dcd605d61c30a57b436c32"},
+ {file = "ruff-0.0.284-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:0a3218458b140ea794da72b20ea09cbe13c4c1cdb7ac35e797370354628f4c05"},
+ {file = "ruff-0.0.284-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2fe880cff13fffd735387efbcad54ba0ff1272bceea07f86852a33ca71276f4"},
+ {file = "ruff-0.0.284-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1d098ea74d0ce31478765d1f8b4fbdbba2efc532397b5c5e8e5ea0c13d7e5ae"},
+ {file = "ruff-0.0.284-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c79ae3308e308b94635cd57a369d1e6f146d85019da2fbc63f55da183ee29b"},
+ {file = "ruff-0.0.284-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f86b2b1e7033c00de45cc176cf26778650fb8804073a0495aca2f674797becbb"},
+ {file = "ruff-0.0.284-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e37e086f4d623c05cd45a6fe5006e77a2b37d57773aad96b7802a6b8ecf9c910"},
+ {file = "ruff-0.0.284-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d29dfbe314e1131aa53df213fdfea7ee874dd96ea0dd1471093d93b59498384d"},
+ {file = "ruff-0.0.284-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:88295fd649d0aa1f1271441df75bf06266a199497afd239fd392abcfd75acd7e"},
+ {file = "ruff-0.0.284-py3-none-win32.whl", hash = "sha256:735cd62fccc577032a367c31f6a9de7c1eb4c01fa9a2e60775067f44f3fc3091"},
+ {file = "ruff-0.0.284-py3-none-win_amd64.whl", hash = "sha256:f67ed868d79fbcc61ad0fa034fe6eed2e8d438d32abce9c04b7c4c1464b2cf8e"},
+ {file = "ruff-0.0.284-py3-none-win_arm64.whl", hash = "sha256:1292cfc764eeec3cde35b3a31eae3f661d86418b5e220f5d5dba1c27a6eccbb6"},
+ {file = "ruff-0.0.284.tar.gz", hash = "sha256:ebd3cc55cd499d326aac17a331deaea29bea206e01c08862f9b5c6e93d77a491"},
]
-[package.dependencies]
-idna = {version = "*", optional = true, markers = "extra == \"idna2008\""}
-
-[package.extras]
-idna2008 = ["idna"]
-
[[package]]
name = "secp256k1"
version = "0.14.0"
@@ -1400,18 +1352,18 @@ cffi = ">=1.3.0"
[[package]]
name = "setuptools"
-version = "65.7.0"
+version = "68.1.2"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "setuptools-65.7.0-py3-none-any.whl", hash = "sha256:8ab4f1dbf2b4a65f7eec5ad0c620e84c34111a68d3349833494b9088212214dd"},
- {file = "setuptools-65.7.0.tar.gz", hash = "sha256:4d3c92fac8f1118bb77a22181355e29c239cabfe2b9effdaa665c66b711136d7"},
+ {file = "setuptools-68.1.2-py3-none-any.whl", hash = "sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b"},
+ {file = "setuptools-68.1.2.tar.gz", hash = "sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d"},
]
[package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
-testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5,<=7.1.2)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
+testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
@@ -1514,13 +1466,13 @@ trio = ["trio (>=0.15)"]
[[package]]
name = "starlette"
-version = "0.19.1"
+version = "0.27.0"
description = "The little ASGI library that shines."
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
files = [
- {file = "starlette-0.19.1-py3-none-any.whl", hash = "sha256:5a60c5c2d051f3a8eb546136aa0c9399773a689595e099e0877704d5888279bf"},
- {file = "starlette-0.19.1.tar.gz", hash = "sha256:c6d21096774ecb9639acad41b86b7706e52ba3bf1dc13ea4ed9ad593d47e24c7"},
+ {file = "starlette-0.27.0-py3-none-any.whl", hash = "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91"},
+ {file = "starlette-0.27.0.tar.gz", hash = "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75"},
]
[package.dependencies]
@@ -1528,7 +1480,7 @@ anyio = ">=3.4.0,<5"
typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""}
[package.extras]
-full = ["itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests"]
+full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"]
[[package]]
name = "tomli"
@@ -1541,6 +1493,31 @@ files = [
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
+[[package]]
+name = "types-requests"
+version = "2.31.0.2"
+description = "Typing stubs for requests"
+optional = false
+python-versions = "*"
+files = [
+ {file = "types-requests-2.31.0.2.tar.gz", hash = "sha256:6aa3f7faf0ea52d728bb18c0a0d1522d9bfd8c72d26ff6f61bfc3d06a411cf40"},
+ {file = "types_requests-2.31.0.2-py3-none-any.whl", hash = "sha256:56d181c85b5925cbc59f4489a57e72a8b2166f18273fd8ba7b6fe0c0b986f12a"},
+]
+
+[package.dependencies]
+types-urllib3 = "*"
+
+[[package]]
+name = "types-urllib3"
+version = "1.26.25.14"
+description = "Typing stubs for urllib3"
+optional = false
+python-versions = "*"
+files = [
+ {file = "types-urllib3-1.26.25.14.tar.gz", hash = "sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f"},
+ {file = "types_urllib3-1.26.25.14-py3-none-any.whl", hash = "sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e"},
+]
+
[[package]]
name = "typing-extensions"
version = "4.7.1"
@@ -1589,13 +1566,13 @@ standard = ["colorama (>=0.4)", "httptools (>=0.4.0)", "python-dotenv (>=0.13)",
[[package]]
name = "virtualenv"
-version = "20.24.2"
+version = "20.24.3"
description = "Virtual Python Environment builder"
optional = false
python-versions = ">=3.7"
files = [
- {file = "virtualenv-20.24.2-py3-none-any.whl", hash = "sha256:43a3052be36080548bdee0b42919c88072037d50d56c28bd3f853cbe92b953ff"},
- {file = "virtualenv-20.24.2.tar.gz", hash = "sha256:fd8a78f46f6b99a67b7ec5cf73f92357891a7b3a40fd97637c27f854aae3b9e0"},
+ {file = "virtualenv-20.24.3-py3-none-any.whl", hash = "sha256:95a6e9398b4967fbcb5fef2acec5efaf9aa4972049d9ae41f95e0972a683fd02"},
+ {file = "virtualenv-20.24.3.tar.gz", hash = "sha256:e5c3b4ce817b0b328af041506a2a299418c98747c4b1e68cb7527e74ced23efc"},
]
[package.dependencies]
@@ -1609,33 +1586,33 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess
[[package]]
name = "websocket-client"
-version = "1.6.1"
+version = "1.6.2"
description = "WebSocket client for Python with low level API options"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "websocket-client-1.6.1.tar.gz", hash = "sha256:c951af98631d24f8df89ab1019fc365f2227c0892f12fd150e935607c79dd0dd"},
- {file = "websocket_client-1.6.1-py3-none-any.whl", hash = "sha256:f1f9f2ad5291f0225a49efad77abf9e700b6fef553900623060dad6e26503b9d"},
+ {file = "websocket-client-1.6.2.tar.gz", hash = "sha256:53e95c826bf800c4c465f50093a8c4ff091c7327023b10bfaff40cf1ef170eaa"},
+ {file = "websocket_client-1.6.2-py3-none-any.whl", hash = "sha256:ce54f419dfae71f4bdba69ebe65bf7f0a93fe71bc009ad3a010aacc3eebad537"},
]
[package.extras]
-docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"]
+docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"]
optional = ["python-socks", "wsaccel"]
test = ["websockets"]
[[package]]
name = "wheel"
-version = "0.38.4"
+version = "0.41.2"
description = "A built-package format for Python"
optional = false
python-versions = ">=3.7"
files = [
- {file = "wheel-0.38.4-py3-none-any.whl", hash = "sha256:b60533f3f5d530e971d6737ca6d58681ee434818fab630c83a734bb10c083ce8"},
- {file = "wheel-0.38.4.tar.gz", hash = "sha256:965f5259b566725405b05e7cf774052044b1ed30119b5d586b2703aafe8719ac"},
+ {file = "wheel-0.41.2-py3-none-any.whl", hash = "sha256:75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8"},
+ {file = "wheel-0.41.2.tar.gz", hash = "sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985"},
]
[package.extras]
-test = ["pytest (>=3.0.0)"]
+test = ["pytest (>=6.0.0)", "setuptools (>=65)"]
[[package]]
name = "win32-setctime"
@@ -1672,4 +1649,4 @@ pgsql = ["psycopg2-binary"]
[metadata]
lock-version = "2.0"
python-versions = "^3.8.1"
-content-hash = "7bc36d84b841a4799da7a9f631d90195a569d3bf38dd5b4a7ed47a5901940d88"
+content-hash = "b801dad77ac4c6b9aca8f25c4fe4d8bab9cb998a2e12d91d9bbf69cb66bb3085"
diff --git a/pyproject.toml b/pyproject.toml
index ee79539e..f5e34b2c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,28 +9,28 @@ license = "MIT"
python = "^3.8.1"
requests = "^2.27.1"
SQLAlchemy = "^1.3.24"
-click = "^8.0.4"
+click = "^8.1.7"
pydantic = "^1.10.2"
bech32 = "^1.2.0"
-fastapi = "^0.83.0"
+fastapi = "^0.101.1"
environs = "^9.5.0"
uvicorn = "^0.18.3"
-loguru = "^0.6.0"
+loguru = "^0.7.0"
ecdsa = "^0.18.0"
bitstring = "^3.1.9"
secp256k1 = "^0.14.0"
sqlalchemy-aio = "^0.17.0"
-python-bitcoinlib = "0.11.2"
-h11 = "^0.12.0"
+python-bitcoinlib = "^0.12.2"
+h11 = "^0.14.0"
PySocks = "^1.7.1"
-cryptography = "^36.0.2"
+cryptography = "^41.0.3"
websocket-client = "^1.3.3"
pycryptodomex = "^3.16.0"
-setuptools = "^65.6.3"
-wheel = "^0.38.4"
-importlib-metadata = "^5.2.0"
-psycopg2-binary = {version = "^2.9.5", optional = true }
-httpx = "0.23.0"
+setuptools = "^68.1.2"
+wheel = "^0.41.1"
+importlib-metadata = "^6.8.0"
+psycopg2-binary = { version = "^2.9.7", optional = true }
+httpx = "^0.24.1"
bip32 = "^3.4"
mnemonic = "^0.20"
@@ -38,14 +38,14 @@ mnemonic = "^0.20"
pgsql = ["psycopg2-binary"]
[tool.poetry.group.dev.dependencies]
-mypy = "^0.971"
-black = {version = "^22.8.0", allow-prereleases = true}
-isort = "^5.10.1"
-pytest-asyncio = "^0.19.0"
+mypy = "^1.5.1"
+black = "^23.7.0"
+pytest-asyncio = "^0.21.1"
pytest-cov = "^4.0.0"
pytest = "^7.4.0"
-flake8 = "^6.0.0"
+ruff = "^0.0.284"
pre-commit = "^3.3.3"
+types-requests = "^2.31.0.2"
[build-system]
requires = ["poetry-core>=1.0.0"]
@@ -55,3 +55,62 @@ build-backend = "poetry.core.masonry.api"
mint = "cashu.mint.main:main"
cashu = "cashu.wallet.cli.cli:cli"
wallet-test = "tests.test_wallet:test"
+
+
+[tool.black]
+line-length = 88
+
+# previously experimental-string-processing = true
+# this should autoformat string properly but does not work
+preview = true
+
+
+[tool.ruff]
+# Same as Black. but black has a 10% overflow rule
+line-length = 150
+
+# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
+# (`I`) means isorting
+select = ["E", "F", "I"]
+ignore = []
+
+# Allow autofix for all enabled rules (when `--fix`) is provided.
+fixable = ["ALL"]
+unfixable = []
+
+# Exclude a variety of commonly ignored directories.
+exclude = [
+ "cashu/nostr",
+ "cashu/core/bolt11.py",
+ ".bzr",
+ ".direnv",
+ ".eggs",
+ ".git",
+ ".git-rewrite",
+ ".hg",
+ ".mypy_cache",
+ ".nox",
+ ".pants.d",
+ ".pytype",
+ ".ruff_cache",
+ ".svn",
+ ".tox",
+ ".venv",
+ "__pypackages__",
+ "_build",
+ "buck-out",
+ "build",
+ "dist",
+ "node_modules",
+ "venv",
+]
+
+# Allow unused variables when underscore-prefixed.
+dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
+
+# Assume Python 3.8
+# target-version = "py38"
+
+[tool.ruff.mccabe]
+# Unlike Flake8, default to a complexity level of 10.
+max-complexity = 10
diff --git a/requirements.txt b/requirements.txt
index 96271c72..d13ce215 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,51 +1,50 @@
-anyio==3.7.1 ; python_version >= "3.7" and python_version < "4.0"
-asn1crypto==1.5.1 ; python_version >= "3.7" and python_version < "4.0"
-attrs==23.1.0 ; python_version >= "3.7" and python_version < "4.0"
-base58==2.1.1 ; python_version >= "3.7" and python_version < "4.0"
-bech32==1.2.0 ; python_version >= "3.7" and python_version < "4.0"
-bip32==3.4 ; python_version >= "3.7" and python_version < "4.0"
-bitstring==3.1.9 ; python_version >= "3.7" and python_version < "4.0"
-certifi==2023.5.7 ; python_version >= "3.7" and python_version < "4.0"
-cffi==1.15.1 ; python_version >= "3.7" and python_version < "4.0"
-charset-normalizer==3.2.0 ; python_version >= "3.7" and python_version < "4.0"
-click==8.1.5 ; python_version >= "3.7" and python_version < "4.0"
-coincurve==18.0.0 ; python_version >= "3.7" and python_version < "4.0"
-colorama==0.4.6 ; python_version >= "3.7" and python_version < "4.0" and platform_system == "Windows" or python_version >= "3.7" and python_version < "4.0" and sys_platform == "win32"
-cryptography==36.0.2 ; python_version >= "3.7" and python_version < "4.0"
-ecdsa==0.18.0 ; python_version >= "3.7" and python_version < "4.0"
-environs==9.5.0 ; python_version >= "3.7" and python_version < "4.0"
-exceptiongroup==1.1.2 ; python_version >= "3.7" and python_version < "3.11"
-fastapi==0.83.0 ; python_version >= "3.7" and python_version < "4.0"
-h11==0.12.0 ; python_version >= "3.7" and python_version < "4.0"
-httpcore==0.15.0 ; python_version >= "3.7" and python_version < "4.0"
-httpx==0.23.0 ; python_version >= "3.7" and python_version < "4.0"
-idna==3.4 ; python_version >= "3.7" and python_version < "4.0"
-importlib-metadata==5.2.0 ; python_version >= "3.7" and python_version < "4.0"
-loguru==0.6.0 ; python_version >= "3.7" and python_version < "4.0"
-marshmallow==3.19.0 ; python_version >= "3.7" and python_version < "4.0"
-mnemonic==0.20 ; python_version >= "3.7" and python_version < "4.0"
-outcome==1.2.0 ; python_version >= "3.7" and python_version < "4.0"
-packaging==23.1 ; python_version >= "3.7" and python_version < "4.0"
-pycparser==2.21 ; python_version >= "3.7" and python_version < "4.0"
-pycryptodomex==3.18.0 ; python_version >= "3.7" and python_version < "4.0"
-pydantic==1.10.11 ; python_version >= "3.7" and python_version < "4.0"
-pysocks==1.7.1 ; python_version >= "3.7" and python_version < "4.0"
-python-bitcoinlib==0.11.2 ; python_version >= "3.7" and python_version < "4.0"
-python-dotenv==0.21.1 ; python_version >= "3.7" and python_version < "4.0"
-represent==1.6.0.post0 ; python_version >= "3.7" and python_version < "4.0"
-requests==2.31.0 ; python_version >= "3.7" and python_version < "4.0"
-rfc3986[idna2008]==1.5.0 ; python_version >= "3.7" and python_version < "4.0"
-secp256k1==0.14.0 ; python_version >= "3.7" and python_version < "4.0"
-setuptools==65.7.0 ; python_version >= "3.7" and python_version < "4.0"
-six==1.16.0 ; python_version >= "3.7" and python_version < "4.0"
-sniffio==1.3.0 ; python_version >= "3.7" and python_version < "4.0"
-sqlalchemy-aio==0.17.0 ; python_version >= "3.7" and python_version < "4.0"
-sqlalchemy==1.3.24 ; python_version >= "3.7" and python_version < "4.0"
-starlette==0.19.1 ; python_version >= "3.7" and python_version < "4.0"
-typing-extensions==4.7.1 ; python_version >= "3.7" and python_version < "4.0"
-urllib3==2.0.3 ; python_version >= "3.7" and python_version < "4.0"
-uvicorn==0.18.3 ; python_version >= "3.7" and python_version < "4.0"
-websocket-client==1.6.1 ; python_version >= "3.7" and python_version < "4.0"
-wheel==0.38.4 ; python_version >= "3.7" and python_version < "4.0"
-win32-setctime==1.1.0 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "win32"
-zipp==3.15.0 ; python_version >= "3.7" and python_version < "4.0"
+anyio==3.7.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+asn1crypto==1.5.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+attrs==23.1.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+base58==2.1.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+bech32==1.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+bip32==3.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+bitstring==3.1.9 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+certifi==2023.7.22 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+cffi==1.15.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+charset-normalizer==3.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+click==8.1.7 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+coincurve==18.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+colorama==0.4.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" and platform_system == "Windows" or python_full_version >= "3.8.1" and python_full_version < "4.0.0" and sys_platform == "win32"
+cryptography==41.0.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+ecdsa==0.18.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+environs==9.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+exceptiongroup==1.1.3 ; python_full_version >= "3.8.1" and python_version < "3.11"
+fastapi==0.101.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+h11==0.14.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+httpcore==0.17.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+httpx==0.24.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+idna==3.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+importlib-metadata==6.8.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+loguru==0.7.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+marshmallow==3.20.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+mnemonic==0.20 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+outcome==1.2.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+packaging==23.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+pycparser==2.21 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+pycryptodomex==3.18.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+pydantic==1.10.12 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+pysocks==1.7.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+python-bitcoinlib==0.12.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+python-dotenv==1.0.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+represent==1.6.0.post0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+requests==2.31.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+secp256k1==0.14.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+setuptools==68.1.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+six==1.16.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+sniffio==1.3.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+sqlalchemy-aio==0.17.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+sqlalchemy==1.3.24 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+starlette==0.27.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+typing-extensions==4.7.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+urllib3==2.0.4 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+uvicorn==0.18.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+websocket-client==1.6.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+wheel==0.41.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
+win32-setctime==1.1.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" and sys_platform == "win32"
+zipp==3.16.2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
diff --git a/tests/conftest.py b/tests/conftest.py
index a7d4c56b..1404216c 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -16,42 +16,36 @@
from cashu.mint import migrations as migrations_mint
from cashu.mint.ledger import Ledger
-SERVER_ENDPOINT = "http://localhost:3337"
+SERVER_PORT = 3337
+SERVER_ENDPOINT = f"http://localhost:{SERVER_PORT}"
+
+settings.cashu_dir = "./test_data/"
+settings.mint_host = "localhost"
+settings.mint_port = SERVER_PORT
+settings.mint_host = "0.0.0.0"
+settings.mint_listen_port = SERVER_PORT
+settings.mint_url = SERVER_ENDPOINT
+settings.lightning = False
+settings.tor = False
+settings.mint_lightning_backend = "FakeWallet"
+settings.mint_database = "./test_data/test_mint"
+settings.mint_derivation_path = "0/0/0/0"
+settings.mint_private_key = "TEST_PRIVATE_KEY"
+
+shutil.rmtree(settings.cashu_dir, ignore_errors=True)
+Path(settings.cashu_dir).mkdir(parents=True, exist_ok=True)
class UvicornServer(multiprocessing.Process):
- def __init__(self, config: Config, private_key: str = "TEST_PRIVATE_KEY"):
+ def __init__(self, config: Config):
super().__init__()
self.server = Server(config=config)
self.config = config
- self.private_key = private_key
def stop(self):
self.terminate()
def run(self, *args, **kwargs):
- settings.lightning = False
- settings.mint_lightning_backend = "FakeWallet"
- settings.mint_database = "data/test_mint"
- settings.mint_private_key = self.private_key
- settings.mint_derivation_path = "0/0/0/0"
-
- dirpath = Path(settings.mint_database)
- if dirpath.exists() and dirpath.is_dir():
- shutil.rmtree(dirpath)
-
- dirpath = Path("data/wallet1")
- if dirpath.exists() and dirpath.is_dir():
- shutil.rmtree(dirpath)
-
- dirpath = Path("data/wallet2")
- if dirpath.exists() and dirpath.is_dir():
- shutil.rmtree(dirpath)
-
- dirpath = Path("data/wallet3")
- if dirpath.exists() and dirpath.is_dir():
- shutil.rmtree(dirpath)
-
self.server.run()
@@ -62,13 +56,13 @@ async def start_mint_init(ledger: Ledger):
await ledger.load_used_proofs()
await ledger.init_keysets()
- db_file = "data/mint/test.sqlite3"
+ db_file = "test_data/mint/test.sqlite3"
if os.path.exists(db_file):
os.remove(db_file)
ledger = Ledger(
- db=Database("test", "data/mint"),
- seed="TEST_PRIVATE_KEY",
- derivation_path="0/0/0/0",
+ db=Database("test", "test_data/mint"),
+ seed=settings.mint_private_key,
+ derivation_path=settings.mint_derivation_path,
lightning=FakeWallet(),
)
await start_mint_init(ledger)
@@ -77,12 +71,10 @@ async def start_mint_init(ledger: Ledger):
@pytest.fixture(autouse=True, scope="session")
def mint():
- settings.mint_listen_port = 3337
- settings.mint_url = "http://localhost:3337"
config = uvicorn.Config(
"cashu.mint.app:app",
port=settings.mint_listen_port,
- host="127.0.0.1",
+ host=settings.mint_listen_host,
)
server = UvicornServer(config=config)
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 1521e1c0..bc1208fd 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -17,7 +17,7 @@ def cli_prefix():
async def init_wallet():
wallet = await Wallet.with_db(
url=settings.mint_host,
- db="data/test_cli_wallet",
+ db="test_data/test_cli_wallet",
name="wallet",
)
await wallet.load_proofs()
@@ -201,8 +201,9 @@ def test_receive_tokenv3(mint, cli_prefix):
def test_receive_tokenv3_no_mint(mint, cli_prefix):
- # this test works only if the previous test succeeds because we simulate the case where the mint URL is not in the token
- # therefore, we need to know the mint keyset already and have the mint URL in the db
+ # this test works only if the previous test succeeds because we simulate the case
+ # where the mint URL is not in the token therefore, we need to know the mint keyset
+ # already and have the mint URL in the db
runner = CliRunner()
token = (
"cashuAeyJ0b2tlbiI6IFt7InByb29mcyI6IFt7ImlkIjogIjFjQ05JQVoyWC93MSIsICJhbW91bnQiOiAyLCAic2VjcmV0IjogIi1oM0ZXMFFoX1FYLW9ac1V2c0RuNlEiLC"
@@ -256,9 +257,6 @@ def test_receive_tokenv1(mint, cli_prefix):
print(result.output)
-()
-
-
def test_nostr_send(mint, cli_prefix):
runner = CliRunner()
result = runner.invoke(
diff --git a/tests/test_mint.py b/tests/test_mint.py
index 1be52a19..ae9ed4a9 100644
--- a/tests/test_mint.py
+++ b/tests/test_mint.py
@@ -8,8 +8,6 @@
from cashu.core.settings import settings
from cashu.mint.ledger import Ledger
-SERVER_ENDPOINT = "http://localhost:3338"
-
async def assert_err(f, msg):
"""Compute f() and expect an error message 'msg'."""
@@ -62,7 +60,7 @@ async def test_keysets(ledger: Ledger):
@pytest.mark.asyncio
async def test_get_keyset(ledger: Ledger):
keyset = ledger.get_keyset()
- assert type(keyset) == dict
+ assert isinstance(keyset, dict)
assert len(keyset) == settings.max_order
diff --git a/tests/test_wallet.py b/tests/test_wallet.py
index c0df41bf..f4ec78b6 100644
--- a/tests/test_wallet.py
+++ b/tests/test_wallet.py
@@ -50,7 +50,7 @@ async def reset_wallet_db(wallet: Wallet):
async def wallet1(mint):
wallet1 = await Wallet1.with_db(
url=SERVER_ENDPOINT,
- db="data/wallet1",
+ db="test_data/wallet1",
name="wallet1",
)
await wallet1.load_mint()
@@ -62,7 +62,7 @@ async def wallet1(mint):
async def wallet2(mint):
wallet2 = await Wallet2.with_db(
url=SERVER_ENDPOINT,
- db="data/wallet2",
+ db="test_data/wallet2",
name="wallet2",
)
await wallet2.load_mint()
@@ -72,13 +72,13 @@ async def wallet2(mint):
@pytest_asyncio.fixture(scope="function")
async def wallet3(mint):
- dirpath = Path("data/wallet3")
+ dirpath = Path("test_data/wallet3")
if dirpath.exists() and dirpath.is_dir():
shutil.rmtree(dirpath)
wallet3 = await Wallet1.with_db(
url=SERVER_ENDPOINT,
- db="data/wallet3",
+ db="test_data/wallet3",
name="wallet3",
)
await wallet3.db.execute("DELETE FROM proofs")
@@ -93,7 +93,8 @@ async def test_get_keys(wallet1: Wallet):
assert wallet1.keys.public_keys
assert len(wallet1.keys.public_keys) == settings.max_order
keyset = await wallet1._get_keys(wallet1.url)
- assert keyset.id
+ assert keyset.id is not None
+ assert isinstance(keyset.id, str)
assert len(keyset.id) > 0
@@ -128,7 +129,7 @@ async def test_get_nonexistent_keyset(wallet1: Wallet):
@pytest.mark.asyncio
async def test_get_keyset_ids(wallet1: Wallet):
keyset = await wallet1._get_keyset_ids(wallet1.url)
- assert type(keyset) == list
+ assert isinstance(keyset, list)
assert len(keyset) > 0
assert keyset[-1] == wallet1.keyset_id
@@ -243,7 +244,7 @@ async def test_duplicate_proofs_double_spent(wallet1: Wallet):
@pytest.mark.asyncio
async def test_send_and_redeem(wallet1: Wallet, wallet2: Wallet):
await wallet1.mint(64)
- _, spendable_proofs = await wallet1.split_to_send( # type: ignore
+ _, spendable_proofs = await wallet1.split_to_send(
wallet1.proofs, 32, set_reserved=True
)
await wallet2.redeem(spendable_proofs)
@@ -324,7 +325,8 @@ async def test_token_state(wallet1: Wallet):
@pytest.mark.asyncio
async def test_bump_secret_derivation(wallet3: Wallet):
await wallet3._init_private_key(
- "half depart obvious quality work element tank gorilla view sugar picture humble"
+ "half depart obvious quality work element tank gorilla view sugar picture"
+ " humble"
)
secrets1, rs1, derivaion_paths1 = await wallet3.generate_n_secrets(5)
secrets2, rs2, derivaion_paths2 = await wallet3.generate_secrets_from_to(0, 4)
@@ -350,7 +352,8 @@ async def test_bump_secret_derivation(wallet3: Wallet):
@pytest.mark.asyncio
async def test_bump_secret_derivation_two_steps(wallet3: Wallet):
await wallet3._init_private_key(
- "half depart obvious quality work element tank gorilla view sugar picture humble"
+ "half depart obvious quality work element tank gorilla view sugar picture"
+ " humble"
)
secrets1_1, rs1_1, derivaion_paths1 = await wallet3.generate_n_secrets(2)
secrets1_2, rs1_2, derivaion_paths2 = await wallet3.generate_n_secrets(3)
@@ -364,7 +367,8 @@ async def test_bump_secret_derivation_two_steps(wallet3: Wallet):
@pytest.mark.asyncio
async def test_generate_secrets_from_to(wallet3: Wallet):
await wallet3._init_private_key(
- "half depart obvious quality work element tank gorilla view sugar picture humble"
+ "half depart obvious quality work element tank gorilla view sugar picture"
+ " humble"
)
secrets1, rs1, derivaion_paths1 = await wallet3.generate_secrets_from_to(0, 4)
assert len(secrets1) == 5
@@ -383,7 +387,7 @@ async def test_restore_wallet_after_mint(wallet3: Wallet):
await wallet3.load_proofs()
wallet3.proofs = []
assert wallet3.balance == 0
- await wallet3.restore_promises(0, 20)
+ await wallet3.restore_promises_from_to(0, 20)
assert wallet3.balance == 64
@@ -391,7 +395,8 @@ async def test_restore_wallet_after_mint(wallet3: Wallet):
async def test_restore_wallet_with_invalid_mnemonic(wallet3: Wallet):
await assert_err(
wallet3._init_private_key(
- "half depart obvious quality work element tank gorilla view sugar picture picture"
+ "half depart obvious quality work element tank gorilla view sugar picture"
+ " picture"
),
"Invalid mnemonic",
)
@@ -400,22 +405,21 @@ async def test_restore_wallet_with_invalid_mnemonic(wallet3: Wallet):
@pytest.mark.asyncio
async def test_restore_wallet_after_split_to_send(wallet3: Wallet):
await wallet3._init_private_key(
- "half depart obvious quality work element tank gorilla view sugar picture humble"
+ "half depart obvious quality work element tank gorilla view sugar picture"
+ " humble"
)
await reset_wallet_db(wallet3)
await wallet3.mint(64)
assert wallet3.balance == 64
- _, spendable_proofs = await wallet3.split_to_send( # type: ignore
- wallet3.proofs, 32, set_reserved=True
- )
+ _, spendable_proofs = await wallet3.split_to_send(wallet3.proofs, 32, set_reserved=True) # type: ignore
await reset_wallet_db(wallet3)
await wallet3.load_proofs()
wallet3.proofs = []
assert wallet3.balance == 0
- await wallet3.restore_promises(0, 100)
+ await wallet3.restore_promises_from_to(0, 100)
assert wallet3.balance == 64 * 2
await wallet3.invalidate(wallet3.proofs)
assert wallet3.balance == 64
@@ -431,9 +435,7 @@ async def test_restore_wallet_after_send_and_receive(wallet3: Wallet, wallet2: W
await wallet3.mint(64)
assert wallet3.balance == 64
- _, spendable_proofs = await wallet3.split_to_send( # type: ignore
- wallet3.proofs, 32, set_reserved=True
- )
+ _, spendable_proofs = await wallet3.split_to_send(wallet3.proofs, 32, set_reserved=True) # type: ignore
await wallet2.redeem(spendable_proofs)
@@ -441,7 +443,7 @@ async def test_restore_wallet_after_send_and_receive(wallet3: Wallet, wallet2: W
await wallet3.load_proofs(reload=True)
assert wallet3.proofs == []
assert wallet3.balance == 0
- await wallet3.restore_promises(0, 100)
+ await wallet3.restore_promises_from_to(0, 100)
assert wallet3.balance == 64 + 2 * 32
await wallet3.invalidate(wallet3.proofs)
assert wallet3.balance == 32
@@ -464,16 +466,15 @@ def add(self, proofs: List[Proof]) -> None:
@pytest.mark.asyncio
async def test_restore_wallet_after_send_and_self_receive(wallet3: Wallet):
await wallet3._init_private_key(
- "lucky broken tell exhibit shuffle tomato ethics virus rabbit spread measure text"
+ "lucky broken tell exhibit shuffle tomato ethics virus rabbit spread measure"
+ " text"
)
await reset_wallet_db(wallet3)
await wallet3.mint(64)
assert wallet3.balance == 64
- _, spendable_proofs = await wallet3.split_to_send( # type: ignore
- wallet3.proofs, 32, set_reserved=True
- )
+ _, spendable_proofs = await wallet3.split_to_send(wallet3.proofs, 32, set_reserved=True) # type: ignore
await wallet3.redeem(spendable_proofs)
@@ -481,7 +482,7 @@ async def test_restore_wallet_after_send_and_self_receive(wallet3: Wallet):
await wallet3.load_proofs(reload=True)
assert wallet3.proofs == []
assert wallet3.balance == 0
- await wallet3.restore_promises(0, 100)
+ await wallet3.restore_promises_from_to(0, 100)
assert wallet3.balance == 64 + 2 * 32 + 32
await wallet3.invalidate(wallet3.proofs)
assert wallet3.balance == 64
@@ -499,9 +500,7 @@ async def test_restore_wallet_after_send_twice(
box.add(wallet3.proofs)
assert wallet3.balance == 2
- keep_proofs, spendable_proofs = await wallet3.split_to_send( # type: ignore
- wallet3.proofs, 1, set_reserved=True
- )
+ keep_proofs, spendable_proofs = await wallet3.split_to_send(wallet3.proofs, 1, set_reserved=True) # type: ignore
box.add(wallet3.proofs)
assert wallet3.available_balance == 1
await wallet3.redeem(spendable_proofs)
@@ -513,7 +512,7 @@ async def test_restore_wallet_after_send_twice(
await wallet3.load_proofs(reload=True)
assert wallet3.proofs == []
assert wallet3.balance == 0
- await wallet3.restore_promises(0, 10)
+ await wallet3.restore_promises_from_to(0, 10)
box.add(wallet3.proofs)
assert wallet3.balance == 5
await wallet3.invalidate(wallet3.proofs)
@@ -521,9 +520,7 @@ async def test_restore_wallet_after_send_twice(
# again
- _, spendable_proofs = await wallet3.split_to_send( # type: ignore
- wallet3.proofs, 1, set_reserved=True
- )
+ _, spendable_proofs = await wallet3.split_to_send(wallet3.proofs, 1, set_reserved=True) # type: ignore
box.add(wallet3.proofs)
assert wallet3.available_balance == 1
@@ -535,7 +532,7 @@ async def test_restore_wallet_after_send_twice(
await wallet3.load_proofs(reload=True)
assert wallet3.proofs == []
assert wallet3.balance == 0
- await wallet3.restore_promises(0, 15)
+ await wallet3.restore_promises_from_to(0, 15)
box.add(wallet3.proofs)
assert wallet3.balance == 7
await wallet3.invalidate(wallet3.proofs)
@@ -556,9 +553,7 @@ async def test_restore_wallet_after_send_and_self_receive_nonquadratic_value(
box.add(wallet3.proofs)
assert wallet3.balance == 64
- keep_proofs, spendable_proofs = await wallet3.split_to_send( # type: ignore
- wallet3.proofs, 10, set_reserved=True
- )
+ keep_proofs, spendable_proofs = await wallet3.split_to_send(wallet3.proofs, 10, set_reserved=True) # type: ignore
box.add(wallet3.proofs)
assert wallet3.available_balance == 64 - 10
@@ -570,7 +565,7 @@ async def test_restore_wallet_after_send_and_self_receive_nonquadratic_value(
await wallet3.load_proofs(reload=True)
assert wallet3.proofs == []
assert wallet3.balance == 0
- await wallet3.restore_promises(0, 20)
+ await wallet3.restore_promises_from_to(0, 20)
box.add(wallet3.proofs)
assert wallet3.balance == 138
await wallet3.invalidate(wallet3.proofs)
@@ -578,9 +573,7 @@ async def test_restore_wallet_after_send_and_self_receive_nonquadratic_value(
# again
- _, spendable_proofs = await wallet3.split_to_send( # type: ignore
- wallet3.proofs, 12, set_reserved=True
- )
+ _, spendable_proofs = await wallet3.split_to_send(wallet3.proofs, 12, set_reserved=True) # type: ignore
assert wallet3.available_balance == 64 - 12
await wallet3.redeem(spendable_proofs)
@@ -590,7 +583,7 @@ async def test_restore_wallet_after_send_and_self_receive_nonquadratic_value(
await wallet3.load_proofs(reload=True)
assert wallet3.proofs == []
assert wallet3.balance == 0
- await wallet3.restore_promises(0, 50)
+ await wallet3.restore_promises_from_to(0, 50)
assert wallet3.balance == 182
await wallet3.invalidate(wallet3.proofs)
assert wallet3.balance == 64
diff --git a/tests/test_wallet_api.py b/tests/test_wallet_api.py
index bda48686..799f834c 100644
--- a/tests/test_wallet_api.py
+++ b/tests/test_wallet_api.py
@@ -12,8 +12,8 @@
async def wallet(mint):
wallet = await Wallet.with_db(
url=SERVER_ENDPOINT,
- db="data/test_wallet_api",
- name="wallet_api",
+ db="test_data/wallet",
+ name="wallet",
)
await wallet.load_mint()
wallet.status()
@@ -89,7 +89,7 @@ async def test_receive_all(wallet: Wallet):
with TestClient(app) as client:
response = client.post("/receive?all=true")
assert response.status_code == 200
- assert response.json()["initial_balance"]
+ assert response.json()["initial_balance"] == 0
assert response.json()["balance"]
@@ -100,7 +100,7 @@ async def test_burn_all(wallet: Wallet):
assert response.status_code == 200
response = client.post("/burn?all=true")
assert response.status_code == 200
- assert response.json()["balance"]
+ assert response.json()["balance"] == 0
@pytest.mark.asyncio
diff --git a/tests/test_wallet_p2pk.py b/tests/test_wallet_p2pk.py
index e92a8509..50101af9 100644
--- a/tests/test_wallet_p2pk.py
+++ b/tests/test_wallet_p2pk.py
@@ -34,7 +34,9 @@ def assert_amt(proofs: List[Proof], expected: int):
@pytest_asyncio.fixture(scope="function")
async def wallet1(mint):
- wallet1 = await Wallet1.with_db(SERVER_ENDPOINT, "data/wallet_p2pk_1", "wallet1")
+ wallet1 = await Wallet1.with_db(
+ SERVER_ENDPOINT, "test_data/wallet_p2pk_1", "wallet1"
+ )
await migrate_databases(wallet1.db, migrations)
await wallet1.load_mint()
wallet1.status()
@@ -43,7 +45,9 @@ async def wallet1(mint):
@pytest_asyncio.fixture(scope="function")
async def wallet2(mint):
- wallet2 = await Wallet2.with_db(SERVER_ENDPOINT, "data/wallet_p2pk_2", "wallet2")
+ wallet2 = await Wallet2.with_db(
+ SERVER_ENDPOINT, "test_data/wallet_p2pk_2", "wallet2"
+ )
await migrate_databases(wallet2.db, migrations)
wallet2.private_key = PrivateKey(secrets.token_bytes(32), raw=True)
await wallet2.load_mint()
@@ -95,7 +99,7 @@ async def test_p2pk_short_locktime_receive_with_wrong_private_key(
pubkey_wallet2 = await wallet2.create_p2pk_pubkey() # receiver side
# sender side
secret_lock = await wallet1.create_p2pk_lock(
- pubkey_wallet2, locktime_seconds=4
+ pubkey_wallet2, locktime_seconds=2
) # sender side
_, send_proofs = await wallet1.split_to_send(
wallet1.proofs, 8, secret_lock=secret_lock
@@ -107,7 +111,7 @@ async def test_p2pk_short_locktime_receive_with_wrong_private_key(
wallet2.redeem(send_proofs),
"Mint Error: no valid signature provided for input.",
)
- await asyncio.sleep(6)
+ await asyncio.sleep(2)
# should succeed because even with the wrong private key we
# can redeem the tokens after the locktime
await wallet2.redeem(send_proofs_copy)
@@ -122,7 +126,7 @@ async def test_p2pk_locktime_with_refund_pubkey(wallet1: Wallet, wallet2: Wallet
assert garbage_pubkey
secret_lock = await wallet1.create_p2pk_lock(
garbage_pubkey.serialize().hex(), # create lock to unspendable pubkey
- locktime_seconds=4, # locktime
+ locktime_seconds=2, # locktime
tags=Tags([["refund", pubkey_wallet2]]), # refund pubkey
) # sender side
_, send_proofs = await wallet1.split_to_send(
@@ -134,7 +138,7 @@ async def test_p2pk_locktime_with_refund_pubkey(wallet1: Wallet, wallet2: Wallet
wallet2.redeem(send_proofs),
"Mint Error: no valid signature provided for input.",
)
- await asyncio.sleep(6)
+ await asyncio.sleep(2)
# we can now redeem because of the refund locktime
await wallet2.redeem(send_proofs_copy)
@@ -150,7 +154,7 @@ async def test_p2pk_locktime_with_wrong_refund_pubkey(wallet1: Wallet, wallet2:
assert garbage_pubkey_2
secret_lock = await wallet1.create_p2pk_lock(
garbage_pubkey.serialize().hex(), # create lock to unspendable pubkey
- locktime_seconds=4, # locktime
+ locktime_seconds=2, # locktime
tags=Tags([["refund", garbage_pubkey_2.serialize().hex()]]), # refund pubkey
) # sender side
_, send_proofs = await wallet1.split_to_send(
@@ -162,7 +166,7 @@ async def test_p2pk_locktime_with_wrong_refund_pubkey(wallet1: Wallet, wallet2:
wallet2.redeem(send_proofs),
"Mint Error: no valid signature provided for input.",
)
- await asyncio.sleep(6)
+ await asyncio.sleep(2)
# we still can't redeem it because we used garbage_pubkey_2 as a refund pubkey
await assert_err(
wallet2.redeem(send_proofs_copy),
diff --git a/tests/test_wallet_p2sh.py b/tests/test_wallet_p2sh.py
index ebfe2a11..95402047 100644
--- a/tests/test_wallet_p2sh.py
+++ b/tests/test_wallet_p2sh.py
@@ -33,7 +33,9 @@ def assert_amt(proofs: List[Proof], expected: int):
@pytest_asyncio.fixture(scope="function")
async def wallet1(mint):
- wallet1 = await Wallet1.with_db(SERVER_ENDPOINT, "data/wallet_p2sh_1", "wallet1")
+ wallet1 = await Wallet1.with_db(
+ SERVER_ENDPOINT, "test_data/wallet_p2sh_1", "wallet1"
+ )
await migrate_databases(wallet1.db, migrations)
await wallet1.load_mint()
wallet1.status()
@@ -42,7 +44,9 @@ async def wallet1(mint):
@pytest_asyncio.fixture(scope="function")
async def wallet2(mint):
- wallet2 = await Wallet2.with_db(SERVER_ENDPOINT, "data/wallet_p2sh_2", "wallet2")
+ wallet2 = await Wallet2.with_db(
+ SERVER_ENDPOINT, "test_data/wallet_p2sh_2", "wallet2"
+ )
await migrate_databases(wallet2.db, migrations)
wallet2.private_key = PrivateKey(secrets.token_bytes(32), raw=True)
await wallet2.load_mint()