diff --git a/CHANGELOG.md b/CHANGELOG.md index 509c65530f..e88287aec4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,21 @@ # Aries Cloud Agent Python Changelog -## 0.12.0rc2 +## 0.12.0rc3 -### March 5, 2024 +### April 8, 2024 -Release 0.12.0 is a relative large release but currently with no breaking changes. We expect there will be breaking changes (at least in the handling of endorsement) before the 0.12.0 release is finalized, hence the minor version update. +Release 0.12.0 is a relatively large release with many new capabilities, feature improvements, upgrades and bug fixes. Importantly, this release completes the ACA-Py implementation of [Aries Interop Profile v20], and enables the elimination of unqualified DIDs. While only deprecated for now, all deployments of ACA-Py to move to using only fully qualified DIDs. -The `rc0` release candidate introduced a regression via [PR \#2705] that has been reverted in `rc1` and later via [PR \#2789]. Further investigation is needed to determine how to accomplish the goal of [PR \#2705] ("feat: inject profile") without the regression. The `rc2` -and later releases address a regression related to the sending of a revocation notification from the issuer to the holder of a newly -revoked credential, fixed in [PR \#2814] +Much progress has been made on `did:peer` support in this release, with the handling of inbound [DID Peer] 1 added, and inbound and outbound support for DID Peer 2 and 4. Much attention was also paid to making sure that the Peer DID and DID Exchange capabilities match those of [Credo-TS] (formerly Aries Framework JavaScript). The completion of that work eliminates the remaining places where "unqualified" DIDs are being used, and to enable the "connection reuse" in the Out of Band protocol when using DID Peer 2 and 4 DIDs. See the document [Qualified DIDs] for details about how to control the use of DID Peer 2 or 4 in an ACA-Py deployment, and how to eliminate the use of unqualified DIDs. Support for DID Exchange v1.1 has been added to ACA-Py, with support for DID Exchange v1.0 retained, and we've added support for DID Rotation. -[PR \#2814]: https://github.com/hyperledger/aries-cloudagent-python/pull/2705 -[PR \#2705]: https://github.com/hyperledger/aries-cloudagent-python/pull/2705 -[PR \#2789]: https://github.com/hyperledger/aries-cloudagent-python/pull/2789 +[Qualified DIDs]: https://github.com/hyperledger/aries-cloudagent-python/blob/main/docs/features/QualifiedDIDs.md +[Credo-TS]: https://github.com/openwallet-foundation/credo-ts -Much progress has been made on `did:peer` support in this release, with the handling of inbound [DID Peer] 1 added, and inbound and outbound support for DID Peer 2 and 4. The goal of that work is to eliminate the remaining places where "unqualified" DIDs remain, and to enable the "connection reuse" in the Out of Band protocol when using DID Peer 2 and 4 DIDs. Work continues in supporting ledger agnostic [AnonCreds], and the new [Hyperledger AnonCreds Rust] library. Attention was also given in the release to the handling of JSON-LD [Data Integrity Verifiable Credentials], with more expected before the release is finalized. In addition to those updates, there were fixes and improvements across the codebase. +Work continues towards supporting ledger agnostic [AnonCreds], and the new [Hyperledger AnonCreds Rust] library. Some of that work is in this release, the rest will be in the next release. -The most visible change in this release is the re-organization of the ACA-Py documentation, moving the vast majority of the documents to the folders within the `docs` folder -- a long overdue change that will allow us to soon publish the documents on [https://aca-py.org](https://aca-py.org) directly from the ACA-Py repository, rather than from the separate [aries-acapy-docs](https://github.com/hyperledger/aries-acapy-docs) currently being used. +Attention was given in the release to simplifying the handling of JSON-LD [Data Integrity Verifiable Credentials]. + +An important change in this release is the re-organization of the ACA-Py documentation, moving the vast majority of the documents to the folders within the `docs` folder -- a long overdue change that will allow us to soon publish the documents on [https://aca-py.org](https://aca-py.org) directly from the ACA-Py repository, rather than from the separate [aries-acapy-docs](https://github.com/hyperledger/aries-acapy-docs) currently being used. A big developer improvement is a revamping of the test handling to eliminate ~2500 warnings that were previously generated in the test suite. Nice job [@ff137](https://github.com/ff137)! @@ -25,15 +24,33 @@ A big developer improvement is a revamping of the test handling to eliminate ~25 [Hyperledger AnonCreds Rust]: https://github.com/hyperledger/anoncreds-rs [Data Integrity Verifiable Credentials]: https://www.w3.org/TR/vc-data-integrity/ -### 0.12.0rc2 Breaking Changes +### 0.12.0rc3 Breaking Changes + +A deployment of this release that proactively uses DID Peer 2 and 4 will encounter problems interacting with agents deployed using older Aries protocols. Led by the Aries Working Group, the Aries community is encouraging the upgrade of all ecosystem deployments to accept all commonly used qualified DIDs, including DID Peer 2 and 4. See the document [Qualified DIDs] for more details about the transition to using only qualified DIDs. + +New deprecation notices were added to ACA-Py on startup and in the OpenAPI/Swagger interface. Those added are listed below. As well, we anticipate 0.12.0 being the **last ACA-Py release** to include support for the previously deprecated Indy SDK. -There are no breaking changes in 0.12.0rc2. +- RFC 0036 Issue Credential v1 + - Migrate to use RFC 0453 Issue Credential v2 +- RFC 0037 Present Proof v2 + - Migrate to use RFC 0454 Present Proof v2 +- RFC 0169 Connections + - Migrate to use RFC 0023 DID Exchange and 0434 Out-of-Band +- The use of `did:sov:...` as a Protocol Doc URI + - Migrate to use `https://didcomm.org/`. - + -#### 0.12.0rc2 Categorized List of Pull Requests +#### 0.12.0rc3 Categorized List of Pull Requests - DID Handling and Connection Establishment Updates/Fixes + - Emit the OOB done event even for multi-use invites [\#2872](https://github.com/hyperledger/aries-cloudagent-python/pull/2872) [ianco](https://github.com/ianco) + - refactor: introduce use_did and use_did_method [\#2862](https://github.com/hyperledger/aries-cloudagent-python/pull/2862) [dbluhm](https://github.com/dbluhm) + - fix(credo-interop): various didexchange and did:peer related fixes 1.0.0 [\#2748](https://github.com/hyperledger/aries-cloudagent-python/pull/2748) [dbluhm](https://github.com/dbluhm) + - Change did <--> verkey logging on connections [\#2853](https://github.com/hyperledger/aries-cloudagent-python/pull/2853) [jamshale](https://github.com/jamshale) + - fix: did exchange multiuse invites respond in kind [\#2850](https://github.com/hyperledger/aries-cloudagent-python/pull/2850) [dbluhm](https://github.com/dbluhm) + - Support connection re-use for did:peer:2/4 [\#2823](https://github.com/hyperledger/aries-cloudagent-python/pull/2823) [ianco](https://github.com/ianco) + - feat: did-rotate [\#2816](https://github.com/hyperledger/aries-cloudagent-python/pull/2816) [amanji](https://github.com/amanji) - Author subwallet setup automation [\#2791](https://github.com/hyperledger/aries-cloudagent-python/pull/2791) [jamshale](https://github.com/jamshale) - fix: save multi_use to the DB for OOB invitations [\#2694](https://github.com/hyperledger/aries-cloudagent-python/pull/2694) [frostyfrog](https://github.com/frostyfrog) - Connection and DIDX Problem Reports [\#2653](https://github.com/hyperledger/aries-cloudagent-python/pull/2653) [usingtechnology](https://github.com/usingtechnology) @@ -47,7 +64,9 @@ There are no breaking changes in 0.12.0rc2. - feat: add did:jwk resolver [\#2645](https://github.com/hyperledger/aries-cloudagent-python/pull/2645) [dbluhm](https://github.com/dbluhm) - feat: support resolving did:peer:1 received in did exchange [\#2611](https://github.com/hyperledger/aries-cloudagent-python/pull/2611) [dbluhm](https://github.com/dbluhm) -- Ledger Agnostic AnonCreds RS Changes +- AnonCreds and Ledger Agnostic AnonCreds RS Changes + - Prevent revocable cred def being created without tails server [\#2849](https://github.com/hyperledger/aries-cloudagent-python/pull/2849) [jamshale](https://github.com/jamshale) + - Anoncreds - support for anoncreds and askar wallets concurrently [\#2822](https://github.com/hyperledger/aries-cloudagent-python/pull/2822) [jamshale](https://github.com/jamshale) - Send revocation list instead of rev_list object - Anoncreds [\#2821](https://github.com/hyperledger/aries-cloudagent-python/pull/2821) [jamshale](https://github.com/jamshale) - Fix anoncreds non-endorsement revocation [\#2814](https://github.com/hyperledger/aries-cloudagent-python/pull/2814) [jamshale](https://github.com/jamshale) - Get and create anoncreds profile when using anoncreds subwallet [\#2803](https://github.com/hyperledger/aries-cloudagent-python/pull/2803) [jamshale](https://github.com/jamshale) - Add anoncreds multitenant endorsement integration tests [\#2801](https://github.com/hyperledger/aries-cloudagent-python/pull/2801) [jamshale](https://github.com/jamshale) @@ -69,12 +88,14 @@ There are no breaking changes in 0.12.0rc2. - Initial code migration from anoncreds-rs branch AnonCreds [\#2596](https://github.com/hyperledger/aries-cloudagent-python/pull/2596) [ianco](https://github.com/ianco) - Hyperledger Indy ledger related updates and fixes + - Remove requirement for write ledger in read-only mode. [\#2836](https://github.com/hyperledger/aries-cloudagent-python/pull/2836) [esune](https://github.com/esune) - Add known issues section to Multiledger.md documentation [\#2788](https://github.com/hyperledger/aries-cloudagent-python/pull/2788) [esune](https://github.com/esune) - fix: update constants in TransactionRecord [\#2698](https://github.com/hyperledger/aries-cloudagent-python/pull/2698) [amanji](https://github.com/amanji) - Cache TAA by wallet name [\#2676](https://github.com/hyperledger/aries-cloudagent-python/pull/2676) [jamshale](https://github.com/jamshale) - Fix: RevRegEntry Transaction Endorsement 0.11.0 [\#2558](https://github.com/hyperledger/aries-cloudagent-python/pull/2558) [shaangill025](https://github.com/shaangill025) - JSON-LD Verifiable Credential/DIF Presentation Exchange updates + - Add missing VC-DI/LD-Proof verification method option [\#2867](https://github.com/hyperledger/aries-cloudagent-python/pull/2867) [PatStLouis](https://github.com/PatStLouis) - Revert profile injection for VcLdpManager on vc-api endpoints [\#2794](https://github.com/hyperledger/aries-cloudagent-python/pull/2794) [PatStLouis](https://github.com/PatStLouis) - Add cached copy of BBS v1 context [\#2749](https://github.com/hyperledger/aries-cloudagent-python/pull/2749) [andrewwhitehead](https://github.com/andrewwhitehead) - Update BBS+ context to bypass redirections [\#2739](https://github.com/hyperledger/aries-cloudagent-python/pull/2739) [swcurran](https://github.com/swcurran) @@ -85,7 +106,8 @@ There are no breaking changes in 0.12.0rc2. - refactor: make ldp_vc logic reusable [\#2533](https://github.com/hyperledger/aries-cloudagent-python/pull/2533) [dbluhm](https://github.com/dbluhm) - Credential Exchange (Issue, Present) Updates - - Allow for crids in event payload to be integers [\#2819](https://github.com/hyperledger/aries-cloudagent-python/pull/2819) [jamshale](https://github.com/jamshale) - Create revocation notification after list entry written to ledger [\#2812](https://github.com/hyperledger/aries-cloudagent-python/pull/2812) [jamshale](https://github.com/jamshale) + - Allow for crids in event payload to be integers [\#2819](https://github.com/hyperledger/aries-cloudagent-python/pull/2819) [jamshale](https://github.com/jamshale) + - Create revocation notification after list entry written to ledger [\#2812](https://github.com/hyperledger/aries-cloudagent-python/pull/2812) [jamshale](https://github.com/jamshale) - Remove exception on connectionless presentation problem report handler [\#2723](https://github.com/hyperledger/aries-cloudagent-python/pull/2723) [loneil](https://github.com/loneil) - Ensure "preserve_exchange_records" flags are set. [\#2664](https://github.com/hyperledger/aries-cloudagent-python/pull/2664) [usingtechnology](https://github.com/usingtechnology) - Slight improvement to credx proof validation error message [\#2655](https://github.com/hyperledger/aries-cloudagent-python/pull/2655) [ianco](https://github.com/ianco) @@ -96,6 +118,14 @@ There are no breaking changes in 0.12.0rc2. - Improve Per Tenant Logging: Fix issues around default log file path [\#2659](https://github.com/hyperledger/aries-cloudagent-python/pull/2659) [shaangill025](https://github.com/shaangill025) - Other Fixes, Demo, DevContainer and Documentation Fixes + - chore: propose official deprecations of a couple of features [\#2856](https://github.com/hyperledger/aries-cloudagent-python/pull/2856) [dbluhm](https://github.com/dbluhm) + - feat: external signature suite provider interface [\#2835](https://github.com/hyperledger/aries-cloudagent-python/pull/2835) [dbluhm](https://github.com/dbluhm) + - Update GHA so that broken image links work on docs site - without breaking them on GitHub [\#2852](https://github.com/hyperledger/aries-cloudagent-python/pull/2852) [swcurran](https://github.com/swcurran) + - Minor updates to the documentation - links [\#2848](https://github.com/hyperledger/aries-cloudagent-python/pull/2848) [swcurran](https://github.com/swcurran) + - Update to run_demo script to support Apple M1 CPUs [\#2843](https://github.com/hyperledger/aries-cloudagent-python/pull/2843) [swcurran](https://github.com/swcurran) + - Add functionality for building and running agents seprately [\#2845](https://github.com/hyperledger/aries-cloudagent-python/pull/2845) [sarthakvijayvergiya](https://github.com/sarthakvijayvergiya) + - Cleanup of docs [\#2831](https://github.com/hyperledger/aries-cloudagent-python/pull/2831) [swcurran](https://github.com/swcurran) + - Create AnonCredsMethods.md [\#2832](https://github.com/hyperledger/aries-cloudagent-python/pull/2832) [swcurran](https://github.com/swcurran) - FIX: GHA update for doc publishing, fix doc file that was blanked [\#2820](https://github.com/hyperledger/aries-cloudagent-python/pull/2820) [swcurran](https://github.com/swcurran) - More updates to get docs publishing [\#2810](https://github.com/hyperledger/aries-cloudagent-python/pull/2810) [swcurran](https://github.com/swcurran) - Eliminate the double workflow event [\#2811](https://github.com/hyperledger/aries-cloudagent-python/pull/2811) [swcurran](https://github.com/swcurran) @@ -115,6 +145,14 @@ There are no breaking changes in 0.12.0rc2. - Update the ReadTheDocs config in case we do another 0.10.x release [\#2629](https://github.com/hyperledger/aries-cloudagent-python/pull/2629) [swcurran](https://github.com/swcurran) - Dependencies and Internal Updates + - chore(deps): Bump pillow from 10.2.0 to 10.3.0 dependencies python [\#2869](https://github.com/hyperledger/aries-cloudagent-python/pull/2869) [dependabot bot](https://github.com/dependabot bot) + - Fix run_tests script [\#2866](https://github.com/hyperledger/aries-cloudagent-python/pull/2866) [ianco](https://github.com/ianco) + - fix: states for discovery record to emit webhook [\#2858](https://github.com/hyperledger/aries-cloudagent-python/pull/2858) [dbluhm](https://github.com/dbluhm) + - Increase promote did retries [\#2854](https://github.com/hyperledger/aries-cloudagent-python/pull/2854) [jamshale](https://github.com/jamshale) + - chore(deps-dev): Bump black from 24.1.1 to 24.3.0 dependencies python [\#2847](https://github.com/hyperledger/aries-cloudagent-python/pull/2847) [dependabot bot](https://github.com/dependabot bot) + - chore(deps): Bump the all-actions group with 1 update dependencies github_actions [\#2844](https://github.com/hyperledger/aries-cloudagent-python/pull/2844) [dependabot bot](https://github.com/dependabot bot) + - patch for #2781: User Agent header in doc loader [\#2824](https://github.com/hyperledger/aries-cloudagent-python/pull/2824) [gmulhearn-anonyome](https://github.com/gmulhearn-anonyome) + - chore(deps): Bump jwcrypto from 1.5.4 to 1.5.6 dependencies python [\#2833](https://github.com/hyperledger/aries-cloudagent-python/pull/2833) [dependabot bot](https://github.com/dependabot bot) - bot chore(deps): Bump cryptography from 42.0.3 to 42.0.4 dependencies python [\#2805](https://github.com/hyperledger/aries-cloudagent-python/pull/2805) [dependabot](https://github.com/dependabot) - bot chore(deps): Bump the all-actions group with 3 updates dependencies github_actions [\#2815](https://github.com/hyperledger/aries-cloudagent-python/pull/2815) [dependabot](https://github.com/dependabot) - Change middleware registration order [\#2796](https://github.com/hyperledger/aries-cloudagent-python/pull/2796) [PatStLouis](https://github.com/PatStLouis) @@ -149,6 +187,7 @@ There are no breaking changes in 0.12.0rc2. - Update snyk workflow to execute on Pull Request [\#2658](https://github.com/hyperledger/aries-cloudagent-python/pull/2658) [usingtechnology](https://github.com/usingtechnology) - Release management pull requests + - 0.12.0rc3 [\#2878](https://github.com/hyperledger/aries-cloudagent-python/pull/2878) [swcurran](https://github.com/swcurran) - 0.12.0rc2 [\#2825](https://github.com/hyperledger/aries-cloudagent-python/pull/2825) [swcurran](https://github.com/swcurran) - 0.12.0rc1 [\#2800](https://github.com/hyperledger/aries-cloudagent-python/pull/2800) [swcurran](https://github.com/swcurran) - 0.12.0rc1 [\#2799](https://github.com/hyperledger/aries-cloudagent-python/pull/2799) [swcurran](https://github.com/swcurran) diff --git a/PUBLISHING.md b/PUBLISHING.md index 4aa7c91003..73f9205a97 100644 --- a/PUBLISHING.md +++ b/PUBLISHING.md @@ -103,7 +103,7 @@ Once you have the list of PRs: 6. Search across the repository for the previous version number and update it everywhere that makes sense. The CHANGELOG.md is a likely exception, and the - `pyproject.toml` in the root is **MUST**. You can skip (although it won't + `pyproject.toml` in the root **MUST** be updated. You can skip (although it won't hurt) to update the files in the `open-api` folder as they will be automagically updated by the next step in publishing. The incremented version number **MUST** adhere to the [Semantic Versioning @@ -114,7 +114,7 @@ Once you have the list of PRs: to better follow the semver rules. 7. Regenerate openapi.json and swagger.json by running - `./scripts/generate-open-api-spec`. + `../scripts/generate-open-api-spec` from within the `aries_cloudagent` folder. 8. Double check all of these steps above, and then submit a PR from the branch. Add this new PR to CHANGELOG.md so that all the PRs are included. diff --git a/aries_cloudagent/config/argparse.py b/aries_cloudagent/config/argparse.py index c7f24c8a62..9b8f33316f 100644 --- a/aries_cloudagent/config/argparse.py +++ b/aries_cloudagent/config/argparse.py @@ -1166,19 +1166,6 @@ def add_arguments(self, parser: ArgumentParser): "using unencrypted rather than encrypted tags" ), ) - parser.add_argument( - "--emit-did-peer-2", - action="store_true", - env_var="ACAPY_EMIT_DID_PEER_2", - help=("Emit did:peer:2 DIDs in DID Exchange Protocol"), - ) - - parser.add_argument( - "--emit-did-peer-4", - action="store_true", - env_var="ACAPY_EMIT_DID_PEER_4", - help=("Emit did:peer:4 DIDs in DID Exchange Protocol"), - ) def get_settings(self, args: Namespace) -> dict: """Get protocol settings.""" @@ -1246,11 +1233,6 @@ def get_settings(self, args: Namespace) -> dict: settings["exch_use_unencrypted_tags"] = True environ["EXCH_UNENCRYPTED_TAGS"] = "True" - if args.emit_did_peer_2: - settings["emit_did_peer_2"] = True - if args.emit_did_peer_4: - settings["emit_did_peer_4"] = True - return settings diff --git a/aries_cloudagent/connections/base_manager.py b/aries_cloudagent/connections/base_manager.py index f771752e46..dc59d54c49 100644 --- a/aries_cloudagent/connections/base_manager.py +++ b/aries_cloudagent/connections/base_manager.py @@ -53,7 +53,7 @@ from ..wallet.base import BaseWallet from ..wallet.crypto import create_keypair, seed_to_did from ..wallet.did_info import INVITATION_REUSE_KEY, DIDInfo, KeyInfo -from ..wallet.did_method import PEER2, PEER4, SOV +from ..wallet.did_method import PEER2, PEER4, SOV, DIDMethod from ..wallet.error import WalletNotFoundError from ..wallet.key_type import ED25519 from ..wallet.util import b64_to_bytes, bytes_to_b58 @@ -245,19 +245,20 @@ async def create_did_peer_2( async def fetch_invitation_reuse_did( self, - did_method: str, - ) -> DIDDoc: + did_method: DIDMethod, + ) -> Optional[DIDInfo]: """Fetch a DID from the wallet to use across multiple invitations. Args: did_method: The DID method used (e.g. PEER2 or PEER4) Returns: - The `DIDDoc` instance, or "None" if no DID is found + The `DIDInfo` instance, or "None" if no DID is found """ did_info = None async with self._profile.session() as session: wallet = session.inject(BaseWallet) + # TODO Iterating through all DIDs is problematic did_list = await wallet.get_local_dids() for did in did_list: if did.method == did_method and INVITATION_REUSE_KEY in did.metadata: diff --git a/aries_cloudagent/core/tests/test_conductor.py b/aries_cloudagent/core/tests/test_conductor.py index 5414c07bea..55a8ab0c4b 100644 --- a/aries_cloudagent/core/tests/test_conductor.py +++ b/aries_cloudagent/core/tests/test_conductor.py @@ -1149,6 +1149,8 @@ async def test_print_invite_connection(self): "debug.print_connections_invitation": True, "invite_base_url": "http://localhost", "wallet.type": "askar", + "default_endpoint": "http://localhost", + "default_label": "test", } ) conductor = test_module.Conductor(builder) diff --git a/aries_cloudagent/messaging/agent_message.py b/aries_cloudagent/messaging/agent_message.py index ccb5895183..9aee776528 100644 --- a/aries_cloudagent/messaging/agent_message.py +++ b/aries_cloudagent/messaging/agent_message.py @@ -335,7 +335,7 @@ def assign_thread_from(self, msg: "AgentMessage"): pthid = thread and thread.pthid self.assign_thread_id(thid, pthid) - def assign_thread_id(self, thid: str, pthid: Optional[str] = None): + def assign_thread_id(self, thid: Optional[str] = None, pthid: Optional[str] = None): """Assign a specific thread ID. Args: @@ -450,7 +450,6 @@ class Meta: # Avoid clobbering keywords _type = fields.Str( data_key="@type", - dump_only=True, required=False, metadata={ "description": "Message type", diff --git a/aries_cloudagent/messaging/tests/test_agent_message.py b/aries_cloudagent/messaging/tests/test_agent_message.py index bf3ee6fa85..8e67e1e63b 100644 --- a/aries_cloudagent/messaging/tests/test_agent_message.py +++ b/aries_cloudagent/messaging/tests/test_agent_message.py @@ -210,12 +210,12 @@ class BadImplementationClass(AgentMessageSchema): def test_extract_decorators_x(self): for serial in [ { - "@type": "signed-agent-message", + "@type": "doc/proto/1.0/signed-agent-message", "@id": "030ac9e6-0d60-49d3-a8c6-e7ce0be8df5a", "value": "Test value", }, { - "@type": "signed-agent-message", + "@type": "doc/proto/1.0/signed-agent-message", "@id": "030ac9e6-0d60-49d3-a8c6-e7ce0be8df5a", "value": "Test value", "value~sig": { @@ -231,7 +231,7 @@ def test_extract_decorators_x(self): }, }, { - "@type": "signed-agent-message", + "@type": "doc/proto/1.0/signed-agent-message", "@id": "030ac9e6-0d60-49d3-a8c6-e7ce0be8df5a", "superfluous~sig": { "@type": DIDCommPrefix.qualify_current( @@ -251,7 +251,7 @@ def test_extract_decorators_x(self): def test_serde(self): serial = { - "@type": "signed-agent-message", + "@type": "doc/proto/1.0/signed-agent-message", "@id": "030ac9e6-0d60-49d3-a8c6-e7ce0be8df5a", "value~sig": { "@type": DIDCommPrefix.qualify_current( diff --git a/aries_cloudagent/messaging/util.py b/aries_cloudagent/messaging/util.py index 7c924f6ef3..ac2feb5cae 100644 --- a/aries_cloudagent/messaging/util.py +++ b/aries_cloudagent/messaging/util.py @@ -6,7 +6,7 @@ from datetime import datetime, timedelta, timezone from hashlib import sha256 from math import floor -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Union LOGGER = logging.getLogger(__name__) @@ -151,7 +151,7 @@ def canon(raw_attr_name: str) -> str: def get_proto_default_version( versions: List[Dict[str, Any]], major_version: int = 1 -) -> Optional[str]: +) -> str: """Return default protocol version from version definition list.""" for version in versions: @@ -160,4 +160,4 @@ def get_proto_default_version( default_minor_version = version["current_minor_version"] return f"{default_major_version}.{default_minor_version}" - return None + return "1.0" diff --git a/aries_cloudagent/multitenant/admin/routes.py b/aries_cloudagent/multitenant/admin/routes.py index 889caefaf2..b2f8210270 100644 --- a/aries_cloudagent/multitenant/admin/routes.py +++ b/aries_cloudagent/multitenant/admin/routes.py @@ -36,8 +36,6 @@ "ACAPY_AUTO_VERIFY_PRESENTATION": "debug.auto_verify_presentation", "ACAPY_AUTO_WRITE_TRANSACTIONS": "endorser.auto_write", "ACAPY_CREATE_REVOCATION_TRANSACTIONS": "endorser.auto_create_rev_reg", - "ACAPY_EMIT_DID_PEER_2": "emit_did_peer_2", - "ACAPY_EMIT_DID_PEER_4": "emit_did_peer_4", "ACAPY_ENDORSER_ALIAS": "endorser.endorser_alias", "ACAPY_ENDORSER_INVITATION": "endorser.endorser_invitation", "ACAPY_ENDORSER_PUBLIC_DID": "endorser.endorser_public_did", @@ -63,8 +61,6 @@ "auto-respond-messages": "debug.auto_respond_messages", "auto-verify-presentation": "debug.auto_verify_presentation", "auto-write-transactions": "endorser.auto_write", - "emit-did-peer-2": "emit_did_peer_2", - "emit-did-peer-4": "emit_did_peer_4", "endorser-alias": "endorser.endorser_alias", "endorser-invitation": "endorser.endorser_invitation", "endorser-protocol-role": "endorser.protocol_role", diff --git a/aries_cloudagent/protocols/coordinate_mediation/v1_0/route_manager.py b/aries_cloudagent/protocols/coordinate_mediation/v1_0/route_manager.py index 4a21fa8c59..b3fb04cb29 100644 --- a/aries_cloudagent/protocols/coordinate_mediation/v1_0/route_manager.py +++ b/aries_cloudagent/protocols/coordinate_mediation/v1_0/route_manager.py @@ -227,9 +227,16 @@ async def route_invitation( raise ValueError("Expected connection to have invitation_key") - async def route_verkey(self, profile: Profile, verkey: str): + async def route_verkey( + self, + profile: Profile, + verkey: str, + mediation_record: Optional[MediationRecord] = None, + ): """Establish routing for a public DID.""" - return await self._route_for_key(profile, verkey, skip_if_exists=True) + return await self._route_for_key( + profile, verkey, mediation_record, skip_if_exists=True + ) async def route_public_did(self, profile: Profile, verkey: str): """Establish routing for a public DID. diff --git a/aries_cloudagent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py b/aries_cloudagent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py index ac23e8c4ef..9dfaf7d611 100644 --- a/aries_cloudagent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py +++ b/aries_cloudagent/protocols/coordinate_mediation/v1_0/tests/test_route_manager.py @@ -432,7 +432,7 @@ async def test_route_public_did(profile: Profile, route_manager: RouteManager): async def test_route_verkey(profile: Profile, route_manager: RouteManager): await route_manager.route_verkey(profile, "test-verkey") route_manager._route_for_key.assert_called_once_with( - profile, "test-verkey", skip_if_exists=True + profile, "test-verkey", None, skip_if_exists=True ) diff --git a/aries_cloudagent/protocols/didexchange/v1_0/manager.py b/aries_cloudagent/protocols/didexchange/v1_0/manager.py index b10f326772..0b12931e12 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/manager.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/manager.py @@ -51,6 +51,8 @@ class LegacyHandlingFallback(DIDXManagerError): class DIDXManager(BaseConnectionManager): """Class for managing connections under RFC 23 (DID exchange).""" + SUPPORTED_USE_DID_METHODS = ("did:peer:2", "did:peer:4") + def __init__(self, profile: Profile): """Initialize a DIDXManager. @@ -191,6 +193,8 @@ async def create_request_implicit( goal: Optional[str] = None, auto_accept: bool = False, protocol: Optional[str] = None, + use_did: Optional[str] = None, + use_did_method: Optional[str] = None, ) -> ConnRecord: """Create and send a request against a public DID only (no explicit invitation). @@ -208,32 +212,49 @@ async def create_request_implicit( The new `ConnRecord` instance """ - my_public_info = None - if use_public_did: - async with self.profile.session() as session: - wallet = session.inject(BaseWallet) - my_public_info = await wallet.get_public_did() - if not my_public_info: + + if use_did and use_did_method: + raise DIDXManagerError("Cannot specify both use_did and use_did_method") + + if use_public_did and use_did: + raise DIDXManagerError("Cannot specify both use_public_did and use_did") + + if use_public_did and use_did_method: + raise DIDXManagerError( + "Cannot specify both use_public_did and use_did_method" + ) + + my_info = None + async with self.profile.session() as session: + wallet = session.inject(BaseWallet) + if use_public_did: + my_info = await wallet.get_public_did() + if not my_info: raise WalletError("No public DID configured") if ( - my_public_info.did == their_public_did - or f"did:sov:{my_public_info.did}" == their_public_did + my_info.did == their_public_did + or f"did:sov:{my_info.did}" == their_public_did ): raise DIDXManagerError( "Cannot connect to yourself through public DID" ) + elif use_did: + my_info = await wallet.get_local_did(use_did) + + if my_info: try: await ConnRecord.retrieve_by_did( session, their_did=their_public_did, - my_did=my_public_info.did, + my_did=my_info.did, ) raise DIDXManagerError( "Connection already exists for their_did " - f"{their_public_did} and my_did {my_public_info.did}" + f"{their_public_did} and my_did {my_info.did}" ) except StorageNotFoundError: pass + auto_accept = bool( auto_accept or ( @@ -244,7 +265,7 @@ async def create_request_implicit( protocol = protocol or DIDEX_1_0 conn_rec = ConnRecord( my_did=( - my_public_info.did if my_public_info else None + my_info.did if my_info else None ), # create-request will fill in on local DID creation their_did=their_public_did, their_label=None, @@ -263,6 +284,7 @@ async def create_request_implicit( mediation_id=mediation_id, goal_code=goal_code, goal=goal, + use_did_method=use_did_method, ) conn_rec.request_id = request._id conn_rec.state = ConnRecord.State.REQUEST.rfc160 @@ -282,6 +304,7 @@ async def create_request( mediation_id: Optional[str] = None, goal_code: Optional[str] = None, goal: Optional[str] = None, + use_did_method: Optional[str] = None, ) -> DIDXRequest: """Create a new connection request for a previously-received invitation. @@ -297,6 +320,12 @@ async def create_request( A new `DIDXRequest` message to send to the other agent """ + if use_did_method and use_did_method not in self.SUPPORTED_USE_DID_METHODS: + raise DIDXManagerError( + f"Unsupported use_did_method: {use_did_method}. Supported methods: " + f"{self.SUPPORTED_USE_DID_METHODS}" + ) + # Mediation Support mediation_records = await self._route_manager.mediation_records_for_connection( self.profile, @@ -331,15 +360,16 @@ async def create_request( conn_rec, my_endpoints, mediation_records ) else: - emit_did_peer_2 = bool(self.profile.settings.get("emit_did_peer_2")) - emit_did_peer_4 = bool(self.profile.settings.get("emit_did_peer_4")) + if conn_rec.accept == ConnRecord.ACCEPT_AUTO or use_did_method is None: + # If we're auto accepting or engaging in 1.1 without setting a + # use_did_method, default to did:peer:4 + use_did_method = "did:peer:4" try: did, attach = await self._qualified_did_with_fallback( conn_rec, my_endpoints, mediation_records, - emit_did_peer_2, - emit_did_peer_4, + use_did_method, ) except LegacyHandlingFallback: did, attach = await self._legacy_did_with_attached_doc( @@ -377,20 +407,13 @@ async def _qualified_did_with_fallback( conn_rec: ConnRecord, my_endpoints: Sequence[str], mediation_records: List[MediationRecord], - emit_did_peer_2: bool, - emit_did_peer_4: bool, + use_did_method: Optional[str] = None, signing_key: Optional[str] = None, ) -> Tuple[str, Optional[AttachDecorator]]: """Create DID Exchange request using a qualified DID. Fall back to unqualified DID if settings don't cause did:peer emission. """ - if emit_did_peer_2 and emit_did_peer_4: - self._logger.warning( - "emit_did_peer_2 and emit_did_peer_4 both set, \ - using did:peer:4" - ) - if conn_rec.my_did: # DID should be public or qualified async with self.profile.session() as session: wallet = session.inject(BaseWallet) @@ -404,13 +427,14 @@ async def _qualified_did_with_fallback( raise LegacyHandlingFallback( "DID has been previously set and not public or qualified" ) - elif emit_did_peer_4: + elif use_did_method == "did:peer:4": my_info = await self.create_did_peer_4(my_endpoints, mediation_records) conn_rec.my_did = my_info.did - elif emit_did_peer_2: + elif use_did_method == "did:peer:2": my_info = await self.create_did_peer_2(my_endpoints, mediation_records) conn_rec.my_did = my_info.did else: + # We shouldn't hit this condition in practice raise LegacyHandlingFallback( "Use of qualified DIDs not set according to settings" ) @@ -771,14 +795,12 @@ async def create_response( my_endpoints.append(default_endpoint) my_endpoints.extend(self.profile.settings.get("additional_endpoints", [])) - respond_with_did_peer_2 = bool( - self.profile.settings.get("emit_did_peer_2") - or (conn_rec.their_did and conn_rec.their_did.startswith("did:peer:2")) - ) - respond_with_did_peer_4 = bool( - self.profile.settings.get("emit_did_peer_4") - or (conn_rec.their_did and conn_rec.their_did.startswith("did:peer:4")) - ) + if conn_rec.their_did and conn_rec.their_did.startswith("did:peer:2"): + use_did_method = "did:peer:2" + elif conn_rec.their_did and conn_rec.their_did.startswith("did:peer:4"): + use_did_method = "did:peer:4" + else: + use_did_method = None if use_public_did: async with self.profile.session() as session: @@ -804,8 +826,7 @@ async def create_response( conn_rec, my_endpoints, mediation_records, - respond_with_did_peer_2, - respond_with_did_peer_4, + use_did_method=use_did_method, signing_key=conn_rec.invitation_key, ) response = DIDXResponse(did=did, did_rotate_attach=attach) diff --git a/aries_cloudagent/protocols/didexchange/v1_0/routes.py b/aries_cloudagent/protocols/didexchange/v1_0/routes.py index 8f81bd715f..075089366b 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/routes.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/routes.py @@ -10,7 +10,6 @@ request_schema, response_schema, ) - from marshmallow import fields, validate from ....admin.request_context import AdminRequestContext @@ -26,6 +25,7 @@ UUID4_VALIDATE, ) from ....storage.error import StorageError, StorageNotFoundError +from ....wallet.base import BaseWallet from ....wallet.error import WalletError from .manager import DIDXManager, DIDXManagerError from .message_types import DIDEX_1_0, DIDEX_1_1, SPEC_URI @@ -44,6 +44,21 @@ class DIDXAcceptInvitationQueryStringSchema(OpenAPISchema): required=False, metadata={"description": "Label for connection request", "example": "Broker"}, ) + use_did = fields.Str( + required=False, + metadata={ + "description": "The DID to use to for this connection", + "example": "did:example:1234", + }, + ) + use_did_method = fields.Str( + required=False, + validate=validate.OneOf(DIDXManager.SUPPORTED_USE_DID_METHODS), + metadata={ + "description": "The DID method to use to generate a DID for this connection", + "example": "did:peer:4", + }, + ) class DIDXCreateRequestImplicitQueryStringSchema(OpenAPISchema): @@ -86,6 +101,21 @@ class DIDXCreateRequestImplicitQueryStringSchema(OpenAPISchema): use_public_did = fields.Boolean( required=False, metadata={"description": "Use public DID for this connection"} ) + use_did = fields.Str( + required=False, + metadata={ + "description": "The DID to use to for this connection", + "example": "did:example:1234", + }, + ) + use_did_method = fields.Str( + required=False, + validate=validate.OneOf(DIDXManager.SUPPORTED_USE_DID_METHODS), + metadata={ + "description": "The DID method to use to generate a DID for this connection", + "example": "did:peer:4", + }, + ) goal_code = fields.Str( required=False, metadata={ @@ -208,7 +238,7 @@ class DIDXRejectRequestSchema(OpenAPISchema): @match_info_schema(DIDXConnIdMatchInfoSchema()) @querystring_schema(DIDXAcceptInvitationQueryStringSchema()) @response_schema(ConnRecordSchema(), 200, description="") -async def didx_accept_invitation(request: web.BaseRequest): +async def didx_accept_invitation(request: web.Request): """Request handler for accepting a stored connection invitation. Args: @@ -225,17 +255,33 @@ async def didx_accept_invitation(request: web.BaseRequest): my_label = request.query.get("my_label") or None my_endpoint = request.query.get("my_endpoint") or None mediation_id = request.query.get("mediation_id") or None + use_did = request.query.get("use_did") or None + use_did_method = request.query.get("use_did_method") or None + + if use_did and use_did_method: + raise web.HTTPBadRequest( + reason="use_did and use_did_method are mutually exclusive" + ) profile = context.profile didx_mgr = DIDXManager(profile) try: async with profile.session() as session: conn_rec = await ConnRecord.retrieve_by_id(session, connection_id) + if use_did: + wallet = session.inject(BaseWallet) + did_info = await wallet.get_local_did(use_did) + conn_rec.my_did = did_info.did + await conn_rec.save( + session, reason="Set my_did from use_did on invite accept" + ) + didx_request = await didx_mgr.create_request( conn_rec=conn_rec, my_label=my_label, my_endpoint=my_endpoint, mediation_id=mediation_id, + use_did_method=use_did_method, ) result = conn_rec.serialize() except StorageNotFoundError as err: @@ -272,6 +318,8 @@ async def didx_create_request_implicit(request: web.BaseRequest): mediation_id = request.query.get("mediation_id") or None alias = request.query.get("alias") or None use_public_did = json.loads(request.query.get("use_public_did", "null")) + use_did = request.query.get("use_did") or None + use_did_method = request.query.get("use_did_method") or None goal_code = request.query.get("goal_code") or None goal = request.query.get("goal") or None auto_accept = json.loads(request.query.get("auto_accept", "null")) @@ -286,6 +334,8 @@ async def didx_create_request_implicit(request: web.BaseRequest): my_endpoint=my_endpoint, mediation_id=mediation_id, use_public_did=use_public_did, + use_did=use_did, + use_did_method=use_did_method, alias=alias, goal_code=goal_code, goal=goal, diff --git a/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py b/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py index feb7020ce2..5066aaf9dd 100644 --- a/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py +++ b/aries_cloudagent/protocols/didexchange/v1_0/tests/test_manager.py @@ -5,6 +5,7 @@ from aries_cloudagent.tests import mock +from .. import manager as test_module from .....admin.server import AdminResponder from .....cache.base import BaseCache from .....cache.in_memory import InMemoryCache @@ -23,7 +24,7 @@ from .....storage.error import StorageNotFoundError from .....transport.inbound.receipt import MessageReceipt from .....wallet.did_info import DIDInfo -from .....wallet.did_method import PEER2, PEER4, SOV, DIDMethods +from .....wallet.did_method import DIDMethods, PEER2, PEER4, SOV from .....wallet.error import WalletError from .....wallet.in_memory import InMemoryWallet from .....wallet.key_type import ED25519 @@ -35,9 +36,10 @@ from ....out_of_band.v1_0.manager import OutOfBandManager from ....out_of_band.v1_0.messages.invitation import HSProto, InvitationMessage from ....out_of_band.v1_0.messages.service import Service as OOBService -from .. import manager as test_module from ..manager import DIDXManager, DIDXManagerError +from ..message_types import DIDEX_1_0, DIDEX_1_1 from ..messages.problem_report import DIDXProblemReport, ProblemReportReason +from ..messages.request import DIDXRequest class TestConfig: @@ -467,7 +469,6 @@ async def test_create_request_mediation_id(self): await mediation_record.save(session) invi = InvitationMessage( - comment="test", handshake_protocols=[ pfx.qualify(HSProto.RFC23.name) for pfx in DIDCommPrefix ], @@ -551,15 +552,13 @@ async def test_create_request_emit_did_peer_2(self): key_type=ED25519, ) - self.profile.context.update_settings({"emit_did_peer_2": True}) - with mock.patch.object( self.manager, "create_did_peer_2", mock.AsyncMock(return_value=mock_did_info), ) as mock_create_did_peer_2: request = await self.manager.create_request( - mock_conn_rec, + mock_conn_rec, use_did_method="did:peer:2" ) assert request.did_doc_attach is None mock_create_did_peer_2.assert_called_once() @@ -583,15 +582,13 @@ async def test_create_request_emit_did_peer_4(self): key_type=ED25519, ) - self.profile.context.update_settings({"emit_did_peer_4": True}) - with mock.patch.object( self.manager, "create_did_peer_4", mock.AsyncMock(return_value=mock_did_info), ) as mock_create_did_peer_4: request = await self.manager.create_request( - mock_conn_rec, + mock_conn_rec, use_did_method="did:peer:4" ) assert request.did_doc_attach is None mock_create_did_peer_4.assert_called_once() @@ -1489,7 +1486,6 @@ async def test_create_response_mediation_id(self): await mediation_record.save(session) invi = InvitationMessage( - comment="test", handshake_protocols=[ pfx.qualify(HSProto.RFC23.name) for pfx in DIDCommPrefix ], @@ -1542,7 +1538,6 @@ async def test_create_response_mediation_id_invalid_conn_state(self): await mediation_record.save(session) invi = InvitationMessage( - comment="test", handshake_protocols=[ pfx.qualify(HSProto.RFC23.name) for pfx in DIDCommPrefix ], @@ -2269,3 +2264,37 @@ async def test_receive_problem_report_x_unrecognized_code(self): with self.assertRaises(DIDXManagerError) as context: await self.manager.receive_problem_report(mock_conn, report) assert "unrecognized problem report" in str(context.exception) + + def test_handshake_proto_to_use(self): + request = DIDXRequest(_version="1.0") + assert self.manager._handshake_protocol_to_use(request) == DIDEX_1_0 + request = DIDXRequest(_version="1.1") + assert self.manager._handshake_protocol_to_use(request) == DIDEX_1_1 + + raw_request = { + "@type": "https://didcomm.org/didexchange/1.0/request", + "@id": "fe838693-d51d-4225-a52b-30c38c2ec396", + "~thread": { + "thid": "fe838693-d51d-4225-a52b-30c38c2ec396", + "pthid": "09dce45f-aeff-4101-bee1-5a577a11d30f", + }, + "label": "Robert Sr", + "did": "BsXa64NdRhXhRM3uDWwT45", + "did_doc~attach": { + "@id": "8c0a141c-a394-4c1b-86a7-122fc0ce383e", + "mime-type": "application/json", + "data": { + "base64": "eyJAY29udGV4dCI6ICJodHRwczovL3czaWQub3JnL2RpZC92MSIsICJpZCI6ICJkaWQ6c292OkJzWGE2NE5kUmhYaFJNM3VEV3dUNDUiLCAicHVibGljS2V5IjogW3siaWQiOiAiZGlkOnNvdjpCc1hhNjROZFJoWGhSTTN1RFd3VDQ1IzEiLCAidHlwZSI6ICJFZDI1NTE5VmVyaWZpY2F0aW9uS2V5MjAxOCIsICJjb250cm9sbGVyIjogImRpZDpzb3Y6QnNYYTY0TmRSaFhoUk0zdURXd1Q0NSIsICJwdWJsaWNLZXlCYXNlNTgiOiAiNnZmQ3B5dWF2dHdDS0xKSlFocjV4TmNhVGVaYUx5b3RjVWRlYlN3UWVzWTkifV0sICJhdXRoZW50aWNhdGlvbiI6IFt7InR5cGUiOiAiRWQyNTUxOVNpZ25hdHVyZUF1dGhlbnRpY2F0aW9uMjAxOCIsICJwdWJsaWNLZXkiOiAiZGlkOnNvdjpCc1hhNjROZFJoWGhSTTN1RFd3VDQ1IzEifV0sICJzZXJ2aWNlIjogW3siaWQiOiAiZGlkOnNvdjpCc1hhNjROZFJoWGhSTTN1RFd3VDQ1O2luZHkiLCAidHlwZSI6ICJJbmR5QWdlbnQiLCAicHJpb3JpdHkiOiAwLCAicmVjaXBpZW50S2V5cyI6IFsiNnZmQ3B5dWF2dHdDS0xKSlFocjV4TmNhVGVaYUx5b3RjVWRlYlN3UWVzWTkiXSwgInNlcnZpY2VFbmRwb2ludCI6ICJodHRwOi8vcm9iZXJ0OjMwMDAifV19", + "jws": { + "header": { + "kid": "did:key:z6MkkNvFREA2GSRfRq916GovoUAaHDqRks4FJVYaRiuRa6KX" + }, + "protected": "eyJhbGciOiAiRWREU0EiLCAia2lkIjogImRpZDprZXk6ejZNa2tOdkZSRUEyR1NSZlJxOTE2R292b1VBYUhEcVJrczRGSlZZYVJpdVJhNktYIiwgImp3ayI6IHsia3R5IjogIk9LUCIsICJjcnYiOiAiRWQyNTUxOSIsICJ4IjogIldBbHFNYk5lLUVsRk1jQU1NSm1uR3IwenhHUVR0TXlCU2lFcnhHT1NuazQiLCAia2lkIjogImRpZDprZXk6ejZNa2tOdkZSRUEyR1NSZlJxOTE2R292b1VBYUhEcVJrczRGSlZZYVJpdVJhNktYIn19", + "signature": "JEROrpnqqHMWbxV8d3fl5MYVPVZuS2vT44esf0dbYnV5BYsv5U25qoeFUuPspq2DXdWb4xDV0J8mFhq8gpz1Ag", + }, + }, + }, + } + request = DIDXRequest.deserialize(raw_request) + assert request._version == "1.0" + assert self.manager._handshake_protocol_to_use(request) == DIDEX_1_0 diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py index 382f7aecfb..590a4a70b0 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/manager.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/manager.py @@ -3,43 +3,49 @@ import asyncio import logging import re -from typing import Mapping, Optional, Sequence, Union, Text +from typing import List, Mapping, NamedTuple, Optional, Sequence, Text, Union import uuid +from aries_cloudagent.protocols.coordinate_mediation.v1_0.route_manager import ( + RouteManager, +) +from aries_cloudagent.wallet.error import WalletNotFoundError -from ....messaging.decorators.service_decorator import ServiceDecorator -from ....core.event_bus import EventBus from ....connections.base_manager import BaseConnectionManager from ....connections.models.conn_record import ConnRecord from ....core.error import BaseError +from ....core.event_bus import EventBus from ....core.oob_processor import OobMessageProcessor from ....core.profile import Profile from ....did.did_key import DIDKey +from ....messaging.decorators.attach_decorator import AttachDecorator +from ....messaging.decorators.service_decorator import ServiceDecorator from ....messaging.responder import BaseResponder from ....messaging.valid import IndyDID from ....storage.error import StorageNotFoundError from ....transport.inbound.receipt import MessageReceipt from ....wallet.base import BaseWallet -from ....wallet.did_info import INVITATION_REUSE_KEY +from ....wallet.did_info import INVITATION_REUSE_KEY, DIDInfo from ....wallet.did_method import PEER2, PEER4 from ....wallet.key_type import ED25519 from ...connections.v1_0.manager import ConnectionManager from ...connections.v1_0.messages.connection_invitation import ConnectionInvitation +from ...coordinate_mediation.v1_0.models.mediation_record import MediationRecord from ...didcomm_prefix import DIDCommPrefix from ...didexchange.v1_0.manager import DIDXManager from ...issue_credential.v1_0.models.credential_exchange import V10CredentialExchange from ...issue_credential.v2_0.models.cred_ex_record import V20CredExRecord from ...present_proof.v1_0.models.presentation_exchange import V10PresentationExchange from ...present_proof.v2_0.models.pres_exchange import V20PresExRecord +from .message_types import DEFAULT_VERSION from .messages.invitation import HSProto, InvitationMessage from .messages.problem_report import OOBProblemReport from .messages.reuse import HandshakeReuse from .messages.reuse_accept import HandshakeReuseAccept from .messages.service import Service as ServiceMessage +from .messages.service import Service from .models.invitation import InvitationRecord from .models.oob_record import OobRecord -from .messages.service import Service -from .message_types import DEFAULT_VERSION LOGGER = logging.getLogger(__name__) REUSE_WEBHOOK_TOPIC = "acapy::webhook::connection_reuse" @@ -54,93 +60,48 @@ class OutOfBandManagerNotImplementedError(BaseError): """Out of band error for unimplemented functionality.""" -class OutOfBandManager(BaseConnectionManager): - """Class for managing out of band messages.""" - - def __init__(self, profile: Profile): - """Initialize a OutOfBandManager. - - Args: - profile: The profile for this out of band manager - """ - self._profile = profile - super().__init__(self._profile) - - @property - def profile(self) -> Profile: - """Accessor for the current profile. +class InvitationCreator: + """Class for creating an out of band invitation.""" - Returns: - The profile for this connection manager + class CreateResult(NamedTuple): + """Result from creating an invitation.""" - """ - return self._profile + invitation_url: str + invitation: InvitationMessage + our_recipient_key: str + connection: Optional[ConnRecord] + service: Optional[ServiceDecorator] - async def create_invitation( + def __init__( self, - my_label: str = None, - my_endpoint: str = None, - auto_accept: bool = None, + profile: Profile, + route_manager: RouteManager, + oob: "OutOfBandManager", + my_label: Optional[str] = None, + my_endpoint: Optional[str] = None, + auto_accept: Optional[bool] = None, public: bool = False, - did_peer_2: bool = False, - did_peer_4: bool = False, - hs_protos: Sequence[HSProto] = None, + use_did: Optional[str] = None, + use_did_method: Optional[str] = None, + hs_protos: Optional[Sequence[HSProto]] = None, multi_use: bool = False, create_unique_did: bool = False, - alias: str = None, - attachments: Sequence[Mapping] = None, - metadata: dict = None, - mediation_id: str = None, + alias: Optional[str] = None, + attachments: Optional[Sequence[Mapping]] = None, + metadata: Optional[dict] = None, + mediation_id: Optional[str] = None, service_accept: Optional[Sequence[Text]] = None, protocol_version: Optional[Text] = None, goal_code: Optional[Text] = None, goal: Optional[Text] = None, - ) -> InvitationRecord: - """Generate new connection invitation. - - This interaction represents an out-of-band communication channel. In the future - and in practice, these sort of invitations will be received over any number of - channels such as SMS, Email, QR Code, NFC, etc. - - Args: - my_label: label for this connection - my_endpoint: endpoint where other party can reach me - auto_accept: auto-accept a corresponding connection request - (None to use config) - public: set to create an invitation from the public DID - hs_protos: list of handshake protocols to include - multi_use: set to True to create an invitation for multiple-use connection - alias: optional alias to apply to connection for later use - attachments: list of dicts in form of {"id": ..., "type": ...} - service_accept: Optional list of mime types in the order of preference of - the sender that the receiver can use in responding to the message - protocol_version: OOB protocol version [1.0, 1.1] - goal_code: Optional self-attested code for receiver logic - goal: Optional self-attested string for receiver logic - Returns: - Invitation record - - """ - mediation_record = await self._route_manager.mediation_record_if_id( - self.profile, - mediation_id, - or_default=True, - ) - image_url = self.profile.context.settings.get("image_url") - + ): + """Initialize the invitation creator.""" if not (hs_protos or attachments): raise OutOfBandManagerError( "Invitation must include handshake protocols, " "request attachments, or both" ) - auto_accept = bool( - auto_accept - or ( - auto_accept is None - and self.profile.settings.get("debug.auto_accept_requests") - ) - ) if not hs_protos and metadata: raise OutOfBandManagerError( "Cannot store metadata without handshake protocols" @@ -151,361 +112,531 @@ async def create_invitation( "Cannot create multi use invitation with attachments" ) - invitation_message_id = str(uuid.uuid4()) + if public and use_did: + raise OutOfBandManagerError("use_did and public are mutually exclusive") - message_attachments = [] - for atch in attachments or []: - a_type = atch.get("type") - a_id = atch.get("id") + if public and use_did_method: + raise OutOfBandManagerError( + "use_did_method and public are mutually exclusive" + ) + + if use_did and use_did_method: + raise OutOfBandManagerError( + "use_did and use_did_method are mutually exclusive" + ) + + if create_unique_did and not use_did_method: + LOGGER.error( + "create_unique_did: `%s`, use_did_method: `%s`", + create_unique_did, + use_did_method, + ) + raise OutOfBandManagerError( + "create_unique_did can only be used with use_did_method" + ) + + if ( + use_did_method + and use_did_method not in DIDXManager.SUPPORTED_USE_DID_METHODS + ): + raise OutOfBandManagerError(f"Unsupported use_did_method: {use_did_method}") + + self.profile = profile + self.route_manager = route_manager + self.oob = oob + + self.msg_id = str(uuid.uuid4()) + self.attachments = attachments + + self.handshake_protocols = [ + DIDCommPrefix.qualify_current(hsp.name) for hsp in hs_protos or [] + ] or None + + if not my_endpoint: + my_endpoint = self.profile.settings.get("default_endpoint") + assert my_endpoint + self.my_endpoint = my_endpoint - message = None + self.version = protocol_version or DEFAULT_VERSION + if not my_label: + my_label = self.profile.settings.get("default_label") + assert my_label + self.my_label = my_label + + self.accept = service_accept if protocol_version != "1.0" else None + self.invitation_mode = ( + ConnRecord.INVITATION_MODE_MULTI + if multi_use + else ConnRecord.INVITATION_MODE_ONCE + ) + self.alias = alias + + auto_accept = bool( + auto_accept + or ( + auto_accept is None + and self.profile.settings.get("debug.auto_accept_requests") + ) + ) + self.auto_accept = ( + ConnRecord.ACCEPT_AUTO if auto_accept else ConnRecord.ACCEPT_MANUAL + ) + self.goal = goal + self.goal_code = goal_code + self.public = public + self.use_did = use_did + self.use_did_method = use_did_method + self.multi_use = multi_use + self.create_unique_did = create_unique_did + self.image_url = self.profile.context.settings.get("image_url") + + self.mediation_id = mediation_id + self.metadata = metadata + + async def create_attachment( + self, attachment: Mapping, pthid: str + ) -> AttachDecorator: + """Create attachment for OOB invitation.""" + a_type = attachment.get("type") + a_id = attachment.get("id") + + if not a_type or not a_id: + raise OutOfBandManagerError("Attachment must include type and id") + + async with self.profile.session() as session: if a_type == "credential-offer": try: - async with self.profile.session() as session: - cred_ex_rec = await V10CredentialExchange.retrieve_by_id( - session, - a_id, - ) - message = cred_ex_rec.credential_offer_dict.serialize() + cred_ex_rec = await V10CredentialExchange.retrieve_by_id( + session, + a_id, + ) + message = cred_ex_rec.credential_offer_dict except StorageNotFoundError: - async with self.profile.session() as session: - cred_ex_rec = await V20CredExRecord.retrieve_by_id( - session, - a_id, - ) - message = cred_ex_rec.cred_offer.serialize() + cred_ex_rec = await V20CredExRecord.retrieve_by_id( + session, + a_id, + ) + message = cred_ex_rec.cred_offer elif a_type == "present-proof": try: - async with self.profile.session() as session: - pres_ex_rec = await V10PresentationExchange.retrieve_by_id( - session, - a_id, - ) - message = pres_ex_rec.presentation_request_dict.serialize() + pres_ex_rec = await V10PresentationExchange.retrieve_by_id( + session, + a_id, + ) + message = pres_ex_rec.presentation_request_dict except StorageNotFoundError: - async with self.profile.session() as session: - pres_ex_rec = await V20PresExRecord.retrieve_by_id( - session, - a_id, - ) - message = pres_ex_rec.pres_request.serialize() + pres_ex_rec = await V20PresExRecord.retrieve_by_id( + session, + a_id, + ) + message = pres_ex_rec.pres_request else: raise OutOfBandManagerError(f"Unknown attachment type: {a_type}") - # Assign pthid to the attached message - message["~thread"] = { - **message.get("~thread", {}), - "pthid": invitation_message_id, - } - message_attachments.append(InvitationMessage.wrap_message(message)) + message.assign_thread_id(pthid=pthid) + return InvitationMessage.wrap_message(message.serialize()) - handshake_protocols = [ - DIDCommPrefix.qualify_current(hsp.name) for hsp in hs_protos or [] - ] or None - # Handshake protocol list should be ordered by preference by caller - connection_protocol = ( - hs_protos[0].name if hs_protos and len(hs_protos) >= 1 else None + async def create_attachments( + self, + invitation_msg_id: str, + attachments: Optional[Sequence[Mapping]] = None, + ) -> List[AttachDecorator]: + """Create attachments for OOB invitation.""" + return [ + await self.create_attachment(attachment, invitation_msg_id) + for attachment in attachments or [] + ] + + async def create(self) -> InvitationRecord: + """Create the invitation, returning the result as an InvitationRecord.""" + attachments = await self.create_attachments(self.msg_id, self.attachments) + mediation_record = await self.oob._route_manager.mediation_record_if_id( + self.profile, self.mediation_id, or_default=True ) - our_recipient_key = None - our_service = None - conn_rec = None + if self.public: + result = await self.handle_public(attachments, mediation_record) + elif self.use_did: + result = await self.handle_use_did(attachments, mediation_record) + elif self.use_did_method: + result = await self.handle_use_did_method(attachments, mediation_record) + else: + result = await self.handle_legacy_invite_key(attachments, mediation_record) - if public: - if not self.profile.settings.get("public_invites"): - raise OutOfBandManagerError("Public invitations are not enabled") + oob_record = OobRecord( + role=OobRecord.ROLE_SENDER, + state=OobRecord.STATE_AWAIT_RESPONSE, + connection_id=( + result.connection.connection_id if result.connection else None + ), + invi_msg_id=self.msg_id, + invitation=result.invitation, + our_recipient_key=result.our_recipient_key, + our_service=result.service, + multi_use=self.multi_use, + ) - async with self.profile.session() as session: - wallet = session.inject(BaseWallet) - public_did = await wallet.get_public_did() + async with self.profile.session() as session: + await oob_record.save(session, reason="Created new oob invitation") - if not public_did: - raise OutOfBandManagerError( - "Cannot create public invitation with no public DID" - ) + return InvitationRecord( + oob_id=oob_record.oob_id, + state=InvitationRecord.STATE_INITIAL, + invi_msg_id=self.msg_id, + invitation=result.invitation, + invitation_url=result.invitation_url, + ) - public_did_did = public_did.did - if bool(IndyDID.PATTERN.match(public_did.did)): - public_did_did = f"did:sov:{public_did.did}" - - invi_msg = InvitationMessage( # create invitation message - _id=invitation_message_id, - label=my_label or self.profile.settings.get("default_label"), - handshake_protocols=handshake_protocols, - requests_attach=message_attachments, - services=[public_did_did], - accept=service_accept if protocol_version != "1.0" else None, - version=protocol_version or DEFAULT_VERSION, - image_url=image_url, - ) + async def handle_handshake_protos( + self, + invitation_key: str, + msg: InvitationMessage, + mediation_record: Optional[MediationRecord], + ) -> ConnRecord: + """Handle handshake protocol options, creating a ConnRecord. + + When handshake protocols are included in the create request, that means + we intend to create a connection for the invitation. When absent, + no connection is created, representing a connectionless exchange. + """ + assert self.handshake_protocols + conn_rec = ConnRecord( + invitation_key=invitation_key, + invitation_msg_id=self.msg_id, + invitation_mode=self.invitation_mode, + their_role=ConnRecord.Role.REQUESTER.rfc23, + state=ConnRecord.State.INVITATION.rfc23, + accept=self.auto_accept, + alias=self.alias, + ) - our_recipient_key = public_did.verkey + async with self.profile.transaction() as session: + await conn_rec.save(session, reason="Created new invitation") + await conn_rec.attach_invitation(session, msg) - endpoint, *_ = await self.resolve_invitation(public_did.did) - invi_url = invi_msg.to_url(endpoint) + if self.metadata: + for key, value in self.metadata.items(): + await conn_rec.metadata_set(session, key, value) - # Only create connection record if hanshake_protocols is defined - if handshake_protocols: - invitation_mode = ( - ConnRecord.INVITATION_MODE_MULTI - if multi_use - else ConnRecord.INVITATION_MODE_ONCE - ) - conn_rec = ConnRecord( # create connection record - invitation_key=public_did.verkey, - invitation_msg_id=invi_msg._id, - invitation_mode=invitation_mode, - their_role=ConnRecord.Role.REQUESTER.rfc23, - state=ConnRecord.State.INVITATION.rfc23, - accept=( - ConnRecord.ACCEPT_AUTO - if auto_accept - else ConnRecord.ACCEPT_MANUAL - ), - alias=alias, - connection_protocol=connection_protocol, - ) + await session.commit() - async with self.profile.session() as session: - await conn_rec.save(session, reason="Created new invitation") - await conn_rec.attach_invitation(session, invi_msg) + await self.route_manager.route_invitation( + self.profile, conn_rec, mediation_record + ) - await conn_rec.attach_invitation(session, invi_msg) + return conn_rec - if metadata: - for key, value in metadata.items(): - await conn_rec.metadata_set(session, key, value) - else: - our_service = ServiceDecorator( - recipient_keys=[our_recipient_key], - endpoint=endpoint, - routing_keys=[], - ).serialize() + def did_key_to_key(self, did_key: str) -> str: + """Convert a DID key to a key.""" + if did_key.startswith("did:key:"): + return DIDKey.from_did(did_key).public_key_b58 + return did_key - elif did_peer_4 or did_peer_2: - mediation_records = [mediation_record] if mediation_record else [] + def did_keys_to_keys(self, did_keys: Sequence[str]) -> List[str]: + """Convert DID keys to keys.""" + return [self.did_key_to_key(did_key) for did_key in did_keys] - if my_endpoint: - my_endpoints = [my_endpoint] - else: - my_endpoints = [] - default_endpoint = self.profile.settings.get("default_endpoint") - if default_endpoint: - my_endpoints.append(default_endpoint) - my_endpoints.extend( - self.profile.settings.get("additional_endpoints", []) - ) + async def handle_did( + self, + did_info: DIDInfo, + attachments: Sequence[AttachDecorator], + mediation_record: Optional[MediationRecord], + ) -> CreateResult: + """Handle use_did invitation creation.""" + invi_msg = InvitationMessage( + _id=self.msg_id, + label=self.my_label, + handshake_protocols=self.handshake_protocols, + requests_attach=attachments or None, + services=[did_info.did], + accept=self.accept, + version=self.version, + image_url=self.image_url, + ) + endpoint, recipient_keys, routing_keys = await self.oob.resolve_invitation( + did_info.did + ) + invi_url = invi_msg.to_url(endpoint) - my_info = None - my_did = None - if not create_unique_did: - # check wallet to see if there is an existing "invitation" DID available - did_method = PEER4 if did_peer_4 else PEER2 - my_info = await self.fetch_invitation_reuse_did(did_method) - if my_info: - my_did = my_info.did - else: - LOGGER.warn("No invitation DID found, creating new DID") - - if not my_did: - did_metadata = ( - {INVITATION_REUSE_KEY: "true"} if not create_unique_did else {} - ) - if did_peer_4: - my_info = await self.create_did_peer_4( - my_endpoints, mediation_records, did_metadata - ) - my_did = my_info.did - else: - my_info = await self.create_did_peer_2( - my_endpoints, mediation_records, did_metadata - ) - my_did = my_info.did - - invi_msg = InvitationMessage( # create invitation message - _id=invitation_message_id, - label=my_label or self.profile.settings.get("default_label"), - handshake_protocols=handshake_protocols, - requests_attach=message_attachments, - services=[my_did], - accept=service_accept if protocol_version != "1.0" else None, - version=protocol_version or DEFAULT_VERSION, - image_url=image_url, + if self.handshake_protocols: + conn_rec = await self.handle_handshake_protos( + did_info.verkey, invi_msg, mediation_record + ) + our_service = None + else: + conn_rec = None + await self.route_manager.route_verkey( + self.profile, did_info.verkey, mediation_record + ) + our_service = ServiceDecorator( + recipient_keys=self.did_keys_to_keys(recipient_keys), + endpoint=self.my_endpoint, + routing_keys=self.did_keys_to_keys(routing_keys), ) - invi_url = invi_msg.to_url() - - our_recipient_key = my_info.verkey - # Only create connection record if hanshake_protocols is defined - if handshake_protocols: - invitation_mode = ( - ConnRecord.INVITATION_MODE_MULTI - if multi_use - else ConnRecord.INVITATION_MODE_ONCE - ) - conn_rec = ConnRecord( # create connection record - invitation_key=our_recipient_key, - invitation_msg_id=invi_msg._id, - invitation_mode=invitation_mode, - their_role=ConnRecord.Role.REQUESTER.rfc23, - state=ConnRecord.State.INVITATION.rfc23, - accept=( - ConnRecord.ACCEPT_AUTO - if auto_accept - else ConnRecord.ACCEPT_MANUAL - ), - alias=alias, - connection_protocol=connection_protocol, - ) + return self.CreateResult( + invitation_url=invi_url, + invitation=invi_msg, + our_recipient_key=did_info.verkey, + connection=conn_rec, + service=our_service, + ) - async with self.profile.session() as session: - await conn_rec.save(session, reason="Created new invitation") - await conn_rec.attach_invitation(session, invi_msg) + async def handle_public( + self, + attachments: Sequence[AttachDecorator], + mediation_record: Optional[MediationRecord] = None, + ) -> CreateResult: + """Handle public invitation creation.""" + assert self.public + if not self.profile.settings.get("public_invites"): + raise OutOfBandManagerError("Public invitations are not enabled") - await conn_rec.attach_invitation(session, invi_msg) + async with self.profile.session() as session: + wallet = session.inject(BaseWallet) + public_did = await wallet.get_public_did() - if metadata: - for key, value in metadata.items(): - await conn_rec.metadata_set(session, key, value) - else: - our_service = ServiceDecorator( - recipient_keys=[our_recipient_key], - endpoint=endpoint, - routing_keys=[], - ).serialize() + if not public_did: + raise OutOfBandManagerError( + "Cannot create public invitation with no public DID" + ) - else: - if not my_endpoint: - my_endpoint = self.profile.settings.get("default_endpoint") + if bool(IndyDID.PATTERN.match(public_did.did)): + public_did = DIDInfo( + did=f"did:sov:{public_did.did}", + verkey=public_did.verkey, + metadata=public_did.metadata, + method=public_did.method, + key_type=public_did.key_type, + ) - # Create and store new key for exchange - async with self.profile.session() as session: - wallet = session.inject(BaseWallet) - connection_key = await wallet.create_signing_key(ED25519) + return await self.handle_did(public_did, attachments, mediation_record) - our_recipient_key = connection_key.verkey + async def handle_use_did( + self, + attachments: Sequence[AttachDecorator], + mediation_record: Optional[MediationRecord], + ) -> CreateResult: + """Handle use_did invitation creation.""" + assert self.use_did + async with self.profile.session() as session: + wallet = session.inject(BaseWallet) + try: + did_info = await wallet.get_local_did(self.use_did) + except WalletNotFoundError: + raise OutOfBandManagerError( + f"Cannot find DID for invitation reuse: {self.use_did}" + ) + return await self.handle_did(did_info, attachments, mediation_record) - # Initializing InvitationMessage here to include - # invitation_msg_id in webhook poyload - invi_msg = InvitationMessage( - _id=invitation_message_id, version=protocol_version or DEFAULT_VERSION + async def handle_use_did_method( + self, + attachments: Sequence[AttachDecorator], + mediation_record: Optional[MediationRecord], + ) -> CreateResult: + """Create an invitation using a DID method, optionally reusing one.""" + assert self.use_did_method + mediation_records = [mediation_record] if mediation_record else [] + + if self.my_endpoint: + my_endpoints = [self.my_endpoint] + else: + my_endpoints = [] + default_endpoint = self.profile.settings.get("default_endpoint") + if default_endpoint: + my_endpoints.append(default_endpoint) + my_endpoints.extend(self.profile.settings.get("additional_endpoints", [])) + + did_peer_4 = self.use_did_method == "did:peer:4" + + my_info = None + if not self.create_unique_did: + # check wallet to see if there is an existing "invitation" DID available + did_method = PEER4 if did_peer_4 else PEER2 + my_info = await self.oob.fetch_invitation_reuse_did(did_method) + if not my_info: + LOGGER.warn("No invitation DID found, creating new DID") + + if not my_info: + did_metadata = ( + {INVITATION_REUSE_KEY: "true"} if not self.create_unique_did else {} ) - - if handshake_protocols: - invitation_mode = ( - ConnRecord.INVITATION_MODE_MULTI - if multi_use - else ConnRecord.INVITATION_MODE_ONCE + if did_peer_4: + my_info = await self.oob.create_did_peer_4( + my_endpoints, mediation_records, did_metadata ) - # Create connection record - conn_rec = ConnRecord( - invitation_key=connection_key.verkey, - their_role=ConnRecord.Role.REQUESTER.rfc23, - state=ConnRecord.State.INVITATION.rfc23, - accept=( - ConnRecord.ACCEPT_AUTO - if auto_accept - else ConnRecord.ACCEPT_MANUAL - ), - invitation_mode=invitation_mode, - alias=alias, - connection_protocol=connection_protocol, - invitation_msg_id=invi_msg._id, + else: + my_info = await self.oob.create_did_peer_2( + my_endpoints, mediation_records, did_metadata ) - async with self.profile.session() as session: - await conn_rec.save(session, reason="Created new connection") + return await self.handle_did(my_info, attachments, mediation_record) - routing_keys, routing_endpoint = await self._route_manager.routing_info( - self.profile, mediation_record - ) - my_endpoint = routing_endpoint or my_endpoint - - if not conn_rec: - our_service = ServiceDecorator( - recipient_keys=[our_recipient_key], - endpoint=my_endpoint, - routing_keys=routing_keys, - ).serialize() - # Need to make sure the created key is routed by the base wallet - await self._route_manager.route_verkey( - self.profile, connection_key.verkey - ) + async def handle_legacy_invite_key( + self, + attachments: Sequence[AttachDecorator], + mediation_record: Optional[MediationRecord], + ) -> CreateResult: + """Create an invitation using legacy bare public key and inline service.""" + async with self.profile.session() as session: + wallet = session.inject(BaseWallet) + connection_key = await wallet.create_signing_key(ED25519) - routing_keys = [ - ( - key - if len(key.split(":")) == 3 - else DIDKey.from_public_key_b58(key, ED25519).key_id - ) - for key in routing_keys or [] - ] + routing_keys, routing_endpoint = await self.route_manager.routing_info( + self.profile, mediation_record + ) + routing_keys = [ + ( + key + if len(key.split(":")) == 3 + else DIDKey.from_public_key_b58(key, ED25519).key_id + ) + for key in routing_keys or [] + ] + recipient_keys = [ + DIDKey.from_public_key_b58(connection_key.verkey, ED25519).key_id + ] - # Create connection invitation message - # Note: Need to split this into two stages to support inbound routing - # of invitations - # Would want to reuse create_did_document and convert the result - invi_msg.label = my_label or self.profile.settings.get("default_label") - invi_msg.handshake_protocols = handshake_protocols - invi_msg.requests_attach = message_attachments - invi_msg.accept = service_accept if protocol_version != "1.0" else None - invi_msg.image_url = image_url - invi_msg.services = [ + my_endpoint = routing_endpoint or self.my_endpoint + + invi_msg = InvitationMessage( + _id=self.msg_id, + label=self.my_label, + handshake_protocols=self.handshake_protocols, + requests_attach=attachments, + accept=self.accept, + image_url=self.image_url, + version=self.version, + services=[ ServiceMessage( _id="#inline", _type="did-communication", - recipient_keys=[ - DIDKey.from_public_key_b58( - connection_key.verkey, ED25519 - ).key_id - ], + recipient_keys=recipient_keys, service_endpoint=my_endpoint, routing_keys=routing_keys, ) - ] - if goal and goal_code: - invi_msg.goal_code = goal_code - invi_msg.goal = goal - - invi_url = invi_msg.to_url() - - # Update connection record - if conn_rec: - async with self.profile.session() as session: - await conn_rec.attach_invitation(session, invi_msg) + ], + goal=self.goal, + goal_code=self.goal_code, + ) - if metadata: - for key, value in metadata.items(): - await conn_rec.metadata_set(session, key, value) + if self.handshake_protocols: + conn_rec = await self.handle_handshake_protos( + connection_key.verkey, invi_msg, mediation_record + ) + our_service = None + else: + await self.route_manager.route_verkey( + self.profile, connection_key.verkey, mediation_record + ) + conn_rec = None + our_service = ServiceDecorator( + recipient_keys=self.did_keys_to_keys(recipient_keys), + endpoint=my_endpoint, + routing_keys=self.did_keys_to_keys(routing_keys), + ) - oob_record = OobRecord( - role=OobRecord.ROLE_SENDER, - state=OobRecord.STATE_AWAIT_RESPONSE, - connection_id=conn_rec.connection_id if conn_rec else None, - invi_msg_id=invi_msg._id, + return self.CreateResult( + invitation_url=invi_msg.to_url(), invitation=invi_msg, - our_recipient_key=our_recipient_key, - our_service=our_service, - multi_use=multi_use, + our_recipient_key=connection_key.verkey, + connection=conn_rec, + service=our_service, ) - async with self.profile.session() as session: - await oob_record.save(session, reason="Created new oob invitation") - if conn_rec: - await self._route_manager.route_invitation( - self.profile, conn_rec, mediation_record - ) +class OutOfBandManager(BaseConnectionManager): + """Class for managing out of band messages.""" - return InvitationRecord( # for return via admin API, not storage - oob_id=oob_record.oob_id, - state=InvitationRecord.STATE_INITIAL, - invi_msg_id=invi_msg._id, - invitation=invi_msg, - invitation_url=invi_url, + def __init__(self, profile: Profile): + """Initialize a OutOfBandManager. + + Args: + profile: The profile for this out of band manager + """ + self._profile = profile + super().__init__(self._profile) + + @property + def profile(self) -> Profile: + """Accessor for the current profile. + + Returns: + The profile for this connection manager + + """ + return self._profile + + async def create_invitation( + self, + my_label: Optional[str] = None, + my_endpoint: Optional[str] = None, + auto_accept: Optional[bool] = None, + public: bool = False, + use_did: Optional[str] = None, + use_did_method: Optional[str] = None, + hs_protos: Optional[Sequence[HSProto]] = None, + multi_use: bool = False, + create_unique_did: bool = False, + alias: Optional[str] = None, + attachments: Optional[Sequence[Mapping]] = None, + metadata: Optional[dict] = None, + mediation_id: Optional[str] = None, + service_accept: Optional[Sequence[Text]] = None, + protocol_version: Optional[Text] = None, + goal_code: Optional[Text] = None, + goal: Optional[Text] = None, + ) -> InvitationRecord: + """Generate new connection invitation. + + This interaction represents an out-of-band communication channel. In the future + and in practice, these sort of invitations will be received over any number of + channels such as SMS, Email, QR Code, NFC, etc. + + Args: + my_label: label for this connection + my_endpoint: endpoint where other party can reach me + auto_accept: auto-accept a corresponding connection request + (None to use config) + public: set to create an invitation from the public DID + hs_protos: list of handshake protocols to include + multi_use: set to True to create an invitation for multiple-use connection + alias: optional alias to apply to connection for later use + attachments: list of dicts in form of {"id": ..., "type": ...} + service_accept: Optional list of mime types in the order of preference of + the sender that the receiver can use in responding to the message + protocol_version: OOB protocol version [1.0, 1.1] + goal_code: Optional self-attested code for receiver logic + goal: Optional self-attested string for receiver logic + Returns: + Invitation record + + """ + creator = InvitationCreator( + self.profile, + self._route_manager, + self, + my_label, + my_endpoint, + auto_accept, + public, + use_did, + use_did_method, + hs_protos, + multi_use, + create_unique_did, + alias, + attachments, + metadata, + mediation_id, + service_accept, + protocol_version, + goal_code, + goal, ) + return await creator.create() async def receive_invitation( self, @@ -961,10 +1092,11 @@ async def _perform_handshake( service.routing_keys = [ DIDKey.from_did(key).public_key_b58 for key in service.routing_keys ] or [] + msg_type = DIDCommPrefix.qualify_current(protocol.name) + "/invitation" connection_invitation = ConnectionInvitation.deserialize( { "@id": invitation._id, - "@type": DIDCommPrefix.qualify_current(protocol.name), + "@type": msg_type, "label": invitation.label, "recipientKeys": service.recipient_keys, "serviceEndpoint": service.service_endpoint, diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/messages/invitation.py b/aries_cloudagent/protocols/out_of_band/v1_0/messages/invitation.py index 53a4e04b75..80ebc284fe 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/messages/invitation.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/messages/invitation.py @@ -120,14 +120,12 @@ class Meta: def __init__( self, - # _id: str = None, *, - comment: str = None, - label: str = None, - image_url: str = None, - handshake_protocols: Sequence[Text] = None, - requests_attach: Sequence[AttachDecorator] = None, - services: Sequence[Union[Service, Text]] = None, + label: Optional[str] = None, + image_url: Optional[str] = None, + handshake_protocols: Optional[Sequence[Text]] = None, + requests_attach: Optional[Sequence[AttachDecorator]] = None, + services: Optional[Sequence[Union[Service, Text]]] = None, accept: Optional[Sequence[Text]] = None, version: str = DEFAULT_VERSION, msg_type: Optional[Text] = None, diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/messages/tests/test_invitation.py b/aries_cloudagent/protocols/out_of_band/v1_0/messages/tests/test_invitation.py index 1db6584ab0..7452b17a28 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/messages/tests/test_invitation.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/messages/tests/test_invitation.py @@ -41,7 +41,6 @@ class TestInvitationMessage(TestCase): def test_init(self): """Test initialization message.""" invi_msg = InvitationMessage( - comment="Hello", label="A label", handshake_protocols=[DIDCommPrefix.qualify_current(DIDEX_1_1)], services=[TEST_DID], @@ -51,7 +50,6 @@ def test_init(self): service = Service(_id="#inline", _type=DID_COMM, did=TEST_DID) invi_msg = InvitationMessage( - comment="Hello", label="A label", handshake_protocols=[DIDCommPrefix.qualify_current(DIDEX_1_1)], services=[service], @@ -112,7 +110,6 @@ def test_url_round_trip(self): service_endpoint="http://1.2.3.4:8080/service", ) invi_msg = InvitationMessage( - comment="Hello", label="A label", handshake_protocols=[DIDCommPrefix.qualify_current(DIDEX_1_1)], services=[service], diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/models/oob_record.py b/aries_cloudagent/protocols/out_of_band/v1_0/models/oob_record.py index 830c523c79..e99201bd4f 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/models/oob_record.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/models/oob_record.py @@ -56,13 +56,13 @@ def __init__( invi_msg_id: str, role: str, invitation: Union[InvitationMessage, Mapping[str, Any]], - their_service: Optional[ServiceDecorator] = None, + their_service: Optional[Union[ServiceDecorator, Mapping[str, Any]]] = None, connection_id: Optional[str] = None, reuse_msg_id: Optional[str] = None, oob_id: Optional[str] = None, attach_thread_id: Optional[str] = None, our_recipient_key: Optional[str] = None, - our_service: Optional[ServiceDecorator] = None, + our_service: Optional[Union[ServiceDecorator, Mapping[str, Any]]] = None, multi_use: bool = False, trace: bool = False, **kwargs, @@ -76,8 +76,8 @@ def __init__( self._invitation = InvitationMessage.serde(invitation) self.connection_id = connection_id self.reuse_msg_id = reuse_msg_id - self.their_service = their_service - self.our_service = our_service + self._their_service = ServiceDecorator.serde(their_service) + self._our_service = ServiceDecorator.serde(our_service) self.attach_thread_id = attach_thread_id self.our_recipient_key = our_recipient_key self.multi_use = multi_use @@ -89,7 +89,7 @@ def oob_id(self) -> str: return self._id @property - def invitation(self) -> InvitationMessage: + def invitation(self) -> Optional[InvitationMessage]: """Accessor; get deserialized view.""" return None if self._invitation is None else self._invitation.de @@ -98,6 +98,21 @@ def invitation(self, value): """Setter; store de/serialized views.""" self._invitation = InvitationMessage.serde(value) + @property + def our_service(self) -> Optional[ServiceDecorator]: + """Accessor; get deserialized view.""" + return None if self._our_service is None else self._our_service.de + + @our_service.setter + def our_service(self, value: Union[ServiceDecorator, Mapping[str, Any]]): + """Setter; store de/serialized views.""" + self._our_service = ServiceDecorator.serde(value) + + @property + def their_service(self) -> Optional[ServiceDecorator]: + """Accessor; get deserialized view.""" + return None if self._their_service is None else self._their_service.de + @property def record_value(self) -> dict: """Accessor for the JSON record value generated for this invitation.""" @@ -109,14 +124,13 @@ def record_value(self) -> dict: "their_service", "connection_id", "role", - "our_service", "invi_msg_id", "multi_use", ) }, **{ prop: getattr(self, f"_{prop}").ser - for prop in ("invitation",) + for prop in ("invitation", "our_service", "their_service") if getattr(self, prop) is not None }, } diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/models/tests/test_invitation.py b/aries_cloudagent/protocols/out_of_band/v1_0/models/tests/test_invitation.py index 50a7fade08..e7d95655a2 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/models/tests/test_invitation.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/models/tests/test_invitation.py @@ -32,7 +32,6 @@ class TestInvitationRecordSchema(IsolatedAsyncioTestCase): def test_make_record(self): """Test making record.""" invi = InvitationMessage( - comment="Hello", label="A label", handshake_protocols=[DIDCommPrefix.qualify_current(DIDEX_1_1)], services=[TEST_DID], diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/routes.py b/aries_cloudagent/protocols/out_of_band/v1_0/routes.py index 210fedd7f9..96aeea265a 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/routes.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/routes.py @@ -20,7 +20,7 @@ from ....messaging.valid import UUID4_EXAMPLE, UUID4_VALIDATE from ....storage.error import StorageError, StorageNotFoundError from ...didcomm_prefix import DIDCommPrefix -from ...didexchange.v1_0.manager import DIDXManagerError +from ...didexchange.v1_0.manager import DIDXManager, DIDXManagerError from .manager import OutOfBandManager, OutOfBandManagerError from .message_types import SPEC_URI from .messages.invitation import HSProto, InvitationMessage, InvitationMessageSchema @@ -106,6 +106,21 @@ class AttachmentDefSchema(OpenAPISchema): "example": False, }, ) + use_did = fields.Str( + required=False, + metadata={ + "description": "DID to use in invitation", + "example": "did:example:123", + }, + ) + use_did_method = fields.Str( + required=False, + validate=validate.OneOf(DIDXManager.SUPPORTED_USE_DID_METHODS), + metadata={ + "description": "DID method to use in invitation", + "example": "did:peer:2", + }, + ) metadata = fields.Dict( required=False, metadata={ @@ -227,6 +242,8 @@ async def invitation_create(request: web.BaseRequest): handshake_protocols = body.get("handshake_protocols", []) service_accept = body.get("accept") use_public_did = body.get("use_public_did", False) + use_did = body.get("use_did") + use_did_method = body.get("use_did_method") metadata = body.get("metadata") my_label = body.get("my_label") alias = body.get("alias") @@ -239,29 +256,16 @@ async def invitation_create(request: web.BaseRequest): auto_accept = json.loads(request.query.get("auto_accept", "null")) create_unique_did = json.loads(request.query.get("create_unique_did", "false")) - if create_unique_did and use_public_did: - raise web.HTTPBadRequest( - reason="create_unique_did cannot be used with use_public_did" - ) - profile = context.profile - emit_did_peer_4 = profile.settings.get("emit_did_peer_4", False) - emit_did_peer_2 = profile.settings.get("emit_did_peer_2", False) - if emit_did_peer_2 and emit_did_peer_4: - LOGGER.warning( - "emit_did_peer_2 and emit_did_peer_4 both set, \ - using did:peer:4" - ) - oob_mgr = OutOfBandManager(profile) try: invi_rec = await oob_mgr.create_invitation( my_label=my_label, auto_accept=auto_accept, public=use_public_did, - did_peer_2=emit_did_peer_2, - did_peer_4=emit_did_peer_4, + use_did=use_did, + use_did_method=use_did_method, hs_protos=[ h for h in [HSProto.get(hsp) for hsp in handshake_protocols] if h ], diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_invite_creator.py b/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_invite_creator.py new file mode 100644 index 0000000000..107357dd15 --- /dev/null +++ b/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_invite_creator.py @@ -0,0 +1,26 @@ +"""Test the InvitationCreator class.""" + +from unittest.mock import MagicMock +import pytest + +from ..manager import InvitationCreator, OutOfBandManagerError + + +@pytest.mark.parametrize( + "args", + [ + ({}), + ({"metadata": "test"}), + ({"attachments": "test", "multi_use": True}), + ({"hs_protos": "test", "public": True, "use_did": True}), + ({"hs_protos": "test", "public": True, "use_did_method": True}), + ({"hs_protos": "test", "use_did": True, "use_did_method": True}), + ({"hs_protos": "test", "create_unique_did": True}), + ({"hs_protos": "test", "use_did_method": "some_did_method"}), + ], +) +def test_init_param_checking_x(args): + with pytest.raises(OutOfBandManagerError): + InvitationCreator( + profile=MagicMock(), route_manager=MagicMock(), oob=MagicMock(), **args + ) diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_manager.py b/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_manager.py index 05034e9685..3b8d33a51c 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_manager.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_manager.py @@ -591,9 +591,7 @@ async def test_create_invitation_attachment_v2_0_cred_offer(self): ) mock_retrieve_cxid_v1.side_effect = test_module.StorageNotFoundError() mock_retrieve_cxid_v2.return_value = mock.MagicMock( - cred_offer=mock.MagicMock( - serialize=mock.MagicMock(return_value={"cred": "offer"}) - ) + cred_offer=V20CredOffer() ) invi_rec = await self.manager.create_invitation( my_endpoint=TestConfig.test_endpoint, @@ -606,10 +604,10 @@ async def test_create_invitation_attachment_v2_0_cred_offer(self): mock_retrieve_cxid_v2.assert_called_once_with(ANY, "dummy-id") assert isinstance(invi_rec, InvitationRecord) assert not invi_rec.invitation.handshake_protocols - assert invi_rec.invitation.requests_attach[0].content == { - "cred": "offer", - "~thread": {"pthid": invi_rec.invi_msg_id}, - } + attach = invi_rec.invitation.requests_attach[0].content + assert isinstance(attach, dict) + assert "~thread" in attach and "pthid" in attach["~thread"] + assert attach["~thread"]["pthid"] == invi_rec.invi_msg_id async def test_create_invitation_attachment_present_proof_v1_0(self): self.profile.context.update_settings({"public_invites": True}) @@ -759,7 +757,15 @@ async def test_create_invitation_attachment_x(self): public=False, hs_protos=[test_module.HSProto.RFC23], multi_use=False, - attachments=[{"having": "attachment", "is": "no", "good": "here"}], + attachments=[ + { + "type": "asdf", + "id": "asdf", + "having": "attachment", + "is": "no", + "good": "here", + } + ], ) assert "Unknown attachment type" in str(context.exception) @@ -1613,7 +1619,9 @@ async def test_request_attach_oob_message_processor_connectionless(self): mock.CoroutineMock(), ) as mock_service_decorator_from_service: mock_create_signing_key.return_value = KeyInfo( - verkey="a-verkey", metadata={}, key_type=ED25519 + verkey="H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", + metadata={}, + key_type=ED25519, ) mock_service_decorator_from_service.return_value = mock_service_decorator oob_invitation = InvitationMessage( @@ -1626,7 +1634,10 @@ async def test_request_attach_oob_message_processor_connectionless(self): oob_invitation, use_existing_connection=True ) - assert oob_record.our_recipient_key == "a-verkey" + assert ( + oob_record.our_recipient_key + == "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV" + ) assert oob_record.our_service assert oob_record.state == OobRecord.STATE_PREPARE_RESPONSE diff --git a/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_routes.py b/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_routes.py index a6ea7eb8c0..7a9384f1cc 100644 --- a/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_routes.py +++ b/aries_cloudagent/protocols/out_of_band/v1_0/tests/test_routes.py @@ -52,8 +52,8 @@ async def test_invitation_create(self): my_label=None, auto_accept=True, public=True, - did_peer_2=False, - did_peer_4=False, + use_did_method=None, + use_did=None, multi_use=True, create_unique_did=False, hs_protos=[test_module.HSProto.RFC23], @@ -112,8 +112,8 @@ async def test_invitation_create_with_accept(self): my_label=None, auto_accept=True, public=True, - did_peer_2=False, - did_peer_4=False, + use_did_method=None, + use_did=None, multi_use=True, create_unique_did=False, hs_protos=[test_module.HSProto.RFC23], diff --git a/aries_cloudagent/utils/tests/test_outofband.py b/aries_cloudagent/utils/tests/test_outofband.py index 81d5763ca7..72bcf6d7e6 100644 --- a/aries_cloudagent/utils/tests/test_outofband.py +++ b/aries_cloudagent/utils/tests/test_outofband.py @@ -13,9 +13,7 @@ class TestOutOfBand(TestCase): test_did_info = DIDInfo(test_did, test_verkey, None, method=SOV, key_type=ED25519) def test_serialize_oob(self): - invi = InvitationMessage( - comment="my sister", label="ma sœur", services=[TestOutOfBand.test_did] - ) + invi = InvitationMessage(label="ma sœur", services=[TestOutOfBand.test_did]) result = test_module.serialize_outofband( invi, TestOutOfBand.test_did_info, "http://1.2.3.4:8081" diff --git a/aries_cloudagent/utils/tests/test_tracing.py b/aries_cloudagent/utils/tests/test_tracing.py index b9c7278383..55cd60465b 100644 --- a/aries_cloudagent/utils/tests/test_tracing.py +++ b/aries_cloudagent/utils/tests/test_tracing.py @@ -23,9 +23,7 @@ def test_get_timer(self): assert test_module.get_timer() > 0.0 def test_tracing_enabled(self): - invi = InvitationMessage( - comment="no comment", label="cable guy", services=[TestTracing.test_did] - ) + invi = InvitationMessage(label="cable guy", services=[TestTracing.test_did]) assert not test_module.tracing_enabled({}, invi) invi._trace = TraceDecorator(target="message") assert test_module.tracing_enabled({}, invi) @@ -71,9 +69,7 @@ def test_tracing_enabled(self): assert test_module.tracing_enabled({}, outbound_message) def test_decode_inbound_message(self): - invi = InvitationMessage( - comment="no comment", label="cable guy", services=[TestTracing.test_did] - ) + invi = InvitationMessage(label="cable guy", services=[TestTracing.test_did]) message = OutboundMessage(payload=invi) assert invi == test_module.decode_inbound_message(message) diff --git a/demo/features/0160-connection.feature b/demo/features/0160-connection.feature index 85d2652161..6befe878cd 100644 --- a/demo/features/0160-connection.feature +++ b/demo/features/0160-connection.feature @@ -15,16 +15,16 @@ Feature: RFC 0160 Aries agent connection functions @GHA @UnqualifiedDids Examples: | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | - | --public-did --did-exchange | --emit-did-peer-2 | --did-exchange | --emit-did-peer-2 | - | --public-did --did-exchange | --emit-did-peer-4 | --did-exchange | --emit-did-peer-4 | - | --public-did --did-exchange --reuse-connections | --emit-did-peer-4 | --did-exchange --reuse-connections | --emit-did-peer-4 | + | --public-did --did-exchange --emit-did-peer-2 | | --did-exchange --emit-did-peer-2 | | + | --public-did --did-exchange --emit-did-peer-4 | | --did-exchange --emit-did-peer-4 | | + | --public-did --did-exchange --reuse-connections --emit-did-peer-4 | | --did-exchange --reuse-connections --emit-did-peer-4 | | @UnqualifiedDids Examples: | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | - | --public-did --did-exchange | --emit-did-peer-2 | --did-exchange | --emit-did-peer-4 | - | --public-did --did-exchange --reuse-connections | --emit-did-peer-4 | --did-exchange --reuse-connections | --emit-did-peer-2 | - | --public-did --did-exchange | --emit-did-peer-4 | --did-exchange | --emit-did-peer-2 | + | --public-did --did-exchange --emit-did-peer-2 | | --did-exchange --emit-did-peer-4 | | + | --public-did --did-exchange --reuse-connections --emit-did-peer-4 | | --did-exchange --reuse-connections --emit-did-peer-2 | | + | --public-did --did-exchange --emit-did-peer-4 | | --did-exchange --emit-did-peer-2 | | @PublicDidReuse Examples: @@ -35,31 +35,31 @@ Feature: RFC 0160 Aries agent connection functions @DidPeerConnectionReuse Examples: | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | - | --did-exchange | --emit-did-peer-2 | | --emit-did-peer-2 | - | --did-exchange --reuse-connections | --emit-did-peer-2 | --reuse-connections | --emit-did-peer-2 | - | --did-exchange | --emit-did-peer-4 | | --emit-did-peer-4 | - | --did-exchange --reuse-connections | --emit-did-peer-4 | --reuse-connections | --emit-did-peer-4 | + | --did-exchange --emit-did-peer-2 | | --emit-did-peer-2 | | + | --did-exchange --reuse-connections --emit-did-peer-2 | | --reuse-connections --emit-did-peer-2 | | + | --did-exchange --emit-did-peer-4 | | --emit-did-peer-4 | | + | --did-exchange --reuse-connections --emit-did-peer-4 | | --reuse-connections --emit-did-peer-4 | | @GHA @MultiUseConnectionReuse Examples: | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | - | --did-exchange --multi-use-invitations | --emit-did-peer-2 | | --emit-did-peer-2 | - | --did-exchange --multi-use-invitations --reuse-connections | --emit-did-peer-4 | --reuse-connections | --emit-did-peer-4 | - | --public-did --did-exchange --multi-use-invitations | --emit-did-peer-2 | --did-exchange | --emit-did-peer-4 | - | --public-did --did-exchange --multi-use-invitations --reuse-connections | --emit-did-peer-4 | --did-exchange --reuse-connections | --emit-did-peer-2 | + | --did-exchange --multi-use-invitations --emit-did-peer-2 | | --emit-did-peer-2 | | + | --did-exchange --multi-use-invitations --reuse-connections --emit-did-peer-4 | | --reuse-connections --emit-did-peer-4 | | + | --public-did --did-exchange --multi-use-invitations --emit-did-peer-2 | | --did-exchange --emit-did-peer-4 | | + | --public-did --did-exchange --multi-use-invitations --reuse-connections --emit-did-peer-4 | | --did-exchange --reuse-connections --emit-did-peer-2 | | @MultiUseConnectionReuse Examples: | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | - | --did-exchange --multi-use-invitations --reuse-connections | --emit-did-peer-2 | --reuse-connections | --emit-did-peer-2 | - | --did-exchange --multi-use-invitations | --emit-did-peer-4 | | --emit-did-peer-4 | - | --public-did --did-exchange --multi-use-invitations | --emit-did-peer-4 | --did-exchange | --emit-did-peer-2 | - | --public-did --did-exchange --multi-use-invitations --reuse-connections | --emit-did-peer-2 | --did-exchange --reuse-connections | --emit-did-peer-4 | + | --did-exchange --multi-use-invitations --reuse-connections --emit-did-peer-2 | | --reuse-connections --emit-did-peer-2 | | + | --did-exchange --multi-use-invitations --emit-did-peer-4 | | --emit-did-peer-4 | | + | --public-did --did-exchange --multi-use-invitations --emit-did-peer-4 | | --did-exchange --emit-did-peer-2 | | + | --public-did --did-exchange --multi-use-invitations --reuse-connections --emit-did-peer-2 | | --did-exchange --reuse-connections --emit-did-peer-4 | | @GHA @WalletType_Askar_AnonCreds Examples: | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | - | --public-did --did-exchange --wallet-type askar-anoncreds | --emit-did-peer-2 | --did-exchange --wallet-type askar-anoncreds | --emit-did-peer-2 | - | --public-did --did-exchange --wallet-type askar-anoncreds --reuse-connections | --emit-did-peer-4 | --did-exchange --wallet-type askar-anoncreds --reuse-connections | --emit-did-peer-4 | - | --did-exchange --wallet-type askar-anoncreds | --emit-did-peer-2 | --wallet-type askar-anoncreds | --emit-did-peer-2 | - | --did-exchange --wallet-type askar-anoncreds --reuse-connections | --emit-did-peer-4 | --wallet-type askar-anoncreds --reuse-connections | --emit-did-peer-4 | + | --public-did --did-exchange --wallet-type askar-anoncreds --emit-did-peer-2 | | --did-exchange --wallet-type askar-anoncreds --emit-did-peer-2 | | + | --public-did --did-exchange --wallet-type askar-anoncreds --reuse-connections --emit-did-peer-4 | | --did-exchange --wallet-type askar-anoncreds --reuse-connections --emit-did-peer-4 | | + | --did-exchange --wallet-type askar-anoncreds --emit-did-peer-2 | | --wallet-type askar-anoncreds --emit-did-peer-2 | | + | --did-exchange --wallet-type askar-anoncreds --reuse-connections --emit-did-peer-4 | | --wallet-type askar-anoncreds --reuse-connections --emit-did-peer-4 | | diff --git a/demo/features/0453-issue-credential.feature b/demo/features/0453-issue-credential.feature index 245144a2ff..0085a393e9 100644 --- a/demo/features/0453-issue-credential.feature +++ b/demo/features/0453-issue-credential.feature @@ -37,15 +37,15 @@ Feature: RFC 0453 Aries agent issue credential @GHA @WalletType_Askar @ConnectionTests Examples: - | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Acme_extra | Bob_extra | - | --did-exchange | --did-exchange | driverslicense | Data_DL_NormalizedValues | --emit-did-peer-4 | --emit-did-peer-4 | - | --did-exchange --reuse-connections | --did-exchange --reuse-connections | driverslicense | Data_DL_NormalizedValues | --emit-did-peer-4 | --emit-did-peer-4 | + | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Acme_extra | Bob_extra | + | --did-exchange --emit-did-peer-4 | --did-exchange --emit-did-peer-4 | driverslicense | Data_DL_NormalizedValues | | | + | --did-exchange --reuse-connections --emit-did-peer-4 | --did-exchange --reuse-connections --emit-did-peer-4 | driverslicense | Data_DL_NormalizedValues | | | @GHA @WalletType_Askar_AnonCreds @ConnectionTests Examples: | Acme_capabilities | Bob_capabilities | Schema_name | Credential_data | Acme_extra | Bob_extra | - | --did-exchange --wallet-type askar-anoncreds | --did-exchange --wallet-type askar-anoncreds | driverslicense | Data_DL_NormalizedValues | --emit-did-peer-4 | --emit-did-peer-4 | - | --did-exchange --wallet-type askar-anoncreds --reuse-connections | --did-exchange --wallet-type askar-anoncreds --reuse-connections | driverslicense | Data_DL_NormalizedValues | --emit-did-peer-4 | --emit-did-peer-4 | + | --did-exchange --wallet-type askar-anoncreds --emit-did-peer-4 | --did-exchange --wallet-type askar-anoncreds --emit-did-peer-4 | driverslicense | Data_DL_NormalizedValues | | | + | --did-exchange --wallet-type askar-anoncreds --reuse-connections --emit-did-peer-4| --did-exchange --wallet-type askar-anoncreds --reuse-connections --emit-did-peer-4| driverslicense | Data_DL_NormalizedValues | | | @T003-RFC0453 Scenario Outline: Holder accepts a deleted credential offer diff --git a/demo/features/0454-present-proof.feature b/demo/features/0454-present-proof.feature index 7a76ec771a..8787541703 100644 --- a/demo/features/0454-present-proof.feature +++ b/demo/features/0454-present-proof.feature @@ -41,12 +41,12 @@ Feature: RFC 0454 Aries agent present proof @WalletType_Askar Examples: | issuer | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | Schema_name | Credential_data | Proof_request | - | Faber | --public-did --did-exchange | --emit-did-peer-2 | --did-exchange | --emit-did-peer-2 | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + | Faber | --public-did --did-exchange --emit-did-peer-2 | | --did-exchange --emit-did-peer-2 | | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | @WalletType_Askar_AnonCreds Examples: | issuer | Acme_capabilities | Acme_extra | Bob_capabilities | Bob_extra | Schema_name | Credential_data | Proof_request | - | Faber | --public-did --wallet-type askar-anoncreds | --emit-did-peer-2 | --wallet-type askar-anoncreds | --emit-did-peer-2 | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | + | Faber | --public-did --wallet-type askar-anoncreds --emit-did-peer-2 | | --wallet-type askar-anoncreds --emit-did-peer-2 | | driverslicense_v2 | Data_DL_MaxValues | DL_age_over_19_v2 | @T001.1-RFC0454 diff --git a/demo/runners/agent_container.py b/demo/runners/agent_container.py index 8e16c9004c..38ee4e739e 100644 --- a/demo/runners/agent_container.py +++ b/demo/runners/agent_container.py @@ -613,6 +613,8 @@ async def generate_invitation( reuse_connections: bool = False, multi_use_invitations: bool = False, public_did_connections: bool = False, + emit_did_peer_2: bool = False, + emit_did_peer_4: bool = False, wait: bool = False, ): self._connection_ready = asyncio.Future() @@ -627,6 +629,8 @@ async def generate_invitation( reuse_connections=reuse_connections, multi_use_invitations=multi_use_invitations, public_did_connections=public_did_connections, + emit_did_peer_2=emit_did_peer_2, + emit_did_peer_4=emit_did_peer_4, ) if display_qr: @@ -728,6 +732,8 @@ def __init__( reuse_connections: bool = False, multi_use_invitations: bool = False, public_did_connections: bool = False, + emit_did_peer_2: bool = False, + emit_did_peer_4: bool = False, taa_accept: bool = False, anoncreds_legacy_revocation: str = None, log_file: str = None, @@ -769,6 +775,8 @@ def __init__( self.reuse_connections = reuse_connections self.multi_use_invitations = multi_use_invitations self.public_did_connections = public_did_connections + self.emit_did_peer_2 = emit_did_peer_2 + self.emit_did_peer_4 = emit_did_peer_4 self.exchange_tracing = False # local agent(s) @@ -1173,6 +1181,8 @@ async def generate_invitation( reuse_connections=reuse_connections, multi_use_invitations=multi_use_invitations, public_did_connections=public_did_connections, + emit_did_peer_2=self.emit_did_peer_2, + emit_did_peer_4=self.emit_did_peer_4, wait=wait, ) @@ -1432,6 +1442,16 @@ def arg_parser(ident: str = None, port: int = 8020): "('debug', 'info', 'warning', 'error', 'critical')" ), ) + parser.add_argument( + "--emit-did-peer-2", + action="store_true", + help="Emit did:peer:2 DID in DID exchange", + ) + parser.add_argument( + "--emit-did-peer-4", + action="store_true", + help="Emit did:peer:4 DID in DID exchange", + ) return parser @@ -1537,6 +1557,9 @@ async def create_agent_with_args(args, ident: str = None, extra_args: list = Non if "anoncreds_legacy_revocation" in args and args.anoncreds_legacy_revocation: anoncreds_legacy_revocation = args.anoncreds_legacy_revocation + emit_did_peer_2 = "emit_did_peer_2" in args and args.emit_did_peer_2 + emit_did_peer_4 = "emit_did_peer_4" in args and args.emit_did_peer_4 + agent = AgentContainer( genesis_txns=genesis, genesis_txn_list=multi_ledger_config_path, @@ -1559,6 +1582,8 @@ async def create_agent_with_args(args, ident: str = None, extra_args: list = Non reuse_connections=reuse_connections, multi_use_invitations=multi_use_invitations, public_did_connections=public_did_connections, + emit_did_peer_2=emit_did_peer_2, + emit_did_peer_4=emit_did_peer_4, taa_accept=args.taa_accept, anoncreds_legacy_revocation=anoncreds_legacy_revocation, log_file=log_file, diff --git a/demo/runners/support/agent.py b/demo/runners/support/agent.py index 90dee157b2..54aa629d50 100644 --- a/demo/runners/support/agent.py +++ b/demo/runners/support/agent.py @@ -4,11 +4,11 @@ import json import logging import os -import random import subprocess import sys from concurrent.futures import ThreadPoolExecutor from timeit import default_timer +from secrets import token_hex import asyncpg import yaml @@ -207,12 +207,8 @@ def __init__( seed = None elif self.endorser_role and not seed: seed = "random" - rand_name = str(random.randint(100_000, 999_999)) - self.seed = ( - ("my_seed_000000000000000000000000" + rand_name)[-32:] - if seed == "random" - else seed - ) + rand_name = token_hex(4) + self.seed = token_hex(16) if seed == "random" else seed self.storage_type = params.get("storage_type") self.wallet_type = params.get("wallet_type") or "askar" self.wallet_name = ( @@ -1455,11 +1451,24 @@ async def get_invite( reuse_connections: bool = False, multi_use_invitations: bool = False, public_did_connections: bool = False, + emit_did_peer_2: bool = False, + emit_did_peer_4: bool = False, ): self.connection_id = None if use_did_exchange: # TODO can mediation be used with DID exchange connections? - create_unique_did = (not reuse_connections) and (not public_did_connections) + if emit_did_peer_2: + use_did_method = "did:peer:2" + elif emit_did_peer_4: + use_did_method = "did:peer:4" + else: + use_did_method = None + + create_unique_did = ( + use_did_method is not None + and (not reuse_connections) + and (not public_did_connections) + ) invi_params = { "auto_accept": json.dumps(auto_accept), "multi_use": json.dumps(multi_use_invitations), @@ -1471,6 +1480,8 @@ async def get_invite( } if self.mediation: payload["mediation_id"] = self.mediator_request_id + if use_did_method: + payload["use_did_method"] = use_did_method print("Calling /out-of-band/create-invitation with:", payload, invi_params) invi_rec = await self.admin_POST( "/out-of-band/create-invitation", diff --git a/docs/demo/README.md b/docs/demo/README.md index 2764ffa14c..5aa0b86601 100644 --- a/docs/demo/README.md +++ b/docs/demo/README.md @@ -265,11 +265,13 @@ You can enable DID Exchange using the `--did-exchange` parameter for the `alice` This will use the new DID Exchange protocol when establishing connections between the agents, rather than the older Connection protocol. There is no other affect on the operation of the agents. -With DID Exchange, you can also enable use of the inviter's public DID for invitations, multi-use invitations, and connection re-use: +With DID Exchange, you can also enable use of the inviter's public DID for invitations, multi-use invitations, connection re-use, and use of qualified DIDs: - `--public-did-connections` - use the inviter's public DID in invitations, and allow use of implicit invitations - `--reuse-connections` - support connection re-use (invitee will reuse an existing connection if it uses the same DID as in the new invitation) - `--multi-use-invitations` - inviter will issue multi-use invitations +- `--emit-did-peer-4` - participants will prefer use of did:peer:4 for their pairwise connection DIDs +- `--emit-did-peer-2` - participants will prefer use of did:peer:2 for their pairwise connection DIDs ### Endorser diff --git a/docs/demo/ReusingAConnection.md b/docs/demo/ReusingAConnection.md index 2c7e94dfd6..497075e7aa 100644 --- a/docs/demo/ReusingAConnection.md +++ b/docs/demo/ReusingAConnection.md @@ -134,14 +134,14 @@ For example, to run faber with connection reuse using a non-public DID: ./run_demo faber --reuse-connections --events ``` -To run faber using a `did_peer` and reusable connections: +To run faber using a `did:peer` and reusable connections: ``` bash -DEMO_EXTRA_AGENT_ARGS="[\"--emit-did-peer-2\"]" ./run_demo faber --reuse-connections --events +./run_demo faber --reuse-connections --emit-did-peer-2 --events ``` To run this demo using a multi-use invitation (from Faber): ``` bash -DEMO_EXTRA_AGENT_ARGS="[\"--emit-did-peer-2\"]" ./run_demo faber --reuse-connections --multi-use-invitations --events +./run_demo faber --reuse-connections --emit-did-peer-2 --multi-use-invitations --events ``` diff --git a/docs/features/DIDResolution.md b/docs/features/DIDResolution.md index 6d5e9fc75e..f2858fff04 100644 --- a/docs/features/DIDResolution.md +++ b/docs/features/DIDResolution.md @@ -176,7 +176,7 @@ plugin: The following is a fully functional Dockerfile encapsulating this setup: ```dockerfile= -FROM ghcr.io/hyperledger/aries-cloudagent-python:py3.9-0.12.0rc2 +FROM ghcr.io/hyperledger/aries-cloudagent-python:py3.9-0.12.0rc3 RUN pip3 install git+https://github.com/dbluhm/acapy-resolver-github CMD ["aca-py", "start", "-it", "http", "0.0.0.0", "3000", "-ot", "http", "-e", "http://localhost:3000", "--admin", "0.0.0.0", "3001", "--admin-insecure-mode", "--no-ledger", "--plugin", "acapy_resolver_github"] diff --git a/docs/features/QualifiedDIDs.md b/docs/features/QualifiedDIDs.md new file mode 100644 index 0000000000..bec33b519e --- /dev/null +++ b/docs/features/QualifiedDIDs.md @@ -0,0 +1,49 @@ +# Qualified DIDs In ACA-Py + +## Context + +In the past, ACA-Py has used "unqualified" DIDs by convention established early on in the Aries ecosystem, before the concept of Peer DIDs, or DIDs that existed only between peers and were not (necessarily) published to a distributed ledger, fully matured. These "unqualified" DIDs were effectively Indy Nyms that had not been published to an Indy network. Key material and service endpoints were communicated by embedding the DID Document for the "DID" in DID Exchange request and response messages. + +For those familiar with the DID Core Specification, it is a stretch to refer to these unqualified DIDs as DIDs. Usage of these DIDs will be phased out, as dictated by [Aries RFC 0793: Unqualified DID Transition][rfc0793]. These DIDs will be phased out in favor of the `did:peer` DID Method. ACA-Py's support for this method and it's use in DID Exchange and DID Rotation is dictated below. + +[rfc0793]: https://github.com/hyperledger/aries-rfcs/blob/50d148b812c45af3fc847c1e7033b084683dceb7/features/0793-unqualfied-dids-transition/README.md + +## DID Exchange + +When using DID Exchange as initiated by an Out-of-Band invitation: + +- `POST /out-of-band/create-invitation` accepts two parameters (in addition to others): + - `use_did_method`: a DID Method (options: `did:peer:2` `did:peer:4`) indicating that a DID of that type is created (if necessary), and used in the invitation. If a DID of the type has to be created, it is flagged as the "invitation" DID and used in all future invitations so that connection reuse is the default behaviour. + - This is the recommend approach, and we further recommend using `did:peer:4`. + - `use_did`: a complete DID, which will be used for the invitation being established. This supports the edge case of an entity wanting to use a new DID for every invitation. It is the responsibility of the controller to create the DID before passing it in. + - If not provided, the 0.11.0 behaviour of an unqualified DID is used. + - We expect this behaviour will change in a later release to be that `use_did_method="did:peer:4"` is the default, which is created and (re)used. +- The provided handshake protocol list must also include `didexchange/1.1`. Optionally, `didexchage/1.0` may also be provided, thus enabling backwards compatibility with agents that do not yet support `didexchage/1.0` and use of unqualified DIDs. + +When receiving an OOB invitation or creating a DID Exchange request to a known Public DID: + +- `POST /didexchange/create-request` and `POST /didexchange/{conn_id}/accept-invitation` accepts two parameters (in addition to others): + - `use_did_method`: a DID Method (options: `did:peer:2` `did:peer:4`) indicating that a DID of that type should be created and used for the connection. + - This is the recommend approach, and we further recommend using `did:peer:4`. + - `use_did`: a complete DID, which will be used for the connection being established. This supports the edge case of an entity wanting to use the same DID for more than one connection. It is the responsibility of the controller to create the DID before passing it in. + - If neither option is provided, the 0.11.0 behaviour of an unqualified DID is created if DID Exchange 1.0 is used, and a DID Peer 4 is used if DID Exchange 1.1 is used. + - We expect this behaviour will change in a later release to be that a `did:peer:4` is created and DID Exchange 1.1 is always used. +- When `auto-accept` is used with DID Exchange, then an unqualified DID is created if DID Exchange 1.0 is being used, and a DID Peer 4 is used if DID Exchange 1.1 is used. + +With these changes, an existing ACA-Py installation using unqualified DIDs can upgrade to use qualified DIDs: + +- Reactively in 0.12.0, by using like DIDs from the other agent. +- Proactively, by adding the `use_did` or `use_did_method` parameter on the `POST /out-of-band/create-invitation`, `POST /didexchange/create-request`. and `POST /didexchange/{conn_id}/accept_invitation` endpoints and specifying `did:peer:2` or `did_peer:4`. + - The other agent must be able to process the selected DID Method. +- Proactively, by updating to use DID Exchange v1.1 and having the other side `auto-accept` the connection. + +## DID Rotation + +As part of the transition to qualified DIDs, existing connections may be updated to qualified DIDs using the DID Rotate protocol. This is not strictly required; since DIDComm v1 depends on recipient keys for correlating a received message back to a connection, the DID itself is mostly ignored. However, as we transition to DIDComm v2 or if it is desired to update the keys associated with a connection, DID Rotate may be used to update keys and service endpoints. + +The steps to do so are: + +- The rotating party creates a new DID using `POST /wallet/did/create` (or through the endpoints provided by a plugged in DID Method, if relevant). + - For example, the rotating party will likely create a new `did:peer:4`. +- The rotating party initiates the rotation with `POST /did-rotate/{conn_id}/rotate` providing the created DID as the `to_did` in the body of the Admin API request. +- If the receiving party supports DID rotation, a `did_rotate` webhook will be emitted indicating success. diff --git a/docs/features/SupportedRFCs.md b/docs/features/SupportedRFCs.md index 7bf280f27e..7c895641ca 100644 --- a/docs/features/SupportedRFCs.md +++ b/docs/features/SupportedRFCs.md @@ -8,7 +8,7 @@ ACA-Py or the repository `main` branch. Reminders (and PRs!) to update this page welcome! If you have any questions, please contact us on the #aries channel on [Hyperledger Discord](https://discord.gg/hyperledger) or through an issue in this repo. -**Last Update**: 2024-03-05, Release 0.12.0rc2 +**Last Update**: 2024-04-08, Release 0.12.0rc3 > The checklist version of this document was created as a joint effort > between [Northern Block](https://northernblock.io/), [Animo Solutions](https://animo.id/) and the Ontario government, on behalf of the Ontario government. @@ -64,7 +64,7 @@ A summary of the Aries Interop Profiles and Aries RFCs supported in ACA-Py can b | Method | Supported | Notes | | --- | :--: | -- | -| "unqualified" | :white_check_mark: | Pre-DID standard identifiers. Used either in a peer-to-peer context, or as an alternate form of a `did:sov` DID published on an Indy network. | +| "unqualified" | :warning: Deprecated | Pre-DID standard identifiers. Used either in a peer-to-peer context, or as an alternate form of a `did:sov` DID published on an Indy network. | | `did:sov` | :white_check_mark: | | | `did:web` | :white_check_mark: | Resolution only | | `did:key` | :white_check_mark: | | @@ -91,6 +91,7 @@ A summary of the Aries Interop Profiles and Aries RFCs supported in ACA-Py can b | ACA-Py Plugins | :white_check_mark: | The [ACA-Py Plugins] repository contains a growing set of plugins that are maintained and (mostly) tested against new releases of ACA-Py. | | Multi use invitations | :white_check_mark: | | | Invitations using public did | :white_check_mark: | | +| Invitations using peer dids supporting connection reuse | :white_check_mark: | | | Implicit pickup of messages in role of mediator | :white_check_mark: | | | [Revocable AnonCreds Credentials](https://github.com/hyperledger/indy-hipe/tree/main/text/0011-cred-revocation) | :white_check_mark: | | | Multi-Tenancy | :white_check_mark: | [Documentation](https://github.com/hyperledger/aries-cloudagent-python/blob/main/Multitenancy.md) | @@ -126,10 +127,7 @@ are fully supported in ACA-Py **EXCEPT** as noted in the table below. | RFC | Supported | Notes | | --- | :--: | -- | -| [0587-encryption-envelope-v2](https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0587-encryption-envelope-v2) | :construction: | Supporting the DIDComm v2 encryption envelope does not make sense until DIDComm v2 is to be supported. | -| [0317-please-ack](https://github.com/hyperledger/aries-rfcs/tree/main/features/0317-please-ack) | :x: | An investigation was done into supporting `please-ack` and a number of complications were found. As a result, we expect that `please-ack` will be dropped from AIP 2.0. It has not been implemented by any Aries frameworks or deployments. | - -There is a [PR to the Aries RFCs repository](https://github.com/hyperledger/aries-rfcs/pull/814) to remove those RFCs from AIP 2.0. If that PR is removed, the RFCs will be removed from the table above. +| Fully Supported | | | ### Other Supported RFCs diff --git a/docs/generated/aries_cloudagent.anoncreds.rst b/docs/generated/aries_cloudagent.anoncreds.rst index 606feb64fa..72b7907708 100644 --- a/docs/generated/aries_cloudagent.anoncreds.rst +++ b/docs/generated/aries_cloudagent.anoncreds.rst @@ -26,6 +26,14 @@ aries\_cloudagent.anoncreds.base module :undoc-members: :show-inheritance: +aries\_cloudagent.anoncreds.error\_messages module +-------------------------------------------------- + +.. automodule:: aries_cloudagent.anoncreds.error_messages + :members: + :undoc-members: + :show-inheritance: + aries\_cloudagent.anoncreds.events module ----------------------------------------- diff --git a/docs/generated/aries_cloudagent.messaging.rst b/docs/generated/aries_cloudagent.messaging.rst index 21bd62a4f3..ef1d420b33 100644 --- a/docs/generated/aries_cloudagent.messaging.rst +++ b/docs/generated/aries_cloudagent.messaging.rst @@ -53,6 +53,14 @@ aries\_cloudagent.messaging.error module :undoc-members: :show-inheritance: +aries\_cloudagent.messaging.message\_type module +------------------------------------------------ + +.. automodule:: aries_cloudagent.messaging.message_type + :members: + :undoc-members: + :show-inheritance: + aries\_cloudagent.messaging.request\_context module --------------------------------------------------- diff --git a/docs/generated/aries_cloudagent.protocols.did_rotate.rst b/docs/generated/aries_cloudagent.protocols.did_rotate.rst new file mode 100644 index 0000000000..7ab84dc303 --- /dev/null +++ b/docs/generated/aries_cloudagent.protocols.did_rotate.rst @@ -0,0 +1,26 @@ +aries\_cloudagent.protocols.did\_rotate package +=============================================== + +.. automodule:: aries_cloudagent.protocols.did_rotate + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + aries_cloudagent.protocols.did_rotate.v1_0 + +Submodules +---------- + +aries\_cloudagent.protocols.did\_rotate.definition module +--------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.definition + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.handlers.rst b/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.handlers.rst new file mode 100644 index 0000000000..44c382d223 --- /dev/null +++ b/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.handlers.rst @@ -0,0 +1,42 @@ +aries\_cloudagent.protocols.did\_rotate.v1\_0.handlers package +============================================================== + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.handlers + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +aries\_cloudagent.protocols.did\_rotate.v1\_0.handlers.ack\_handler module +-------------------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.handlers.ack_handler + :members: + :undoc-members: + :show-inheritance: + +aries\_cloudagent.protocols.did\_rotate.v1\_0.handlers.hangup\_handler module +----------------------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.handlers.hangup_handler + :members: + :undoc-members: + :show-inheritance: + +aries\_cloudagent.protocols.did\_rotate.v1\_0.handlers.problem\_report\_handler module +-------------------------------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.handlers.problem_report_handler + :members: + :undoc-members: + :show-inheritance: + +aries\_cloudagent.protocols.did\_rotate.v1\_0.handlers.rotate\_handler module +----------------------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.handlers.rotate_handler + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.messages.rst b/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.messages.rst new file mode 100644 index 0000000000..86a97af963 --- /dev/null +++ b/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.messages.rst @@ -0,0 +1,42 @@ +aries\_cloudagent.protocols.did\_rotate.v1\_0.messages package +============================================================== + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.messages + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +aries\_cloudagent.protocols.did\_rotate.v1\_0.messages.ack module +----------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.messages.ack + :members: + :undoc-members: + :show-inheritance: + +aries\_cloudagent.protocols.did\_rotate.v1\_0.messages.hangup module +-------------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.messages.hangup + :members: + :undoc-members: + :show-inheritance: + +aries\_cloudagent.protocols.did\_rotate.v1\_0.messages.problem\_report module +----------------------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.messages.problem_report + :members: + :undoc-members: + :show-inheritance: + +aries\_cloudagent.protocols.did\_rotate.v1\_0.messages.rotate module +-------------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.messages.rotate + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.models.rst b/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.models.rst new file mode 100644 index 0000000000..f0a8aa910a --- /dev/null +++ b/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.models.rst @@ -0,0 +1,18 @@ +aries\_cloudagent.protocols.did\_rotate.v1\_0.models package +============================================================ + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.models + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +aries\_cloudagent.protocols.did\_rotate.v1\_0.models.rotate\_record module +-------------------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.models.rotate_record + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.rst b/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.rst new file mode 100644 index 0000000000..e98962f94c --- /dev/null +++ b/docs/generated/aries_cloudagent.protocols.did_rotate.v1_0.rst @@ -0,0 +1,44 @@ +aries\_cloudagent.protocols.did\_rotate.v1\_0 package +===================================================== + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0 + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + aries_cloudagent.protocols.did_rotate.v1_0.handlers + aries_cloudagent.protocols.did_rotate.v1_0.messages + aries_cloudagent.protocols.did_rotate.v1_0.models + +Submodules +---------- + +aries\_cloudagent.protocols.did\_rotate.v1\_0.manager module +------------------------------------------------------------ + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.manager + :members: + :undoc-members: + :show-inheritance: + +aries\_cloudagent.protocols.did\_rotate.v1\_0.message\_types module +------------------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.message_types + :members: + :undoc-members: + :show-inheritance: + +aries\_cloudagent.protocols.did\_rotate.v1\_0.routes module +----------------------------------------------------------- + +.. automodule:: aries_cloudagent.protocols.did_rotate.v1_0.routes + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/generated/aries_cloudagent.protocols.rst b/docs/generated/aries_cloudagent.protocols.rst index c569e1d81b..4414c5866b 100644 --- a/docs/generated/aries_cloudagent.protocols.rst +++ b/docs/generated/aries_cloudagent.protocols.rst @@ -16,6 +16,7 @@ Subpackages aries_cloudagent.protocols.basicmessage aries_cloudagent.protocols.connections aries_cloudagent.protocols.coordinate_mediation + aries_cloudagent.protocols.did_rotate aries_cloudagent.protocols.didexchange aries_cloudagent.protocols.discovery aries_cloudagent.protocols.endorse_transaction diff --git a/docs/generated/aries_cloudagent.storage.rst b/docs/generated/aries_cloudagent.storage.rst index bd06d4d460..b38e0fbb92 100644 --- a/docs/generated/aries_cloudagent.storage.rst +++ b/docs/generated/aries_cloudagent.storage.rst @@ -64,3 +64,11 @@ aries\_cloudagent.storage.record module :members: :undoc-members: :show-inheritance: + +aries\_cloudagent.storage.type module +------------------------------------- + +.. automodule:: aries_cloudagent.storage.type + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/generated/aries_cloudagent.utils.rst b/docs/generated/aries_cloudagent.utils.rst index b231555d64..0cb4042147 100644 --- a/docs/generated/aries_cloudagent.utils.rst +++ b/docs/generated/aries_cloudagent.utils.rst @@ -81,6 +81,14 @@ aries\_cloudagent.utils.outofband module :undoc-members: :show-inheritance: +aries\_cloudagent.utils.profiles module +--------------------------------------- + +.. automodule:: aries_cloudagent.utils.profiles + :members: + :undoc-members: + :show-inheritance: + aries\_cloudagent.utils.repeat module ------------------------------------- diff --git a/docs/generated/aries_cloudagent.vc.vc_ld.rst b/docs/generated/aries_cloudagent.vc.vc_ld.rst index fe05d177f9..f7e8566043 100644 --- a/docs/generated/aries_cloudagent.vc.vc_ld.rst +++ b/docs/generated/aries_cloudagent.vc.vc_ld.rst @@ -17,6 +17,14 @@ Subpackages Submodules ---------- +aries\_cloudagent.vc.vc\_ld.external\_suite module +-------------------------------------------------- + +.. automodule:: aries_cloudagent.vc.vc_ld.external_suite + :members: + :undoc-members: + :show-inheritance: + aries\_cloudagent.vc.vc\_ld.issue module ---------------------------------------- diff --git a/mkdocs.yml b/mkdocs.yml index 00ffcf2280..30e012bb11 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -89,6 +89,7 @@ nav: - The Admin API: features/AdminAPI.md - ACA-Py Plugins: features/PlugIns.md - Multitenant ACA-Py: features/Multitenancy.md + - Qualified DIDs: features/QualifiedDIDs.md - DID Methods: features/DIDMethods.md - DID Resolution: features/DIDResolution.md - Publishing AnonCreds Objects To Other Ledgers/Verifiable Data Registries: features/AnonCredsMethods.md diff --git a/open-api/openapi.json b/open-api/openapi.json index 0a7fdf6522..7fe3aa076b 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -2,7 +2,7 @@ "openapi" : "3.0.1", "info" : { "title" : "Aries Cloud Agent", - "version" : "v0.12.0rc2" + "version" : "v0.12.0rc3" }, "servers" : [ { "url" : "/" @@ -13,6 +13,27 @@ "tags" : [ { "description" : "Menu interaction over connection", "name" : "action-menu" + }, { + "description" : "Anoncreds credential definition management", + "externalDocs" : { + "description" : "Specification", + "url" : "https://hyperledger.github.io/anoncreds-spec" + }, + "name" : "anoncreds - credential definitions" + }, { + "description" : "Revocation registry management", + "externalDocs" : { + "description" : "Overview", + "url" : "https://github.com/hyperledger/indy-hipe/tree/master/text/0011-cred-revocation" + }, + "name" : "anoncreds - revocation" + }, { + "description" : "Anoncreds schema management", + "externalDocs" : { + "description" : "Specification", + "url" : "https://hyperledger.github.io/anoncreds-spec" + }, + "name" : "anoncreds - schemas" }, { "description" : "Simple messaging", "externalDocs" : { @@ -48,6 +69,13 @@ "url" : "https://github.com/hyperledger/aries-rfcs/tree/25464a5c8f8a17b14edaa4310393df6094ace7b0/features/0023-did-exchange" }, "name" : "did-exchange" + }, { + "description" : "Rorate a DID", + "externalDocs" : { + "description" : "Specification", + "url" : "https://github.com/hyperledger/aries-rfcs/tree/main/features/0794-did-rotate" + }, + "name" : "did-rotate" }, { "description" : "Feature discovery", "externalDocs" : { @@ -282,53 +310,771 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ActionMenuModulesResult" + "$ref" : "#/components/schemas/ActionMenuModulesResult" + } + } + }, + "description" : "" + } + }, + "summary" : "Request the active menu", + "tags" : [ "action-menu" ] + } + }, + "/action-menu/{conn_id}/send-menu" : { + "post" : { + "parameters" : [ { + "description" : "Connection identifier", + "in" : "path", + "name" : "conn_id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/SendMenu" + } + } + }, + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ActionMenuModulesResult" + } + } + }, + "description" : "" + } + }, + "summary" : "Send an action menu to a connection", + "tags" : [ "action-menu" ], + "x-codegen-request-body-name" : "body" + } + }, + "/anoncreds/credential-definition" : { + "post" : { + "requestBody" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/CredDefPostRequest" + } + } + }, + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CredDefResult" + } + } + }, + "description" : "" + } + }, + "summary" : "Create a credential definition on the connected ledger", + "tags" : [ "anoncreds - credential definitions" ], + "x-codegen-request-body-name" : "body" + } + }, + "/anoncreds/credential-definition/{cred_def_id}" : { + "get" : { + "parameters" : [ { + "description" : "Credential definition identifier", + "in" : "path", + "name" : "cred_def_id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/GetCredDefResult" + } + } + }, + "description" : "" + } + }, + "summary" : "Retrieve an individual credential definition details", + "tags" : [ "anoncreds - credential definitions" ] + } + }, + "/anoncreds/credential-definitions" : { + "get" : { + "parameters" : [ { + "description" : "Issuer Identifier of the credential definition", + "in" : "query", + "name" : "issuer_id", + "schema" : { + "type" : "string" + } + }, { + "description" : "Schema identifier", + "in" : "query", + "name" : "schema_id", + "schema" : { + "type" : "string" + } + }, { + "description" : "Schema name", + "in" : "query", + "name" : "schema_name", + "schema" : { + "type" : "string" + } + }, { + "description" : "Schema version", + "in" : "query", + "name" : "schema_version", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/GetCredDefsResponse" + } + } + }, + "description" : "" + } + }, + "summary" : "Retrieve all credential definition ids", + "tags" : [ "anoncreds - credential definitions" ] + } + }, + "/anoncreds/registry/{rev_reg_id}/active" : { + "put" : { + "parameters" : [ { + "description" : "Revocation Registry identifier", + "in" : "path", + "name" : "rev_reg_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevocationModuleResponse" + } + } + }, + "description" : "" + } + }, + "summary" : "Update the active registry", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/registry/{rev_reg_id}/tails-file" : { + "put" : { + "parameters" : [ { + "description" : "Revocation Registry identifier", + "in" : "path", + "name" : "rev_reg_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevocationModuleResponse" + } + } + }, + "description" : "" + } + }, + "summary" : "Upload local tails file to server", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation-list" : { + "post" : { + "requestBody" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/RevListCreateRequest" + } + } + }, + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevListResult" + } + } + }, + "description" : "" + } + }, + "summary" : "Create and publish a revocation status list on the connected ledger", + "tags" : [ "anoncreds - revocation" ], + "x-codegen-request-body-name" : "body" + } + }, + "/anoncreds/revocation-registry-definition" : { + "post" : { + "requestBody" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/RevRegCreateRequestSchemaAnoncreds" + } + } + }, + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevRegDefResult" + } + } + }, + "description" : "" + } + }, + "summary" : "Create and publish a registration revocation on the connected ledger", + "tags" : [ "anoncreds - revocation" ], + "x-codegen-request-body-name" : "body" + } + }, + "/anoncreds/revocation/active-registry/{cred_def_id}" : { + "get" : { + "parameters" : [ { + "description" : "Credential definition identifier", + "in" : "path", + "name" : "cred_def_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevRegResultSchemaAnoncreds" + } + } + }, + "description" : "" + } + }, + "summary" : "Get current active revocation registry by credential definition id", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/active-registry/{cred_def_id}/rotate" : { + "post" : { + "parameters" : [ { + "description" : "Credential definition identifier", + "in" : "path", + "name" : "cred_def_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevRegsCreatedSchemaAnoncreds" + } + } + }, + "description" : "" + } + }, + "summary" : "Rotate revocation registry", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/credential-record" : { + "get" : { + "parameters" : [ { + "description" : "Credential exchange identifier", + "in" : "query", + "name" : "cred_ex_id", + "schema" : { + "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type" : "string" + } + }, { + "description" : "Credential revocation identifier", + "in" : "query", + "name" : "cred_rev_id", + "schema" : { + "pattern" : "^[1-9][0-9]*$", + "type" : "string" + } + }, { + "description" : "Revocation registry identifier", + "in" : "query", + "name" : "rev_reg_id", + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CredRevRecordResult" + } + } + }, + "description" : "" + } + }, + "summary" : "Get credential revocation status", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/publish-revocations" : { + "post" : { + "requestBody" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/PublishRevocations" + } + } + }, + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PublishRevocationsResult" + } + } + }, + "description" : "" + } + }, + "summary" : "Publish pending revocations to ledger", + "tags" : [ "anoncreds - revocation" ], + "x-codegen-request-body-name" : "body" + } + }, + "/anoncreds/revocation/registries" : { + "get" : { + "parameters" : [ { + "description" : "Credential definition identifier", + "in" : "query", + "name" : "cred_def_id", + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$", + "type" : "string" + } + }, { + "description" : "Revocation registry state", + "in" : "query", + "name" : "state", + "schema" : { + "enum" : [ "finished", "failed", "action", "wait", "decommissioned", "full" ], + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevRegsCreatedSchemaAnoncreds" + } + } + }, + "description" : "" + } + }, + "summary" : "Search for matching revocation registries that current agent created", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}" : { + "get" : { + "parameters" : [ { + "description" : "Revocation Registry identifier", + "in" : "path", + "name" : "rev_reg_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevRegResultSchemaAnoncreds" + } + } + }, + "description" : "" + } + }, + "summary" : "Get revocation registry by revocation registry id", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/fix-revocation-entry-state" : { + "put" : { + "parameters" : [ { + "description" : "Revocation Registry identifier", + "in" : "path", + "name" : "rev_reg_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + }, { + "description" : "Apply updated accumulator transaction to ledger", + "in" : "query", + "name" : "apply_ledger_update", + "required" : true, + "schema" : { + "type" : "boolean" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevRegWalletUpdatedResultSchemaAnoncreds" + } + } + }, + "description" : "" + } + }, + "summary" : "Fix revocation state in wallet and return number of updated entries", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/issued" : { + "get" : { + "parameters" : [ { + "description" : "Revocation Registry identifier", + "in" : "path", + "name" : "rev_reg_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevRegIssuedResultSchemaAnoncreds" + } + } + }, + "description" : "" + } + }, + "summary" : "Get number of credentials issued against revocation registry", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/issued/details" : { + "get" : { + "parameters" : [ { + "description" : "Revocation Registry identifier", + "in" : "path", + "name" : "rev_reg_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CredRevRecordDetailsResultSchemaAnoncreds" + } + } + }, + "description" : "" + } + }, + "summary" : "Get details of credentials issued against revocation registry", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/issued/indy_recs" : { + "get" : { + "parameters" : [ { + "description" : "Revocation Registry identifier", + "in" : "path", + "name" : "rev_reg_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CredRevIndyRecordsResultSchemaAnoncreds" + } + } + }, + "description" : "" + } + }, + "summary" : "Get details of revoked credentials from ledger", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/set-state" : { + "patch" : { + "parameters" : [ { + "description" : "Revocation Registry identifier", + "in" : "path", + "name" : "rev_reg_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + }, { + "description" : "Revocation registry state to set", + "in" : "query", + "name" : "state", + "required" : true, + "schema" : { + "enum" : [ "finished", "failed", "action", "wait", "decommissioned", "full" ], + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevRegResultSchemaAnoncreds" + } + } + }, + "description" : "" + } + }, + "summary" : "Set revocation registry state manually", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/tails-file" : { + "get" : { + "parameters" : [ { + "description" : "Revocation Registry identifier", + "in" : "path", + "name" : "rev_reg_id", + "required" : true, + "schema" : { + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/octet-stream" : { + "schema" : { + "$ref" : "#/components/schemas/RevocationAnoncredsModuleResponse" + } + } + }, + "description" : "tails file" + } + }, + "summary" : "Download tails file", + "tags" : [ "anoncreds - revocation" ] + } + }, + "/anoncreds/revocation/revoke" : { + "post" : { + "requestBody" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/RevokeRequestSchemaAnoncreds" + } + } + }, + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RevocationAnoncredsModuleResponse" + } + } + }, + "description" : "" + } + }, + "summary" : "Revoke an issued credential", + "tags" : [ "anoncreds - revocation" ], + "x-codegen-request-body-name" : "body" + } + }, + "/anoncreds/schema" : { + "post" : { + "requestBody" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/SchemaPostRequest" + } + } + }, + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/SchemaResult" + } + } + }, + "description" : "" + } + }, + "summary" : "Create a schema on the connected ledger", + "tags" : [ "anoncreds - schemas" ], + "x-codegen-request-body-name" : "body" + } + }, + "/anoncreds/schema/{schema_id}" : { + "get" : { + "parameters" : [ { + "description" : "Schema identifier", + "in" : "path", + "name" : "schema_id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/GetSchemaResult" } } }, "description" : "" } }, - "summary" : "Request the active menu", - "tags" : [ "action-menu" ] + "summary" : "Retrieve an individual schemas details", + "tags" : [ "anoncreds - schemas" ] } }, - "/action-menu/{conn_id}/send-menu" : { - "post" : { + "/anoncreds/schemas" : { + "get" : { "parameters" : [ { - "description" : "Connection identifier", - "in" : "path", - "name" : "conn_id", - "required" : true, + "description" : "Schema issuer identifier", + "in" : "query", + "name" : "schema_issuer_id", + "schema" : { + "type" : "string" + } + }, { + "description" : "Schema name", + "in" : "query", + "name" : "schema_name", + "schema" : { + "type" : "string" + } + }, { + "description" : "Schema version", + "in" : "query", + "name" : "schema_version", "schema" : { "type" : "string" } } ], - "requestBody" : { - "content" : { - "*/*" : { - "schema" : { - "$ref" : "#/components/schemas/SendMenu" - } - } - }, - "required" : false - }, "responses" : { "200" : { "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/ActionMenuModulesResult" + "$ref" : "#/components/schemas/GetSchemasResponse" } } }, "description" : "" } }, - "summary" : "Send an action menu to a connection", - "tags" : [ "action-menu" ], - "x-codegen-request-body-name" : "body" + "summary" : "Retrieve all schema ids", + "tags" : [ "anoncreds - schemas" ] } }, "/connections" : { @@ -345,7 +1091,7 @@ "in" : "query", "name" : "connection_protocol", "schema" : { - "enum" : [ "connections/1.0", "didexchange/1.0" ], + "enum" : [ "connections/1.0", "didexchange/1.0", "didexchange/1.1" ], "type" : "string" } }, { @@ -376,7 +1122,7 @@ "in" : "query", "name" : "state", "schema" : { - "enum" : [ "abandoned", "invitation", "response", "active", "start", "request", "error", "init", "completed" ], + "enum" : [ "response", "active", "request", "init", "error", "invitation", "completed", "start", "abandoned" ], "type" : "string" } }, { @@ -422,6 +1168,7 @@ }, "/connections/create-invitation" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Alias", "in" : "query", @@ -509,6 +1256,7 @@ }, "/connections/receive-invitation" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Alias", "in" : "query", @@ -613,6 +1361,7 @@ }, "/connections/{conn_id}/accept-invitation" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Connection identifier", "in" : "path", @@ -663,6 +1412,7 @@ }, "/connections/{conn_id}/accept-request" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Connection identifier", "in" : "path", @@ -1348,6 +2098,71 @@ "x-codegen-request-body-name" : "body" } }, + "/did-rotate/{conn_id}/hangup" : { + "post" : { + "parameters" : [ { + "description" : "Connection identifier", + "in" : "path", + "name" : "conn_id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Hangup" + } + } + }, + "description" : "Hangup agent message for observer" + } + }, + "summary" : "Send hangup of DID rotation as a rotator", + "tags" : [ "did-rotate" ] + } + }, + "/did-rotate/{conn_id}/rotate" : { + "post" : { + "parameters" : [ { + "description" : "Connection identifier", + "in" : "path", + "name" : "conn_id", + "required" : true, + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/DIDRotateRequestJSON" + } + } + }, + "required" : false + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/Rotate" + } + } + }, + "description" : "Rotate agent message for observer" + } + }, + "summary" : "Begin rotation of a DID as a rotator", + "tags" : [ "did-rotate" ], + "x-codegen-request-body-name" : "body" + } + }, "/didexchange/create-request" : { "post" : { "parameters" : [ { @@ -1410,6 +2225,29 @@ "schema" : { "type" : "string" } + }, { + "description" : "Which DID Exchange Protocol version to use", + "in" : "query", + "name" : "protocol", + "schema" : { + "enum" : [ "didexchange/1.0", "didexchange/1.1" ], + "type" : "string" + } + }, { + "description" : "The DID to use to for this connection", + "in" : "query", + "name" : "use_did", + "schema" : { + "type" : "string" + } + }, { + "description" : "The DID method to use to generate a DID for this connection", + "in" : "query", + "name" : "use_did_method", + "schema" : { + "enum" : [ "did:peer:2", "did:peer:4" ], + "type" : "string" + } }, { "description" : "Use public DID for this connection", "in" : "query", @@ -1436,6 +2274,7 @@ }, "/didexchange/receive-request" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Alias for connection", "in" : "query", @@ -1519,6 +2358,21 @@ "schema" : { "type" : "string" } + }, { + "description" : "The DID to use to for this connection", + "in" : "query", + "name" : "use_did", + "schema" : { + "type" : "string" + } + }, { + "description" : "The DID method to use to generate a DID for this connection", + "in" : "query", + "name" : "use_did_method", + "schema" : { + "enum" : [ "did:peer:2", "did:peer:4" ], + "type" : "string" + } } ], "responses" : { "200" : { @@ -2230,6 +3084,7 @@ }, "/issue-credential/create" : { "post" : { + "deprecated" : true, "requestBody" : { "content" : { "*/*" : { @@ -2259,6 +3114,7 @@ }, "/issue-credential/create-offer" : { "post" : { + "deprecated" : true, "requestBody" : { "content" : { "*/*" : { @@ -2288,6 +3144,7 @@ }, "/issue-credential/records" : { "get" : { + "deprecated" : true, "parameters" : [ { "description" : "Connection identifier", "in" : "query", @@ -2337,6 +3194,7 @@ }, "/issue-credential/records/{cred_ex_id}" : { "delete" : { + "deprecated" : true, "parameters" : [ { "description" : "Credential exchange identifier", "in" : "path", @@ -2363,6 +3221,7 @@ "tags" : [ "issue-credential v1.0" ] }, "get" : { + "deprecated" : true, "parameters" : [ { "description" : "Credential exchange identifier", "in" : "path", @@ -2391,6 +3250,7 @@ }, "/issue-credential/records/{cred_ex_id}/issue" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Credential exchange identifier", "in" : "path", @@ -2430,6 +3290,7 @@ }, "/issue-credential/records/{cred_ex_id}/problem-report" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Credential exchange identifier", "in" : "path", @@ -2469,6 +3330,7 @@ }, "/issue-credential/records/{cred_ex_id}/send-offer" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Credential exchange identifier", "in" : "path", @@ -2508,6 +3370,7 @@ }, "/issue-credential/records/{cred_ex_id}/send-request" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Credential exchange identifier", "in" : "path", @@ -2547,6 +3410,7 @@ }, "/issue-credential/records/{cred_ex_id}/store" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Credential exchange identifier", "in" : "path", @@ -2586,6 +3450,7 @@ }, "/issue-credential/send" : { "post" : { + "deprecated" : true, "requestBody" : { "content" : { "*/*" : { @@ -2615,6 +3480,7 @@ }, "/issue-credential/send-offer" : { "post" : { + "deprecated" : true, "requestBody" : { "content" : { "*/*" : { @@ -2644,6 +3510,7 @@ }, "/issue-credential/send-proposal" : { "post" : { + "deprecated" : true, "requestBody" : { "content" : { "*/*" : { @@ -3653,6 +4520,13 @@ "schema" : { "type" : "boolean" } + }, { + "description" : "Create unique DID for this invitation (default false)", + "in" : "query", + "name" : "create_unique_did", + "schema" : { + "type" : "boolean" + } }, { "description" : "Create invitation for multiple use (default false)", "in" : "query", @@ -4192,6 +5066,7 @@ }, "/present-proof/create-request" : { "post" : { + "deprecated" : true, "requestBody" : { "content" : { "*/*" : { @@ -4221,6 +5096,7 @@ }, "/present-proof/records" : { "get" : { + "deprecated" : true, "parameters" : [ { "description" : "Connection identifier", "in" : "query", @@ -4270,6 +5146,7 @@ }, "/present-proof/records/{pres_ex_id}" : { "delete" : { + "deprecated" : true, "parameters" : [ { "description" : "Presentation exchange identifier", "in" : "path", @@ -4296,6 +5173,7 @@ "tags" : [ "present-proof v1.0" ] }, "get" : { + "deprecated" : true, "parameters" : [ { "description" : "Presentation exchange identifier", "in" : "path", @@ -4324,6 +5202,7 @@ }, "/present-proof/records/{pres_ex_id}/credentials" : { "get" : { + "deprecated" : true, "parameters" : [ { "description" : "Presentation exchange identifier", "in" : "path", @@ -4386,6 +5265,7 @@ }, "/present-proof/records/{pres_ex_id}/problem-report" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Presentation exchange identifier", "in" : "path", @@ -4425,6 +5305,7 @@ }, "/present-proof/records/{pres_ex_id}/send-presentation" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Presentation exchange identifier", "in" : "path", @@ -4464,6 +5345,7 @@ }, "/present-proof/records/{pres_ex_id}/send-request" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Presentation exchange identifier", "in" : "path", @@ -4503,6 +5385,7 @@ }, "/present-proof/records/{pres_ex_id}/verify-presentation" : { "post" : { + "deprecated" : true, "parameters" : [ { "description" : "Presentation exchange identifier", "in" : "path", @@ -4531,6 +5414,7 @@ }, "/present-proof/send-proposal" : { "post" : { + "deprecated" : true, "requestBody" : { "content" : { "*/*" : { @@ -4560,6 +5444,7 @@ }, "/present-proof/send-request" : { "post" : { + "deprecated" : true, "requestBody" : { "content" : { "*/*" : { @@ -4688,7 +5573,7 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/PublishRevocations" + "$ref" : "#/components/schemas/PublishRevocationsSchemaAnoncreds" } } }, @@ -4761,7 +5646,7 @@ "content" : { "application/json" : { "schema" : { - "$ref" : "#/components/schemas/CredRevRecordResult" + "$ref" : "#/components/schemas/CredRevRecordResultSchemaAnoncreds" } } }, @@ -4793,7 +5678,7 @@ "content" : { "*/*" : { "schema" : { - "$ref" : "#/components/schemas/PublishRevocations" + "$ref" : "#/components/schemas/PublishRevocationsSchemaAnoncreds" } } }, @@ -6085,7 +6970,7 @@ "in" : "query", "name" : "method", "schema" : { - "enum" : [ "key", "sov" ], + "enum" : [ "key", "sov", "did:peer:2", "did:peer:4" ], "type" : "string" } }, { @@ -6539,6 +7424,35 @@ }, "type" : "object" }, + "AnonCredsSchema" : { + "properties" : { + "attrNames" : { + "description" : "Schema attribute names", + "items" : { + "description" : "Attribute name", + "example" : "score", + "type" : "string" + }, + "type" : "array" + }, + "issuerId" : { + "description" : "Issuer Identifier of the credential definition or schema", + "example" : "WgWxqztrNooG92RXvxSTWv", + "type" : "string" + }, + "name" : { + "description" : "Schema name", + "example" : "Example schema", + "type" : "string" + }, + "version" : { + "description" : "Schema version", + "example" : "1.0", + "type" : "string" + } + }, + "type" : "object" + }, "AttachDecorator" : { "properties" : { "@id" : { @@ -6785,7 +7699,7 @@ }, "connection_protocol" : { "description" : "Connection protocol used", - "enum" : [ "connections/1.0", "didexchange/1.0" ], + "enum" : [ "connections/1.0", "didexchange/1.0", "didexchange/1.1" ], "example" : "connections/1.0", "type" : "string" }, @@ -6886,7 +7800,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "did" : { @@ -7184,9 +8097,9 @@ "type" : "string" }, "wallet_type" : { - "description" : "Type of the wallet to create", + "description" : "Type of the wallet to create. Must be same as base wallet.", "enum" : [ "askar", "askar-anoncreds", "in_memory", "indy" ], - "example" : "indy", + "example" : "askar", "type" : "string" }, "wallet_webhook_urls" : { @@ -7254,36 +8167,136 @@ }, "type" : "object" }, - "CreateWalletTokenResponse" : { + "CreateWalletTokenResponse" : { + "properties" : { + "token" : { + "description" : "Authorization token to authenticate wallet requests", + "example" : "eyJhbGciOiJFZERTQSJ9.eyJhIjogIjAifQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", + "type" : "string" + } + }, + "type" : "object" + }, + "CredAttrSpec" : { + "properties" : { + "mime-type" : { + "description" : "MIME type: omit for (null) default", + "example" : "image/jpeg", + "nullable" : true, + "type" : "string" + }, + "name" : { + "description" : "Attribute name", + "example" : "favourite_drink", + "type" : "string" + }, + "value" : { + "description" : "Attribute value: base64-encode if MIME type is present", + "example" : "martini", + "type" : "string" + } + }, + "required" : [ "name", "value" ], + "type" : "object" + }, + "CredDef" : { + "properties" : { + "issuerId" : { + "description" : "Issuer Identifier of the credential definition or schema", + "example" : "WgWxqztrNooG92RXvxSTWv", + "type" : "string" + }, + "schemaId" : { + "description" : "Schema identifier", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "type" : "string" + }, + "tag" : { + "description" : "The tag value passed in by the Issuer to\n an AnonCred's Credential Definition create and store implementation.", + "example" : "default", + "type" : "string" + }, + "type" : { + "enum" : [ "CL" ], + "type" : "string" + }, + "value" : { + "$ref" : "#/components/schemas/CredDefValueSchemaAnoncreds" + } + }, + "type" : "object" + }, + "CredDefPostOptions" : { + "properties" : { + "create_transaction_for_endorser" : { + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign.", + "example" : false, + "type" : "boolean" + }, + "endorser_connection_id" : { + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection.", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type" : "string" + }, + "revocation_registry_size" : { + "description" : "Maximum number of credential revocations per registry", + "example" : 1000, + "format" : "int32", + "type" : "integer" + }, + "support_revocation" : { + "description" : "Support credential revocation", + "type" : "boolean" + } + }, + "type" : "object" + }, + "CredDefPostRequest" : { + "properties" : { + "credential_definition" : { + "$ref" : "#/components/schemas/InnerCredDef" + }, + "options" : { + "$ref" : "#/components/schemas/CredDefPostOptions" + } + }, + "type" : "object" + }, + "CredDefResult" : { "properties" : { - "token" : { - "description" : "Authorization token to authenticate wallet requests", - "example" : "eyJhbGciOiJFZERTQSJ9.eyJhIjogIjAifQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", + "credential_definition_metadata" : { + "properties" : { }, + "type" : "object" + }, + "credential_definition_state" : { + "$ref" : "#/components/schemas/CredDefState" + }, + "job_id" : { "type" : "string" + }, + "registration_metadata" : { + "properties" : { }, + "type" : "object" } }, "type" : "object" }, - "CredAttrSpec" : { + "CredDefState" : { "properties" : { - "mime-type" : { - "description" : "MIME type: omit for (null) default", - "example" : "image/jpeg", - "nullable" : true, - "type" : "string" + "credential_definition" : { + "$ref" : "#/components/schemas/CredDefState_credential_definition" }, - "name" : { - "description" : "Attribute name", - "example" : "favourite_drink", + "credential_definition_id" : { + "description" : "credential definition id", + "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "nullable" : true, "type" : "string" }, - "value" : { - "description" : "Attribute value: base64-encode if MIME type is present", - "example" : "martini", + "state" : { + "enum" : [ "finished", "failed", "action", "wait" ], "type" : "string" } }, - "required" : [ "name", "value" ], "type" : "object" }, "CredDefValue" : { @@ -7325,6 +8338,35 @@ }, "type" : "object" }, + "CredDefValuePrimarySchemaAnoncreds" : { + "properties" : { + "n" : { + "example" : "0", + "pattern" : "^[0-9]*$", + "type" : "string" + }, + "r" : { + "properties" : { }, + "type" : "object" + }, + "rctxt" : { + "example" : "0", + "pattern" : "^[0-9]*$", + "type" : "string" + }, + "s" : { + "example" : "0", + "pattern" : "^[0-9]*$", + "type" : "string" + }, + "z" : { + "example" : "0", + "pattern" : "^[0-9]*$", + "type" : "string" + } + }, + "type" : "object" + }, "CredDefValueRevocation" : { "properties" : { "g" : { @@ -7374,6 +8416,66 @@ }, "type" : "object" }, + "CredDefValueRevocationSchemaAnoncreds" : { + "properties" : { + "g" : { + "example" : "1 1F14F&ECB578F 2 095E45DDF417D", + "type" : "string" + }, + "g_dash" : { + "example" : "1 1D64716fCDC00C 1 0C781960FA66E3D3 2 095E45DDF417D", + "type" : "string" + }, + "h" : { + "example" : "1 16675DAE54BFAE8 2 095E45DD417D", + "type" : "string" + }, + "h0" : { + "example" : "1 21E5EF9476EAF18 2 095E45DDF417D", + "type" : "string" + }, + "h1" : { + "example" : "1 236D1D99236090 2 095E45DDF417D", + "type" : "string" + }, + "h2" : { + "example" : "1 1C3AE8D1F1E277 2 095E45DDF417D", + "type" : "string" + }, + "h_cap" : { + "example" : "1 1B2A32CF3167 1 2490FEBF6EE55 1 0000000000000000", + "type" : "string" + }, + "htilde" : { + "example" : "1 1D8549E8C0F8 2 095E45DDF417D", + "type" : "string" + }, + "pk" : { + "example" : "1 142CD5E5A7DC 1 153885BD903312 2 095E45DDF417D", + "type" : "string" + }, + "u" : { + "example" : "1 0C430AAB2B4710 1 1CB3A0932EE7E 1 0000000000000000", + "type" : "string" + }, + "y" : { + "example" : "1 153558BD903312 2 095E45DDF417D 1 0000000000000000", + "type" : "string" + } + }, + "type" : "object" + }, + "CredDefValueSchemaAnoncreds" : { + "properties" : { + "primary" : { + "$ref" : "#/components/schemas/CredDefValueSchemaAnoncreds_primary" + }, + "revocation" : { + "$ref" : "#/components/schemas/CredDefValueSchemaAnoncreds_revocation" + } + }, + "type" : "object" + }, "CredInfoList" : { "properties" : { "results" : { @@ -7395,6 +8497,16 @@ }, "type" : "object" }, + "CredRevIndyRecordsResultSchemaAnoncreds" : { + "properties" : { + "rev_reg_delta" : { + "description" : "Indy revocation registry delta", + "properties" : { }, + "type" : "object" + } + }, + "type" : "object" + }, "CredRevRecordDetailsResult" : { "properties" : { "results" : { @@ -7406,7 +8518,26 @@ }, "type" : "object" }, + "CredRevRecordDetailsResultSchemaAnoncreds" : { + "properties" : { + "results" : { + "items" : { + "$ref" : "#/components/schemas/IssuerCredRevRecordSchemaAnoncreds" + }, + "type" : "array" + } + }, + "type" : "object" + }, "CredRevRecordResult" : { + "properties" : { + "result" : { + "$ref" : "#/components/schemas/IssuerCredRevRecordSchemaAnoncreds" + } + }, + "type" : "object" + }, + "CredRevRecordResultSchemaAnoncreds" : { "properties" : { "result" : { "$ref" : "#/components/schemas/IssuerCredRevRecord" @@ -7585,7 +8716,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -7633,7 +8763,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -7700,6 +8829,11 @@ "example" : "ed25519", "type" : "string" }, + "metadata" : { + "description" : "Additional metadata associated with the DID", + "properties" : { }, + "type" : "object" + }, "method" : { "description" : "Did method associated with the DID", "example" : "sov", @@ -7819,6 +8953,17 @@ }, "type" : "object" }, + "DIDRotateRequestJSON" : { + "properties" : { + "to_did" : { + "description" : "The DID the rotating party is rotating to", + "example" : "did:web:example.com", + "type" : "string" + } + }, + "required" : [ "to_did" ], + "type" : "object" + }, "DIDXRejectRequest" : { "properties" : { "reason" : { @@ -7839,7 +8984,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "did" : { @@ -8024,7 +9168,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "protocols" : { @@ -8048,7 +9191,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "disclosures" : { @@ -8221,6 +9363,40 @@ }, "type" : "object" }, + "GetCredDefResult" : { + "properties" : { + "credential_definition" : { + "$ref" : "#/components/schemas/CredDefState_credential_definition" + }, + "credential_definition_id" : { + "description" : "credential definition id", + "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "type" : "string" + }, + "credential_definitions_metadata" : { + "properties" : { }, + "type" : "object" + }, + "resolution_metadata" : { + "properties" : { }, + "type" : "object" + } + }, + "type" : "object" + }, + "GetCredDefsResponse" : { + "properties" : { + "credential_definition_ids" : { + "items" : { + "description" : "credential definition identifiers", + "example" : "GvLGiRogTJubmj5B36qhYz:3:CL:8:faber.agent.degree_schema", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, "GetDIDEndpointResponse" : { "properties" : { "endpoint" : { @@ -8256,6 +9432,55 @@ }, "type" : "object" }, + "GetSchemaResult" : { + "properties" : { + "resolution_metadata" : { + "properties" : { }, + "type" : "object" + }, + "schema" : { + "$ref" : "#/components/schemas/AnonCredsSchema" + }, + "schema_id" : { + "description" : "Schema identifier", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "type" : "string" + }, + "schema_metadata" : { + "properties" : { }, + "type" : "object" + } + }, + "type" : "object" + }, + "GetSchemasResponse" : { + "properties" : { + "schema_ids" : { + "items" : { + "description" : "Schema identifiers", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "Hangup" : { + "properties" : { + "@id" : { + "description" : "Message identifier", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type" : "string" + }, + "@type" : { + "description" : "Message type", + "example" : "https://didcomm.org/my-family/1.0/my-message-type", + "type" : "string" + } + }, + "type" : "object" + }, "HolderModuleResponse" : { "type" : "object" }, @@ -8668,7 +9893,7 @@ "properties" : { "@type" : { "description" : "Message type identifier", - "example" : "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/presentation-preview", + "example" : "https://didcomm.org/present-proof/1.0/presentation-preview", "type" : "string" }, "attributes" : { @@ -9245,6 +10470,53 @@ }, "type" : "object" }, + "InnerCredDef" : { + "properties" : { + "issuerId" : { + "description" : "Issuer Identifier of the credential definition", + "example" : "WgWxqztrNooG92RXvxSTWv", + "type" : "string" + }, + "schemaId" : { + "description" : "Schema identifier", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "type" : "string" + }, + "tag" : { + "description" : "Credential definition tag", + "example" : "default", + "type" : "string" + } + }, + "required" : [ "issuerId", "schemaId", "tag" ], + "type" : "object" + }, + "InnerRevRegDef" : { + "properties" : { + "credDefId" : { + "description" : "Credential definition identifier", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "type" : "string" + }, + "issuerId" : { + "description" : "Issuer Identifier of the credential definition or schema", + "example" : "WgWxqztrNooG92RXvxSTWv", + "type" : "string" + }, + "maxCredNum" : { + "description" : "Maximum number of credential revocations per registry", + "example" : 777, + "format" : "int32", + "type" : "integer" + }, + "tag" : { + "description" : "tag for revocation registry", + "example" : "default", + "type" : "string" + } + }, + "type" : "object" + }, "InputDescriptors" : { "properties" : { "constraints" : { @@ -9318,7 +10590,7 @@ "handshake_protocols" : { "items" : { "description" : "Handshake protocol to specify in invitation", - "example" : "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/1.0", + "example" : "https://didcomm.org/didexchange/1.0", "type" : "string" }, "type" : "array" @@ -9344,6 +10616,17 @@ "example" : "1.1", "type" : "string" }, + "use_did" : { + "description" : "DID to use in invitation", + "example" : "did:example:123", + "type" : "string" + }, + "use_did_method" : { + "description" : "DID method to use in invitation", + "enum" : [ "did:peer:2", "did:peer:4" ], + "example" : "did:peer:2", + "type" : "string" + }, "use_public_did" : { "description" : "Whether to use public DID in invitation", "example" : false, @@ -9385,7 +10668,7 @@ "handshake_protocols" : { "items" : { "description" : "Handshake protocol", - "example" : "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/1.0", + "example" : "https://didcomm.org/didexchange/1.0", "type" : "string" }, "type" : "array" @@ -9498,27 +10781,6 @@ "required" : [ "connection_id", "invitation", "invitation_url" ], "type" : "object" }, - "IssuanceOptions" : { - "properties" : { - "challenge" : { - "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "type" : "string" - }, - "created" : { - "example" : "2010-01-01T19:23:24Z", - "type" : "string" - }, - "domain" : { - "example" : "website.example", - "type" : "string" - }, - "type" : { - "example" : "Ed25519Signature2020", - "type" : "string" - } - }, - "type" : "object" - }, "IssueCredentialModuleResponse" : { "type" : "object" }, @@ -9528,7 +10790,7 @@ "$ref" : "#/components/schemas/Credential" }, "options" : { - "$ref" : "#/components/schemas/IssuanceOptions" + "$ref" : "#/components/schemas/LDProofVCOptions" } }, "type" : "object" @@ -9595,6 +10857,54 @@ }, "type" : "object" }, + "IssuerCredRevRecordSchemaAnoncreds" : { + "properties" : { + "created_at" : { + "description" : "Time of record creation", + "example" : "2021-12-31T23:59:59Z", + "pattern" : "^\\d{4}-\\d\\d-\\d\\d[T ]\\d\\d:\\d\\d(?:\\:(?:\\d\\d(?:\\.\\d{1,6})?))?(?:[+-]\\d\\d:?\\d\\d|Z|)$", + "type" : "string" + }, + "cred_def_id" : { + "description" : "Credential definition identifier", + "type" : "string" + }, + "cred_ex_id" : { + "description" : "Credential exchange record identifier at credential issue", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type" : "string" + }, + "cred_ex_version" : { + "description" : "Credential exchange version", + "type" : "string" + }, + "cred_rev_id" : { + "description" : "Credential revocation identifier", + "type" : "string" + }, + "record_id" : { + "description" : "Issuer credential revocation record identifier", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type" : "string" + }, + "rev_reg_id" : { + "description" : "Revocation registry identifier", + "type" : "string" + }, + "state" : { + "description" : "Issue credential revocation record state", + "example" : "issued", + "type" : "string" + }, + "updated_at" : { + "description" : "Time of last record update", + "example" : "2021-12-31T23:59:59Z", + "pattern" : "^\\d{4}-\\d\\d-\\d\\d[T ]\\d\\d:\\d\\d(?:\\:(?:\\d\\d(?:\\.\\d{1,6})?))?(?:[+-]\\d\\d:?\\d\\d|Z|)$", + "type" : "string" + } + }, + "type" : "object" + }, "IssuerRevRegRecord" : { "properties" : { "created_at" : { @@ -9774,7 +11084,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "filter" : { @@ -9828,7 +11137,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "updates" : { @@ -10031,7 +11339,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" } }, @@ -10047,7 +11354,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "endpoint" : { @@ -10154,7 +11460,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "description" : { @@ -10499,7 +11804,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -10524,7 +11828,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -10621,7 +11924,7 @@ "ProvePresentationRequest" : { "properties" : { "options" : { - "$ref" : "#/components/schemas/IssuanceOptions" + "$ref" : "#/components/schemas/LDProofVCOptions" }, "presentation" : { "$ref" : "#/components/schemas/Presentation" @@ -10638,6 +11941,60 @@ "type" : "object" }, "PublishRevocations" : { + "properties" : { + "options" : { + "$ref" : "#/components/schemas/PublishRevocationsOptions" + }, + "rrid2crid" : { + "additionalProperties" : { + "items" : { + "description" : "Credential revocation identifier", + "example" : "12345", + "pattern" : "^[1-9][0-9]*$", + "type" : "string" + }, + "type" : "array" + }, + "description" : "Credential revocation ids by revocation registry id", + "type" : "object" + } + }, + "type" : "object" + }, + "PublishRevocationsOptions" : { + "properties" : { + "create_transaction_for_endorser" : { + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign.", + "example" : false, + "type" : "boolean" + }, + "endorser_connection_id" : { + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection.", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type" : "string" + } + }, + "type" : "object" + }, + "PublishRevocationsResult" : { + "properties" : { + "rrid2crid" : { + "additionalProperties" : { + "items" : { + "description" : "Credential revocation identifier", + "example" : "12345", + "pattern" : "^[1-9][0-9]*$", + "type" : "string" + }, + "type" : "array" + }, + "description" : "Credential revocation ids by revocation registry id", + "type" : "object" + } + }, + "type" : "object" + }, + "PublishRevocationsSchemaAnoncreds" : { "properties" : { "rrid2crid" : { "additionalProperties" : { @@ -10680,7 +12037,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "queries" : { @@ -10702,7 +12058,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -10756,7 +12111,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "did" : { @@ -10797,55 +12151,259 @@ }, "type" : "array" }, - "serviceEndpoint" : { - "description" : "Service endpoint at which to reach this agent", - "example" : "http://192.168.56.101:8020", + "serviceEndpoint" : { + "description" : "Service endpoint at which to reach this agent", + "example" : "http://192.168.56.101:8020", + "type" : "string" + } + }, + "type" : "object" + }, + "RemoveWalletRequest" : { + "properties" : { + "wallet_key" : { + "description" : "Master key used for key derivation. Only required for unmanaged wallets.", + "example" : "MySecretKey123", + "type" : "string" + } + }, + "type" : "object" + }, + "ResolutionResult" : { + "properties" : { + "did_document" : { + "description" : "DID Document", + "properties" : { }, + "type" : "object" + }, + "metadata" : { + "description" : "Resolution metadata", + "properties" : { }, + "type" : "object" + } + }, + "required" : [ "did_document", "metadata" ], + "type" : "object" + }, + "RevList" : { + "properties" : { + "currentAccumulator" : { + "description" : "The current accumalator value", + "example" : "21 118...1FB", + "type" : "string" + }, + "issuerId" : { + "description" : "Issuer Identifier of the credential definition or schema", + "example" : "WgWxqztrNooG92RXvxSTWv", + "type" : "string" + }, + "revRegDefId" : { + "description" : "The ID of the revocation registry definition", + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "type" : "string" + }, + "revocationList" : { + "description" : "Bit list representing revoked credentials", + "example" : [ 0, 1, 1, 0 ], + "items" : { + "format" : "int32", + "type" : "integer" + }, + "type" : "array" + }, + "timestamp" : { + "description" : "Timestamp at which revocation list is applicable", + "format" : "int32", + "type" : "integer" + } + }, + "type" : "object" + }, + "RevListCreateRequest" : { + "properties" : { + "options" : { + "$ref" : "#/components/schemas/RevListOptions" + }, + "rev_reg_def_id" : { + "description" : "Revocation registry definition identifier", + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "type" : "string" + } + }, + "type" : "object" + }, + "RevListOptions" : { + "properties" : { + "create_transaction_for_endorser" : { + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign.", + "example" : false, + "type" : "boolean" + }, + "endorser_connection_id" : { + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection.", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type" : "string" + } + }, + "type" : "object" + }, + "RevListResult" : { + "properties" : { + "job_id" : { + "type" : "string" + }, + "registration_metadata" : { + "properties" : { }, + "type" : "object" + }, + "revocation_list_metadata" : { + "properties" : { }, + "type" : "object" + }, + "revocation_list_state" : { + "$ref" : "#/components/schemas/RevListState" + } + }, + "type" : "object" + }, + "RevListState" : { + "properties" : { + "revocation_list" : { + "$ref" : "#/components/schemas/RevListState_revocation_list" + }, + "state" : { + "enum" : [ "finished", "failed", "action", "wait" ], + "type" : "string" + } + }, + "type" : "object" + }, + "RevRegCreateRequest" : { + "properties" : { + "credential_definition_id" : { + "description" : "Credential definition identifier", + "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$", + "type" : "string" + }, + "max_cred_num" : { + "description" : "Revocation registry size", + "example" : 1000, + "format" : "int32", + "maximum" : 32768, + "minimum" : 4, + "type" : "integer" + } + }, + "type" : "object" + }, + "RevRegCreateRequestSchemaAnoncreds" : { + "properties" : { + "options" : { + "$ref" : "#/components/schemas/RevRegDefOptions" + }, + "revocation_registry_definition" : { + "$ref" : "#/components/schemas/InnerRevRegDef" + } + }, + "type" : "object" + }, + "RevRegDef" : { + "properties" : { + "credDefId" : { + "description" : "Credential definition identifier", + "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "type" : "string" + }, + "issuerId" : { + "description" : "Issuer Identifier of the credential definition or schema", + "example" : "WgWxqztrNooG92RXvxSTWv", "type" : "string" + }, + "revocDefType" : { + "type" : "string" + }, + "tag" : { + "description" : "tag for the revocation registry definition", + "example" : "default", + "type" : "string" + }, + "value" : { + "$ref" : "#/components/schemas/RevRegDefValue" } }, "type" : "object" }, - "RemoveWalletRequest" : { + "RevRegDefOptions" : { "properties" : { - "wallet_key" : { - "description" : "Master key used for key derivation. Only required for unmanaged wallets.", - "example" : "MySecretKey123", + "create_transaction_for_endorser" : { + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign.", + "example" : false, + "type" : "boolean" + }, + "endorser_connection_id" : { + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection.", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", "type" : "string" } }, "type" : "object" }, - "ResolutionResult" : { + "RevRegDefResult" : { "properties" : { - "did_document" : { - "description" : "DID Document", + "job_id" : { + "type" : "string" + }, + "registration_metadata" : { "properties" : { }, "type" : "object" }, - "metadata" : { - "description" : "Resolution metadata", + "revocation_registry_definition_metadata" : { "properties" : { }, "type" : "object" + }, + "revocation_registry_definition_state" : { + "$ref" : "#/components/schemas/RevRegDefState" } }, - "required" : [ "did_document", "metadata" ], "type" : "object" }, - "RevRegCreateRequest" : { + "RevRegDefState" : { "properties" : { - "credential_definition_id" : { - "description" : "Credential definition identifier", - "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", - "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$", + "revocation_registry_definition" : { + "$ref" : "#/components/schemas/RevRegDefState_revocation_registry_definition" + }, + "revocation_registry_definition_id" : { + "description" : "revocation registry definition id", + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", "type" : "string" }, - "max_cred_num" : { - "description" : "Revocation registry size", - "example" : 1000, + "state" : { + "enum" : [ "finished", "failed", "action", "wait", "decommissioned", "full" ], + "type" : "string" + } + }, + "type" : "object" + }, + "RevRegDefValue" : { + "properties" : { + "maxCredNum" : { + "example" : 777, "format" : "int32", - "maximum" : 32768, - "minimum" : 4, "type" : "integer" + }, + "publicKeys" : { + "example" : "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", + "properties" : { }, + "type" : "object" + }, + "tailsHash" : { + "example" : "7Qen9RDyemMuV7xGQvp7NjwMSpyHieJyBakycxN7dX7P", + "type" : "string" + }, + "tailsLocation" : { + "example" : "https://tails-server.com/hash/7Qen9RDyemMuV7xGQvp7NjwMSpyHieJyBakycxN7dX7P", + "type" : "string" } }, "type" : "object" @@ -10862,6 +12420,18 @@ }, "type" : "object" }, + "RevRegIssuedResultSchemaAnoncreds" : { + "properties" : { + "result" : { + "description" : "Number of credentials issued against revocation registry", + "example" : 0, + "format" : "int32", + "minimum" : 0, + "type" : "integer" + } + }, + "type" : "object" + }, "RevRegResult" : { "properties" : { "result" : { @@ -10870,6 +12440,14 @@ }, "type" : "object" }, + "RevRegResultSchemaAnoncreds" : { + "properties" : { + "result" : { + "$ref" : "#/components/schemas/IssuerRevRegRecord" + } + }, + "type" : "object" + }, "RevRegUpdateTailsFileUri" : { "properties" : { "tails_public_uri" : { @@ -10902,6 +12480,26 @@ }, "type" : "object" }, + "RevRegWalletUpdatedResultSchemaAnoncreds" : { + "properties" : { + "accum_calculated" : { + "description" : "Calculated accumulator for phantom revocations", + "properties" : { }, + "type" : "object" + }, + "accum_fixed" : { + "description" : "Applied ledger transaction to fix revocations", + "properties" : { }, + "type" : "object" + }, + "rev_reg_delta" : { + "description" : "Indy revocation registry delta", + "properties" : { }, + "type" : "object" + } + }, + "type" : "object" + }, "RevRegsCreated" : { "properties" : { "rev_reg_ids" : { @@ -10916,6 +12514,23 @@ }, "type" : "object" }, + "RevRegsCreatedSchemaAnoncreds" : { + "properties" : { + "rev_reg_ids" : { + "items" : { + "description" : "Revocation registry identifiers", + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "RevocationAnoncredsModuleResponse" : { + "type" : "object" + }, "RevocationModuleResponse" : { "type" : "object" }, @@ -10969,6 +12584,77 @@ }, "type" : "object" }, + "RevokeRequestSchemaAnoncreds" : { + "properties" : { + "comment" : { + "description" : "Optional comment to include in revocation notification", + "type" : "string" + }, + "connection_id" : { + "description" : "Connection ID to which the revocation notification will be sent; required if notify is true", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type" : "string" + }, + "cred_ex_id" : { + "description" : "Credential exchange identifier", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}", + "type" : "string" + }, + "cred_rev_id" : { + "description" : "Credential revocation identifier", + "example" : "12345", + "pattern" : "^[1-9][0-9]*$", + "type" : "string" + }, + "notify" : { + "description" : "Send a notification to the credential recipient", + "type" : "boolean" + }, + "notify_version" : { + "description" : "Specify which version of the revocation notification should be sent", + "enum" : [ "v1_0", "v2_0" ], + "type" : "string" + }, + "publish" : { + "description" : "(True) publish revocation to ledger immediately, or (default, False) mark it pending", + "type" : "boolean" + }, + "rev_reg_id" : { + "description" : "Revocation registry identifier", + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)", + "type" : "string" + }, + "thread_id" : { + "description" : "Thread ID of the credential exchange message thread resulting in the credential now being revoked; required if notify is true", + "type" : "string" + } + }, + "type" : "object" + }, + "Rotate" : { + "properties" : { + "@id" : { + "description" : "Message identifier", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type" : "string" + }, + "@type" : { + "description" : "Message type", + "example" : "https://didcomm.org/my-family/1.0/my-message-type", + "type" : "string" + }, + "to_did" : { + "description" : "The DID the rotating party is rotating to", + "example" : "did:example:newdid", + "type" : "string" + } + }, + "required" : [ "to_did" ], + "type" : "object" + }, "RouteRecord" : { "properties" : { "connection_id" : { @@ -11156,6 +12842,51 @@ }, "type" : "object" }, + "SchemaPostOption" : { + "properties" : { + "create_transaction_for_endorser" : { + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign.", + "example" : false, + "type" : "boolean" + }, + "endorser_connection_id" : { + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection.", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "type" : "string" + } + }, + "type" : "object" + }, + "SchemaPostRequest" : { + "properties" : { + "options" : { + "$ref" : "#/components/schemas/SchemaPostOption" + }, + "schema" : { + "$ref" : "#/components/schemas/AnonCredsSchema" + } + }, + "type" : "object" + }, + "SchemaResult" : { + "properties" : { + "job_id" : { + "type" : "string" + }, + "registration_metadata" : { + "properties" : { }, + "type" : "object" + }, + "schema_metadata" : { + "properties" : { }, + "type" : "object" + }, + "schema_state" : { + "$ref" : "#/components/schemas/SchemaState" + } + }, + "type" : "object" + }, "SchemaSendRequest" : { "properties" : { "attributes" : { @@ -11197,6 +12928,23 @@ "required" : [ "schema_id" ], "type" : "object" }, + "SchemaState" : { + "properties" : { + "schema" : { + "$ref" : "#/components/schemas/AnonCredsSchema" + }, + "schema_id" : { + "description" : "Schema identifier", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "type" : "string" + }, + "state" : { + "enum" : [ "finished", "failed", "action", "wait" ], + "type" : "string" + } + }, + "type" : "object" + }, "SchemasCreatedResult" : { "properties" : { "schema_ids" : { @@ -11625,7 +13373,7 @@ "TxnOrPublishRevocationsResult" : { "properties" : { "sent" : { - "$ref" : "#/components/schemas/PublishRevocations" + "$ref" : "#/components/schemas/PublishRevocationsSchemaAnoncreds" }, "txn" : { "$ref" : "#/components/schemas/TxnOrPublishRevocationsResult_txn" @@ -12872,7 +14620,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -12932,7 +14679,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -13068,7 +14814,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -13107,7 +14852,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -13300,7 +15044,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -13513,7 +15256,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -13590,7 +15332,6 @@ "@type" : { "description" : "Message type", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "readOnly" : true, "type" : "string" }, "comment" : { @@ -14092,6 +15833,13 @@ "description" : "Detached Java Web Signature", "type" : "object" }, + "CredDefState_credential_definition" : { + "allOf" : [ { + "$ref" : "#/components/schemas/CredDef" + } ], + "description" : "credential definition", + "type" : "object" + }, "CredDefValue_primary" : { "allOf" : [ { "$ref" : "#/components/schemas/CredDefValuePrimary" @@ -14106,6 +15854,20 @@ "description" : "Revocation value for credential definition", "type" : "object" }, + "CredDefValueSchemaAnoncreds_primary" : { + "allOf" : [ { + "$ref" : "#/components/schemas/CredDefValuePrimarySchemaAnoncreds" + } ], + "description" : "Primary value for credential definition", + "type" : "object" + }, + "CredDefValueSchemaAnoncreds_revocation" : { + "allOf" : [ { + "$ref" : "#/components/schemas/CredDefValueRevocationSchemaAnoncreds" + } ], + "description" : "Revocation value for credential definition", + "type" : "object" + }, "Credential_proof" : { "allOf" : [ { "$ref" : "#/components/schemas/LinkedDataProof" @@ -14356,6 +16118,20 @@ }, "type" : "object" }, + "RevListState_revocation_list" : { + "allOf" : [ { + "$ref" : "#/components/schemas/RevList" + } ], + "description" : "revocation list", + "type" : "object" + }, + "RevRegDefState_revocation_registry_definition" : { + "allOf" : [ { + "$ref" : "#/components/schemas/RevRegDef" + } ], + "description" : "revocation registry definition", + "type" : "object" + }, "SchemaSendResult_schema" : { "allOf" : [ { "$ref" : "#/components/schemas/Schema" diff --git a/open-api/swagger.json b/open-api/swagger.json index 6e07a870f8..e3560b1712 100644 --- a/open-api/swagger.json +++ b/open-api/swagger.json @@ -1,12 +1,33 @@ { "swagger" : "2.0", "info" : { - "version" : "v0.12.0rc2", + "version" : "v0.12.0rc3", "title" : "Aries Cloud Agent" }, "tags" : [ { "name" : "action-menu", "description" : "Menu interaction over connection" + }, { + "name" : "anoncreds - credential definitions", + "description" : "Anoncreds credential definition management", + "externalDocs" : { + "description" : "Specification", + "url" : "https://hyperledger.github.io/anoncreds-spec" + } + }, { + "name" : "anoncreds - revocation", + "description" : "Revocation registry management", + "externalDocs" : { + "description" : "Overview", + "url" : "https://github.com/hyperledger/indy-hipe/tree/master/text/0011-cred-revocation" + } + }, { + "name" : "anoncreds - schemas", + "description" : "Anoncreds schema management", + "externalDocs" : { + "description" : "Specification", + "url" : "https://hyperledger.github.io/anoncreds-spec" + } }, { "name" : "basicmessage", "description" : "Simple messaging", @@ -42,6 +63,13 @@ "description" : "Specification", "url" : "https://github.com/hyperledger/aries-rfcs/tree/25464a5c8f8a17b14edaa4310393df6094ace7b0/features/0023-did-exchange" } + }, { + "name" : "did-rotate", + "description" : "Rorate a DID", + "externalDocs" : { + "description" : "Specification", + "url" : "https://github.com/hyperledger/aries-rfcs/tree/main/features/0794-did-rotate" + } }, { "name" : "discover-features", "description" : "Feature discovery", @@ -195,64 +223,648 @@ }, "/action-menu/{conn_id}/fetch" : { "post" : { - "tags" : [ "action-menu" ], - "summary" : "Fetch the active menu", + "tags" : [ "action-menu" ], + "summary" : "Fetch the active menu", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "conn_id", + "in" : "path", + "description" : "Connection identifier", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/ActionMenuFetchResult" + } + } + } + } + }, + "/action-menu/{conn_id}/perform" : { + "post" : { + "tags" : [ "action-menu" ], + "summary" : "Perform an action associated with the active menu", + "produces" : [ "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "required" : false, + "schema" : { + "$ref" : "#/definitions/PerformRequest" + } + }, { + "name" : "conn_id", + "in" : "path", + "description" : "Connection identifier", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/ActionMenuModulesResult" + } + } + } + } + }, + "/action-menu/{conn_id}/request" : { + "post" : { + "tags" : [ "action-menu" ], + "summary" : "Request the active menu", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "conn_id", + "in" : "path", + "description" : "Connection identifier", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/ActionMenuModulesResult" + } + } + } + } + }, + "/action-menu/{conn_id}/send-menu" : { + "post" : { + "tags" : [ "action-menu" ], + "summary" : "Send an action menu to a connection", + "produces" : [ "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "required" : false, + "schema" : { + "$ref" : "#/definitions/SendMenu" + } + }, { + "name" : "conn_id", + "in" : "path", + "description" : "Connection identifier", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/ActionMenuModulesResult" + } + } + } + } + }, + "/anoncreds/credential-definition" : { + "post" : { + "tags" : [ "anoncreds - credential definitions" ], + "summary" : "Create a credential definition on the connected ledger", + "produces" : [ "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "required" : false, + "schema" : { + "$ref" : "#/definitions/CredDefPostRequest" + } + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/CredDefResult" + } + } + } + } + }, + "/anoncreds/credential-definition/{cred_def_id}" : { + "get" : { + "tags" : [ "anoncreds - credential definitions" ], + "summary" : "Retrieve an individual credential definition details", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "cred_def_id", + "in" : "path", + "description" : "Credential definition identifier", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/GetCredDefResult" + } + } + } + } + }, + "/anoncreds/credential-definitions" : { + "get" : { + "tags" : [ "anoncreds - credential definitions" ], + "summary" : "Retrieve all credential definition ids", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "issuer_id", + "in" : "query", + "description" : "Issuer Identifier of the credential definition", + "required" : false, + "type" : "string" + }, { + "name" : "schema_id", + "in" : "query", + "description" : "Schema identifier", + "required" : false, + "type" : "string" + }, { + "name" : "schema_name", + "in" : "query", + "description" : "Schema name", + "required" : false, + "type" : "string" + }, { + "name" : "schema_version", + "in" : "query", + "description" : "Schema version", + "required" : false, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/GetCredDefsResponse" + } + } + } + } + }, + "/anoncreds/registry/{rev_reg_id}/active" : { + "put" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Update the active registry", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "rev_reg_id", + "in" : "path", + "description" : "Revocation Registry identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevocationModuleResponse" + } + } + } + } + }, + "/anoncreds/registry/{rev_reg_id}/tails-file" : { + "put" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Upload local tails file to server", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "rev_reg_id", + "in" : "path", + "description" : "Revocation Registry identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevocationModuleResponse" + } + } + } + } + }, + "/anoncreds/revocation-list" : { + "post" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Create and publish a revocation status list on the connected ledger", + "produces" : [ "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "required" : false, + "schema" : { + "$ref" : "#/definitions/RevListCreateRequest" + } + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevListResult" + } + } + } + } + }, + "/anoncreds/revocation-registry-definition" : { + "post" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Create and publish a registration revocation on the connected ledger", + "produces" : [ "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "required" : false, + "schema" : { + "$ref" : "#/definitions/RevRegCreateRequestSchemaAnoncreds" + } + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevRegDefResult" + } + } + } + } + }, + "/anoncreds/revocation/active-registry/{cred_def_id}" : { + "get" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Get current active revocation registry by credential definition id", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "cred_def_id", + "in" : "path", + "description" : "Credential definition identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevRegResultSchemaAnoncreds" + } + } + } + } + }, + "/anoncreds/revocation/active-registry/{cred_def_id}/rotate" : { + "post" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Rotate revocation registry", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "cred_def_id", + "in" : "path", + "description" : "Credential definition identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevRegsCreatedSchemaAnoncreds" + } + } + } + } + }, + "/anoncreds/revocation/credential-record" : { + "get" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Get credential revocation status", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "cred_ex_id", + "in" : "query", + "description" : "Credential exchange identifier", + "required" : false, + "type" : "string", + "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" + }, { + "name" : "cred_rev_id", + "in" : "query", + "description" : "Credential revocation identifier", + "required" : false, + "type" : "string", + "pattern" : "^[1-9][0-9]*$" + }, { + "name" : "rev_reg_id", + "in" : "query", + "description" : "Revocation registry identifier", + "required" : false, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/CredRevRecordResult" + } + } + } + } + }, + "/anoncreds/revocation/publish-revocations" : { + "post" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Publish pending revocations to ledger", + "produces" : [ "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "required" : false, + "schema" : { + "$ref" : "#/definitions/PublishRevocations" + } + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/PublishRevocationsResult" + } + } + } + } + }, + "/anoncreds/revocation/registries" : { + "get" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Search for matching revocation registries that current agent created", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "cred_def_id", + "in" : "query", + "description" : "Credential definition identifier", + "required" : false, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$" + }, { + "name" : "state", + "in" : "query", + "description" : "Revocation registry state", + "required" : false, + "type" : "string", + "enum" : [ "finished", "failed", "action", "wait", "decommissioned", "full" ] + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevRegsCreatedSchemaAnoncreds" + } + } + } + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}" : { + "get" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Get revocation registry by revocation registry id", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "rev_reg_id", + "in" : "path", + "description" : "Revocation Registry identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevRegResultSchemaAnoncreds" + } + } + } + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/fix-revocation-entry-state" : { + "put" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Fix revocation state in wallet and return number of updated entries", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "rev_reg_id", + "in" : "path", + "description" : "Revocation Registry identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + }, { + "name" : "apply_ledger_update", + "in" : "query", + "description" : "Apply updated accumulator transaction to ledger", + "required" : true, + "type" : "boolean" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevRegWalletUpdatedResultSchemaAnoncreds" + } + } + } + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/issued" : { + "get" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Get number of credentials issued against revocation registry", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "rev_reg_id", + "in" : "path", + "description" : "Revocation Registry identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevRegIssuedResultSchemaAnoncreds" + } + } + } + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/issued/details" : { + "get" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Get details of credentials issued against revocation registry", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "rev_reg_id", + "in" : "path", + "description" : "Revocation Registry identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/CredRevRecordDetailsResultSchemaAnoncreds" + } + } + } + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/issued/indy_recs" : { + "get" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Get details of revoked credentials from ledger", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "rev_reg_id", + "in" : "path", + "description" : "Revocation Registry identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/CredRevIndyRecordsResultSchemaAnoncreds" + } + } + } + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/set-state" : { + "patch" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Set revocation registry state manually", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "rev_reg_id", + "in" : "path", + "description" : "Revocation Registry identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + }, { + "name" : "state", + "in" : "query", + "description" : "Revocation registry state to set", + "required" : true, + "type" : "string", + "enum" : [ "finished", "failed", "action", "wait", "decommissioned", "full" ] + } ], + "responses" : { + "200" : { + "description" : "", + "schema" : { + "$ref" : "#/definitions/RevRegResultSchemaAnoncreds" + } + } + } + } + }, + "/anoncreds/revocation/registry/{rev_reg_id}/tails-file" : { + "get" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Download tails file", + "produces" : [ "application/octet-stream" ], + "parameters" : [ { + "name" : "rev_reg_id", + "in" : "path", + "description" : "Revocation Registry identifier", + "required" : true, + "type" : "string", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + } ], + "responses" : { + "200" : { + "description" : "tails file", + "schema" : { + "$ref" : "#/definitions/RevocationAnoncredsModuleResponse" + } + } + } + } + }, + "/anoncreds/revocation/revoke" : { + "post" : { + "tags" : [ "anoncreds - revocation" ], + "summary" : "Revoke an issued credential", "produces" : [ "application/json" ], "parameters" : [ { - "name" : "conn_id", - "in" : "path", - "description" : "Connection identifier", - "required" : true, - "type" : "string" + "in" : "body", + "name" : "body", + "required" : false, + "schema" : { + "$ref" : "#/definitions/RevokeRequestSchemaAnoncreds" + } } ], "responses" : { "200" : { "description" : "", "schema" : { - "$ref" : "#/definitions/ActionMenuFetchResult" + "$ref" : "#/definitions/RevocationAnoncredsModuleResponse" } } } } }, - "/action-menu/{conn_id}/perform" : { + "/anoncreds/schema" : { "post" : { - "tags" : [ "action-menu" ], - "summary" : "Perform an action associated with the active menu", + "tags" : [ "anoncreds - schemas" ], + "summary" : "Create a schema on the connected ledger", "produces" : [ "application/json" ], "parameters" : [ { "in" : "body", "name" : "body", "required" : false, "schema" : { - "$ref" : "#/definitions/PerformRequest" + "$ref" : "#/definitions/SchemaPostRequest" } - }, { - "name" : "conn_id", - "in" : "path", - "description" : "Connection identifier", - "required" : true, - "type" : "string" } ], "responses" : { "200" : { "description" : "", "schema" : { - "$ref" : "#/definitions/ActionMenuModulesResult" + "$ref" : "#/definitions/SchemaResult" } } } } }, - "/action-menu/{conn_id}/request" : { - "post" : { - "tags" : [ "action-menu" ], - "summary" : "Request the active menu", + "/anoncreds/schema/{schema_id}" : { + "get" : { + "tags" : [ "anoncreds - schemas" ], + "summary" : "Retrieve an individual schemas details", "produces" : [ "application/json" ], "parameters" : [ { - "name" : "conn_id", + "name" : "schema_id", "in" : "path", - "description" : "Connection identifier", + "description" : "Schema identifier", "required" : true, "type" : "string" } ], @@ -260,36 +872,41 @@ "200" : { "description" : "", "schema" : { - "$ref" : "#/definitions/ActionMenuModulesResult" + "$ref" : "#/definitions/GetSchemaResult" } } } } }, - "/action-menu/{conn_id}/send-menu" : { - "post" : { - "tags" : [ "action-menu" ], - "summary" : "Send an action menu to a connection", + "/anoncreds/schemas" : { + "get" : { + "tags" : [ "anoncreds - schemas" ], + "summary" : "Retrieve all schema ids", "produces" : [ "application/json" ], "parameters" : [ { - "in" : "body", - "name" : "body", + "name" : "schema_issuer_id", + "in" : "query", + "description" : "Schema issuer identifier", "required" : false, - "schema" : { - "$ref" : "#/definitions/SendMenu" - } + "type" : "string" }, { - "name" : "conn_id", - "in" : "path", - "description" : "Connection identifier", - "required" : true, + "name" : "schema_name", + "in" : "query", + "description" : "Schema name", + "required" : false, + "type" : "string" + }, { + "name" : "schema_version", + "in" : "query", + "description" : "Schema version", + "required" : false, "type" : "string" } ], "responses" : { "200" : { "description" : "", "schema" : { - "$ref" : "#/definitions/ActionMenuModulesResult" + "$ref" : "#/definitions/GetSchemasResponse" } } } @@ -312,7 +929,7 @@ "description" : "Connection protocol used", "required" : false, "type" : "string", - "enum" : [ "connections/1.0", "didexchange/1.0" ] + "enum" : [ "connections/1.0", "didexchange/1.0", "didexchange/1.1" ] }, { "name" : "invitation_key", "in" : "query", @@ -339,7 +956,7 @@ "description" : "Connection state", "required" : false, "type" : "string", - "enum" : [ "abandoned", "invitation", "response", "active", "start", "request", "error", "init", "completed" ] + "enum" : [ "response", "active", "request", "init", "error", "invitation", "completed", "start", "abandoned" ] }, { "name" : "their_did", "in" : "query", @@ -409,6 +1026,7 @@ "required" : false, "type" : "boolean" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -474,6 +1092,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -558,6 +1177,7 @@ "required" : false, "type" : "string" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -587,6 +1207,7 @@ "type" : "string", "pattern" : "^[A-Za-z0-9\\.\\-\\+]+://([A-Za-z0-9][.A-Za-z0-9-_]+[A-Za-z0-9])+(:[1-9][0-9]*)?(/[^?&#]+)?$" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -1127,6 +1748,57 @@ } } }, + "/did-rotate/{conn_id}/hangup" : { + "post" : { + "tags" : [ "did-rotate" ], + "summary" : "Send hangup of DID rotation as a rotator", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "conn_id", + "in" : "path", + "description" : "Connection identifier", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "Hangup agent message for observer", + "schema" : { + "$ref" : "#/definitions/Hangup" + } + } + } + } + }, + "/did-rotate/{conn_id}/rotate" : { + "post" : { + "tags" : [ "did-rotate" ], + "summary" : "Begin rotation of a DID as a rotator", + "produces" : [ "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "body", + "required" : false, + "schema" : { + "$ref" : "#/definitions/DIDRotateRequestJSON" + } + }, { + "name" : "conn_id", + "in" : "path", + "description" : "Connection identifier", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "Rotate agent message for observer", + "schema" : { + "$ref" : "#/definitions/Rotate" + } + } + } + } + }, "/didexchange/create-request" : { "post" : { "tags" : [ "did-exchange" ], @@ -1183,6 +1855,26 @@ "description" : "Label for connection request", "required" : false, "type" : "string" + }, { + "name" : "protocol", + "in" : "query", + "description" : "Which DID Exchange Protocol version to use", + "required" : false, + "type" : "string", + "enum" : [ "didexchange/1.0", "didexchange/1.1" ] + }, { + "name" : "use_did", + "in" : "query", + "description" : "The DID to use to for this connection", + "required" : false, + "type" : "string" + }, { + "name" : "use_did_method", + "in" : "query", + "description" : "The DID method to use to generate a DID for this connection", + "required" : false, + "type" : "string", + "enum" : [ "did:peer:2", "did:peer:4" ] }, { "name" : "use_public_did", "in" : "query", @@ -1239,6 +1931,7 @@ "type" : "string", "pattern" : "^[A-Za-z0-9\\.\\-\\+]+://([A-Za-z0-9][.A-Za-z0-9-_]+[A-Za-z0-9])+(:[1-9][0-9]*)?(/[^?&#]+)?$" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -1273,6 +1966,19 @@ "description" : "Label for connection request", "required" : false, "type" : "string" + }, { + "name" : "use_did", + "in" : "query", + "description" : "The DID to use to for this connection", + "required" : false, + "type" : "string" + }, { + "name" : "use_did_method", + "in" : "query", + "description" : "The DID method to use to generate a DID for this connection", + "required" : false, + "type" : "string", + "enum" : [ "did:peer:2", "did:peer:4" ] } ], "responses" : { "200" : { @@ -1854,6 +2560,7 @@ "$ref" : "#/definitions/V10CredentialCreate" } } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -1877,6 +2584,7 @@ "$ref" : "#/definitions/V10CredentialConnFreeOfferRequest" } } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -1919,6 +2627,7 @@ "required" : false, "type" : "string" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -1942,6 +2651,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -1963,6 +2673,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -1993,6 +2704,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -2023,6 +2735,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -2053,6 +2766,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -2083,6 +2797,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -2113,6 +2828,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -2136,6 +2852,7 @@ "$ref" : "#/definitions/V10CredentialProposalRequestMand" } } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -2159,6 +2876,7 @@ "$ref" : "#/definitions/V10CredentialFreeOfferRequest" } } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -2182,6 +2900,7 @@ "$ref" : "#/definitions/V10CredentialProposalRequestOpt" } } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3000,6 +3719,12 @@ "description" : "Auto-accept connection (defaults to configuration)", "required" : false, "type" : "boolean" + }, { + "name" : "create_unique_did", + "in" : "query", + "description" : "Create unique DID for this invitation (default false)", + "required" : false, + "type" : "boolean" }, { "name" : "multi_use", "in" : "query", @@ -3438,6 +4163,7 @@ "$ref" : "#/definitions/V10PresentationCreateRequestRequest" } } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3480,6 +4206,7 @@ "required" : false, "type" : "string" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3503,6 +4230,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3524,6 +4252,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3574,6 +4303,7 @@ "type" : "string", "pattern" : "^[0-9]*$" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3607,6 +4337,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3637,6 +4368,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3667,6 +4399,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3690,6 +4423,7 @@ "type" : "string", "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3713,6 +4447,7 @@ "$ref" : "#/definitions/V10PresentationProposalRequest" } } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3736,6 +4471,7 @@ "$ref" : "#/definitions/V10PresentationSendRequestRequest" } } ], + "deprecated" : true, "responses" : { "200" : { "description" : "", @@ -3832,7 +4568,7 @@ "200" : { "description" : "", "schema" : { - "$ref" : "#/definitions/PublishRevocations" + "$ref" : "#/definitions/PublishRevocationsSchemaAnoncreds" } } } @@ -3892,7 +4628,7 @@ "200" : { "description" : "", "schema" : { - "$ref" : "#/definitions/CredRevRecordResult" + "$ref" : "#/definitions/CredRevRecordResultSchemaAnoncreds" } } } @@ -3908,7 +4644,7 @@ "name" : "body", "required" : false, "schema" : { - "$ref" : "#/definitions/PublishRevocations" + "$ref" : "#/definitions/PublishRevocationsSchemaAnoncreds" } }, { "name" : "conn_id", @@ -4988,7 +5724,7 @@ "description" : "DID method to query for. e.g. sov to only fetch indy/sov DIDs", "required" : false, "type" : "string", - "enum" : [ "key", "sov" ] + "enum" : [ "key", "sov", "did:peer:2", "did:peer:4" ] }, { "name" : "posture", "in" : "query", @@ -5380,6 +6116,35 @@ } } }, + "AnonCredsSchema" : { + "type" : "object", + "properties" : { + "attrNames" : { + "type" : "array", + "description" : "Schema attribute names", + "items" : { + "type" : "string", + "example" : "score", + "description" : "Attribute name" + } + }, + "issuerId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv", + "description" : "Issuer Identifier of the credential definition or schema" + }, + "name" : { + "type" : "string", + "example" : "Example schema", + "description" : "Schema name" + }, + "version" : { + "type" : "string", + "example" : "1.0", + "description" : "Schema version" + } + } + }, "AttachDecorator" : { "type" : "object", "required" : [ "data" ], @@ -5629,7 +6394,7 @@ "type" : "string", "example" : "connections/1.0", "description" : "Connection protocol used", - "enum" : [ "connections/1.0", "didexchange/1.0" ] + "enum" : [ "connections/1.0", "didexchange/1.0", "didexchange/1.1" ] }, "created_at" : { "type" : "string", @@ -5727,8 +6492,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "did" : { "type" : "string", @@ -6026,8 +6790,8 @@ }, "wallet_type" : { "type" : "string", - "example" : "indy", - "description" : "Type of the wallet to create", + "example" : "askar", + "description" : "Type of the wallet to create. Must be same as base wallet.", "enum" : [ "askar", "askar-anoncreds", "in_memory", "indy" ] }, "wallet_webhook_urls" : { @@ -6126,6 +6890,106 @@ } } }, + "CredDef" : { + "type" : "object", + "properties" : { + "issuerId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv", + "description" : "Issuer Identifier of the credential definition or schema" + }, + "schemaId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "description" : "Schema identifier" + }, + "tag" : { + "type" : "string", + "example" : "default", + "description" : "The tag value passed in by the Issuer to\n an AnonCred's Credential Definition create and store implementation." + }, + "type" : { + "type" : "string", + "enum" : [ "CL" ] + }, + "value" : { + "$ref" : "#/definitions/CredDefValueSchemaAnoncreds" + } + } + }, + "CredDefPostOptions" : { + "type" : "object", + "properties" : { + "create_transaction_for_endorser" : { + "type" : "boolean", + "example" : false, + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign." + }, + "endorser_connection_id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection." + }, + "revocation_registry_size" : { + "type" : "integer", + "format" : "int32", + "example" : 1000, + "description" : "Maximum number of credential revocations per registry" + }, + "support_revocation" : { + "type" : "boolean", + "description" : "Support credential revocation" + } + } + }, + "CredDefPostRequest" : { + "type" : "object", + "properties" : { + "credential_definition" : { + "$ref" : "#/definitions/InnerCredDef" + }, + "options" : { + "$ref" : "#/definitions/CredDefPostOptions" + } + } + }, + "CredDefResult" : { + "type" : "object", + "properties" : { + "credential_definition_metadata" : { + "type" : "object", + "properties" : { } + }, + "credential_definition_state" : { + "$ref" : "#/definitions/CredDefState" + }, + "job_id" : { + "type" : "string" + }, + "registration_metadata" : { + "type" : "object", + "properties" : { } + } + } + }, + "CredDefState" : { + "type" : "object", + "properties" : { + "credential_definition" : { + "$ref" : "#/definitions/CredDefState_credential_definition" + }, + "credential_definition_id" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "description" : "credential definition id", + "x-nullable" : true + }, + "state" : { + "type" : "string", + "enum" : [ "finished", "failed", "action", "wait" ] + } + } + }, "CredDefValue" : { "type" : "object", "properties" : { @@ -6165,6 +7029,35 @@ } } }, + "CredDefValuePrimarySchemaAnoncreds" : { + "type" : "object", + "properties" : { + "n" : { + "type" : "string", + "example" : "0", + "pattern" : "^[0-9]*$" + }, + "r" : { + "type" : "object", + "properties" : { } + }, + "rctxt" : { + "type" : "string", + "example" : "0", + "pattern" : "^[0-9]*$" + }, + "s" : { + "type" : "string", + "example" : "0", + "pattern" : "^[0-9]*$" + }, + "z" : { + "type" : "string", + "example" : "0", + "pattern" : "^[0-9]*$" + } + } + }, "CredDefValueRevocation" : { "type" : "object", "properties" : { @@ -6214,6 +7107,66 @@ } } }, + "CredDefValueRevocationSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "g" : { + "type" : "string", + "example" : "1 1F14F&ECB578F 2 095E45DDF417D" + }, + "g_dash" : { + "type" : "string", + "example" : "1 1D64716fCDC00C 1 0C781960FA66E3D3 2 095E45DDF417D" + }, + "h" : { + "type" : "string", + "example" : "1 16675DAE54BFAE8 2 095E45DD417D" + }, + "h0" : { + "type" : "string", + "example" : "1 21E5EF9476EAF18 2 095E45DDF417D" + }, + "h1" : { + "type" : "string", + "example" : "1 236D1D99236090 2 095E45DDF417D" + }, + "h2" : { + "type" : "string", + "example" : "1 1C3AE8D1F1E277 2 095E45DDF417D" + }, + "h_cap" : { + "type" : "string", + "example" : "1 1B2A32CF3167 1 2490FEBF6EE55 1 0000000000000000" + }, + "htilde" : { + "type" : "string", + "example" : "1 1D8549E8C0F8 2 095E45DDF417D" + }, + "pk" : { + "type" : "string", + "example" : "1 142CD5E5A7DC 1 153885BD903312 2 095E45DDF417D" + }, + "u" : { + "type" : "string", + "example" : "1 0C430AAB2B4710 1 1CB3A0932EE7E 1 0000000000000000" + }, + "y" : { + "type" : "string", + "example" : "1 153558BD903312 2 095E45DDF417D 1 0000000000000000" + } + } + }, + "CredDefValueSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "primary" : { + "$ref" : "#/definitions/CredDefValue_primary" + }, + "revocation" : { + "$ref" : "#/definitions/CredDefValue_revocation" + } + } + }, "CredInfoList" : { "type" : "object", "properties" : { @@ -6235,6 +7188,16 @@ } } }, + "CredRevIndyRecordsResultSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "rev_reg_delta" : { + "type" : "object", + "description" : "Indy revocation registry delta", + "properties" : { } + } + } + }, "CredRevRecordDetailsResult" : { "type" : "object", "properties" : { @@ -6246,7 +7209,26 @@ } } }, + "CredRevRecordDetailsResultSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "results" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/IssuerCredRevRecordSchemaAnoncreds" + } + } + } + }, "CredRevRecordResult" : { + "type" : "object", + "properties" : { + "result" : { + "$ref" : "#/definitions/IssuerCredRevRecordSchemaAnoncreds" + } + } + }, + "CredRevRecordResultSchemaAnoncreds" : { "type" : "object", "properties" : { "result" : { @@ -6421,8 +7403,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -6468,8 +7449,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -6536,6 +7516,11 @@ "description" : "Key type associated with the DID", "enum" : [ "ed25519", "bls12381g2" ] }, + "metadata" : { + "type" : "object", + "description" : "Additional metadata associated with the DID", + "properties" : { } + }, "method" : { "type" : "string", "example" : "sov", @@ -6653,6 +7638,17 @@ } } }, + "DIDRotateRequestJSON" : { + "type" : "object", + "required" : [ "to_did" ], + "properties" : { + "to_did" : { + "type" : "string", + "example" : "did:web:example.com", + "description" : "The DID the rotating party is rotating to" + } + } + }, "DIDXRejectRequest" : { "type" : "object", "properties" : { @@ -6675,8 +7671,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "did" : { "type" : "string", @@ -6860,8 +7855,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "protocols" : { "type" : "array", @@ -6884,8 +7878,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "disclosures" : { "type" : "array", @@ -7047,6 +8040,40 @@ } } }, + "GetCredDefResult" : { + "type" : "object", + "properties" : { + "credential_definition" : { + "$ref" : "#/definitions/CredDefState_credential_definition" + }, + "credential_definition_id" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "description" : "credential definition id" + }, + "credential_definitions_metadata" : { + "type" : "object", + "properties" : { } + }, + "resolution_metadata" : { + "type" : "object", + "properties" : { } + } + } + }, + "GetCredDefsResponse" : { + "type" : "object", + "properties" : { + "credential_definition_ids" : { + "type" : "array", + "items" : { + "type" : "string", + "example" : "GvLGiRogTJubmj5B36qhYz:3:CL:8:faber.agent.degree_schema", + "description" : "credential definition identifiers" + } + } + } + }, "GetDIDEndpointResponse" : { "type" : "object", "properties" : { @@ -7082,6 +8109,55 @@ } } }, + "GetSchemaResult" : { + "type" : "object", + "properties" : { + "resolution_metadata" : { + "type" : "object", + "properties" : { } + }, + "schema" : { + "$ref" : "#/definitions/AnonCredsSchema" + }, + "schema_id" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "description" : "Schema identifier" + }, + "schema_metadata" : { + "type" : "object", + "properties" : { } + } + } + }, + "GetSchemasResponse" : { + "type" : "object", + "properties" : { + "schema_ids" : { + "type" : "array", + "items" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "description" : "Schema identifiers" + } + } + } + }, + "Hangup" : { + "type" : "object", + "properties" : { + "@id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "Message identifier" + }, + "@type" : { + "type" : "string", + "example" : "https://didcomm.org/my-family/1.0/my-message-type", + "description" : "Message type" + } + } + }, "HolderModuleResponse" : { "type" : "object" }, @@ -7496,7 +8572,7 @@ "properties" : { "@type" : { "type" : "string", - "example" : "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/presentation-preview", + "example" : "https://didcomm.org/present-proof/1.0/presentation-preview", "description" : "Message type identifier" }, "attributes" : { @@ -8071,6 +9147,53 @@ } } }, + "InnerCredDef" : { + "type" : "object", + "required" : [ "issuerId", "schemaId", "tag" ], + "properties" : { + "issuerId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv", + "description" : "Issuer Identifier of the credential definition" + }, + "schemaId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "description" : "Schema identifier" + }, + "tag" : { + "type" : "string", + "example" : "default", + "description" : "Credential definition tag" + } + } + }, + "InnerRevRegDef" : { + "type" : "object", + "properties" : { + "credDefId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "description" : "Credential definition identifier" + }, + "issuerId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv", + "description" : "Issuer Identifier of the credential definition or schema" + }, + "maxCredNum" : { + "type" : "integer", + "format" : "int32", + "example" : 777, + "description" : "Maximum number of credential revocations per registry" + }, + "tag" : { + "type" : "string", + "example" : "default", + "description" : "tag for revocation registry" + } + } + }, "InputDescriptors" : { "type" : "object", "properties" : { @@ -8146,7 +9269,7 @@ "type" : "array", "items" : { "type" : "string", - "example" : "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/1.0", + "example" : "https://didcomm.org/didexchange/1.0", "description" : "Handshake protocol to specify in invitation" } }, @@ -8171,6 +9294,17 @@ "example" : "1.1", "description" : "OOB protocol version" }, + "use_did" : { + "type" : "string", + "example" : "did:example:123", + "description" : "DID to use in invitation" + }, + "use_did_method" : { + "type" : "string", + "example" : "did:peer:2", + "description" : "DID method to use in invitation", + "enum" : [ "did:peer:2", "did:peer:4" ] + }, "use_public_did" : { "type" : "boolean", "example" : false, @@ -8213,7 +9347,7 @@ "type" : "array", "items" : { "type" : "string", - "example" : "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/1.0", + "example" : "https://didcomm.org/didexchange/1.0", "description" : "Handshake protocol" } }, @@ -8308,39 +9442,18 @@ "type" : "object", "required" : [ "connection_id", "invitation", "invitation_url" ], "properties" : { - "connection_id" : { - "type" : "string", - "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "description" : "Connection identifier" - }, - "invitation" : { - "$ref" : "#/definitions/ConnectionInvitation" - }, - "invitation_url" : { - "type" : "string", - "example" : "http://192.168.56.101:8020/invite?c_i=eyJAdHlwZSI6Li4ufQ==", - "description" : "Invitation URL" - } - } - }, - "IssuanceOptions" : { - "type" : "object", - "properties" : { - "challenge" : { - "type" : "string", - "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6" - }, - "created" : { + "connection_id" : { "type" : "string", - "example" : "2010-01-01T19:23:24Z" + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "Connection identifier" }, - "domain" : { - "type" : "string", - "example" : "website.example" + "invitation" : { + "$ref" : "#/definitions/ConnectionInvitation" }, - "type" : { + "invitation_url" : { "type" : "string", - "example" : "Ed25519Signature2020" + "example" : "http://192.168.56.101:8020/invite?c_i=eyJAdHlwZSI6Li4ufQ==", + "description" : "Invitation URL" } } }, @@ -8354,7 +9467,7 @@ "$ref" : "#/definitions/Credential" }, "options" : { - "$ref" : "#/definitions/IssuanceOptions" + "$ref" : "#/definitions/LDProofVCOptions" } } }, @@ -8420,6 +9533,54 @@ } } }, + "IssuerCredRevRecordSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "created_at" : { + "type" : "string", + "example" : "2021-12-31T23:59:59Z", + "description" : "Time of record creation", + "pattern" : "^\\d{4}-\\d\\d-\\d\\d[T ]\\d\\d:\\d\\d(?:\\:(?:\\d\\d(?:\\.\\d{1,6})?))?(?:[+-]\\d\\d:?\\d\\d|Z|)$" + }, + "cred_def_id" : { + "type" : "string", + "description" : "Credential definition identifier" + }, + "cred_ex_id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "Credential exchange record identifier at credential issue" + }, + "cred_ex_version" : { + "type" : "string", + "description" : "Credential exchange version" + }, + "cred_rev_id" : { + "type" : "string", + "description" : "Credential revocation identifier" + }, + "record_id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "Issuer credential revocation record identifier" + }, + "rev_reg_id" : { + "type" : "string", + "description" : "Revocation registry identifier" + }, + "state" : { + "type" : "string", + "example" : "issued", + "description" : "Issue credential revocation record state" + }, + "updated_at" : { + "type" : "string", + "example" : "2021-12-31T23:59:59Z", + "description" : "Time of last record update", + "pattern" : "^\\d{4}-\\d\\d-\\d\\d[T ]\\d\\d:\\d\\d(?:\\:(?:\\d\\d(?:\\.\\d{1,6})?))?(?:[+-]\\d\\d:?\\d\\d|Z|)$" + } + } + }, "IssuerRevRegRecord" : { "type" : "object", "properties" : { @@ -8600,8 +9761,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "filter" : { "type" : "object", @@ -8654,8 +9814,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "updates" : { "type" : "array", @@ -8857,8 +10016,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" } } }, @@ -8873,8 +10031,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "endpoint" : { "type" : "string", @@ -8981,8 +10138,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "description" : { "type" : "string", @@ -9323,8 +10479,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -9348,8 +10503,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -9444,7 +10598,7 @@ "type" : "object", "properties" : { "options" : { - "$ref" : "#/definitions/IssuanceOptions" + "$ref" : "#/definitions/LDProofVCOptions" }, "presentation" : { "$ref" : "#/definitions/Presentation" @@ -9460,6 +10614,60 @@ } }, "PublishRevocations" : { + "type" : "object", + "properties" : { + "options" : { + "$ref" : "#/definitions/PublishRevocationsOptions" + }, + "rrid2crid" : { + "type" : "object", + "description" : "Credential revocation ids by revocation registry id", + "additionalProperties" : { + "type" : "array", + "items" : { + "type" : "string", + "example" : "12345", + "description" : "Credential revocation identifier", + "pattern" : "^[1-9][0-9]*$" + } + } + } + } + }, + "PublishRevocationsOptions" : { + "type" : "object", + "properties" : { + "create_transaction_for_endorser" : { + "type" : "boolean", + "example" : false, + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign." + }, + "endorser_connection_id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection." + } + } + }, + "PublishRevocationsResult" : { + "type" : "object", + "properties" : { + "rrid2crid" : { + "type" : "object", + "description" : "Credential revocation ids by revocation registry id", + "additionalProperties" : { + "type" : "array", + "items" : { + "type" : "string", + "example" : "12345", + "description" : "Credential revocation identifier", + "pattern" : "^[1-9][0-9]*$" + } + } + } + } + }, + "PublishRevocationsSchemaAnoncreds" : { "type" : "object", "properties" : { "rrid2crid" : { @@ -9503,8 +10711,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "queries" : { "type" : "array", @@ -9526,8 +10733,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -9579,8 +10785,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "did" : { "type" : "string", @@ -9610,65 +10815,270 @@ "pattern" : "^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{43,44}$" } }, - "routingKeys" : { - "type" : "array", - "description" : "List of routing keys", - "items" : { - "type" : "string", - "example" : "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", - "description" : "Routing key", - "pattern" : "^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{43,44}$" - } + "routingKeys" : { + "type" : "array", + "description" : "List of routing keys", + "items" : { + "type" : "string", + "example" : "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", + "description" : "Routing key", + "pattern" : "^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{43,44}$" + } + }, + "serviceEndpoint" : { + "type" : "string", + "example" : "http://192.168.56.101:8020", + "description" : "Service endpoint at which to reach this agent" + } + } + }, + "RemoveWalletRequest" : { + "type" : "object", + "properties" : { + "wallet_key" : { + "type" : "string", + "example" : "MySecretKey123", + "description" : "Master key used for key derivation. Only required for unmanaged wallets." + } + } + }, + "ResolutionResult" : { + "type" : "object", + "required" : [ "did_document", "metadata" ], + "properties" : { + "did_document" : { + "type" : "object", + "description" : "DID Document", + "properties" : { } + }, + "metadata" : { + "type" : "object", + "description" : "Resolution metadata", + "properties" : { } + } + } + }, + "RevList" : { + "type" : "object", + "properties" : { + "currentAccumulator" : { + "type" : "string", + "example" : "21 118...1FB", + "description" : "The current accumalator value" + }, + "issuerId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv", + "description" : "Issuer Identifier of the credential definition or schema" + }, + "revRegDefId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "description" : "The ID of the revocation registry definition" + }, + "revocationList" : { + "type" : "array", + "example" : [ 0, 1, 1, 0 ], + "description" : "Bit list representing revoked credentials", + "items" : { + "type" : "integer", + "format" : "int32" + } + }, + "timestamp" : { + "type" : "integer", + "format" : "int32", + "example" : "2021-12-31T23:59:59Z", + "description" : "Timestamp at which revocation list is applicable" + } + } + }, + "RevListCreateRequest" : { + "type" : "object", + "properties" : { + "options" : { + "$ref" : "#/definitions/RevListOptions" + }, + "rev_reg_def_id" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "description" : "Revocation registry definition identifier" + } + } + }, + "RevListOptions" : { + "type" : "object", + "properties" : { + "create_transaction_for_endorser" : { + "type" : "boolean", + "example" : false, + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign." + }, + "endorser_connection_id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection." + } + } + }, + "RevListResult" : { + "type" : "object", + "properties" : { + "job_id" : { + "type" : "string" + }, + "registration_metadata" : { + "type" : "object", + "properties" : { } + }, + "revocation_list_metadata" : { + "type" : "object", + "properties" : { } + }, + "revocation_list_state" : { + "$ref" : "#/definitions/RevListState" + } + } + }, + "RevListState" : { + "type" : "object", + "properties" : { + "revocation_list" : { + "$ref" : "#/definitions/RevListState_revocation_list" + }, + "state" : { + "type" : "string", + "enum" : [ "finished", "failed", "action", "wait" ] + } + } + }, + "RevRegCreateRequest" : { + "type" : "object", + "properties" : { + "credential_definition_id" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "description" : "Credential definition identifier", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$" + }, + "max_cred_num" : { + "type" : "integer", + "format" : "int32", + "example" : 1000, + "description" : "Revocation registry size", + "minimum" : 4, + "maximum" : 32768 + } + } + }, + "RevRegCreateRequestSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "options" : { + "$ref" : "#/definitions/RevRegDefOptions" + }, + "revocation_registry_definition" : { + "$ref" : "#/definitions/InnerRevRegDef" + } + } + }, + "RevRegDef" : { + "type" : "object", + "properties" : { + "credDefId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "description" : "Credential definition identifier" + }, + "issuerId" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv", + "description" : "Issuer Identifier of the credential definition or schema" }, - "serviceEndpoint" : { + "revocDefType" : { + "type" : "string" + }, + "tag" : { "type" : "string", - "example" : "http://192.168.56.101:8020", - "description" : "Service endpoint at which to reach this agent" + "example" : "default", + "description" : "tag for the revocation registry definition" + }, + "value" : { + "$ref" : "#/definitions/RevRegDefValue" } } }, - "RemoveWalletRequest" : { + "RevRegDefOptions" : { "type" : "object", "properties" : { - "wallet_key" : { + "create_transaction_for_endorser" : { + "type" : "boolean", + "example" : false, + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign." + }, + "endorser_connection_id" : { "type" : "string", - "example" : "MySecretKey123", - "description" : "Master key used for key derivation. Only required for unmanaged wallets." + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection." } } }, - "ResolutionResult" : { + "RevRegDefResult" : { "type" : "object", - "required" : [ "did_document", "metadata" ], "properties" : { - "did_document" : { + "job_id" : { + "type" : "string" + }, + "registration_metadata" : { "type" : "object", - "description" : "DID Document", "properties" : { } }, - "metadata" : { + "revocation_registry_definition_metadata" : { "type" : "object", - "description" : "Resolution metadata", "properties" : { } + }, + "revocation_registry_definition_state" : { + "$ref" : "#/definitions/RevRegDefState" } } }, - "RevRegCreateRequest" : { + "RevRegDefState" : { "type" : "object", "properties" : { - "credential_definition_id" : { + "revocation_registry_definition" : { + "$ref" : "#/definitions/RevRegDefState_revocation_registry_definition" + }, + "revocation_registry_definition_id" : { "type" : "string", - "example" : "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", - "description" : "Credential definition identifier", - "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+)):(.+)?$" + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "description" : "revocation registry definition id" }, - "max_cred_num" : { + "state" : { + "type" : "string", + "enum" : [ "finished", "failed", "action", "wait", "decommissioned", "full" ] + } + } + }, + "RevRegDefValue" : { + "type" : "object", + "properties" : { + "maxCredNum" : { "type" : "integer", "format" : "int32", - "example" : 1000, - "description" : "Revocation registry size", - "minimum" : 4, - "maximum" : 32768 + "example" : 777 + }, + "publicKeys" : { + "type" : "object", + "example" : "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV", + "properties" : { } + }, + "tailsHash" : { + "type" : "string", + "example" : "7Qen9RDyemMuV7xGQvp7NjwMSpyHieJyBakycxN7dX7P" + }, + "tailsLocation" : { + "type" : "string", + "example" : "https://tails-server.com/hash/7Qen9RDyemMuV7xGQvp7NjwMSpyHieJyBakycxN7dX7P" } } }, @@ -9684,6 +11094,18 @@ } } }, + "RevRegIssuedResultSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "result" : { + "type" : "integer", + "format" : "int32", + "example" : 0, + "description" : "Number of credentials issued against revocation registry", + "minimum" : 0 + } + } + }, "RevRegResult" : { "type" : "object", "properties" : { @@ -9692,6 +11114,14 @@ } } }, + "RevRegResultSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "result" : { + "$ref" : "#/definitions/IssuerRevRegRecord" + } + } + }, "RevRegUpdateTailsFileUri" : { "type" : "object", "required" : [ "tails_public_uri" ], @@ -9724,6 +11154,26 @@ } } }, + "RevRegWalletUpdatedResultSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "accum_calculated" : { + "type" : "object", + "description" : "Calculated accumulator for phantom revocations", + "properties" : { } + }, + "accum_fixed" : { + "type" : "object", + "description" : "Applied ledger transaction to fix revocations", + "properties" : { } + }, + "rev_reg_delta" : { + "type" : "object", + "description" : "Indy revocation registry delta", + "properties" : { } + } + } + }, "RevRegsCreated" : { "type" : "object", "properties" : { @@ -9738,6 +11188,23 @@ } } }, + "RevRegsCreatedSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "rev_reg_ids" : { + "type" : "array", + "items" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "description" : "Revocation registry identifiers", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + } + } + } + }, + "RevocationAnoncredsModuleResponse" : { + "type" : "object" + }, "RevocationModuleResponse" : { "type" : "object" }, @@ -9791,6 +11258,77 @@ } } }, + "RevokeRequestSchemaAnoncreds" : { + "type" : "object", + "properties" : { + "comment" : { + "type" : "string", + "description" : "Optional comment to include in revocation notification" + }, + "connection_id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "Connection ID to which the revocation notification will be sent; required if notify is true", + "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" + }, + "cred_ex_id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "Credential exchange identifier", + "pattern" : "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}" + }, + "cred_rev_id" : { + "type" : "string", + "example" : "12345", + "description" : "Credential revocation identifier", + "pattern" : "^[1-9][0-9]*$" + }, + "notify" : { + "type" : "boolean", + "description" : "Send a notification to the credential recipient" + }, + "notify_version" : { + "type" : "string", + "description" : "Specify which version of the revocation notification should be sent", + "enum" : [ "v1_0", "v2_0" ] + }, + "publish" : { + "type" : "boolean", + "description" : "(True) publish revocation to ledger immediately, or (default, False) mark it pending" + }, + "rev_reg_id" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:4:WgWxqztrNooG92RXvxSTWv:3:CL:20:tag:CL_ACCUM:0", + "description" : "Revocation registry identifier", + "pattern" : "^([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):4:([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}):3:CL:(([1-9][0-9]*)|([123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)" + }, + "thread_id" : { + "type" : "string", + "description" : "Thread ID of the credential exchange message thread resulting in the credential now being revoked; required if notify is true" + } + } + }, + "Rotate" : { + "type" : "object", + "required" : [ "to_did" ], + "properties" : { + "@id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "Message identifier" + }, + "@type" : { + "type" : "string", + "example" : "https://didcomm.org/my-family/1.0/my-message-type", + "description" : "Message type" + }, + "to_did" : { + "type" : "string", + "example" : "did:example:newdid", + "description" : "The DID the rotating party is rotating to" + } + } + }, "RouteRecord" : { "type" : "object", "required" : [ "recipient_key" ], @@ -9976,6 +11514,51 @@ } } }, + "SchemaPostOption" : { + "type" : "object", + "properties" : { + "create_transaction_for_endorser" : { + "type" : "boolean", + "example" : false, + "description" : "\n Create transaction for endorser (optional, default false). \n Use this for agents who don't specify an author role but want to \n create a transaction for an endorser to sign." + }, + "endorser_connection_id" : { + "type" : "string", + "example" : "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "description" : "\n Connection identifier (optional) (this is an example)\n You can set this is you know the endorsers connection id you want to use.\n If not specified then the agent will attempt to find an endorser connection." + } + } + }, + "SchemaPostRequest" : { + "type" : "object", + "properties" : { + "options" : { + "$ref" : "#/definitions/SchemaPostOption" + }, + "schema" : { + "$ref" : "#/definitions/AnonCredsSchema" + } + } + }, + "SchemaResult" : { + "type" : "object", + "properties" : { + "job_id" : { + "type" : "string" + }, + "registration_metadata" : { + "type" : "object", + "properties" : { } + }, + "schema_metadata" : { + "type" : "object", + "properties" : { } + }, + "schema_state" : { + "$ref" : "#/definitions/SchemaState" + } + } + }, "SchemaSendRequest" : { "type" : "object", "required" : [ "attributes", "schema_name", "schema_version" ], @@ -10017,6 +11600,23 @@ } } }, + "SchemaState" : { + "type" : "object", + "properties" : { + "schema" : { + "$ref" : "#/definitions/AnonCredsSchema" + }, + "schema_id" : { + "type" : "string", + "example" : "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "description" : "Schema identifier" + }, + "state" : { + "type" : "string", + "enum" : [ "finished", "failed", "action", "wait" ] + } + } + }, "SchemasCreatedResult" : { "type" : "object", "properties" : { @@ -10446,7 +12046,7 @@ "type" : "object", "properties" : { "sent" : { - "$ref" : "#/definitions/PublishRevocations" + "$ref" : "#/definitions/PublishRevocationsSchemaAnoncreds" }, "txn" : { "$ref" : "#/definitions/TxnOrPublishRevocationsResult_txn" @@ -11698,8 +13298,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -11758,8 +13357,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -11894,8 +13492,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -11933,8 +13530,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -12130,8 +13726,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -12343,8 +13938,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -12420,8 +14014,7 @@ "@type" : { "type" : "string", "example" : "https://didcomm.org/my-family/1.0/my-message-type", - "description" : "Message type", - "readOnly" : true + "description" : "Message type" }, "comment" : { "type" : "string", @@ -12906,6 +14499,10 @@ "type" : "object", "description" : "Detached Java Web Signature" }, + "CredDefState_credential_definition" : { + "type" : "object", + "description" : "credential definition" + }, "CredDefValue_primary" : { "type" : "object", "description" : "Primary value for credential definition" @@ -13029,6 +14626,14 @@ "description" : "The proof of the presentation", "example" : "{\"created\":\"2019-12-11T03:50:55\",\"jws\":\"eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0JiNjQiXX0..lKJU0Df_keblRKhZAS9Qq6zybm-HqUXNVZ8vgEPNTAjQKBhQDxvXNo7nvtUBb_Eq1Ch6YBKY5qBQ\",\"proofPurpose\":\"assertionMethod\",\"type\":\"Ed25519Signature2018\",\"verificationMethod\":\"did:key:z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL#z6Mkgg342Ycpuk263R9d8Aq6MUaxPn1DDeHyGo38EefXmgDL\"}" }, + "RevListState_revocation_list" : { + "type" : "object", + "description" : "revocation list" + }, + "RevRegDefState_revocation_registry_definition" : { + "type" : "object", + "description" : "revocation registry definition" + }, "SchemaSendResult_schema" : { "type" : "object", "description" : "Schema definition" diff --git a/pyproject.toml b/pyproject.toml index 3a0333e63f..345da099f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aries_cloudagent" -version = "0.12.0rc2" +version = "0.12.0rc3" description = "Hyperledger Aries Cloud Agent Python (ACA-Py) is a foundation for building decentralized identity applications and services running in non-mobile environments. " authors = ["Hyperledger Aries "] license = "Apache-2.0"