@sphereon/ssi-sdk.ebsi-support 0.26.1-unstable.101

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.
Files changed (68) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +13 -0
  3. package/dist/agent/EbsiSupport.d.ts +12 -0
  4. package/dist/agent/EbsiSupport.d.ts.map +1 -0
  5. package/dist/agent/EbsiSupport.js +202 -0
  6. package/dist/agent/EbsiSupport.js.map +1 -0
  7. package/dist/did/EbsiDidProvider.d.ts +47 -0
  8. package/dist/did/EbsiDidProvider.d.ts.map +1 -0
  9. package/dist/did/EbsiDidProvider.js +172 -0
  10. package/dist/did/EbsiDidProvider.js.map +1 -0
  11. package/dist/did/EbsiDidResolver.d.ts +5 -0
  12. package/dist/did/EbsiDidResolver.d.ts.map +1 -0
  13. package/dist/did/EbsiDidResolver.js +10 -0
  14. package/dist/did/EbsiDidResolver.js.map +1 -0
  15. package/dist/did/functions.d.ts +66 -0
  16. package/dist/did/functions.d.ts.map +1 -0
  17. package/dist/did/functions.js +416 -0
  18. package/dist/did/functions.js.map +1 -0
  19. package/dist/did/index.d.ts +6 -0
  20. package/dist/did/index.d.ts.map +1 -0
  21. package/dist/did/index.js +6 -0
  22. package/dist/did/index.js.map +1 -0
  23. package/dist/did/services/EbsiRPCService.d.ts +13 -0
  24. package/dist/did/services/EbsiRPCService.d.ts.map +1 -0
  25. package/dist/did/services/EbsiRPCService.js +64 -0
  26. package/dist/did/services/EbsiRPCService.js.map +1 -0
  27. package/dist/did/services/EbsiRestService.d.ts +37 -0
  28. package/dist/did/services/EbsiRestService.d.ts.map +1 -0
  29. package/dist/did/services/EbsiRestService.js +90 -0
  30. package/dist/did/services/EbsiRestService.js.map +1 -0
  31. package/dist/did/types.d.ts +386 -0
  32. package/dist/did/types.d.ts.map +1 -0
  33. package/dist/did/types.js +47 -0
  34. package/dist/did/types.js.map +1 -0
  35. package/dist/functions/Attestation.d.ts +32 -0
  36. package/dist/functions/Attestation.d.ts.map +1 -0
  37. package/dist/functions/Attestation.js +182 -0
  38. package/dist/functions/Attestation.js.map +1 -0
  39. package/dist/functions/AttestationHeadlessCallbacks.d.ts +17 -0
  40. package/dist/functions/AttestationHeadlessCallbacks.d.ts.map +1 -0
  41. package/dist/functions/AttestationHeadlessCallbacks.js +194 -0
  42. package/dist/functions/AttestationHeadlessCallbacks.js.map +1 -0
  43. package/dist/functions/index.d.ts +7 -0
  44. package/dist/functions/index.d.ts.map +1 -0
  45. package/dist/functions/index.js +8 -0
  46. package/dist/functions/index.js.map +1 -0
  47. package/dist/index.d.ts +7 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +8 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/types/IEbsiSupport.d.ts +211 -0
  52. package/dist/types/IEbsiSupport.d.ts.map +1 -0
  53. package/dist/types/IEbsiSupport.js +5 -0
  54. package/dist/types/IEbsiSupport.js.map +1 -0
  55. package/package.json +86 -0
  56. package/src/agent/EbsiSupport.ts +250 -0
  57. package/src/did/EbsiDidProvider.ts +269 -0
  58. package/src/did/EbsiDidResolver.ts +16 -0
  59. package/src/did/functions.ts +528 -0
  60. package/src/did/index.ts +5 -0
  61. package/src/did/services/EbsiRPCService.ts +68 -0
  62. package/src/did/services/EbsiRestService.ts +117 -0
  63. package/src/did/types.ts +449 -0
  64. package/src/functions/Attestation.ts +262 -0
  65. package/src/functions/AttestationHeadlessCallbacks.ts +242 -0
  66. package/src/functions/index.ts +15 -0
  67. package/src/index.ts +8 -0
  68. package/src/types/IEbsiSupport.ts +241 -0
