Loading poolpay/fints/__main__.py +34 −13 Changes for poolpay/fints/__main__.py: 34 added lines, 13 removed lines. Original line number Diff line number Diff line import getpass import sys from pathlib import Path from typing import Annotated import minisign import typer from pyrage import encrypt as age_encrypt from pyrage import x25519 Loading @@ -11,7 +13,7 @@ from poolpay import db, paths from poolpay.model.BankAccount import BankAccount from poolpay.model.messages.UpdateBalanceMessage import UpdateBalanceMessage from poolpay.model.Transaction import Transaction from poolpay.paths import age_public_key_file from poolpay.paths import age_public_key_file, minisign_private_key_file app = typer.Typer() Loading @@ -35,6 +37,18 @@ def sync() -> None: bank_account.sync(password) def _encrypt_if_requested(content: str, encrypt: bool) -> str: if encrypt: recipient = x25519.Recipient.from_str( age_public_key_file.read_text(encoding="utf-8") ) return age_encrypt(content.encode("utf-8"), [recipient], armored=True).decode( "utf-8" ) else: return content @app.command() def export( filter_purpose: Annotated[ Loading @@ -49,11 +63,19 @@ def export( help="If the export should be encrypted with the poolpaypi age key." ), ] = False, sign: Annotated[ bool, typer.Option( help="If the export should be signed with the jakob minisign key." ), ] = False, ) -> None: """ Export all relevant transactions as messages to be applied in a running PoolPay instance via the Wire server. Produces output in JSONL format to stdout. Produces output in JSONL format or as an ASCII-armored age blob to STDOUT. If signing is requested, produces detached signature to STDERR. """ base_selection = select(Transaction) selection = ( Loading @@ -72,18 +94,17 @@ def export( for transaction in transactions ] messages_string = "\n".join(str(m) for m in messages) payload = _encrypt_if_requested("\n".join(str(m) for m in messages), encrypt) print(payload) if encrypt: recipient = x25519.Recipient.from_str( age_public_key_file.read_text(encoding="utf-8") ) encrypted = age_encrypt( messages_string.encode("utf-8"), [recipient], armored=True ) print(encrypted.decode("utf-8")) else: print(messages_string) if sign: key = minisign.SecretKey.from_file(minisign_private_key_file) # Apparently, py-minisign always needs an encrypted secret key. We don't need that, but we still need to do # something, so we encrypt the key with an empty string as password. key.decrypt("") signature = key.sign(payload.encode("utf-8")) print(bytes(signature).decode("utf-8"), file=sys.stderr) if __name__ == "__main__": Loading poolpay/paths.py +4 −0 Changes for poolpay/paths.py: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ db_file = instance_dir / "poolpay.db" socket_path = proj_dir / "wire.socket" age_public_key_file = keys_dir / "poolpaypi.age-public" age_secret_key_file = keys_dir / "private" / "poolpaypi.age-secret" minisign_public_key_file = keys_dir / "jakob.minisign-public" minisign_private_key_file = keys_dir / "private" / "jakob.minisign-private" __all__ = [ "proj_dir", Loading @@ -19,4 +21,6 @@ __all__ = [ "socket_path", "age_public_key_file", "age_secret_key_file", "minisign_public_key_file", "minisign_private_key_file", ] pyproject.toml +1 −0 Changes for pyproject.toml: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ dependencies = [ "fints>=5.0.0", "mfrc522~=0.0.7", "pi-rc522~=2.3.0", "py-minisign>=0.13.2", "pygame~=2.6.1", "pyrage>=1.3.0", "rpi-lgpio~=0.6", Loading uv.lock +130 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
poolpay/fints/__main__.py +34 −13 Changes for poolpay/fints/__main__.py: 34 added lines, 13 removed lines. Original line number Diff line number Diff line import getpass import sys from pathlib import Path from typing import Annotated import minisign import typer from pyrage import encrypt as age_encrypt from pyrage import x25519 Loading @@ -11,7 +13,7 @@ from poolpay import db, paths from poolpay.model.BankAccount import BankAccount from poolpay.model.messages.UpdateBalanceMessage import UpdateBalanceMessage from poolpay.model.Transaction import Transaction from poolpay.paths import age_public_key_file from poolpay.paths import age_public_key_file, minisign_private_key_file app = typer.Typer() Loading @@ -35,6 +37,18 @@ def sync() -> None: bank_account.sync(password) def _encrypt_if_requested(content: str, encrypt: bool) -> str: if encrypt: recipient = x25519.Recipient.from_str( age_public_key_file.read_text(encoding="utf-8") ) return age_encrypt(content.encode("utf-8"), [recipient], armored=True).decode( "utf-8" ) else: return content @app.command() def export( filter_purpose: Annotated[ Loading @@ -49,11 +63,19 @@ def export( help="If the export should be encrypted with the poolpaypi age key." ), ] = False, sign: Annotated[ bool, typer.Option( help="If the export should be signed with the jakob minisign key." ), ] = False, ) -> None: """ Export all relevant transactions as messages to be applied in a running PoolPay instance via the Wire server. Produces output in JSONL format to stdout. Produces output in JSONL format or as an ASCII-armored age blob to STDOUT. If signing is requested, produces detached signature to STDERR. """ base_selection = select(Transaction) selection = ( Loading @@ -72,18 +94,17 @@ def export( for transaction in transactions ] messages_string = "\n".join(str(m) for m in messages) payload = _encrypt_if_requested("\n".join(str(m) for m in messages), encrypt) print(payload) if encrypt: recipient = x25519.Recipient.from_str( age_public_key_file.read_text(encoding="utf-8") ) encrypted = age_encrypt( messages_string.encode("utf-8"), [recipient], armored=True ) print(encrypted.decode("utf-8")) else: print(messages_string) if sign: key = minisign.SecretKey.from_file(minisign_private_key_file) # Apparently, py-minisign always needs an encrypted secret key. We don't need that, but we still need to do # something, so we encrypt the key with an empty string as password. key.decrypt("") signature = key.sign(payload.encode("utf-8")) print(bytes(signature).decode("utf-8"), file=sys.stderr) if __name__ == "__main__": Loading
poolpay/paths.py +4 −0 Changes for poolpay/paths.py: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ db_file = instance_dir / "poolpay.db" socket_path = proj_dir / "wire.socket" age_public_key_file = keys_dir / "poolpaypi.age-public" age_secret_key_file = keys_dir / "private" / "poolpaypi.age-secret" minisign_public_key_file = keys_dir / "jakob.minisign-public" minisign_private_key_file = keys_dir / "private" / "jakob.minisign-private" __all__ = [ "proj_dir", Loading @@ -19,4 +21,6 @@ __all__ = [ "socket_path", "age_public_key_file", "age_secret_key_file", "minisign_public_key_file", "minisign_private_key_file", ]
pyproject.toml +1 −0 Changes for pyproject.toml: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ dependencies = [ "fints>=5.0.0", "mfrc522~=0.0.7", "pi-rc522~=2.3.0", "py-minisign>=0.13.2", "pygame~=2.6.1", "pyrage>=1.3.0", "rpi-lgpio~=0.6", Loading