async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status("#7 Provision an agent and wallet, get back configuration details") agent = AliceAgent( start_port, start_port + 1, genesis_data=genesis, timing=show_timing ) await agent.listen_webhooks(start_port + 2) with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) log_status("#9 Input faber.py invitation details") await input_invitation(agent) async for option in prompt_loop( "(3) Send Message (4) Input New Invitation (X) Exit? [3/4/X]: " ): if option is None or option in "xX": break elif option == "3": msg = await prompt("Enter message: ") if msg: await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}, ) elif option == "4": # handle new invitation log_status("Input new invitation details") await input_invitation(agent) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def input_invitation(agent): agent._connection_ready = asyncio.Future() async for details in prompt_loop("Invite details: "): b64_invite = None try: url = urlparse(details) query = url.query if query and "c_i=" in query: pos = query.index("c_i=") + 4 b64_invite = query[pos:] elif query and "oob=" in query: pos = query.index("oob=") + 4 b64_invite = query[pos:] else: b64_invite = details except ValueError: b64_invite = details if b64_invite: try: padlen = 4 - len(b64_invite) % 4 if padlen <= 2: b64_invite += "=" * padlen invite_json = base64.urlsafe_b64decode(b64_invite) details = invite_json.decode("utf-8") except binascii.Error: pass except UnicodeDecodeError: pass if details: try: details = json.loads(details) break except json.JSONDecodeError as e: log_msg("Invalid invitation:", str(e)) with log_timer("Connect duration:"): if "/out-of-band/" in details.get("@type", ""): connection = await agent.admin_POST( "/out-of-band/receive-invitation", details ) else: connection = await agent.admin_POST( "/connections/receive-invitation", details ) agent.connection_id = connection["connection_id"] log_json(connection, label="Invitation response:") await agent.detect_connection()
async def input_invitation(agent): async for details in prompt_loop("Invite details: "): if details: try: json.loads(details) break except json.JSONDecodeError as e: log_msg("Invalid JSON:", str(e)) pass with log_timer("Connect duration:"): connection = await agent.admin_POST("/connections/receive-invitation", details) agent.connection_id = connection["connection_id"] log_json(connection, label="Invitation response:") await agent.detect_connection()
async def input_invitation(agent_container): agent_container.agent._connection_ready = asyncio.Future() async for details in prompt_loop("Invite details: "): b64_invite = None try: url = urlparse(details) query = url.query if query and "c_i=" in query: pos = query.index("c_i=") + 4 b64_invite = query[pos:] elif query and "oob=" in query: pos = query.index("oob=") + 4 b64_invite = query[pos:] else: b64_invite = details except ValueError: b64_invite = details if b64_invite: try: padlen = 4 - len(b64_invite) % 4 if padlen <= 2: b64_invite += "=" * padlen invite_json = base64.urlsafe_b64decode(b64_invite) details = invite_json.decode("utf-8") except binascii.Error: pass except UnicodeDecodeError: pass if details: try: details = json.loads(details) break except json.JSONDecodeError as e: log_msg("Invalid invitation:", str(e)) with log_timer("Connect duration:"): connection = await agent_container.input_invitation(details, wait=True)
async def input_invitation(agent): async for details in prompt_loop("Invite details: "): b64_invite = None try: url = urlparse(details) query = url.query if query and "c_i=" in query: pos = query.index("c_i=") + 4 b64_invite = query[pos:] else: b64_invite = details except ValueError: b64_invite = details if b64_invite: try: invite_json = base64.urlsafe_b64decode(b64_invite) details = invite_json.decode("utf-8") except binascii.Error: pass except UnicodeDecodeError: pass if details: try: json.loads(details) break except json.JSONDecodeError as e: log_msg("Invalid invitation:", str(e)) with log_timer("Connect duration:"): connection = await agent.admin_POST("/connections/receive-invitation", details) agent.connection_id = connection["connection_id"] log_json(connection, label="Invitation response:") await agent.detect_connection()
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = EAPAgent(start_port, start_port + 1, genesis_data=genesis, timing=show_timing) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) # Create a schema with log_timer("Publish schema/cred def duration:"): log_status("#3/4 Create a new schema/cred def on the ledger") version = format("%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), )) ( _, # schema id credential_definition_id, ) = await agent.register_schema_and_creddef( "degree schema", version, ["name", "date", "degree", "average"]) # TODO add an additional credential for Student ID async for option in prompt_loop( "(1) Issue Credential, (2) Send Proof Request, " + "(3) Send Message (X) Exit? [1/2/3/X] "): if option is None or option in "xX": break elif option == "1": log_status("#13 Issue credential offer to X") # TODO define attributes to send for credential agent.cred_attrs[credential_definition_id] = { "name": "Alice Smith", "date": "2018-05-28", "degree": "Maths", "age": "24", } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [{ "name": n, "value": v } for (n, v) in agent.cred_attrs[credential_definition_id].items()], } offer_request = { "connection_id": agent.connection_id, "cred_def_id": credential_definition_id, "comment": f"Offer on cred def id {credential_definition_id}", "credential_preview": cred_preview, } await agent.admin_POST("/issue-credential/send-offer", offer_request) # TODO issue an additional credential for Student ID elif option == "2": log_status("#20 Request proof of degree from alice") req_attrs = [ { "name": "name", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "date", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "degree", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "self_attested_thing" }, ] req_preds = [{ "name": "age", "p_type": ">=", "p_value": 18, "restrictions": [{ "issuer_did": agent.did }], }] indy_proof_request = { "name": "Proof of Education", "version": "1.0", "nonce": str(uuid4().int), "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": { f"0_{req_pred['name']}_GE_uuid": req_pred for req_pred in req_preds }, } proof_request_web_request = { "connection_id": agent.connection_id, "proof_request": indy_proof_request, } await agent.admin_POST("/present-proof/send-request", proof_request_web_request) elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = NhsheadofficeAgent(start_port, start_port + 1, genesis_data=genesis, timing=show_timing) await agent.listen_webhooks(start_port + 2) await agent.register_did() log_msg("HEAD OFFICE DID: ", agent.did) with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) # Create a schema with log_timer("Publish schema/cred def duration:"): log_status("#3/4 Create a new schema/cred def on the ledger") version = format("%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), )) ( _, # schema id credential_definition_id, ) = await agent.register_schema_and_creddef( "Verified Hospital schema", version, ["date", "hospital_name"]) # TODO add an additional credential for Student ID with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to Hospital and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.active_connection_id = connection["connection_id"] agent.connection_list.append(connection["connection_id"]) log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") log_msg("Waiting for connection...") await agent.detect_connection() async for option in prompt_loop( "(1) Request Hospital name, (2) Issue Verified Hospital Credential, (3) Create a New Invitation, (X) Exit? [1/2/X] " ): if option is None or option in "xX": break elif option == "1": log_status("#20 Request Self Attested Hospital Name") req_attrs = [{"name": "name"}] indy_proof_request = { "name": "Proof of Hospital Name", "version": "1.0", "nonce": str(uuid4().int), "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": {}, } proof_request_web_request = { "connection_id": agent.active_connection_id, "proof_request": indy_proof_request, } await agent.admin_POST("/present-proof/send-request", proof_request_web_request) elif option == "2": log_status("#13 Issue Verified Hospital credential offer to X") today = date.today() # TODO define attributes to send for credential agent.cred_attrs[credential_definition_id] = { "hospital_name": agent.current_hospital_name, "date": str(today), # "degree": "Health", # "age": "24", } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [{ "name": n, "value": v } for (n, v) in agent.cred_attrs[credential_definition_id].items()], } offer_request = { "connection_id": agent.active_connection_id, "credential_definition_id": credential_definition_id, "comment": f"Offer on cred def id {credential_definition_id}", "credential_preview": cred_preview, } await agent.admin_POST("/issue-credential/send-offer", offer_request) # elif option == "3": # msg = await prompt("Enter message: ") # await agent.admin_POST( # f"/connections/{agent.active_connection_id}/send-message", {"content": msg} # ) elif option == "3": # handle new invitation with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.active_connection_id = connection["connection_id"] agent.connection_list.append(connection["connection_id"]) log_msg("all connections :", agent.connection_list) log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") agent._connection_ready = asyncio.Future() log_msg("Waiting for connection...") await agent.detect_connection() if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(args): alice_agent = await create_agent_with_args(args, ident="alice") try: log_status( "#7 Provision an agent and wallet, get back configuration details" + (f" (Wallet type: {alice_agent.wallet_type})" if alice_agent. wallet_type else "")) agent = AliceAgent( "alice.agent", alice_agent.start_port, alice_agent.start_port + 1, genesis_data=alice_agent.genesis_txns, no_auto=alice_agent.no_auto, timing=alice_agent.show_timing, multitenant=alice_agent.multitenant, mediation=alice_agent.mediation, wallet_type=alice_agent.wallet_type, ) await alice_agent.initialize(the_agent=agent) log_status("#9 Input faber.py invitation details") await input_invitation(alice_agent) options = " (3) Send Message\n" " (4) Input New Invitation\n" if alice_agent.multitenant: options += " (W) Create and/or Enable Wallet\n" options += " (X) Exit?\n[3/4/{}X] ".format( "W/" if alice_agent.multitenant else "", ) async for option in prompt_loop(options): if option is not None: option = option.strip() if option is None or option in "xX": break elif option in "wW" and alice_agent.multitenant: target_wallet_name = await prompt("Enter wallet name: ") include_subwallet_webhook = await prompt( "(Y/N) Create sub-wallet webhook target: ") if include_subwallet_webhook.lower() == "y": await alice_agent.agent.register_or_switch_wallet( target_wallet_name, webhook_port=alice_agent.agent.get_new_webhook_port(), mediator_agent=alice_agent.mediator_agent, ) else: await alice_agent.agent.register_or_switch_wallet( target_wallet_name, mediator_agent=alice_agent.mediator_agent, ) elif option == "3": msg = await prompt("Enter message: ") if msg: await alice_agent.agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}, ) elif option == "4": # handle new invitation log_status("Input new invitation details") await input_invitation(alice_agent) if alice_agent.show_timing: timing = await alice_agent.agent.fetch_timing() if timing: for line in alice_agent.agent.format_timing(timing): log_msg(line) finally: terminated = await alice_agent.terminate() await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = AcmeAgent(start_port, start_port + 1, genesis_data=genesis, timing=show_timing) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin URL is at:", agent.admin_url) log_msg("Endpoint URL is at:", agent.endpoint) # Create a schema log_status("#3 Create a new schema on the ledger") with log_timer("Publish schema and cred def duration:"): pass # TODO define schema # version = format( # "%d.%d.%d" # % ( # random.randint(1, 101), # random.randint(1, 101), # random.randint(1, 101), # ) # ) # (schema_id, cred_def_id) = await agent.register_schema_and_creddef( # "employee id schema", # version, # ["employee_id", "name", "date", "position"], # support_revocation=False, # revocation_registry_size=TAILS_FILE_COUNT, # ) with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) invi_msg = await agent.admin_POST( "/out-of-band/create-invitation", {"handshake_protocols": ["rfc23"]}, ) log_msg(json.dumps(invi_msg["invitation"]), label="Invitation Data:", color=None) log_msg("*****************") log_msg("Waiting for connection...") await agent.detect_connection() async for option in prompt_loop( "(1) Issue Credential, (2) Send Proof Request, " + "(3) Send Message (X) Exit? [1/2/3/X] "): option = option.strip() if option in "xX": break elif option == "1": log_status("#13 Issue credential offer to X") # TODO credential offers elif option == "2": log_status("#20 Request proof of degree from alice") # TODO presentation requests elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#7 Provision an agent and wallet, get back configuration details") agent = Hospital1Agent(start_port, start_port + 1, genesis_data=genesis, timing=show_timing) await agent.listen_webhooks(start_port + 2) with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) log_status("#9 Input the invitation details") await input_invitation(agent) async for option in prompt_loop( "(3) Send Message (4) Input New Invitation (5) Send Proof Request to the Issuer (X) Exit? [3/4/5/X]: " ): if option is None or option in "xX": break elif option == "3": msg = await prompt("Enter message: ") if msg: await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}, ) elif option == "4": # handle new invitation log_status("Input new invitation details") await input_invitation(agent) elif option == "5": log_status("#20 Request proof of Research Certification") req_attrs = [ { "name": "date", "restrictions": [{ "issuer_did": agent.regulator_did }] }, { "name": "institution", "restrictions": [{ "issuer_did": agent.regulator_did }] }, ] indy_proof_request = { "name": "Proof of Verified Research Institution", "version": "1.0", "nonce": str(uuid4().int), "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": {}, } print("Asking for this proof: ", indy_proof_request) proof_request_web_request = { "connection_id": agent.connection_id, "proof_request": indy_proof_request, } await agent.admin_POST("/present-proof/send-request", proof_request_web_request) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main( start_port: int, no_auto: bool = False, show_timing: bool = False, multitenant: bool = False, mediation: bool = False, wallet_type: str = None, ): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None mediator_agent = None try: log_status( "#7 Provision an agent and wallet, get back configuration details" + (f" (Wallet type: {wallet_type})" if wallet_type else "")) agent = AliceAgent( "Alice.Agent", start_port, start_port + 1, genesis_data=genesis, no_auto=no_auto, timing=show_timing, multitenant=multitenant, mediation=mediation, wallet_type=wallet_type, ) await agent.listen_webhooks(start_port + 2) with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin URL is at:", agent.admin_url) log_msg("Endpoint URL is at:", agent.endpoint) if mediation: mediator_agent = await start_mediator_agent( start_port + 4, genesis) if not mediator_agent: raise Exception("Mediator agent returns None :-(") else: mediator_agent = None if multitenant: # create an initial managed sub-wallet (also mediated) await agent.register_or_switch_wallet( "Alice.initial", webhook_port=agent.get_new_webhook_port(), mediator_agent=mediator_agent, ) elif mediation: # we need to pre-connect the agent to its mediator if not await connect_wallet_to_mediator(agent, mediator_agent): log_msg("Mediation setup FAILED :-(") raise Exception("Mediation setup FAILED :-(") log_status("#9 Input faber.py invitation details") await input_invitation(agent) options = " (3) Send Message\n" " (4) Input New Invitation\n" if multitenant: options += " (W) Create and/or Enable Wallet\n" options += " (X) Exit?\n[3/4/{}X] ".format( "W/" if multitenant else "", ) async for option in prompt_loop(options): if option is not None: option = option.strip() if option is None or option in "xX": break elif option in "wW" and multitenant: target_wallet_name = await prompt("Enter wallet name: ") include_subwallet_webhook = await prompt( "(Y/N) Create sub-wallet webhook target: ") if include_subwallet_webhook.lower() == "y": await agent.register_or_switch_wallet( target_wallet_name, webhook_port=agent.get_new_webhook_port(), mediator_agent=mediator_agent, ) else: await agent.register_or_switch_wallet( target_wallet_name, mediator_agent=mediator_agent, ) elif option == "3": msg = await prompt("Enter message: ") if msg: await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}, ) elif option == "4": # handle new invitation log_status("Input new invitation details") await input_invitation(agent) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if mediator_agent: log_msg("Shutting down mediator agent ...") await mediator_agent.terminate() if agent: log_msg("Shutting down alice agent ...") await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = FaberAgent(start_port, start_port + 1, genesis_data=genesis, timing=show_timing) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) # Create a schema with log_timer("Publish schema/cred def duration:"): log_status("#3/4 Create a new schema/cred def on the ledger") version = format("%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), )) ( schema_id, credential_definition_id, ) = await agent.register_schema_and_creddef( "degree schema", version, ["name", "date", "degree", "age"]) # TODO add an additional credential for Student ID with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.connection_id = connection["connection_id"] log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") log_msg("Waiting for connection...") await agent.detect_connection() async for option in prompt_loop( "(1) Issue Credential, (2) Send Proof Request, " + "(3) Send Message (X) Exit? [1/2/3/X] "): if option is None or option in "xX": break elif option == "1": log_status("#13 Issue credential offer to X") offer = { "credential_definition_id": credential_definition_id, "connection_id": agent.connection_id, } # TODO define attributes to send for credential agent.cred_attrs[credential_definition_id] = { "name": "Alice Smith", "date": "2018-05-28", "degree": "Maths", "age": "24", } await agent.admin_POST("/credential_exchange/send-offer", offer) # TODO issue an additional credential for Student ID elif option == "2": log_status("#20 Request proof of degree from alice") proof_attrs = [ { "name": "name", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "date", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "degree", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "self_attested_thing" }, ] proof_predicates = [{ "name": "age", "p_type": ">=", "p_value": 18 }] proof_request = { "name": "Proof of Education", "version": "1.0", "connection_id": agent.connection_id, "requested_attributes": proof_attrs, "requested_predicates": proof_predicates, } await agent.admin_POST("/presentation_exchange/send_request", proof_request) elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, no_auto: bool = False, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = FaberAgent( start_port, start_port + 1, genesis_data=genesis, no_auto=no_auto, timing=show_timing, ) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) # Create a schema with log_timer("Publish schema/cred def duration:"): log_status("#3/4 Create a new schema/cred def on the ledger") version = format("%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), )) ( _, # schema id credential_definition_id, ) = await agent.register_schema_and_creddef( "ethereum_identity", version, ["name", "address"]) # TODO add an additional credential for Student ID with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.connection_id = connection["connection_id"] log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") log_msg("Waiting for connection...") await agent.detect_connection() async for option in prompt_loop( "(1) Issue Credential, (2) Send Proof Request, " + "(3) Send Message (X) Exit? [1/2/3/X] "): if option is None or option in "xX": break elif option == "1": log_status("#13 Issue credential offer to X") # TODO define attributes to send for credential agent.cred_attrs[credential_definition_id] = { "name": "Kai Jun Eer", "address": "0xEDB4400a8b1DEccc6C62DFDDBD6F73E48537012A" } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [{ "name": n, "value": v } for (n, v) in agent.cred_attrs[credential_definition_id].items()], } offer_request = { "connection_id": agent.connection_id, "cred_def_id": credential_definition_id, "comment": f"Offer on cred def id {credential_definition_id}", "credential_preview": cred_preview, } await agent.admin_POST("/issue-credential/send-offer", offer_request) # TODO issue an additional credential for Student ID elif option == "2": log_status("#20 Request proof of degree from alice") req_attrs = [ { "name": "name", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "address", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "self_attested_thing" }, ] req_preds = [{ "name": "age", "p_type": ">=", "p_value": 18, "restrictions": [{ "issuer_did": agent.did }], }] indy_proof_request = { "name": "Proof of Ethereum Identity", "version": "1.0", "nonce": str(uuid4().int), "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, } proof_request_web_request = { "connection_id": agent.connection_id, "proof_request": indy_proof_request, } await agent.admin_POST("/present-proof/send-request", proof_request_web_request) elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = CoordinatorAgent(start_port, start_port + 1, genesis_data=genesis, timing=show_timing) await agent.listen_webhooks(start_port + 2) with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.active_connection_id = connection["connection_id"] agent.connection_list.append(connection["connection_id"]) log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") # log_msg("Waiting for connection...") # await agent.detect_connection() async for option in prompt_loop( "(1) Send Proof Request, " + "(2) Send Message (3) New Connection (4) Input New Invitation Details (X) Exit? [1/2/3/4/X] " ): if option is None or option in "xX": break elif option == "1": log_status("#20 Request proof of degree from alice") req_attrs = [ { "name": "date", "restrictions": [{ "issuer_did": agent.nhsheadoffice_did }] }, { "name": "hospital_name", "restrictions": [{ "issuer_did": agent.nhsheadoffice_did }] }, ] # req_preds = [ # { # "name": "age", # "p_type": ">=", # "p_value": 18, # "restrictions": [{"issuer_did": agent.did}], # } # ] indy_proof_request = { "name": "Proof of Verified Hospital", "version": "1.0", "nonce": str(uuid4().int), "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": {}, } print("Asking for this proof: ", indy_proof_request) proof_request_web_request = { "connection_id": agent.active_connection_id, "proof_request": indy_proof_request, } await agent.admin_POST("/present-proof/send-request", proof_request_web_request) elif option == "2": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.active_connection_id}/send-message", {"content": msg}) elif option == "3": # handle new invitation with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.active_connection_id = connection["connection_id"] agent.connection_list.append(connection["connection_id"]) log_msg("all connections :", agent.connection_list) log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") agent._connection_ready = asyncio.Future() log_msg("Waiting for connection...") await agent.detect_connection() elif option == "4": # handle new invitation log_status("Input new invitation details") await input_invitation(agent) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(args): faber_agent = await create_agent_with_args(args, ident="faber") try: log_status( "#1 Provision an agent and wallet, get back configuration details" + (f" (Wallet type: {faber_agent.wallet_type})" if faber_agent. wallet_type else "")) agent = FaberAgent( "faber.agent", faber_agent.start_port, faber_agent.start_port + 1, genesis_data=faber_agent.genesis_txns, no_auto=faber_agent.no_auto, tails_server_base_url=faber_agent.tails_server_base_url, timing=faber_agent.show_timing, multitenant=faber_agent.multitenant, mediation=faber_agent.mediation, wallet_type=faber_agent.wallet_type, ) faber_agent.public_did = True faber_schema_name = "degree schema" faber_schema_attrs = ["name", "date", "degree", "age", "timestamp"] await faber_agent.initialize( the_agent=agent, schema_name=faber_schema_name, schema_attrs=faber_schema_attrs, ) # generate an invitation for Alice await faber_agent.generate_invitation(display_qr=True, wait=True) exchange_tracing = False options = (" (1) Issue Credential\n" " (2) Send Proof Request\n" " (3) Send Message\n" " (4) Create New Invitation\n") if faber_agent.revocation: options += " (5) Revoke Credential\n" " (6) Publish Revocations\n" if faber_agent.multitenant: options += " (W) Create and/or Enable Wallet\n" options += " (T) Toggle tracing on credential/proof exchange\n" options += " (X) Exit?\n[1/2/3/4/{}{}T/X] ".format( "5/6/" if faber_agent.revocation else "", "W/" if faber_agent.multitenant else "", ) async for option in prompt_loop(options): if option is not None: option = option.strip() if option is None or option in "xX": break elif option in "wW" and faber_agent.multitenant: target_wallet_name = await prompt("Enter wallet name: ") include_subwallet_webhook = await prompt( "(Y/N) Create sub-wallet webhook target: ") if include_subwallet_webhook.lower() == "y": created = await faber_agent.agent.register_or_switch_wallet( target_wallet_name, webhook_port=faber_agent.agent.get_new_webhook_port(), public_did=True, mediator_agent=faber_agent.mediator_agent, ) else: created = await faber_agent.agent.register_or_switch_wallet( target_wallet_name, public_did=True, mediator_agent=faber_agent.mediator_agent, ) # create a schema and cred def for the new wallet # TODO check first in case we are switching between existing wallets if created: # TODO this fails because the new wallet doesn't get a public DID await faber_agent.create_schema_and_cred_def( schema_name=faber_schema_name, schema_attrs=faber_schema_attrs, ) elif option in "tT": exchange_tracing = not exchange_tracing log_msg(">>> Credential/Proof Exchange Tracing is {}".format( "ON" if exchange_tracing else "OFF")) elif option == "1": log_status("#13 Issue credential offer to X") # TODO define attributes to send for credential faber_agent.agent.cred_attrs[faber_agent.cred_def_id] = { "name": "Alice Smith", "date": "2018-05-28", "degree": "Maths", "age": "24", "timestamp": str(int(time.time())), } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [{ "name": n, "value": v } for (n, v) in faber_agent.agent.cred_attrs[ faber_agent.cred_def_id].items()], } offer_request = { "connection_id": faber_agent.agent.connection_id, "comment": f"Offer on cred def id {faber_agent.cred_def_id}", "auto_remove": False, "credential_preview": cred_preview, "filter": { "indy": { "cred_def_id": faber_agent.cred_def_id } }, "trace": exchange_tracing, } await faber_agent.agent.admin_POST( "/issue-credential-2.0/send-offer", offer_request) # TODO issue an additional credential for Student ID elif option == "2": log_status("#20 Request proof of degree from alice") req_attrs = [ { "name": "name", "restrictions": [{ "schema_name": faber_schema_name }], }, { "name": "date", "restrictions": [{ "schema_name": faber_schema_name }], }, ] if faber_agent.revocation: req_attrs.append( { "name": "degree", "restrictions": [{ "schema_name": faber_schema_name }], "non_revoked": { "to": int(time.time() - 1) }, }, ) else: req_attrs.append({ "name": "degree", "restrictions": [{ "schema_name": faber_schema_name }], }) if SELF_ATTESTED: # test self-attested claims req_attrs.append({"name": "self_attested_thing"}, ) req_preds = [ # test zero-knowledge proofs { "name": "age", "p_type": ">=", "p_value": 18, "restrictions": [{ "schema_name": faber_schema_name }], } ] indy_proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": { f"0_{req_pred['name']}_GE_uuid": req_pred for req_pred in req_preds }, } if faber_agent.revocation: indy_proof_request["non_revoked"] = { "to": int(time.time()) } proof_request_web_request = { "connection_id": faber_agent.agent.connection_id, "proof_request": indy_proof_request, "trace": exchange_tracing, } await faber_agent.agent.admin_POST( "/present-proof/send-request", proof_request_web_request) elif option == "3": msg = await prompt("Enter message: ") await faber_agent.agent.admin_POST( f"/connections/{faber_agent.agent.connection_id}/send-message", {"content": msg}, ) elif option == "4": log_msg("Creating a new invitation, please receive " "and accept this invitation using Alice agent") await faber_agent.generate_invitation(display_qr=True, wait=True) elif option == "5" and faber_agent.revocation: rev_reg_id = ( await prompt("Enter revocation registry ID: ")).strip() cred_rev_id = ( await prompt("Enter credential revocation ID: ")).strip() publish = (await prompt("Publish now? [Y/N]: ", default="N")).strip() in "yY" try: await faber_agent.agent.admin_POST( "/revocation/revoke", { "rev_reg_id": rev_reg_id, "cred_rev_id": cred_rev_id, "publish": publish, }, ) except ClientError: pass elif option == "6" and faber_agent.revocation: try: resp = await faber_agent.agent.admin_POST( "/revocation/publish-revocations", {}) faber_agent.agent.log( "Published revocations for {} revocation registr{} {}". format( len(resp["rrid2crid"]), "y" if len(resp["rrid2crid"]) == 1 else "ies", json.dumps([k for k in resp["rrid2crid"]], indent=4), )) except ClientError: pass if faber_agent.show_timing: timing = await faber_agent.agent.fetch_timing() if timing: for line in faber_agent.agent.format_timing(timing): log_msg(line) finally: terminated = await faber_agent.terminate() await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main( start_port: int, no_auto: bool = False, revocation: bool = False, show_timing: bool = False, ): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = FaberAgent( start_port, start_port + 1, genesis_data=genesis, no_auto=no_auto, timing=show_timing, ) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin URL is at:", agent.admin_url) log_msg("Endpoint URL is at:", agent.endpoint) # Create a schema with log_timer("Publish schema/cred def duration:"): log_status("#3/4 Create a new schema/cred def on the ledger") version = format("%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), )) ( _, # schema id credential_definition_id, ) = await agent.register_schema_and_creddef( "degree schema", version, ["name", "date", "degree", "age", "timestamp"], support_revocation=revocation, ) if revocation: with log_timer("Publish revocation registry duration:"): log_status( "#5/6 Create and publish the revocation registry on the ledger" ) await agent.create_and_publish_revocation_registry( credential_definition_id, TAILS_FILE_COUNT) # TODO add an additional credential for Student ID with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#7 Create a connection to Thapelo and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.connection_id = connection["connection_id"] qr = QRCode() qr.add_data(connection["invitation_url"]) log_msg( "Use the following JSON to accept the invite from another demo agent. Or use the QR code to connect from a mobile agent." ) log_msg(json.dumps(connection["invitation"]), label="Invitation Data:", color=None) qr.print_ascii(invert=True) log_msg("Waiting for connection...") await agent.detect_connection() exchange_tracing = False options = (" (1) Issue Credential\n" " (2) Send Proof Request\n" " (3) Send Message\n") if revocation: options += (" (4) Revoke Credential\n" " (5) Publish Revocations\n" " (6) Add Revocation Registry\n") options += " (T) Toggle tracing on credential/proof exchange\n" options += " (X) Exit?\n[1/2/3/{}T/X] ".format( "4/5/6/" if revocation else "") async for option in prompt_loop(options): option = option.strip() if option is None or option in "xX": break elif option in "tT": exchange_tracing = not exchange_tracing log_msg(">>> Credential/Proof Exchange Tracing is {}".format( "ON" if exchange_tracing else "OFF")) elif option == "1": log_status("#13 Issue credential offer to X") # TODO define attributes to send for credential agent.cred_attrs[credential_definition_id] = { "name": "Thapelo Sekwena", "date": "2020-06-01", "degree": "MBA", "age": "26", "timestamp": str(int(time.time())), } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [{ "name": n, "value": v } for (n, v) in agent.cred_attrs[credential_definition_id].items()], } offer_request = { "connection_id": agent.connection_id, "cred_def_id": credential_definition_id, "comment": f"Offer on cred def id {credential_definition_id}", "auto_remove": False, "credential_preview": cred_preview, "trace": exchange_tracing, } await agent.admin_POST("/issue-credential/send-offer", offer_request) # TODO issue an additional credential for Student ID elif option == "2": log_status("#20 Request proof of degree from Thapelo") req_attrs = [ { "name": "name", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "date", "restrictions": [{ "issuer_did": agent.did }] }, ] if revocation: req_attrs.append( { "name": "degree", "restrictions": [{ "issuer_did": agent.did }], "non_revoked": { "to": int(time.time() - 1) }, }, ) else: req_attrs.append({ "name": "degree", "restrictions": [{ "issuer_did": agent.did }] }) if SELF_ATTESTED: # test self-attested claims req_attrs.append({"name": "self_attested_thing"}, ) req_preds = [ # test zero-knowledge proofs { "name": "age", "p_type": ">=", "p_value": 18, "restrictions": [{ "issuer_did": agent.did }], } ] indy_proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": { f"0_{req_pred['name']}_GE_uuid": req_pred for req_pred in req_preds }, } if revocation: indy_proof_request["non_revoked"] = { "to": int(time.time()) } proof_request_web_request = { "connection_id": agent.connection_id, "proof_request": indy_proof_request, "trace": exchange_tracing, } await agent.admin_POST("/present-proof/send-request", proof_request_web_request) elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}) elif option == "4" and revocation: rev_reg_id = ( await prompt("Enter revocation registry ID: ")).strip() cred_rev_id = ( await prompt("Enter credential revocation ID: ")).strip() publish = json.dumps( (await prompt("Publish now? [Y/N]: ", default="N") ).strip() in ("yY")) try: await agent.admin_POST("/issue-credential/revoke" f"?publish={publish}" f"&rev_reg_id={rev_reg_id}" f"&cred_rev_id={cred_rev_id}") except ClientError: pass elif option == "5" and revocation: try: resp = await agent.admin_POST( "/issue-credential/publish-revocations") agent.log( "Published revocations for {} revocation registr{} {}". format( len(resp["results"]), "y" if len(resp) == 1 else "ies", json.dumps([k for k in resp["results"]], indent=4), )) except ClientError: pass elif option == "6" and revocation: log_status("#19 Add another revocation registry") await agent.create_and_publish_revocation_registry( credential_definition_id, TAILS_FILE_COUNT) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(args): acme_agent = await create_agent_with_args(args, ident="acme") try: log_status( "#1 Provision an agent and wallet, get back configuration details" + (f" (Wallet type: {acme_agent.wallet_type})" if acme_agent. wallet_type else "")) agent = AcmeAgent( "acme.agent", acme_agent.start_port, acme_agent.start_port + 1, genesis_data=acme_agent.genesis_txns, no_auto=acme_agent.no_auto, tails_server_base_url=acme_agent.tails_server_base_url, timing=acme_agent.show_timing, multitenant=acme_agent.multitenant, mediation=acme_agent.mediation, wallet_type=acme_agent.wallet_type, seed=acme_agent.seed, ) acme_agent.public_did = True # TODO: Create schema # acme_schema_name = "employee id schema" # acme_schema_attrs = ["employee_id", "name", "date", "position"] await acme_agent.initialize( the_agent=agent, # schema_name=acme_schema_name, # schema_attrs=acme_schema_attrs, ) # generate an invitation for Alice await acme_agent.generate_invitation(display_qr=True, wait=True) options = (" (1) Issue Credential\n" " (2) Send Proof Request\n" " (3) Send Message\n" " (X) Exit?\n" "[1/2/3/X]") async for option in prompt_loop(options): if option is not None: option = option.strip() if option is None or option in "xX": break elif option == "1": log_status("#13 Issue credential offer to X") # TODO credential offers elif option == "2": log_status("#20 Request proof of degree from alice") # TODO presentation requests elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}) if acme_agent.show_timing: timing = await acme_agent.agent.fetch_timing() if timing: for line in acme_agent.agent.format_timing(timing): log_msg(line) finally: terminated = await acme_agent.terminate() await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(args): faber_agent = await create_agent_with_args(args, ident="faber") try: log_status( "#1 Provision an agent and wallet, get back configuration details" + ( f" (Wallet type: {faber_agent.wallet_type})" if faber_agent.wallet_type else "" ) ) agent = FaberAgent( "faber.agent", faber_agent.start_port, faber_agent.start_port + 1, genesis_data=faber_agent.genesis_txns, no_auto=faber_agent.no_auto, tails_server_base_url=faber_agent.tails_server_base_url, timing=faber_agent.show_timing, multitenant=faber_agent.multitenant, mediation=faber_agent.mediation, wallet_type=faber_agent.wallet_type, seed=faber_agent.seed, ) if faber_agent.cred_type == CRED_FORMAT_INDY: faber_agent.public_did = True faber_schema_name = "degree schema" faber_schema_attrs = ["name", "date", "degree", "age", "timestamp"] await faber_agent.initialize( the_agent=agent, schema_name=faber_schema_name, schema_attrs=faber_schema_attrs, ) elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: faber_agent.public_did = True await faber_agent.initialize(the_agent=agent) else: raise Exception("Invalid credential type:" + faber_agent.cred_type) # generate an invitation for Alice await faber_agent.generate_invitation(display_qr=True, wait=True) exchange_tracing = False options = ( " (1) Issue Credential\n" " (2) Send Proof Request\n" " (3) Send Message\n" " (4) Create New Invitation\n" ) if faber_agent.revocation: options += " (5) Revoke Credential\n" " (6) Publish Revocations\n" if faber_agent.multitenant: options += " (W) Create and/or Enable Wallet\n" options += " (T) Toggle tracing on credential/proof exchange\n" options += " (X) Exit?\n[1/2/3/4/{}{}T/X] ".format( "5/6/" if faber_agent.revocation else "", "W/" if faber_agent.multitenant else "", ) async for option in prompt_loop(options): if option is not None: option = option.strip() if option is None or option in "xX": break elif option in "wW" and faber_agent.multitenant: target_wallet_name = await prompt("Enter wallet name: ") include_subwallet_webhook = await prompt( "(Y/N) Create sub-wallet webhook target: " ) if include_subwallet_webhook.lower() == "y": created = await faber_agent.agent.register_or_switch_wallet( target_wallet_name, webhook_port=faber_agent.agent.get_new_webhook_port(), public_did=True, mediator_agent=faber_agent.mediator_agent, ) else: created = await faber_agent.agent.register_or_switch_wallet( target_wallet_name, public_did=True, mediator_agent=faber_agent.mediator_agent, ) # create a schema and cred def for the new wallet # TODO check first in case we are switching between existing wallets if created: # TODO this fails because the new wallet doesn't get a public DID await faber_agent.create_schema_and_cred_def( schema_name=faber_schema_name, schema_attrs=faber_schema_attrs, ) elif option in "tT": exchange_tracing = not exchange_tracing log_msg( ">>> Credential/Proof Exchange Tracing is {}".format( "ON" if exchange_tracing else "OFF" ) ) elif option == "1": log_status("#13 Issue credential offer to X") if faber_agent.aip == 10: # define attributes to send for credential faber_agent.agent.cred_attrs[faber_agent.cred_def_id] = { "name": "Alice Smith", "date": "2018-05-28", "degree": "Maths", "age": "24", "timestamp": str(int(time.time())), } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [ {"name": n, "value": v} for (n, v) in faber_agent.agent.cred_attrs[ faber_agent.cred_def_id ].items() ], } offer_request = { "connection_id": faber_agent.agent.connection_id, "cred_def_id": faber_agent.cred_def_id, "comment": f"Offer on cred def id {faber_agent.cred_def_id}", "auto_remove": False, "credential_preview": cred_preview, "trace": exchange_tracing, } await faber_agent.agent.admin_POST( "/issue-credential/send-offer", offer_request ) elif faber_agent.aip == 20: if faber_agent.cred_type == CRED_FORMAT_INDY: faber_agent.agent.cred_attrs[faber_agent.cred_def_id] = { "name": "Alice Smith", "date": "2018-05-28", "degree": "Maths", "age": "24", "timestamp": str(int(time.time())), } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [ {"name": n, "value": v} for (n, v) in faber_agent.agent.cred_attrs[ faber_agent.cred_def_id ].items() ], } offer_request = { "connection_id": faber_agent.agent.connection_id, "comment": f"Offer on cred def id {faber_agent.cred_def_id}", "auto_remove": False, "credential_preview": cred_preview, "filter": { "indy": {"cred_def_id": faber_agent.cred_def_id} }, "trace": exchange_tracing, } elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: offer_request = { "connection_id": faber_agent.agent.connection_id, "filter": { "ld_proof": { "credential": { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://w3id.org/citizenship/v1", ], "type": [ "VerifiableCredential", "PermanentResident", ], "id": "https://credential.example.com/residents/1234567890", "issuer": faber_agent.agent.did, "issuanceDate": "2020-01-01T12:00:00Z", "credentialSubject": { "type": ["PermanentResident"], # "id": "<TODO need did:key of holder>", "givenName": "ALICE", "familyName": "SMITH", "gender": "Female", "birthCountry": "Bahamas", "birthDate": "1958-07-17", }, }, "options": {"proofType": SIG_TYPE_BLS}, } }, } else: raise Exception( f"Error invalid credential type: {faber_agent.cred_type}" ) await faber_agent.agent.admin_POST( "/issue-credential-2.0/send-offer", offer_request ) else: raise Exception(f"Error invalid AIP level: {faber_agent.aip}") elif option == "2": log_status("#20 Request proof of degree from alice") if faber_agent.aip == 10: req_attrs = [ { "name": "name", "restrictions": [{"schema_name": "degree schema"}], }, { "name": "date", "restrictions": [{"schema_name": "degree schema"}], }, ] if faber_agent.revocation: req_attrs.append( { "name": "degree", "restrictions": [{"schema_name": "degree schema"}], "non_revoked": {"to": int(time.time() - 1)}, }, ) else: req_attrs.append( { "name": "degree", "restrictions": [{"schema_name": "degree schema"}], } ) if SELF_ATTESTED: # test self-attested claims req_attrs.append( {"name": "self_attested_thing"}, ) req_preds = [ # test zero-knowledge proofs { "name": "age", "p_type": ">=", "p_value": 18, "restrictions": [{"schema_name": "degree schema"}], } ] indy_proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": { f"0_{req_pred['name']}_GE_uuid": req_pred for req_pred in req_preds }, } if faber_agent.revocation: indy_proof_request["non_revoked"] = {"to": int(time.time())} proof_request_web_request = { "connection_id": faber_agent.agent.connection_id, "proof_request": indy_proof_request, "trace": exchange_tracing, } await faber_agent.agent.admin_POST( "/present-proof/send-request", proof_request_web_request ) pass elif faber_agent.aip == 20: if faber_agent.cred_type == CRED_FORMAT_INDY: req_attrs = [ { "name": "name", "restrictions": [{"schema_name": faber_schema_name}], }, { "name": "date", "restrictions": [{"schema_name": faber_schema_name}], }, ] if faber_agent.revocation: req_attrs.append( { "name": "degree", "restrictions": [ {"schema_name": faber_schema_name} ], "non_revoked": {"to": int(time.time() - 1)}, }, ) else: req_attrs.append( { "name": "degree", "restrictions": [ {"schema_name": faber_schema_name} ], } ) if SELF_ATTESTED: # test self-attested claims req_attrs.append( {"name": "self_attested_thing"}, ) req_preds = [ # test zero-knowledge proofs { "name": "age", "p_type": ">=", "p_value": 18, "restrictions": [{"schema_name": faber_schema_name}], } ] indy_proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": { f"0_{req_pred['name']}_GE_uuid": req_pred for req_pred in req_preds }, } if faber_agent.revocation: indy_proof_request["non_revoked"] = {"to": int(time.time())} proof_request_web_request = { "connection_id": faber_agent.agent.connection_id, "presentation_request": {"indy": indy_proof_request}, "trace": exchange_tracing, } elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: proof_request_web_request = { "comment": "test proof request for json-ld", "connection_id": faber_agent.agent.connection_id, "presentation_request": { "dif": { "options": { "challenge": "3fa85f64-5717-4562-b3fc-2c963f66afa7", "domain": "4jt78h47fh47", }, "presentation_definition": { "id": "32f54163-7166-48f1-93d8-ff217bdb0654", "format": { "ldp_vp": {"proof_type": [SIG_TYPE_BLS]} }, "input_descriptors": [ { "id": "citizenship_input_1", "name": "EU Driver's License", "schema": [ { "uri": "https://www.w3.org/2018/credentials#VerifiableCredential" }, { "uri": "https://w3id.org/citizenship#PermanentResident" }, ], "constraints": { "limit_disclosure": "required", "fields": [ { "path": [ "$.credentialSubject.familyName" ], "purpose": "The claim must be from one of the specified person", "filter": { "const": "SMITH" }, }, { "path": [ "$.credentialSubject.givenName" ], "purpose": "The claim must be from one of the specified person", }, ], }, } ], }, } }, } else: raise Exception( "Error invalid credential type:" + faber_agent.cred_type ) await agent.admin_POST( "/present-proof-2.0/send-request", proof_request_web_request ) else: raise Exception(f"Error invalid AIP level: {faber_agent.aip}") elif option == "3": msg = await prompt("Enter message: ") await faber_agent.agent.admin_POST( f"/connections/{faber_agent.agent.connection_id}/send-message", {"content": msg}, ) elif option == "4": log_msg( "Creating a new invitation, please receive " "and accept this invitation using Alice agent" ) await faber_agent.generate_invitation(display_qr=True, wait=True) elif option == "5" and faber_agent.revocation: rev_reg_id = (await prompt("Enter revocation registry ID: ")).strip() cred_rev_id = (await prompt("Enter credential revocation ID: ")).strip() publish = ( await prompt("Publish now? [Y/N]: ", default="N") ).strip() in "yY" try: await faber_agent.agent.admin_POST( "/revocation/revoke", { "rev_reg_id": rev_reg_id, "cred_rev_id": cred_rev_id, "publish": publish, }, ) except ClientError: pass elif option == "6" and faber_agent.revocation: try: resp = await faber_agent.agent.admin_POST( "/revocation/publish-revocations", {} ) faber_agent.agent.log( "Published revocations for {} revocation registr{} {}".format( len(resp["rrid2crid"]), "y" if len(resp["rrid2crid"]) == 1 else "ies", json.dumps([k for k in resp["rrid2crid"]], indent=4), ) ) except ClientError: pass if faber_agent.show_timing: timing = await faber_agent.agent.fetch_timing() if timing: for line in faber_agent.agent.format_timing(timing): log_msg(line) finally: terminated = await faber_agent.terminate() await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main( start_port: int, no_auto: bool = False, revocation: bool = False, tails_server_base_url: str = None, show_timing: bool = False, multitenant: bool = False, mediation: bool = False, use_did_exchange: bool = False, wallet_type: str = None, ): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None mediator_agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details" + (f" (Wallet type: {wallet_type})" if wallet_type else "") ) agent = FaberAgent( "Faber.Agent", start_port, start_port + 1, genesis_data=genesis, no_auto=no_auto, tails_server_base_url=tails_server_base_url, timing=show_timing, multitenant=multitenant, mediation=mediation, wallet_type=wallet_type, ) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin URL is at:", agent.admin_url) log_msg("Endpoint URL is at:", agent.endpoint) if mediation: mediator_agent = await start_mediator_agent(start_port + 4, genesis) if not mediator_agent: raise Exception("Mediator agent returns None :-(") else: mediator_agent = None if multitenant: # create an initial managed sub-wallet (also mediated) await agent.register_or_switch_wallet( "Faber.initial", public_did=True, webhook_port=agent.get_new_webhook_port(), mediator_agent=mediator_agent, ) elif mediation: # we need to pre-connect the agent to its mediator if not await connect_wallet_to_mediator(agent, mediator_agent): log_msg("Mediation setup FAILED :-(") raise Exception("Mediation setup FAILED :-(") # Create a schema cred_def_id = await create_schema_and_cred_def(agent, revocation) # TODO add an additional credential for Student ID await generate_invitation(agent, use_did_exchange) exchange_tracing = False options = ( " (1) Issue Credential\n" " (2) Send Proof Request\n" " (3) Send Message\n" " (4) Create New Invitation\n" ) if revocation: options += " (5) Revoke Credential\n" " (6) Publish Revocations\n" if multitenant: options += " (W) Create and/or Enable Wallet\n" options += " (T) Toggle tracing on credential/proof exchange\n" options += " (X) Exit?\n[1/2/3/4/{}{}T/X] ".format( "5/6/" if revocation else "", "W/" if multitenant else "", ) async for option in prompt_loop(options): if option is not None: option = option.strip() if option is None or option in "xX": break elif option in "wW" and multitenant: target_wallet_name = await prompt("Enter wallet name: ") include_subwallet_webhook = await prompt( "(Y/N) Create sub-wallet webhook target: " ) if include_subwallet_webhook.lower() == "y": created = await agent.register_or_switch_wallet( target_wallet_name, webhook_port=agent.get_new_webhook_port(), public_did=True, mediator_agent=mediator_agent, ) else: created = await agent.register_or_switch_wallet( target_wallet_name, public_did=True, mediator_agent=mediator_agent, ) # create a schema and cred def for the new wallet # TODO check first in case we are switching between existing wallets if created: # TODO this fails because the new wallet doesn't get a public DID cred_def_id = await create_schema_and_cred_def(agent, revocation) elif option in "tT": exchange_tracing = not exchange_tracing log_msg( ">>> Credential/Proof Exchange Tracing is {}".format( "ON" if exchange_tracing else "OFF" ) ) elif option == "1": log_status("#13 Issue credential offer to X") # TODO define attributes to send for credential agent.cred_attrs[cred_def_id] = { "name": "Alice Smith", "date": "2018-05-28", "degree": "Maths", "age": "24", "timestamp": str(int(time.time())), } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [ {"name": n, "value": v} for (n, v) in agent.cred_attrs[cred_def_id].items() ], } offer_request = { "connection_id": agent.connection_id, "comment": f"Offer on cred def id {cred_def_id}", "auto_remove": False, "credential_preview": cred_preview, "filter": {"indy": {"cred_def_id": cred_def_id}}, "trace": exchange_tracing, } await agent.admin_POST( "/issue-credential-2.0/send-offer", offer_request ) # TODO issue an additional credential for Student ID elif option == "2": log_status("#20 Request proof of degree from alice") req_attrs = [ { "name": "name", "restrictions": [{"schema_name": "degree schema"}], }, { "name": "date", "restrictions": [{"schema_name": "degree schema"}], }, ] if revocation: req_attrs.append( { "name": "degree", "restrictions": [{"schema_name": "degree schema"}], "non_revoked": {"to": int(time.time() - 1)}, }, ) else: req_attrs.append( { "name": "degree", "restrictions": [{"schema_name": "degree schema"}], } ) if SELF_ATTESTED: # test self-attested claims req_attrs.append( {"name": "self_attested_thing"}, ) req_preds = [ # test zero-knowledge proofs { "name": "age", "p_type": ">=", "p_value": 18, "restrictions": [{"schema_name": "degree schema"}], } ] indy_proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": { f"0_{req_pred['name']}_GE_uuid": req_pred for req_pred in req_preds }, } if revocation: indy_proof_request["non_revoked"] = {"to": int(time.time())} proof_request_web_request = { "connection_id": agent.connection_id, "proof_request": indy_proof_request, "trace": exchange_tracing, } await agent.admin_POST( "/present-proof/send-request", proof_request_web_request ) elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg} ) elif option == "4": log_msg( "Creating a new invitation, please receive " "and accept this invitation using Alice agent" ) await generate_invitation(agent, use_did_exchange) elif option == "5" and revocation: rev_reg_id = (await prompt("Enter revocation registry ID: ")).strip() cred_rev_id = (await prompt("Enter credential revocation ID: ")).strip() publish = ( await prompt("Publish now? [Y/N]: ", default="N") ).strip() in "yY" try: await agent.admin_POST( "/revocation/revoke", { "rev_reg_id": rev_reg_id, "cred_rev_id": cred_rev_id, "publish": publish, }, ) except ClientError: pass elif option == "6" and revocation: try: resp = await agent.admin_POST("/revocation/publish-revocations", {}) agent.log( "Published revocations for {} revocation registr{} {}".format( len(resp["rrid2crid"]), "y" if len(resp["rrid2crid"]) == 1 else "ies", json.dumps([k for k in resp["rrid2crid"]], indent=4), ) ) except ClientError: pass if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if mediator_agent: log_msg("Shutting down mediator agent ...") await mediator_agent.terminate() if agent: log_msg("Shutting down faber agent ...") await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status("#1 Provision an agent and wallet, get back configuration details") agent = AcmeAgent( start_port, start_port + 1, genesis_data=genesis, timing=show_timing ) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin URL is at:", agent.admin_url) log_msg("Endpoint URL is at:", agent.endpoint) # Create a schema log_status("#3 Create a new schema on the ledger") with log_timer("Publish schema duration:"): version = format( "%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), ) ) ( schema_id, credential_definition_id, ) = await agent.register_schema_and_creddef( "employee id schema", version, ["employee_id", "name", "date", "position"], ) with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST("/connections/create-invitation") agent.connection_id = connection["connection_id"] log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") log_msg("Waiting for connection...") await agent.detect_connection() async for option in prompt_loop( "(1) Issue Credential, (2) Send Proof Request, " + "(3) Send Message (X) Exit? [1/2/3/X] " ): option = option.strip() if option in "xX": break elif option == "1": log_status("#13 Issue credential offer to X") agent.cred_attrs[credential_definition_id] = { "employee_id": "ACME0009", "name": "Alice Smith", "date": date.isoformat(date.today()), "position": "CEO" } offer_request = { "connection_id": agent.connection_id, "cred_def_id": credential_definition_id, "comment": f"Offer on cred def id {credential_definition_id}", } await agent.admin_POST( "/issue-credential/send-offer", offer_request ) elif option == "2": log_status("#20 Request proof of degree from alice") req_attrs = [ { "name": "name", "restrictions": [{"schema_name": "degree schema"}] }, { "name": "date", "restrictions": [{"schema_name": "degree schema"}] }, { "name": "degree", "restrictions": [{"schema_name": "degree schema"}] } ] req_preds = [] indy_proof_request = { "name": "Proof of Education", "version": "1.0", "nonce": str(uuid4().int), "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": {} } proof_request_web_request = { "connection_id": agent.connection_id, "proof_request": indy_proof_request } # this sends the request to our agent, which forwards it to Alice # (based on the connection_id) await agent.admin_POST( "/present-proof/send-request", proof_request_web_request ) elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg} )
async def main( start_port: int, no_auto: bool = False, revocation: bool = False, show_timing: bool = False, ): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status("#1 Provision an agent and wallet, get back configuration details") agent = FaberAgent( start_port, start_port + 1, genesis_data=genesis, no_auto=no_auto, timing=show_timing, ) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) # Create a schema with log_timer("Publish schema/cred def duration:"): log_status("#3/4 Create a new schema/cred def on the ledger") version = format( "%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), ) ) ( _, # schema id credential_definition_id, ) = await agent.register_schema_and_creddef( "degree schema", version, ["name", "date", "degree", "age", "timestamp"], support_revocation=revocation, ) if revocation: with log_timer("Publish revocation registry duration:"): log_status( "#5/6 Create and publish the revocation registry on the ledger" ) revocation_registry_id = await ( agent.create_and_publish_revocation_registry( credential_definition_id, TAILS_FILE_COUNT ) ) else: revocation_registry_id = None # TODO add an additional credential for Student ID with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#7 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST("/connections/create-invitation") agent.connection_id = connection["connection_id"] log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") log_msg("Waiting for connection...") await agent.detect_connection() options = "(1) Issue Credential (2) Send Proof Request (3) Send Message" if revocation: options += " (4) Revoke Credential (5) Add Revocation Registry" options += " (X) Exit? [1/2/3/X] " async for option in prompt_loop(options): if option is None or option in "xX": break elif option == "1": log_status("#13 Issue credential offer to X") # TODO define attributes to send for credential agent.cred_attrs[credential_definition_id] = { "name": "Alice Smith", "date": "2018-05-28", "degree": "Maths", "age": "24", "timestamp": str(int(time.time())), } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [ {"name": n, "value": v} for (n, v) in agent.cred_attrs[credential_definition_id].items() ], } offer_request = { "connection_id": agent.connection_id, "cred_def_id": credential_definition_id, "comment": f"Offer on cred def id {credential_definition_id}", "auto_remove": False, "credential_preview": cred_preview, "revoc_reg_id": revocation_registry_id, } await agent.admin_POST("/issue-credential/send-offer", offer_request) # TODO issue an additional credential for Student ID elif option == "2": log_status("#20 Request proof of degree from alice") req_attrs = [ {"name": "name", "restrictions": [{"issuer_did": agent.did}]}, {"name": "date", "restrictions": [{"issuer_did": agent.did}]}, ] if revocation: req_attrs.append( { "name": "degree", "restrictions": [{"issuer_did": agent.did}], "non_revoked": {"to": int(time.time() - 1)}, }, ) else: req_attrs.append( {"name": "degree", "restrictions": [{"issuer_did": agent.did}]} ) # test self-attested claims req_attrs.append({"name": "self_attested_thing"},) req_preds = [ # test zero-knowledge proofs { "name": "age", "p_type": ">=", "p_value": 18, "restrictions": [{"issuer_did": agent.did}], } ] indy_proof_request = { "name": "Proof of Education", "version": "1.0", "nonce": str(uuid4().int), "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": { f"0_{req_pred['name']}_GE_uuid": req_pred for req_pred in req_preds }, } if revocation: indy_proof_request["non_revoked"] = {"to": int(time.time())} proof_request_web_request = { "connection_id": agent.connection_id, "proof_request": indy_proof_request, } await agent.admin_POST( "/present-proof/send-request", proof_request_web_request ) elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg} ) elif option == "4" and revocation: revoking_cred_id = await prompt("Enter credential exchange id: ") await agent.admin_POST( f"/issue-credential/records/{revoking_cred_id}/revoke" ) elif option == "5" and revocation: log_status("#19 Add another revocation registry") revocation_registry_id = await ( agent.create_and_publish_revocation_registry( credential_definition_id, TAILS_FILE_COUNT ) ) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status("#1 Provision an agent and wallet, get back configuration details") agent = CoordinatorAgent( start_port, start_port + 1, genesis_data=genesis, timing=show_timing ) await agent.listen_webhooks(start_port + 2) with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST("/connections/create-invitation") agent.active_connection_id = connection["connection_id"] agent.connection_list.append(connection["connection_id"]) log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") # log_msg("Waiting for connection...") # await agent.detect_connection() async for option in prompt_loop( "(1) Request proof of Verified Hospital \n" + "(2) Input New Invitation \n" + "(3) Create New Invitation \n" + "(4) List trusted connections \n" + "(5) Initiate Learning \n" + "(6) Reset trusted connections \n" + "(X) Exit? \n[1/2/3/4/5/6/X] " ): if option is None or option in "xX": break elif option == "1": log_status("#20 Request proof of degree from alice") req_attrs = [ {"name": "date", "restrictions": [{"issuer_did": agent.nhsheadoffice_did}]}, {"name": "hospital_name", "restrictions": [{"issuer_did": agent.nhsheadoffice_did}]}, ] # req_preds = [ # { # "name": "age", # "p_type": ">=", # "p_value": 18, # "restrictions": [{"issuer_did": agent.did}], # } # ] indy_proof_request = { "name": "Proof of Verified Hospital", "version": "1.0", "nonce": str(uuid4().int), "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": { }, } print("Asking for this proof: ", indy_proof_request) proof_request_web_request = { "connection_id": agent.active_connection_id, "proof_request": indy_proof_request, } await agent.admin_POST( "/present-proof/send-request", proof_request_web_request ) elif option == "2": # handle new invitation log_status("Input new invitation details") await input_invitation(agent) elif option == "3": # handle new invitation with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST("/connections/create-invitation") agent.active_connection_id = connection["connection_id"] agent.connection_list.append(connection["connection_id"]) log_msg("all connections :", agent.connection_list) log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") agent._connection_ready = asyncio.Future() log_msg("Waiting for connection...") await agent.detect_connection() elif option == "4": # handle new invitation log_status("List of Trusted Connections") log_msg(agent.trusted_connection_ids) # log_msg(agent.trusted_hospitals) elif option == "5": # handle new invitation log_status("Initiate Learning") # TODO Need to get the updated file somehow # Some sort of await until coordinator recieved message back successfully_generated = await generate_model() successfully_validated = await validate_model(agent.current_model_file) # f = open(agent.current_model_file, "rb") if successfully_generated: log_msg("MODEL CREATED AND SAVED SUCCESSFULLY") f = open(agent.current_model_file, "rb") log_msg("MODEL OPENED FOR TRANSPORT") contents = f.read() f.close() await agent.admin_POST( f"/connections/{agent.trusted_connection_ids[0]}/send-message", {"content": contents.hex()} ) await agent.learning_complete else: log_msg("THERE WAS A PROBLEM WITH THE MODEL CREATION") elif option == "6": # handle new invitation log_status("Reset trusted connection list") agent.trusted_connection_ids = [] agent.trusted_hospitals = [] if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = AcmeAgent(start_port, start_port + 1, genesis_data=genesis, timing=show_timing) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) # Create a schema log_status("#3 Create a new schema on the ledger") with log_timer("Publish schema duration:"): # define schema version = format("%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), )) ( schema_id, credential_definition_id, ) = await agent.register_schema_and_creddef( "current_employee schema", version, ["employee_id", "name", "start_date", "position", "salary"], ) with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.connection_id = connection["connection_id"] log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") log_msg("Waiting for connection...") await agent.detect_connection() async for option in prompt_loop( "(1) Issue Credential, (2) Send Proof Request, " + "(3) Send Message (X) Exit? [1/2/3/X] "): if option in "xX": break elif option == "1": log_status("#13 Issue credential offer to X") # TODO credential offers agent.cred_attrs[credential_definition_id] = { "employee_id": "ACME0009", "name": "Alice Smith", "start_date": "2019-05-28", "position": "CEO", "salary": "3000" } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [{ "name": n, "value": v } for (n, v) in agent.cred_attrs[credential_definition_id].items()], } offer_request = { "connection_id": agent.connection_id, "cred_def_id": credential_definition_id, "comment": f"Offer on cred def id {credential_definition_id}", "credential_preview": cred_preview } await agent.admin_POST("/issue-credential/send-offer", offer_request) elif option == "2": log_status("#20 Request proof of employement from alice") # TODO presentation requests req_attrs = [{ "name": "name", "restrictions": [{ "schema_name": "ex_employee schema" }] }, { "name": "end_date", "restrictions": [{ "schema_name": "ex_employee schema" }] }, { "name": "start_date", "restrictions": [{ "schema_name": "ex_employee schema" }] }] req_preds = [] indy_proof_request = { "name": "Proof of Employment", "version": "1.0", "nonce": str(uuid4().int), "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": {} } proof_request_web_request = { "connection_id": agent.connection_id, "proof_request": indy_proof_request } # this sends the request to our agent, which forwards it to Alice # (based on the connection_id) await agent.admin_POST("/present-proof/send-request", proof_request_web_request) elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(args): faber_agent = await create_agent_with_args(args, ident="faber") try: log_status( "#1 Provision an agent and wallet, get back configuration details" + (f" (Wallet type: {faber_agent.wallet_type})" if faber_agent. wallet_type else "")) agent = FaberAgent( "faber.agent", faber_agent.start_port, faber_agent.start_port + 1, genesis_data=faber_agent.genesis_txns, no_auto=faber_agent.no_auto, tails_server_base_url=faber_agent.tails_server_base_url, timing=faber_agent.show_timing, multitenant=faber_agent.multitenant, mediation=faber_agent.mediation, wallet_type=faber_agent.wallet_type, seed=faber_agent.seed, aip=faber_agent.aip, ) if faber_agent.cred_type == CRED_FORMAT_INDY: faber_agent.public_did = True faber_schema_name = "degree schema" faber_schema_attrs = [ "name", "date", "degree", "birthdate_dateint", "timestamp", ] await faber_agent.initialize( the_agent=agent, schema_name=faber_schema_name, schema_attrs=faber_schema_attrs, ) elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: faber_agent.public_did = True await faber_agent.initialize(the_agent=agent) else: raise Exception("Invalid credential type:" + faber_agent.cred_type) # generate an invitation for Alice await faber_agent.generate_invitation(display_qr=True, wait=True) exchange_tracing = False options = ( " (1) Issue Credential\n" " (2) Send Proof Request\n" " (2a) Send *Connectionless* Proof Request (requires a Mobile client)\n" " (3) Send Message\n" " (4) Create New Invitation\n") if faber_agent.revocation: options += " (5) Revoke Credential\n" " (6) Publish Revocations\n" if faber_agent.multitenant: options += " (W) Create and/or Enable Wallet\n" options += " (T) Toggle tracing on credential/proof exchange\n" options += " (X) Exit?\n[1/2/3/4/{}{}T/X] ".format( "5/6/" if faber_agent.revocation else "", "W/" if faber_agent.multitenant else "", ) async for option in prompt_loop(options): if option is not None: option = option.strip() if option is None or option in "xX": break elif option in "wW" and faber_agent.multitenant: target_wallet_name = await prompt("Enter wallet name: ") include_subwallet_webhook = await prompt( "(Y/N) Create sub-wallet webhook target: ") if include_subwallet_webhook.lower() == "y": created = await faber_agent.agent.register_or_switch_wallet( target_wallet_name, webhook_port=faber_agent.agent.get_new_webhook_port(), public_did=True, mediator_agent=faber_agent.mediator_agent, ) else: created = await faber_agent.agent.register_or_switch_wallet( target_wallet_name, public_did=True, mediator_agent=faber_agent.mediator_agent, ) # create a schema and cred def for the new wallet # TODO check first in case we are switching between existing wallets if created: # TODO this fails because the new wallet doesn't get a public DID await faber_agent.create_schema_and_cred_def( schema_name=faber_schema_name, schema_attrs=faber_schema_attrs, ) elif option in "tT": exchange_tracing = not exchange_tracing log_msg(">>> Credential/Proof Exchange Tracing is {}".format( "ON" if exchange_tracing else "OFF")) elif option == "1": log_status("#13 Issue credential offer to X") if faber_agent.aip == 10: offer_request = faber_agent.agent.generate_credential_offer( faber_agent.aip, None, faber_agent.cred_def_id, exchange_tracing) await faber_agent.agent.admin_POST( "/issue-credential/send-offer", offer_request) elif faber_agent.aip == 20: if faber_agent.cred_type == CRED_FORMAT_INDY: offer_request = faber_agent.agent.generate_credential_offer( faber_agent.aip, faber_agent.cred_type, faber_agent.cred_def_id, exchange_tracing, ) elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: offer_request = faber_agent.agent.generate_credential_offer( faber_agent.aip, faber_agent.cred_type, None, exchange_tracing, ) else: raise Exception( f"Error invalid credential type: {faber_agent.cred_type}" ) await faber_agent.agent.admin_POST( "/issue-credential-2.0/send-offer", offer_request) else: raise Exception( f"Error invalid AIP level: {faber_agent.aip}") elif option == "2": log_status("#20 Request proof of degree from alice") if faber_agent.aip == 10: proof_request_web_request = ( faber_agent.agent.generate_proof_request_web_request( faber_agent.aip, faber_agent.cred_type, faber_agent.revocation, exchange_tracing, )) await faber_agent.agent.admin_POST( "/present-proof/send-request", proof_request_web_request) pass elif faber_agent.aip == 20: if faber_agent.cred_type == CRED_FORMAT_INDY: proof_request_web_request = ( faber_agent.agent. generate_proof_request_web_request( faber_agent.aip, faber_agent.cred_type, faber_agent.revocation, exchange_tracing, )) elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: proof_request_web_request = ( faber_agent.agent. generate_proof_request_web_request( faber_agent.aip, faber_agent.cred_type, faber_agent.revocation, exchange_tracing, )) else: raise Exception("Error invalid credential type:" + faber_agent.cred_type) await agent.admin_POST("/present-proof-2.0/send-request", proof_request_web_request) else: raise Exception( f"Error invalid AIP level: {faber_agent.aip}") elif option == "2a": log_status( "#20 Request * Connectionless * proof of degree from alice" ) if faber_agent.aip == 10: proof_request_web_request = ( faber_agent.agent.generate_proof_request_web_request( faber_agent.aip, faber_agent.cred_type, faber_agent.revocation, exchange_tracing, connectionless=True, )) proof_request = await faber_agent.agent.admin_POST( "/present-proof/create-request", proof_request_web_request) pres_req_id = proof_request["presentation_exchange_id"] url = ("http://" + os.getenv("DOCKERHOST").replace( "{PORT}", str(faber_agent.agent.admin_port + 1)) + "/webhooks/pres_req/" + pres_req_id + "/") log_msg(f"Proof request url: {url}") qr = QRCode(border=1) qr.add_data(url) log_msg( "Scan the following QR code to accept the proof request from a mobile agent." ) qr.print_ascii(invert=True) elif faber_agent.aip == 20: if faber_agent.cred_type == CRED_FORMAT_INDY: proof_request_web_request = ( faber_agent.agent. generate_proof_request_web_request( faber_agent.aip, faber_agent.cred_type, faber_agent.revocation, exchange_tracing, connectionless=True, )) elif faber_agent.cred_type == CRED_FORMAT_JSON_LD: proof_request_web_request = ( faber_agent.agent. generate_proof_request_web_request( faber_agent.aip, faber_agent.cred_type, faber_agent.revocation, exchange_tracing, connectionless=True, )) else: raise Exception("Error invalid credential type:" + faber_agent.cred_type) proof_request = await faber_agent.agent.admin_POST( "/present-proof-2.0/create-request", proof_request_web_request) pres_req_id = proof_request["pres_ex_id"] url = ("http://" + os.getenv("DOCKERHOST").replace( "{PORT}", str(faber_agent.agent.admin_port + 1)) + "/webhooks/pres_req/" + pres_req_id + "/") log_msg(f"Proof request url: {url}") qr = QRCode(border=1) qr.add_data(url) log_msg( "Scan the following QR code to accept the proof request from a mobile agent." ) qr.print_ascii(invert=True) else: raise Exception( f"Error invalid AIP level: {faber_agent.aip}") elif option == "3": msg = await prompt("Enter message: ") await faber_agent.agent.admin_POST( f"/connections/{faber_agent.agent.connection_id}/send-message", {"content": msg}, ) elif option == "4": log_msg("Creating a new invitation, please receive " "and accept this invitation using Alice agent") await faber_agent.generate_invitation(display_qr=True, wait=True) elif option == "5" and faber_agent.revocation: rev_reg_id = ( await prompt("Enter revocation registry ID: ")).strip() cred_rev_id = ( await prompt("Enter credential revocation ID: ")).strip() publish = (await prompt("Publish now? [Y/N]: ", default="N")).strip() in "yY" try: await faber_agent.agent.admin_POST( "/revocation/revoke", { "rev_reg_id": rev_reg_id, "cred_rev_id": cred_rev_id, "publish": publish, }, ) except ClientError: pass elif option == "6" and faber_agent.revocation: try: resp = await faber_agent.agent.admin_POST( "/revocation/publish-revocations", {}) faber_agent.agent.log( "Published revocations for {} revocation registr{} {}". format( len(resp["rrid2crid"]), "y" if len(resp["rrid2crid"]) == 1 else "ies", json.dumps([k for k in resp["rrid2crid"]], indent=4), )) except ClientError: pass if faber_agent.show_timing: timing = await faber_agent.agent.fetch_timing() if timing: for line in faber_agent.agent.format_timing(timing): log_msg(line) finally: terminated = await faber_agent.terminate() await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main(start_port: int, show_timing: bool = False): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = RegulatorAgent(start_port, start_port + 1, genesis_data=genesis, timing=show_timing) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin url is at:", agent.admin_url) log_msg("Endpoint url is at:", agent.endpoint) # Create a schema with log_timer("Publish schema/cred def duration:"): log_status("#3/4 Create a new schema/cred def on the ledger") version = format("%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), )) ( _, # schema id credential_definition_id, ) = await agent.register_schema_and_creddef( "Certified Researcher schema", version, ["institution", "date"]) # TODO add an additional credential for Student ID with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to Hospital and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.active_connection_id = connection["connection_id"] agent.connection_list.append(connection["connection_id"]) log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") log_msg("Waiting for connection...") await agent.detect_connection() async for option in prompt_loop( "(1) Issue Credential, (2) Create a New Invitation, (X) Exit? [1/2/X] " ): if option is None or option in "xX": break elif option == "1": log_status("#13 Issue credential offer to X") today = date.today() # TODO define attributes to send for credential agent.cred_attrs[credential_definition_id] = { # "name": str(credential_definition_id), "date": str(today), "institution": "Edinburgh Napier University", # "age": "24", } cred_preview = { "@type": CRED_PREVIEW_TYPE, "attributes": [{ "name": n, "value": v } for (n, v) in agent.cred_attrs[credential_definition_id].items()], } offer_request = { "connection_id": agent.active_connection_id, "credential_definition_id": credential_definition_id, "comment": f"Offer on cred def id {credential_definition_id}", "credential_preview": cred_preview, } await agent.admin_POST("/issue-credential/send-offer", offer_request) elif option == "2": # handle new invitation with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#5 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.active_connection_id = connection["connection_id"] agent.connection_list.append(connection["connection_id"]) log_msg("all connections :", agent.connection_list) log_json(connection, label="Invitation response:") log_msg("*****************") log_msg(json.dumps(connection["invitation"]), label="Invitation:", color=None) log_msg("*****************") agent._connection_ready = asyncio.Future() log_msg("Waiting for connection...") await agent.detect_connection() if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)
async def main( start_port: int, no_auto: bool = False, revocation: bool = False, show_timing: bool = False, ): genesis = await default_genesis_txns() if not genesis: print("Error retrieving ledger genesis transactions") sys.exit(1) agent = None try: log_status( "#1 Provision an agent and wallet, get back configuration details") agent = CourtAgent( start_port, start_port + 1, genesis_data=genesis, no_auto=no_auto, timing=show_timing, ) await agent.listen_webhooks(start_port + 2) await agent.register_did() with log_timer("Startup duration:"): await agent.start_process() log_msg("Admin URL is at:", agent.admin_url) log_msg("Endpoint URL is at:", agent.endpoint) # Create a schema with log_timer("Publish schema/cred def duration:"): log_status("#3/4 Create a new schema/cred def on the ledger") version = format("%d.%d.%d" % ( random.randint(1, 101), random.randint(1, 101), random.randint(1, 101), )) ( _, # schema id credential_definition_id, ) = await agent.register_schema_and_creddef( "custody schema", version, [ "issuanceDate", "issuer", "trustFrameworkURI", "auditURI", "appealURI", "caseResult", "credentialSubject.holder.type", "credentialSubject.holder.role", "credentialSubject.holder.rationaleURI", "credentialSubject.holder.firstName", "credentialSubject.holder.lastName", "credentialSubject.holder.kinshipStatus", "credentialSubject.holder.constraints.boundaries", "credentialSubject.holder.constraints.pointOfOrigin", "credentialSubject.holder.constraints.radiusKM", "credentialSubject.holder.constraints.jurisdictions", "credentialSubject.holder.constraints.trigger", "credentialSubject.holder.constraints.circumstances", "credentialSubject.holder.constraints.startTime", "credentialSubject.holder.constraints.endTime", "credentialSubject.proxied.type", "credentialSubject.proxied.firstName", "credentialSubject.proxied.lastName", "credentialSubject.proxied.birthDate", "credentialSubject.proxied.photo", "credentialSubject.proxied.iris", "credentialSubject.proxied.fingerprint", "credentialSubject.holder.permissions" ], support_revocation=revocation, ) if revocation: with log_timer("Publish revocation registry duration:"): log_status( "#5/6 Create and publish the revocation registry on the ledger" ) await agent.create_and_publish_revocation_registry( credential_definition_id, TAILS_FILE_COUNT) with log_timer("Generate invitation duration:"): # Generate an invitation log_status( "#7 Create a connection to alice and print out the invite details" ) connection = await agent.admin_POST( "/connections/create-invitation") agent.connection_id = connection["connection_id"] log_msg(json.dumps(connection["invitation"]), label="Invitation Data:", color=None) log_msg("Waiting for connection...") await agent.detect_connection() exchange_tracing = False options = (" (1) Issue Credential\n" " (2) Send Proof Request\n" " (3) Send Message\n") if revocation: options += (" (4) Revoke Credential\n" " (5) Publish Revocations\n" " (6) Add Revocation Registry\n") options += " (T) Toggle tracing on credential/proof exchange\n" options += " (X) Exit?\n[1/2/3/{}T/X] ".format( "4/5/6/" if revocation else "") async for option in prompt_loop(options): if option is not None: option = option.strip() if option is None or option in "xX": break elif option in "tT": exchange_tracing = not exchange_tracing log_msg(">>> Credential/Proof Exchange Tracing is {}".format( "ON" if exchange_tracing else "OFF")) elif option == "1": log_status("# Issue credential offer to X") offer_request = perform_time_measurement( agent, credential_definition_id, exchange_tracing) # offer_request = await prepare_cred(agent, credential_definition_id, exchange_tracing) await issue_cred(agent, offer_request) elif option == "2": log_status("#20 Request proof of degree from alice") req_attrs = [ { "name": "name", "restrictions": [{ "issuer_did": agent.did }] }, { "name": "date", "restrictions": [{ "issuer_did": agent.did }] }, ] if revocation: req_attrs.append( { "name": "degree", "restrictions": [{ "issuer_did": agent.did }], "non_revoked": { "to": int(time.time() - 1) }, }, ) else: req_attrs.append({ "name": "degree", "restrictions": [{ "issuer_did": agent.did }] }) if SELF_ATTESTED: # test self-attested claims req_attrs.append({"name": "self_attested_thing"}, ) req_preds = [ # test zero-knowledge proofs { "name": "caseResult", "p_type": "==", "p_value": "joint-custody", "restrictions": [{ "issuer_did": agent.did }], } ] indy_proof_request = { "name": "Proof of Education", "version": "1.0", "requested_attributes": { f"0_{req_attr['name']}_uuid": req_attr for req_attr in req_attrs }, "requested_predicates": { f"0_{req_pred['name']}_GE_uuid": req_pred for req_pred in req_preds }, } if revocation: indy_proof_request["non_revoked"] = { "to": int(time.time()) } proof_request_web_request = { "connection_id": agent.connection_id, "proof_request": indy_proof_request, "trace": exchange_tracing, } await agent.admin_POST("/present-proof/send-request", proof_request_web_request) elif option == "3": msg = await prompt("Enter message: ") await agent.admin_POST( f"/connections/{agent.connection_id}/send-message", {"content": msg}) elif option == "4" and revocation: rev_reg_id = ( await prompt("Enter revocation registry ID: ")).strip() cred_rev_id = ( await prompt("Enter credential revocation ID: ")).strip() publish = json.dumps( (await prompt("Publish now? [Y/N]: ", default="N") ).strip() in ("yY")) try: await agent.admin_POST("/issue-credential/revoke" f"?publish={publish}" f"&rev_reg_id={rev_reg_id}" f"&cred_rev_id={cred_rev_id}") except ClientError: pass elif option == "5" and revocation: try: resp = await agent.admin_POST( "/issue-credential/publish-revocations", {}) agent.log( "Published revocations for {} revocation registr{} {}". format( len(resp["rrid2crid"]), "y" if len(resp) == 1 else "ies", json.dumps([k for k in resp["rrid2crid"]], indent=4), )) except ClientError: pass elif option == "6" and revocation: log_status("#19 Add another revocation registry") await agent.create_and_publish_revocation_registry( credential_definition_id, TAILS_FILE_COUNT) if show_timing: timing = await agent.fetch_timing() if timing: for line in agent.format_timing(timing): log_msg(line) finally: terminated = True try: if agent: await agent.terminate() except Exception: LOGGER.exception("Error terminating agent:") terminated = False await asyncio.sleep(0.1) if not terminated: os._exit(1)