diff --git a/AnonCredsWalletType.md b/AnonCredsWalletType.md index 0b508b1d7c..2023faed18 100644 --- a/AnonCredsWalletType.md +++ b/AnonCredsWalletType.md @@ -80,14 +80,13 @@ The Tails file changes are minimal -- nothing about the file itself changed. Wh ## Outstanding work +* revocation notifications (not sure if they're included in `anoncreds-rs` updates, haven't tested them ...) +* revocation support - complete the revocation implementation (support for unhappy path scenarios) +* testing - various scenarios like mediation, multitenancy etc. + - unit tests (in the new anoncreds package) (see https://github.com/hyperledger/aries-cloudagent-python/pull/2596/commits/229ffbba209aff0ea7def5bad6556d93057f3c2a) - unit tests (review and possibly update unit tests for the credential and presentation integration) -- revocation support - migrate code from `anoncreds-rs` branch (in progress) -- revocation notifications (not sure if they're included in `anoncreds-rs` updates, haven'e tested them ...) -- revocation support - complete the revocation implementation (support for unhappy path scenarios) - endorsement (not implemented with new anoncreds code) -- endpoints - don't load the schema/cred-def endpoints when wallet type is anoncreds (will require some BDD updates) -- testing - various scenarios like mediation, multitenancy etc. - wallet upgrade (askar to askar-anoncreds) - update V1.0 versions of the Credential and Presentation endpoints to use anoncreds - any other anoncreds issues - https://github.com/hyperledger/aries-cloudagent-python/issues?q=is%3Aopen+is%3Aissue+label%3AAnonCreds diff --git a/aries_cloudagent/config/argparse.py b/aries_cloudagent/config/argparse.py index 22a3b1e62f..016dff65a7 100644 --- a/aries_cloudagent/config/argparse.py +++ b/aries_cloudagent/config/argparse.py @@ -1684,8 +1684,7 @@ def get_settings(self, args: Namespace) -> dict: if args.recreate_wallet: settings["wallet.recreate"] = True # check required settings for 'indy' wallets - # TODO should this also include "askar*" wallet types? - if settings["wallet.type"] == "indy": + if settings["wallet.type"] in ["indy", "askar", "askar-anoncreds"]: # requires name, key if not args.wallet_name or not args.wallet_key: raise ArgsParseError( diff --git a/aries_cloudagent/config/default_context.py b/aries_cloudagent/config/default_context.py index ebc25bd42c..283679c97d 100644 --- a/aries_cloudagent/config/default_context.py +++ b/aries_cloudagent/config/default_context.py @@ -138,10 +138,6 @@ async def load_plugins(self, context: InjectionContext): # Currently providing admin routes only plugin_registry.register_plugin("aries_cloudagent.holder") plugin_registry.register_plugin("aries_cloudagent.ledger") - plugin_registry.register_plugin( - "aries_cloudagent.messaging.credential_definitions" - ) - plugin_registry.register_plugin("aries_cloudagent.messaging.schemas") plugin_registry.register_plugin("aries_cloudagent.messaging.jsonld") plugin_registry.register_plugin("aries_cloudagent.resolver") plugin_registry.register_plugin("aries_cloudagent.settings") @@ -159,6 +155,10 @@ async def load_plugins(self, context: InjectionContext): ) plugin_registry.register_plugin("aries_cloudagent.revocation_anoncreds") else: + plugin_registry.register_plugin( + "aries_cloudagent.messaging.credential_definitions" + ) + plugin_registry.register_plugin("aries_cloudagent.messaging.schemas") plugin_registry.register_plugin("aries_cloudagent.revocation") if context.settings.get("multitenant.admin_enabled"): diff --git a/demo/bdd_support/agent_backchannel_client.py b/demo/bdd_support/agent_backchannel_client.py index 9b0c9c0e6c..907f159f75 100644 --- a/demo/bdd_support/agent_backchannel_client.py +++ b/demo/bdd_support/agent_backchannel_client.py @@ -103,6 +103,43 @@ def aries_container_create_schema_cred_def( ) +def aries_container_fetch_schemas( + the_container: AgentContainer, +): + return run_coroutine( + the_container.fetch_schemas, + ) + + +def aries_container_fetch_cred_defs( + the_container: AgentContainer, +): + return run_coroutine( + the_container.fetch_cred_defs, + ) + + +def aries_container_fetch_cred_def( + the_container: AgentContainer, + cred_def_id: str, +): + return run_coroutine( + the_container.fetch_cred_def, + cred_def_id, + ) + + +def aries_container_check_exists_cred_def( + the_container: AgentContainer, + cred_def_id: str, +): + cred_def = aries_container_fetch_cred_def(the_container, cred_def_id) + if cred_def: + return True + else: + return False + + def aries_container_issue_credential( the_container: AgentContainer, cred_def_id: str, diff --git a/demo/features/revocation-api.feature b/demo/features/revocation-api.feature new file mode 100644 index 0000000000..9fcaa2d099 --- /dev/null +++ b/demo/features/revocation-api.feature @@ -0,0 +1,136 @@ +Feature: ACA-Py Revocation API + + @Revoc-api @GHA + Scenario Outline: Using revocation api, issue and revoke credentials + Given we have "3" agents + | name | role | capabilities | + | Acme | issuer | | + | Faber | verifier | | + | Bob | prover | | + And "" and "Bob" have an existing connection + And "Bob" has an issued credential from "" + And "" revokes the credential + And "Faber" and "Bob" have an existing connection + When "Faber" sends a request for proof presentation to "Bob" + Then "Faber" has the proof verification fail + + Examples: + | issuer | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Proof_request | + #| Acme | --revocation --public-did | | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + | Acme | --revocation --public-did --wallet-type askar-anoncreds | --wallet-type askar-anoncreds | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + + @Revoc-api @GHA + Scenario Outline: Using revocation api, issue, revoke credentials and publish + Given we have "3" agents + | name | role | capabilities | + | Acme | issuer | | + | Faber | verifier | | + | Bob | prover | | + And "" and "Bob" have an existing connection + And "Bob" has an issued credential from "" + And "" has written the credential definition for to the ledger + And "" has written the revocation registry definition to the ledger + And "" has written the revocation registry entry transaction to the ledger + And "" revokes the credential without publishing the entry + And "" authors a revocation registry entry publishing transaction + And "Faber" and "Bob" have an existing connection + When "Faber" sends a request for proof presentation to "Bob" + Then "Faber" has the proof verification fail + Then "Bob" can verify the credential from "" was revoked + Examples: + | issuer | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Proof_request | + #| Acme | --revocation --public-did | | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + | Acme | --revocation --public-did --wallet-type askar-anoncreds | --wallet-type askar-anoncreds | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + + @Revoc-api.x @GHA-Anoncreds-break + Scenario Outline: Without endorser: issue, revoke credentials, manually create revocation registries + Given we have "3" agents + | name | role | capabilities | + | Acme | issuer | | + | Faber | verifier | | + | Bob | prover | | + And "" and "Bob" have an existing connection + And Without endorser, "" authors a schema transaction with + And "" has written the schema to the ledger + And Without endorser, "" authors a credential definition transaction with ' + And "" has written the credential definition for to the ledger + And Without endorser, "" authors a revocation registry definition transaction for the credential definition matching + And Without endorser, "" has written the revocation registry definition to the ledger + And "" has activated the tails file, and uploaded it to the tails server + And Without endorser, "" authors a revocation registry entry transaction for the credential definition matching + And "" has written the revocation registry entry transaction to the ledger + And "" offers a credential with data + Then "Bob" has the credential issued + And "" revokes the credential without publishing the entry + And "" authors a revocation registry entry publishing transaction + And "Faber" and "Bob" have an existing connection + When "Faber" sends a request for proof presentation to "Bob" + Then "Faber" has the proof verification fail + Then "Bob" can verify the credential from "" was revoked + Examples: + | issuer | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Proof_request | + #| Acme | --revocation --public-did --did-exchange | | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + | Acme | --revocation --public-did --did-exchange --wallet-type askar-anoncreds | --wallet-type askar-anoncreds | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + + @Revoc-api @GHA + Scenario Outline: Using revocation api, rotate revocation + Given we have "3" agents + | name | role | capabilities | + | Acme | issuer | | + | Faber | verifier | | + | Bob | prover | | + And "" and "Bob" have an existing connection + And "Bob" has an issued credential from "" + And "" lists revocation registries 1 + And "" rotates revocation registries + + Examples: + | issuer | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Proof_request | + #| Acme | --revocation --public-did | | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + | Acme | --revocation --public-did --wallet-type askar-anoncreds | --wallet-type askar-anoncreds | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + + @Revoc-api @GHA + Scenario Outline: Using revocation api, fill registry (need to run with "TAILS_FILE_COUNT": "4" env var) + Given we have "2" agents + | name | role | capabilities | + | Acme | issuer | | + | Bob | prover | | + And "" and "Bob" have an existing connection + And "Bob" has an issued credential from "" + And wait 5 seconds + And "" lists revocation registries 1 + When "" offers a credential with data + Then "Bob" has the credential issued + And wait 5 seconds + And "" lists revocation registries 2 + When "" offers a credential with data + Then "Bob" has the credential issued + And wait 5 seconds + And "" lists revocation registries 3 + When "" offers a credential with data + Then "Bob" has the credential issued + And wait 5 seconds + And "" lists revocation registries 4 + When "" offers a credential with data + Then "Bob" has the credential issued + And wait 5 seconds + And "" lists revocation registries 5 + When "" offers a credential with data + Then "Bob" has the credential issued + And wait 5 seconds + And "" lists revocation registries 6 + When "" offers a credential with data + Then "Bob" has the credential issued + And wait 5 seconds + And "" lists revocation registries 7 + When "" offers a credential with data + Then "Bob" has the credential issued + And "" lists revocation registries 8 + When "" offers a credential with data + Then "Bob" has the credential issued + And wait 5 seconds + + Examples: + | issuer | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Proof_request | + #| Acme | --revocation --public-did | | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + | Acme | --revocation --public-did --wallet-type askar-anoncreds | --wallet-type askar-anoncreds | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | diff --git a/demo/features/steps/0453-issue-credential.py b/demo/features/steps/0453-issue-credential.py index 41d5b65d9f..5ccee12d5b 100644 --- a/demo/features/steps/0453-issue-credential.py +++ b/demo/features/steps/0453-issue-credential.py @@ -5,6 +5,7 @@ from bdd_support.agent_backchannel_client import ( aries_container_create_schema_cred_def, + aries_container_check_exists_cred_def, aries_container_issue_credential, aries_container_receive_credential, read_schema_data, @@ -46,9 +47,7 @@ def step_impl(context, issuer, schema_name): # confirm the cred def was actually created # TODO for anoncreds, this should call the anoncreds/cred-def endpoint async_sleep(2.0) - cred_def_saved = agent_container_GET( - agent["agent"], "/credential-definitions/" + cred_def_id - ) + cred_def_saved = aries_container_check_exists_cred_def(agent["agent"], cred_def_id) assert cred_def_saved context.schema_name = schema_name diff --git a/demo/features/steps/0454-present-proof.py b/demo/features/steps/0454-present-proof.py index 8569f77821..030dd42f44 100644 --- a/demo/features/steps/0454-present-proof.py +++ b/demo/features/steps/0454-present-proof.py @@ -36,6 +36,20 @@ def step_impl(context, verifier, request_for_proof, prover): proof_request_info = read_proof_req_data(request_for_proof) + # replace any restrictions that need the cred def id... + cred_def_id = context.cred_def_id + cred_def_restrictions = [{"cred_def_id": cred_def_id}] + + if "cred_def_restriction" in proof_request_info["requested_attributes"]: + proof_request_info["requested_attributes"]["cred_def_restriction"][ + "restrictions" + ] = cred_def_restrictions + + if "cred_def_predicate" in proof_request_info["requested_predicates"]: + proof_request_info["requested_predicates"]["cred_def_predicate"][ + "restrictions" + ] = cred_def_restrictions + proof_exchange = aries_container_request_proof(agent["agent"], proof_request_info) context.proof_request = proof_request_info diff --git a/demo/features/steps/0586-sign-transaction.py b/demo/features/steps/0586-sign-transaction.py index 29dc2b29a8..204eca0cfa 100644 --- a/demo/features/steps/0586-sign-transaction.py +++ b/demo/features/steps/0586-sign-transaction.py @@ -10,6 +10,9 @@ async_sleep, read_json_data, read_schema_data, + aries_container_fetch_schemas, + aries_container_fetch_cred_defs, + aries_container_fetch_cred_def, ) from behave import given, then, when from runners.agent_container import AgentContainer @@ -179,6 +182,7 @@ def step_impl(context, agent_name): assert written_txn["state"] == "transaction_acked" +@given('"{agent_name}" has written the schema {schema_name} to the ledger') @when('"{agent_name}" has written the schema {schema_name} to the ledger') @then('"{agent_name}" has written the schema {schema_name} to the ledger') def step_impl(context, agent_name, schema_name): @@ -190,7 +194,7 @@ def step_impl(context, agent_name, schema_name): i = 5 while 0 == len(schemas["schema_ids"]) and i > 0: async_sleep(1.0) - schemas = agent_container_GET(agent["agent"], "/schemas/created") + schemas = aries_container_fetch_schemas(agent["agent"]) i = i - 1 assert len(schemas["schema_ids"]) == 1 @@ -210,7 +214,7 @@ def step_impl(context, agent_name, schema_name): connection_id = agent["agent"].agent.connection_id # TODO for now assume there is a single schema; should find the schema based on the supplied name - schemas = agent_container_GET(agent["agent"], "/schemas/created") + schemas = aries_container_fetch_schemas(agent["agent"]) assert len(schemas["schema_ids"]) == 1 schema_id = schemas["schema_ids"][0] @@ -236,6 +240,9 @@ def step_impl(context, agent_name, schema_name): context.txn_ids["AUTHOR"] = created_txn["txn"]["transaction_id"] +@given( + '"{agent_name}" has written the credential definition for {schema_name} to the ledger' +) @when( '"{agent_name}" has written the credential definition for {schema_name} to the ledger' ) @@ -251,16 +258,12 @@ def step_impl(context, agent_name, schema_name): i = 5 while 0 == len(cred_defs["credential_definition_ids"]) and i > 0: async_sleep(1.0) - cred_defs = agent_container_GET( - agent["agent"], "/credential-definitions/created" - ) + cred_defs = aries_container_fetch_cred_defs(agent["agent"]) i = i - 1 assert len(cred_defs["credential_definition_ids"]) == 1 cred_def_id = cred_defs["credential_definition_ids"][0] - cred_def = agent_container_GET( - agent["agent"], "/credential-definitions/" + cred_def_id - ) + cred_def = aries_container_fetch_cred_def(agent["agent"], cred_def_id) context.cred_def_id = cred_def_id @@ -314,6 +317,7 @@ def step_impl(context, agent_name, schema_name): context.txn_ids["AUTHOR"] = created_txn["txn"]["transaction_id"] +@given('"{agent_name}" has written the revocation registry definition to the ledger') @when('"{agent_name}" has written the revocation registry definition to the ledger') @then('"{agent_name}" has written the revocation registry definition to the ledger') def step_impl(context, agent_name): @@ -331,7 +335,7 @@ def step_impl(context, agent_name): }, ) i = i - 1 - assert len(rev_regs["rev_reg_ids"]) == 1 + assert len(rev_regs["rev_reg_ids"]) >= 1 rev_reg_id = rev_regs["rev_reg_ids"][0] @@ -364,6 +368,9 @@ def step_impl(context, agent_name): ) +@given( + '"{agent_name}" has written the revocation registry entry transaction to the ledger' +) @when( '"{agent_name}" has written the revocation registry entry transaction to the ledger' ) @@ -382,7 +389,7 @@ def step_impl(context, agent_name): f"/revocation/registry/{context.rev_reg_id}", ) state = reg_info["result"]["state"] - if state == "active": + if state in ["active", "finished"]: return i = i - 1 @@ -438,6 +445,7 @@ def step_impl(context, holder, schema_name, credential_data, issuer): ) +@given('"{agent_name}" revokes the credential without publishing the entry') @when('"{agent_name}" revokes the credential without publishing the entry') @then('"{agent_name}" revokes the credential without publishing the entry') def step_impl(context, agent_name): @@ -502,6 +510,7 @@ def step_impl(context, agent_name): async_sleep(3.0) +@given('"{agent_name}" authors a revocation registry entry publishing transaction') @when('"{agent_name}" authors a revocation registry entry publishing transaction') @then('"{agent_name}" authors a revocation registry entry publishing transaction') def step_impl(context, agent_name): @@ -585,3 +594,140 @@ def step_impl(context, holder_name, issuer_name): counter = counter + 1 async_sleep(1.0) assert revoc_status_bool is True + + +@given( + 'Without endorser, "{agent_name}" authors a schema transaction with {schema_name}' +) +def step_impl(context, agent_name, schema_name): + agent = context.active_agents[agent_name] + + schema_info = read_schema_data(schema_name) + connection_id = agent["agent"].agent.connection_id + + created_txn = agent_container_POST( + agent["agent"], + "/schemas", + data=schema_info["schema"], + params={"conn_id": connection_id, "create_transaction_for_endorser": "false"}, + ) + + # assert goodness + assert created_txn["schema_id"] + context.schema_id = created_txn["schema_id"] + + +@given( + 'Without endorser, "{agent_name}" authors a credential definition transaction with {schema_name}' +) +def step_impl(context, agent_name, schema_name): + agent = context.active_agents[agent_name] + + connection_id = agent["agent"].agent.connection_id + + # TODO for now assume there is a single schema; should find the schema based on the supplied name + schemas = agent_container_GET(agent["agent"], "/schemas/created") + assert len(schemas["schema_ids"]) == 1 + + schema_id = schemas["schema_ids"][0] + created_txn = agent_container_POST( + agent["agent"], + "/credential-definitions", + data={ + "schema_id": schema_id, + "tag": "test_cred_def_with_endorsement", + "support_revocation": True, + "revocation_registry_size": 1000, + }, + params={"conn_id": connection_id, "create_transaction_for_endorser": "false"}, + ) + + # assert goodness + assert created_txn["credential_definition_id"] + context.cred_def_id = created_txn["credential_definition_id"] + + +@given( + 'Without endorser, "{agent_name}" authors a revocation registry definition transaction for the credential definition matching {schema_name}' +) +def step_impl(context, agent_name, schema_name): + agent = context.active_agents[agent_name] + + connection_id = agent["agent"].agent.connection_id + + # generate revocation registry transaction + rev_reg = agent_container_POST( + agent["agent"], + "/revocation/create-registry", + data={"credential_definition_id": context.cred_def_id, "max_cred_num": 1000}, + params={}, + ) + rev_reg_id = rev_reg["result"]["revoc_reg_id"] + assert rev_reg_id is not None + + # update revocation registry + agent_container_PATCH( + agent["agent"], + f"/revocation/registry/{rev_reg_id}", + data={ + "tails_public_uri": f"http://host.docker.internal:6543/revocation/registry/{rev_reg_id}/tails-file" + }, + params={}, + ) + + # create rev_reg def + created_txn = agent_container_POST( + agent["agent"], + f"/revocation/registry/{rev_reg_id}/definition", + data={}, + params={ + "conn_id": connection_id, + "create_transaction_for_endorser": "false", + }, + ) + assert created_txn + context.rev_reg_id = rev_reg_id + + +@given( + 'Without endorser, "{agent_name}" has written the revocation registry definition to the ledger' +) +def step_impl(context, agent_name): + agent = context.active_agents[agent_name] + + rev_regs = {"rev_reg_ids": []} + i = 5 + while 0 == len(rev_regs["rev_reg_ids"]) and i > 0: + async_sleep(1.0) + rev_regs = agent_container_GET( + agent["agent"], + "/revocation/registries/created", + params={ + "cred_def_id": context.cred_def_id, + }, + ) + i = i - 1 + + assert context.rev_reg_id in rev_regs["rev_reg_ids"] + + +@given( + 'Without endorser, "{agent_name}" authors a revocation registry entry transaction for the credential definition matching {schema_name}' +) +def step_impl(context, agent_name, schema_name): + agent = context.active_agents[agent_name] + + connection_id = agent["agent"].agent.connection_id + + # generate revocation registry entry transaction + # create rev_reg transaction + created_txn = agent_container_POST( + agent["agent"], + f"/revocation/registry/{context.rev_reg_id}/entry", + data={}, + params={ + "conn_id": connection_id, + "create_transaction_for_endorser": "false", + }, + ) + assert created_txn diff --git a/demo/features/steps/revocation-api.py b/demo/features/steps/revocation-api.py new file mode 100644 index 0000000000..d7cfc271a8 --- /dev/null +++ b/demo/features/steps/revocation-api.py @@ -0,0 +1,84 @@ +from behave import given, when, then +import json +import os + +from bdd_support.agent_backchannel_client import ( + agent_container_GET, + agent_container_POST, + async_sleep, +) +from runners.agent_container import AgentContainer + + +BDD_EXTRA_AGENT_ARGS = os.getenv("BDD_EXTRA_AGENT_ARGS") + +# And "" lists revocation registries +# And "" rotates revocation registries + + +@given("wait {count} seconds") +@then("wait {count} seconds") +def step_impl(context, count=None): + if count: + print(f"sleeping for {count} seconds..") + async_sleep(int(count)) + + +@given('"{issuer}" lists revocation registries {count}') +@then('"{issuer}" lists revocation registries {count}') +def step_impl(context, issuer, count=None): + agent = context.active_agents[issuer] + async_sleep(5.0) + created_response = agent_container_GET( + agent["agent"], f"/revocation/registries/created" + ) + full_response = agent_container_GET( + agent["agent"], f"/revocation/registries/created", params={"state": "full"} + ) + decommissioned_response = agent_container_GET( + agent["agent"], + f"/revocation/registries/created", + params={"state": "decommissioned"}, + ) + finished_response = agent_container_GET( + agent["agent"], f"/revocation/registries/created", params={"state": "finished"} + ) + async_sleep(4.0) + if count: + print( + f"\nlists revocation registries ({count} creds) = = = = = = = = = = = = = =" + ) + else: + print( + "\nlists revocation registries = = = = = = = = = = = = = = = = = = = = = =" + ) + print("\ncreated_response: ", len(created_response["rev_reg_ids"])) + print("full_response: ", len(full_response["rev_reg_ids"])) + print("decommissioned_response:", len(decommissioned_response["rev_reg_ids"])) + print("finished_response: ", len(finished_response["rev_reg_ids"])) + async_sleep(1.0) + + +@given('"{issuer}" rotates revocation registries') +@then('"{issuer}" rotates revocation registries') +def step_impl(context, issuer): + agent = context.active_agents[issuer] + cred_def_id = context.cred_def_id + original_active_response = agent_container_GET( + agent["agent"], f"/revocation/active-registry/{cred_def_id}" + ) + print("original_active_response:", json.dumps(original_active_response)) + + rotate_response = agent_container_POST( + agent["agent"], + f"/revocation/active-registry/{cred_def_id}/rotate", + data={}, + ) + print("rotate_response:", json.dumps(rotate_response)) + + async_sleep(10.0) + + active_response = agent_container_GET( + agent["agent"], f"/revocation/active-registry/{cred_def_id}" + ) + print("active_response:", json.dumps(active_response)) diff --git a/demo/runners/agent_container.py b/demo/runners/agent_container.py index 2916fffb27..6dcff17115 100644 --- a/demo/runners/agent_container.py +++ b/demo/runners/agent_container.py @@ -919,6 +919,28 @@ async def create_schema_and_cred_def( else: raise Exception("Invalid credential type:" + self.cred_type) + async def fetch_schemas( + self, + ): + return await self.agent.fetch_schemas( + wallet_type=self.agent.wallet_type, + ) + + async def fetch_cred_defs( + self, + ): + return await self.agent.fetch_cred_defs( + wallet_type=self.agent.wallet_type, + ) + + async def fetch_cred_def( + self, + cred_def_id: str, + ): + return await self.agent.fetch_cred_def( + cred_def_id, wallet_type=self.agent.wallet_type + ) + async def issue_credential( self, cred_def_id: str, diff --git a/demo/runners/support/agent.py b/demo/runners/support/agent.py index 0983cc711f..64a7d1a562 100644 --- a/demo/runners/support/agent.py +++ b/demo/runners/support/agent.py @@ -291,6 +291,52 @@ async def register_schema_and_creddef( else: raise Exception("Invalid wallet_type: " + str(wallet_type)) + async def fetch_schemas( + self, + wallet_type=WALLET_TYPE_INDY, + ): + if wallet_type in [WALLET_TYPE_INDY, WALLET_TYPE_ASKAR]: + schemas_saved = await self.admin_GET("/schemas/created") + return schemas_saved + elif wallet_type == WALLET_TYPE_ANONCREDS: + schemas_saved = await self.admin_GET("/anoncreds/schemas") + return schemas_saved + else: + raise Exception("Invalid wallet_type: " + str(wallet_type)) + + async def fetch_cred_defs( + self, + wallet_type=WALLET_TYPE_INDY, + ): + if wallet_type in [WALLET_TYPE_INDY, WALLET_TYPE_ASKAR]: + cred_defs_saved = await self.admin_GET("/credential-definitions/created") + return cred_defs_saved + elif wallet_type == WALLET_TYPE_ANONCREDS: + cred_defs_saved = await self.admin_GET("/anoncreds/credential-definitions") + return { + "credential_definition_ids": cred_defs_saved, + } + else: + raise Exception("Invalid wallet_type: " + str(wallet_type)) + + async def fetch_cred_def( + self, + cred_def_id: str, + wallet_type=WALLET_TYPE_INDY, + ): + if wallet_type in [WALLET_TYPE_INDY, WALLET_TYPE_ASKAR]: + cred_def_saved = await self.admin_GET( + "/credential-definitions/" + cred_def_id + ) + return cred_def_saved + elif wallet_type == WALLET_TYPE_ANONCREDS: + cred_def_saved = await self.admin_GET( + "/anoncreds/credential-definition/" + cred_def_id + ) + return cred_def_saved + else: + raise Exception("Invalid wallet_type: " + str(wallet_type)) + async def register_schema_and_creddef_indy( self, schema_name,