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

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,201 @@
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'
41
- import * as u8a from 'uint8arrays'
32
+ // @ts-ignore
33
+ import { fromString } from 'uint8arrays/from-string'
34
+ // @ts-ignore
35
+ import { toString } from 'uint8arrays/to-string'
42
36
  import {
43
- CreateIdentifierOpts,
44
- CreateOrGetIdentifierOpts,
45
- DID_PREFIX,
46
- GetOrCreateResult,
47
- GetSignerArgs,
48
- IdentifierAliasEnum,
49
- IdentifierProviderOpts,
50
- IDIDOptions,
51
- SignJwtArgs,
52
- SupportedDidMethodEnum,
37
+ CreateIdentifierOpts,
38
+ CreateOrGetIdentifierOpts,
39
+ DID_PREFIX,
40
+ GetOrCreateResult,
41
+ GetSignerArgs,
42
+ IdentifierAliasEnum,
43
+ IdentifierProviderOpts,
44
+ IDIDOptions,
45
+ SignJwtArgs,
46
+ SupportedDidMethodEnum,
53
47
  } from './types'
54
48
 
55
49
  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(
56
66
  {
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
67
+ identifier,
68
+ offlineWhenNoDIDRegistered,
69
+ noVerificationMethodFallback,
70
+ keyType,
71
+ controllerKey,
72
+ vmRelationship: 'authentication',
68
73
  },
69
- context: IAgentContext<IResolver & IDIDManager>
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>
70
94
  ): Promise<_ExtendedIKey> => {
71
- return await getFirstKeyWithRelation(
95
+ let key: _ExtendedIKey | undefined = undefined
96
+ try {
97
+ key =
98
+ (await getFirstKeyWithRelationFromDIDDoc(
72
99
  {
73
- identifier,
74
- offlineWhenNoDIDRegistered,
75
- noVerificationMethodFallback,
76
- keyType,
77
- controllerKey,
78
- vmRelationship: 'authentication',
100
+ identifier,
101
+ vmRelationship,
102
+ errorOnNotFound: false,
103
+ keyType,
104
+ controllerKey,
79
105
  },
80
106
  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
- }
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(
133
+ {
134
+ identifier,
135
+ vmRelationship,
136
+ errorOnNotFound: false,
137
+ didDocument: offlineDID,
138
+ keyType,
139
+ controllerKey,
140
+ },
141
+ 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
+ ))
169
156
  if (!key) {
170
- throw Error(`Could not find authentication key for DID ${identifier.did}`)
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'))
171
161
  }
172
- return key
162
+ }
163
+ if (!key) {
164
+ throw Error(`Could not find authentication key for DID ${identifier.did}`)
165
+ }
166
+ return key
173
167
  }
174
168
 
175
169
  export const getOrCreatePrimaryIdentifier = async (
176
- context: IAgentContext<IDIDManager>,
177
- opts?: CreateOrGetIdentifierOpts
170
+ context: IAgentContext<IDIDManager>,
171
+ opts?: CreateOrGetIdentifierOpts
178
172
  ): 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)
173
+ const primaryIdentifier = await getPrimaryIdentifier(context, { ...opts?.createOpts?.options, ...(opts?.method && { method: opts.method }) })
174
+ if (primaryIdentifier !== undefined) {
193
175
  return {
194
- created: true,
195
- result: createdIdentifier,
176
+ created: false,
177
+ result: primaryIdentifier,
196
178
  }
179
+ }
180
+
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
+ }
197
191
  }
198
192
 
199
193
  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
- )
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
+ )
203
197
 
204
- return identifiers && identifiers.length > 0 ? identifiers[0] : undefined
198
+ return identifiers && identifiers.length > 0 ? identifiers[0] : undefined
205
199
  }
206
200
 
207
201
  export const createIdentifier = async (context: IAgentContext<IDIDManager>, opts?: CreateIdentifierOpts): Promise<IIdentifier> => {
@@ -214,80 +208,80 @@ export const createIdentifier = async (context: IAgentContext<IDIDManager>, opts
214
208
  }
215
209
 
216
210
  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>
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>
233
227
  ): 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
