@sphereon/ssi-sdk-ext.did-utils 0.28.0 → 0.28.1-feature.esm.cjs.13

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