@sphereon/ssi-sdk-ext.did-utils 0.25.1-next.22 → 0.25.1-next.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,283 +1,292 @@
1
- import { computeAddress } from '@ethersproject/transactions'
2
- import { UniResolver } from '@sphereon/did-uni-client'
1
+ import {computeAddress} from '@ethersproject/transactions'
2
+ import {UniResolver} from '@sphereon/did-uni-client'
3
3
  import {
4
- ENC_KEY_ALGS,
5
- getKms,
6
- JwkKeyUse,
7
- keyTypeFromCryptographicSuite,
8
- signatureAlgorithmFromKey,
9
- TKeyType,
10
- toJwk,
4
+ ENC_KEY_ALGS,
5
+ getKms,
6
+ JwkKeyUse,
7
+ keyTypeFromCryptographicSuite,
8
+ signatureAlgorithmFromKey,
9
+ TKeyType,
10
+ toJwk,
11
11
  } from '@sphereon/ssi-sdk-ext.key-utils'
12
- import { base64ToHex, hexKeyFromPEMBasedJwk } from '@sphereon/ssi-sdk-ext.x509-utils'
13
- import { base58ToBytes, base64ToBytes, bytesToHex, hexToBytes, multibaseKeyToBytes } from '@sphereon/ssi-sdk.core'
14
- import { JWK } from '@sphereon/ssi-types'
15
- import { convertPublicKeyToX25519 } from '@stablelib/ed25519'
16
- import { DIDDocument, DIDDocumentSection, DIDResolutionResult, IAgentContext, IDIDManager, IIdentifier, IKey, IResolver } from '@veramo/core'
12
+ import {base64ToHex, hexKeyFromPEMBasedJwk} from '@sphereon/ssi-sdk-ext.x509-utils'
13
+ import {base58ToBytes, base64ToBytes, bytesToHex, hexToBytes, multibaseKeyToBytes} from '@sphereon/ssi-sdk.core'
14
+ import {JWK} from '@sphereon/ssi-types'
15
+ import {convertPublicKeyToX25519} from '@stablelib/ed25519'
17
16
  import {
18
- _ExtendedIKey,
19
- _ExtendedVerificationMethod,
20
- _NormalizedVerificationMethod,
21
- compressIdentifierSecp256k1Keys,
22
- convertIdentifierEncryptionKeys,
23
- getEthereumAddress,
24
- isDefined,
25
- mapIdentifierKeysToDoc,
17
+ DIDDocument,
18
+ DIDDocumentSection,
19
+ DIDResolutionResult,
20
+ IAgentContext,
21
+ IDIDManager,
22
+ IIdentifier,
23
+ IKey,
24
+ IResolver
25
+ } from '@veramo/core'
26
+ import {
27
+ _ExtendedIKey,
28
+ _ExtendedVerificationMethod,
29
+ _NormalizedVerificationMethod,
30
+ compressIdentifierSecp256k1Keys,
31
+ convertIdentifierEncryptionKeys,
32
+ getEthereumAddress,
33
+ isDefined,
34
+ mapIdentifierKeysToDoc,
26
35
  } from '@veramo/utils'
27
- import { createJWT, Signer } from 'did-jwt'
28
- import { DIDResolutionOptions, JsonWebKey, Resolvable, VerificationMethod } from 'did-resolver'
36
+ import {createJWT, Signer} from 'did-jwt'
37
+ import {DIDResolutionOptions, JsonWebKey, Resolvable, VerificationMethod} from 'did-resolver'
29
38
  // @ts-ignore
30
39
  import elliptic from 'elliptic'
31
40
  import * as u8a from 'uint8arrays'
32
41
  import {
33
- CreateIdentifierOpts,
34
- CreateOrGetIdentifierOpts,
35
- DID_PREFIX,
36
- GetOrCreateResult,
37
- GetSignerArgs,
38
- IdentifierAliasEnum,
39
- IdentifierProviderOpts,
40
- IDIDOptions,
41
- SignJwtArgs,
42
- SupportedDidMethodEnum,
42
+ CreateIdentifierOpts,
43
+ CreateOrGetIdentifierOpts,
44
+ DID_PREFIX,
45
+ GetOrCreateResult,
46
+ GetSignerArgs,
47
+ IdentifierAliasEnum,
48
+ IdentifierProviderOpts,
49
+ IDIDOptions,
50
+ SignJwtArgs,
51
+ SupportedDidMethodEnum,
43
52
  } from './types'
44
53
 
45
54
  export const getAuthenticationKey = async (
46
- {
47
- identifier,
48
- offlineWhenNoDIDRegistered,
49
- noVerificationMethodFallback,
50
- keyType,
51
- controllerKey,
52
- }: {
53
- identifier: IIdentifier
54
- keyType?: TKeyType
55
- offlineWhenNoDIDRegistered?: boolean
56
- noVerificationMethodFallback?: boolean
57
- controllerKey?: boolean
58
- },
59
- context: IAgentContext<IResolver & IDIDManager>
60
- ): Promise<_ExtendedIKey> => {
61
- return await getFirstKeyWithRelation(
62
55
  {
63
- identifier,
64
- offlineWhenNoDIDRegistered,
65
- noVerificationMethodFallback,
66
- keyType,
67
- controllerKey,
68
- vmRelationship: 'authentication',
56
+ identifier,
57
+ offlineWhenNoDIDRegistered,
58
+ noVerificationMethodFallback,
59
+ keyType,
60
+ controllerKey,
61
+ }: {
62
+ identifier: IIdentifier
63
+ keyType?: TKeyType
64
+ offlineWhenNoDIDRegistered?: boolean
65
+ noVerificationMethodFallback?: boolean
66
+ controllerKey?: boolean
69
67
  },
70
- context
71
- )
72
- }
73
- export const getFirstKeyWithRelation = async (
74
- {
75
- identifier,
76
- offlineWhenNoDIDRegistered,
77
- noVerificationMethodFallback,
78
- keyType,
79
- controllerKey,
80
- vmRelationship,
81
- }: {
82
- identifier: IIdentifier
83
- keyType?: TKeyType
84
- offlineWhenNoDIDRegistered?: boolean
85
- noVerificationMethodFallback?: boolean
86
- controllerKey?: boolean
87
- vmRelationship: DIDDocumentSection
88
- },
89
- context: IAgentContext<IResolver & IDIDManager>
68
+ context: IAgentContext<IResolver & IDIDManager>
90
69
  ): Promise<_ExtendedIKey> => {
91
- let key: _ExtendedIKey | undefined = undefined
92
- try {
93
- key =
94
- (await getFirstKeyWithRelationFromDIDDoc(
70
+ return await getFirstKeyWithRelation(
95
71
  {
96
- identifier,
97
- vmRelationship,
98
- errorOnNotFound: false,
99
- keyType,
100
- controllerKey,
72
+ identifier,
73
+ offlineWhenNoDIDRegistered,
74
+ noVerificationMethodFallback,
75
+ keyType,
76
+ controllerKey,
77
+ vmRelationship: 'authentication',
101
78
  },
102
79
  context
103
- )) ??
104
- (noVerificationMethodFallback || vmRelationship === 'verificationMethod' // let's not fallback to the same value again
105
- ? undefined
106
- : await getFirstKeyWithRelationFromDIDDoc(
107
- {
108
- identifier,
109
- vmRelationship: 'verificationMethod',
110
- errorOnNotFound: false,
111
- keyType,
112
- controllerKey,
113
- },
114
- context
115
- ))
116
- } catch (e) {
117
- if (e instanceof Error) {
118
- if (!e.message.includes('404') || !offlineWhenNoDIDRegistered) {
119
- throw e
120
- }
121
- } else {
122
- throw e
123
- }
124
- }
125
- if (!key && offlineWhenNoDIDRegistered) {
126
- const offlineDID = toDidDocument(identifier)
127
- key =
128
- (await getFirstKeyWithRelationFromDIDDoc(
129
- {
130
- identifier,
131
- vmRelationship,
132
- errorOnNotFound: false,
133
- didDocument: offlineDID,
134
- keyType,
135
- controllerKey,
136
- },
137
- context
138
- )) ??
139
- (noVerificationMethodFallback || vmRelationship === 'verificationMethod' // let's not fallback to the same value again
140
- ? undefined
141
- : await getFirstKeyWithRelationFromDIDDoc(
142
- {
143
- identifier,
144
- vmRelationship: 'verificationMethod',
145
- errorOnNotFound: false,
146
- didDocument: offlineDID,
147
- keyType,
148
- controllerKey,
149
- },
150
- context
151
- ))
80
+ )
81
+ }
82
+ export const getFirstKeyWithRelation = async (
83
+ {
84
+ identifier,
85
+ offlineWhenNoDIDRegistered,
86
+ noVerificationMethodFallback,
87
+ keyType,
88
+ controllerKey,
89
+ vmRelationship,
90
+ }: {
91
+ identifier: IIdentifier
92
+ keyType?: TKeyType
93
+ offlineWhenNoDIDRegistered?: boolean
94
+ noVerificationMethodFallback?: boolean
95
+ controllerKey?: boolean
96
+ vmRelationship: DIDDocumentSection
97
+ },
98
+ context: IAgentContext<IResolver & IDIDManager>
99
+ ): Promise<_ExtendedIKey> => {
100
+ let key: _ExtendedIKey | undefined = undefined
101
+ try {
102
+ key =
103
+ (await getFirstKeyWithRelationFromDIDDoc(
104
+ {
105
+ identifier,
106
+ vmRelationship,
107
+ errorOnNotFound: false,
108
+ keyType,
109
+ controllerKey,
110
+ },
111
+ context
112
+ )) ??
113
+ (noVerificationMethodFallback || vmRelationship === 'verificationMethod' // let's not fallback to the same value again
114
+ ? undefined
115
+ : await getFirstKeyWithRelationFromDIDDoc(
116
+ {
117
+ identifier,
118
+ vmRelationship: 'verificationMethod',
119
+ errorOnNotFound: false,
120
+ keyType,
121
+ controllerKey,
122
+ },
123
+ context
124
+ ))
125
+ } catch (e) {
126
+ if (e instanceof Error) {
127
+ if (!e.message.includes('404') || !offlineWhenNoDIDRegistered) {
128
+ throw e
129
+ }
130
+ } else {
131
+ throw e
132
+ }
133
+ }
134
+ if (!key && offlineWhenNoDIDRegistered) {
135
+ const offlineDID = toDidDocument(identifier)
136
+ key =
137
+ (await getFirstKeyWithRelationFromDIDDoc(
138
+ {
139
+ identifier,
140
+ vmRelationship,
141
+ errorOnNotFound: false,
142
+ didDocument: offlineDID,
143
+ keyType,
144
+ controllerKey,
145
+ },
146
+ context
147
+ )) ??
148
+ (noVerificationMethodFallback || vmRelationship === 'verificationMethod' // let's not fallback to the same value again
149
+ ? undefined
150
+ : await getFirstKeyWithRelationFromDIDDoc(
151
+ {
152
+ identifier,
153
+ vmRelationship: 'verificationMethod',
154
+ errorOnNotFound: false,
155
+ didDocument: offlineDID,
156
+ keyType,
157
+ controllerKey,
158
+ },
159
+ context
160
+ ))
161
+ if (!key) {
162
+ key = identifier.keys
163
+ .map((key) => key as _ExtendedIKey)
164
+ .filter((key) => keyType === undefined || key.type === keyType || (controllerKey && key.kid === identifier.controllerKeyId))
165
+ .find((key) => key.meta.verificationMethod?.type.includes('authentication') || key.meta.purposes?.includes('authentication'))
166
+ }
167
+ }
152
168
  if (!key) {
153
- key = identifier.keys
154
- .map((key) => key as _ExtendedIKey)
155
- .filter((key) => keyType === undefined || key.type === keyType || (controllerKey && key.kid === identifier.controllerKeyId))
156
- .find((key) => key.meta.verificationMethod?.type.includes('authentication') || key.meta.purposes?.includes('authentication'))
169
+ throw Error(`Could not find authentication key for DID ${identifier.did}`)
157
170
  }
158
- }
159
- if (!key) {
160
- throw Error(`Could not find authentication key for DID ${identifier.did}`)
161
- }
162
- return key
171
+ return key
163
172
  }
