@sphereon/ssi-sdk-ext.did-utils 0.28.1-feature.esm.cjs.8 → 0.28.1-feature.oyd.cmsm.improv.16

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