36 lines
1.1 KiB
Python
36 lines
1.1 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import time
|
|
from typing import Any
|
|
|
|
|
|
class LedgerSigner:
|
|
def __init__(self, key: str):
|
|
self.key = key
|
|
|
|
def sign(self, message: str) -> str:
|
|
import hmac
|
|
import hashlib
|
|
return hmac.new(self.key.encode("utf-8"), message.encode("utf-8"), hashlib.sha256).hexdigest()
|
|
|
|
def verify(self, message: str, signature: str) -> bool:
|
|
return self.sign(message) == signature
|
|
|
|
|
|
def sign_and_append(plan_delta: Any, signer: LedgerSigner, log_path: str = "ledger.log") -> bool:
|
|
# Convert plan_delta to a portable dict if possible
|
|
if hasattr(plan_delta, "to_dict"):
|
|
payload = plan_delta.to_dict()
|
|
elif isinstance(plan_delta, dict):
|
|
payload = plan_delta
|
|
else:
|
|
payload = {"repr": repr(plan_delta)}
|
|
|
|
payload_str = json.dumps(payload, sort_keys=True)
|
|
signature = signer.sign(payload_str)
|
|
entry = {"timestamp": time.time(), "payload": payload, "signature": signature}
|
|
with open(log_path, "a", encoding="utf-8") as f:
|
|
f.write(json.dumps(entry) + "\n")
|
|
return True
|