@@ -0,0 +1,269 @@
1
+ import { getControllerKey, getEthereumAddressFromKey } from '@sphereon/ssi-sdk-ext.did-utils'
2
+ import { calculateJwkThumbprint, calculateJwkThumbprintForKey, toJwk } from '@sphereon/ssi-sdk-ext.key-utils'
3
+ import { IAgentContext, IDIDManager, IIdentifier, IKeyManager } from '@veramo/core'
4
+ import { IKey, IService } from '@veramo/core'
5
+ import { AbstractIdentifierProvider } from '@veramo/did-manager'
6
+ import Debug from 'debug'
7
+ import { ApiOpts, IRequiredContext } from '../types/IEbsiSupport'
8
+ import {
9
+ ebsiCreateDidOnLedger,
10
+ ebsiGenerateOrUseKeyPair,
11
+ ebsiSignAndSendTransaction,
12
+ formatEbsiPublicKey,
13
+ generateEbsiMethodSpecificId,
14
+ randomRpcId,
15
+ } from './functions'
16
+ import { EBSI_DID_SPEC_INFOS, EbsiRpcMethod, ICreateIdentifierArgs, UpdateIdentifierParams } from './types'
17
+
18
+ const debug = Debug('sphereon:did-provider-ebsi')
19
+
20
+ export class EbsiDidProvider extends AbstractIdentifierProvider {
21
+ static readonly PROVIDER = 'did:ebsi'
22
+ private readonly defaultKms?: string
23
+ private readonly apiOpts?: ApiOpts
24
+
25
+ constructor(options: { defaultKms?: string; apiOpts?: ApiOpts }) {
26
+ super()
27
+ this.defaultKms = options.defaultKms
28
+ this.apiOpts = options.apiOpts
29
+ }
30
+
31
+ async createIdentifier(args: ICreateIdentifierArgs, context: IRequiredContext): Promise<Omit<IIdentifier, 'provider'>> {
32
+ const { type, options, kms = this.defaultKms, alias } = args
33
+ const {
34
+ notBefore,
35
+ notAfter,
36
+ secp256k1Key,
37
+ secp256r1Key,
38
+ accessTokenOpts,
39
+ executeLedgerOperation = !!args.options?.accessTokenOpts,
40
+ methodSpecificId = generateEbsiMethodSpecificId(EBSI_DID_SPEC_INFOS.V1),
41
+ baseDocument,
42
+ services,
43
+ } = { ...options }
44
+
45
+ if (executeLedgerOperation && !accessTokenOpts) {
46
+ throw new Error('Access token options must be provided to execute ledger operation')
47
+ }
48
+ const rpcId = options?.rpcId ?? randomRpcId()
49
+
50
+ if (type === EBSI_DID_SPEC_INFOS.KEY) {
51
+ throw new Error(`Type ${type} not supported. Please use @sphereon/ssi-sdk-ext.did-provider-key for Natural Person EBSI DIDs`)
52
+ } else if (!kms) {
53
+ return Promise.reject(Error(`No KMS value provided`))
54
+ }
55
+
56
+ // CapabilityInvocation purpose
57
+ const secp256k1ImportKey = await ebsiGenerateOrUseKeyPair(
58
+ {
59
+ keyOpts: secp256k1Key,
60
+ keyType: 'Secp256k1',
61
+ kms,
62
+ controllerKey: true,
63
+ },
64
+ context,
65
+ )
66
+ const secp256k1ManagedKeyInfo = await context.agent.keyManagerImport(secp256k1ImportKey)
67
+
68
+ // Authentication, assertionMethod purpose
69
+ const secp256r1ImportKey = await ebsiGenerateOrUseKeyPair(
70
+ {
71
+ keyOpts: secp256r1Key,
72
+ keyType: 'Secp256r1',
73
+ kms,
74
+ },
75
+ context,
76
+ )
77
+
78
+ const secp256r1ManagedKeyInfo = await context.agent.keyManagerImport(secp256r1ImportKey)
79
+
80
+ const identifier: IIdentifier = {
81
+ did: `${EBSI_DID_SPEC_INFOS.V1.method}${methodSpecificId}`,
82
+ controllerKeyId: secp256k1ManagedKeyInfo.kid,
83
+ keys: [secp256k1ManagedKeyInfo, secp256r1ManagedKeyInfo],
84
+ alias,
85
+ services: services ?? [],
86
+ provider: EbsiDidProvider.PROVIDER,
87
+ }
88
+
89
+ const apiOpts = { ...this.apiOpts }
90
+ if (!apiOpts.environment) {
91
+ apiOpts.environment = accessTokenOpts?.environment ?? 'pilot'
92
+ }
93
+ if (!apiOpts.version) {
94
+ apiOpts.version = 'v5'
95
+ }
96
+
97
+ if (executeLedgerOperation) {
98
+ await ebsiCreateDidOnLedger(
99
+ {
100
+ identifier,
101
+ baseDocument,
102
+ accessTokenOpts: accessTokenOpts!,
103
+ rpcId,
104
+ notBefore,
105
+ notAfter,
106
+ },
107
+ context,
108
+ )
109
+ }
110
+
111
+ debug('Created', identifier.did)
112
+ return identifier
113
+ }
114
+
115
+ async addKey(
116
+ args: {
117
+ identifier: IIdentifier
118
+ key: IKey
119
+ options: {
120
+ rpcId?: number
121
+ accessToken: string
122
+ vmRelationships: 'authentication' | 'assertionMethod' | 'keyAgreement' | 'capabilityInvocation' | 'capabilityDelegation'[]
123
+ apiOpts?: ApiOpts
124
+ }
125
+ },
126
+ context: IAgentContext<IKeyManager>,
127
+ ): Promise<any> {
128
+ const { identifier, key, options } = args
129
+ const { accessToken, vmRelationships, apiOpts, rpcId = randomRpcId() } = options
130
+ if (vmRelationships.length === 0) {
131
+ return Promise.reject(Error(`No verification method relationship provided`))
132
+ }
133
+ const controllerKey = getControllerKey({ identifier })
134
+ const from = getEthereumAddressFromKey({ key: controllerKey })
135
+ const kid = controllerKey.kid
136
+ const did = identifier.did
137
+
138
+ const addVerificationMethodRequest = {
139
+ params: [
140
+ {
141
+ from,
142
+ did,
143
+ isSecp256k1: true,
144
+ vMethodId: calculateJwkThumbprint({ jwk: toJwk(key.publicKeyHex, key.type) }),
145
+ publicKey: formatEbsiPublicKey({ key: key, type: key.type }),
146
+ },
147
+ ],
148
+ rpcMethod: EbsiRpcMethod.ADD_VERIFICATION_METHOD,
149
+ rpcId,
150
+ apiOpts,
151
+ accessToken,
152
+ }
153
+
154
+ let rpcResponse = await ebsiSignAndSendTransaction(
155
+ {
156
+ rpcRequest: addVerificationMethodRequest,
157
+ kid,
158
+ accessToken: accessToken,
159
+ apiOpts,
160
+ },
161
+ context,
162
+ )
163
+
164
+ const vMethodId = calculateJwkThumbprintForKey({ key })
165
+ for (const vmRelationshipsKey in vmRelationships as string[]) {
166
+ const addVerificationMethodRelationshipRequest = {
167
+ params: [
168
+ {
169
+ from,
170
+ did,
171
+ vMethodId,
172
+ name: vmRelationshipsKey,
173
+ notAfter: Date.now() / 1000 - 60_000,
174
+ notBefore: Date.now() / 1000 + 5 * 365 * 24 * 60 * 60,
175
+ },
176
+ ],
177
+ rpcMethod: EbsiRpcMethod.ADD_VERIFICATION_RELATIONSHIP,
178
+ rpcId,
179
+ apiOpts,
180
+ accessToken,
181
+ }
182
+ rpcResponse = await ebsiSignAndSendTransaction(
183
+ {
184
+ rpcRequest: addVerificationMethodRelationshipRequest,
185
+ previousTxResponse: rpcResponse,
186
+ kid,
187
+ accessToken,
188
+ apiOpts,
189
+ },
190
+ context,
191
+ )
192
+ }
193
+ }
194
+
195
+ async addService(
196
+ args: {
197
+ identifier: IIdentifier
198
+ service: IService
199
+ options: {
200
+ rpcId?: number
201
+ accessToken: string
202
+ apiOpts?: ApiOpts
203
+ }
204
+ },
205
+ context: IAgentContext<IKeyManager>,
206
+ ): Promise<any> {
207
+ const { identifier, service, options } = args
208
+ const { accessToken, apiOpts, rpcId = randomRpcId() } = options
209
+ const controllerKey = getControllerKey({ identifier })
210
+ const from = getEthereumAddressFromKey({ key: controllerKey })
211
+ const did = identifier.did
212
+ const kid = controllerKey.kid
213
+
214
+ const addServiceRequest = {
215
+ params: [
216
+ {
217
+ from,
218
+ did,
219
+ service,
220
+ },
221
+ ],
222
+ rpcMethod: EbsiRpcMethod.ADD_SERVICE,
223
+ rpcId,
224
+ apiOpts,
225
+ accessToken,
226
+ }
227
+
228
+ return await ebsiSignAndSendTransaction(
229
+ {
230
+ rpcRequest: addServiceRequest,
231
+ kid,
232
+ accessToken,
233
+ apiOpts,
234
+ },
235
+ context,
236
+ )
237
+ }
238
+
239
+ deleteIdentifier(args: IIdentifier, context: IAgentContext<IKeyManager>): Promise<boolean> {
240
+ return Promise.resolve(true)
241
+ }
242
+
243
+ removeKey(
244
+ args: {
245
+ identifier: IIdentifier
246
+ kid: string
247
+ options?: any
248
+ },
249
+ context: IAgentContext<IKeyManager>,
250
+ ): Promise<any> {
251
+ throw new Error(`Not (yet) implemented for the EBSI did provider`)
252
+ }
253
+
254
+ removeService(
255
+ args: {
256
+ identifier: IIdentifier
257
+ id: string
258
+ options?: any
259
+ },
260
+ context: IAgentContext<IKeyManager>,
261
+ ): Promise<any> {
262
+ throw new Error(`Not (yet) implemented for the EBSI did provider`)
263
+ }
264
+
265
+ // TODO How does it work? Not inferable from the api: https://hub.ebsi.eu/apis/pilot/did-registry/v5/post-jsonrpc#updatebasedocument
266
+ async updateIdentifier(args: UpdateIdentifierParams, context: IAgentContext<IKeyManager & IDIDManager>): Promise<IIdentifier> {
267
+ throw new Error(`Not (yet) implemented for the EBSI did provider`)
268
+ }
269
+ }
@@ -0,0 +1,16 @@
1
+ import { DIDResolutionOptions, DIDResolutionResult, DIDResolver, ParsedDID, Resolvable, Resolver } from 'did-resolver'
2
+ import { getResolver } from '@sphereon/ssi-sdk-ext.did-resolver-ebsi'
3
+
4
+ const resolveDidEbsi: DIDResolver = async (
5
+ didUrl: string,
6
+ _parsed: ParsedDID,
7
+ _resolver: Resolvable,
8
+ options: DIDResolutionOptions,
9
+ ): Promise<DIDResolutionResult> => {
10
+ const resolver = new Resolver({ ...getResolver() })
11
+ return resolver.resolve(didUrl, options)
12
+ }
13
+
14
+ export function getDidEbsiResolver() {
15
+ return { key: resolveDidEbsi }
16
+ }