164
173
 
165
174
  export const getOrCreatePrimaryIdentifier = async (
166
- context: IAgentContext<IDIDManager>,
167
- opts?: CreateOrGetIdentifierOpts
175
+ context: IAgentContext<IDIDManager>,
176
+ opts?: CreateOrGetIdentifierOpts
168
177
  ): Promise<GetOrCreateResult<IIdentifier>> => {
169
- const primaryIdentifier = await getPrimaryIdentifier(context, { ...opts?.createOpts?.options, ...(opts?.method && { method: opts.method }) })
170
- if (primaryIdentifier !== undefined) {
171
- return {
172
- created: false,
173
- result: primaryIdentifier,
178
+ const primaryIdentifier = await getPrimaryIdentifier(context, {...opts?.createOpts?.options, ...(opts?.method && {method: opts.method})})
179
+ if (primaryIdentifier !== undefined) {
180
+ return {
181
+ created: false,
182
+ result: primaryIdentifier,
183
+ }
174
184
  }
175
- }
176
185
 
177
- if (opts?.method === SupportedDidMethodEnum.DID_KEY) {
178
- const createOpts = opts?.createOpts ?? {}
179
- createOpts.options = { codecName: 'EBSI', type: 'Secp256r1', ...createOpts }
180
- opts.createOpts = createOpts
181
- }
182
- const createdIdentifier = await createIdentifier(context, opts)
183
- return {
184
- created: true,
185
- result: createdIdentifier,
186
- }
186
+ if (opts?.method === SupportedDidMethodEnum.DID_KEY) {
187
+ const createOpts = opts?.createOpts ?? {}
188
+ createOpts.options = {codecName: 'EBSI', type: 'Secp256r1', ...createOpts}
189
+ opts.createOpts = createOpts
190
+ }
191
+ const createdIdentifier = await createIdentifier(context, opts)
192
+ return {
193
+ created: true,
194
+ result: createdIdentifier,
195
+ }
187
196
  }
188
197
 
189
198
  export const getPrimaryIdentifier = async (context: IAgentContext<IDIDManager>, opts?: IdentifierProviderOpts): Promise<IIdentifier | undefined> => {
190
- const identifiers = (await context.agent.didManagerFind(opts?.method ? { provider: `${DID_PREFIX}${opts?.method}` } : {})).filter(
191
- (identifier: IIdentifier) => opts?.type === undefined || identifier.keys.some((key: IKey) => key.type === opts?.type)
192
- )
199
+ const identifiers = (await context.agent.didManagerFind(opts?.method ? {provider: `${DID_PREFIX}${opts?.method}`} : {})).filter(
200
+ (identifier: IIdentifier) => opts?.type === undefined || identifier.keys.some((key: IKey) => key.type === opts?.type)
201
+ )
193
202
 
194
- return identifiers && identifiers.length > 0 ? identifiers[0] : undefined
203
+ return identifiers && identifiers.length > 0 ? identifiers[0] : undefined
195
204
  }
196
205
 
197
206
  export const createIdentifier = async (context: IAgentContext<IDIDManager>, opts?: CreateIdentifierOpts): Promise<IIdentifier> => {
198
- return await context.agent.didManagerCreate({
199
- kms: await getKms(context, opts?.createOpts?.kms),
200
- ...(opts?.method && { provider: `${DID_PREFIX}${opts?.method}` }),
201
- alias: opts?.createOpts?.alias ?? `${IdentifierAliasEnum.PRIMARY}-${opts?.method}-${opts?.createOpts?.options?.type}-${new Date().toUTCString()}`,
202
- options: opts?.createOpts?.options,
203
- })
207
+ return await context.agent.didManagerCreate({
208
+ kms: await getKms(context, opts?.createOpts?.kms),
209
+ ...(opts?.method && {provider: `${DID_PREFIX}${opts?.method}`}),
210
+ alias: opts?.createOpts?.alias ?? `${IdentifierAliasEnum.PRIMARY}-${opts?.method}-${opts?.createOpts?.options?.type}-${new Date().toUTCString()}`,
211
+ options: opts?.createOpts?.options,
212
+ })
204
213
  }
205
214
 
206
215
  export const getFirstKeyWithRelationFromDIDDoc = async (
207
- {
208
- identifier,
209
- vmRelationship = 'verificationMethod',
210
- keyType,
211
- errorOnNotFound = false,
212
- didDocument,
213
- controllerKey,
214
- }: {
215
- identifier: IIdentifier
216
- controllerKey?: boolean
217
- vmRelationship?: DIDDocumentSection
218
- keyType?: TKeyType
219
- errorOnNotFound?: boolean
220
- didDocument?: DIDDocument
221
- },
222
- context: IAgentContext<IResolver & IDIDManager>
216
+ {
217
+ identifier,
218
+ vmRelationship = 'verificationMethod',
219
+ keyType,
220
+ errorOnNotFound = false,
221
+ didDocument,
222
+ controllerKey,
223
+ }: {
224
+ identifier: IIdentifier
225
+ controllerKey?: boolean
226
+ vmRelationship?: DIDDocumentSection
227
+ keyType?: TKeyType
228
+ errorOnNotFound?: boolean
229
+ didDocument?: DIDDocument
230
+ },
231
+ context: IAgentContext<IResolver & IDIDManager>
223
232
  ): Promise<_ExtendedIKey | undefined> => {
224
- const matchedKeys = await mapIdentifierKeysToDocWithJwkSupport({ identifier, vmRelationship, didDocument }, context)
225
- if (Array.isArray(matchedKeys) && matchedKeys.length > 0) {
226
- const result = matchedKeys.find(
227
- (key) => keyType === undefined || key.type === keyType || (controllerKey && key.kid === identifier.controllerKeyId)
228
- )
229
- if (result) {
230
- return result
233
+ const matchedKeys = await mapIdentifierKeysToDocWithJwkSupport({identifier, vmRelationship, didDocument}, context)
234
+ if (Array.isArray(matchedKeys) && matchedKeys.length > 0) {
235
+ const result = matchedKeys.find(
236
+ (key) => keyType === undefined || key.type === keyType || (controllerKey && key.kid === identifier.controllerKeyId)
237
+ )
238
+ if (result) {
239
+ return result
240
+ }
231
241
  }
232
- }
233
- if (errorOnNotFound) {
234
- throw new Error(
235
- `Could not find key with relationship ${vmRelationship} in DID document for ${identifier.did}${keyType ? ' and key type: ' + keyType : ''}`
236
- )
237
- }
238
- return undefined
242
+ if (errorOnNotFound) {
243
+ throw new Error(
244
+ `Could not find key with relationship ${vmRelationship} in DID document for ${identifier.did}${keyType ? ' and key type: ' + keyType : ''}`
245
+ )
246
+ }
247
+ return undefined
239
248
  }
240
249
 
241
- export const getEthereumAddressFromKey = ({ key }: { key: IKey }) => {
242
- if (key.type !== 'Secp256k1') {
243
- throw Error(`Can only get ethereum address from a Secp256k1 key. Type is ${key.type} for keyRef: ${key.kid}`)
244
- }
245
- const ethereumAddress = key.meta?.ethereumAddress ?? key.meta?.account?.toLowerCase() ?? computeAddress(`0x${key.publicKeyHex}`).toLowerCase()
246
- if (!ethereumAddress) {
247
- throw Error(`Could not get or generate ethereum address from key with keyRef ${key.kid}`)
248
- }
249
- return ethereumAddress
250
+ export const getEthereumAddressFromKey = ({key}: { key: IKey }) => {
251
+ if (key.type !== 'Secp256k1') {
252
+ throw Error(`Can only get ethereum address from a Secp256k1 key. Type is ${key.type} for keyRef: ${key.kid}`)
253
+ }
254
+ const ethereumAddress = key.meta?.ethereumAddress ?? key.meta?.account?.toLowerCase() ?? computeAddress(`0x${key.publicKeyHex}`).toLowerCase()
255
+ if (!ethereumAddress) {
256
+ throw Error(`Could not get or generate ethereum address from key with keyRef ${key.kid}`)
257
+ }
258
+ return ethereumAddress
250
259
  }
251
260
 
252
- export const getControllerKey = ({ identifier }: { identifier: IIdentifier }) => {
253
- const key = identifier.keys.find((key) => key.kid === identifier.controllerKeyId)
254
- if (!key) {
255
- throw Error(`Could not get controller key for identifier ${identifier}`)
256
- }
257
- return key
261
+ export const getControllerKey = ({identifier}: { identifier: IIdentifier }) => {
262
+ const key = identifier.keys.find((key) => key.kid === identifier.controllerKeyId)
263
+ if (!key) {
264
+ throw Error(`Could not get controller key for identifier ${identifier}`)
265
+ }
266
+ return key
258
267
  }
259
268
 
260
269
  export const getKeys = ({
261
- jwkThumbprint,
262
- kms,
263
- identifier,
264
- kmsKeyRef,
265
- keyType,
266
- controllerKey,
267
- }: {
268
- identifier: IIdentifier
269
- kmsKeyRef?: string
270
- keyType?: TKeyType
271
- kms?: string
272
- jwkThumbprint?: string
273
- controllerKey?: boolean
270
+ jwkThumbprint,
271
+ kms,
272
+ identifier,
273
+ kmsKeyRef,
274
+ keyType,
275
+ controllerKey,
276
+ }: {
277
+ identifier: IIdentifier
278
+ kmsKeyRef?: string
279
+ keyType?: TKeyType
280
+ kms?: string
281
+ jwkThumbprint?: string
282
+ controllerKey?: boolean
274
283
  }) => {
275
- return identifier.keys
276
- .filter((key) => !keyType || key.type === keyType)
277
- .filter((key) => !kms || key.kms === kms)
278
- .filter((key) => !kmsKeyRef || key.kid === kmsKeyRef)
279
- .filter((key) => !jwkThumbprint || key.meta?.jwkThumbprint === jwkThumbprint)
280
- .filter((key) => !controllerKey || identifier.controllerKeyId === key.kid)
284
+ return identifier.keys
285
+ .filter((key) => !keyType || key.type === keyType)
286
+ .filter((key) => !kms || key.kms === kms)
287
+ .filter((key) => !kmsKeyRef || key.kid === kmsKeyRef)
288
+ .filter((key) => !jwkThumbprint || key.meta?.jwkThumbprint === jwkThumbprint)
289
+ .filter((key) => !controllerKey || identifier.controllerKeyId === key.kid)
281
290
  }
282
291
 
283
292
  //TODO: Move to ssi-sdk/core and create PR upstream
@@ -292,52 +301,52 @@ export const getKeys = ({
292
301
  * @beta This API may change without a BREAKING CHANGE notice.
293
302
  */
294
303
  export async function dereferenceDidKeysWithJwkSupport(
295
- didDocument: DIDDocument,
296
- section: DIDDocumentSection = 'keyAgreement',
297
- context: IAgentContext<IResolver>
304
+ didDocument: DIDDocument,
305
+ section: DIDDocumentSection = 'keyAgreement',
306
+ context: IAgentContext<IResolver>
298
307
  ): Promise<_NormalizedVerificationMethod[]> {
299
- const convert = section === 'keyAgreement'
300
- if (section === 'service') {
301
- return []
302
- }
303
- return (
304
- await Promise.all(
305
- (didDocument[section] || []).map(async (key: string | VerificationMethod) => {
306
- if (typeof key === 'string') {
307
- try {
308
- return (await context.agent.getDIDComponentById({
309
- didDocument,
310
- didUrl: key,
311
- section,
312
- })) as _ExtendedVerificationMethod
313
- } catch (e) {
314
- return null
315
- }
316
- } else {
317
- return key as _ExtendedVerificationMethod
318
- }
319
- })
308
+ const convert = section === 'keyAgreement'
309
+ if (section === 'service') {
310
+ return []
311
+ }
312
+ return (
313
+ await Promise.all(
314
+ (didDocument[section] || []).map(async (key: string | VerificationMethod) => {
315
+ if (typeof key === 'string') {
316
+ try {
317
+ return (await context.agent.getDIDComponentById({
318
+ didDocument,
319
+ didUrl: key,
320
+ section,
321
+ })) as _ExtendedVerificationMethod
322
+ } catch (e) {
323
+ return null
324
+ }
325
+ } else {
326
+ return key as _ExtendedVerificationMethod
327
+ }
328
+ })
329
+ )
320
330
  )
321
- )
322
- .filter(isDefined)
323
- .map((key) => {
324
- const hexKey = extractPublicKeyHexWithJwkSupport(key, convert)
325
- const { publicKeyHex, publicKeyBase58, publicKeyBase64, publicKeyJwk, ...keyProps } = key
326
- const newKey = { ...keyProps, publicKeyHex: hexKey }
327
- if (convert && 'Ed25519VerificationKey2018' === newKey.type) {
328
- newKey.type = 'X25519KeyAgreementKey2019'
329
- }
330
- return newKey
331
- })
331
+ .filter(isDefined)
332
+ .map((key) => {
333
+ const hexKey = extractPublicKeyHexWithJwkSupport(key, convert)
334
+ const {publicKeyHex, publicKeyBase58, publicKeyBase64, publicKeyJwk, ...keyProps} = key
335
+ const newKey = {...keyProps, publicKeyHex: hexKey}
336
+ if (convert && 'Ed25519VerificationKey2018' === newKey.type) {
337
+ newKey.type = 'X25519KeyAgreementKey2019'
338
+ }
339
+ return newKey
340
+ })
332
341
  }
333
342
 
334
343
  export function jwkTtoPublicKeyHex(jwk: JWK): string {
335
- // todo: Hacky way to convert this to a VM. Should extract the logic from the below methods
336
- // @ts-ignore
337
- const vm: _ExtendedVerificationMethod = {
338
- publicKeyJwk: jwk,
339
- }
340
- return extractPublicKeyHexWithJwkSupport(vm)
344
+ // todo: Hacky way to convert this to a VM. Should extract the logic from the below methods
345
+ // @ts-ignore
346
+ const vm: _ExtendedVerificationMethod = {
347
+ publicKeyJwk: jwk,
348
+ }
349
+ return extractPublicKeyHexWithJwkSupport(vm)
341
350
  }
342
351
 
343
352
  /**
@@ -350,37 +359,38 @@ export function jwkTtoPublicKeyHex(jwk: JWK): string {
350
359
  * @beta This API may change without a BREAKING CHANGE notice.
351
360
  */
352
361
  export function extractPublicKeyHexWithJwkSupport(pk: _ExtendedVerificationMethod, convert = false): string {
353
- if (pk.publicKeyJwk) {
354
- if (pk.publicKeyJwk.kty === 'EC') {
355
- const secp256 = new elliptic.ec(pk.publicKeyJwk.crv === 'secp256k1' ? 'secp256k1' : 'p256')
356
-
357
- const xHex = base64ToHex(pk.publicKeyJwk.x!, 'base64url')
358
- const yHex = base64ToHex(pk.publicKeyJwk.y!, 'base64url')
359
- const prefix = '04' // isEven(yHex) ? '02' : '03'
360
- // Uncompressed Hex format: 04<x><y>
361
- // Compressed Hex format: 02<x> (for even y) or 03<x> (for uneven y)
362
- const hex = `${prefix}${xHex}${yHex}`
363
- // We return directly as we don't want to convert the result back into Uint8Array and then convert again to hex as the elliptic lib already returns hex strings
364
- const publicKeyHex = secp256.keyFromPublic(hex, 'hex').getPublic(true, 'hex')
365
- // This returns a short form (x) with 02 or 03 prefix
366
- return publicKeyHex
367
- } else if (pk.publicKeyJwk.crv === 'Ed25519') {
368
- return u8a.toString(u8a.fromString(pk.publicKeyJwk.x!, 'base64url'), 'base16')
369
- } else if (pk.publicKeyJwk.kty === 'RSA') {
370
- return hexKeyFromPEMBasedJwk(pk.publicKeyJwk, 'public')
371
- }
372
- }
373
- // delegate the other types to the original Veramo function
374
- return extractPublicKeyHex(pk, convert)
362
+ if (pk.publicKeyJwk) {
363
+ if (pk.publicKeyJwk.kty === 'EC') {
364
+ const curve = pk.publicKeyJwk.crv ? toEcLibCurve(pk.publicKeyJwk.crv): 'p256'
365
+ const ec = new elliptic.ec(curve)
366
+
367
+ const xHex = base64ToHex(pk.publicKeyJwk.x!, 'base64url')
368
+ const yHex = base64ToHex(pk.publicKeyJwk.y!, 'base64url')
369
+ const prefix = '04' // isEven(yHex) ? '02' : '03'
370
+ // Uncompressed Hex format: 04<x><y>
371
+ // Compressed Hex format: 02<x> (for even y) or 03<x> (for uneven y)
372
+ const hex = `${prefix}${xHex}${yHex}`
373
+ // We return directly as we don't want to convert the result back into Uint8Array and then convert again to hex as the elliptic lib already returns hex strings
374
+ const publicKeyHex = ec.keyFromPublic(hex, 'hex').getPublic(true, 'hex')
375
+ // This returns a short form (x) with 02 or 03 prefix
376
+ return publicKeyHex
377
+ } else if (pk.publicKeyJwk.crv === 'Ed25519') {
378
+ return u8a.toString(u8a.fromString(pk.publicKeyJwk.x!, 'base64url'), 'base16')
379
+ } else if (pk.publicKeyJwk.kty === 'RSA') {
380
+ return hexKeyFromPEMBasedJwk(pk.publicKeyJwk, 'public')
381
+ }
382
+ }
383
+ // delegate the other types to the original Veramo function
384
+ return extractPublicKeyHex(pk, convert)
375
385
  }
376
386
 
377
387
  export function isEvenHexString(hex: string) {
378
- const lastChar = hex[hex.length - 1].toLowerCase()
379
- return ['0', '2', '4', '6', '8', 'a', 'c', 'e'].includes(lastChar)
388
+ const lastChar = hex[hex.length - 1].toLowerCase()
389
+ return ['0', '2', '4', '6', '8', 'a', 'c', 'e'].includes(lastChar)
380
390
  }
381
391
 
382
392
  interface LegacyVerificationMethod extends VerificationMethod {
383
- publicKeyBase64: string
393
+ publicKeyBase64: string
384
394
  }
385
395
 
386
396
  /**
@@ -393,87 +403,91 @@ interface LegacyVerificationMethod extends VerificationMethod {
393
403
  * @beta This API may change without a BREAKING CHANGE notice.
394
404
  */
395
405
  export function extractPublicKeyHex(pk: _ExtendedVerificationMethod, convert: boolean = false): string {
396
- let keyBytes = extractPublicKeyBytes(pk)
397
- if (convert) {
398
- if (
399
- ['Ed25519', 'Ed25519VerificationKey2018', 'Ed25519VerificationKey2020'].includes(pk.type) ||
400
- (pk.type === 'JsonWebKey2020' && pk.publicKeyJwk?.crv === 'Ed25519')
401
- ) {
402
- keyBytes = convertPublicKeyToX25519(keyBytes)
403
- } else if (
404
- !['X25519', 'X25519KeyAgreementKey2019', 'X25519KeyAgreementKey2020'].includes(pk.type) &&
405
- !(pk.type === 'JsonWebKey2020' && pk.publicKeyJwk?.crv === 'X25519')
406
- ) {
407
- return ''
406
+ let keyBytes = extractPublicKeyBytes(pk)
407
+ if (convert) {
408
+ if (
409
+ ['Ed25519', 'Ed25519VerificationKey2018', 'Ed25519VerificationKey2020'].includes(pk.type) ||
410
+ (pk.type === 'JsonWebKey2020' && pk.publicKeyJwk?.crv === 'Ed25519')
411
+ ) {
412
+ keyBytes = convertPublicKeyToX25519(keyBytes)
413
+ } else if (
414
+ !['X25519', 'X25519KeyAgreementKey2019', 'X25519KeyAgreementKey2020'].includes(pk.type) &&
415
+ !(pk.type === 'JsonWebKey2020' && pk.publicKeyJwk?.crv === 'X25519')
416
+ ) {
417
+ return ''
418
+ }
408
419
  }
409
- }
410
- return bytesToHex(keyBytes)
420
+ return bytesToHex(keyBytes)
421
+ }
422
+
423
+ function toEcLibCurve(input: string) {
424
+ return input.toLowerCase().replace("-", "").replace("_", "")
411
425
  }
412
426
 
413
427
  function extractPublicKeyBytes(pk: VerificationMethod): Uint8Array {
414
- if (pk.publicKeyBase58) {
415
- return base58ToBytes(pk.publicKeyBase58)
416
- } else if (pk.publicKeyMultibase) {
417
- return multibaseKeyToBytes(pk.publicKeyMultibase)
418
- } else if ((<LegacyVerificationMethod>pk).publicKeyBase64) {
419
- return base64ToBytes((<LegacyVerificationMethod>pk).publicKeyBase64)
420
- } else if (pk.publicKeyHex) {
421
- return hexToBytes(pk.publicKeyHex)
422
- } else if (pk.publicKeyJwk && (pk.publicKeyJwk.crv === 'secp256k1' || pk.publicKeyJwk.crv === 'P-256') && pk.publicKeyJwk.x && pk.publicKeyJwk.y) {
423
- const secp = new elliptic.ec(pk.publicKeyJwk.crv)
424
- return hexToBytes(
425
- secp
426
- .keyFromPublic({
427
- x: base64ToHex(pk.publicKeyJwk.x, 'base64url'),
428
- y: base64ToHex(pk.publicKeyJwk.y, 'base64url'),
429
- })
430
- .getPublic('hex')
431
- )
432
- } else if (pk.publicKeyJwk && (pk.publicKeyJwk.crv === 'Ed25519' || pk.publicKeyJwk.crv === 'X25519') && pk.publicKeyJwk.x) {
433
- return base64ToBytes(pk.publicKeyJwk.x)
434
- }
435
- return new Uint8Array()
428
+ if (pk.publicKeyBase58) {
429
+ return base58ToBytes(pk.publicKeyBase58)
430
+ } else if (pk.publicKeyMultibase) {
431
+ return multibaseKeyToBytes(pk.publicKeyMultibase)
432
+ } else if ((<LegacyVerificationMethod>pk).publicKeyBase64) {
433
+ return base64ToBytes((<LegacyVerificationMethod>pk).publicKeyBase64)
434
+ } else if (pk.publicKeyHex) {
435
+ return hexToBytes(pk.publicKeyHex)
436
+ } else if (pk.publicKeyJwk?.crv && pk.publicKeyJwk.x && pk.publicKeyJwk.y) {
437
+ const secp = new elliptic.ec(toEcLibCurve(pk.publicKeyJwk.crv))
438
+ return hexToBytes(
439
+ secp
440
+ .keyFromPublic({
441
+ x: base64ToHex(pk.publicKeyJwk.x, 'base64url'),
442
+ y: base64ToHex(pk.publicKeyJwk.y, 'base64url'),
443
+ })
444
+ .getPublic('hex')
445
+ )
446
+ } else if (pk.publicKeyJwk && (pk.publicKeyJwk.crv === 'Ed25519' || pk.publicKeyJwk.crv === 'X25519') && pk.publicKeyJwk.x) {
447
+ return base64ToBytes(pk.publicKeyJwk.x)
448
+ }
449
+ return new Uint8Array()
436
450
  }
437
451
 
438
452
  export function verificationMethodToJwk(vm: VerificationMethod): JWK {
439
- let jwk: JWK | undefined = vm.publicKeyJwk as JWK
440
- if (!jwk) {
441
- let publicKeyHex = vm.publicKeyHex ?? u8a.toString(extractPublicKeyBytes(vm), 'hex')
442
- jwk = toJwk(publicKeyHex, keyTypeFromCryptographicSuite({ suite: vm.type }))
443
- }
444
- if (!jwk) {
445
- throw Error(`Could not convert verification method to jwk`)
446
- }
447
- jwk.kid = vm.id
448
- return jwk
453
+ let jwk: JWK | undefined = vm.publicKeyJwk as JWK
454
+ if (!jwk) {
455
+ let publicKeyHex = vm.publicKeyHex ?? u8a.toString(extractPublicKeyBytes(vm), 'hex')
456
+ jwk = toJwk(publicKeyHex, keyTypeFromCryptographicSuite({suite: vm.type}))
457
+ }
458
+ if (!jwk) {
459
+ throw Error(`Could not convert verification method to jwk`)
460
+ }
461
+ jwk.kid = vm.id
462
+ return jwk
449
463
  }
450
464
 
451
465
  function didDocumentSectionToJwks(
452
- didDocumentSection: DIDDocumentSection,
453
- searchForVerificationMethods?: (VerificationMethod | string)[],
454
- verificationMethods?: VerificationMethod[]
466
+ didDocumentSection: DIDDocumentSection,
467
+ searchForVerificationMethods?: (VerificationMethod | string)[],
468
+ verificationMethods?: VerificationMethod[]
455
469
  ) {
456
- const jwks = (searchForVerificationMethods ?? [])
457
- .map((vmOrId) => (typeof vmOrId === 'object' ? vmOrId : verificationMethods?.find((vm) => vm.id === vmOrId)))
458
- .filter(isDefined)
459
- .map((vm) => verificationMethodToJwk(vm))
460
- return { didDocumentSection, jwks: jwks }
470
+ const jwks = (searchForVerificationMethods ?? [])
471
+ .map((vmOrId) => (typeof vmOrId === 'object' ? vmOrId : verificationMethods?.find((vm) => vm.id === vmOrId)))
472
+ .filter(isDefined)
473
+ .map((vm) => verificationMethodToJwk(vm))
474
+ return {didDocumentSection, jwks: jwks}
461
475
  }
462
476
 
463
477
  export type DidDocumentJwks = Record<Exclude<DIDDocumentSection, 'publicKey' | 'service'>, Array<JWK>>
464
478
 
465
479
  export function didDocumentToJwks(didDocument: DIDDocument): DidDocumentJwks {
466
- return {
467
- verificationMethod: [
468
- ...didDocumentSectionToJwks('publicKey', didDocument.publicKey, didDocument.verificationMethod).jwks, // legacy support
469
- ...didDocumentSectionToJwks('verificationMethod', didDocument.verificationMethod, didDocument.verificationMethod).jwks,
470
- ],
471
- assertionMethod: didDocumentSectionToJwks('assertionMethod', didDocument.assertionMethod, didDocument.verificationMethod).jwks,
472
- authentication: didDocumentSectionToJwks('authentication', didDocument.authentication, didDocument.verificationMethod).jwks,
473
- keyAgreement: didDocumentSectionToJwks('keyAgreement', didDocument.keyAgreement, didDocument.verificationMethod).jwks,
474
- capabilityInvocation: didDocumentSectionToJwks('capabilityInvocation', didDocument.capabilityInvocation, didDocument.verificationMethod).jwks,
475
- capabilityDelegation: didDocumentSectionToJwks('capabilityDelegation', didDocument.capabilityDelegation, didDocument.verificationMethod).jwks,
476
- }
480
+ return {
481
+ verificationMethod: [
482
+ ...didDocumentSectionToJwks('publicKey', didDocument.publicKey, didDocument.verificationMethod).jwks, // legacy support
483
+ ...didDocumentSectionToJwks('verificationMethod', didDocument.verificationMethod, didDocument.verificationMethod).jwks,
484
+ ],
485
+ assertionMethod: didDocumentSectionToJwks('assertionMethod', didDocument.assertionMethod, didDocument.verificationMethod).jwks,
486
+ authentication: didDocumentSectionToJwks('authentication', didDocument.authentication, didDocument.verificationMethod).jwks,
487
+ keyAgreement: didDocumentSectionToJwks('keyAgreement', didDocument.keyAgreement, didDocument.verificationMethod).jwks,
488
+ capabilityInvocation: didDocumentSectionToJwks('capabilityInvocation', didDocument.capabilityInvocation, didDocument.verificationMethod).jwks,
489
+ capabilityDelegation: didDocumentSectionToJwks('capabilityDelegation', didDocument.capabilityDelegation, didDocument.verificationMethod).jwks,
490
+ }
477
491
  }
478
492
 
479
493
  /**
@@ -494,58 +508,58 @@ export function didDocumentToJwks(didDocument: DIDDocument): DidDocumentJwks {
494
508
  * @beta This API may change without a BREAKING CHANGE notice.
495
509
  */
496
510
  export async function mapIdentifierKeysToDocWithJwkSupport(
497
- {
498
- identifier,
499
- vmRelationship = 'verificationMethod',
500
- didDocument,
501
- }: {
502
- identifier: IIdentifier
503
- vmRelationship?: DIDDocumentSection
504
- didDocument?: DIDDocument
505
- },
506
- context: IAgentContext<IResolver & IDIDManager>
511
+ {
512
+ identifier,
513
+ vmRelationship = 'verificationMethod',
514
+ didDocument,
515
+ }: {
516
+ identifier: IIdentifier
517
+ vmRelationship?: DIDDocumentSection
518
+ didDocument?: DIDDocument
519
+ },
520
+ context: IAgentContext<IResolver & IDIDManager>
507
521
  ): Promise<_ExtendedIKey[]> {
508
- const didDoc =
509
- didDocument ??
510
- (await getAgentResolver(context)
511
- .resolve(identifier.did)
512
- .then((result) => result.didDocument))
513
- if (!didDoc) {
514
- throw Error(`Could not resolve DID ${identifier.did}`)
515
- }
516
-
517
- // const rsaDidWeb = identifier.keys && identifier.keys.length > 0 && identifier.keys.find((key) => key.type === 'RSA') && didDocument
518
-
519
- // We skip mapping in case the identifier is RSA and a did document is supplied.
520
- const keys = didDoc ? [] : await mapIdentifierKeysToDoc(identifier, vmRelationship, context)
521
-
522
- // dereference all key agreement keys from DID document and normalize
523
- const documentKeys: VerificationMethod[] = await dereferenceDidKeysWithJwkSupport(didDoc, vmRelationship, context)
524
-
525
- const localKeys = vmRelationship === 'keyAgreement' ? convertIdentifierEncryptionKeys(identifier) : compressIdentifierSecp256k1Keys(identifier)
526
-
527
- // finally map the didDocument keys to the identifier keys by comparing `publicKeyHex`
528
- const extendedKeys: _ExtendedIKey[] = documentKeys
529
- .map((verificationMethod) => {
530
- /*if (verificationMethod.type !== 'JsonWebKey2020') {
531
- return null
532
- }*/
533
- const localKey = localKeys.find(
534
- (localKey) =>
535
- localKey.publicKeyHex === verificationMethod.publicKeyHex ||
536
- verificationMethod.publicKeyHex?.startsWith(localKey.publicKeyHex) ||
537
- compareBlockchainAccountId(localKey, verificationMethod)
538
- )
539
- if (localKey) {
540
- const { meta, ...localProps } = localKey
541
- return { ...localProps, meta: { ...meta, verificationMethod } }
542
- } else {
543
- return null
544
- }
545
- })
546
- .filter(isDefined)
522
+ const didDoc =
523
+ didDocument ??
524
+ (await getAgentResolver(context)
525
+ .resolve(identifier.did)
526
+ .then((result) => result.didDocument))
527
+ if (!didDoc) {
528
+ throw Error(`Could not resolve DID ${identifier.did}`)
529
+ }
530
+
531
+ // const rsaDidWeb = identifier.keys && identifier.keys.length > 0 && identifier.keys.find((key) => key.type === 'RSA') && didDocument
547
532
 
548
- return keys.concat(extendedKeys)
533
+ // We skip mapping in case the identifier is RSA and a did document is supplied.
534
+ const keys = didDoc ? [] : await mapIdentifierKeysToDoc(identifier, vmRelationship, context)
535
+
536
+ // dereference all key agreement keys from DID document and normalize
537
+ const documentKeys: VerificationMethod[] = await dereferenceDidKeysWithJwkSupport(didDoc, vmRelationship, context)
538
+
539
+ const localKeys = vmRelationship === 'keyAgreement' ? convertIdentifierEncryptionKeys(identifier) : compressIdentifierSecp256k1Keys(identifier)
540
+
541
+ // finally map the didDocument keys to the identifier keys by comparing `publicKeyHex`
542
+ const extendedKeys: _ExtendedIKey[] = documentKeys
543
+ .map((verificationMethod) => {
544
+ /*if (verificationMethod.type !== 'JsonWebKey2020') {
545
+ return null
546
+ }*/
547
+ const localKey = localKeys.find(
548
+ (localKey) =>
549
+ localKey.publicKeyHex === verificationMethod.publicKeyHex ||
550
+ verificationMethod.publicKeyHex?.startsWith(localKey.publicKeyHex) ||
551
+ compareBlockchainAccountId(localKey, verificationMethod)
552
+ )
553
+ if (localKey) {
554
+ const {meta, ...localProps} = localKey
555
+ return {...localProps, meta: {...meta, verificationMethod}}
556
+ } else {
557
+ return null
558
+ }
559
+ })
560
+ .filter(isDefined)
561
+
562
+ return keys.concat(extendedKeys)
549
563
  }
550
564
 
551
565
  /**
@@ -561,96 +575,96 @@ export async function mapIdentifierKeysToDocWithJwkSupport(
561
575
  * @beta This API may change without a BREAKING CHANGE notice.
562
576
  */
563
577
  function compareBlockchainAccountId(localKey: IKey, verificationMethod: VerificationMethod): boolean {
564
- if (
565
- (verificationMethod.type !== 'EcdsaSecp256k1RecoveryMethod2020' && verificationMethod.type !== 'EcdsaSecp256k1VerificationKey2019') ||
566
- localKey.type !== 'Secp256k1'
567
- ) {
568
- return false
569
- }
570
- let vmEthAddr = getEthereumAddress(verificationMethod)
571
- if (localKey.meta?.account) {
572
- return vmEthAddr === localKey.meta?.account.toLowerCase()
573
- }
574
- const computedAddr = computeAddress('0x' + localKey.publicKeyHex).toLowerCase()
575
- return computedAddr === vmEthAddr
578
+ if (
579
+ (verificationMethod.type !== 'EcdsaSecp256k1RecoveryMethod2020' && verificationMethod.type !== 'EcdsaSecp256k1VerificationKey2019') ||
580
+ localKey.type !== 'Secp256k1'
581
+ ) {
582
+ return false
583
+ }
584
+ let vmEthAddr = getEthereumAddress(verificationMethod)
585
+ if (localKey.meta?.account) {
586
+ return vmEthAddr === localKey.meta?.account.toLowerCase()
587
+ }
588
+ const computedAddr = computeAddress('0x' + localKey.publicKeyHex).toLowerCase()
589
+ return computedAddr === vmEthAddr
576
590
  }
577
591
 
578
592
  export async function getAgentDIDMethods(context: IAgentContext<IDIDManager>) {
579
- return (await context.agent.didManagerGetProviders()).map((provider) => provider.toLowerCase().replace('did:', ''))
593
+ return (await context.agent.didManagerGetProviders()).map((provider) => provider.toLowerCase().replace('did:', ''))
580
594
  }
581
595
 
582
596
  export function getDID(idOpts: { identifier: IIdentifier | string }): string {
583
- if (typeof idOpts.identifier === 'string') {
584
- return idOpts.identifier
585
- } else if (typeof idOpts.identifier === 'object') {
586
- return idOpts.identifier.did
587
- }
588
- throw Error(`Cannot get DID from identifier value`)
597
+ if (typeof idOpts.identifier === 'string') {
598
+ return idOpts.identifier
599
+ } else if (typeof idOpts.identifier === 'object') {
600
+ return idOpts.identifier.did
601
+ }
602
+ throw Error(`Cannot get DID from identifier value`)
589
603
  }
590
604
 
591
605
  export function toDID(identifier: string | IIdentifier | Partial<IIdentifier>): string {
592
- if (typeof identifier === 'string') {
593
- return identifier
594
- }
595
- if (identifier.did) {
596
- return identifier.did
597
- }
598
- throw Error(`No DID value present in identifier`)
606
+ if (typeof identifier === 'string') {
607
+ return identifier
608
+ }
609
+ if (identifier.did) {
610
+ return identifier.did
611
+ }
612
+ throw Error(`No DID value present in identifier`)
599
613
  }
600
614
 
601
615
  export function toDIDs(identifiers?: (string | IIdentifier | Partial<IIdentifier>)[]): string[] {
602
- if (!identifiers) {
603
- return []
604
- }
605
- return identifiers.map(toDID)
616
+ if (!identifiers) {
617
+ return []
618
+ }
619
+ return identifiers.map(toDID)
606
620
  }
607
621
 
608
622
  export async function getKey(
609
- {
610
- identifier,
611
- vmRelationship = 'authentication',
612
- kmsKeyRef,
613
- }: {
614
- identifier: IIdentifier
615
- vmRelationship?: DIDDocumentSection
616
- kmsKeyRef?: string
617
- },
618
- context: IAgentContext<IResolver & IDIDManager>
623
+ {
624
+ identifier,
625
+ vmRelationship = 'authentication',
626
+ kmsKeyRef,
627
+ }: {
628
+ identifier: IIdentifier
629
+ vmRelationship?: DIDDocumentSection
630
+ kmsKeyRef?: string
631
+ },
632
+ context: IAgentContext<IResolver & IDIDManager>
619
633
  ): Promise<IKey> {
620
- if (!identifier) {
621
- return Promise.reject(new Error(`No identifier provided to getKey method!`))
622
- }
623
- // normalize to kid, in case keyId was passed in as did#vm or #vm
624
- const kmsKeyRefParts = kmsKeyRef?.split(`#`)
625
- const kid = kmsKeyRefParts ? (kmsKeyRefParts?.length === 2 ? kmsKeyRefParts[1] : kmsKeyRefParts[0]) : undefined
626
- // todo: We really should do a keyRef and external kid here
627
- let identifierKey = kmsKeyRef ? identifier.keys.find((key: IKey) => key.kid === kid || key?.meta?.jwkThumbprint === kid) : undefined
628
- if (!identifierKey) {
629
- const keys = await mapIdentifierKeysToDocWithJwkSupport({ identifier, vmRelationship: vmRelationship }, context)
630
- if (!keys || keys.length === 0) {
631
- throw new Error(`No keys found for verificationMethodSection: ${vmRelationship} and did ${identifier.did}`)
632
- }
633
- if (kmsKeyRef) {
634
- identifierKey = keys.find(
635
- (key: _ExtendedIKey) => key.meta.verificationMethod?.id === kmsKeyRef || (kid && key.meta.verificationMethod?.id?.includes(kid))
636
- )
634
+ if (!identifier) {
635
+ return Promise.reject(new Error(`No identifier provided to getKey method!`))
637
636
  }
637
+ // normalize to kid, in case keyId was passed in as did#vm or #vm
638
+ const kmsKeyRefParts = kmsKeyRef?.split(`#`)
639
+ const kid = kmsKeyRefParts ? (kmsKeyRefParts?.length === 2 ? kmsKeyRefParts[1] : kmsKeyRefParts[0]) : undefined
640
+ // todo: We really should do a keyRef and external kid here
641
+ let identifierKey = kmsKeyRef ? identifier.keys.find((key: IKey) => key.kid === kid || key?.meta?.jwkThumbprint === kid) : undefined
638
642
  if (!identifierKey) {
639
- identifierKey = keys.find(
640
- (key: _ExtendedIKey) => key.meta.verificationMethod?.type === vmRelationship || key.meta.purposes?.includes(vmRelationship)
641
- )
643
+ const keys = await mapIdentifierKeysToDocWithJwkSupport({identifier, vmRelationship: vmRelationship}, context)
644
+ if (!keys || keys.length === 0) {
645
+ throw new Error(`No keys found for verificationMethodSection: ${vmRelationship} and did ${identifier.did}`)
646
+ }
647
+ if (kmsKeyRef) {
648
+ identifierKey = keys.find(
649
+ (key: _ExtendedIKey) => key.meta.verificationMethod?.id === kmsKeyRef || (kid && key.meta.verificationMethod?.id?.includes(kid))
650
+ )
651
+ }
652
+ if (!identifierKey) {
653
+ identifierKey = keys.find(
654
+ (key: _ExtendedIKey) => key.meta.verificationMethod?.type === vmRelationship || key.meta.purposes?.includes(vmRelationship)
655
+ )
656
+ }
657
+ if (!identifierKey) {
658
+ identifierKey = keys[0]
659
+ }
642
660
  }
643
661
  if (!identifierKey) {
644
- identifierKey = keys[0]
662
+ throw new Error(
663
+ `No matching verificationMethodSection key found for keyId: ${kmsKeyRef} and vmSection: ${vmRelationship} for id ${identifier.did}`
664
+ )
645
665
  }
646
- }
647
- if (!identifierKey) {
648
- throw new Error(
649
- `No matching verificationMethodSection key found for keyId: ${kmsKeyRef} and vmSection: ${vmRelationship} for id ${identifier.did}`
650
- )
651
- }
652
666
 
653
- return identifierKey
667
+ return identifierKey
654
668
  }
655
669
 
656
670
  /**
@@ -661,17 +675,17 @@ export async function getKey(
661
675
  * @deprecated Replaced by the identfier resolution plugin
662
676
  */
663
677
  async function legacyGetIdentifier(
664
- {
665
- identifier,
666
- }: {
667
- identifier: string | IIdentifier
668
- },
669
- context: IAgentContext<IDIDManager>
678
+ {
679
+ identifier,
680
+ }: {
681
+ identifier: string | IIdentifier
682
+ },
683
+ context: IAgentContext<IDIDManager>
670
684
  ): Promise<IIdentifier> {
671
- if (typeof identifier === 'string') {
672
- return await context.agent.didManagerGet({ did: identifier })
673
- }
674
- return identifier
685
+ if (typeof identifier === 'string') {
686
+ return await context.agent.didManagerGet({did: identifier})
687
+ }
688
+ return identifier
675
689
  }
676
690
 
677
691
  /**
@@ -681,132 +695,132 @@ async function legacyGetIdentifier(
681
695
  * @param context
682
696
  */
683
697
  export async function determineKid(
684
- {
685
- key,
686
- idOpts,
687
- }: {
688
- key: IKey
689
- idOpts: { identifier: IIdentifier | string; kmsKeyRef?: string }
690
- },
691
- context: IAgentContext<IResolver & IDIDManager>
692
- ): Promise<string> {
693
- if (key.meta?.verificationMethod?.id) {
694
- return key.meta?.verificationMethod?.id
695
- }
696
- const identifier = await legacyGetIdentifier(idOpts, context)
697
- const mappedKeys = await mapIdentifierKeysToDocWithJwkSupport(
698
698
  {
699
- identifier,
700
- vmRelationship: 'verificationMethod',
699
+ key,
700
+ idOpts,
701
+ }: {
702
+ key: IKey
703
+ idOpts: { identifier: IIdentifier | string; kmsKeyRef?: string }
701
704
  },
702
- context
703
- )
704
- const vmKey = mappedKeys.find((extendedKey) => extendedKey.kid === key.kid)
705
- if (vmKey) {
706
- return vmKey.meta?.verificationMethod?.id ?? vmKey.meta?.jwkThumbprint ?? idOpts.kmsKeyRef ?? vmKey.kid
707
- }
705
+ context: IAgentContext<IResolver & IDIDManager>
706
+ ): Promise<string> {
707
+ if (key.meta?.verificationMethod?.id) {
708
+ return key.meta?.verificationMethod?.id
709
+ }
710
+ const identifier = await legacyGetIdentifier(idOpts, context)
711
+ const mappedKeys = await mapIdentifierKeysToDocWithJwkSupport(
712
+ {
713
+ identifier,
714
+ vmRelationship: 'verificationMethod',
715
+ },
716
+ context
717
+ )
718
+ const vmKey = mappedKeys.find((extendedKey) => extendedKey.kid === key.kid)
719
+ if (vmKey) {
720
+ return vmKey.meta?.verificationMethod?.id ?? vmKey.meta?.jwkThumbprint ?? idOpts.kmsKeyRef ?? vmKey.kid
721
+ }
708
722
 
709
- return key.meta?.jwkThumbprint ?? idOpts.kmsKeyRef ?? key.kid
723
+ return key.meta?.jwkThumbprint ?? idOpts.kmsKeyRef ?? key.kid
710
724
  }
711
725
 
712
726
  export async function getSupportedDIDMethods(didOpts: IDIDOptions, context: IAgentContext<IDIDManager>) {
713
- return didOpts.supportedDIDMethods ?? (await getAgentDIDMethods(context))
727
+ return didOpts.supportedDIDMethods ?? (await getAgentDIDMethods(context))
714
728
  }
715
729
 
716
730
  export function getAgentResolver(
717
- context: IAgentContext<IResolver & IDIDManager>,
718
- opts?: {
719
- localResolution?: boolean // Resolve identifiers hosted by the agent
720
- uniresolverResolution?: boolean // Resolve identifiers using universal resolver
721
- resolverResolution?: boolean // Use registered drivers
722
- }
731
+ context: IAgentContext<IResolver & IDIDManager>,
732
+ opts?: {
733
+ localResolution?: boolean // Resolve identifiers hosted by the agent
734
+ uniresolverResolution?: boolean // Resolve identifiers using universal resolver
735
+ resolverResolution?: boolean // Use registered drivers
736
+ }
723
737
  ): Resolvable {
724
- return new AgentDIDResolver(context, opts)
738
+ return new AgentDIDResolver(context, opts)
725
739
  }
726
740
 
727
741
  export class AgentDIDResolver implements Resolvable {
728
- private readonly context: IAgentContext<IResolver & IDIDManager>
729
- private readonly resolverResolution: boolean
730
- private readonly uniresolverResolution: boolean
731
- private readonly localResolution: boolean
742
+ private readonly context: IAgentContext<IResolver & IDIDManager>
743
+ private readonly resolverResolution: boolean
744
+ private readonly uniresolverResolution: boolean
745
+ private readonly localResolution: boolean
746
+
747
+ constructor(
748
+ context: IAgentContext<IResolver & IDIDManager>,
749
+ opts?: { uniresolverResolution?: boolean; localResolution?: boolean; resolverResolution?: boolean }
750
+ ) {
751
+ this.context = context
752
+ this.resolverResolution = opts?.resolverResolution !== false
753
+ this.uniresolverResolution = opts?.uniresolverResolution !== false
754
+ this.localResolution = opts?.localResolution !== false
755
+ }
732
756
 
733
- constructor(
734
- context: IAgentContext<IResolver & IDIDManager>,
735
- opts?: { uniresolverResolution?: boolean; localResolution?: boolean; resolverResolution?: boolean }
736
- ) {
737
- this.context = context
738
- this.resolverResolution = opts?.resolverResolution !== false
739
- this.uniresolverResolution = opts?.uniresolverResolution !== false
740
- this.localResolution = opts?.localResolution !== false
741
- }
742
-
743
- async resolve(didUrl: string, options?: DIDResolutionOptions): Promise<DIDResolutionResult> {
744
- let resolutionResult: DIDResolutionResult | undefined
745
- let origResolutionResult: DIDResolutionResult | undefined
746
- let err: any
747
- if (!this.resolverResolution && !this.localResolution && !this.uniresolverResolution) {
748
- throw Error(`No agent hosted DID resolution, regular agent resolution nor universal resolver resolution is enabled. Cannot resolve DIDs.`)
749
- }
750
- if (this.resolverResolution) {
751
- try {
752
- resolutionResult = await this.context.agent.resolveDid({ didUrl, options })
753
- } catch (error: unknown) {
754
- err = error
755
- }
756
- }
757
- if (resolutionResult) {
758
- origResolutionResult = resolutionResult
759
- if (resolutionResult.didDocument === null) {
760
- resolutionResult = undefined
761
- }
762
- } else {
763
- console.log(`Agent resolver resolution is disabled. This typically isn't desirable!`)
764
- }
765
- if (!resolutionResult && this.localResolution) {
766
- console.log(`Using local DID resolution, looking at DIDs hosted by the agent.`)
767
- try {
768
- const did = didUrl.split('#')[0]
769
- const iIdentifier = await this.context.agent.didManagerGet({ did })
770
- resolutionResult = toDidResolutionResult(iIdentifier, { did })
771
- if (resolutionResult.didDocument) {
772
- err = undefined
757
+ async resolve(didUrl: string, options?: DIDResolutionOptions): Promise<DIDResolutionResult> {
758
+ let resolutionResult: DIDResolutionResult | undefined
759
+ let origResolutionResult: DIDResolutionResult | undefined
760
+ let err: any
761
+ if (!this.resolverResolution && !this.localResolution && !this.uniresolverResolution) {
762
+ throw Error(`No agent hosted DID resolution, regular agent resolution nor universal resolver resolution is enabled. Cannot resolve DIDs.`)
763
+ }
764
+ if (this.resolverResolution) {
765
+ try {
766
+ resolutionResult = await this.context.agent.resolveDid({didUrl, options})
767
+ } catch (error: unknown) {
768
+ err = error
769
+ }
770
+ }
771
+ if (resolutionResult) {
772
+ origResolutionResult = resolutionResult
773
+ if (resolutionResult.didDocument === null) {
774
+ resolutionResult = undefined
775
+ }
773
776
  } else {
774
- console.log(`Local resolution resulted in a DID Document for ${did}`)
777
+ console.log(`Agent resolver resolution is disabled. This typically isn't desirable!`)
775
778
  }
776
- } catch (error: unknown) {
777
- if (!err) {
778
- err = error
779
+ if (!resolutionResult && this.localResolution) {
780
+ console.log(`Using local DID resolution, looking at DIDs hosted by the agent.`)
781
+ try {
782
+ const did = didUrl.split('#')[0]
783
+ const iIdentifier = await this.context.agent.didManagerGet({did})
784
+ resolutionResult = toDidResolutionResult(iIdentifier, {did})
785
+ if (resolutionResult.didDocument) {
786
+ err = undefined
787
+ } else {
788
+ console.log(`Local resolution resulted in a DID Document for ${did}`)
789
+ }
790
+ } catch (error: unknown) {
791
+ if (!err) {
792
+ err = error
793
+ }
794
+ }
795
+ }
796
+ if (resolutionResult) {
797
+ if (!origResolutionResult) {
798
+ origResolutionResult = resolutionResult
799
+ }
800
+ if (!resolutionResult.didDocument) {
801
+ resolutionResult = undefined
802
+ }
803
+ }
804
+ if (!resolutionResult && this.uniresolverResolution) {
805
+ console.log(`Using universal resolver resolution for did ${didUrl} `)
806
+ resolutionResult = await new UniResolver().resolve(didUrl, options)
807
+ if (!origResolutionResult) {
808
+ origResolutionResult = resolutionResult
809
+ }
810
+ if (resolutionResult.didDocument) {
811
+ err = undefined
812
+ }
779
813
  }
780
- }
781
- }
782
- if (resolutionResult) {
783
- if (!origResolutionResult) {
784
- origResolutionResult = resolutionResult
785
- }
786
- if (!resolutionResult.didDocument) {
787
- resolutionResult = undefined
788
- }
789
- }
790
- if (!resolutionResult && this.uniresolverResolution) {
791
- console.log(`Using universal resolver resolution for did ${didUrl} `)
792
- resolutionResult = await new UniResolver().resolve(didUrl, options)
793
- if (!origResolutionResult) {
794
- origResolutionResult = resolutionResult
795
- }
796
- if (resolutionResult.didDocument) {
797
- err = undefined
798
- }
799
- }
800
814
 
801
- if (err) {
802
- // throw original error
803
- throw err
804
- }
805
- if (!resolutionResult && !origResolutionResult) {
806
- throw `Could not resolve ${didUrl}. Resolutions tried: online: ${this.resolverResolution}, local: ${this.localResolution}, uni resolver: ${this.uniresolverResolution}`
815
+ if (err) {
816
+ // throw original error
817
+ throw err
818
+ }
819
+ if (!resolutionResult && !origResolutionResult) {
820
+ throw `Could not resolve ${didUrl}. Resolutions tried: online: ${this.resolverResolution}, local: ${this.localResolution}, uni resolver: ${this.uniresolverResolution}`
821
+ }
822
+ return resolutionResult ?? origResolutionResult!
807
823
  }
808
- return resolutionResult ?? origResolutionResult!
809
- }
810
824
  }
811
825
 
812
826
  /**
@@ -820,190 +834,190 @@ export class AgentDIDResolver implements Resolvable {
820
834
  * @param opts
821
835
  */
822
836
  export function toDidDocument(
823
- identifier?: IIdentifier,
824
- opts?: {
825
- did?: string
826
- use?: JwkKeyUse[]
827
- }
837
+ identifier?: IIdentifier,
838
+ opts?: {
839
+ did?: string
840
+ use?: JwkKeyUse[]
841
+ }
828
842
  ): DIDDocument | undefined {
829
- let didDocument: DIDDocument | undefined = undefined
830
- // TODO: Introduce jwk thumbprints here
831
- if (identifier) {
832
- const did = identifier.did ?? opts?.did
833
- didDocument = {
834
- '@context': 'https://www.w3.org/ns/did/v1',
835
- id: did,
836
- verificationMethod: identifier.keys.map((key) => {
837
- const vm: VerificationMethod = {
838
- controller: did,
839
- id: key.kid.startsWith(did) && key.kid.includes('#') ? key.kid : `${did}#${key.kid}`,
840
- publicKeyJwk: toJwk(key.publicKeyHex, key.type, {
841
- use: ENC_KEY_ALGS.includes(key.type) ? JwkKeyUse.Encryption : JwkKeyUse.Signature,
842
- key,
843
- }) as JsonWebKey,
844
- type: 'JsonWebKey2020',
845
- }
846
- return vm
847
- }),
848
- ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Signature)) &&
849
- identifier.keys && {
850
- assertionMethod: identifier.keys
851
- .filter(
852
- (key) =>
853
- key?.meta?.purpose === undefined || key?.meta?.purpose === 'assertionMethod' || key?.meta?.purposes?.includes('assertionMethod')
854
- )
855
- .map((key) => {
856
- if (key.kid.startsWith(did) && key.kid.includes('#')) {
857
- return key.kid
858
- }
859
- return `${did}#${key.kid}`
860
- }),
861
- }),
862
- ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Signature)) &&
863
- identifier.keys && {
864
- authentication: identifier.keys
865
- .filter(
866
- (key) => key?.meta?.purpose === undefined || key?.meta?.purpose === 'authentication' || key?.meta?.purposes?.includes('authentication')
867
- )
868
- .map((key) => {
869
- if (key.kid.startsWith(did) && key.kid.includes('#')) {
870
- return key.kid
871
- }
872
- return `${did}#${key.kid}`
873
- }),
874
- }),
875
- ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Encryption)) &&
876
- identifier.keys && {
877
- keyAgreement: identifier.keys
878
- .filter((key) => key.type === 'X25519' || key?.meta?.purpose === 'keyAgreement' || key?.meta?.purposes?.includes('keyAgreement'))
879
- .map((key) => {
880
- if (key.kid.startsWith(did) && key.kid.includes('#')) {
881
- return key.kid
882
- }
883
- return `${did}#${key.kid}`
884
- }),
885
- }),
886
- ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Encryption)) &&
887
- identifier.keys && {
888
- capabilityInvocation: identifier.keys
889
- .filter(
890
- (key) => key.type === 'X25519' || key?.meta?.purpose === 'capabilityInvocation' || key?.meta?.purposes?.includes('capabilityInvocation')
891
- )
892
- .map((key) => {
893
- if (key.kid.startsWith(did) && key.kid.includes('#')) {
894
- return key.kid
895
- }
896
- return `${did}#${key.kid}`
897
- }),
898
- }),
899
- ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Encryption)) &&
900
- identifier.keys && {
901
- capabilityDelegation: identifier.keys
902
- .filter(
903
- (key) => key.type === 'X25519' || key?.meta?.purpose === 'capabilityDelegation' || key?.meta?.purposes?.includes('capabilityDelegation')
904
- )
905
- .map((key) => {
906
- if (key.kid.startsWith(did) && key.kid.includes('#')) {
907
- return key.kid
908
- }
909
- return `${did}#${key.kid}`
843
+ let didDocument: DIDDocument | undefined = undefined
844
+ // TODO: Introduce jwk thumbprints here
845
+ if (identifier) {
846
+ const did = identifier.did ?? opts?.did
847
+ didDocument = {
848
+ '@context': 'https://www.w3.org/ns/did/v1',
849
+ id: did,
850
+ verificationMethod: identifier.keys.map((key) => {
851
+ const vm: VerificationMethod = {
852
+ controller: did,
853
+ id: key.kid.startsWith(did) && key.kid.includes('#') ? key.kid : `${did}#${key.kid}`,
854
+ publicKeyJwk: toJwk(key.publicKeyHex, key.type, {
855
+ use: ENC_KEY_ALGS.includes(key.type) ? JwkKeyUse.Encryption : JwkKeyUse.Signature,
856
+ key,
857
+ }) as JsonWebKey,
858
+ type: 'JsonWebKey2020',
859
+ }
860
+ return vm
910
861
  }),
911
- }),
912
- ...(identifier.services && identifier.services.length > 0 && { service: identifier.services }),
862
+ ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Signature)) &&
863
+ identifier.keys && {
864
+ assertionMethod: identifier.keys
865
+ .filter(
866
+ (key) =>
867
+ key?.meta?.purpose === undefined || key?.meta?.purpose === 'assertionMethod' || key?.meta?.purposes?.includes('assertionMethod')
868
+ )
869
+ .map((key) => {
870
+ if (key.kid.startsWith(did) && key.kid.includes('#')) {
871
+ return key.kid
872
+ }
873
+ return `${did}#${key.kid}`
874
+ }),
875
+ }),
876
+ ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Signature)) &&
877
+ identifier.keys && {
878
+ authentication: identifier.keys
879
+ .filter(
880
+ (key) => key?.meta?.purpose === undefined || key?.meta?.purpose === 'authentication' || key?.meta?.purposes?.includes('authentication')
881
+ )
882
+ .map((key) => {
883
+ if (key.kid.startsWith(did) && key.kid.includes('#')) {
884
+ return key.kid
885
+ }
886
+ return `${did}#${key.kid}`
887
+ }),
888
+ }),
889
+ ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Encryption)) &&
890
+ identifier.keys && {
891
+ keyAgreement: identifier.keys
892
+ .filter((key) => key.type === 'X25519' || key?.meta?.purpose === 'keyAgreement' || key?.meta?.purposes?.includes('keyAgreement'))
893
+ .map((key) => {
894
+ if (key.kid.startsWith(did) && key.kid.includes('#')) {
895
+ return key.kid
896
+ }
897
+ return `${did}#${key.kid}`
898
+ }),
899
+ }),
900
+ ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Encryption)) &&
901
+ identifier.keys && {
902
+ capabilityInvocation: identifier.keys
903
+ .filter(
904
+ (key) => key.type === 'X25519' || key?.meta?.purpose === 'capabilityInvocation' || key?.meta?.purposes?.includes('capabilityInvocation')
905
+ )
906
+ .map((key) => {
907
+ if (key.kid.startsWith(did) && key.kid.includes('#')) {
908
+ return key.kid
909
+ }
910
+ return `${did}#${key.kid}`
911
+ }),
912
+ }),
913
+ ...((opts?.use === undefined || opts?.use?.includes(JwkKeyUse.Encryption)) &&
914
+ identifier.keys && {
915
+ capabilityDelegation: identifier.keys
916
+ .filter(
917
+ (key) => key.type === 'X25519' || key?.meta?.purpose === 'capabilityDelegation' || key?.meta?.purposes?.includes('capabilityDelegation')
918
+ )
919
+ .map((key) => {
920
+ if (key.kid.startsWith(did) && key.kid.includes('#')) {
921
+ return key.kid
922
+ }
923
+ return `${did}#${key.kid}`
924
+ }),
925
+ }),
926
+ ...(identifier.services && identifier.services.length > 0 && {service: identifier.services}),
927
+ }
913
928
  }