- )
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
247
235
  }
248
- return undefined
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
249
243
  }
250
244
 
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
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
260
254
  }
261
255
 
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
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
268
262
  }
269
263
 
270
264
  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
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
284
278
  }) => {
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)
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)
291
285
  }
292
286
 
293
287
  //TODO: Move to ssi-sdk/core and create PR upstream
@@ -302,52 +296,52 @@ export const getKeys = ({
302
296
  * @beta This API may change without a BREAKING CHANGE notice.
303
297
  */
304
298
  export async function dereferenceDidKeysWithJwkSupport(
305
- didDocument: DIDDocument,
306
- section: DIDDocumentSection = 'keyAgreement',
307
- context: IAgentContext<IResolver>
299
+ didDocument: DIDDocument,
300
+ section: DIDDocumentSection = 'keyAgreement',
301
+ context: IAgentContext<IResolver>
308
302
  ): 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
- )
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
+ })
331
324
  )
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
- })
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
+ })
342
336
  }
343
337
 
344
338
  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)
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)
351
345
  }
352
346
 
353
347
  /**
@@ -360,42 +354,42 @@ export function jwkTtoPublicKeyHex(jwk: JWK): string {
360
354
  * @beta This API may change without a BREAKING CHANGE notice.
361
355
  */
362
356
  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)
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)
390
384
  }
391
385
 
392
386
  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)
387
+ const lastChar = hex[hex.length - 1].toLowerCase()
388
+ return ['0', '2', '4', '6', '8', 'a', 'c', 'e'].includes(lastChar)
395
389
  }
396
390
 
397
391
  interface LegacyVerificationMethod extends VerificationMethod {
398
- publicKeyBase64: string
392
+ publicKeyBase64: string
399
393
  }
400
394
 
401
395
  /**
@@ -408,86 +402,86 @@ interface LegacyVerificationMethod extends VerificationMethod {
408
402
  * @beta This API may change without a BREAKING CHANGE notice.
409
403
  */
410
404
  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
- }
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 ''
425
418
  }
426
- return bytesToHex(keyBytes)
419
+ }
420
+ return bytesToHex(keyBytes)
427
421
  }
428
422
 
429
423
  function toEcLibCurve(input: string) {
430
- return input.toLowerCase().replace('-', '').replace('_', '')
424
+ return input.toLowerCase().replace('-', '').replace('_', '')
431
425
  }
432
426
 
433
427
  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()
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()
450
442
  }
451
443
 
452
444
  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)
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)
463
455
  }
464
456
 
465
457
  function didDocumentSectionToJwks(
466
- didDocumentSection: DIDDocumentSection,
467
- searchForVerificationMethods?: (VerificationMethod | string)[],
468
- verificationMethods?: VerificationMethod[]
458
+ didDocumentSection: DIDDocumentSection,
459
+ searchForVerificationMethods?: (VerificationMethod | string)[],
460
+ verificationMethods?: VerificationMethod[]
469
461
  ) {
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)}
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) }
475
469
  }
476
470
 
477
471
  export type DidDocumentJwks = Record<Exclude<DIDDocumentSection, 'publicKey' | 'service'>, Array<JWK>>
478
472
 
479
473
  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
- }
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
+ }
491
485
  }
492
486
 
493
487
  /**
@@ -508,58 +502,58 @@ export function didDocumentToJwks(didDocument: DIDDocument): DidDocumentJwks {
508
502
  * @beta This API may change without a BREAKING CHANGE notice.
509
503
  */
510
504
  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>
505
+ {
506
+ identifier,
507
+ vmRelationship = 'verificationMethod',
508
+ didDocument,
509
+ }: {
510
+ identifier: IIdentifier
511
+ vmRelationship?: DIDDocumentSection
512
+ didDocument?: DIDDocument
513
+ },
514
+ context: IAgentContext<IResolver & IDIDManager>
521
515
  ): 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
- }
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
+ }
530
524
 
531
- // const rsaDidWeb = identifier.keys && identifier.keys.length > 0 && identifier.keys.find((key) => key.type === 'RSA') && didDocument
525
+ // const rsaDidWeb = identifier.keys && identifier.keys.length > 0 && identifier.keys.find((key) => key.type === 'RSA') && didDocument
532
526
 
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)
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)
535
529
 
