Package: did-peer-2
did-peer-2A minimal did:peer:2 (and 3) library.did:peer:2 has (or will soon be) superseded bydid:peer:4. Even so, we anticipate did:peer:2 being around for at least a while longer. This library is built against the most recent version of the did:peer:2 spec.Installpipinstalldid-peer-2Usage>>>fromdid_peer_2importgenerate,KeySpec,resolve,peer2to3>>># Define keys using KeySpec>>>keys=[...KeySpec.verification("z6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc"),...KeySpec.encryption("z6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR")...]>>># Define service objects>>>services=[...{..."type":"DIDCommMessaging",..."serviceEndpoint":{..."uri":"http://example.com/didcomm",..."accept":["didcomm/v2"],..."routingKeys":["did:example:123456789abcdefghi#key-1"],...},...},...]>>>>>># Generate the DID>>>did=generate(keys,services)>>>print(did)did:peer:2.Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc.Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ>>>>>># Resolve the DID>>>resolved=resolve(did)>>># The resolved document will be a dictionary>>>assertisinstance(resolved,dict)>>>>>># Let's print it out>>>importjson>>>print(json.dumps(resolved,indent=2)){"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1"],"id":"did:peer:2.Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc.Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ","verificationMethod":[{"type":"Multikey","id":"#key-1","controller":"did:peer:2.Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc.Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ","publicKeyMultibase":"z6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc"},{"type":"Multikey","id":"#key-2","controller":"did:peer:2.Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc.Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ","publicKeyMultibase":"z6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR"}],"authentication":["#key-1"],"keyAgreement":["#key-2"],"service":[{"type":"DIDCommMessaging","serviceEndpoint":{"uri":"http://example.com/didcomm","accept":["didcomm/v2"],"routingKeys":["did:example:123456789abcdefghi#key-1"]},"id":"#service"}],"alsoKnownAs":["did:peer:3zQmbRvRJgKBuubq8T9VBjrDPTmjb2Ed91f89ekW4gr6aZxa"]}>>># Let's derive the did:peer:3>>>did3=peer2to3(did)>>>print(did3)did:peer:3zQmbRvRJgKBuubq8T9VBjrDPTmjb2Ed91f89ekW4gr6aZxaDID Peer 2 SpecificationIfnumalgo==2, the generation mode is similar to Method 0 (and therefore also did:key) with the ability to specify additional keys in the generated DID Document. This method is necessary when both an encryption key and a signing key are required. This method also enables including services in the generated DID Document.[!NOTE]
The first iteration of this method left some elements of the encoding and decoding process underspecified. Clarifications have been made to this specification to resolve this. These clarifications will be noted by appending "(clarified)" to the relevant statements.peer-did-method-2 = "did:peer:2" 1*element 
element = "." ( purposecode transform encnumbasis / service )
purposecode = "A" / "E" / "V" / "I" / "D" / "S" 
keypurpose = 
transform = "z"
encnumbasis = 46*BASE58BTC
service = 1*B64URLGenerating adid:peer:2When generating adid:peer:2, take as inputs a set of keys and their purpose. Each key's purpose corresponds to theVerification Relationshipit will hold in the DID Document generated from the DID.Abstractly, these inputs may look like the following (in this example, the keys are already multibase, multicodec encoded values):[{"purpose":"verification","publicKeyMultibase":"z6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc"},{"purpose":"encryption","publicKeyMultibase":"z6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR"}]To encode these keys:Construct amultibase,multicodecform of each public key to be included.Prefix each encoded key with a period character (.) and single character from the purpose codes table below.Concatenate the prefixed encoded keys. The inputs above will result in:.Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc.Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBRIn addition to keys,did:peer:2can encode one or moreservices.The service SHOULD follow the DID Core specification for services.For use withdid:peer:2, serviceidattributes MUST be relative. The service MAY omit theid; however, this is NOT recommended (clarified).Consider the following service as input:{"type":"DIDCommMessaging","serviceEndpoint":{"uri":"http://example.com/didcomm","accept":["didcomm/v2"],"routingKeys":["did:example:123456789abcdefghi#key-1"]}}To encode a service:Start with the JSON structure for your service, like the example input above.Recursively replace common strings in key names and type value with abbreviations from the abbreviations table below (clarified). For the above input, this will result in:{
  "t": "dm",
  "s": {
    "uri": "http://example.com/didcomm",
    "a": [
      "didcomm/v2"
    ],
    "r": [
      "did:example:123456789abcdefghi#key-1"
    ]
  }
}Convert to string, and remove unnecessary whitespace, such as spaces and newlines. For the above input, this will result in:{"t":"dm","s":{"uri":"http://example.com/didcomm","a":["didcomm/v2"],"r":["did:example:123456789abcdefghi#key-1"]}}Base64URL Encode String (Padding MUST be removed as the "=" character is, per the DID Core Specification, not permitted in a DID). For the above example, this will result in:eyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQPrefix encoded service with a period character (.) and S. For the above input, this will result in:.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYWNjZXB0IjpbImRpZGNvbW0vdjIiXSwicm91dGluZ0tleXMiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQFor any additional services, repeat the steps above and concatenate each additional service to the previous (clarified). This will result in a string like the following (newline added between service strings for clarity; in practice, there will be no whitespace between the concatenated services):.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYWNjZXB0IjpbImRpZGNvbW0vdjIiXSwicm91dGluZ0tleXMiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ
.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9hbm90aGVyIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0yIl19fQFinally, to create the DID, concatenate the following values:did:peer:2Encoded, concatenated, and prefixed keys.Encoded, concatenated, and prefixed services.This concatenation will result in a value like the following:did:peer:2.Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc.Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9hbm90aGVyIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0yIl19fQLookup TablesCommon String AbbreviationsCommon StringAbbreviationtypetDIDCommMessagingdmserviceEndpointsroutingKeysracceptaPurpose CodesPurpose CodeVerification RelationshipAAssertionEKey Agreement (Encryption)VAuthentication (Verification)ICapability InvocationDCapability DelegationSServiceResolving adid:peer:2[!NOTE]
Below is the normative approach to resolving did:peer:2 DIDs. However, it is often the case that the resolved value is only used within a particular component. In this case, some of these rules may be relaxed. For instance, the verification material may be transformed into a JWK or other representation if the resolving component is more accustomed to working with those key representations. It is not strictly necessary to first represent the document as described here only to immediately transform it into the more familiar representation. Shortcuts like these are not problematic unless they impact the function of the DID Document.Theidvalue of the Document, verification method, and service objects MUST be set as outlined below. These values are used to reference elements of the document and must be consistent across implementations regardless of shortcuts taken within the resolver.When Resolving the peer DID into a DID Document, the process is reversed:Start with an empty document with the DID Core context andMultikey context(clarified):{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1"]}Set theidof the document to the DID being resolved.Optionally, set thealsoKnownAsto thedid:peer:3value corresponding to the DID being resolved.Split the DID string into elements.For each element with a purpose corresponding to a key, transform keys into verification methods in the DID Document:Remove the period (.) and the Purpose prefix. Consider the remaining string the "encoded key."Create an empty object. Consider this value the "verification method."Set thetypeof the verification method toMultikey(clarified).Set theidof the verification method to#key-NwhereNis an incrementing number starting at1(clarified). The keys MUST be processed in the order they appear in the DID string. For example, if you have the DID (whitespace added for example only):did:peer:2
    .Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc
    .Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR
    .SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ
    .SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9hbm90aGVyIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0yIl19fQThe key with purpose codeVand encoded key valuez6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKcwill have theid:#key-1.
The key with purpose codeEand encoded key valuez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBRwill have theid:#key-2.Set thecontrollerof the verification method to the value of the DID being resolved.Set thepublicKeyMultibaseof the verification method to the value of the encoded key.Append this object toverificationMethodof the document (clarified).Append a reference to the verification method to the appropriate verification relationship, using the lookup table above. The reference should be the exact value used in theidof the verification method (clarified). For example, using the DID above and the key with purpose codeV:{
  ... // Context and other elements previously added to the document
  "authentication": [..., "#key-1"]
}For each element with a purpose corresponding to a service, transform the service and add to the DID Document:Remove the period (.) and S prefix.Base64URL Decode String.Parse as JSON.Replace abbreviations in key names and type value with common names from the abbreviations table above.If theidis NOT set (clarified):Setidto#servicefor the first such service.For all subsequent services WITHOUT anid, setidto#service-1,#service-2, etc. incrementing the integer with each service, starting from1.[!NOTE]
It is  not possible to express a verification method not controlled by the controller of the DID Document withdid:peer:2.{"@context":["https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1",],"id":"did:peer:2.Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc.Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9hbm90aGVyIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0yIl19fQ","verificationMethod":[{"id":"#key-1","controller":"did:peer:2.Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc.Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9hbm90aGVyIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0yIl19fQ","type":"Multikey","publicKeyMultibase":"z6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc",},{"id":"#key-2","controller":"did:peer:2.Vz6Mkj3PUd1WjvaDhNZhhhXQdz5UnZXmS7ehtx8bsPpD47kKc.Ez6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9kaWRjb21tIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0xIl19fQ.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHA6Ly9leGFtcGxlLmNvbS9hbm90aGVyIiwiYSI6WyJkaWRjb21tL3YyIl0sInIiOlsiZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleS0yIl19fQ","type":"Multikey","publicKeyMultibase":"z6LSg8zQom395jKLrGiBNruB9MM6V8PWuf2FpEy4uRFiqQBR",},],"authentication":["#key-1"],"keyAgreement":["#key-2"],"service":[{"type":"DIDCommMessaging","serviceEndpoint":{"uri":"http://example.com/didcomm","accept":["didcomm/v2"],"routingKeys":["did:example:123456789abcdefghi#key-1"],},"id":"#service",},{"type":"DIDCommMessaging","serviceEndpoint":{"uri":"http://example.com/another","accept":["didcomm/v2"],"routingKeys":["did:example:123456789abcdefghi#key-2"],},"id":"#service-1",},],"alsoKnownAs":["did:peer:3zQmd6RdU6e2nDrLn1rjwdA5Buzq7wJwsv3WJ1AgrwKYJoLE"],}DID Peer 3: DID Shortening with SHA-256 HashIfnumalgo==3, the generation mode is similar to Method 2, but with a shorter DID identifier derived from a SHA-256 hash of the original identifier. The benefit of using Method 3 over Method 2 is the ability to have smaller size didcomm messages asdid:peer:2.dids tend to be verbose in nature. Method 3 peer dids can only be used after a peer did method 2 has been exchange with the other party and thus can map the shortened did to the longform one. In order to send a message encrypted with method 3 you first MUST send a discover-feature message (using the method 2 as thetofield) to make sure that the receiving agent is capable of resolving method 3 dids.peer-did-method-3 = "did:peer:3" transform encnumbasis
transform = "z"
encnumbasis = 46*BASE58BTCStart with the DID generated using Method 2.Take the SHA-256 hash of the generated DID (excluding the "did:peer:2" prefix).Encode the hash using the base58btc multibase encoding.Construct the final Method 3 DID by concatenating the prefix "did:peer:3" with the encoded hash.For example, if the Method 2 DID is:did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0First, remove the prefix "did:peer:2":.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0Take the SHA-256 hash of the remaining string and represent as a multi-hash, multi-base encoded(base58btc) string:zQmS19jtYDvGtKVrJhQnRFpBQAx3pJ9omx2HpNrcXFuRCz9Finally, concatenate the prefix "did:peer:3" with the computed and encoded hash:did:peer:3zQmS19jtYDvGtKVrJhQnRFpBQAx3pJ9omx2HpNrcXFuRCz9