914
- }
915
- return didDocument
929
+ return didDocument
916
930
  }
917
931
 
918
932
  export function toDidResolutionResult(
919
- identifier?: IIdentifier,
920
- opts?: {
921
- did?: string
922
- supportedMethods?: string[]
923
- }
933
+ identifier?: IIdentifier,
934
+ opts?: {
935
+ did?: string
936
+ supportedMethods?: string[]
937
+ }
924
938
  ): DIDResolutionResult {
925
- const didDocument = toDidDocument(identifier, opts) ?? null // null is used in case of errors and required by the did resolution spec
926
-
927
- const resolutionResult: DIDResolutionResult = {
928
- '@context': 'https://w3id.org/did-resolution/v1',
929
- didDocument,
930
- didResolutionMetadata: {
931
- ...(!didDocument && { error: 'notFound' }),
932
- ...(Array.isArray(opts?.supportedMethods) &&
933
- identifier &&
934
- !opts?.supportedMethods.includes(identifier.provider.replace('did:', '')) && { error: 'unsupportedDidMethod' }),
935
- },
936
- didDocumentMetadata: {
937
- ...(identifier?.alias && { equivalentId: identifier?.alias }),
938
- },
939
- }
940
- return resolutionResult
939
+ const didDocument = toDidDocument(identifier, opts) ?? null // null is used in case of errors and required by the did resolution spec
940
+
941
+ const resolutionResult: DIDResolutionResult = {
942
+ '@context': 'https://w3id.org/did-resolution/v1',
943
+ didDocument,
944
+ didResolutionMetadata: {
945
+ ...(!didDocument && {error: 'notFound'}),
946
+ ...(Array.isArray(opts?.supportedMethods) &&
947
+ identifier &&
948
+ !opts?.supportedMethods.includes(identifier.provider.replace('did:', '')) && {error: 'unsupportedDidMethod'}),
949
+ },
950
+ didDocumentMetadata: {
951
+ ...(identifier?.alias && {equivalentId: identifier?.alias}),
952
+ },
953
+ }
954
+ return resolutionResult
941
955
  }
