diff --git a/cashu/core/base.py b/cashu/core/base.py
index 3860e622..b26f953e 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
@@ -161,18 +161,20 @@ class Proof(BaseModel):
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
+ ""
+ )
amount: int = 0
secret: str = "" # secret or message to be blinded and signed
C: str = "" # signature on secret, unblinded by wallet
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
+ 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
+ )
time_created: Union[None, str] = ""
time_reserved: Union[None, str] = ""
derivation_path: Union[None, str] = "" # derivation path of the proof
@@ -338,9 +340,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)
@@ -421,9 +423,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"],
@@ -489,7 +493,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/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..412cd907 100644
--- a/cashu/mint/app.py
+++ b/cashu/mint/app.py
@@ -36,11 +36,16 @@ 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: str = (
+ "{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"
+ "{time:YYYY-MM-DD HH:mm:ss.SS} | {level:"
+ " <4} |"
+ " {name}:{function}:{line}"
+ " | {message}\n"
)
else:
self.fmt: str = self.minimal_fmt
diff --git a/cashu/mint/crud.py b/cashu/mint/crud.py
index c7eaffcc..d15ab222 100644
--- a/cashu/mint/crud.py
+++ b/cashu/mint/crud.py
@@ -90,11 +90,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]
@@ -123,11 +121,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 1544c110..8f972d58 100644
--- a/cashu/mint/ledger.py
+++ b/cashu/mint/ledger.py
@@ -276,9 +276,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
@@ -310,9 +311,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
@@ -327,20 +329,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)
@@ -424,11 +430,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.")
@@ -492,7 +500,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}")
@@ -549,14 +558,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
@@ -658,7 +669,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(
@@ -1005,7 +1017,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}")
@@ -1071,7 +1084,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 0ad57cdc..44779e62 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/router.py b/cashu/wallet/api/router.py
index 7ad7e9de..3a671b6d 100644
--- a/cashu/wallet/api/router.py
+++ b/cashu/wallet/api/router.py
@@ -276,8 +276,9 @@ async def burn(
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
diff --git a/cashu/wallet/cli/cli.py b/cashu/wallet/cli/cli.py
index c3e6b377..9acf2b29 100644
--- a/cashu/wallet/cli/cli.py
+++ b/cashu/wallet/cli/cli.py
@@ -90,18 +90,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 +164,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 +216,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 +243,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 +318,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 +327,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")
@@ -386,7 +400,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."
@@ -454,8 +468,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:
@@ -527,7 +542,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")
@@ -657,7 +673,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:
@@ -741,12 +758,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 ac71118d..302298d7 100644
--- a/cashu/wallet/helpers.py
+++ b/cashu/wallet/helpers.py
@@ -195,7 +195,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 1ea1918c..3f508b71 100644
--- a/cashu/wallet/nostr.py
+++ b/cashu/wallet/nostr.py
@@ -99,8 +99,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 61cd606c..8926ffa7 100644
--- a/cashu/wallet/wallet.py
+++ b/cashu/wallet/wallet.py
@@ -702,7 +702,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
@@ -1425,7 +1426,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:
@@ -1559,7 +1561,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}")
diff --git a/tests/test_wallet.py b/tests/test_wallet.py
index a118007f..c33eee12 100644
--- a/tests/test_wallet.py
+++ b/tests/test_wallet.py
@@ -24,7 +24,9 @@ async def assert_err(f, msg: Union[str, CashuError]):
error_message: str = str(exc.args[0])
if isinstance(msg, CashuError):
if msg.detail not in error_message:
- raise Exception(f"CashuError. Expected error: {msg.detail}, got: {error_message}")
+ raise Exception(
+ f"CashuError. Expected error: {msg.detail}, got: {error_message}"
+ )
return
if msg not in error_message:
raise Exception(f"Expected error: {msg}, got: {error_message}")
@@ -183,7 +185,9 @@ async def test_split(wallet1: Wallet):
@pytest.mark.asyncio
async def test_split_to_send(wallet1: Wallet):
await wallet1.mint(64)
- keep_proofs, spendable_proofs = await wallet1.split_to_send(wallet1.proofs, 32, set_reserved=True)
+ keep_proofs, spendable_proofs = await wallet1.split_to_send(
+ wallet1.proofs, 32, set_reserved=True
+ )
get_spendable = await wallet1._select_proofs_to_send(wallet1.proofs, 32)
assert keep_proofs == get_spendable
@@ -301,7 +305,9 @@ async def test_p2sh_receive_with_wrong_wallet(wallet1: Wallet, wallet2: Wallet):
await wallet1.mint(64)
wallet1_address = await wallet1.create_p2sh_address_and_store() # receiver side
secret_lock = await wallet1.create_p2sh_lock(wallet1_address) # sender side
- _, send_proofs = await wallet1.split_to_send(wallet1.proofs, 8, secret_lock) # sender side
+ _, send_proofs = await wallet1.split_to_send(
+ wallet1.proofs, 8, secret_lock
+ ) # sender side
await assert_err(wallet2.redeem(send_proofs), "lock not found.") # wrong receiver
@@ -316,7 +322,10 @@ 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")
+ await wallet3._init_private_key(
+ "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)
assert secrets1 == secrets2
@@ -340,7 +349,10 @@ 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")
+ await wallet3._init_private_key(
+ "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)
secrets1 = secrets1_1 + secrets1_2
@@ -352,7 +364,10 @@ 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")
+ await wallet3._init_private_key(
+ "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
secrets2, rs2, derivaion_paths2 = await wallet3.generate_secrets_from_to(2, 4)
@@ -377,14 +392,20 @@ async def test_restore_wallet_after_mint(wallet3: Wallet):
@pytest.mark.asyncio
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"),
+ wallet3._init_private_key(
+ "half depart obvious quality work element tank gorilla view sugar picture"
+ " picture"
+ ),
"Invalid mnemonic",
)
@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")
+ await wallet3._init_private_key(
+ "half depart obvious quality work element tank gorilla view sugar picture"
+ " humble"
+ )
await reset_wallet_db(wallet3)
await wallet3.mint(64)
@@ -404,7 +425,9 @@ async def test_restore_wallet_after_split_to_send(wallet3: Wallet):
@pytest.mark.asyncio
async def test_restore_wallet_after_send_and_receive(wallet3: Wallet, wallet2: Wallet):
- await wallet3._init_private_key("hello rug want adapt talent together lunar method bean expose beef position")
+ await wallet3._init_private_key(
+ "hello rug want adapt talent together lunar method bean expose beef position"
+ )
await reset_wallet_db(wallet3)
await wallet3.mint(64)
@@ -440,7 +463,10 @@ 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")
+ await wallet3._init_private_key(
+ "lucky broken tell exhibit shuffle tomato ethics virus rabbit spread measure"
+ " text"
+ )
await reset_wallet_db(wallet3)
await wallet3.mint(64)
@@ -516,7 +542,9 @@ async def test_restore_wallet_after_send_and_self_receive_nonquadratic_value(
wallet3: Wallet,
):
box = ProofBox()
- await wallet3._init_private_key("casual demise flight cradle feature hub link slim remember anger front asthma")
+ await wallet3._init_private_key(
+ "casual demise flight cradle feature hub link slim remember anger front asthma"
+ )
await reset_wallet_db(wallet3)
await wallet3.mint(64)