Fork of github.com/did-method-plc/did-method-plc
1import * as crypto from '@atproto/crypto' 2import * as t from './types' 3import { UnsupportedKeyError } from './error' 4import { ParsedMultikey } from '@atproto/crypto' 5 6export const formatDidDoc = (data: t.DocumentData): t.DidDocument => { 7 const context = [ 8 'https://www.w3.org/ns/did/v1', 9 'https://w3id.org/security/multikey/v1', 10 ] 11 12 const verificationMethods: VerificationMethod[] = [] 13 for (const [keyid, key] of Object.entries(data.verificationMethods)) { 14 const info = formatKeyAndContext(key) 15 if (info.context && !context.includes(info.context)) { 16 context.push(info.context) 17 } 18 verificationMethods.push({ 19 id: `${data.did}#${keyid}`, 20 type: info.type, 21 controller: data.did, 22 publicKeyMultibase: info.publicKeyMultibase, 23 }) 24 } 25 26 const services: Service[] = [] 27 for (const [serviceId, service] of Object.entries(data.services)) { 28 services.push({ 29 id: `#${serviceId}`, 30 type: service.type, 31 serviceEndpoint: service.endpoint, 32 }) 33 } 34 35 return { 36 '@context': context, 37 id: data.did, 38 alsoKnownAs: data.alsoKnownAs, 39 verificationMethod: verificationMethods, 40 service: services, 41 } 42} 43 44type VerificationMethod = { 45 id: string 46 type: string 47 controller: string 48 publicKeyMultibase: string 49} 50 51type Service = { 52 id: string 53 type: string 54 serviceEndpoint: string 55} 56 57type KeyAndContext = { 58 context?: string 59 type: string 60 publicKeyMultibase: string 61} 62 63const formatKeyAndContext = (key: string): KeyAndContext => { 64 let keyInfo: ParsedMultikey 65 try { 66 keyInfo = crypto.parseDidKey(key) 67 } catch (err) { 68 return { 69 // we can't specify a context for a key type we don't recognize 70 type: 'Multikey', 71 publicKeyMultibase: key.replace(/^(did:key:)/, ''), 72 } 73 } 74 const { jwtAlg } = keyInfo 75 76 if (jwtAlg === crypto.P256_JWT_ALG) { 77 return { 78 context: 'https://w3id.org/security/suites/ecdsa-2019/v1', 79 type: 'Multikey', 80 publicKeyMultibase: key.replace(/^(did:key:)/, ''), 81 } 82 } else if (jwtAlg === crypto.SECP256K1_JWT_ALG) { 83 return { 84 context: 'https://w3id.org/security/suites/secp256k1-2019/v1', 85 type: 'Multikey', 86 publicKeyMultibase: key.replace(/^(did:key:)/, ''), 87 } 88 } 89 90 // this codepath might seem unreachable/redundant, but it's possible 91 // parseDidKey() supports more key formats in future, before this function 92 // can be updated likewise 93 return { 94 // we can't specify a context for a key type we don't recognize 95 type: 'Multikey', 96 publicKeyMultibase: key.replace(/^(did:key:)/, ''), 97 } 98}