@credo-ts/core
Version:
<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1
1 lines • 11.8 kB
Source Map (JSON)
{"version":3,"file":"peerDidNumAlgo2.mjs","names":[],"sources":["../../../../../src/modules/dids/methods/peer/peerDidNumAlgo2.ts"],"sourcesContent":["import { CredoError } from '../../../../error'\nimport type { JsonObject } from '../../../../types'\nimport { JsonEncoder, JsonTransformer } from '../../../../utils'\nimport { PublicJwk } from '../../../kms'\nimport type { DidDocument, DidPurpose, VerificationMethod } from '../../domain'\nimport { DidDocumentService } from '../../domain'\nimport { DidDocumentBuilder } from '../../domain/DidDocumentBuilder'\nimport {\n getPublicJwkFromVerificationMethod,\n getVerificationMethodsForPublicJwk,\n} from '../../domain/key-type/keyDidMapping'\nimport { parseDid } from '../../domain/parse'\n\nenum DidPeerPurpose {\n Assertion = 'A',\n Encryption = 'E',\n Verification = 'V',\n CapabilityInvocation = 'I',\n CapabilityDelegation = 'D',\n Service = 'S',\n}\n\nfunction isDidPeerKeyPurpose(purpose: string): purpose is Exclude<DidPeerPurpose, DidPeerPurpose.Service> {\n return purpose !== DidPeerPurpose.Service && Object.values(DidPeerPurpose).includes(purpose as DidPeerPurpose)\n}\n\nconst didPeerAbbreviations: { [key: string]: string | undefined } = {\n type: 't',\n DIDCommMessaging: 'dm',\n serviceEndpoint: 's',\n routingKeys: 'r',\n accept: 'a',\n}\n\nconst didPeerExpansions: { [key: string]: string | undefined } = {\n t: 'type',\n dm: 'DIDCommMessaging',\n s: 'serviceEndpoint',\n r: 'routingKeys',\n a: 'accept',\n}\n\nexport function didToNumAlgo2DidDocument(did: string) {\n const parsed = parseDid(did)\n const identifierWithoutNumAlgo = parsed.id.substring(2)\n\n // Get a list of all did document entries splitted by .\n const entries = identifierWithoutNumAlgo.split('.')\n const didDocument = new DidDocumentBuilder(did)\n let serviceIndex = 0\n let keyIndex = 1\n\n for (const entry of entries) {\n // Remove the purpose identifier to get the service or key content\n const entryContent = entry.substring(1)\n // Get the purpose identifier\n const purpose = entry[0]\n\n // Handle service entry first\n if (purpose === DidPeerPurpose.Service) {\n let services = JsonEncoder.fromBase64Url(entryContent)\n\n // Make sure we have an array of services (can be both json or array)\n services = Array.isArray(services) ? services : [services]\n\n for (let service of services) {\n // Expand abbreviations used for service key/values\n service = expandServiceAbbreviations(service)\n\n service.id = `${did}#${service.type.toLowerCase()}-${serviceIndex++}`\n\n didDocument.addService(JsonTransformer.fromJSON(service, DidDocumentService))\n }\n }\n // Otherwise we can be sure it is a key\n else {\n // Decode the fingerprint, and extract the verification method(s)\n const publicJwk = PublicJwk.fromFingerprint(entryContent)\n const verificationMethods = getVerificationMethodsForPublicJwk(publicJwk, did)\n\n // Add all verification methods to the did document\n for (const verificationMethod of verificationMethods) {\n verificationMethod.id = `${did}#key-${keyIndex++}`\n addVerificationMethodToDidDocument(didDocument, verificationMethod, purpose)\n }\n }\n }\n\n return didDocument.build()\n}\n\nexport function didDocumentToNumAlgo2Did(didDocument: DidDocument) {\n const purposeMapping: Array<[DidPeerPurpose, DidPurpose]> = [\n [DidPeerPurpose.Assertion, 'assertionMethod'],\n [DidPeerPurpose.Encryption, 'keyAgreement'],\n // FIXME: should verification be authentication or verificationMethod\n // verificationMethod is general so it doesn't make a lot of sense to add\n // it to the verificationMethod list\n [DidPeerPurpose.Verification, 'authentication'],\n [DidPeerPurpose.CapabilityInvocation, 'capabilityInvocation'],\n [DidPeerPurpose.CapabilityDelegation, 'capabilityDelegation'],\n ]\n\n let did = 'did:peer:2'\n\n const keys: { id: string; encoded: string }[] = []\n\n for (const [purpose, entries] of purposeMapping) {\n // Not all entries are required to be defined\n // Dereference all entries to full verification methods\n // Transform all verification methods into a fingerprint (multibase, multicodec)\n for (const entry of didDocument.findVerificationMethodsByPurpose([entries])) {\n const key = getPublicJwkFromVerificationMethod(entry)\n\n // Encode as '.PurposeFingerprint'\n const encoded = `.${purpose}${key.fingerprint}`\n\n keys.push({ id: entry.id, encoded })\n }\n }\n\n const prefix = 'key-'\n if (!keys.every((key) => key.id.split('#')[1]?.startsWith(prefix))) {\n throw new CredoError('Ids for keys within DID Document for did:peer:2 creation must follow the pattern `#key-n`')\n }\n\n // Add all encoded keys ordered by their id (#key-1, #key-2, etc.)\n did += keys\n .sort((a, b) => {\n const aFragment = a.id.split('#')[1]\n const bFragment = b.id.split('#')[1]\n const aIndex = Number(aFragment.replace(prefix, ''))\n const bIndex = Number(bFragment.replace(prefix, ''))\n\n return aIndex - bIndex\n })\n .map((key) => key.encoded)\n .join('')\n\n if (didDocument.service && didDocument.service.length > 0) {\n const abbreviatedServices = didDocument.service.map((service) => {\n // Transform to JSON, remove id property\n const serviceJson = JsonTransformer.toJSON(service)\n serviceJson.id = undefined\n\n return abbreviateServiceJson(serviceJson)\n })\n\n for (const abbreviatedService of abbreviatedServices) {\n const encodedService = JsonEncoder.toBase64Url(abbreviatedService)\n did += `.${DidPeerPurpose.Service}${encodedService}`\n }\n }\n\n return did\n}\n\nfunction expandServiceAbbreviations(service: JsonObject) {\n const expand = (abbreviated: string) => didPeerExpansions[abbreviated] ?? abbreviated\n const expandJson = (json: unknown): unknown => {\n if (!json) return json\n if (typeof json === 'number') return json\n if (typeof json === 'string') return expand(json)\n if (Array.isArray(json)) return json.map(expandJson)\n if (typeof json === 'object')\n return Object.entries(json as Record<string, unknown>).reduce(\n (jsonBody, [key, value]) => ({\n // biome-ignore lint/performance/noAccumulatingSpread: no explanation\n ...jsonBody,\n [expand(key)]: expandJson(value),\n }),\n {}\n )\n }\n\n const fullService = expandJson(service) as Record<string, unknown>\n\n // Handle the case where a legacy DIDComm v2 service has been encoded in the did:peer:2.\n // We use the legacy `DIDComm` type (over `DIDCommMessaging`)\n if ('t' in service && service.t === 'dm' && typeof service.serviceEndpoint === 'string') {\n return {\n ...fullService,\n type: 'DIDComm',\n }\n }\n\n return fullService\n}\n\nfunction abbreviateServiceJson(service: JsonObject) {\n const abbreviate = (expanded: string) => didPeerAbbreviations[expanded] ?? expanded\n\n const abbreviatedService = Object.entries(service).reduce(\n (serviceBody, [key, value]) => ({\n // biome-ignore lint/performance/noAccumulatingSpread: no explanation\n ...serviceBody,\n [abbreviate(key)]: abbreviate(value as string),\n }),\n {}\n )\n\n return abbreviatedService\n}\n\nfunction addVerificationMethodToDidDocument(\n didDocument: DidDocumentBuilder,\n verificationMethod: VerificationMethod,\n purpose: string\n) {\n const purposeMapping = {\n [DidPeerPurpose.Assertion]: didDocument.addAssertionMethod.bind(didDocument),\n [DidPeerPurpose.Encryption]: didDocument.addKeyAgreement.bind(didDocument),\n // FIXME: should verification be authentication or verificationMethod\n // verificationMethod is general so it doesn't make a lot of sense to add\n // it to the verificationMethod list\n [DidPeerPurpose.Verification]: didDocument.addAuthentication.bind(didDocument),\n [DidPeerPurpose.CapabilityInvocation]: didDocument.addCapabilityInvocation.bind(didDocument),\n [DidPeerPurpose.CapabilityDelegation]: didDocument.addCapabilityDelegation.bind(didDocument),\n }\n\n // Verify the purpose is a did peer key purpose (service excluded)\n if (isDidPeerKeyPurpose(purpose)) {\n const addVerificationMethod = purposeMapping[purpose]\n\n // Add the verification method based on the method from the mapping\n addVerificationMethod(verificationMethod)\n } else {\n throw new CredoError(`Unsupported peer did purpose '${purpose}'`)\n }\n}\n"],"mappings":"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"}