"""Offline client-managed registry creation (same structure as demo/setup_managed_demo).""" from __future__ import annotations import base64 import json from pathlib import Path import zkac from zkac_cli import creds def create_registry_bundle( slug: str, role_names: list[str], out_dir: Path, ) -> dict[str, str]: """ Build a new registry with admin issuer = role issuer for all listed roles. Writes admin.json, registry.json under out_dir. """ out_dir.mkdir(parents=True, exist_ok=True) admin_issuer = zkac.BbsIssuer() admin_pk = admin_issuer.public_key() admin_rid = zkac.admin_role_id() req = zkac.prepare_blind_request() sig = admin_issuer.issue_blind(req.commitment_with_proof(), admin_rid, 0) admin_cred = zkac.Credential.finalize( sig, req.member_secret(), req.prover_blind(), admin_rid, 0, admin_pk ) issuance_kp = zkac.IssuanceKeypair() role_entries = [(zkac.role_id(name), admin_pk, 1) for name in role_names] state = zkac.RegistryState.build( admin_pk, issuance_kp.public_key_bytes(), 1, b"\x00" * 32, role_entries ) state_bytes = state.serialize() state_cert = state.certify(admin_cred) registry_id = state.registry_id() admin_payload = { "slug": slug, "admin_issuer_secret_b64": base64.b64encode(admin_issuer.secret_key_bytes()).decode(), "admin_issuer_public_key_b64": base64.b64encode(admin_pk.to_bytes()).decode(), "admin_member_secret_b64": base64.b64encode(req.member_secret()).decode(), "admin_prover_blind_b64": base64.b64encode(req.prover_blind()).decode(), "admin_blind_sig_b64": base64.b64encode(sig).decode(), "issuance_secret_b64": base64.b64encode(issuance_kp.secret_bytes()).decode(), "issuance_public_key_b64": base64.b64encode(issuance_kp.public_key_bytes()).decode(), "registry_id_hex": registry_id.hex(), } creds.save_json(out_dir / "admin.json", admin_payload) reg_payload = { "slug": slug, "registry_id_hex": registry_id.hex(), "state_bytes_b64": base64.b64encode(state_bytes).decode(), "state_cert_b64": base64.b64encode(bytes(state_cert)).decode(), "admin_issuer_public_key_b64": base64.b64encode(admin_pk.to_bytes()).decode(), "issuance_public_key_b64": base64.b64encode(issuance_kp.public_key_bytes()).decode(), "roles": role_names, } creds.save_json(out_dir / "registry.json", reg_payload) return {"registry_id_hex": registry_id.hex(), "path": str(out_dir)}