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)
Esempio n. 2
0
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()
Esempio n. 4
0
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()
Esempio n. 6
0
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)
Esempio n. 8
0
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)
Esempio n. 9
0
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)
Esempio n. 11
0
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)
Esempio n. 12
0
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)
Esempio n. 13
0
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)
Esempio n. 14
0
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)
Esempio n. 15
0
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)
Esempio n. 17
0
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)
Esempio n. 18
0
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)
Esempio n. 19
0
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)
Esempio n. 20
0
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}
                )
Esempio n. 21
0
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)
Esempio n. 23
0
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)
Esempio n. 24
0
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)
Esempio n. 26
0
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)