536
- // dereference all key agreement keys from DID document and normalize
537
- const documentKeys: VerificationMethod[] = await dereferenceDidKeysWithJwkSupport(didDoc, vmRelationship, context)
530
+ // dereference all key agreement keys from DID document and normalize
531
+ const documentKeys: VerificationMethod[] = await dereferenceDidKeysWithJwkSupport(didDoc, vmRelationship, context)
538
532
 
539
- const localKeys = vmRelationship === 'keyAgreement' ? convertIdentifierEncryptionKeys(identifier) : compressIdentifierSecp256k1Keys(identifier)
533
+ const localKeys = vmRelationship === 'keyAgreement' ? convertIdentifierEncryptionKeys(identifier) : compressIdentifierSecp256k1Keys(identifier)
540
534
 
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') {
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') {
545
539
  return null
546
540
  }*/
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)
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)
563
557
  }
564
558
 
565
559
  /**
@@ -575,96 +569,96 @@ export async function mapIdentifierKeysToDocWithJwkSupport(
575
569
  * @beta This API may change without a BREAKING CHANGE notice.
576
570
  */
577
571
  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
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
590
584
  }
591
585
 
592
586
  export async function getAgentDIDMethods(context: IAgentContext<IDIDManager>) {
593
- return (await context.agent.didManagerGetProviders()).map((provider) => provider.toLowerCase().replace('did:', ''))
587
+ return (await context.agent.didManagerGetProviders()).map((provider) => provider.toLowerCase().replace('did:', ''))
594
588
  }
595
589
 
596
590
  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`)
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`)
603
597
  }
604
598
 
605
599
  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`)
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`)
613
607
  }
614
608
 
615
609
  export function toDIDs(identifiers?: (string | IIdentifier | Partial<IIdentifier>)[]): string[] {
616
- if (!identifiers) {
617
- return []
618
- }
619
- return identifiers.map(toDID)
610
+ if (!identifiers) {
611
+ return []
612
+ }
613
+ return identifiers.map(toDID)
620
614
  }
621
615
 
622
616
  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>
617
+ {
618
+ identifier,
619
+ vmRelationship = 'authentication',
620
+ kmsKeyRef,
621
+ }: {
622
+ identifier: IIdentifier
623
+ vmRelationship?: DIDDocumentSection
624
+ kmsKeyRef?: string
625
+ },
626
+ context: IAgentContext<IResolver & IDIDManager>
633
627
  ): Promise<IKey> {
634
- if (!identifier) {
635
- return Promise.reject(new Error(`No identifier provided to getKey method!`))
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
+ )
636
645
  }
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
646
  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
- }
647
+ identifierKey = keys.find(
648
+ (key: _ExtendedIKey) => key.meta.verificationMethod?.type === vmRelationship || key.meta.purposes?.includes(vmRelationship)
649
+ )
660
650
  }
661
651
  if (!identifierKey) {
662
- throw new Error(
663
- `No matching verificationMethodSection key found for keyId: ${kmsKeyRef} and vmSection: ${vmRelationship} for id ${identifier.did}`
664
- )
652
+ identifierKey = keys[0]
665
653
  }
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
+ }
666
660
 
667
- return identifierKey
661
+ return identifierKey
668
662
  }
669
663
 
670
664
  /**
@@ -675,17 +669,17 @@ export async function getKey(
675
669
  * @deprecated Replaced by the identfier resolution plugin
676
670
  */
677
671
  async function legacyGetIdentifier(
678
- {
679
- identifier,
680
- }: {
681
- identifier: string | IIdentifier
682
- },
683
- context: IAgentContext<IDIDManager>
672
+ {
673
+ identifier,
674
+ }: {
675
+ identifier: string | IIdentifier
676
+ },
677
+ context: IAgentContext<IDIDManager>
684
678
  ): Promise<IIdentifier> {
685
- if (typeof identifier === 'string') {
686
- return await context.agent.didManagerGet({did: identifier})
687
- }
688
- return identifier
679
+ if (typeof identifier === 'string') {
680
+ return await context.agent.didManagerGet({ did: identifier })
681
+ }
682
+ return identifier
689
683
  }
