diff --git a/.changeset/sharp-masks-deliver.md b/.changeset/sharp-masks-deliver.md new file mode 100644 index 0000000000..cf67465f8c --- /dev/null +++ b/.changeset/sharp-masks-deliver.md @@ -0,0 +1,7 @@ +--- +'@credo-ts/indy-vdr': patch +'@credo-ts/cheqd': patch +'@credo-ts/core': patch +--- + +feat: support new 'DIDCommMessaging' didcomm v2 service type (in addition to older 'DIDComm' service type) diff --git a/packages/cheqd/tests/setup.ts b/packages/cheqd/tests/setup.ts index 6521088639..f9b3e68f1a 100644 --- a/packages/cheqd/tests/setup.ts +++ b/packages/cheqd/tests/setup.ts @@ -16,7 +16,7 @@ export function validVerificationMethod(did: string) { export function validService(did: string) { return new DidDocumentService({ id: did + '#service-1', - type: 'DIDCommMessaging', + type: 'CustomType', serviceEndpoint: 'https://rand.io', }) } diff --git a/packages/core/src/agent/TransportService.ts b/packages/core/src/agent/TransportService.ts index de90b09984..fee9f1166e 100644 --- a/packages/core/src/agent/TransportService.ts +++ b/packages/core/src/agent/TransportService.ts @@ -56,7 +56,7 @@ export class TransportService { } public hasInboundEndpoint(didDocument: DidDocument): boolean { - return Boolean(didDocument.service?.find((s) => s.serviceEndpoint !== DID_COMM_TRANSPORT_QUEUE)) + return Boolean(didDocument.didCommServices?.find((s) => s.serviceEndpoint !== DID_COMM_TRANSPORT_QUEUE)) } public findSessionById(sessionId: string) { diff --git a/packages/core/src/agent/__tests__/MessageSender.test.ts b/packages/core/src/agent/__tests__/MessageSender.test.ts index 6c12cf1e01..0d6682a90d 100644 --- a/packages/core/src/agent/__tests__/MessageSender.test.ts +++ b/packages/core/src/agent/__tests__/MessageSender.test.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ import type { ConnectionRecord } from '../../modules/connections' import type { ResolvedDidCommService } from '../../modules/didcomm' -import type { DidDocumentService } from '../../modules/dids' +import type { DidDocumentService, IndyAgentService } from '../../modules/dids' import type { MessagePickupRepository } from '../../modules/message-pickup/storage' import type { OutboundTransport } from '../../transport' import type { EncryptedMessage } from '../../types' @@ -693,7 +693,7 @@ function getMockDidDocument({ service }: { service: DidDocumentService[] }) { }) } -function getMockResolvedDidService(service: DidDocumentService): ResolvedDidCommService { +function getMockResolvedDidService(service: DidCommV1Service | IndyAgentService): ResolvedDidCommService { return { id: service.id, serviceEndpoint: service.serviceEndpoint, diff --git a/packages/core/src/modules/dids/__tests__/__fixtures__/didExample123DidcommV2Service.json b/packages/core/src/modules/dids/__tests__/__fixtures__/didExample123DidcommV2Service.json new file mode 100644 index 0000000000..d07b599648 --- /dev/null +++ b/packages/core/src/modules/dids/__tests__/__fixtures__/didExample123DidcommV2Service.json @@ -0,0 +1,30 @@ +{ + "@context": ["https://w3id.org/did/v1"], + "id": "did:example:123", + "service": [ + { + "id": "did:example:123#service-1", + "type": "DIDCommMessaging", + "serviceEndpoint": { + "uri": "did:sov:Q4zqM7aXqm7gDQkUVLng9h", + "routingKeys": ["Q4zqM7aXqm7gDQkUVLng9h"] + } + }, + { + "id": "did:example:123#service-2", + "type": "DIDComm", + "serviceEndpoint": "https://agent.com/did-comm", + "routingKeys": ["DADEajsDSaksLng9h"] + }, + { + "id": "did:example:123#service-3", + "type": "DIDCommMessaging", + "serviceEndpoint": [ + { + "uri": "did:sov:Q4zqM7aXqm7gDQkUVLng9h", + "routingKeys": ["Q4zqM7aXqm7gDQkUVLng9h"] + } + ] + } + ] +} diff --git a/packages/core/src/modules/dids/__tests__/__fixtures__/didExample456Invalid.json b/packages/core/src/modules/dids/__tests__/__fixtures__/didExample456Invalid.json index 17f6c5c251..83b25c0e48 100644 --- a/packages/core/src/modules/dids/__tests__/__fixtures__/didExample456Invalid.json +++ b/packages/core/src/modules/dids/__tests__/__fixtures__/didExample456Invalid.json @@ -20,7 +20,8 @@ "service": [ { "id": "did:example:123#service-1", - "type": "Mediator" + "type": "Mediator", + "serviceEndpoint": "uri:uri" }, { "id": "did:example:123#service-2", diff --git a/packages/core/src/modules/dids/domain/DidDocumentBuilder.ts b/packages/core/src/modules/dids/domain/DidDocumentBuilder.ts index 503a1f2759..f06e03b8ae 100644 --- a/packages/core/src/modules/dids/domain/DidDocumentBuilder.ts +++ b/packages/core/src/modules/dids/domain/DidDocumentBuilder.ts @@ -1,5 +1,7 @@ import type { DidDocumentService } from './service' +import { asArray } from '../../../utils' + import { DidDocument } from './DidDocument' import { VerificationMethod } from './verificationMethod' @@ -13,12 +15,10 @@ export class DidDocumentBuilder { } public addContext(context: string) { - if (typeof this.didDocument.context === 'string') { - this.didDocument.context = [this.didDocument.context, context] - } else { - this.didDocument.context.push(context) - } + const currentContexts = asArray(this.didDocument.context) + if (currentContexts.includes(context)) return this + this.didDocument.context = [...currentContexts, context] return this } diff --git a/packages/core/src/modules/dids/domain/service/DidCommV1Service.ts b/packages/core/src/modules/dids/domain/service/DidCommV1Service.ts index 52b1a84195..af39aff270 100644 --- a/packages/core/src/modules/dids/domain/service/DidCommV1Service.ts +++ b/packages/core/src/modules/dids/domain/service/DidCommV1Service.ts @@ -1,5 +1,8 @@ import { ArrayNotEmpty, IsOptional, IsString } from 'class-validator' +import { IsUri } from '../../../../utils' +import { getProtocolScheme } from '../../../../utils/uri' + import { DidDocumentService } from './DidDocumentService' export class DidCommV1Service extends DidDocumentService { @@ -23,6 +26,14 @@ export class DidCommV1Service extends DidDocumentService { public static type = 'did-communication' + public get protocolScheme(): string { + return getProtocolScheme(this.serviceEndpoint) + } + + @IsString() + @IsUri() + public serviceEndpoint!: string + @ArrayNotEmpty() @IsString({ each: true }) public recipientKeys!: string[] diff --git a/packages/core/src/modules/dids/domain/service/DidCommV2Service.ts b/packages/core/src/modules/dids/domain/service/DidCommV2Service.ts index c8f04d227a..6eb1bf0c47 100644 --- a/packages/core/src/modules/dids/domain/service/DidCommV2Service.ts +++ b/packages/core/src/modules/dids/domain/service/DidCommV2Service.ts @@ -1,14 +1,28 @@ import { IsOptional, IsString } from 'class-validator' +import { IsUri } from '../../../../utils' + import { DidDocumentService } from './DidDocumentService' +import { NewDidCommV2Service, NewDidCommV2ServiceEndpoint } from './NewDidCommV2Service' + +export interface DidCommV2ServiceOptions { + id: string + serviceEndpoint: string + routingKeys?: string[] + accept?: string[] +} +/** + * @deprecated use `NewDidCommV2Service` instead. Will be renamed to `LegacyDidCommV2Service` in 0.6 + */ export class DidCommV2Service extends DidDocumentService { - public constructor(options: { id: string; serviceEndpoint: string; routingKeys?: string[]; accept?: string[] }) { + public constructor(options: DidCommV2ServiceOptions) { super({ ...options, type: DidCommV2Service.type }) if (options) { - this.routingKeys = options.routingKeys + this.serviceEndpoint = options.serviceEndpoint this.accept = options.accept + this.routingKeys = options.routingKeys } } @@ -21,4 +35,19 @@ export class DidCommV2Service extends DidDocumentService { @IsString({ each: true }) @IsOptional() public accept?: string[] + + @IsUri() + @IsString() + public serviceEndpoint!: string + + public toNewDidCommV2(): NewDidCommV2Service { + return new NewDidCommV2Service({ + id: this.id, + serviceEndpoint: new NewDidCommV2ServiceEndpoint({ + uri: this.serviceEndpoint, + accept: this.accept, + routingKeys: this.routingKeys, + }), + }) + } } diff --git a/packages/core/src/modules/dids/domain/service/DidDocumentService.ts b/packages/core/src/modules/dids/domain/service/DidDocumentService.ts index c3fd763ec5..25ed0f53c2 100644 --- a/packages/core/src/modules/dids/domain/service/DidDocumentService.ts +++ b/packages/core/src/modules/dids/domain/service/DidDocumentService.ts @@ -1,9 +1,15 @@ -import { IsString } from 'class-validator' +import type { ValidationOptions } from 'class-validator' +import { buildMessage, isString, IsString, ValidateBy } from 'class-validator' + +import { CredoError } from '../../../../error' +import { isJsonObject, SingleOrArray } from '../../../../utils' import { getProtocolScheme } from '../../../../utils/uri' +type ServiceEndpointType = SingleOrArray> + export class DidDocumentService { - public constructor(options: { id: string; serviceEndpoint: string; type: string }) { + public constructor(options: { id: string; serviceEndpoint: ServiceEndpointType; type: string }) { if (options) { this.id = options.id this.serviceEndpoint = options.serviceEndpoint @@ -11,16 +17,47 @@ export class DidDocumentService { } } + /** + * @deprecated will be removed in 0.6, as it's not possible from the base did document service class to determine + * the protocol scheme. It needs to be implemented on a specific did document service class. + */ public get protocolScheme(): string { + if (typeof this.serviceEndpoint !== 'string') { + throw new CredoError('Unable to extract protocol scheme from serviceEndpoint as it is not a string.') + } + return getProtocolScheme(this.serviceEndpoint) } @IsString() public id!: string - @IsString() - public serviceEndpoint!: string + @IsStringOrJsonObjectSingleOrArray() + public serviceEndpoint!: SingleOrArray> @IsString() public type!: string } + +/** + * Checks if a given value is a string, a json object, or an array of strings and json objects + */ +function IsStringOrJsonObjectSingleOrArray(validationOptions?: Omit): PropertyDecorator { + return ValidateBy( + { + name: 'isStringOrJsonObjectSingleOrArray', + validator: { + validate: (value): boolean => + isString(value) || + isJsonObject(value) || + (Array.isArray(value) && value.every((v) => isString(v) || isJsonObject(v))), + defaultMessage: buildMessage( + (eachPrefix) => + eachPrefix + '$property must be a string, JSON object, or an array consisting of strings and JSON objects', + validationOptions + ), + }, + }, + validationOptions + ) +} diff --git a/packages/core/src/modules/dids/domain/service/IndyAgentService.ts b/packages/core/src/modules/dids/domain/service/IndyAgentService.ts index 588547fda2..3cc95faf46 100644 --- a/packages/core/src/modules/dids/domain/service/IndyAgentService.ts +++ b/packages/core/src/modules/dids/domain/service/IndyAgentService.ts @@ -1,5 +1,8 @@ import { ArrayNotEmpty, IsOptional, IsString } from 'class-validator' +import { IsUri } from '../../../../utils' +import { getProtocolScheme } from '../../../../utils/uri' + import { DidDocumentService } from './DidDocumentService' export class IndyAgentService extends DidDocumentService { @@ -21,6 +24,14 @@ export class IndyAgentService extends DidDocumentService { public static type = 'IndyAgent' + public get protocolScheme(): string { + return getProtocolScheme(this.serviceEndpoint) + } + + @IsString() + @IsUri() + public serviceEndpoint!: string + @ArrayNotEmpty() @IsString({ each: true }) public recipientKeys!: string[] diff --git a/packages/core/src/modules/dids/domain/service/NewDidCommV2Service.ts b/packages/core/src/modules/dids/domain/service/NewDidCommV2Service.ts new file mode 100644 index 0000000000..865a107653 --- /dev/null +++ b/packages/core/src/modules/dids/domain/service/NewDidCommV2Service.ts @@ -0,0 +1,74 @@ +import { Type } from 'class-transformer' +import { IsOptional, IsString, ValidateNested } from 'class-validator' + +import { CredoError } from '../../../../error' +import { SingleOrArray, IsInstanceOrArrayOfInstances, IsUri } from '../../../../utils' + +import { DidDocumentService } from './DidDocumentService' + +export interface NewDidCommV2ServiceEndpointOptions { + uri: string + routingKeys?: string[] + accept?: string[] +} + +export class NewDidCommV2ServiceEndpoint { + public constructor(options: NewDidCommV2ServiceEndpointOptions) { + if (options) { + this.uri = options.uri + this.routingKeys = options.routingKeys + this.accept = options.accept + } + } + + @IsString() + @IsUri() + public uri!: string + + @IsString({ each: true }) + @IsOptional() + public routingKeys?: string[] + + @IsString({ each: true }) + @IsOptional() + public accept?: string[]; + + [key: string]: unknown | undefined +} + +export interface DidCommV2ServiceOptions { + id: string + serviceEndpoint: SingleOrArray +} + +/** + * Will be renamed to `DidCommV2Service` in 0.6 (and replace the current `DidCommV2Service`) + */ +export class NewDidCommV2Service extends DidDocumentService { + public constructor(options: DidCommV2ServiceOptions) { + super({ ...options, type: NewDidCommV2Service.type }) + + if (options) { + this.serviceEndpoint = options.serviceEndpoint + } + } + + public static type = 'DIDCommMessaging' + + @IsInstanceOrArrayOfInstances({ classType: [NewDidCommV2ServiceEndpoint] }) + @ValidateNested() + @Type(() => NewDidCommV2ServiceEndpoint) + public serviceEndpoint!: SingleOrArray + + public get firstServiceEndpointUri(): string { + if (Array.isArray(this.serviceEndpoint)) { + if (this.serviceEndpoint.length === 0) { + throw new CredoError('No entries in serviceEndpoint array') + } + + return this.serviceEndpoint[0].uri + } + + return this.serviceEndpoint.uri + } +} diff --git a/packages/core/src/modules/dids/domain/service/ServiceTransformer.ts b/packages/core/src/modules/dids/domain/service/ServiceTransformer.ts index a47c6173d5..ec4ae98d9a 100644 --- a/packages/core/src/modules/dids/domain/service/ServiceTransformer.ts +++ b/packages/core/src/modules/dids/domain/service/ServiceTransformer.ts @@ -1,15 +1,19 @@ import type { ClassConstructor } from 'class-transformer' -import { Transform, plainToInstance } from 'class-transformer' +import { Transform } from 'class-transformer' + +import { JsonTransformer } from '../../../../utils' import { DidCommV1Service } from './DidCommV1Service' import { DidCommV2Service } from './DidCommV2Service' import { DidDocumentService } from './DidDocumentService' import { IndyAgentService } from './IndyAgentService' +import { NewDidCommV2Service } from './NewDidCommV2Service' export const serviceTypes: { [key: string]: unknown | undefined } = { [IndyAgentService.type]: IndyAgentService, [DidCommV1Service.type]: DidCommV1Service, + [NewDidCommV2Service.type]: NewDidCommV2Service, [DidCommV2Service.type]: DidCommV2Service, } @@ -26,9 +30,20 @@ export function ServiceTransformer() { return Transform( ({ value }: { value?: Array<{ type: string }> }) => { return value?.map((serviceJson) => { - const serviceClass = (serviceTypes[serviceJson.type] ?? + let serviceClass = (serviceTypes[serviceJson.type] ?? DidDocumentService) as ClassConstructor - const service = plainToInstance(serviceClass, serviceJson) + + // NOTE: deal with `DIDCommMessaging` type but using `serviceEndpoint` string value, parse it using the + // legacy class type + if ( + serviceJson.type === NewDidCommV2Service.type && + 'serviceEndpoint' in serviceJson && + typeof serviceJson.serviceEndpoint === 'string' + ) { + serviceClass = DidCommV2Service + } + + const service = JsonTransformer.fromJSON(serviceJson, serviceClass) return service }) diff --git a/packages/core/src/modules/dids/domain/service/__tests__/DidcommV2Service.test.ts b/packages/core/src/modules/dids/domain/service/__tests__/DidcommV2Service.test.ts new file mode 100644 index 0000000000..230ef604af --- /dev/null +++ b/packages/core/src/modules/dids/domain/service/__tests__/DidcommV2Service.test.ts @@ -0,0 +1,54 @@ +import { JsonTransformer } from '../../../../../utils' +import didExample123DidcommV2 from '../../../__tests__/__fixtures__/didExample123DidcommV2Service.json' +import { DidDocument } from '../../DidDocument' +import { DidCommV2Service } from '../DidCommV2Service' +import { NewDidCommV2Service } from '../NewDidCommV2Service' + +describe('Did | DidDocument | DidCommV2Service', () => { + it('should correctly transforms Json to DidDocument class with didcomm v2 service', () => { + const didDocument = JsonTransformer.fromJSON(didExample123DidcommV2, DidDocument) + + expect(didDocument.service?.[0]).toBeInstanceOf(NewDidCommV2Service) + expect(didDocument.service?.[1]).toBeInstanceOf(DidCommV2Service) + + const didcommV2Service = didDocument.service?.[0] as NewDidCommV2Service + const legacyDidcommV2Service = didDocument.service?.[1] as DidCommV2Service + const didcommV2ServiceArray = didDocument.service?.[2] as NewDidCommV2Service + + expect(didcommV2Service).toEqual({ + id: 'did:example:123#service-1', + type: 'DIDCommMessaging', + serviceEndpoint: { + uri: 'did:sov:Q4zqM7aXqm7gDQkUVLng9h', + routingKeys: ['Q4zqM7aXqm7gDQkUVLng9h'], + }, + }) + + expect(legacyDidcommV2Service).toEqual({ + id: 'did:example:123#service-2', + type: 'DIDComm', + serviceEndpoint: 'https://agent.com/did-comm', + routingKeys: ['DADEajsDSaksLng9h'], + }) + + expect(didcommV2ServiceArray).toEqual({ + id: 'did:example:123#service-3', + type: 'DIDCommMessaging', + serviceEndpoint: [ + { + uri: 'did:sov:Q4zqM7aXqm7gDQkUVLng9h', + routingKeys: ['Q4zqM7aXqm7gDQkUVLng9h'], + }, + ], + }) + + expect(legacyDidcommV2Service.toNewDidCommV2()).toEqual({ + id: 'did:example:123#service-2', + type: 'DIDCommMessaging', + serviceEndpoint: { + uri: 'https://agent.com/did-comm', + routingKeys: ['DADEajsDSaksLng9h'], + }, + }) + }) +}) diff --git a/packages/core/src/modules/dids/domain/service/index.ts b/packages/core/src/modules/dids/domain/service/index.ts index 51fc9bc8d9..aa646b0d0d 100644 --- a/packages/core/src/modules/dids/domain/service/index.ts +++ b/packages/core/src/modules/dids/domain/service/index.ts @@ -1,7 +1,22 @@ import { DidCommV1Service } from './DidCommV1Service' -import { DidCommV2Service } from './DidCommV2Service' import { DidDocumentService } from './DidDocumentService' import { IndyAgentService } from './IndyAgentService' +import { + NewDidCommV2Service, + NewDidCommV2ServiceEndpoint, + NewDidCommV2ServiceEndpointOptions, +} from './NewDidCommV2Service' import { ServiceTransformer, serviceTypes } from './ServiceTransformer' -export { IndyAgentService, DidCommV1Service, DidDocumentService, DidCommV2Service, ServiceTransformer, serviceTypes } +export { DidCommV2ServiceOptions, DidCommV2Service } from './DidCommV2Service' + +export { + IndyAgentService, + DidCommV1Service, + DidDocumentService, + ServiceTransformer, + serviceTypes, + NewDidCommV2Service, + NewDidCommV2ServiceEndpoint, + NewDidCommV2ServiceEndpointOptions, +} diff --git a/packages/core/src/modules/dids/methods/peer/__tests__/__fixtures__/didPeer2Ez6L.json b/packages/core/src/modules/dids/methods/peer/__tests__/__fixtures__/didPeer2Ez6L.json index a3d9c8e48c..f7d141e7b3 100644 --- a/packages/core/src/modules/dids/methods/peer/__tests__/__fixtures__/didPeer2Ez6L.json +++ b/packages/core/src/modules/dids/methods/peer/__tests__/__fixtures__/didPeer2Ez6L.json @@ -1,34 +1,36 @@ { - "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0", + "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InVyaSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyb3V0aW5nS2V5cyI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJhY2NlcHQiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjNTg3Il19LCJ0IjoiZG0ifQ", "authentication": [ { - "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0#key-1", + "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InVyaSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyb3V0aW5nS2V5cyI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJhY2NlcHQiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjNTg3Il19LCJ0IjoiZG0ifQ#key-1", "type": "Ed25519VerificationKey2018", - "controller": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0", + "controller": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InVyaSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyb3V0aW5nS2V5cyI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJhY2NlcHQiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjNTg3Il19LCJ0IjoiZG0ifQ", "publicKeyBase58": "ByHnpUCFb1vAfh9CFZ8ZkmUZguURW8nSw889hy6rD8L7" }, { - "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0#key-3", + "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InVyaSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyb3V0aW5nS2V5cyI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJhY2NlcHQiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjNTg3Il19LCJ0IjoiZG0ifQ#key-3", "type": "Ed25519VerificationKey2018", - "controller": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0", + "controller": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InVyaSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyb3V0aW5nS2V5cyI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJhY2NlcHQiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjNTg3Il19LCJ0IjoiZG0ifQ", "publicKeyBase58": "3M5RCDjPTWPkKSN3sxUmmMqHbmRPegYP1tjcKyrDbt9J" } ], "keyAgreement": [ { - "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0#key-2", + "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InVyaSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyb3V0aW5nS2V5cyI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJhY2NlcHQiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjNTg3Il19LCJ0IjoiZG0ifQ#key-2", "type": "X25519KeyAgreementKey2019", - "controller": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0", + "controller": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InVyaSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyb3V0aW5nS2V5cyI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJhY2NlcHQiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjNTg3Il19LCJ0IjoiZG0ifQ", "publicKeyBase58": "JhNWeSVLMYccCk7iopQW4guaSJTojqpMEELgSLhKwRr" } ], "service": [ { - "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0#didcommmessaging-0", + "id": "did:peer:2.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InVyaSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyb3V0aW5nS2V5cyI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJhY2NlcHQiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjNTg3Il19LCJ0IjoiZG0ifQ#didcommmessaging-0", "type": "DIDCommMessaging", - "serviceEndpoint": "https://example.com/endpoint", - "routingKeys": ["did:example:somemediator#somekey"], - "accept": ["didcomm/v2", "didcomm/aip2;env=rfc587"] + "serviceEndpoint": { + "uri": "https://example.com/endpoint", + "routingKeys": ["did:example:somemediator#somekey"], + "accept": ["didcomm/v2", "didcomm/aip2;env=rfc587"] + } } ] } diff --git a/packages/core/src/modules/dids/methods/peer/__tests__/__fixtures__/didPeer2Ez6LSe3YyteKQAcaPy.json b/packages/core/src/modules/dids/methods/peer/__tests__/__fixtures__/didPeer2Ez6LSe3YyteKQAcaPy.json new file mode 100644 index 0000000000..306a153c92 --- /dev/null +++ b/packages/core/src/modules/dids/methods/peer/__tests__/__fixtures__/didPeer2Ez6LSe3YyteKQAcaPy.json @@ -0,0 +1,52 @@ +{ + "@context": ["https://w3id.org/did/v1"], + "id": "did:peer:2.Ez6LSe3YyteKQVXSgGfZyCzbLq9K34zjAfap4EuaWJjbo5Gwk.Vz6MkvLvjZVc9jWJVs8M3qNZeRsnXXZGFjzcRJDH9vvdJMgHB.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdfX0.SeyJzIjogImh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsICJhIjogWyJkaWRjb21tL2FpcDEiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzE5Il0sICJyZWNpcGllbnRLZXlzIjogWyIja2V5LTIiXSwgInQiOiAiZGlkLWNvbW11bmljYXRpb24ifQ.SeyJzIjogIndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwgImEiOiBbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwgInJlY2lwaWVudEtleXMiOiBbIiNrZXktMiJdLCAidCI6ICJkaWQtY29tbXVuaWNhdGlvbiJ9", + "service": [ + { + "type": "DIDCommMessaging", + "serviceEndpoint": { + "uri": "https://us-east.proven.mediator.indiciotech.io/message", + "accept": ["didcomm/v2", "didcomm/aip2;env=rfc19"] + }, + "id": "did:peer:2.Ez6LSe3YyteKQVXSgGfZyCzbLq9K34zjAfap4EuaWJjbo5Gwk.Vz6MkvLvjZVc9jWJVs8M3qNZeRsnXXZGFjzcRJDH9vvdJMgHB.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdfX0.SeyJzIjogImh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsICJhIjogWyJkaWRjb21tL2FpcDEiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzE5Il0sICJyZWNpcGllbnRLZXlzIjogWyIja2V5LTIiXSwgInQiOiAiZGlkLWNvbW11bmljYXRpb24ifQ.SeyJzIjogIndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwgImEiOiBbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwgInJlY2lwaWVudEtleXMiOiBbIiNrZXktMiJdLCAidCI6ICJkaWQtY29tbXVuaWNhdGlvbiJ9#didcommmessaging-0" + }, + { + "type": "DIDCommMessaging", + "serviceEndpoint": { + "uri": "wss://ws.us-east.proven.mediator.indiciotech.io/ws", + "accept": ["didcomm/v2", "didcomm/aip2;env=rfc19"] + }, + "id": "did:peer:2.Ez6LSe3YyteKQVXSgGfZyCzbLq9K34zjAfap4EuaWJjbo5Gwk.Vz6MkvLvjZVc9jWJVs8M3qNZeRsnXXZGFjzcRJDH9vvdJMgHB.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdfX0.SeyJzIjogImh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsICJhIjogWyJkaWRjb21tL2FpcDEiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzE5Il0sICJyZWNpcGllbnRLZXlzIjogWyIja2V5LTIiXSwgInQiOiAiZGlkLWNvbW11bmljYXRpb24ifQ.SeyJzIjogIndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwgImEiOiBbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwgInJlY2lwaWVudEtleXMiOiBbIiNrZXktMiJdLCAidCI6ICJkaWQtY29tbXVuaWNhdGlvbiJ9#didcommmessaging-1" + }, + { + "serviceEndpoint": "https://us-east.proven.mediator.indiciotech.io/message", + "accept": ["didcomm/aip1", "didcomm/aip2;env=rfc19"], + "recipientKeys": ["#key-2"], + "type": "did-communication", + "id": "did:peer:2.Ez6LSe3YyteKQVXSgGfZyCzbLq9K34zjAfap4EuaWJjbo5Gwk.Vz6MkvLvjZVc9jWJVs8M3qNZeRsnXXZGFjzcRJDH9vvdJMgHB.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdfX0.SeyJzIjogImh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsICJhIjogWyJkaWRjb21tL2FpcDEiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzE5Il0sICJyZWNpcGllbnRLZXlzIjogWyIja2V5LTIiXSwgInQiOiAiZGlkLWNvbW11bmljYXRpb24ifQ.SeyJzIjogIndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwgImEiOiBbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwgInJlY2lwaWVudEtleXMiOiBbIiNrZXktMiJdLCAidCI6ICJkaWQtY29tbXVuaWNhdGlvbiJ9#did-communication-2" + }, + { + "serviceEndpoint": "wss://ws.us-east.proven.mediator.indiciotech.io/ws", + "accept": ["didcomm/aip1", "didcomm/aip2;env=rfc19"], + "recipientKeys": ["#key-2"], + "type": "did-communication", + "id": "did:peer:2.Ez6LSe3YyteKQVXSgGfZyCzbLq9K34zjAfap4EuaWJjbo5Gwk.Vz6MkvLvjZVc9jWJVs8M3qNZeRsnXXZGFjzcRJDH9vvdJMgHB.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdfX0.SeyJzIjogImh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsICJhIjogWyJkaWRjb21tL2FpcDEiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzE5Il0sICJyZWNpcGllbnRLZXlzIjogWyIja2V5LTIiXSwgInQiOiAiZGlkLWNvbW11bmljYXRpb24ifQ.SeyJzIjogIndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwgImEiOiBbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwgInJlY2lwaWVudEtleXMiOiBbIiNrZXktMiJdLCAidCI6ICJkaWQtY29tbXVuaWNhdGlvbiJ9#did-communication-3" + } + ], + "authentication": [ + { + "id": "did:peer:2.Ez6LSe3YyteKQVXSgGfZyCzbLq9K34zjAfap4EuaWJjbo5Gwk.Vz6MkvLvjZVc9jWJVs8M3qNZeRsnXXZGFjzcRJDH9vvdJMgHB.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdfX0.SeyJzIjogImh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsICJhIjogWyJkaWRjb21tL2FpcDEiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzE5Il0sICJyZWNpcGllbnRLZXlzIjogWyIja2V5LTIiXSwgInQiOiAiZGlkLWNvbW11bmljYXRpb24ifQ.SeyJzIjogIndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwgImEiOiBbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwgInJlY2lwaWVudEtleXMiOiBbIiNrZXktMiJdLCAidCI6ICJkaWQtY29tbXVuaWNhdGlvbiJ9#key-2", + "type": "Ed25519VerificationKey2018", + "controller": "did:peer:2.Ez6LSe3YyteKQVXSgGfZyCzbLq9K34zjAfap4EuaWJjbo5Gwk.Vz6MkvLvjZVc9jWJVs8M3qNZeRsnXXZGFjzcRJDH9vvdJMgHB.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdfX0.SeyJzIjogImh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsICJhIjogWyJkaWRjb21tL2FpcDEiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzE5Il0sICJyZWNpcGllbnRLZXlzIjogWyIja2V5LTIiXSwgInQiOiAiZGlkLWNvbW11bmljYXRpb24ifQ.SeyJzIjogIndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwgImEiOiBbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwgInJlY2lwaWVudEtleXMiOiBbIiNrZXktMiJdLCAidCI6ICJkaWQtY29tbXVuaWNhdGlvbiJ9", + "publicKeyBase58": "GtfgyFMiPxp2kdWM9oboanEXhyzQL7N4cCNE6efHSTVo" + } + ], + "keyAgreement": [ + { + "id": "did:peer:2.Ez6LSe3YyteKQVXSgGfZyCzbLq9K34zjAfap4EuaWJjbo5Gwk.Vz6MkvLvjZVc9jWJVs8M3qNZeRsnXXZGFjzcRJDH9vvdJMgHB.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdfX0.SeyJzIjogImh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsICJhIjogWyJkaWRjb21tL2FpcDEiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzE5Il0sICJyZWNpcGllbnRLZXlzIjogWyIja2V5LTIiXSwgInQiOiAiZGlkLWNvbW11bmljYXRpb24ifQ.SeyJzIjogIndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwgImEiOiBbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwgInJlY2lwaWVudEtleXMiOiBbIiNrZXktMiJdLCAidCI6ICJkaWQtY29tbXVuaWNhdGlvbiJ9#key-1", + "type": "X25519KeyAgreementKey2019", + "controller": "did:peer:2.Ez6LSe3YyteKQVXSgGfZyCzbLq9K34zjAfap4EuaWJjbo5Gwk.Vz6MkvLvjZVc9jWJVs8M3qNZeRsnXXZGFjzcRJDH9vvdJMgHB.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmMxOSJdfX0.SeyJzIjogImh0dHBzOi8vdXMtZWFzdC5wcm92ZW4ubWVkaWF0b3IuaW5kaWNpb3RlY2guaW8vbWVzc2FnZSIsICJhIjogWyJkaWRjb21tL2FpcDEiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzE5Il0sICJyZWNpcGllbnRLZXlzIjogWyIja2V5LTIiXSwgInQiOiAiZGlkLWNvbW11bmljYXRpb24ifQ.SeyJzIjogIndzczovL3dzLnVzLWVhc3QucHJvdmVuLm1lZGlhdG9yLmluZGljaW90ZWNoLmlvL3dzIiwgImEiOiBbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwgInJlY2lwaWVudEtleXMiOiBbIiNrZXktMiJdLCAidCI6ICJkaWQtY29tbXVuaWNhdGlvbiJ9", + "publicKeyBase58": "3NNpNLWYQ4iwBHCCgM5PWZ6ZDrC3xyduMvrppGxGMuAz" + } + ] +} diff --git a/packages/core/src/modules/dids/methods/peer/__tests__/peerDidNumAlgo2.test.ts b/packages/core/src/modules/dids/methods/peer/__tests__/peerDidNumAlgo2.test.ts index e34ddc68b0..2ae2b24b03 100644 --- a/packages/core/src/modules/dids/methods/peer/__tests__/peerDidNumAlgo2.test.ts +++ b/packages/core/src/modules/dids/methods/peer/__tests__/peerDidNumAlgo2.test.ts @@ -1,6 +1,7 @@ import { JsonTransformer } from '../../../../../utils' import { OutOfBandDidCommService } from '../../../../oob/domain/OutOfBandDidCommService' import { DidDocument } from '../../../domain' +import { isValidPeerDid } from '../didPeer' import { didToNumAlgo2DidDocument, didDocumentToNumAlgo2Did, @@ -11,6 +12,7 @@ import { import didPeer2Ez6L from './__fixtures__/didPeer2Ez6L.json' import didPeer2Ez6LMoreServices from './__fixtures__/didPeer2Ez6LMoreServices.json' import didPeer2Ez6LMultipleServicesSingleToken from './__fixtures__/didPeer2Ez6LMultipleServicesSingleToken.json' +import didPeer2Ez6LSe3YyteKQAcaPy from './__fixtures__/didPeer2Ez6LSe3YyteKQAcaPy.json' describe('peerDidNumAlgo2', () => { describe('didToNumAlgo2DidDocument', () => { @@ -25,6 +27,11 @@ describe('peerDidNumAlgo2', () => { didPeer2Ez6LMultipleServicesSingleToken ) }) + + test('transforms method 2 peer did created by aca-py to a did document', async () => { + expect(isValidPeerDid(didPeer2Ez6LSe3YyteKQAcaPy.id)).toEqual(true) + expect(didToNumAlgo2DidDocument(didPeer2Ez6LSe3YyteKQAcaPy.id).toJSON()).toEqual(didPeer2Ez6LSe3YyteKQAcaPy) + }) }) describe('didDocumentToNumAlgo2Did', () => { diff --git a/packages/core/src/modules/dids/methods/peer/didPeer.ts b/packages/core/src/modules/dids/methods/peer/didPeer.ts index fb8aee487e..7e4b164888 100644 --- a/packages/core/src/modules/dids/methods/peer/didPeer.ts +++ b/packages/core/src/modules/dids/methods/peer/didPeer.ts @@ -3,7 +3,7 @@ import { CredoError } from '../../../../error' import { getAlternativeDidsForNumAlgo4Did } from './peerDidNumAlgo4' const PEER_DID_REGEX = new RegExp( - '^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=]*)?))|([4](z[1-9a-km-zA-HJ-NP-Z]{46})(:z[1-9a-km-zA-HJ-NP-Z]{6,}){0,1}))$' + '^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=]*)*))|([4](z[1-9a-km-zA-HJ-NP-Z]{46})(:z[1-9a-km-zA-HJ-NP-Z]{6,}){0,1}))$' ) export function isValidPeerDid(did: string): boolean { diff --git a/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo2.ts b/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo2.ts index fafefb8e50..a12801af84 100644 --- a/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo2.ts +++ b/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo2.ts @@ -210,14 +210,31 @@ export function outOfBandServiceToInlineKeysNumAlgo2Did(service: OutOfBandDidCom function expandServiceAbbreviations(service: JsonObject) { const expand = (abbreviated: string) => didPeerExpansions[abbreviated] ?? abbreviated + const expandJson = (json: unknown): unknown => { + if (!json) return json + if (typeof json === 'number') return json + if (typeof json === 'string') return expand(json) + if (Array.isArray(json)) return json.map(expandJson) + if (typeof json === 'object') + return Object.entries(json as Record).reduce( + (jsonBody, [key, value]) => ({ + ...jsonBody, + [expand(key)]: expandJson(value), + }), + {} + ) + } - const fullService = Object.entries(service).reduce( - (serviceBody, [key, value]) => ({ - ...serviceBody, - [expand(key)]: expand(value as string), - }), - {} - ) + const fullService = expandJson(service) as Record + + // Handle the case where a legacy DIDComm v2 service has been encoded in the did:peer:2. + // We use the legacy `DIDComm` type (over `DIDCommMessaging`) + if ('t' in service && service.t === 'dm' && typeof service.serviceEndpoint === 'string') { + return { + ...fullService, + type: 'DIDComm', + } + } return fullService } diff --git a/packages/core/src/modules/oob/__tests__/implicit.test.ts b/packages/core/src/modules/oob/__tests__/implicit.test.ts index f2e028ff96..96eaab7a4c 100644 --- a/packages/core/src/modules/oob/__tests__/implicit.test.ts +++ b/packages/core/src/modules/oob/__tests__/implicit.test.ts @@ -8,11 +8,12 @@ import { DidExchangeState, HandshakeProtocol } from '../../connections' import { InMemoryDidRegistry } from '../../connections/__tests__/InMemoryDidRegistry' import { DidCommV1Service, - DidCommV2Service, + NewDidCommV2Service, DidDocumentService, DidDocumentBuilder, getEd25519VerificationKey2018, DidsModule, + NewDidCommV2ServiceEndpoint, } from '../../dids' const inMemoryDidsRegistry = new InMemoryDidRegistry() @@ -265,11 +266,13 @@ async function createInMemoryDid(agent: Agent, endpoint: string) { ) builder.addService( - new DidCommV2Service({ - accept: ['didcomm/v2'], - id: `${did}#didcomm-1`, - routingKeys: [], - serviceEndpoint: endpoint, + new NewDidCommV2Service({ + id: `${did}#didcomm-messaging-1`, + serviceEndpoint: new NewDidCommV2ServiceEndpoint({ + accept: ['didcomm/v2'], + routingKeys: [], + uri: endpoint, + }), }) ) diff --git a/packages/core/src/modules/oob/domain/OutOfBandDidCommService.ts b/packages/core/src/modules/oob/domain/OutOfBandDidCommService.ts index 8c747523f1..e40759d007 100644 --- a/packages/core/src/modules/oob/domain/OutOfBandDidCommService.ts +++ b/packages/core/src/modules/oob/domain/OutOfBandDidCommService.ts @@ -3,7 +3,7 @@ import type { ValidationOptions } from 'class-validator' import { ArrayNotEmpty, buildMessage, IsOptional, isString, IsString, ValidateBy } from 'class-validator' -import { isDid } from '../../../utils' +import { isDid, IsUri } from '../../../utils' import { DidDocumentService, DidKey } from '../../dids' export class OutOfBandDidCommService extends DidDocumentService { @@ -25,6 +25,10 @@ export class OutOfBandDidCommService extends DidDocumentService { public static type = 'did-communication' + @IsString() + @IsUri() + public serviceEndpoint!: string + @ArrayNotEmpty() @IsDidKeyString({ each: true }) public recipientKeys!: string[] diff --git a/packages/indy-vdr/src/dids/IndyVdrIndyDidRegistrar.ts b/packages/indy-vdr/src/dids/IndyVdrIndyDidRegistrar.ts index f46d071a11..01752cc8cc 100644 --- a/packages/indy-vdr/src/dids/IndyVdrIndyDidRegistrar.ts +++ b/packages/indy-vdr/src/dids/IndyVdrIndyDidRegistrar.ts @@ -17,7 +17,7 @@ import type { IndyVdrRequest } from '@hyperledger/indy-vdr-shared' import { parseIndyDid } from '@credo-ts/anoncreds' import { DidCommV1Service, - DidCommV2Service, + NewDidCommV2Service, DidDocumentRole, DidRecord, DidRepository, @@ -25,6 +25,7 @@ import { IndyAgentService, Key, KeyType, + DidCommV2Service, TypedArrayEncoder, } from '@credo-ts/core' import { AttribRequest, CustomRequest, NymRequest } from '@hyperledger/indy-vdr-shared' @@ -231,7 +232,7 @@ export class IndyVdrIndyDidRegistrar implements DidRegistrar { didDocumentBuilder.addService(item) }) - const commTypes = [IndyAgentService.type, DidCommV1Service.type, DidCommV2Service.type] + const commTypes = [IndyAgentService.type, DidCommV1Service.type, NewDidCommV2Service.type, DidCommV2Service.type] const serviceTypes = new Set(services.map((item) => item.type)) const keyAgreementId = `${did}#key-agreement-1` @@ -249,8 +250,9 @@ export class IndyVdrIndyDidRegistrar implements DidRegistrar { .addKeyAgreement(keyAgreementId) } + // FIXME: it doesn't seem this context exists? // If there is a DIDComm V2 service, add context - if (serviceTypes.has(DidCommV2Service.type)) { + if (serviceTypes.has(NewDidCommV2Service.type) || serviceTypes.has(DidCommV2Service.type)) { didDocumentBuilder.addContext('https://didcomm.org/messaging/contexts/v2') } diff --git a/packages/indy-vdr/src/dids/__tests__/IndyVdrIndyDidRegistrar.test.ts b/packages/indy-vdr/src/dids/__tests__/IndyVdrIndyDidRegistrar.test.ts index cb8617a210..136ae0b3a8 100644 --- a/packages/indy-vdr/src/dids/__tests__/IndyVdrIndyDidRegistrar.test.ts +++ b/packages/indy-vdr/src/dids/__tests__/IndyVdrIndyDidRegistrar.test.ts @@ -3,7 +3,7 @@ import type { DidRecord, RecordSavedEvent } from '@credo-ts/core' import { DidCommV1Service, - DidCommV2Service, + NewDidCommV2Service, DidDocumentService, DidDocument, DidDocumentRole, @@ -16,6 +16,7 @@ import { RepositoryEventTypes, TypedArrayEncoder, VerificationMethod, + NewDidCommV2ServiceEndpoint, } from '@credo-ts/core' import { Subject } from 'rxjs' @@ -381,11 +382,13 @@ describe('IndyVdrIndyDidRegistrar', () => { serviceEndpoint: 'https://example.com/endpoint', accept: ['didcomm/aip2;env=rfc19'], }), - new DidCommV2Service({ - accept: ['didcomm/v2'], - id: `#didcomm-1`, - routingKeys: ['key-1'], - serviceEndpoint: 'https://example.com/endpoint', + new NewDidCommV2Service({ + id: `#didcomm-messaging-1`, + serviceEndpoint: new NewDidCommV2ServiceEndpoint({ + accept: ['didcomm/v2'], + routingKeys: ['key-1'], + uri: 'https://example.com/endpoint', + }), }), ], }, @@ -424,11 +427,13 @@ describe('IndyVdrIndyDidRegistrar', () => { type: 'did-communication', }, { - accept: ['didcomm/v2'], - id: 'did:indy:pool1:B6xaJg1c2xU3D9ppCtt1CZ#didcomm-1', - routingKeys: ['key-1'], - serviceEndpoint: 'https://example.com/endpoint', - type: 'DIDComm', + id: 'did:indy:pool1:B6xaJg1c2xU3D9ppCtt1CZ#didcomm-messaging-1', + serviceEndpoint: { + uri: 'https://example.com/endpoint', + accept: ['didcomm/v2'], + routingKeys: ['key-1'], + }, + type: 'DIDCommMessaging', }, ], verificationMethod: [ @@ -493,11 +498,13 @@ describe('IndyVdrIndyDidRegistrar', () => { accept: ['didcomm/aip2;env=rfc19'], }, { - id: 'did:indy:pool1:B6xaJg1c2xU3D9ppCtt1CZ#didcomm-1', - serviceEndpoint: 'https://example.com/endpoint', - type: 'DIDComm', - routingKeys: ['key-1'], - accept: ['didcomm/v2'], + id: 'did:indy:pool1:B6xaJg1c2xU3D9ppCtt1CZ#didcomm-messaging-1', + type: 'DIDCommMessaging', + serviceEndpoint: { + uri: 'https://example.com/endpoint', + routingKeys: ['key-1'], + accept: ['didcomm/v2'], + }, }, ], authentication: ['did:indy:pool1:B6xaJg1c2xU3D9ppCtt1CZ#verkey'], @@ -562,11 +569,13 @@ describe('IndyVdrIndyDidRegistrar', () => { serviceEndpoint: 'https://example.com/endpoint', accept: ['didcomm/aip2;env=rfc19'], }), - new DidCommV2Service({ - accept: ['didcomm/v2'], - id: `#didcomm-1`, - routingKeys: ['key-1'], - serviceEndpoint: 'https://example.com/endpoint', + new NewDidCommV2Service({ + id: `#didcomm-messaging-1`, + serviceEndpoint: new NewDidCommV2ServiceEndpoint({ + accept: ['didcomm/v2'], + routingKeys: ['key-1'], + uri: 'https://example.com/endpoint', + }), }), ], }, @@ -574,6 +583,7 @@ describe('IndyVdrIndyDidRegistrar', () => { privateKey, }, }) + expect(result.didState.state).toEqual('finished') expect(createRegisterDidWriteRequestSpy).toHaveBeenCalledWith({ agentContext, @@ -603,7 +613,7 @@ describe('IndyVdrIndyDidRegistrar', () => { endpoints: { endpoint: 'https://example.com/endpoint', routingKeys: ['key-1'], - types: ['endpoint', 'did-communication', 'DIDComm'], + types: ['endpoint', 'did-communication', 'DIDCommMessaging'], }, }) expect(setEndpointsForDidSpy).not.toHaveBeenCalled() @@ -651,11 +661,9 @@ describe('IndyVdrIndyDidRegistrar', () => { accept: ['didcomm/aip2;env=rfc19'], }, { - id: 'did:indy:pool1:B6xaJg1c2xU3D9ppCtt1CZ#didcomm-1', - serviceEndpoint: 'https://example.com/endpoint', - type: 'DIDComm', - routingKeys: ['key-1'], - accept: ['didcomm/v2'], + id: 'did:indy:pool1:B6xaJg1c2xU3D9ppCtt1CZ#didcomm-messaging-1', + type: 'DIDCommMessaging', + serviceEndpoint: { uri: 'https://example.com/endpoint', routingKeys: ['key-1'], accept: ['didcomm/v2'] }, }, ], authentication: ['did:indy:pool1:B6xaJg1c2xU3D9ppCtt1CZ#verkey'], @@ -714,11 +722,13 @@ describe('IndyVdrIndyDidRegistrar', () => { serviceEndpoint: 'https://example.com/endpoint', accept: ['didcomm/aip2;env=rfc19'], }), - new DidCommV2Service({ - accept: ['didcomm/v2'], - id: `#didcomm-1`, - routingKeys: ['key-1'], - serviceEndpoint: 'https://example.com/endpoint', + new NewDidCommV2Service({ + id: `#didcomm-messaging-1`, + serviceEndpoint: new NewDidCommV2ServiceEndpoint({ + accept: ['didcomm/v2'], + routingKeys: ['key-1'], + uri: 'https://example.com/endpoint', + }), }), ], }, diff --git a/packages/indy-vdr/src/dids/didSovUtil.ts b/packages/indy-vdr/src/dids/didSovUtil.ts index c2bd6cdc6a..aa52580bb2 100644 --- a/packages/indy-vdr/src/dids/didSovUtil.ts +++ b/packages/indy-vdr/src/dids/didSovUtil.ts @@ -3,12 +3,15 @@ import { DidDocumentService, DidDocumentBuilder, DidCommV1Service, - DidCommV2Service, + NewDidCommV2Service, convertPublicKeyToX25519, CredoError, + Buffer, + NewDidCommV2ServiceEndpoint, + DidCommV2Service, } from '@credo-ts/core' -export type CommEndpointType = 'endpoint' | 'did-communication' | 'DIDComm' +export type CommEndpointType = 'endpoint' | 'did-communication' | 'DIDComm' | 'DIDCommMessaging' export interface IndyEndpointAttrib { endpoint?: string @@ -88,7 +91,7 @@ export function sovDidDocumentFromDid(fullDid: string, verkey: string) { // Process Indy Attrib Endpoint Types according to: https://sovrin-foundation.github.io/sovrin/spec/did-method-spec-template.html > Read (Resolve) > DID Service Endpoint function processEndpointTypes(types?: string[]) { - const expectedTypes = ['endpoint', 'did-communication', 'DIDComm'] + const expectedTypes = ['endpoint', 'did-communication', 'DIDComm', 'DIDCommMessaging'] const defaultTypes = ['endpoint', 'did-communication'] // Return default types if types "is NOT present [or] empty" @@ -108,11 +111,26 @@ function processEndpointTypes(types?: string[]) { } export function endpointsAttribFromServices(services: DidDocumentService[]): IndyEndpointAttrib { - const commTypes: CommEndpointType[] = ['endpoint', 'did-communication', 'DIDComm'] + const commTypes: CommEndpointType[] = ['endpoint', 'did-communication', 'DIDComm', 'DIDCommMessaging'] const commServices = services.filter((item) => commTypes.includes(item.type as CommEndpointType)) + const endpoint = + commServices[0] instanceof NewDidCommV2Service + ? commServices[0].firstServiceEndpointUri + : commServices[0].serviceEndpoint + + if (typeof endpoint !== 'string') { + throw new CredoError( + `For unknown service endpoint types (${commServices[0].type}) the 'serviceEndpoint' needs to be of type 'string'` + ) + } + // Check that all services use the same endpoint, as only one is accepted - if (!commServices.every((item) => item.serviceEndpoint === services[0].serviceEndpoint)) { + if ( + !commServices.every( + (item) => (item instanceof NewDidCommV2Service ? item.firstServiceEndpointUri : item.serviceEndpoint) === endpoint + ) + ) { throw new CredoError('serviceEndpoint for all services must match') } @@ -132,10 +150,16 @@ export function endpointsAttribFromServices(services: DidDocumentService[]): Ind commService.routingKeys ) { commService.routingKeys.forEach((item) => routingKeys.add(item)) + } else if (commService instanceof NewDidCommV2Service) { + const firstServiceEndpoint = Array.isArray(commService.serviceEndpoint) + ? commService.serviceEndpoint[0] + : commService.serviceEndpoint + + firstServiceEndpoint.routingKeys?.forEach((item) => routingKeys.add(item)) } } - return { endpoint: services[0].serviceEndpoint, types, routingKeys: Array.from(routingKeys) } + return { endpoint, types, routingKeys: Array.from(routingKeys) } } export function addServicesFromEndpointsAttrib( @@ -172,21 +196,36 @@ export function addServicesFromEndpointsAttrib( accept: ['didcomm/aip2;env=rfc19'], }) ) + } - // If 'DIDComm' included in types, add DIDComm v2 entry - // TODO: should it be DIDComm or DIDCommMessaging? (see https://github.com/sovrin-foundation/sovrin/issues/343) - if (processedTypes.includes('DIDComm')) { - builder - .addService( - new DidCommV2Service({ - id: `${did}#didcomm-1`, - serviceEndpoint: endpoint, - routingKeys: routingKeys ?? [], + // If 'DIDCommMessaging' included in types, add DIDComm v2 entry + if (processedTypes.includes('DIDCommMessaging')) { + builder + .addService( + new NewDidCommV2Service({ + id: `${did}#didcomm-messaging-1`, + serviceEndpoint: new NewDidCommV2ServiceEndpoint({ + uri: endpoint, + routingKeys: routingKeys, accept: ['didcomm/v2'], - }) - ) - .addContext('https://didcomm.org/messaging/contexts/v2') - } + }), + }) + ) + .addContext('https://didcomm.org/messaging/contexts/v2') + } + + // If 'DIDComm' included in types, add legacy DIDComm v2 entry + if (processedTypes.includes('DIDComm')) { + builder + .addService( + new DidCommV2Service({ + id: `${did}#didcomm-1`, + routingKeys: routingKeys, + accept: ['didcomm/v2'], + serviceEndpoint: endpoint, + }) + ) + .addContext('https://didcomm.org/messaging/contexts/v2') } } diff --git a/packages/indy-vdr/tests/helpers.ts b/packages/indy-vdr/tests/helpers.ts index bb8c1fc4b2..992cfdfc4b 100644 --- a/packages/indy-vdr/tests/helpers.ts +++ b/packages/indy-vdr/tests/helpers.ts @@ -1,7 +1,13 @@ import type { IndyVdrDidCreateOptions } from '../src/dids/IndyVdrIndyDidRegistrar' import type { Agent } from '@credo-ts/core' -import { DidCommV1Service, DidCommV2Service, DidDocumentService, KeyType } from '@credo-ts/core' +import { + DidCommV1Service, + NewDidCommV2Service, + DidDocumentService, + KeyType, + NewDidCommV2ServiceEndpoint, +} from '@credo-ts/core' import { indyVdr } from '@hyperledger/indy-vdr-nodejs' import { sleep } from '../../core/src/utils/sleep' @@ -46,11 +52,13 @@ export async function createDidOnLedger(agent: Agent, endorserDid: string) { serviceEndpoint: 'http://localhost:3000', accept: ['didcomm/aip2;env=rfc19'], }), - new DidCommV2Service({ - accept: ['didcomm/v2'], - id: `#didcomm-1`, - routingKeys: ['a-routing-key'], - serviceEndpoint: 'http://localhost:3000', + new NewDidCommV2Service({ + id: `#didcomm--messaging-1`, + serviceEndpoint: new NewDidCommV2ServiceEndpoint({ + accept: ['didcomm/v2'], + routingKeys: ['a-routing-key'], + uri: 'http://localhost:3000', + }), }), ], }, diff --git a/packages/indy-vdr/tests/indy-vdr-did-registrar.e2e.test.ts b/packages/indy-vdr/tests/indy-vdr-did-registrar.e2e.test.ts index 9cd8063c7e..dc5521653c 100644 --- a/packages/indy-vdr/tests/indy-vdr-did-registrar.e2e.test.ts +++ b/packages/indy-vdr/tests/indy-vdr-did-registrar.e2e.test.ts @@ -7,10 +7,11 @@ import { KeyType, TypedArrayEncoder, DidCommV1Service, - DidCommV2Service, + NewDidCommV2Service, DidDocumentService, Agent, DidsModule, + NewDidCommV2ServiceEndpoint, } from '@credo-ts/core' import { indyVdr } from '@hyperledger/indy-vdr-nodejs' import { convertPublicKeyToX25519, generateKeyPairFromSeed } from '@stablelib/ed25519' @@ -378,11 +379,13 @@ describe('Indy VDR Indy Did Registrar', () => { serviceEndpoint: 'https://example.com/endpoint', accept: ['didcomm/aip2;env=rfc19'], }), - new DidCommV2Service({ - accept: ['didcomm/v2'], - id: `${did}#didcomm-1`, - routingKeys: ['a-routing-key'], - serviceEndpoint: 'https://example.com/endpoint', + new NewDidCommV2Service({ + id: `${did}#didcomm-messaging-1`, + serviceEndpoint: new NewDidCommV2ServiceEndpoint({ + accept: ['didcomm/v2'], + routingKeys: ['a-routing-key'], + uri: 'https://example.com/endpoint', + }), }), ], }, @@ -431,11 +434,13 @@ describe('Indy VDR Indy Did Registrar', () => { type: 'did-communication', }, { - accept: ['didcomm/v2'], - id: `${did}#didcomm-1`, - routingKeys: ['a-routing-key'], - serviceEndpoint: 'https://example.com/endpoint', - type: 'DIDComm', + id: `${did}#didcomm-messaging-1`, + serviceEndpoint: { + uri: 'https://example.com/endpoint', + accept: ['didcomm/v2'], + routingKeys: ['a-routing-key'], + }, + type: 'DIDCommMessaging', }, ], } @@ -500,11 +505,13 @@ describe('Indy VDR Indy Did Registrar', () => { serviceEndpoint: 'https://example.com/endpoint', accept: ['didcomm/aip2;env=rfc19'], }), - new DidCommV2Service({ - accept: ['didcomm/v2'], - id: `${did}#didcomm-1`, - routingKeys: ['a-routing-key'], - serviceEndpoint: 'https://example.com/endpoint', + new NewDidCommV2Service({ + id: `${did}#didcomm-messaging-1`, + serviceEndpoint: new NewDidCommV2ServiceEndpoint({ + accept: ['didcomm/v2'], + routingKeys: ['a-routing-key'], + uri: 'https://example.com/endpoint', + }), }), ], }, @@ -579,11 +586,13 @@ describe('Indy VDR Indy Did Registrar', () => { type: 'did-communication', }, { - accept: ['didcomm/v2'], - id: `${did}#didcomm-1`, - routingKeys: ['a-routing-key'], - serviceEndpoint: 'https://example.com/endpoint', - type: 'DIDComm', + id: `${did}#didcomm-messaging-1`, + serviceEndpoint: { + uri: 'https://example.com/endpoint', + routingKeys: ['a-routing-key'], + accept: ['didcomm/v2'], + }, + type: 'DIDCommMessaging', }, ], } diff --git a/packages/indy-vdr/tests/indy-vdr-indy-did-resolver.e2e.test.ts b/packages/indy-vdr/tests/indy-vdr-indy-did-resolver.e2e.test.ts index c0461fe114..b5386cfe79 100644 --- a/packages/indy-vdr/tests/indy-vdr-indy-did-resolver.e2e.test.ts +++ b/packages/indy-vdr/tests/indy-vdr-indy-did-resolver.e2e.test.ts @@ -125,11 +125,9 @@ describe('indy-vdr DID Resolver E2E', () => { type: 'did-communication', }, { - id: `${did}#didcomm-1`, - accept: ['didcomm/v2'], - routingKeys: ['a-routing-key'], - serviceEndpoint: 'http://localhost:3000', - type: 'DIDComm', + id: `${did}#didcomm-messaging-1`, + serviceEndpoint: { uri: 'http://localhost:3000', accept: ['didcomm/v2'], routingKeys: ['a-routing-key'] }, + type: 'DIDCommMessaging', }, ], }, diff --git a/packages/indy-vdr/tests/indy-vdr-sov-did-resolver.e2e.test.ts b/packages/indy-vdr/tests/indy-vdr-sov-did-resolver.e2e.test.ts index 2088c50d51..427ff542f0 100644 --- a/packages/indy-vdr/tests/indy-vdr-sov-did-resolver.e2e.test.ts +++ b/packages/indy-vdr/tests/indy-vdr-sov-did-resolver.e2e.test.ts @@ -137,11 +137,9 @@ describe('Indy VDR Sov DID Resolver', () => { type: 'did-communication', }, { - id: `${sovDid}#didcomm-1`, - accept: ['didcomm/v2'], - routingKeys: ['a-routing-key'], - serviceEndpoint: 'http://localhost:3000', - type: 'DIDComm', + id: `${sovDid}#didcomm-messaging-1`, + serviceEndpoint: { uri: 'http://localhost:3000', routingKeys: ['a-routing-key'], accept: ['didcomm/v2'] }, + type: 'DIDCommMessaging', }, ], },