942
956
 
943
957
  export async function asDidWeb(hostnameOrDID: string): Promise<string> {
944
- let did = hostnameOrDID
945
- if (!did) {
946
- throw Error('Domain or DID expected, but received nothing.')
947
- }
948
- if (did.startsWith('did:web:')) {
949
- return did
950
- }
951
- return `did:web:${did.replace(/https?:\/\/([^/?#]+).*/i, '$1').toLowerCase()}`
958
+ let did = hostnameOrDID
959
+ if (!did) {
960
+ throw Error('Domain or DID expected, but received nothing.')
961
+ }
962
+ if (did.startsWith('did:web:')) {
963
+ return did
964
+ }
965
+ return `did:web:${did.replace(/https?:\/\/([^/?#]+).*/i, '$1').toLowerCase()}`
952
966
  }
953
967
 
954
968
  /**
955
969
  * @deprecated Replaced by the new signer service
956
970
  */
957
971
  export const signDidJWT = async (args: SignJwtArgs): Promise<string> => {
958
- const { idOpts, header, payload, context, options } = args
959
- const jwtOptions = {
960
- ...options,
961
- signer: await getDidSigner({ idOpts, context }),
962
- }
972
+ const {idOpts, header, payload, context, options} = args
973
+ const jwtOptions = {
974
+ ...options,
975
+ signer: await getDidSigner({idOpts, context}),
976
+ }
963
977
 
964
- return createJWT(payload, jwtOptions, header)
978
+ return createJWT(payload, jwtOptions, header)
965
979
  }
