owned this note
owned this note
Published
Linked with GitHub
# Peer DID Method 1 DIDExchange support
## Introduction
Outlines high level changes for implementing Peer DID Method1 [Genesis Doc] support in ACA-Py. More details from the spec can be found [here](https://identity.foundation/peer-did-method-spec/index.html#generation-method):
### AFGO implementation [relevant code]
- [`pkg/vdr/peer`](https://github.com/hyperledger/aries-framework-go/tree/main/pkg/vdr/peer)
- `creator.go`
- `did.go`
- `resolver.go`
- `store.go`
- `vdr.go`
### AFJ implementation [relevant code]
- [`packages/core/src/modules/dids/methods/peer`](https://github.com/hyperledger/aries-framework-javascript/tree/main/packages/core/src/modules/dids/methods/peer)
- [`createPeerDidDocumentFromServices.ts`](https://github.com/hyperledger/aries-framework-javascript/blob/c72ba149bad3a4596f5818b28516f6286b9088bf/packages/core/src/modules/dids/methods/peer/createPeerDidDocumentFromServices.ts#L14) - Create new Peer DIDDoc from services
- `didPeer.ts`
- [`peerDidNumAlgo1Did.ts`](https://github.com/hyperledger/aries-framework-javascript/blob/c72ba149bad3a4596f5818b28516f6286b9088bf/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo1.ts#L3) - Compute method 1 DID
- `PeerDidRegistrar.ts`
- `PeerDidResolver.ts`
- [`src/modules/connections/services`](https://github.com/hyperledger/aries-framework-javascript/tree/main/packages/core/src/modules/connections/services)
- [`helpers.ts`](https://github.com/hyperledger/aries-framework-javascript/blob/c72ba149bad3a4596f5818b28516f6286b9088bf/packages/core/src/modules/connections/services/helpers.ts#L11) - convert to new DIDDoc
- Exmaple DIDDoc structure to be matched in ACA-Py implementation
```
{
"@context": ["https://w3id.org/did/v1"],
"id": "did:peer:1zQmXv3d2vqC2Q9JrnrFqqj5h8vzcNAumL1UZbb1TGh58j2c",
"authentication": [
{
"id": "#6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V",
"type": "Ed25519VerificationKey2018",
"publicKeyBase58": "ByHnpUCFb1vAfh9CFZ8ZkmUZguURW8nSw889hy6rD8L7"
},
{
"id": "#6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg",
"type": "Ed25519VerificationKey2018",
"publicKeyBase58": "3M5RCDjPTWPkKSN3sxUmmMqHbmRPegYP1tjcKyrDbt9J"
}
],
"keyAgreement": [
{
"id": "#6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc",
"type": "X25519KeyAgreementKey2019",
"publicKeyBase58": "JhNWeSVLMYccCk7iopQW4guaSJTojqpMEELgSLhKwRr"
}
],
"service": [
{
"id": "#service-0",
"type": "DIDCommMessaging",
"serviceEndpoint": "https://example.com/endpoint",
"routingKeys": ["did:example:somemediator#somekey"],
"accept": ["didcomm/v2", "didcomm/aip2;env=rfc587"]
}
]
}
```
This implementation will address the following ACA-Py issues:
- [Create DID docs with peer DID method in did exchange](https://github.com/hyperledger/aries-cloudagent-python/issues/1048)
- [did doc - referenced verification methods should be plain strings](https://github.com/hyperledger/aries-cloudagent-python/issues/1104)
- [recipientKeys and routingKeys format don't match RFCs](https://github.com/hyperledger/aries-cloudagent-python/issues/1106)
- [use did-communication service type in DID Exchange](https://github.com/hyperledger/aries-cloudagent-python/issues/1043)
- [use and accept updated media types](https://github.com/hyperledger/aries-cloudagent-python/issues/1044)
### Deliverables
- Implementation of the agreed upon design, unit test coverage and interop with AFJ and possibly AFGO.
- Ability to convert old unqualified DIDs to Peer DIDs and corresponding DIDDocs accordingly.
## Goals
- Maintain backwards compatibility with unqualified DIDs
- Ability to use unqualified DIDs and associated old DIDDoc type with use of startup flag
- Complete unit test coverage for new changes in ACA-Py
- Interop with AFJ and AFGO
## Proposed ACA-Py Changes
- Add in `aries_cloudagent/messaging/valid.py`
```
class PeerDID(Regexp):
EXAMPLE = "did:peer:1zQmZMygzYqNwU6Uhmewx5Xepf2VLp5S4HLSwwgf2aiKZuwa"
PATTERN = re.compile(rf"^did:peer:(([01](z)([1-9a-km-zA-HJ-NP-Z]{5,200}))|(2((.[AEVID](z)([1-9a-km-zA-HJ-NP-Z]{5,200}))+(.(S)[0-9a-zA-Z=]*)?)))$")
def __init__(self):
"""Initializer."""
super().__init__(
PeerDID.PATTERN,
error="Value {input} is not a Peer decentralized identifier (DID)",
)
```
- create `did_peer.py` in `aries_cloudagent/did`
```
class PeerDidNumAlgo(Enum):
INCEPTION_KEY_WITHOUT_DOC = 0
GENESIS_DOC = 1
MULTIPLE_INCEPTION_KEY_WITHOUT_DOC = 2
class DIDPeer:
@classmethod
def get_did_from_did_doc_json(did_doc_json: str) -> str
@classmethod
def is_valid_peer_did(str) -> bool
@classmethod
def get_num_algo_from_peer_did(str)
construct_did_peer(
id,
services,
auth: List[PublicKeyBase58],
key_agreement: List[PublicKeyBase58]
) -> dict
```
- `get_did_from_did_doc_json` <br/>[AFJ reference](https://github.com/hyperledger/aries-framework-javascript/blob/c72ba149bad3a4596f5818b28516f6286b9088bf/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo1.ts#L3) </br>Exclude id property then hash it to generate did:peer:1 which will be same as id property
- Create `didpeerdoc.py` in `aries_cloudagent/connections/connections/models/diddoc`</br>
it will match the new structure of DIDDoc as depicted above
- Add `convert_did_doc_to_did_peer_doc` function to `aries_cloudagent/connections/connections/models/diddoc/util.py`<br/>[AFJ reference](https://github.com/hyperledger/aries-framework-javascript/blob/c72ba149bad3a4596f5818b28516f6286b9088bf/packages/core/src/modules/connections/services/helpers.ts#L11) </br>To convert old DIDDoc to DIDPeerDoc and support converstion of existing unqualified DIDs to qualified Peer DIDs
- Changes in `aries_cloudagent/connections/base_manager.py`
- create `create_peer_did_document` function<br/>[AFJ reference](https://github.com/hyperledger/aries-framework-javascript/blob/c72ba149bad3a4596f5818b28516f6286b9088bf/packages/core/src/modules/dids/methods/peer/createPeerDidDocumentFromServices.ts#L14)<br/>`create_did_document` function will remain unchanged for backward compatiblity and to allow for usage of unqualified DID, if required [setup by startup flag].<br/>
<b>Question:</b> When creating implicit DIDXRequest against public DID then how should we handle this?
- update `store_did_document` function to be able to handle both `DIDDoc` [existing] and `DIDPeerDoc`
- update `diddoc_connection_targets` function to be able to handle both `DIDDoc` [existing] and `DIDPeerDoc`
- update `fetch_did_document` function to be able to handle both `DIDDoc` [existing] and `DIDPeerDoc`
- Add a statup flag something like `--use-unqualified-did` or `--use-legacy-did` to use flow as currently implemented in ACA-Py. By default, we use Peer DID when creating DIDXRequest and DIDXResponse.
- Changes in `aries_cloudagent/protocols/didexchange/v1_0/manager.py`
- In `create_request` and `create_response` functions, call `create_peer_did_document` if the above startup flag is not included otherwise call `create_did_document`
- Update `verify_diddoc` function to handle both `DIDDoc` [existing] and `DIDPeerDoc`
- Update `get_resolved_did_document` to call `fetch_did_document` [from storage] instead if did is of `did:peer:1` pattern.