690
684
 
691
685
  /**
@@ -695,132 +689,132 @@ async function legacyGetIdentifier(
695
689
  * @param context
696
690
  */
697
691
  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(
698
706
  {
699
- key,
700
- idOpts,
701
- }: {
702
- key: IKey
703
- idOpts: { identifier: IIdentifier | string; kmsKeyRef?: string }
707
+ identifier,
708
+ vmRelationship: 'verificationMethod',
704
709
  },
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
- }
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
+ }
722
716
 
723
- return key.meta?.jwkThumbprint ?? idOpts.kmsKeyRef ?? key.kid
717
+ return key.meta?.jwkThumbprint ?? idOpts.kmsKeyRef ?? key.kid
724
718
  }
725
719
 
726
720
  export async function getSupportedDIDMethods(didOpts: IDIDOptions, context: IAgentContext<IDIDManager>) {
727
- return didOpts.supportedDIDMethods ?? (await getAgentDIDMethods(context))
721
+ return didOpts.supportedDIDMethods ?? (await getAgentDIDMethods(context))
728
722
  }
729
723
 
730
724
  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
- }
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
+ }
737
731
  ): Resolvable {
738
- return new AgentDIDResolver(context, opts)
732
+ return new AgentDIDResolver(context, opts)
739
733
  }
740
734
 
741
735
  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
- }
736
+ private readonly context: IAgentContext<IResolver & IDIDManager>
737
+ private readonly resolverResolution: boolean
738
+ private readonly uniresolverResolution: boolean
739
+ private readonly localResolution: boolean
756
740
 
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
- }
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
776
781
  } 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
- }
782
+ console.log(`Local resolution resulted in a DID Document for ${did}`)
795
783
  }
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
- }
784
+ } catch (error: unknown) {
785
+ if (!err) {
786
+ err = error
813
787
  }
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
+ }
814
808
 
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!
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}`
823
815
  }
816
+ return resolutionResult ?? origResolutionResult!
817
+ }
824
818
  }
825
819
 
826
820
  /**
@@ -834,190 +828,190 @@ export class AgentDIDResolver implements Resolvable {
834
828
  * @param opts
835
829
  */
836
830
  export function toDidDocument(
837
- identifier?: IIdentifier,
838
- opts?: {
839
- did?: string
840
- use?: JwkKeyUse[]
841
- }
831
+ identifier?: IIdentifier,
832
+ opts?: {
833
+ did?: string
834
+ use?: JwkKeyUse[]
835
+ }
842
836
  ): 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}),
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',
927
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}`
881
+ }),
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 }),
928
921
  }
929
- return didDocument
922
+ }
923
+ return didDocument
930
924
  }
931
925
 
932
926
  export function toDidResolutionResult(
933
- identifier?: IIdentifier,
934
- opts?: {
935
- did?: string
936
- supportedMethods?: string[]
937
- }
927
+ identifier?: IIdentifier,
928
+ opts?: {
929
+ did?: string
930
+ supportedMethods?: string[]
931
+ }
938
932
  ): 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
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
955
949
  }
956
950
 
957
951
  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()}`
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()}`
966
960
  }
967
961
 
968
962
  /**
969
963
  * @deprecated Replaced by the new signer service
970
964
  */
971
965
  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
- }
966
+ const { idOpts, header, payload, context, options } = args
967
+ const jwtOptions = {
968
+ ...options,
969
+ signer: await getDidSigner({ idOpts, context }),
970
+ }
977
971
 
978
- return createJWT(payload, jwtOptions, header)
972
+ return createJWT(payload, jwtOptions, header)
979
973
  }
980
974
 
981
975
  /**
982
976
  * @deprecated Replaced by the new signer service
983
977
  */
984
978
  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
- }
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
+ }
1001
995
  ): Promise<Signer> => {
1002
- const {idOpts, context} = args
996
+ const { idOpts, context } = args
1003
997
 
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
- }
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
+ }
1023
1017
  }