Loading poolpay/fints/__main__.py +34 −13 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 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 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 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 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 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