966
980
 
967
981
  /**
968
982
  * @deprecated Replaced by the new signer service
969
983
  */
970
984
  export const getDidSigner = async (
971
- args: GetSignerArgs & {
972
- idOpts: {
973
- /**
974
- * @deprecated
975
- */
976
- identifier: IIdentifier | string
977
- /**
978
- * @deprecated
979
- */
980
- verificationMethodSection?: DIDDocumentSection
981
- /**
982
- * @deprecated
983
- */
984
- kmsKeyRef?: string
985
- }
986
- }
985
+ args: GetSignerArgs & {
986
+ idOpts: {
987
+ /**
988
+ * @deprecated
989
+ */
990
+ identifier: IIdentifier | string
991
+ /**
992
+ * @deprecated
993
+ */
994
+ verificationMethodSection?: DIDDocumentSection
995
+ /**
996
+ * @deprecated
997
+ */
998
+ kmsKeyRef?: string
999
+ }
1000
+ }
987
1001
  ): Promise<Signer> => {
988
- const { idOpts, context } = args
1002
+ const {idOpts, context} = args
989
1003
 
990
- const identifier = await legacyGetIdentifier(idOpts, context)
991
- const key = await getKey(
992
- {
993
- identifier,
994
- vmRelationship: idOpts.verificationMethodSection,
995
- kmsKeyRef: idOpts.kmsKeyRef,
996
- },
997
- context
998
- )
999
- const algorithm = await signatureAlgorithmFromKey({ key })
1000
-
1001
- return async (data: string | Uint8Array): Promise<string> => {
1002
- const input = data instanceof Object.getPrototypeOf(Uint8Array) ? new TextDecoder().decode(data as Uint8Array) : (data as string)
1003
- return await context.agent.keyManagerSign({
1004
- keyRef: key.kid,
1005
- algorithm,
1006
- data: input,
1007
- })
1008
- }
1004
+ const identifier = await legacyGetIdentifier(idOpts, context)
1005
+ const key = await getKey(
1006
+ {
1007
+ identifier,
1008
+ vmRelationship: idOpts.verificationMethodSection,
1009
+ kmsKeyRef: idOpts.kmsKeyRef,
1010
+ },
1011
+ context
1012
+ )
1013
+ const algorithm = await signatureAlgorithmFromKey({key})
1014
+
1015
+ return async (data: string | Uint8Array): Promise<string> => {
1016
+ const input = data instanceof Object.getPrototypeOf(Uint8Array) ? new TextDecoder().decode(data as Uint8Array) : (data as string)
1017
+ return await context.agent.keyManagerSign({
1018
+ keyRef: key.kid,
1019
+ algorithm,
1020
+ data: input,
1021
+ })
1022
+ }
1009
1023
  }