chore: initialize monorepo with project scaffolding, configs, and CI setup
This commit is contained in:
78
examples/receipts-sign-verify/fetch_and_verify.py
Normal file
78
examples/receipts-sign-verify/fetch_and_verify.py
Normal file
@ -0,0 +1,78 @@
|
||||
"""Example script that fetches a job receipt from the coordinator API and verifies signatures.
|
||||
|
||||
Usage::
|
||||
|
||||
export PYTHONPATH=packages/py/aitbc-sdk/src:packages/py/aitbc-crypto/src
|
||||
python examples/receipts-sign-verify/fetch_and_verify.py --job-id <job_id> \
|
||||
--coordinator http://localhost:8011 --api-key client_dev_key_1
|
||||
|
||||
The script prints the verification results for the miner signature and any
|
||||
coordinator attestations present on the receipt payload.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from typing import Iterable
|
||||
|
||||
from aitbc_sdk import CoordinatorReceiptClient, verify_receipt
|
||||
|
||||
|
||||
def _print_attestations(attestations: Iterable[bool]) -> None:
|
||||
statuses = ["✔" if valid else "✖" for valid in attestations]
|
||||
if statuses:
|
||||
print("Coordinator attestations:", " ".join(statuses))
|
||||
else:
|
||||
print("Coordinator attestations: none")
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Fetch and verify receipts")
|
||||
parser.add_argument("--job-id", required=True, help="Job ID to fetch receipts for")
|
||||
parser.add_argument(
|
||||
"--coordinator",
|
||||
default="http://localhost:8011",
|
||||
help="Coordinator base URL (default: http://localhost:8011)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--api-key",
|
||||
default="client_dev_key_1",
|
||||
help="Client API key to authenticate against the coordinator",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--history",
|
||||
action="store_true",
|
||||
help="Fetch full receipt history instead of only the latest receipt",
|
||||
)
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
client = CoordinatorReceiptClient(args.coordinator, args.api_key)
|
||||
|
||||
if args.history:
|
||||
receipts = client.fetch_history(args.job_id)
|
||||
if not receipts:
|
||||
print("No receipts found for job", args.job_id)
|
||||
return 0
|
||||
for idx, receipt in enumerate(receipts, start=1):
|
||||
verification = verify_receipt(receipt)
|
||||
print(f"Receipt #{idx} ({verification.receipt['receipt_id']}):")
|
||||
print(" Miner signature valid:", verification.miner_signature.valid)
|
||||
_print_attestations(att.valid for att in verification.coordinator_attestations)
|
||||
return 0
|
||||
|
||||
receipt = client.fetch_latest(args.job_id)
|
||||
if receipt is None:
|
||||
print("Latest receipt not available for job", args.job_id)
|
||||
return 1
|
||||
|
||||
verification = verify_receipt(receipt)
|
||||
print("Latest receipt ID:", verification.receipt["receipt_id"])
|
||||
print("Miner signature valid:", verification.miner_signature.valid)
|
||||
_print_attestations(att.valid for att in verification.coordinator_attestations)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover - manual invocation
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user