@cheqd/did-provider-cheqd 4.4.1 → 4.5.0-develop.1

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 (75) hide show
  1. package/build/esm/did-manager/cheqd-did-provider.d.ts.map +1 -1
  2. package/build/esm/did-manager/cheqd-did-provider.js +2 -1
  3. package/build/esm/did-manager/cheqd-did-provider.js.map +1 -1
  4. package/build/esm/utils/helpers.d.ts +1 -1
  5. package/build/esm/utils/helpers.d.ts.map +1 -1
  6. package/build/tsconfig.esm.tsbuildinfo +1 -1
  7. package/build/tsconfig.types.tsbuildinfo +1 -1
  8. package/build/types/did-manager/cheqd-did-provider.d.ts.map +1 -1
  9. package/build/types/utils/helpers.d.ts +1 -1
  10. package/build/types/utils/helpers.d.ts.map +1 -1
  11. package/package.json +3 -9
  12. package/src/did-manager/cheqd-did-provider.ts +2 -0
  13. package/src/utils/helpers.ts +1 -1
  14. package/tsconfig.json +1 -1
  15. package/build/cjs/agent/ICheqd.d.ts +0 -769
  16. package/build/cjs/agent/ICheqd.d.ts.map +0 -1
  17. package/build/cjs/agent/ICheqd.js +0 -4399
  18. package/build/cjs/agent/ICheqd.js.map +0 -1
  19. package/build/cjs/agent/index.d.ts +0 -2
  20. package/build/cjs/agent/index.d.ts.map +0 -1
  21. package/build/cjs/agent/index.js +0 -18
  22. package/build/cjs/agent/index.js.map +0 -1
  23. package/build/cjs/did-manager/cheqd-did-provider.d.ts +0 -233
  24. package/build/cjs/did-manager/cheqd-did-provider.d.ts.map +0 -1
  25. package/build/cjs/did-manager/cheqd-did-provider.js +0 -750
  26. package/build/cjs/did-manager/cheqd-did-provider.js.map +0 -1
  27. package/build/cjs/did-manager/cheqd-did-resolver.d.ts +0 -26
  28. package/build/cjs/did-manager/cheqd-did-resolver.d.ts.map +0 -1
  29. package/build/cjs/did-manager/cheqd-did-resolver.js +0 -52
  30. package/build/cjs/did-manager/cheqd-did-resolver.js.map +0 -1
  31. package/build/cjs/did-manager/index.d.ts +0 -4
  32. package/build/cjs/did-manager/index.d.ts.map +0 -1
  33. package/build/cjs/did-manager/index.js +0 -20
  34. package/build/cjs/did-manager/index.js.map +0 -1
  35. package/build/cjs/did-manager/resolver.d.ts +0 -47
  36. package/build/cjs/did-manager/resolver.d.ts.map +0 -1
  37. package/build/cjs/did-manager/resolver.js +0 -75
  38. package/build/cjs/did-manager/resolver.js.map +0 -1
  39. package/build/cjs/dkg-threshold/index.d.ts +0 -2
  40. package/build/cjs/dkg-threshold/index.d.ts.map +0 -1
  41. package/build/cjs/dkg-threshold/index.js +0 -18
  42. package/build/cjs/dkg-threshold/index.js.map +0 -1
  43. package/build/cjs/dkg-threshold/lit-protocol/v2.d.ts +0 -95
  44. package/build/cjs/dkg-threshold/lit-protocol/v2.d.ts.map +0 -1
  45. package/build/cjs/dkg-threshold/lit-protocol/v2.js +0 -193
  46. package/build/cjs/dkg-threshold/lit-protocol/v2.js.map +0 -1
  47. package/build/cjs/dkg-threshold/lit-protocol/v3.d.ts +0 -95
  48. package/build/cjs/dkg-threshold/lit-protocol/v3.d.ts.map +0 -1
  49. package/build/cjs/dkg-threshold/lit-protocol/v3.js +0 -232
  50. package/build/cjs/dkg-threshold/lit-protocol/v3.js.map +0 -1
  51. package/build/cjs/dkg-threshold/lit-protocol/v6.d.ts +0 -131
  52. package/build/cjs/dkg-threshold/lit-protocol/v6.d.ts.map +0 -1
  53. package/build/cjs/dkg-threshold/lit-protocol/v6.js +0 -345
  54. package/build/cjs/dkg-threshold/lit-protocol/v6.js.map +0 -1
  55. package/build/cjs/index.d.ts +0 -9
  56. package/build/cjs/index.d.ts.map +0 -1
  57. package/build/cjs/index.js +0 -25
  58. package/build/cjs/index.js.map +0 -1
  59. package/build/cjs/utils/constants.d.ts +0 -2
  60. package/build/cjs/utils/constants.d.ts.map +0 -1
  61. package/build/cjs/utils/constants.js +0 -5
  62. package/build/cjs/utils/constants.js.map +0 -1
  63. package/build/cjs/utils/env.d.ts +0 -7
  64. package/build/cjs/utils/env.d.ts.map +0 -1
  65. package/build/cjs/utils/env.js +0 -19
  66. package/build/cjs/utils/env.js.map +0 -1
  67. package/build/cjs/utils/helpers.d.ts +0 -18
  68. package/build/cjs/utils/helpers.d.ts.map +0 -1
  69. package/build/cjs/utils/helpers.js +0 -112
  70. package/build/cjs/utils/helpers.js.map +0 -1
  71. package/build/cjs/utils/index.d.ts +0 -3
  72. package/build/cjs/utils/index.d.ts.map +0 -1
  73. package/build/cjs/utils/index.js +0 -19
  74. package/build/cjs/utils/index.js.map +0 -1
  75. package/build/tsconfig.cjs.tsbuildinfo +0 -1
@@ -1,4399 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Cheqd = exports.CheqdDidMethod = exports.DidPrefix = exports.DelegateCapacityCreditMethodName = exports.MintCapacityCreditMethodName = exports.ObservePaymentConditionMethodName = exports.TransactSendTokensMethodName = exports.UnsuspendCredentialsMethodName = exports.UnsuspendCredentialMethodName = exports.SuspendCredentialsMethodName = exports.SuspendCredentialMethodName = exports.RevokeCredentialsMethodName = exports.RevokeCredentialMethodName = exports.CheckCredentialStatusMethodName = exports.VerifyPresentationMethodName = exports.VerifyCredentialMethodName = exports.IssueSuspendableCredentialWithStatusList2021MethodName = exports.IssueRevocableCredentialWithStatusList2021MethodName = exports.GenerateStatusList2021MethodName = exports.GenerateVersionIdMethodName = exports.GenerateKeyPairMethodName = exports.GenerateDidDocWithLinkedResourceMethodName = exports.GenerateDidDocMethodName = exports.BroadcastStatusList2021MethodName = exports.CreateStatusList2021MethodName = exports.CreateResourceMethodName = exports.DeactivateIdentifierMethodName = exports.UpdateIdentifierMethodName = exports.CreateIdentifierMethodName = exports.RemoteListPattern = exports.AccessControlConditionReturnValueComparators = exports.AccessControlConditionTypes = void 0;
7
- /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars, @typescript-eslint/no-non-null-assertion */
8
- // any is used for extensibility
9
- // unused vars are kept by convention
10
- // non-null assertion is used when we know better than the compiler that the value is not null or undefined
11
- const sdk_1 = require("@cheqd/sdk");
12
- const cheqd_did_provider_js_1 = require("../did-manager/cheqd-did-provider.js");
13
- const uint8arrays_1 = require("uint8arrays");
14
- const did_jwt_1 = require("did-jwt");
15
- const vc_status_list_1 = require("@digitalbazaar/vc-status-list");
16
- const uuid_1 = require("uuid");
17
- const fs_1 = __importDefault(require("fs"));
18
- const debug_1 = __importDefault(require("debug"));
19
- const v6_js_1 = require("../dkg-threshold/lit-protocol/v6.js");
20
- const helpers_js_1 = require("../utils/helpers.js");
21
- const cheqd_did_resolver_js_1 = require("../did-manager/cheqd-did-resolver.js");
22
- const v2_js_1 = require("../dkg-threshold/lit-protocol/v2.js");
23
- const debug = (0, debug_1.default)('veramo:did-provider-cheqd');
24
- exports.AccessControlConditionTypes = {
25
- timelockPayment: 'timelockPayment',
26
- memoNonce: 'memoNonce',
27
- balance: 'balance',
28
- };
29
- exports.AccessControlConditionReturnValueComparators = {
30
- lessThan: '<',
31
- greaterThan: '>',
32
- equalTo: '=',
33
- lessThanOrEqualTo: '<=',
34
- greaterThanOrEqualTo: '>=',
35
- };
36
- exports.RemoteListPattern = /^(https:\/\/)?[a-z0-9_-]+(\.[a-z0-9_-]+)*\.[a-z]{2,}\/1\.0\/identifiers\/did:cheqd:[a-z]+:[a-zA-Z0-9-]+\?((resourceName=[^&]*)&(resourceType=[^&]*)|((resourceType=[^&]*)&(resourceName=[^&]*)))$/;
37
- exports.CreateIdentifierMethodName = 'cheqdCreateIdentifier';
38
- exports.UpdateIdentifierMethodName = 'cheqdUpdateIdentifier';
39
- exports.DeactivateIdentifierMethodName = 'cheqdDeactivateIdentifier';
40
- exports.CreateResourceMethodName = 'cheqdCreateLinkedResource';
41
- exports.CreateStatusList2021MethodName = 'cheqdCreateStatusList2021';
42
- exports.BroadcastStatusList2021MethodName = 'cheqdBroadcastStatusList2021';
43
- exports.GenerateDidDocMethodName = 'cheqdGenerateDidDoc';
44
- exports.GenerateDidDocWithLinkedResourceMethodName = 'cheqdGenerateDidDocWithLinkedResource';
45
- exports.GenerateKeyPairMethodName = 'cheqdGenerateIdentityKeys';
46
- exports.GenerateVersionIdMethodName = 'cheqdGenerateVersionId';
47
- exports.GenerateStatusList2021MethodName = 'cheqdGenerateStatusList2021';
48
- exports.IssueRevocableCredentialWithStatusList2021MethodName = 'cheqdIssueRevocableCredentialWithStatusList2021';
49
- exports.IssueSuspendableCredentialWithStatusList2021MethodName = 'cheqdIssueSuspendableCredentialWithStatusList2021';
50
- exports.VerifyCredentialMethodName = 'cheqdVerifyCredential';
51
- exports.VerifyPresentationMethodName = 'cheqdVerifyPresentation';
52
- exports.CheckCredentialStatusMethodName = 'cheqdCheckCredentialStatus';
53
- exports.RevokeCredentialMethodName = 'cheqdRevokeCredential';
54
- exports.RevokeCredentialsMethodName = 'cheqdRevokeCredentials';
55
- exports.SuspendCredentialMethodName = 'cheqdSuspendCredential';
56
- exports.SuspendCredentialsMethodName = 'cheqdSuspendCredentials';
57
- exports.UnsuspendCredentialMethodName = 'cheqdUnsuspendCredential';
58
- exports.UnsuspendCredentialsMethodName = 'cheqdUnsuspendCredentials';
59
- exports.TransactSendTokensMethodName = 'cheqdTransactSendTokens';
60
- exports.ObservePaymentConditionMethodName = 'cheqdObservePaymentCondition';
61
- exports.MintCapacityCreditMethodName = 'cheqdMintCapacityCredit';
62
- exports.DelegateCapacityCreditMethodName = 'cheqdDelegateCapacityCredit';
63
- exports.DidPrefix = 'did';
64
- exports.CheqdDidMethod = 'cheqd';
65
- class Cheqd {
66
- methods;
67
- schema = {
68
- components: {
69
- schemas: {},
70
- methods: {
71
- cheqdCreateIdentifier: {
72
- description: 'Create a new identifier',
73
- arguments: {
74
- type: 'object',
75
- properties: {
76
- args: {
77
- type: 'object',
78
- description: 'A cheqdCreateIdentifierArgs object as any for extensibility',
79
- },
80
- },
81
- required: ['args'],
82
- },
83
- returnType: {
84
- type: 'object',
85
- },
86
- },
87
- cheqdUpdateIdentifier: {
88
- description: 'Update an identifier',
89
- arguments: {
90
- type: 'object',
91
- properties: {
92
- args: {
93
- type: 'object',
94
- description: 'A cheqdUpdateIdentifierArgs object as any for extensibility',
95
- },
96
- },
97
- required: ['args'],
98
- },
99
- returnType: {
100
- type: 'object',
101
- },
102
- },
103
- cheqdDeactivateIdentifier: {
104
- description: 'Deactivate an identifier',
105
- arguments: {
106
- type: 'object',
107
- properties: {
108
- args: {
109
- type: 'object',
110
- description: 'A cheqdDeactivateIdentifierArgs object as any for extensibility',
111
- },
112
- },
113
- required: ['args'],
114
- },
115
- returnType: {
116
- type: 'object',
117
- },
118
- },
119
- cheqdCreateLinkedResource: {
120
- description: 'Create a new resource',
121
- arguments: {
122
- type: 'object',
123
- properties: {
124
- args: {
125
- type: 'object',
126
- description: 'A cheqdCreateLinkedResource object as any for extensibility',
127
- },
128
- },
129
- required: ['args'],
130
- },
131
- returnType: {
132
- type: 'boolean',
133
- },
134
- },
135
- cheqdCreateStatusList2021: {
136
- description: 'Create a new Status List 2021',
137
- arguments: {
138
- type: 'object',
139
- properties: {
140
- args: {
141
- type: 'object',
142
- description: 'A cheqdCreateStatusList2021Args object as any for extensibility',
143
- },
144
- },
145
- required: ['args'],
146
- },
147
- returnType: {
148
- type: 'object',
149
- },
150
- },
151
- cheqdBroadcastStatusList2021: {
152
- description: 'Broadcast a Status List 2021 to cheqd ledger',
153
- arguments: {
154
- type: 'object',
155
- properties: {
156
- args: {
157
- type: 'object',
158
- description: 'A cheqdBroadcastStatusList2021Args object as any for extensibility',
159
- },
160
- },
161
- required: ['args'],
162
- },
163
- returnType: {
164
- type: 'object',
165
- },
166
- },
167
- cheqdGenerateDidDoc: {
168
- description: 'Generate a new DID document to use with `createIdentifier`',
169
- arguments: {
170
- type: 'object',
171
- properties: {
172
- args: {
173
- type: 'object',
174
- description: 'A cheqdGenerateDidDocArgs object as any for extensibility',
175
- },
176
- },
177
- required: ['args'],
178
- },
179
- returnType: {
180
- type: 'object',
181
- },
182
- },
183
- cheqdGenerateDidDocWithLinkedResource: {
184
- description: 'Generate a new DID document to use with `createIdentifier` and / or `createResource`',
185
- arguments: {
186
- type: 'object',
187
- properties: {
188
- args: {
189
- type: 'object',
190
- description: 'A cheqdGenerateDidDocWithLinkedResourceArgs object as any for extensibility',
191
- },
192
- },
193
- required: ['args'],
194
- },
195
- returnType: {
196
- type: 'object',
197
- },
198
- },
199
- cheqdGenerateIdentityKeys: {
200
- description: 'Generate a new key pair in hex to use with `createIdentifier`',
201
- arguments: {
202
- type: 'object',
203
- properties: {
204
- args: {
205
- type: 'object',
206
- description: 'A cheqdGenerateIdentityKeysArgs object as any for extensibility',
207
- },
208
- },
209
- },
210
- returnType: {
211
- type: 'object',
212
- },
213
- },
214
- cheqdGenerateVersionId: {
215
- description: 'Generate a random uuid',
216
- arguments: {
217
- type: 'object',
218
- properties: {
219
- args: {
220
- type: 'object',
221
- description: 'A cheqdGenerateVersionIdArgs object as any for extensibility',
222
- },
223
- },
224
- },
225
- returnType: {
226
- type: 'object',
227
- },
228
- },
229
- cheqdGenerateStatusList2021: {
230
- description: 'Generate a new Status List 2021',
231
- arguments: {
232
- type: 'object',
233
- properties: {
234
- args: {
235
- type: 'object',
236
- description: 'A cheqdGenerateStatusList2021Args object as any for extensibility',
237
- },
238
- },
239
- },
240
- returnType: {
241
- type: 'string',
242
- },
243
- },
244
- cheqdIssueRevocableCredentialWithStatusList2021: {
245
- description: 'Issue a revocable credential with a Status List 2021 as credential status registry',
246
- arguments: {
247
- type: 'object',
248
- properties: {
249
- args: {
250
- type: 'object',
251
- description: 'A cheqdIssueCredentialWithStatusList2021Args object as any for extensibility',
252
- },
253
- },
254
- required: ['args'],
255
- },
256
- returnType: {
257
- type: 'object',
258
- },
259
- },
260
- cheqdIssueSuspendableCredentialWithStatusList2021: {
261
- description: 'Issue a suspendable credential with a Status List 2021 as credential status registry',
262
- arguments: {
263
- type: 'object',
264
- properties: {
265
- args: {
266
- type: 'object',
267
- description: 'A cheqdIssueCredentialWithStatusList2021Args object as any for extensibility',
268
- },
269
- },
270
- required: ['args'],
271
- },
272
- returnType: {
273
- type: 'object',
274
- },
275
- },
276
- cheqdVerifyCredential: {
277
- description: 'Verify a credential, enhanced by revocation / suspension check with a Status List 2021 as credential status registry',
278
- arguments: {
279
- type: 'object',
280
- properties: {
281
- args: {
282
- type: 'object',
283
- description: 'A cheqdVerifyCredentialWithStatusList2021Args object as any for extensibility',
284
- },
285
- },
286
- required: ['args'],
287
- },
288
- returnType: {
289
- type: 'object',
290
- },
291
- },
292
- cheqdVerifyPresentation: {
293
- description: 'Verify a presentation, enhanced by revocation / suspension check with a Status List 2021 as credential status registry',
294
- arguments: {
295
- type: 'object',
296
- properties: {
297
- args: {
298
- type: 'object',
299
- description: 'A cheqdVerifyPresentationWithStatusList2021Args object as any for extensibility',
300
- },
301
- },
302
- required: ['args'],
303
- },
304
- returnType: {
305
- type: 'object',
306
- },
307
- },
308
- cheqdCheckCredentialStatus: {
309
- description: 'Check the revocation / suspension status of a credential with a Status List 2021 as credential status registry',
310
- arguments: {
311
- type: 'object',
312
- properties: {
313
- args: {
314
- type: 'object',
315
- description: 'A cheqdCheckCredentialStatusWithStatusList2021Args object as any for extensibility',
316
- },
317
- },
318
- required: ['args'],
319
- },
320
- returnType: {
321
- type: 'object',
322
- },
323
- },
324
- cheqdRevokeCredential: {
325
- description: 'Revoke a credential against a Status List 2021 as credential status registry',
326
- arguments: {
327
- type: 'object',
328
- properties: {
329
- args: {
330
- type: 'object',
331
- description: 'A cheqdRevokeCredentialWithStatusList2021Args object as any for extensibility',
332
- },
333
- },
334
- required: ['args'],
335
- },
336
- returnType: {
337
- type: 'object',
338
- },
339
- },
340
- cheqdRevokeCredentials: {
341
- description: 'Revoke multiple credentials against a Status List 2021 as credential status registry',
342
- arguments: {
343
- type: 'object',
344
- properties: {
345
- args: {
346
- type: 'object',
347
- description: 'A cheqdRevokeBulkCredentialsWithStatusList2021Args object as any for extensibility',
348
- },
349
- },
350
- required: ['args'],
351
- },
352
- returnType: {
353
- type: 'array',
354
- },
355
- },
356
- cheqdSuspendCredential: {
357
- description: 'Suspend a credential against a Status List 2021 as credential status registry',
358
- arguments: {
359
- type: 'object',
360
- properties: {
361
- args: {
362
- type: 'object',
363
- description: 'A cheqdSuspendCredentialWithStatusList2021Args object as any for extensibility',
364
- },
365
- },
366
- required: ['args'],
367
- },
368
- returnType: {
369
- type: 'object',
370
- },
371
- },
372
- cheqdSuspendCredentials: {
373
- description: 'Suspend multiple credentials against a Status List 2021 as credential status registry',
374
- arguments: {
375
- type: 'object',
376
- properties: {
377
- args: {
378
- type: 'object',
379
- description: 'A cheqdSuspendBulkCredentialsWithStatusList2021Args object as any for extensibility',
380
- },
381
- },
382
- required: ['args'],
383
- },
384
- returnType: {
385
- type: 'array',
386
- },
387
- },
388
- cheqdUnsuspendCredential: {
389
- description: 'Unsuspend a credential against a Status List 2021 as credential status registry',
390
- arguments: {
391
- type: 'object',
392
- properties: {
393
- args: {
394
- type: 'object',
395
- description: 'cheqdUnsuspendCredentialWithStatusList2021Args object as any for extensibility',
396
- },
397
- },
398
- required: ['args'],
399
- },
400
- returnType: {
401
- type: 'object',
402
- },
403
- },
404
- cheqdUnsuspendCredentials: {
405
- description: 'Unsuspend multiple credentials against a Status List 2021 as credential status registry',
406
- arguments: {
407
- type: 'object',
408
- properties: {
409
- args: {
410
- type: 'object',
411
- description: 'A cheqdUnsuspendBulkCredentialsWithStatusList2021Args object as any for extensibility',
412
- },
413
- },
414
- required: ['args'],
415
- },
416
- returnType: {
417
- type: 'array',
418
- },
419
- },
420
- cheqdTransactSendTokens: {
421
- description: 'Send tokens from one account to another',
422
- arguments: {
423
- type: 'object',
424
- properties: {
425
- args: {
426
- type: 'object',
427
- description: 'A cheqdTransactSendTokensArgs object as any for extensibility',
428
- },
429
- },
430
- required: ['args'],
431
- },
432
- returnType: {
433
- type: 'object',
434
- },
435
- },
436
- cheqdObservePaymentCondition: {
437
- description: 'Observe payment conditions for a given set of payment conditions',
438
- arguments: {
439
- type: 'object',
440
- properties: {
441
- args: {
442
- type: 'object',
443
- description: 'cheqdObservePaymentConditionArgs object as any for extensibility',
444
- },
445
- },
446
- required: ['args'],
447
- },
448
- returnType: {
449
- type: 'object',
450
- },
451
- },
452
- },
453
- },
454
- };
455
- supportedDidProviders;
456
- didProvider;
457
- providerId;
458
- static defaultStatusList2021Length = 16 * 1024 * 8; // 16KB in bits or 131072 bits / entries
459
- static defaultContextV1 = 'https://www.w3.org/2018/credentials/v1';
460
- static statusList2021Context = 'https://w3id.org/vc-status-list-2021/v1';
461
- constructor(args) {
462
- if (typeof args.providers !== 'object') {
463
- throw new Error('[did-provider-cheqd]: at least one did provider is required');
464
- }
465
- this.supportedDidProviders = args.providers;
466
- this.didProvider = args.providers[0];
467
- this.providerId = Cheqd.generateProviderId(this.didProvider.network);
468
- this.methods = {
469
- [exports.CreateIdentifierMethodName]: this.CreateIdentifier.bind(this),
470
- [exports.UpdateIdentifierMethodName]: this.UpdateIdentifier.bind(this),
471
- [exports.DeactivateIdentifierMethodName]: this.DeactivateIdentifier.bind(this),
472
- [exports.CreateResourceMethodName]: this.CreateResource.bind(this),
473
- [exports.CreateStatusList2021MethodName]: this.CreateStatusList2021.bind(this),
474
- [exports.BroadcastStatusList2021MethodName]: this.BroadcastStatusList2021.bind(this),
475
- [exports.GenerateDidDocMethodName]: this.GenerateDidDoc.bind(this),
476
- [exports.GenerateDidDocWithLinkedResourceMethodName]: this.GenerateDidDocWithLinkedResource.bind(this),
477
- [exports.GenerateKeyPairMethodName]: this.GenerateIdentityKeys.bind(this),
478
- [exports.GenerateVersionIdMethodName]: this.GenerateVersionId.bind(this),
479
- [exports.GenerateStatusList2021MethodName]: this.GenerateStatusList2021.bind(this),
480
- [exports.IssueRevocableCredentialWithStatusList2021MethodName]: this.IssueRevocableCredentialWithStatusList2021.bind(this),
481
- [exports.IssueSuspendableCredentialWithStatusList2021MethodName]: this.IssueSuspendableCredentialWithStatusList2021.bind(this),
482
- [exports.VerifyCredentialMethodName]: this.VerifyCredentialWithStatusList2021.bind(this),
483
- [exports.VerifyPresentationMethodName]: this.VerifyPresentationWithStatusList2021.bind(this),
484
- [exports.CheckCredentialStatusMethodName]: this.CheckCredentialStatusWithStatusList2021.bind(this),
485
- [exports.RevokeCredentialMethodName]: this.RevokeCredentialWithStatusList2021.bind(this),
486
- [exports.RevokeCredentialsMethodName]: this.RevokeBulkCredentialsWithStatusList2021.bind(this),
487
- [exports.SuspendCredentialMethodName]: this.SuspendCredentialWithStatusList2021.bind(this),
488
- [exports.SuspendCredentialsMethodName]: this.SuspendBulkCredentialsWithStatusList2021.bind(this),
489
- [exports.UnsuspendCredentialMethodName]: this.UnsuspendCredentialWithStatusList2021.bind(this),
490
- [exports.UnsuspendCredentialsMethodName]: this.UnsuspendBulkCredentialsWithStatusList2021.bind(this),
491
- [exports.TransactSendTokensMethodName]: this.TransactSendTokens.bind(this),
492
- [exports.ObservePaymentConditionMethodName]: this.ObservePaymentCondition.bind(this),
493
- [exports.MintCapacityCreditMethodName]: this.MintCapacityCredit.bind(this),
494
- [exports.DelegateCapacityCreditMethodName]: this.DelegateCapacityCredit.bind(this),
495
- };
496
- }
497
- async CreateIdentifier(args, context) {
498
- if (typeof args.kms !== 'string') {
499
- throw new Error('[did-provider-cheqd]: kms is required');
500
- }
501
- if (typeof args.alias !== 'string') {
502
- throw new Error('[did-provider-cheqd]: alias is required');
503
- }
504
- if (typeof args.document !== 'object') {
505
- throw new Error('[did-provider-cheqd]: document object is required');
506
- }
507
- const provider = await Cheqd.getProviderFromDidUrl(args.document.id, this.supportedDidProviders);
508
- this.didProvider = provider;
509
- this.providerId = Cheqd.generateProviderId(this.didProvider.network);
510
- return await context.agent.didManagerCreate({
511
- kms: args.kms,
512
- alias: args.alias,
513
- provider: this.providerId,
514
- options: {
515
- document: args.document,
516
- keys: args.keys,
517
- versionId: args?.versionId,
518
- fee: args?.fee,
519
- },
520
- });
521
- }
522
- async UpdateIdentifier(args, context) {
523
- if (typeof args.kms !== 'string') {
524
- throw new Error('[did-provider-cheqd]: kms is required');
525
- }
526
- if (typeof args.document !== 'object') {
527
- throw new Error('[did-provider-cheqd]: document object is required');
528
- }
529
- const provider = await Cheqd.getProviderFromDidUrl(args.document.id, this.supportedDidProviders);
530
- this.didProvider = provider;
531
- this.providerId = Cheqd.generateProviderId(this.didProvider.network);
532
- return await context.agent.didManagerUpdate({
533
- did: args.document.id,
534
- document: args.document,
535
- options: {
536
- kms: args.kms,
537
- keys: args.keys,
538
- versionId: args?.versionId,
539
- fee: args?.fee,
540
- },
541
- });
542
- }
543
- async DeactivateIdentifier(args, context) {
544
- if (typeof args.kms !== 'string') {
545
- throw new Error('[did-provider-cheqd]: kms is required');
546
- }
547
- if (typeof args.document !== 'object') {
548
- throw new Error('[did-provider-cheqd]: document object is required');
549
- }
550
- const provider = await Cheqd.getProviderFromDidUrl(args.document.id, this.supportedDidProviders);
551
- this.didProvider = provider;
552
- this.providerId = Cheqd.generateProviderId(this.didProvider.network);
553
- return await this.didProvider.deactivateIdentifier({
554
- did: args.document.id,
555
- document: args.document,
556
- options: {
557
- keys: args.keys,
558
- fee: args?.fee,
559
- },
560
- }, context);
561
- }
562
- async CreateResource(args, context) {
563
- if (typeof args.kms !== 'string') {
564
- throw new Error('[did-provider-cheqd]: kms is required');
565
- }
566
- if (typeof args.payload !== 'object') {
567
- throw new Error('[did-provider-cheqd]: payload object is required');
568
- }
569
- if (typeof args.network !== 'string') {
570
- throw new Error('[did-provider-cheqd]: network is required');
571
- }
572
- if (args?.file) {
573
- args.payload.data = await Cheqd.getFile(args.file);
574
- }
575
- if (typeof args?.payload?.data === 'string') {
576
- args.payload.data = (0, uint8arrays_1.fromString)(args.payload.data, 'base64');
577
- }
578
- this.providerId = Cheqd.generateProviderId(args.network);
579
- this.didProvider = await Cheqd.getProviderFromNetwork(args.network, this.supportedDidProviders);
580
- return await this.didProvider.createResource({
581
- options: {
582
- kms: args.kms,
583
- payload: args.payload,
584
- signInputs: args.signInputs,
585
- fee: args?.fee,
586
- },
587
- }, context);
588
- }
589
- async CreateStatusList2021(args, context) {
590
- if (typeof args.kms !== 'string') {
591
- throw new Error('[did-provider-cheqd]: kms is required');
592
- }
593
- if (typeof args.issuerDid !== 'string' || !args.issuerDid) {
594
- throw new Error('[did-provider-cheqd]: issuerDid is required');
595
- }
596
- if (typeof args.statusListName !== 'string' || !args.statusListName) {
597
- throw new Error('[did-provider-cheqd]: statusListName is required');
598
- }
599
- if (typeof args.statusPurpose !== 'string' || !args.statusPurpose) {
600
- throw new Error('[did-provider-cheqd]: statusPurpose is required');
601
- }
602
- if (typeof args.encrypted === 'undefined') {
603
- throw new Error('[did-provider-cheqd]: encrypted is required');
604
- }
605
- // validate statusPurpose
606
- if (!Object.values(cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes).includes(args.statusPurpose)) {
607
- throw new Error(`[did-provider-cheqd]: statusPurpose must be one of ${Object.values(cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes).join(', ')}`);
608
- }
609
- // validate statusListLength
610
- if (args?.statusListLength) {
611
- if (typeof args.statusListLength !== 'number') {
612
- throw new Error('[did-provider-cheqd]: statusListLength must be number');
613
- }
614
- if (args.statusListLength < Cheqd.defaultStatusList2021Length) {
615
- throw new Error(`[did-provider-cheqd]: statusListLength must be greater than or equal to ${Cheqd.defaultStatusList2021Length} number of entries`);
616
- }
617
- }
618
- // validate statusListEncoding
619
- if (args?.statusListEncoding) {
620
- if (typeof args.statusListEncoding !== 'string') {
621
- throw new Error('[did-provider-cheqd]: statusListEncoding must be string');
622
- }
623
- if (!Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(args.statusListEncoding)) {
624
- throw new Error(`[did-provider-cheqd]: statusListEncoding must be one of ${Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).join(', ')}`);
625
- }
626
- }
627
- // validate validUntil
628
- if (args?.validUntil) {
629
- if (typeof args.validUntil !== 'string') {
630
- throw new Error('[did-provider-cheqd]: validUntil must be string');
631
- }
632
- if (new Date() <= new Date(args.validUntil)) {
633
- throw new Error('[did-provider-cheqd]: validUntil must be greater than current date');
634
- }
635
- }
636
- // validate args in pairs - case: encrypted
637
- if (args.encrypted) {
638
- // validate paymentConditions
639
- if (!args?.paymentConditions ||
640
- !args?.paymentConditions?.length ||
641
- !Array.isArray(args?.paymentConditions) ||
642
- args?.paymentConditions.length === 0) {
643
- throw new Error('[did-provider-cheqd]: paymentConditions is required');
644
- }
645
- if (!args?.paymentConditions?.every((condition) => condition.feePaymentAddress && condition.feePaymentAmount && condition.intervalInSeconds)) {
646
- throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
647
- }
648
- if (!args?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' &&
649
- typeof condition.feePaymentAmount === 'string' &&
650
- typeof condition.intervalInSeconds === 'number')) {
651
- throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
652
- }
653
- if (!args?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
654
- throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
655
- }
656
- }
657
- // get network
658
- const network = args.issuerDid.split(':')[2];
659
- // define provider
660
- const provider = (function (that) {
661
- // switch on network
662
- return (that.supportedDidProviders.find((provider) => provider.network === network) ||
663
- (function () {
664
- throw new Error(`[did-provider-cheqd]: no relevant providers found`);
665
- })());
666
- })(this);
667
- // generate bitstring
668
- const bitstring = await context.agent[exports.GenerateStatusList2021MethodName]({
669
- length: args?.statusListLength || Cheqd.defaultStatusList2021Length,
670
- bitstringEncoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url,
671
- });
672
- // construct data and metadata tuple
673
- const data = args.encrypted
674
- ? await (async function (that) {
675
- // encrypt bitstring - case: symmetric
676
- const { encryptedString: symmetricEncryptionCiphertext, symmetricKey } = await v6_js_1.LitProtocol.encryptDirect((0, uint8arrays_1.fromString)(bitstring, args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url));
677
- // instantiate dkg-threshold client, in which case lit-protocol is used
678
- const lit = await provider.instantiateDkgThresholdProtocolClient({});
679
- // construct access control conditions
680
- const unifiedAccessControlConditions = await Promise.all(args.paymentConditions.map(async (condition) => {
681
- switch (condition.type) {
682
- case exports.AccessControlConditionTypes.timelockPayment:
683
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
684
- key: '$.tx_responses.*.timestamp',
685
- comparator: '<=',
686
- value: `${condition.intervalInSeconds}`,
687
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, args?.dkgOptions?.chain || that.didProvider.dkgOptions.chain);
688
- default:
689
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
690
- }
691
- }));
692
- // encrypt bitstring - case: threshold
693
- const { encryptedString: thresholdEncryptionCiphertext, stringHash } = await lit.encrypt((0, uint8arrays_1.fromString)(bitstring, args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url), unifiedAccessControlConditions);
694
- // construct encoded list
695
- const encodedList = `${await (0, helpers_js_1.blobToHexString)(symmetricEncryptionCiphertext)}-${(0, uint8arrays_1.toString)(thresholdEncryptionCiphertext, 'hex')}`;
696
- // return result tuple
697
- switch (args.statusPurpose) {
698
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation:
699
- return [
700
- {
701
- StatusList2021: {
702
- statusPurpose: args.statusPurpose,
703
- encodedList,
704
- validFrom: new Date().toISOString(),
705
- validUntil: args?.validUntil,
706
- },
707
- metadata: {
708
- type: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.revocation,
709
- encrypted: true,
710
- encoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url,
711
- statusListHash: stringHash,
712
- paymentConditions: args.paymentConditions,
713
- },
714
- },
715
- {
716
- symmetricEncryptionCiphertext: await (0, helpers_js_1.blobToHexString)(symmetricEncryptionCiphertext),
717
- thresholdEncryptionCiphertext: (0, uint8arrays_1.toString)(thresholdEncryptionCiphertext, 'hex'),
718
- stringHash,
719
- symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex'),
720
- },
721
- ];
722
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension:
723
- return [
724
- {
725
- StatusList2021: {
726
- statusPurpose: args.statusPurpose,
727
- encodedList,
728
- validFrom: new Date().toISOString(),
729
- validUntil: args?.validUntil,
730
- },
731
- metadata: {
732
- type: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension,
733
- encrypted: true,
734
- encoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url,
735
- statusListHash: stringHash,
736
- paymentConditions: args.paymentConditions,
737
- },
738
- },
739
- {
740
- symmetricEncryptionCiphertext: await (0, helpers_js_1.blobToHexString)(symmetricEncryptionCiphertext),
741
- thresholdEncryptionCiphertext: (0, uint8arrays_1.toString)(thresholdEncryptionCiphertext, 'hex'),
742
- stringHash,
743
- symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex'),
744
- },
745
- ];
746
- default:
747
- throw new Error(`[did-provider-cheqd]: status purpose is not valid ${args.statusPurpose}`);
748
- }
749
- })(this)
750
- : await (async function () {
751
- switch (args.statusPurpose) {
752
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation:
753
- return [
754
- {
755
- StatusList2021: {
756
- statusPurpose: args.statusPurpose,
757
- encodedList: bitstring,
758
- validFrom: new Date().toISOString(),
759
- validUntil: args?.validUntil,
760
- },
761
- metadata: {
762
- type: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.revocation,
763
- encrypted: false,
764
- encoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url,
765
- },
766
- },
767
- undefined,
768
- ];
769
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension:
770
- return [
771
- {
772
- StatusList2021: {
773
- statusPurpose: args.statusPurpose,
774
- encodedList: bitstring,
775
- validFrom: new Date().toISOString(),
776
- validUntil: args?.validUntil,
777
- },
778
- metadata: {
779
- type: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension,
780
- encrypted: false,
781
- encoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url,
782
- },
783
- },
784
- undefined,
785
- ];
786
- default:
787
- throw new Error('[did-provider-cheqd]: statusPurpose is not valid');
788
- }
789
- })();
790
- // construct payload
791
- const payload = {
792
- id: (0, uuid_1.v4)(),
793
- collectionId: args.issuerDid.split(':').reverse()[0],
794
- name: args.statusListName,
795
- resourceType: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes[args.statusPurpose],
796
- version: args?.resourceVersion || new Date().toISOString(),
797
- alsoKnownAs: args?.alsoKnownAs || [],
798
- data: (0, uint8arrays_1.fromString)(JSON.stringify(data[0]), 'utf-8'),
799
- };
800
- // return result
801
- return {
802
- created: await context.agent[exports.BroadcastStatusList2021MethodName]({
803
- kms: args.kms,
804
- payload,
805
- network: network,
806
- }),
807
- resource: data[0],
808
- resourceMetadata: await Cheqd.fetchStatusList2021Metadata({
809
- credentialStatus: {
810
- id: `${cheqd_did_resolver_js_1.DefaultResolverUrl}${args.issuerDid}?resourceName=${args.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes[args.statusPurpose]}`,
811
- type: 'StatusList2021Entry',
812
- },
813
- }),
814
- encrypted: args.encrypted,
815
- symmetricKey: args.encrypted && args.returnSymmetricKey ? data[1]?.symmetricKey : undefined,
816
- };
817
- }
818
- async BroadcastStatusList2021(args, context) {
819
- if (typeof args.kms !== 'string') {
820
- throw new Error('[did-provider-cheqd]: kms is required');
821
- }
822
- if (typeof args.payload !== 'object') {
823
- throw new Error('[did-provider-cheqd]: payload object is required');
824
- }
825
- if (typeof args.network !== 'string') {
826
- throw new Error('[did-provider-cheqd]: network is required');
827
- }
828
- if (args?.file) {
829
- args.payload.data = await Cheqd.getFile(args.file);
830
- }
831
- if (typeof args?.payload?.data === 'string') {
832
- args.payload.data = (0, uint8arrays_1.fromString)(args.payload.data, 'base64');
833
- }
834
- // TODO: validate data as per bitstring
835
- // validate resource type
836
- if (!Object.values(cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes).includes(args?.payload?.resourceType)) {
837
- throw new Error(`[did-provider-cheqd]: resourceType must be one of ${Object.values(cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes).join(', ')}`);
838
- }
839
- this.providerId = Cheqd.generateProviderId(args.network);
840
- this.didProvider = await Cheqd.getProviderFromNetwork(args.network, this.supportedDidProviders);
841
- return await this.didProvider.createResource({
842
- options: {
843
- kms: args.kms,
844
- payload: args.payload,
845
- signInputs: args.signInputs,
846
- fee: args?.fee ||
847
- (await sdk_1.ResourceModule.generateCreateResourceJsonFees((await this.didProvider.getWalletAccounts())[0].address)),
848
- },
849
- }, context);
850
- }
851
- async GenerateDidDoc(args, context) {
852
- if (typeof args.verificationMethod !== 'string') {
853
- throw new Error('[did-provider-cheqd]: verificationMethod is required');
854
- }
855
- if (typeof args.methodSpecificIdAlgo !== 'string') {
856
- throw new Error('[did-provider-cheqd]: methodSpecificIdAlgo is required');
857
- }
858
- if (typeof args.network !== 'string') {
859
- throw new Error('[did-provider-cheqd]: network is required');
860
- }
861
- const keyPair = (0, sdk_1.createKeyPairBase64)();
862
- const keyPairHex = {
863
- publicKey: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(keyPair.publicKey, 'base64'), 'hex'),
864
- privateKey: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(keyPair.privateKey, 'base64'), 'hex'),
865
- };
866
- const verificationKeys = (0, sdk_1.createVerificationKeys)(keyPair.publicKey, args.methodSpecificIdAlgo, 'key-1', args.network);
867
- const verificationMethods = (0, sdk_1.createDidVerificationMethod)([args.verificationMethod], [verificationKeys]);
868
- return {
869
- didDoc: (0, sdk_1.createDidPayload)(verificationMethods, [verificationKeys]),
870
- versionId: (0, uuid_1.v4)(),
871
- keys: [
872
- {
873
- publicKeyHex: keyPairHex.publicKey,
874
- privateKeyHex: keyPairHex.privateKey,
875
- kid: keyPairHex.publicKey,
876
- type: 'Ed25519',
877
- },
878
- ],
879
- };
880
- }
881
- async GenerateDidDocWithLinkedResource(args, context) {
882
- if (typeof args.verificationMethod !== 'string') {
883
- throw new Error('[did-provider-cheqd]: verificationMethod is required');
884
- }
885
- if (typeof args.methodSpecificIdAlgo !== 'string') {
886
- throw new Error('[did-provider-cheqd]: methodSpecificIdAlgo is required');
887
- }
888
- if (typeof args.network !== 'string') {
889
- throw new Error('[did-provider-cheqd]: network is required');
890
- }
891
- const keyPair = (0, sdk_1.createKeyPairBase64)();
892
- const keyPairHex = {
893
- publicKey: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(keyPair.publicKey, 'base64'), 'hex'),
894
- privateKey: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(keyPair.privateKey, 'base64'), 'hex'),
895
- };
896
- const verificationKeys = (0, sdk_1.createVerificationKeys)(keyPair.publicKey, args.methodSpecificIdAlgo, 'key-1', args.network);
897
- const verificationMethods = (0, sdk_1.createDidVerificationMethod)([args.verificationMethod], [verificationKeys]);
898
- const payload = (0, sdk_1.createDidPayload)(verificationMethods, [verificationKeys]);
899
- return {
900
- didDoc: payload,
901
- versionId: (0, uuid_1.v4)(),
902
- keys: [
903
- {
904
- publicKeyHex: keyPairHex.publicKey,
905
- privateKeyHex: keyPairHex.privateKey,
906
- kid: keyPairHex.publicKey,
907
- type: 'Ed25519',
908
- },
909
- ],
910
- linkedResource: {
911
- id: (0, uuid_1.v4)(),
912
- collectionId: payload.id.split(':').reverse()[0],
913
- name: 'sample json resource',
914
- version: '1.0.0',
915
- resourceType: 'SampleResource',
916
- alsoKnownAs: [],
917
- data: (0, uint8arrays_1.toString)(new TextEncoder().encode(JSON.stringify({ sample: 'json' })), 'base64'),
918
- },
919
- };
920
- }
921
- async GenerateIdentityKeys(args, context) {
922
- const keyPair = (0, sdk_1.createKeyPairHex)();
923
- return {
924
- publicKeyHex: keyPair.publicKey,
925
- privateKeyHex: keyPair.privateKey,
926
- kid: keyPair.publicKey,
927
- type: 'Ed25519',
928
- };
929
- }
930
- async GenerateVersionId(args, context) {
931
- return (0, uuid_1.v4)();
932
- }
933
- async GenerateStatusList2021(args, context) {
934
- const statusList = args?.buffer
935
- ? new vc_status_list_1.StatusList({ buffer: args.buffer })
936
- : new vc_status_list_1.StatusList({ length: args?.length || Cheqd.defaultStatusList2021Length });
937
- const encoded = (await statusList.encode());
938
- switch (args?.bitstringEncoding) {
939
- case 'base64url':
940
- return encoded;
941
- case 'hex':
942
- return (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(encoded, 'base64url'), 'hex');
943
- default:
944
- return encoded;
945
- }
946
- }
947
- async IssueRevocableCredentialWithStatusList2021(args, context) {
948
- // generate index
949
- const statusListIndex = args.statusOptions.statusListIndex ||
950
- (await (0, helpers_js_1.randomFromRange)(args.statusOptions.statusListRangeStart || 0, (args.statusOptions.statusListRangeEnd || Cheqd.defaultStatusList2021Length) - 1, args.statusOptions.indexNotIn || []));
951
- // construct issuer
952
- const issuer = args.issuanceOptions.credential.issuer.id
953
- ? args.issuanceOptions.credential.issuer.id
954
- : args.issuanceOptions.credential.issuer;
955
- // generate status list credential
956
- const statusListCredential = `${cheqd_did_resolver_js_1.DefaultResolverUrl}${issuer}?resourceName=${args.statusOptions.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.revocation}`;
957
- // construct credential status
958
- const credentialStatus = {
959
- id: `${statusListCredential}#${statusListIndex}`,
960
- type: 'StatusList2021Entry',
961
- statusPurpose: cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation,
962
- statusListIndex: `${statusListIndex}`,
963
- };
964
- // add credential status to credential
965
- args.issuanceOptions.credential.credentialStatus = credentialStatus;
966
- // add relevant context
967
- args.issuanceOptions.credential['@context'] = (function () {
968
- // if no context is provided, add default context
969
- if (!args.issuanceOptions.credential['@context']) {
970
- return [Cheqd.defaultContextV1, Cheqd.statusList2021Context];
971
- }
972
- // if context is provided as an array, add default context if it is not already present
973
- if (Array.isArray(args.issuanceOptions.credential['@context'])) {
974
- if (args.issuanceOptions.credential['@context'].length === 0) {
975
- return [Cheqd.defaultContextV1, Cheqd.statusList2021Context];
976
- }
977
- if (!args.issuanceOptions.credential['@context'].includes(Cheqd.statusList2021Context)) {
978
- return [...args.issuanceOptions.credential['@context'], Cheqd.statusList2021Context];
979
- }
980
- }
981
- // if context is provided as a string, add default context if it is not already present
982
- if (typeof args.issuanceOptions.credential['@context'] === 'string')
983
- return [Cheqd.defaultContextV1, Cheqd.statusList2021Context];
984
- })();
985
- // create a credential
986
- const credential = await context.agent.createVerifiableCredential(args.issuanceOptions);
987
- return credential;
988
- }
989
- async IssueSuspendableCredentialWithStatusList2021(args, context) {
990
- // generate index
991
- const statusListIndex = args.statusOptions.statusListIndex ||
992
- (await (0, helpers_js_1.randomFromRange)(args.statusOptions.statusListRangeStart || 0, (args.statusOptions.statusListRangeEnd || Cheqd.defaultStatusList2021Length) - 1, args.statusOptions.indexNotIn || []));
993
- // construct issuer
994
- const issuer = args.issuanceOptions.credential.issuer.id
995
- ? args.issuanceOptions.credential.issuer.id
996
- : args.issuanceOptions.credential.issuer;
997
- // generate status list credential
998
- const statusListCredential = `${cheqd_did_resolver_js_1.DefaultResolverUrl}${issuer}?resourceName=${args.statusOptions.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension}`;
999
- // construct credential status
1000
- const credentialStatus = {
1001
- id: `${statusListCredential}#${statusListIndex}`,
1002
- type: 'StatusList2021Entry',
1003
- statusPurpose: cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension,
1004
- statusListIndex: `${statusListIndex}`,
1005
- };
1006
- // add credential status to credential
1007
- args.issuanceOptions.credential.credentialStatus = credentialStatus;
1008
- // add relevant context
1009
- args.issuanceOptions.credential['@context'] = (function () {
1010
- // if no context is provided, add default context
1011
- if (!args.issuanceOptions.credential['@context']) {
1012
- return [Cheqd.defaultContextV1, Cheqd.statusList2021Context];
1013
- }
1014
- // if context is provided as an array, add default context if it is not already present
1015
- if (Array.isArray(args.issuanceOptions.credential['@context'])) {
1016
- if (args.issuanceOptions.credential['@context'].length === 0) {
1017
- return [Cheqd.defaultContextV1, Cheqd.statusList2021Context];
1018
- }
1019
- if (!args.issuanceOptions.credential['@context'].includes(Cheqd.statusList2021Context)) {
1020
- return [...args.issuanceOptions.credential['@context'], Cheqd.statusList2021Context];
1021
- }
1022
- }
1023
- // if context is provided as a string, add default context if it is not already present
1024
- if (typeof args.issuanceOptions.credential['@context'] === 'string')
1025
- return [Cheqd.defaultContextV1, Cheqd.statusList2021Context];
1026
- })();
1027
- // create a credential
1028
- const credential = await context.agent.createVerifiableCredential(args.issuanceOptions);
1029
- return credential;
1030
- }
1031
- async VerifyCredentialWithStatusList2021(args, context) {
1032
- // verify default policies
1033
- const verificationResult = await context.agent.verifyCredential({
1034
- ...args?.verificationArgs,
1035
- credential: args.credential,
1036
- policies: {
1037
- ...args?.verificationArgs?.policies,
1038
- credentialStatus: false,
1039
- },
1040
- });
1041
- // early return if verification failed
1042
- if (!verificationResult.verified) {
1043
- return { verified: false, error: verificationResult.error };
1044
- }
1045
- // if jwt credential, decode it
1046
- const credential = typeof args.credential === 'string' ? await Cheqd.decodeCredentialJWT(args.credential) : args.credential;
1047
- // define issuer
1048
- const issuer = typeof credential.issuer === 'string' ? credential.issuer : credential.issuer.id;
1049
- // define provider, if applicable
1050
- this.didProvider = await Cheqd.getProviderFromDidUrl(issuer, this.supportedDidProviders);
1051
- // define provider id, if applicable
1052
- this.providerId = Cheqd.generateProviderId(issuer);
1053
- // define dkg options, if provided
1054
- args.dkgOptions ||= this.didProvider.dkgOptions;
1055
- // verify credential status
1056
- switch (credential.credentialStatus?.statusPurpose) {
1057
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation:
1058
- return {
1059
- ...verificationResult,
1060
- revoked: await Cheqd.checkRevoked(credential, { ...args.options, topArgs: args }),
1061
- };
1062
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension:
1063
- return {
1064
- ...verificationResult,
1065
- suspended: await Cheqd.checkSuspended(credential, { ...args.options, topArgs: args }),
1066
- };
1067
- default:
1068
- throw new Error(`[did-provider-cheqd]: verify credential: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
1069
- }
1070
- }
1071
- async VerifyPresentationWithStatusList2021(args, context) {
1072
- // verify default policies
1073
- const verificationResult = await context.agent.verifyPresentation({
1074
- ...args?.verificationArgs,
1075
- presentation: args.presentation,
1076
- policies: {
1077
- ...args?.verificationArgs?.policies,
1078
- credentialStatus: false,
1079
- },
1080
- });
1081
- // early return if verification failed
1082
- if (!verificationResult.verified) {
1083
- return { verified: false, error: verificationResult.error };
1084
- }
1085
- // early return if no verifiable credentials are provided
1086
- if (!args.presentation.verifiableCredential)
1087
- throw new Error('[did-provider-cheqd]: verify presentation: presentation.verifiableCredential is required');
1088
- // verify credential(s) status(es)
1089
- for (let credential of args.presentation.verifiableCredential) {
1090
- // if jwt credential, decode it
1091
- if (typeof credential === 'string')
1092
- credential = await Cheqd.decodeCredentialJWT(credential);
1093
- // define issuer
1094
- const issuer = typeof credential.issuer === 'string' ? credential.issuer : credential.issuer.id;
1095
- // define provider, if applicable
1096
- this.didProvider = await Cheqd.getProviderFromDidUrl(issuer, this.supportedDidProviders);
1097
- // define provider id, if applicable
1098
- this.providerId = Cheqd.generateProviderId(issuer);
1099
- // define dkg options, if provided
1100
- args.dkgOptions ||= this.didProvider.dkgOptions;
1101
- switch (credential.credentialStatus?.statusPurpose) {
1102
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation:
1103
- return {
1104
- ...verificationResult,
1105
- revoked: await Cheqd.checkRevoked(credential, { ...args.options, topArgs: args }),
1106
- };
1107
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension:
1108
- return {
1109
- ...verificationResult,
1110
- suspended: await Cheqd.checkSuspended(credential, { ...args.options, topArgs: args }),
1111
- };
1112
- default:
1113
- throw new Error(`[did-provider-cheqd]: verify presentation: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
1114
- }
1115
- }
1116
- return { ...verificationResult, verified: true };
1117
- }
1118
- async CheckCredentialStatusWithStatusList2021(args, context) {
1119
- // verify credential, if provided and status options are not
1120
- if (args?.credential && !args?.statusOptions) {
1121
- const verificationResult = await context.agent.verifyCredential({
1122
- ...args?.verificationOptions,
1123
- credential: args.credential,
1124
- policies: {
1125
- credentialStatus: false,
1126
- },
1127
- });
1128
- // early return if verification failed
1129
- if (!verificationResult.verified) {
1130
- return { revoked: false, error: verificationResult.error };
1131
- }
1132
- }
1133
- // if status options are provided, give precedence
1134
- if (args?.statusOptions) {
1135
- // validate status options - case: statusOptions.issuerDid
1136
- if (!args.statusOptions.issuerDid)
1137
- throw new Error('[did-provider-cheqd]: check status: statusOptions.issuerDid is required');
1138
- // validate status options - case: statusOptions.statusListName
1139
- if (!args.statusOptions.statusListName)
1140
- throw new Error('[did-provider-cheqd]: check status: statusOptions.statusListName is required');
1141
- // validate status options - case: statusOptions.statusListIndex
1142
- if (!args.statusOptions.statusPurpose)
1143
- throw new Error('[did-provider-cheqd]: check status: statusOptions.statusListIndex is required');
1144
- // validate status options - case: statusOptions.statusListIndex
1145
- if (!args.statusOptions.statusListIndex)
1146
- throw new Error('[did-provider-cheqd]: check status: statusOptions.statusListIndex is required');
1147
- // generate resource type
1148
- const resourceType = args.statusOptions.statusPurpose === cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation
1149
- ? cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.revocation
1150
- : cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension;
1151
- // construct status list credential
1152
- const statusListCredential = `${cheqd_did_resolver_js_1.DefaultResolverUrl}${args.statusOptions.issuerDid}?resourceName=${args.statusOptions.statusListName}&resourceType=${resourceType}`;
1153
- // construct credential status
1154
- args.credential = {
1155
- '@context': [],
1156
- issuer: args.statusOptions.issuerDid,
1157
- credentialSubject: {},
1158
- credentialStatus: {
1159
- id: `${statusListCredential}#${args.statusOptions.statusListIndex}`,
1160
- type: 'StatusList2021Entry',
1161
- statusPurpose: `${args.statusOptions.statusPurpose}`,
1162
- statusListIndex: `${args.statusOptions.statusListIndex}`,
1163
- },
1164
- issuanceDate: '',
1165
- proof: {},
1166
- };
1167
- }
1168
- // validate args - case: credential
1169
- if (!args.credential)
1170
- throw new Error('[did-provider-cheqd]: revocation: credential is required');
1171
- // if jwt credential, decode it
1172
- const credential = typeof args.credential === 'string' ? await Cheqd.decodeCredentialJWT(args.credential) : args.credential;
1173
- // define issuer
1174
- const issuer = typeof credential.issuer === 'string' ? credential.issuer : credential.issuer.id;
1175
- // define provider, if applicable
1176
- this.didProvider = await Cheqd.getProviderFromDidUrl(issuer, this.supportedDidProviders);
1177
- // define provider id, if applicable
1178
- this.providerId = Cheqd.generateProviderId(issuer);
1179
- // define dkg options, if provided
1180
- args.dkgOptions ||= this.didProvider.dkgOptions;
1181
- switch (credential.credentialStatus?.statusPurpose) {
1182
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation:
1183
- return { revoked: await Cheqd.checkRevoked(credential, { ...args.options, topArgs: args }) };
1184
- case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension:
1185
- return { suspended: await Cheqd.checkSuspended(credential, { ...args.options, topArgs: args }) };
1186
- default:
1187
- throw new Error(`[did-provider-cheqd]: check status: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
1188
- }
1189
- }
1190
- async RevokeCredentialWithStatusList2021(args, context) {
1191
- // verify credential, if provided and revocation options are not
1192
- if (args?.credential && !args?.revocationOptions) {
1193
- const verificationResult = await context.agent.verifyCredential({
1194
- ...args?.verificationOptions,
1195
- credential: args.credential,
1196
- policies: {
1197
- credentialStatus: false,
1198
- },
1199
- });
1200
- // early return if verification failed
1201
- if (!verificationResult.verified) {
1202
- return { revoked: false, error: verificationResult.error };
1203
- }
1204
- }
1205
- // if revocation options are provided, give precedence
1206
- if (args?.revocationOptions) {
1207
- // validate revocation options - case: revocationOptions.issuerDid
1208
- if (!args.revocationOptions.issuerDid)
1209
- throw new Error('[did-provider-cheqd]: revocation: revocationOptions.issuerDid is required');
1210
- // validate revocation options - case: revocationOptions.statusListName
1211
- if (!args.revocationOptions.statusListName)
1212
- throw new Error('[did-provider-cheqd]: revocation: revocationOptions.statusListName is required');
1213
- // validate revocation options - case: revocationOptions.statusListIndex
1214
- if (!args.revocationOptions.statusListIndex)
1215
- throw new Error('[did-provider-cheqd]: revocation: revocationOptions.statusListIndex is required');
1216
- // construct status list credential
1217
- const statusListCredential = `${cheqd_did_resolver_js_1.DefaultResolverUrl}${args.revocationOptions.issuerDid}?resourceName=${args.revocationOptions.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.revocation}`;
1218
- // construct credential status
1219
- args.credential = {
1220
- '@context': [],
1221
- issuer: args.revocationOptions.issuerDid,
1222
- credentialSubject: {},
1223
- credentialStatus: {
1224
- id: `${statusListCredential}#${args.revocationOptions.statusListIndex}`,
1225
- type: 'StatusList2021Entry',
1226
- statusPurpose: cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation,
1227
- statusListIndex: `${args.revocationOptions.statusListIndex}`,
1228
- },
1229
- issuanceDate: '',
1230
- proof: {},
1231
- };
1232
- }
1233
- // validate args - case: credential
1234
- if (!args.credential)
1235
- throw new Error('[did-provider-cheqd]: revocation: credential is required');
1236
- // if jwt credential, decode it
1237
- const credential = typeof args.credential === 'string' ? await Cheqd.decodeCredentialJWT(args.credential) : args.credential;
1238
- // validate status purpose
1239
- if (credential.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation) {
1240
- throw new Error(`[did-provider-cheqd]: revocation: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
1241
- }
1242
- // validate args in pairs - case: statusListFile and statusList
1243
- if (args.options?.statusListFile && args.options?.statusList) {
1244
- throw new Error('[did-provider-cheqd]: revocation: statusListFile and statusList are mutually exclusive');
1245
- }
1246
- // validate args in pairs - case: statusListFile and fetchList
1247
- if (args.options?.statusListFile && args.options?.fetchList) {
1248
- throw new Error('[did-provider-cheqd]: revocation: statusListFile and fetchList are mutually exclusive');
1249
- }
1250
- // validate args in pairs - case: statusList and fetchList
1251
- if (args.options?.statusList && args.options?.fetchList) {
1252
- throw new Error('[did-provider-cheqd]: revocation: statusList and fetchList are mutually exclusive');
1253
- }
1254
- // validate args in pairs - case: publish
1255
- if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
1256
- throw new Error('[did-provider-cheqd]: revocation: publish requires statusListFile or statusList, if fetchList is disabled');
1257
- }
1258
- // define issuer
1259
- const issuer = typeof credential.issuer === 'string' ? credential.issuer : credential.issuer.id;
1260
- // define provider, if applicable
1261
- this.didProvider = await Cheqd.getProviderFromDidUrl(issuer, this.supportedDidProviders);
1262
- // define provider id, if applicable
1263
- this.providerId = Cheqd.generateProviderId(issuer);
1264
- // define dkg options, if provided
1265
- args.dkgOptions ||= this.didProvider.dkgOptions;
1266
- // revoke credential
1267
- return await Cheqd.revokeCredential(credential, {
1268
- ...args.options,
1269
- topArgs: args,
1270
- publishOptions: {
1271
- context,
1272
- statusListEncoding: args?.options?.statusListEncoding,
1273
- statusListValidUntil: args?.options?.statusListValidUntil,
1274
- resourceId: args?.options?.resourceId,
1275
- resourceVersion: args?.options?.resourceVersion,
1276
- resourceAlsoKnownAs: args?.options?.alsoKnownAs,
1277
- signInputs: args?.options?.signInputs,
1278
- fee: args?.options?.fee,
1279
- },
1280
- });
1281
- }
1282
- async RevokeBulkCredentialsWithStatusList2021(args, context) {
1283
- // verify credential, if provided and revocation options are not
1284
- if (args?.credentials && !args?.revocationOptions) {
1285
- const verificationResult = await Promise.all(args.credentials.map(async (credential) => {
1286
- return await context.agent.verifyCredential({
1287
- ...args?.verificationOptions,
1288
- credential,
1289
- policies: {
1290
- credentialStatus: false,
1291
- },
1292
- });
1293
- }));
1294
- // early return if verification failed for any credential
1295
- if (verificationResult.some((result) => !result.verified)) {
1296
- // define verified
1297
- return {
1298
- revoked: Array(args.credentials.length).fill(false),
1299
- error: verificationResult.find((result) => !result.verified).error || {
1300
- message: 'verification: could not verify credential',
1301
- },
1302
- };
1303
- }
1304
- }
1305
- // if revocation options are provided, give precedence
1306
- if (args?.revocationOptions) {
1307
- // validate revocation options - case: revocationOptions.issuerDid
1308
- if (!args.revocationOptions.issuerDid)
1309
- throw new Error('[did-provider-cheqd]: revocation: revocationOptions.issuerDid is required');
1310
- // validate revocation options - case: revocationOptions.statusListName
1311
- if (!args.revocationOptions.statusListName)
1312
- throw new Error('[did-provider-cheqd]: revocation: revocationOptions.statusListName is required');
1313
- // validate revocation options - case: revocationOptions.statusListIndices
1314
- if (!args.revocationOptions.statusListIndices ||
1315
- !args.revocationOptions.statusListIndices.length ||
1316
- args.revocationOptions.statusListIndices.length === 0 ||
1317
- !args.revocationOptions.statusListIndices.every((index) => !isNaN(+index)))
1318
- throw new Error('[did-provider-cheqd]: revocation: revocationOptions.statusListIndex is required and must be an array of indices');
1319
- // construct status list credential
1320
- const statusListCredential = `${cheqd_did_resolver_js_1.DefaultResolverUrl}${args.revocationOptions.issuerDid}?resourceName=${args.revocationOptions.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.revocation}`;
1321
- // construct credential status
1322
- args.credentials = args.revocationOptions.statusListIndices.map((index) => ({
1323
- '@context': [],
1324
- issuer: args.revocationOptions.issuerDid,
1325
- credentialSubject: {},
1326
- credentialStatus: {
1327
- id: `${statusListCredential}#${index}`,
1328
- type: 'StatusList2021Entry',
1329
- statusPurpose: cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation,
1330
- statusListIndex: `${index}`,
1331
- },
1332
- issuanceDate: '',
1333
- proof: {},
1334
- }));
1335
- }
1336
- // validate args - case: credentials
1337
- if (!args.credentials || !args.credentials.length || args.credentials.length === 0)
1338
- throw new Error('[did-provider-cheqd]: revocation: credentials is required and must be an array of credentials');
1339
- // if jwt credentials, decode them
1340
- const credentials = await Promise.all(args.credentials.map(async (credential) => typeof credential === 'string' ? await Cheqd.decodeCredentialJWT(credential) : credential));
1341
- // validate args in pairs - case: statusListFile and statusList
1342
- if (args.options?.statusListFile && args.options?.statusList) {
1343
- throw new Error('[did-provider-cheqd]: revocation: statusListFile and statusList are mutually exclusive');
1344
- }
1345
- // validate args in pairs - case: statusListFile and fetchList
1346
- if (args.options?.statusListFile && args.options?.fetchList) {
1347
- throw new Error('[did-provider-cheqd]: revocation: statusListFile and fetchList are mutually exclusive');
1348
- }
1349
- // validate args in pairs - case: statusList and fetchList
1350
- if (args.options?.statusList && args.options?.fetchList) {
1351
- throw new Error('[did-provider-cheqd]: revocation: statusList and fetchList are mutually exclusive');
1352
- }
1353
- // validate args in pairs - case: publish
1354
- if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
1355
- throw new Error('[did-provider-cheqd]: revocation: publish requires statusListFile or statusList, if fetchList is disabled');
1356
- }
1357
- // define issuer
1358
- const issuer = typeof credentials[0].issuer === 'string'
1359
- ? credentials[0].issuer
1360
- : credentials[0].issuer.id;
1361
- // define provider, if applicable
1362
- this.didProvider = await Cheqd.getProviderFromDidUrl(issuer, this.supportedDidProviders);
1363
- // define provider id, if applicable
1364
- this.providerId = Cheqd.generateProviderId(issuer);
1365
- // define dkg options, if provided
1366
- args.dkgOptions ||= this.didProvider.dkgOptions;
1367
- // revoke credentials
1368
- return await Cheqd.revokeCredentials(credentials, {
1369
- ...args.options,
1370
- topArgs: args,
1371
- publishOptions: {
1372
- context,
1373
- resourceId: args?.options?.resourceId,
1374
- resourceVersion: args?.options?.resourceVersion,
1375
- resourceAlsoKnownAs: args?.options?.alsoKnownAs,
1376
- signInputs: args?.options?.signInputs,
1377
- fee: args?.options?.fee,
1378
- },
1379
- });
1380
- }
1381
- async SuspendCredentialWithStatusList2021(args, context) {
1382
- // verify credential, if provided and suspension options are not
1383
- if (args?.credential && !args?.suspensionOptions) {
1384
- const verificationResult = await context.agent.verifyCredential({
1385
- ...args?.verificationOptions,
1386
- credential: args.credential,
1387
- policies: {
1388
- credentialStatus: false,
1389
- },
1390
- });
1391
- // early return if verification failed
1392
- if (!verificationResult.verified) {
1393
- return { suspended: false, error: verificationResult.error };
1394
- }
1395
- }
1396
- // if suspension options are provided, give precedence
1397
- if (args?.suspensionOptions) {
1398
- // validate suspension options - case: suspensionOptions.issuerDid
1399
- if (!args.suspensionOptions.issuerDid)
1400
- throw new Error('[did-provider-cheqd]: suspension: suspensionOptions.issuerDid is required');
1401
- // validate suspension options - case: suspensionOptions.statusListName
1402
- if (!args.suspensionOptions.statusListName)
1403
- throw new Error('[did-provider-cheqd]: suspension: suspensionOptions.statusListName is required');
1404
- // validate suspension options - case: suspensionOptions.statusListIndex
1405
- if (!args.suspensionOptions.statusListIndex)
1406
- throw new Error('[did-provider-cheqd]: suspension: suspensionOptions.statusListIndex is required');
1407
- // construct status list credential
1408
- const statusListCredential = `${cheqd_did_resolver_js_1.DefaultResolverUrl}${args.suspensionOptions.issuerDid}?resourceName=${args.suspensionOptions.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension}`;
1409
- // construct credential status
1410
- args.credential = {
1411
- '@context': [],
1412
- issuer: args.suspensionOptions.issuerDid,
1413
- credentialSubject: {},
1414
- credentialStatus: {
1415
- id: `${statusListCredential}#${args.suspensionOptions.statusListIndex}`,
1416
- type: 'StatusList2021Entry',
1417
- statusPurpose: cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension,
1418
- statusListIndex: `${args.suspensionOptions.statusListIndex}`,
1419
- },
1420
- issuanceDate: '',
1421
- proof: {},
1422
- };
1423
- }
1424
- // validate args - case: credential
1425
- if (!args.credential)
1426
- throw new Error('[did-provider-cheqd]: suspension: credential is required');
1427
- // if jwt credential, decode it
1428
- const credential = typeof args.credential === 'string' ? await Cheqd.decodeCredentialJWT(args.credential) : args.credential;
1429
- // validate status purpose
1430
- if (credential.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension) {
1431
- throw new Error(`[did-provider-cheqd]: suspension: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
1432
- }
1433
- // validate args in pairs - case: statusListFile and statusList
1434
- if (args.options?.statusListFile && args.options?.statusList) {
1435
- throw new Error('[did-provider-cheqd]: suspension: statusListFile and statusList are mutually exclusive');
1436
- }
1437
- // validate args in pairs - case: statusListFile and fetchList
1438
- if (args.options?.statusListFile && args.options?.fetchList) {
1439
- throw new Error('[did-provider-cheqd]: suspension: statusListFile and fetchList are mutually exclusive');
1440
- }
1441
- // validate args in pairs - case: statusList and fetchList
1442
- if (args.options?.statusList && args.options?.fetchList) {
1443
- throw new Error('[did-provider-cheqd]: suspension: statusList and fetchList are mutually exclusive');
1444
- }
1445
- // validate args in pairs - case: publish
1446
- if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
1447
- throw new Error('[did-provider-cheqd]: suspension: publish requires statusListFile or statusList, if fetchList is disabled');
1448
- }
1449
- // define issuer
1450
- const issuer = typeof credential.issuer === 'string' ? credential.issuer : credential.issuer.id;
1451
- // define provider, if applicable
1452
- this.didProvider = await Cheqd.getProviderFromDidUrl(issuer, this.supportedDidProviders);
1453
- // define provider id, if applicable
1454
- this.providerId = Cheqd.generateProviderId(issuer);
1455
- // define dkg options, if provided
1456
- args.dkgOptions ||= this.didProvider.dkgOptions;
1457
- // suspend credential
1458
- return await Cheqd.suspendCredential(credential, {
1459
- ...args.options,
1460
- topArgs: args,
1461
- publishOptions: {
1462
- context,
1463
- statusListEncoding: args?.options?.statusListEncoding,
1464
- statusListValidUntil: args?.options?.statusListValidUntil,
1465
- resourceId: args?.options?.resourceId,
1466
- resourceVersion: args?.options?.resourceVersion,
1467
- resourceAlsoKnownAs: args?.options?.alsoKnownAs,
1468
- signInputs: args?.options?.signInputs,
1469
- fee: args?.options?.fee,
1470
- },
1471
- });
1472
- }
1473
- async SuspendBulkCredentialsWithStatusList2021(args, context) {
1474
- // verify credential, if provided and suspension options are not
1475
- if (args?.credentials && !args?.suspensionOptions) {
1476
- const verificationResult = await Promise.all(args.credentials.map(async (credential) => {
1477
- return await context.agent.verifyCredential({
1478
- ...args?.verificationOptions,
1479
- credential,
1480
- policies: {
1481
- credentialStatus: false,
1482
- },
1483
- });
1484
- }));
1485
- // early return if verification failed for any credential
1486
- if (verificationResult.some((result) => !result.verified)) {
1487
- // define verified
1488
- return {
1489
- suspended: Array(args.credentials.length).fill(false),
1490
- error: verificationResult.find((result) => !result.verified).error || {
1491
- message: 'verification: could not verify credential',
1492
- },
1493
- };
1494
- }
1495
- }
1496
- // if suspension options are provided, give precedence
1497
- if (args?.suspensionOptions) {
1498
- // validate suspension options - case: suspensionOptions.issuerDid
1499
- if (!args.suspensionOptions.issuerDid)
1500
- throw new Error('[did-provider-cheqd]: suspension: suspensionOptions.issuerDid is required');
1501
- // validate suspension options - case: suspensionOptions.statusListName
1502
- if (!args.suspensionOptions.statusListName)
1503
- throw new Error('[did-provider-cheqd]: suspension: suspensionOptions.statusListName is required');
1504
- // validate suspension options - case: suspensionOptions.statusListIndices
1505
- if (!args.suspensionOptions.statusListIndices ||
1506
- !args.suspensionOptions.statusListIndices.length ||
1507
- args.suspensionOptions.statusListIndices.length === 0 ||
1508
- !args.suspensionOptions.statusListIndices.every((index) => !isNaN(+index)))
1509
- throw new Error('[did-provider-cheqd]: suspension: suspensionOptions.statusListIndex is required and must be an array of indices');
1510
- // construct status list credential
1511
- const statusListCredential = `${cheqd_did_resolver_js_1.DefaultResolverUrl}${args.suspensionOptions.issuerDid}?resourceName=${args.suspensionOptions.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension}`;
1512
- // construct credential status
1513
- args.credentials = args.suspensionOptions.statusListIndices.map((index) => ({
1514
- '@context': [],
1515
- issuer: args.suspensionOptions.issuerDid,
1516
- credentialSubject: {},
1517
- credentialStatus: {
1518
- id: `${statusListCredential}#${index}`,
1519
- type: 'StatusList2021Entry',
1520
- statusPurpose: cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension,
1521
- statusListIndex: `${index}`,
1522
- },
1523
- issuanceDate: '',
1524
- proof: {},
1525
- }));
1526
- }
1527
- // validate args - case: credentials
1528
- if (!args.credentials || !args.credentials.length || args.credentials.length === 0)
1529
- throw new Error('[did-provider-cheqd]: suspension: credentials is required and must be an array of credentials');
1530
- // if jwt credentials, decode them
1531
- const credentials = await Promise.all(args.credentials.map(async (credential) => typeof credential === 'string' ? await Cheqd.decodeCredentialJWT(credential) : credential));
1532
- // validate args in pairs - case: statusListFile and statusList
1533
- if (args.options?.statusListFile && args.options?.statusList) {
1534
- throw new Error('[did-provider-cheqd]: suspension: statusListFile and statusList are mutually exclusive');
1535
- }
1536
- // validate args in pairs - case: statusListFile and fetchList
1537
- if (args.options?.statusListFile && args.options?.fetchList) {
1538
- throw new Error('[did-provider-cheqd]: suspension: statusListFile and fetchList are mutually exclusive');
1539
- }
1540
- // validate args in pairs - case: statusList and fetchList
1541
- if (args.options?.statusList && args.options?.fetchList) {
1542
- throw new Error('[did-provider-cheqd]: suspension: statusList and fetchList are mutually exclusive');
1543
- }
1544
- // validate args in pairs - case: publish
1545
- if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
1546
- throw new Error('[did-provider-cheqd]: suspension: publish requires statusListFile or statusList, if fetchList is disabled');
1547
- }
1548
- // define issuer
1549
- const issuer = typeof credentials[0].issuer === 'string'
1550
- ? credentials[0].issuer
1551
- : credentials[0].issuer.id;
1552
- // define provider, if applicable
1553
- this.didProvider = await Cheqd.getProviderFromDidUrl(issuer, this.supportedDidProviders);
1554
- // define provider id, if applicable
1555
- this.providerId = Cheqd.generateProviderId(issuer);
1556
- // define dkg options, if provided
1557
- args.dkgOptions ||= this.didProvider.dkgOptions;
1558
- // suspend credentials
1559
- return await Cheqd.suspendCredentials(credentials, {
1560
- ...args.options,
1561
- topArgs: args,
1562
- publishOptions: {
1563
- context,
1564
- resourceId: args?.options?.resourceId,
1565
- resourceVersion: args?.options?.resourceVersion,
1566
- resourceAlsoKnownAs: args?.options?.alsoKnownAs,
1567
- signInputs: args?.options?.signInputs,
1568
- fee: args?.options?.fee,
1569
- },
1570
- });
1571
- }
1572
- async UnsuspendCredentialWithStatusList2021(args, context) {
1573
- // verify credential, if provided and unsuspension options are not
1574
- if (args?.credential && !args?.unsuspensionOptions) {
1575
- const verificationResult = await context.agent.verifyCredential({
1576
- ...args?.verificationOptions,
1577
- credential: args.credential,
1578
- policies: {
1579
- credentialStatus: false,
1580
- },
1581
- });
1582
- // early return if verification failed
1583
- if (!verificationResult.verified) {
1584
- return { unsuspended: false, error: verificationResult.error };
1585
- }
1586
- }
1587
- // if unsuspension options are provided, give precedence
1588
- if (args?.unsuspensionOptions) {
1589
- // validate unsuspension options - case: unsuspensionOptions.issuerDid
1590
- if (!args.unsuspensionOptions.issuerDid)
1591
- throw new Error('[did-provider-cheqd]: unsuspension: unsuspensionOptions.issuerDid is required');
1592
- // validate unsuspension options - case: unsuspensionOptions.statusListName
1593
- if (!args.unsuspensionOptions.statusListName)
1594
- throw new Error('[did-provider-cheqd]: unsuspension: unsuspensionOptions.statusListName is required');
1595
- // validate unsuspension options - case: unsuspensionOptions.statusListIndex
1596
- if (!args.unsuspensionOptions.statusListIndex)
1597
- throw new Error('[did-provider-cheqd]: unsuspension: unsuspensionOptions.statusListIndex is required');
1598
- // construct status list credential
1599
- const statusListCredential = `${cheqd_did_resolver_js_1.DefaultResolverUrl}${args.unsuspensionOptions.issuerDid}?resourceName=${args.unsuspensionOptions.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension}`;
1600
- // construct credential status
1601
- args.credential = {
1602
- '@context': [],
1603
- issuer: args.unsuspensionOptions.issuerDid,
1604
- credentialSubject: {},
1605
- credentialStatus: {
1606
- id: `${statusListCredential}#${args.unsuspensionOptions.statusListIndex}`,
1607
- type: 'StatusList2021Entry',
1608
- statusPurpose: cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension,
1609
- statusListIndex: `${args.unsuspensionOptions.statusListIndex}`,
1610
- },
1611
- issuanceDate: '',
1612
- proof: {},
1613
- };
1614
- }
1615
- // validate args - case: credential
1616
- if (!args.credential)
1617
- throw new Error('[did-provider-cheqd]: unsuspension: credential is required');
1618
- // if jwt credential, decode it
1619
- const credential = typeof args.credential === 'string' ? await Cheqd.decodeCredentialJWT(args.credential) : args.credential;
1620
- // validate status purpose
1621
- if (credential.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension) {
1622
- throw new Error(`[did-provider-cheqd]: suspension: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
1623
- }
1624
- // validate args in pairs - case: statusListFile and statusList
1625
- if (args.options?.statusListFile && args.options?.statusList) {
1626
- throw new Error('[did-provider-cheqd]: suspension: statusListFile and statusList are mutually exclusive');
1627
- }
1628
- // validate args in pairs - case: statusListFile and fetchList
1629
- if (args.options?.statusListFile && args.options?.fetchList) {
1630
- throw new Error('[did-provider-cheqd]: suspension: statusListFile and fetchList are mutually exclusive');
1631
- }
1632
- // validate args in pairs - case: statusList and fetchList
1633
- if (args.options?.statusList && args.options?.fetchList) {
1634
- throw new Error('[did-provider-cheqd]: suspension: statusList and fetchList are mutually exclusive');
1635
- }
1636
- // validate args in pairs - case: publish
1637
- if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
1638
- throw new Error('[did-provider-cheqd]: suspension: publish requires statusListFile or statusList, if fetchList is disabled');
1639
- }
1640
- // define issuer
1641
- const issuer = typeof credential.issuer === 'string' ? credential.issuer : credential.issuer.id;
1642
- // define provider, if applicable
1643
- this.didProvider = await Cheqd.getProviderFromDidUrl(issuer, this.supportedDidProviders);
1644
- // define provider id, if applicable
1645
- this.providerId = Cheqd.generateProviderId(issuer);
1646
- // define dkg options, if provided
1647
- args.dkgOptions ||= this.didProvider.dkgOptions;
1648
- // suspend credential
1649
- return await Cheqd.unsuspendCredential(credential, {
1650
- ...args.options,
1651
- topArgs: args,
1652
- publishOptions: {
1653
- context,
1654
- statusListEncoding: args?.options?.statusListEncoding,
1655
- statusListValidUntil: args?.options?.statusListValidUntil,
1656
- resourceId: args?.options?.resourceId,
1657
- resourceVersion: args?.options?.resourceVersion,
1658
- resourceAlsoKnownAs: args?.options?.alsoKnownAs,
1659
- signInputs: args?.options?.signInputs,
1660
- fee: args?.options?.fee,
1661
- },
1662
- });
1663
- }
1664
- async UnsuspendBulkCredentialsWithStatusList2021(args, context) {
1665
- // verify credential, if provided and unsuspension options are not
1666
- if (args?.credentials && !args?.unsuspensionOptions) {
1667
- const verificationResult = await Promise.all(args.credentials.map(async (credential) => {
1668
- return await context.agent.verifyCredential({
1669
- ...args?.verificationOptions,
1670
- credential,
1671
- policies: {
1672
- credentialStatus: false,
1673
- },
1674
- });
1675
- }));
1676
- // early return if verification failed for any credential
1677
- if (verificationResult.some((result) => !result.verified)) {
1678
- // define verified
1679
- return {
1680
- unsuspended: Array(args.credentials.length).fill(false),
1681
- error: verificationResult.find((result) => !result.verified).error || {
1682
- message: 'verification: could not verify credential',
1683
- },
1684
- };
1685
- }
1686
- }
1687
- // if unsuspension options are provided, give precedence
1688
- if (args?.unsuspensionOptions) {
1689
- // validate unsuspension options - case: unsuspensionOptions.issuerDid
1690
- if (!args.unsuspensionOptions.issuerDid)
1691
- throw new Error('[did-provider-cheqd]: unsuspension: unsuspensionOptions.issuerDid is required');
1692
- // validate unsuspension options - case: unsuspensionOptions.statusListName
1693
- if (!args.unsuspensionOptions.statusListName)
1694
- throw new Error('[did-provider-cheqd]: unsuspension: unsuspensionOptions.statusListName is required');
1695
- // validate unsuspension options - case: unsuspensionOptions.statusListIndices
1696
- if (!args.unsuspensionOptions.statusListIndices ||
1697
- !args.unsuspensionOptions.statusListIndices.length ||
1698
- args.unsuspensionOptions.statusListIndices.length === 0 ||
1699
- !args.unsuspensionOptions.statusListIndices.every((index) => !isNaN(+index)))
1700
- throw new Error('[did-provider-cheqd]: unsuspension: unsuspensionOptions.statusListIndex is required and must be an array of indices');
1701
- // construct status list credential
1702
- const statusListCredential = `${cheqd_did_resolver_js_1.DefaultResolverUrl}${args.unsuspensionOptions.issuerDid}?resourceName=${args.unsuspensionOptions.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension}`;
1703
- // construct credential status
1704
- args.credentials = args.unsuspensionOptions.statusListIndices.map((index) => ({
1705
- '@context': [],
1706
- issuer: args.unsuspensionOptions.issuerDid,
1707
- credentialSubject: {},
1708
- credentialStatus: {
1709
- id: `${statusListCredential}#${index}`,
1710
- type: 'StatusList2021Entry',
1711
- statusPurpose: cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension,
1712
- statusListIndex: `${index}`,
1713
- },
1714
- issuanceDate: '',
1715
- proof: {},
1716
- }));
1717
- }
1718
- // validate args - case: credentials
1719
- if (!args.credentials || !args.credentials.length || args.credentials.length === 0)
1720
- throw new Error('[did-provider-cheqd]: unsuspension: credentials is required and must be an array of credentials');
1721
- // if jwt credentials, decode them
1722
- const credentials = await Promise.all(args.credentials.map(async (credential) => typeof credential === 'string' ? await Cheqd.decodeCredentialJWT(credential) : credential));
1723
- // validate args in pairs - case: statusListFile and statusList
1724
- if (args.options?.statusListFile && args.options?.statusList) {
1725
- throw new Error('[did-provider-cheqd]: unsuspension: statusListFile and statusList are mutually exclusive');
1726
- }
1727
- // validate args in pairs - case: statusListFile and fetchList
1728
- if (args.options?.statusListFile && args.options?.fetchList) {
1729
- throw new Error('[did-provider-cheqd]: unsuspension: statusListFile and fetchList are mutually exclusive');
1730
- }
1731
- // validate args in pairs - case: statusList and fetchList
1732
- if (args.options?.statusList && args.options?.fetchList) {
1733
- throw new Error('[did-provider-cheqd]: unsuspension: statusList and fetchList are mutually exclusive');
1734
- }
1735
- // validate args in pairs - case: publish
1736
- if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
1737
- throw new Error('[did-provider-cheqd]: unsuspension: publish requires statusListFile or statusList, if fetchList is disabled');
1738
- }
1739
- // define issuer
1740
- const issuer = typeof credentials[0].issuer === 'string'
1741
- ? credentials[0].issuer
1742
- : credentials[0].issuer.id;
1743
- // define provider, if applicable
1744
- this.didProvider = await Cheqd.getProviderFromDidUrl(issuer, this.supportedDidProviders);
1745
- // define provider id, if applicable
1746
- this.providerId = Cheqd.generateProviderId(issuer);
1747
- // define dkg options, if provided
1748
- args.dkgOptions ||= this.didProvider.dkgOptions;
1749
- // suspend credentials
1750
- return await Cheqd.unsuspendCredentials(credentials, {
1751
- ...args.options,
1752
- topArgs: args,
1753
- publishOptions: {
1754
- context,
1755
- resourceId: args?.options?.resourceId,
1756
- resourceVersion: args?.options?.resourceVersion,
1757
- resourceAlsoKnownAs: args?.options?.alsoKnownAs,
1758
- signInputs: args?.options?.signInputs,
1759
- fee: args?.options?.fee,
1760
- },
1761
- });
1762
- }
1763
- async TransactSendTokens(args, context) {
1764
- // define provider
1765
- const provider = await Cheqd.getProviderFromNetwork(args.network, this.supportedDidProviders);
1766
- try {
1767
- // delegate to provider
1768
- const transactionResult = await provider.transactSendTokens({
1769
- recipientAddress: args.recipientAddress,
1770
- amount: args.amount,
1771
- memo: args.memo,
1772
- txBytes: args.txBytes,
1773
- });
1774
- // return transaction result
1775
- return {
1776
- successful: !transactionResult.code,
1777
- transactionHash: transactionResult.transactionHash,
1778
- events: transactionResult.events,
1779
- rawLog: transactionResult.rawLog,
1780
- txResponse: args?.returnTxResponse ? transactionResult : undefined,
1781
- };
1782
- }
1783
- catch (error) {
1784
- // return error
1785
- return {
1786
- successful: false,
1787
- error: error,
1788
- };
1789
- }
1790
- }
1791
- async ObservePaymentCondition(args, context) {
1792
- // verify with raw unified access control condition, if any
1793
- if (args?.unifiedAccessControlCondition) {
1794
- // validate args - case: unifiedAccessControlCondition.chain
1795
- if (!args.unifiedAccessControlCondition.chain ||
1796
- !Object.values(v6_js_1.LitCompatibleCosmosChains).includes(args.unifiedAccessControlCondition.chain))
1797
- throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.chain is required and must be a valid Lit-compatible chain');
1798
- // validate args - case: unifiedAccessControlCondition.path
1799
- if (!args.unifiedAccessControlCondition.path)
1800
- throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.path is required');
1801
- // validate args - case: unifiedAccessControlCondition.conditionType
1802
- if (args.unifiedAccessControlCondition.conditionType !== 'cosmos')
1803
- throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.conditionType must be cosmos');
1804
- // validate args - case: unifiedAccessControlCondition.method
1805
- if (args.unifiedAccessControlCondition.method !== 'timelock')
1806
- throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.method must be timelock');
1807
- // validate args - case: unifiedAccessControlCondition.parameters
1808
- if (!args.unifiedAccessControlCondition.parameters ||
1809
- !Array.isArray(args.unifiedAccessControlCondition.parameters) ||
1810
- args.unifiedAccessControlCondition.parameters.length === 0 ||
1811
- args.unifiedAccessControlCondition.parameters.length > 1)
1812
- throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.parameters is required and must be an array of length 1 of type string content');
1813
- // validate args - case: unifiedAccessControlCondition.returnValueTest
1814
- if (!args.unifiedAccessControlCondition.returnValueTest ||
1815
- !args.unifiedAccessControlCondition.returnValueTest.comparator ||
1816
- !args.unifiedAccessControlCondition.returnValueTest.key ||
1817
- !args.unifiedAccessControlCondition.returnValueTest.value)
1818
- throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.returnValueTest is required');
1819
- try {
1820
- // define network
1821
- const network = (function () {
1822
- switch (args.unifiedAccessControlCondition.chain) {
1823
- case v6_js_1.LitCompatibleCosmosChains.cheqdMainnet:
1824
- return sdk_1.CheqdNetwork.Mainnet;
1825
- case v6_js_1.LitCompatibleCosmosChains.cheqdTestnet:
1826
- return sdk_1.CheqdNetwork.Testnet;
1827
- default:
1828
- throw new Error(`[did-provider-cheqd]: observe: Unsupported chain: ${args.unifiedAccessControlCondition.chain}`);
1829
- }
1830
- })();
1831
- // get block height url
1832
- const blockHeightUrl = (function () {
1833
- switch (args.unifiedAccessControlCondition.parameters[0]) {
1834
- case 'latest':
1835
- return `${cheqd_did_provider_js_1.DefaultRESTUrls[network]}/cosmos/base/tendermint/v1beta1/blocks/latest`;
1836
- default:
1837
- return `${cheqd_did_provider_js_1.DefaultRESTUrls[network]}/cosmos/base/tendermint/v1beta1/blocks/${args.unifiedAccessControlCondition.parameters[0]}`;
1838
- }
1839
- })();
1840
- // fetch block response
1841
- const blockHeightResponse = (await (await fetch(blockHeightUrl)).json());
1842
- // get timestamp from block response
1843
- const blockTimestamp = Date.parse(blockHeightResponse.block.header.time);
1844
- // construct url
1845
- const url = `${cheqd_did_provider_js_1.DefaultRESTUrls[network]}${args.unifiedAccessControlCondition.path}`;
1846
- // fetch relevant txs
1847
- const txs = (await (await fetch(url)).json());
1848
- // skim through txs for relevant events, in which case the transaction timestamp is within the defined interval in seconds, from the block timestamp
1849
- const meetsConditionTxIndex = txs?.tx_responses?.findIndex((tx) => {
1850
- // get tx timestamp
1851
- const txTimestamp = Date.parse(tx.timestamp);
1852
- // calculate diff in seconds
1853
- const diffInSeconds = Math.floor((blockTimestamp - txTimestamp) / 1000);
1854
- // return meets condition
1855
- switch (args.unifiedAccessControlCondition.returnValueTest.comparator) {
1856
- case '<':
1857
- return diffInSeconds < parseInt(args.unifiedAccessControlCondition.returnValueTest.value);
1858
- case '<=':
1859
- return diffInSeconds <= parseInt(args.unifiedAccessControlCondition.returnValueTest.value);
1860
- default:
1861
- throw new Error(`[did-provider-cheqd]: observe: Unsupported comparator: ${args.unifiedAccessControlCondition.returnValueTest.comparator}`);
1862
- }
1863
- });
1864
- // define meetsCondition
1865
- const meetsCondition = typeof meetsConditionTxIndex !== 'undefined' && meetsConditionTxIndex !== -1;
1866
- // return observation result
1867
- return {
1868
- subscribed: true,
1869
- meetsCondition: meetsCondition,
1870
- transactionHash: meetsCondition ? txs.tx_responses[meetsConditionTxIndex].txhash : undefined,
1871
- events: meetsCondition ? txs.tx_responses[meetsConditionTxIndex].events : undefined,
1872
- rawLog: meetsCondition ? txs.tx_responses[meetsConditionTxIndex].raw_log : undefined,
1873
- txResponse: meetsCondition
1874
- ? args?.returnTxResponse
1875
- ? txs.tx_responses[meetsConditionTxIndex]
1876
- : undefined
1877
- : undefined,
1878
- };
1879
- }
1880
- catch (error) {
1881
- // return error
1882
- return {
1883
- subscribed: false,
1884
- meetsCondition: false,
1885
- error: error,
1886
- };
1887
- }
1888
- }
1889
- // validate access control conditions components - case: recipientAddress
1890
- if (!args.recipientAddress) {
1891
- throw new Error('[did-provider-cheqd]: observation: recipientAddress is required');
1892
- }
1893
- // validate access control conditions components - case: amount
1894
- if (!args.amount || !args.amount.amount || !args.amount.denom || args.amount.denom !== 'ncheq') {
1895
- throw new Error('[did-provider-cheqd]: observation: amount is required, and must be an object with amount and denom valid string properties, amongst which denom must be `ncheq`');
1896
- }
1897
- // validate access control conditions components - case: intervalInSeconds
1898
- if (!args.intervalInSeconds) {
1899
- throw new Error('[did-provider-cheqd]: observation: intervalInSeconds is required');
1900
- }
1901
- // validate access control conditions components - case: comparator
1902
- if (!args.comparator || (args.comparator !== '<' && args.comparator !== '<=')) {
1903
- throw new Error('[did-provider-cheqd]: observation: comparator is required and must be either `<` or `<=`');
1904
- }
1905
- // validate access control conditions components - case: network
1906
- if (!args.network) {
1907
- throw new Error('[did-provider-cheqd]: observation: network is required');
1908
- }
1909
- // define block height, if not provided
1910
- args.blockHeight ||= 'latest';
1911
- try {
1912
- // get block height url
1913
- const blockHeightUrl = (function () {
1914
- switch (args.blockHeight) {
1915
- case 'latest':
1916
- return `${cheqd_did_provider_js_1.DefaultRESTUrls[args.network]}/cosmos/base/tendermint/v1beta1/blocks/latest`;
1917
- default:
1918
- return `${cheqd_did_provider_js_1.DefaultRESTUrls[args.network]}/cosmos/base/tendermint/v1beta1/blocks/${args.blockHeight}`;
1919
- }
1920
- })();
1921
- // fetch block response
1922
- const blockHeightResponse = (await (await fetch(blockHeightUrl)).json());
1923
- // get timestamp from block response
1924
- const blockTimestamp = Date.parse(blockHeightResponse.block.header.time);
1925
- // otherwise, construct url, as per components
1926
- const url = `${cheqd_did_provider_js_1.DefaultRESTUrls[args.network]}/cosmos/tx/v1beta1/txs?events=transfer.recipient='${args.recipientAddress}'&events=transfer.amount='${args.amount.amount}${args.amount.denom}'&order_by=2&pagination.limit=1`;
1927
- // fetch relevant txs
1928
- const txs = (await (await fetch(url)).json());
1929
- // skim through txs for relevant events, in which case the transaction timestamp is within the defined interval in seconds, from the block timestamp
1930
- const meetsConditionTxIndex = txs?.tx_responses?.findIndex((tx) => {
1931
- // get tx timestamp
1932
- const txTimestamp = Date.parse(tx.timestamp);
1933
- // calculate diff in seconds
1934
- const diffInSeconds = Math.floor((blockTimestamp - txTimestamp) / 1000);
1935
- // return meets condition
1936
- switch (args.comparator) {
1937
- case '<':
1938
- return diffInSeconds < args.intervalInSeconds;
1939
- case '<=':
1940
- return diffInSeconds <= args.intervalInSeconds;
1941
- default:
1942
- throw new Error(`[did-provider-cheqd]: observe: Unsupported comparator: ${args.unifiedAccessControlCondition.returnValueTest.comparator}`);
1943
- }
1944
- });
1945
- // define meetsCondition
1946
- const meetsCondition = typeof meetsConditionTxIndex !== 'undefined' && meetsConditionTxIndex !== -1;
1947
- // return observation result
1948
- return {
1949
- subscribed: true,
1950
- meetsCondition: meetsCondition,
1951
- transactionHash: meetsCondition ? txs.tx_responses[meetsConditionTxIndex].txhash : undefined,
1952
- events: meetsCondition ? txs.tx_responses[meetsConditionTxIndex].events : undefined,
1953
- rawLog: meetsCondition ? txs.tx_responses[meetsConditionTxIndex].raw_log : undefined,
1954
- txResponse: meetsCondition
1955
- ? args?.returnTxResponse
1956
- ? txs.tx_responses[meetsConditionTxIndex]
1957
- : undefined
1958
- : undefined,
1959
- };
1960
- }
1961
- catch (error) {
1962
- // return error
1963
- return {
1964
- subscribed: false,
1965
- meetsCondition: false,
1966
- error: error,
1967
- };
1968
- }
1969
- }
1970
- async MintCapacityCredit(args, context) {
1971
- // define provider
1972
- const provider = await Cheqd.getProviderFromNetwork(args.network, this.supportedDidProviders);
1973
- try {
1974
- // delegate to provider
1975
- const mintingResult = await provider.mintCapacityCredit({
1976
- effectiveDays: args.effectiveDays,
1977
- requestsPerDay: args.requestsPerDay,
1978
- requestsPerSecond: args.requestsPerSecond,
1979
- requestsPerKilosecond: args.requestsPerKilosecond,
1980
- });
1981
- // return mint result
1982
- return {
1983
- minted: true,
1984
- ...mintingResult,
1985
- };
1986
- }
1987
- catch (error) {
1988
- // return error
1989
- return {
1990
- minted: false,
1991
- error: error,
1992
- };
1993
- }
1994
- }
1995
- async DelegateCapacityCredit(args, context) {
1996
- // define provider
1997
- const provider = await Cheqd.getProviderFromNetwork(args.network, this.supportedDidProviders);
1998
- try {
1999
- // delegate to provider
2000
- const delegationResult = await provider.delegateCapacityCredit({
2001
- capacityTokenId: args.capacityTokenId,
2002
- delegateeAddresses: args.delegateeAddresses,
2003
- uses: args.usesPermitted,
2004
- expiration: args.expiration,
2005
- statement: args.statement,
2006
- });
2007
- // return delegation result
2008
- return {
2009
- delegated: true,
2010
- ...delegationResult,
2011
- };
2012
- }
2013
- catch (error) {
2014
- // return error
2015
- return {
2016
- delegated: false,
2017
- error: error,
2018
- };
2019
- }
2020
- }
2021
- static async revokeCredential(credential, options) {
2022
- try {
2023
- // validate status purpose
2024
- if (credential?.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation)
2025
- throw new Error('[did-provider-cheqd]: revocation: Invalid status purpose');
2026
- // fetch status list 2021
2027
- const publishedList = (await Cheqd.fetchStatusList2021(credential));
2028
- // early return, if encrypted and no decryption key provided
2029
- if (publishedList.metadata.encrypted && !options?.topArgs?.symmetricKey)
2030
- throw new Error('[did-provider-cheqd]: revocation: symmetricKey is required, if status list 2021 is encrypted');
2031
- // fetch status list 2021 inscribed in credential
2032
- const statusList2021 = options?.topArgs?.fetchList
2033
- ? await (async function () {
2034
- // if not encrypted, return bitstring
2035
- if (!publishedList.metadata.encrypted)
2036
- return publishedList.metadata.encoding === 'base64url'
2037
- ? publishedList.StatusList2021.encodedList
2038
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
2039
- // decrypt + return bitstring, if qualified for migration
2040
- if (publishedList.metadata.encryptedSymmetricKey)
2041
- return await v2_js_1.LitProtocolV2.decryptDirect(await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021
2042
- .encodedList, 'hex')), (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
2043
- // validate encoded list
2044
- if (!(0, helpers_js_1.isEncodedList)(publishedList.StatusList2021.encodedList))
2045
- throw new Error('[did-provider-cheqd]: revocation: Invalid encoded list');
2046
- // otherwise, decrypt and return raw bitstring
2047
- const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)((0, helpers_js_1.getEncodedList)(publishedList.StatusList2021.encodedList, false)[0], 'hex'));
2048
- // decrypt
2049
- return (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
2050
- })()
2051
- : await (async function () {
2052
- // transcode to base64url, if needed
2053
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
2054
- ? publishedList.StatusList2021.encodedList
2055
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
2056
- // if status list 2021 is not fetched, read from file
2057
- if (options?.statusListFile) {
2058
- // if not encrypted, return bitstring
2059
- if (!publishedList.metadata.encrypted) {
2060
- // construct encoded status list
2061
- const encoded = new vc_status_list_1.StatusList({
2062
- buffer: await Cheqd.getFile(options.statusListFile),
2063
- }).encode();
2064
- // validate against published list
2065
- if (encoded !== publishedListTranscoded)
2066
- throw new Error('[did-provider-cheqd]: revocation: statusListFile does not match published status list 2021');
2067
- // return encoded
2068
- return encoded;
2069
- }
2070
- // otherwise, decrypt and return bitstring
2071
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
2072
- // decrypt
2073
- const decrypted = (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
2074
- // validate against published list
2075
- if (decrypted !== publishedListTranscoded)
2076
- throw new Error('[did-provider-cheqd]: revocation: statusListFile does not match published status list 2021');
2077
- // return decrypted
2078
- return decrypted;
2079
- }
2080
- if (!options?.statusListInlineBitstring)
2081
- throw new Error('[did-provider-cheqd]: revocation: statusListInlineBitstring is required, if statusListFile is not provided');
2082
- // validate against published list
2083
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
2084
- throw new Error('[did-provider-cheqd]: revocation: statusListInlineBitstring does not match published status list 2021');
2085
- // otherwise, read from inline bitstring
2086
- return options?.statusListInlineBitstring;
2087
- })();
2088
- // parse status list 2021
2089
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: statusList2021 });
2090
- // early exit, if credential is already revoked
2091
- if (statusList.getStatus(Number(credential.credentialStatus.statusListIndex)))
2092
- return { revoked: true };
2093
- // update revocation status
2094
- statusList.setStatus(Number(credential.credentialStatus.statusListIndex), true);
2095
- // set in-memory status list ref
2096
- const bitstring = (await statusList.encode());
2097
- // cast top-level args
2098
- const topArgs = options?.topArgs;
2099
- // write status list 2021 to file, if provided
2100
- if (topArgs?.writeToFile) {
2101
- await Cheqd.writeFile((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options?.statusListFile);
2102
- }
2103
- // publish status list 2021, if provided
2104
- const published = topArgs?.publish
2105
- ? await (async function () {
2106
- // fetch status list 2021 metadata
2107
- const statusListMetadata = await Cheqd.fetchStatusList2021Metadata(credential);
2108
- // publish status list 2021 as new version
2109
- const scoped = topArgs.publishEncrypted
2110
- ? await (async function () {
2111
- // validate encoding, if provided
2112
- if (options?.publishOptions?.statusListEncoding &&
2113
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
2114
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list encoding');
2115
- }
2116
- // validate validUntil, if provided
2117
- if (options?.publishOptions?.statusListValidUntil) {
2118
- // validate validUntil as string
2119
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
2120
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be string)');
2121
- // validate validUntil as date
2122
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
2123
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be date)');
2124
- // validate validUntil as future date
2125
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
2126
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be future date)');
2127
- // validate validUntil towards validFrom
2128
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
2129
- new Date(publishedList.StatusList2021.validFrom))
2130
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be after validFrom)');
2131
- }
2132
- // validate paymentConditions, if provided
2133
- if (topArgs?.paymentConditions) {
2134
- if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress &&
2135
- condition.feePaymentAmount &&
2136
- condition.intervalInSeconds)) {
2137
- throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
2138
- }
2139
- if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' &&
2140
- typeof condition.feePaymentAmount === 'string' &&
2141
- typeof condition.intervalInSeconds === 'number')) {
2142
- throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
2143
- }
2144
- if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
2145
- throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
2146
- }
2147
- }
2148
- // validate dkgOptions
2149
- if (!topArgs?.dkgOptions ||
2150
- !topArgs?.dkgOptions?.chain ||
2151
- !topArgs?.dkgOptions?.network) {
2152
- throw new Error('[did-provider-cheqd]: dkgOptions is required');
2153
- }
2154
- // encrypt bitstring - case: symmetric
2155
- const { encryptedString: symmetricEncryptionCiphertext, stringHash: symmetricEncryptionStringHash, symmetricKey, } = await v6_js_1.LitProtocol.encryptDirect((0, uint8arrays_1.fromString)(bitstring, 'base64url'));
2156
- // instantiate dkg-threshold client, in which case lit-protocol is used
2157
- const lit = (await options.publishOptions.instantiateDkgClient);
2158
- // construct access control conditions and payment conditions tuple
2159
- const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
2160
- ? await (async function () {
2161
- // define payment conditions, give precedence to top-level args
2162
- const paymentConditions = topArgs?.paymentConditions ||
2163
- publishedList.metadata.paymentConditions;
2164
- // return access control conditions and payment conditions tuple
2165
- return [
2166
- await Promise.all(paymentConditions.map(async (condition) => {
2167
- switch (condition.type) {
2168
- case exports.AccessControlConditionTypes.timelockPayment:
2169
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
2170
- key: '$.tx_responses.*.timestamp',
2171
- comparator: '<=',
2172
- value: `${condition.intervalInSeconds}`,
2173
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
2174
- default:
2175
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
2176
- }
2177
- })),
2178
- paymentConditions,
2179
- ];
2180
- })()
2181
- : await (async function () {
2182
- // validate paymentConditions
2183
- if (!topArgs?.paymentConditions) {
2184
- throw new Error('[did-provider-cheqd]: paymentConditions is required');
2185
- }
2186
- // return access control conditions and payment conditions tuple
2187
- return [
2188
- await Promise.all(topArgs.paymentConditions.map(async (condition) => {
2189
- switch (condition.type) {
2190
- case exports.AccessControlConditionTypes.timelockPayment:
2191
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
2192
- key: '$.tx_responses.*.timestamp',
2193
- comparator: '<=',
2194
- value: `${condition.intervalInSeconds}`,
2195
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
2196
- default:
2197
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
2198
- }
2199
- })),
2200
- topArgs.paymentConditions,
2201
- ];
2202
- })();
2203
- // encrypt bitstring - case: threshold
2204
- const { encryptedString: thresholdEncryptionCiphertext, stringHash: thresholdEncryptionStringHash, } = await lit.encrypt((0, uint8arrays_1.fromString)(bitstring, 'base64url'), unifiedAccessControlConditionsTuple[0]);
2205
- // construct encoded list
2206
- const encodedList = `${await (0, helpers_js_1.blobToHexString)(symmetricEncryptionCiphertext)}-${(0, uint8arrays_1.toString)(thresholdEncryptionCiphertext, 'hex')}`;
2207
- // define status list content
2208
- const content = {
2209
- StatusList2021: {
2210
- statusPurpose: publishedList.StatusList2021.statusPurpose,
2211
- encodedList,
2212
- validFrom: publishedList.StatusList2021.validFrom,
2213
- validUntil: options?.publishOptions?.statusListValidUntil ||
2214
- publishedList.StatusList2021.validUntil,
2215
- },
2216
- metadata: {
2217
- type: publishedList.metadata.type,
2218
- encrypted: true,
2219
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
2220
- statusListHash: symmetricEncryptionStringHash === thresholdEncryptionStringHash
2221
- ? symmetricEncryptionStringHash
2222
- : (function () {
2223
- throw new Error('[did-provider-cheqd]: revocation: symmetricEncryptionStringHash and thresholdEncryptionStringHash do not match');
2224
- })(),
2225
- paymentConditions: unifiedAccessControlConditionsTuple[1],
2226
- },
2227
- };
2228
- // return tuple of publish result and encryption relevant metadata
2229
- return [
2230
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
2231
- {
2232
- symmetricEncryptionCiphertext,
2233
- thresholdEncryptionCiphertext,
2234
- stringHash: symmetricEncryptionStringHash,
2235
- symmetricKey,
2236
- },
2237
- ];
2238
- })()
2239
- : await (async function () {
2240
- // validate encoding, if provided
2241
- if (options?.publishOptions?.statusListEncoding &&
2242
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
2243
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list encoding');
2244
- }
2245
- // validate validUntil, if provided
2246
- if (options?.publishOptions?.statusListValidUntil) {
2247
- // validate validUntil as string
2248
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
2249
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be string)');
2250
- // validate validUntil as date
2251
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
2252
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be date)');
2253
- // validate validUntil as future date
2254
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
2255
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be future date)');
2256
- // validate validUntil towards validFrom
2257
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
2258
- new Date(publishedList.StatusList2021.validFrom))
2259
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be after validFrom)');
2260
- }
2261
- // define status list content
2262
- const content = {
2263
- StatusList2021: {
2264
- statusPurpose: publishedList.StatusList2021.statusPurpose,
2265
- encodedList: publishedList.metadata.encoding === 'base64url'
2266
- ? bitstring
2267
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options.publishOptions
2268
- .statusListEncoding),
2269
- validFrom: publishedList.StatusList2021.validFrom,
2270
- validUntil: options?.publishOptions?.statusListValidUntil ||
2271
- publishedList.StatusList2021.validUntil,
2272
- },
2273
- metadata: {
2274
- type: publishedList.metadata.type,
2275
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
2276
- encrypted: false,
2277
- },
2278
- };
2279
- // return tuple of publish result and encryption relevant metadata
2280
- return [
2281
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
2282
- undefined,
2283
- ];
2284
- })();
2285
- // early exit, if publish failed
2286
- if (!scoped[0])
2287
- throw new Error('[did-provider-cheqd]: revocation: Failed to publish status list 2021');
2288
- // return publish result
2289
- return scoped;
2290
- })()
2291
- : undefined;
2292
- return {
2293
- revoked: true,
2294
- published: topArgs?.publish ? true : undefined,
2295
- statusList: topArgs?.returnUpdatedStatusList
2296
- ? (await Cheqd.fetchStatusList2021(credential))
2297
- : undefined,
2298
- symmetricKey: topArgs?.returnSymmetricKey
2299
- ? (0, uint8arrays_1.toString)(published?.[1]?.symmetricKey, 'hex')
2300
- : undefined,
2301
- resourceMetadata: topArgs?.returnStatusListMetadata
2302
- ? await Cheqd.fetchStatusList2021Metadata(credential)
2303
- : undefined,
2304
- };
2305
- }
2306
- catch (error) {
2307
- // silent fail + early exit
2308
- console.error(error);
2309
- return { revoked: false, error: error };
2310
- }
2311
- }
2312
- static async revokeCredentials(credentials, options) {
2313
- // validate credentials - case: empty
2314
- if (!credentials.length || credentials.length === 0)
2315
- throw new Error('[did-provider-cheqd]: revocation: No credentials provided');
2316
- // validate credentials - case: consistent issuer
2317
- if (credentials
2318
- .map((credential) => {
2319
- return credential.issuer.id
2320
- ? credential.issuer.id
2321
- : credential.issuer;
2322
- })
2323
- .filter((value, _, self) => value && value !== self[0]).length > 0)
2324
- throw new Error('[did-provider-cheqd]: revocation: Credentials must be issued by the same issuer');
2325
- // validate credentials - case: status list index
2326
- if (credentials
2327
- .map((credential) => credential.credentialStatus.statusListIndex)
2328
- .filter((value, index, self) => self.indexOf(value) !== index).length > 0)
2329
- throw new Error('[did-provider-cheqd]: revocation: Credentials must have unique status list index');
2330
- // validate credentials - case: status purpose
2331
- if (!credentials.every((credential) => credential.credentialStatus?.statusPurpose === cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation))
2332
- throw new Error('[did-provider-cheqd]: revocation: Invalid status purpose');
2333
- // validate credentials - case: status list id
2334
- const remote = credentials[0].credentialStatus?.id
2335
- ? credentials[0].credentialStatus.id.split('#')[0]
2336
- : (function () {
2337
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list id');
2338
- })();
2339
- // validate credentials - case: status list id format
2340
- if (!exports.RemoteListPattern.test(remote))
2341
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list id format: expected: https://<optional_subdomain>.<sld>.<tld>/1.0/identifiers/<did:cheqd:<namespace>:<method_specific_id>>?resourceName=<resource_name>&resourceType=<resource_type>');
2342
- if (!credentials.every((credential) => {
2343
- return credential.credentialStatus.id.split('#')[0] === remote;
2344
- }))
2345
- throw new Error('[did-provider-cheqd]: revocation: Credentials must belong to the same status list');
2346
- // validate credentials - case: status list type
2347
- if (!credentials.every((credential) => credential.credentialStatus?.type === 'StatusList2021Entry'))
2348
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list type');
2349
- try {
2350
- // fetch status list 2021
2351
- const publishedList = (await Cheqd.fetchStatusList2021(credentials[0]));
2352
- // early return, if encrypted and no decryption key provided
2353
- if (publishedList.metadata.encrypted && !options?.topArgs?.symmetricKey)
2354
- throw new Error('[did-provider-cheqd]: revocation: symmetricKey is required, if status list 2021 is encrypted');
2355
- // fetch status list 2021 inscribed in credential
2356
- const statusList2021 = options?.topArgs?.fetchList
2357
- ? await (async function () {
2358
- // if not encrypted, return bitstring
2359
- if (!publishedList.metadata.encrypted)
2360
- return publishedList.metadata.encoding === 'base64url'
2361
- ? publishedList.StatusList2021.encodedList
2362
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
2363
- // decrypt + return bitstring, if qualified for migration
2364
- if (publishedList.metadata.encryptedSymmetricKey)
2365
- return await v2_js_1.LitProtocolV2.decryptDirect(await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021
2366
- .encodedList, 'hex')), (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
2367
- // validate encoded list
2368
- if (!(0, helpers_js_1.isEncodedList)(publishedList.StatusList2021.encodedList))
2369
- throw new Error('[did-provider-cheqd]: revocation: Invalid encoded list');
2370
- // otherwise, decrypt and return raw bitstring
2371
- const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)((0, helpers_js_1.getEncodedList)(publishedList.StatusList2021.encodedList, false)[0], 'hex'));
2372
- // decrypt
2373
- return (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
2374
- })()
2375
- : await (async function () {
2376
- // transcode to base64url, if needed
2377
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
2378
- ? publishedList.StatusList2021.encodedList
2379
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
2380
- // if status list 2021 is not fetched, read from file
2381
- if (options?.statusListFile) {
2382
- // if not encrypted, return bitstring
2383
- if (!publishedList.metadata.encrypted) {
2384
- // construct encoded status list
2385
- const encoded = new vc_status_list_1.StatusList({
2386
- buffer: await Cheqd.getFile(options.statusListFile),
2387
- }).encode();
2388
- // validate against published list
2389
- if (encoded !== publishedListTranscoded)
2390
- throw new Error('[did-provider-cheqd]: revocation: statusListFile does not match published status list 2021');
2391
- // return encoded
2392
- return encoded;
2393
- }
2394
- // otherwise, decrypt and return bitstring
2395
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
2396
- // decrypt
2397
- const decrypted = (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
2398
- // validate against published list
2399
- if (decrypted !== publishedListTranscoded)
2400
- throw new Error('[did-provider-cheqd]: revocation: statusListFile does not match published status list 2021');
2401
- // return decrypted
2402
- return decrypted;
2403
- }
2404
- if (!options?.statusListInlineBitstring)
2405
- throw new Error('[did-provider-cheqd]: revocation: statusListInlineBitstring is required, if statusListFile is not provided');
2406
- // validate against published list
2407
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
2408
- throw new Error('[did-provider-cheqd]: revocation: statusListInlineBitstring does not match published status list 2021');
2409
- // otherwise, read from inline bitstring
2410
- return options?.statusListInlineBitstring;
2411
- })();
2412
- // parse status list 2021
2413
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: statusList2021 });
2414
- // initiate bulk revocation
2415
- const revoked = (await Promise.allSettled(credentials.map((credential) => {
2416
- return (async function () {
2417
- // early return, if no credential status
2418
- if (!credential.credentialStatus)
2419
- return { revoked: false };
2420
- // early exit, if credential is already revoked
2421
- if (statusList.getStatus(Number(credential.credentialStatus.statusListIndex)))
2422
- return { revoked: true };
2423
- // update revocation status
2424
- statusList.setStatus(Number(credential.credentialStatus.statusListIndex), true);
2425
- // return revocation status
2426
- return { revoked: true };
2427
- })();
2428
- })));
2429
- // revert bulk ops, if some failed
2430
- if (revoked.some((result) => result.status === 'fulfilled' && !result.value.revoked))
2431
- throw new Error(`[did-provider-cheqd]: revocation: Bulk revocation failed: already revoked credentials in revocation bundle: raw log: ${JSON.stringify(revoked.map((result) => ({
2432
- revoked: result.status === 'fulfilled' ? result.value.revoked : false,
2433
- })))}`);
2434
- // set in-memory status list ref
2435
- const bitstring = (await statusList.encode());
2436
- // cast top-level args
2437
- const topArgs = options?.topArgs;
2438
- // write status list 2021 to file, if provided
2439
- if (topArgs?.writeToFile) {
2440
- await Cheqd.writeFile((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options?.statusListFile);
2441
- }
2442
- // publish status list 2021, if provided
2443
- const published = topArgs?.publish
2444
- ? await (async function () {
2445
- // fetch status list 2021 metadata
2446
- const statusListMetadata = await Cheqd.fetchStatusList2021Metadata(credentials[0]);
2447
- // publish status list 2021 as new version
2448
- const scoped = topArgs.publishEncrypted
2449
- ? await (async function () {
2450
- // validate encoding, if provided
2451
- if (options?.publishOptions?.statusListEncoding &&
2452
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
2453
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list encoding');
2454
- }
2455
- // validate validUntil, if provided
2456
- if (options?.publishOptions?.statusListValidUntil) {
2457
- // validate validUntil as string
2458
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
2459
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be string)');
2460
- // validate validUntil as date
2461
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
2462
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be date)');
2463
- // validate validUntil as future date
2464
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
2465
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be future date)');
2466
- // validate validUntil towards validFrom
2467
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
2468
- new Date(publishedList.StatusList2021.validFrom))
2469
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be after validFrom)');
2470
- }
2471
- // validate paymentConditions, if provided
2472
- if (topArgs?.paymentConditions) {
2473
- if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress &&
2474
- condition.feePaymentAmount &&
2475
- condition.intervalInSeconds)) {
2476
- throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
2477
- }
2478
- if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' &&
2479
- typeof condition.feePaymentAmount === 'string' &&
2480
- typeof condition.intervalInSeconds === 'number')) {
2481
- throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
2482
- }
2483
- if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
2484
- throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
2485
- }
2486
- }
2487
- // validate dkgOptions
2488
- if (!topArgs?.dkgOptions ||
2489
- !topArgs?.dkgOptions?.chain ||
2490
- !topArgs?.dkgOptions?.network) {
2491
- throw new Error('[did-provider-cheqd]: dkgOptions is required');
2492
- }
2493
- // encrypt bitstring - case: symmetric
2494
- const { encryptedString: symmetricEncryptionCiphertext, stringHash: symmetricEncryptionStringHash, symmetricKey, } = await v6_js_1.LitProtocol.encryptDirect((0, uint8arrays_1.fromString)(bitstring, 'base64url'));
2495
- // instantiate dkg-threshold client, in which case lit-protocol is used
2496
- const lit = (await options.publishOptions.instantiateDkgClient);
2497
- // construct access control conditions and payment conditions tuple
2498
- const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
2499
- ? await (async function () {
2500
- // define payment conditions, give precedence to top-level args
2501
- const paymentConditions = topArgs?.paymentConditions ||
2502
- publishedList.metadata.paymentConditions;
2503
- // return access control conditions and payment conditions tuple
2504
- return [
2505
- await Promise.all(paymentConditions.map(async (condition) => {
2506
- switch (condition.type) {
2507
- case exports.AccessControlConditionTypes.timelockPayment:
2508
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
2509
- key: '$.tx_responses.*.timestamp',
2510
- comparator: '<=',
2511
- value: `${condition.intervalInSeconds}`,
2512
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
2513
- default:
2514
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
2515
- }
2516
- })),
2517
- paymentConditions,
2518
- ];
2519
- })()
2520
- : await (async function () {
2521
- // validate paymentConditions
2522
- if (!topArgs?.paymentConditions) {
2523
- throw new Error('[did-provider-cheqd]: paymentConditions is required');
2524
- }
2525
- // return access control conditions and payment conditions tuple
2526
- return [
2527
- await Promise.all(topArgs.paymentConditions.map(async (condition) => {
2528
- switch (condition.type) {
2529
- case exports.AccessControlConditionTypes.timelockPayment:
2530
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
2531
- key: '$.tx_responses.*.timestamp',
2532
- comparator: '<=',
2533
- value: `${condition.intervalInSeconds}`,
2534
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
2535
- default:
2536
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
2537
- }
2538
- })),
2539
- topArgs.paymentConditions,
2540
- ];
2541
- })();
2542
- // encrypt bitstring - case: threshold
2543
- const { encryptedString: thresholdEncryptionCiphertext, stringHash: thresholdEncryptionStringHash, } = await lit.encrypt((0, uint8arrays_1.fromString)(bitstring, 'base64url'), unifiedAccessControlConditionsTuple[0]);
2544
- // construct encoded list
2545
- const encodedList = `${await (0, helpers_js_1.blobToHexString)(symmetricEncryptionCiphertext)}-${(0, uint8arrays_1.toString)(thresholdEncryptionCiphertext, 'hex')}`;
2546
- // define status list content
2547
- const content = {
2548
- StatusList2021: {
2549
- statusPurpose: publishedList.StatusList2021.statusPurpose,
2550
- encodedList,
2551
- validFrom: publishedList.StatusList2021.validFrom,
2552
- validUntil: options?.publishOptions?.statusListValidUntil ||
2553
- publishedList.StatusList2021.validUntil,
2554
- },
2555
- metadata: {
2556
- type: publishedList.metadata.type,
2557
- encrypted: true,
2558
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
2559
- statusListHash: symmetricEncryptionStringHash === thresholdEncryptionStringHash
2560
- ? symmetricEncryptionStringHash
2561
- : (function () {
2562
- throw new Error('[did-provider-cheqd]: revocation: symmetricEncryptionStringHash and thresholdEncryptionStringHash do not match');
2563
- })(),
2564
- paymentConditions: unifiedAccessControlConditionsTuple[1],
2565
- },
2566
- };
2567
- // return tuple of publish result and encryption relevant metadata
2568
- return [
2569
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
2570
- {
2571
- symmetricEncryptionCiphertext,
2572
- thresholdEncryptionCiphertext,
2573
- stringHash: symmetricEncryptionStringHash,
2574
- symmetricKey,
2575
- },
2576
- ];
2577
- })()
2578
- : await (async function () {
2579
- // validate encoding, if provided
2580
- if (options?.publishOptions?.statusListEncoding &&
2581
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
2582
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list encoding');
2583
- }
2584
- // validate validUntil, if provided
2585
- if (options?.publishOptions?.statusListValidUntil) {
2586
- // validate validUntil as string
2587
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
2588
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be string)');
2589
- // validate validUntil as date
2590
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
2591
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be date)');
2592
- // validate validUntil as future date
2593
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
2594
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be future date)');
2595
- // validate validUntil towards validFrom
2596
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
2597
- new Date(publishedList.StatusList2021.validFrom))
2598
- throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be after validFrom)');
2599
- }
2600
- // define status list content
2601
- const content = {
2602
- StatusList2021: {
2603
- statusPurpose: publishedList.StatusList2021.statusPurpose,
2604
- encodedList: publishedList.metadata.encoding === 'base64url'
2605
- ? bitstring
2606
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options.publishOptions
2607
- .statusListEncoding),
2608
- validFrom: publishedList.StatusList2021.validFrom,
2609
- validUntil: options?.publishOptions?.statusListValidUntil ||
2610
- publishedList.StatusList2021.validUntil,
2611
- },
2612
- metadata: {
2613
- type: publishedList.metadata.type,
2614
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
2615
- encrypted: false,
2616
- },
2617
- };
2618
- // return tuple of publish result and encryption relevant metadata
2619
- return [
2620
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
2621
- undefined,
2622
- ];
2623
- })();
2624
- // early exit, if publish failed
2625
- if (!scoped[0])
2626
- throw new Error('[did-provider-cheqd]: revocation: Failed to publish status list 2021');
2627
- // return publish result
2628
- return scoped;
2629
- })()
2630
- : undefined;
2631
- return {
2632
- revoked: revoked.map((result) => (result.status === 'fulfilled' ? result.value.revoked : false)),
2633
- published: topArgs?.publish ? true : undefined,
2634
- statusList: topArgs?.returnUpdatedStatusList
2635
- ? (await Cheqd.fetchStatusList2021(credentials[0]))
2636
- : undefined,
2637
- symmetricKey: topArgs?.returnSymmetricKey
2638
- ? (0, uint8arrays_1.toString)(published?.[1]?.symmetricKey, 'hex')
2639
- : undefined,
2640
- resourceMetadata: topArgs?.returnStatusListMetadata
2641
- ? await Cheqd.fetchStatusList2021Metadata(credentials[0])
2642
- : undefined,
2643
- };
2644
- }
2645
- catch (error) {
2646
- // silent fail + early exit
2647
- console.error(error);
2648
- return { revoked: [], error: error };
2649
- }
2650
- }
2651
- static async suspendCredential(credential, options) {
2652
- try {
2653
- // validate status purpose
2654
- if (credential?.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension)
2655
- throw new Error('[did-provider-cheqd]: suspension: Invalid status purpose');
2656
- // fetch status list 2021
2657
- const publishedList = (await Cheqd.fetchStatusList2021(credential));
2658
- // early return, if encrypted and no decryption key provided
2659
- if (publishedList.metadata.encrypted && !options?.topArgs?.symmetricKey)
2660
- throw new Error('[did-provider-cheqd]: suspension: symmetricKey is required, if status list 2021 is encrypted');
2661
- // fetch status list 2021 inscribed in credential
2662
- const statusList2021 = options?.topArgs?.fetchList
2663
- ? await (async function () {
2664
- // if not encrypted, return bitstring
2665
- if (!publishedList.metadata.encrypted)
2666
- return publishedList.metadata.encoding === 'base64url'
2667
- ? publishedList.StatusList2021.encodedList
2668
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
2669
- // decrypt + return bitstring, if qualified for migration
2670
- if (publishedList.metadata.encryptedSymmetricKey)
2671
- return await v2_js_1.LitProtocolV2.decryptDirect(await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021
2672
- .encodedList, 'hex')), (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
2673
- // validate encoded list
2674
- if (!(0, helpers_js_1.isEncodedList)(publishedList.StatusList2021.encodedList))
2675
- throw new Error('[did-provider-cheqd]: suspension: Invalid encoded list');
2676
- // otherwise, decrypt and return raw bitstring
2677
- const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)((0, helpers_js_1.getEncodedList)(publishedList.StatusList2021.encodedList, false)[0], 'hex'));
2678
- // decrypt
2679
- return (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
2680
- })()
2681
- : await (async function () {
2682
- // transcode to base64url, if needed
2683
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
2684
- ? publishedList.StatusList2021.encodedList
2685
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
2686
- // if status list 2021 is not fetched, read from file
2687
- if (options?.statusListFile) {
2688
- // if not encrypted, return bitstring
2689
- if (!publishedList.metadata.encrypted) {
2690
- // construct encoded status list
2691
- const encoded = new vc_status_list_1.StatusList({
2692
- buffer: await Cheqd.getFile(options.statusListFile),
2693
- }).encode();
2694
- // validate against published list
2695
- if (encoded !== publishedListTranscoded)
2696
- throw new Error('[did-provider-cheqd]: suspension: statusListFile does not match published status list 2021');
2697
- // return encoded
2698
- return encoded;
2699
- }
2700
- // otherwise, decrypt and return bitstring
2701
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
2702
- // decrypt
2703
- const decrypted = (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
2704
- // validate against published list
2705
- if (decrypted !== publishedListTranscoded)
2706
- throw new Error('[did-provider-cheqd]: suspension: statusListFile does not match published status list 2021');
2707
- // return decrypted
2708
- return decrypted;
2709
- }
2710
- if (!options?.statusListInlineBitstring)
2711
- throw new Error('[did-provider-cheqd]: suspension: statusListInlineBitstring is required, if statusListFile is not provided');
2712
- // validate against published list
2713
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
2714
- throw new Error('[did-provider-cheqd]: suspension: statusListInlineBitstring does not match published status list 2021');
2715
- // otherwise, read from inline bitstring
2716
- return options?.statusListInlineBitstring;
2717
- })();
2718
- // parse status list 2021
2719
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: statusList2021 });
2720
- // early exit, if already suspended
2721
- if (statusList.getStatus(Number(credential.credentialStatus.statusListIndex)))
2722
- return { suspended: true };
2723
- // update suspension status
2724
- statusList.setStatus(Number(credential.credentialStatus.statusListIndex), true);
2725
- // set in-memory status list ref
2726
- const bitstring = (await statusList.encode());
2727
- // cast top-level args
2728
- const topArgs = options?.topArgs;
2729
- // write status list 2021 to file, if provided
2730
- if (topArgs?.writeToFile) {
2731
- await Cheqd.writeFile((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options?.statusListFile);
2732
- }
2733
- // publish status list 2021, if provided
2734
- const published = topArgs?.publish
2735
- ? await (async function () {
2736
- // fetch status list 2021 metadata
2737
- const statusListMetadata = await Cheqd.fetchStatusList2021Metadata(credential);
2738
- // publish status list 2021 as new version
2739
- const scoped = topArgs.publishEncrypted
2740
- ? await (async function () {
2741
- // validate encoding, if provided
2742
- if (options?.publishOptions?.statusListEncoding &&
2743
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
2744
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list encoding');
2745
- }
2746
- // validate validUntil, if provided
2747
- if (options?.publishOptions?.statusListValidUntil) {
2748
- // validate validUntil as string
2749
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
2750
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be string)');
2751
- // validate validUntil as date
2752
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
2753
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be date)');
2754
- // validate validUntil as future date
2755
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
2756
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be future date)');
2757
- // validate validUntil towards validFrom
2758
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
2759
- new Date(publishedList.StatusList2021.validFrom))
2760
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be after validFrom)');
2761
- }
2762
- // validate paymentConditions, if provided
2763
- if (topArgs?.paymentConditions) {
2764
- if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress &&
2765
- condition.feePaymentAmount &&
2766
- condition.intervalInSeconds)) {
2767
- throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
2768
- }
2769
- if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' &&
2770
- typeof condition.feePaymentAmount === 'string' &&
2771
- typeof condition.intervalInSeconds === 'number')) {
2772
- throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
2773
- }
2774
- if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
2775
- throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
2776
- }
2777
- }
2778
- // validate dkgOptions
2779
- if (!topArgs?.dkgOptions ||
2780
- !topArgs?.dkgOptions?.chain ||
2781
- !topArgs?.dkgOptions?.network) {
2782
- throw new Error('[did-provider-cheqd]: dkgOptions is required');
2783
- }
2784
- // encrypt bitstring - case: symmetric
2785
- const { encryptedString: symmetricEncryptionCiphertext, stringHash: symmetricEncryptionStringHash, symmetricKey, } = await v6_js_1.LitProtocol.encryptDirect((0, uint8arrays_1.fromString)(bitstring, 'base64url'));
2786
- // instantiate dkg-threshold client, in which case lit-protocol is used
2787
- const lit = (await options.publishOptions.instantiateDkgClient);
2788
- // construct access control conditions and payment conditions tuple
2789
- const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
2790
- ? await (async function () {
2791
- // define payment conditions, give precedence to top-level args
2792
- const paymentConditions = topArgs?.paymentConditions ||
2793
- publishedList.metadata.paymentConditions;
2794
- // return access control conditions and payment conditions tuple
2795
- return [
2796
- await Promise.all(paymentConditions.map(async (condition) => {
2797
- switch (condition.type) {
2798
- case exports.AccessControlConditionTypes.timelockPayment:
2799
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
2800
- key: '$.tx_responses.*.timestamp',
2801
- comparator: '<=',
2802
- value: `${condition.intervalInSeconds}`,
2803
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
2804
- default:
2805
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
2806
- }
2807
- })),
2808
- paymentConditions,
2809
- ];
2810
- })()
2811
- : await (async function () {
2812
- // validate paymentConditions
2813
- if (!topArgs?.paymentConditions) {
2814
- throw new Error('[did-provider-cheqd]: paymentConditions is required');
2815
- }
2816
- // return access control conditions and payment conditions tuple
2817
- return [
2818
- await Promise.all(topArgs.paymentConditions.map(async (condition) => {
2819
- switch (condition.type) {
2820
- case exports.AccessControlConditionTypes.timelockPayment:
2821
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
2822
- key: '$.tx_responses.*.timestamp',
2823
- comparator: '<=',
2824
- value: `${condition.intervalInSeconds}`,
2825
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
2826
- default:
2827
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
2828
- }
2829
- })),
2830
- topArgs.paymentConditions,
2831
- ];
2832
- })();
2833
- // encrypt bitstring - case: threshold
2834
- const { encryptedString: thresholdEncryptionCiphertext, stringHash: thresholdEncryptionStringHash, } = await lit.encrypt((0, uint8arrays_1.fromString)(bitstring, 'base64url'), unifiedAccessControlConditionsTuple[0]);
2835
- // construct encoded list
2836
- const encodedList = `${await (0, helpers_js_1.blobToHexString)(symmetricEncryptionCiphertext)}-${(0, uint8arrays_1.toString)(thresholdEncryptionCiphertext, 'hex')}`;
2837
- // define status list content
2838
- const content = {
2839
- StatusList2021: {
2840
- statusPurpose: publishedList.StatusList2021.statusPurpose,
2841
- encodedList,
2842
- validFrom: publishedList.StatusList2021.validFrom,
2843
- validUntil: options?.publishOptions?.statusListValidUntil ||
2844
- publishedList.StatusList2021.validUntil,
2845
- },
2846
- metadata: {
2847
- type: publishedList.metadata.type,
2848
- encrypted: true,
2849
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
2850
- statusListHash: symmetricEncryptionStringHash === thresholdEncryptionStringHash
2851
- ? symmetricEncryptionStringHash
2852
- : (function () {
2853
- throw new Error('[did-provider-cheqd]: suspension: symmetricEncryptionStringHash and thresholdEncryptionStringHash do not match');
2854
- })(),
2855
- paymentConditions: unifiedAccessControlConditionsTuple[1],
2856
- },
2857
- };
2858
- // return tuple of publish result and encryption relevant metadata
2859
- return [
2860
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
2861
- {
2862
- symmetricEncryptionCiphertext,
2863
- thresholdEncryptionCiphertext,
2864
- stringHash: symmetricEncryptionStringHash,
2865
- symmetricKey,
2866
- },
2867
- ];
2868
- })()
2869
- : await (async function () {
2870
- // validate encoding, if provided
2871
- if (options?.publishOptions?.statusListEncoding &&
2872
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
2873
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list encoding');
2874
- }
2875
- // validate validUntil, if provided
2876
- if (options?.publishOptions?.statusListValidUntil) {
2877
- // validate validUntil as string
2878
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
2879
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be string)');
2880
- // validate validUntil as date
2881
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
2882
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be date)');
2883
- // validate validUntil as future date
2884
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
2885
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be future date)');
2886
- // validate validUntil towards validFrom
2887
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
2888
- new Date(publishedList.StatusList2021.validFrom))
2889
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be after validFrom)');
2890
- }
2891
- // define status list content
2892
- const content = {
2893
- StatusList2021: {
2894
- statusPurpose: publishedList.StatusList2021.statusPurpose,
2895
- encodedList: publishedList.metadata.encoding === 'base64url'
2896
- ? bitstring
2897
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options.publishOptions
2898
- .statusListEncoding),
2899
- validFrom: publishedList.StatusList2021.validFrom,
2900
- validUntil: options?.publishOptions?.statusListValidUntil ||
2901
- publishedList.StatusList2021.validUntil,
2902
- },
2903
- metadata: {
2904
- type: publishedList.metadata.type,
2905
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
2906
- encrypted: false,
2907
- },
2908
- };
2909
- // return tuple of publish result and encryption relevant metadata
2910
- return [
2911
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
2912
- undefined,
2913
- ];
2914
- })();
2915
- // early exit, if publish failed
2916
- if (!scoped[0])
2917
- throw new Error('[did-provider-cheqd]: suspension: Failed to publish status list 2021');
2918
- // return publish result
2919
- return scoped;
2920
- })()
2921
- : undefined;
2922
- return {
2923
- suspended: true,
2924
- published: topArgs?.publish ? true : undefined,
2925
- statusList: topArgs?.returnUpdatedStatusList
2926
- ? (await Cheqd.fetchStatusList2021(credential))
2927
- : undefined,
2928
- symmetricKey: topArgs?.returnSymmetricKey
2929
- ? (0, uint8arrays_1.toString)(published?.[1]?.symmetricKey, 'hex')
2930
- : undefined,
2931
- resourceMetadata: topArgs?.returnStatusListMetadata
2932
- ? await Cheqd.fetchStatusList2021Metadata(credential)
2933
- : undefined,
2934
- };
2935
- }
2936
- catch (error) {
2937
- // silent fail + early exit
2938
- console.error(error);
2939
- return { suspended: false, error: error };
2940
- }
2941
- }
2942
- static async suspendCredentials(credentials, options) {
2943
- // validate credentials - case: empty
2944
- if (!credentials.length || credentials.length === 0)
2945
- throw new Error('[did-provider-cheqd]: suspension: No credentials provided');
2946
- // validate credentials - case: consistent issuer
2947
- if (credentials
2948
- .map((credential) => {
2949
- return credential.issuer.id
2950
- ? credential.issuer.id
2951
- : credential.issuer;
2952
- })
2953
- .filter((value, _, self) => value && value !== self[0]).length > 0)
2954
- throw new Error('[did-provider-cheqd]: suspension: Credentials must be issued by the same issuer');
2955
- // validate credentials - case: status list index
2956
- if (credentials
2957
- .map((credential) => credential.credentialStatus.statusListIndex)
2958
- .filter((value, index, self) => self.indexOf(value) !== index).length > 0)
2959
- throw new Error('[did-provider-cheqd]: suspension: Credentials must have unique status list index');
2960
- // validate credentials - case: status purpose
2961
- if (!credentials.every((credential) => credential.credentialStatus?.statusPurpose === cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension))
2962
- throw new Error('[did-provider-cheqd]: suspension: Invalid status purpose');
2963
- // validate credentials - case: status list id
2964
- const remote = credentials[0].credentialStatus?.id
2965
- ? credentials[0].credentialStatus.id.split('#')[0]
2966
- : (function () {
2967
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list id');
2968
- })();
2969
- // validate credentials - case: status list id format
2970
- if (!exports.RemoteListPattern.test(remote))
2971
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list id format: expected: https://<optional_subdomain>.<sld>.<tld>/1.0/identifiers/<did:cheqd:<namespace>:<method_specific_id>>?resourceName=<resource_name>&resourceType=<resource_type>');
2972
- if (!credentials.every((credential) => {
2973
- return credential.credentialStatus.id.split('#')[0] === remote;
2974
- }))
2975
- throw new Error('[did-provider-cheqd]: suspension: Credentials must belong to the same status list');
2976
- // validate credentials - case: status list type
2977
- if (!credentials.every((credential) => credential.credentialStatus?.type === 'StatusList2021Entry'))
2978
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list type');
2979
- try {
2980
- // fetch status list 2021
2981
- const publishedList = (await Cheqd.fetchStatusList2021(credentials[0]));
2982
- // early return, if encrypted and no decryption key provided
2983
- if (publishedList.metadata.encrypted && !options?.topArgs?.symmetricKey)
2984
- throw new Error('[did-provider-cheqd]: suspension: symmetricKey is required, if status list 2021 is encrypted');
2985
- // fetch status list 2021 inscribed in credential
2986
- const statusList2021 = options?.topArgs?.fetchList
2987
- ? await (async function () {
2988
- // if not encrypted, return bitstring
2989
- if (!publishedList.metadata.encrypted)
2990
- return publishedList.metadata.encoding === 'base64url'
2991
- ? publishedList.StatusList2021.encodedList
2992
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
2993
- // decrypt + return bitstring, if qualified for migration
2994
- if (publishedList.metadata.encryptedSymmetricKey)
2995
- return await v2_js_1.LitProtocolV2.decryptDirect(await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021
2996
- .encodedList, 'hex')), (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
2997
- // validate encoded list
2998
- if (!(0, helpers_js_1.isEncodedList)(publishedList.StatusList2021.encodedList))
2999
- throw new Error('[did-provider-cheqd]: suspension: Invalid encoded list');
3000
- // otherwise, decrypt and return raw bitstring
3001
- const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)((0, helpers_js_1.getEncodedList)(publishedList.StatusList2021.encodedList, false)[0], 'hex'));
3002
- // decrypt
3003
- return (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
3004
- })()
3005
- : await (async function () {
3006
- // transcode to base64url, if needed
3007
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
3008
- ? publishedList.StatusList2021.encodedList
3009
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
3010
- // if status list 2021 is not fetched, read from file
3011
- if (options?.statusListFile) {
3012
- // if not encrypted, return bitstring
3013
- if (!publishedList.metadata.encrypted) {
3014
- // construct encoded status list
3015
- const encoded = new vc_status_list_1.StatusList({
3016
- buffer: await Cheqd.getFile(options.statusListFile),
3017
- }).encode();
3018
- // validate against published list
3019
- if (encoded !== publishedListTranscoded)
3020
- throw new Error('[did-provider-cheqd]: suspension: statusListFile does not match published status list 2021');
3021
- // return encoded
3022
- return encoded;
3023
- }
3024
- // otherwise, decrypt and return bitstring
3025
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
3026
- // decrypt
3027
- const decrypted = (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
3028
- // validate against published list
3029
- if (decrypted !== publishedListTranscoded)
3030
- throw new Error('[did-provider-cheqd]: suspension: statusListFile does not match published status list 2021');
3031
- // return decrypted
3032
- return decrypted;
3033
- }
3034
- if (!options?.statusListInlineBitstring)
3035
- throw new Error('[did-provider-cheqd]: suspension: statusListInlineBitstring is required, if statusListFile is not provided');
3036
- // validate against published list
3037
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
3038
- throw new Error('[did-provider-cheqd]: suspension: statusListInlineBitstring does not match published status list 2021');
3039
- // otherwise, read from inline bitstring
3040
- return options?.statusListInlineBitstring;
3041
- })();
3042
- // parse status list 2021
3043
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: statusList2021 });
3044
- // initiate bulk suspension
3045
- const suspended = (await Promise.allSettled(credentials.map((credential) => {
3046
- return (async function () {
3047
- // early return, if no credential status
3048
- if (!credential.credentialStatus)
3049
- return { suspended: false };
3050
- // early exit, if credential is already suspended
3051
- if (statusList.getStatus(Number(credential.credentialStatus.statusListIndex)))
3052
- return { suspended: true };
3053
- // update suspension status
3054
- statusList.setStatus(Number(credential.credentialStatus.statusListIndex), true);
3055
- // return suspension status
3056
- return { suspended: true };
3057
- })();
3058
- })));
3059
- // revert bulk ops, if some failed
3060
- if (suspended.some((result) => result.status === 'fulfilled' && !result.value.suspended))
3061
- throw new Error(`[did-provider-cheqd]: suspension: Bulk suspension failed: already suspended credentials in suspension bundle: raw log: ${JSON.stringify(suspended.map((result) => ({
3062
- suspended: result.status === 'fulfilled' ? result.value.suspended : false,
3063
- })))}`);
3064
- // set in-memory status list ref
3065
- const bitstring = (await statusList.encode());
3066
- // cast top-level args
3067
- const topArgs = options?.topArgs;
3068
- // write status list 2021 to file, if provided
3069
- if (topArgs?.writeToFile) {
3070
- await Cheqd.writeFile((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options?.statusListFile);
3071
- }
3072
- // publish status list 2021, if provided
3073
- const published = topArgs?.publish
3074
- ? await (async function () {
3075
- // fetch status list 2021 metadata
3076
- const statusListMetadata = await Cheqd.fetchStatusList2021Metadata(credentials[0]);
3077
- // publish status list 2021 as new version
3078
- const scoped = topArgs.publishEncrypted
3079
- ? await (async function () {
3080
- // validate encoding, if provided
3081
- if (options?.publishOptions?.statusListEncoding &&
3082
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
3083
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list encoding');
3084
- }
3085
- // validate validUntil, if provided
3086
- if (options?.publishOptions?.statusListValidUntil) {
3087
- // validate validUntil as string
3088
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
3089
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be string)');
3090
- // validate validUntil as date
3091
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
3092
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be date)');
3093
- // validate validUntil as future date
3094
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
3095
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be future date)');
3096
- // validate validUntil towards validFrom
3097
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
3098
- new Date(publishedList.StatusList2021.validFrom))
3099
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be after validFrom)');
3100
- }
3101
- // validate paymentConditions, if provided
3102
- if (topArgs?.paymentConditions) {
3103
- if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress &&
3104
- condition.feePaymentAmount &&
3105
- condition.intervalInSeconds)) {
3106
- throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
3107
- }
3108
- if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' &&
3109
- typeof condition.feePaymentAmount === 'string' &&
3110
- typeof condition.intervalInSeconds === 'number')) {
3111
- throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
3112
- }
3113
- if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
3114
- throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
3115
- }
3116
- }
3117
- // validate dkgOptions
3118
- if (!topArgs?.dkgOptions ||
3119
- !topArgs?.dkgOptions?.chain ||
3120
- !topArgs?.dkgOptions?.network) {
3121
- throw new Error('[did-provider-cheqd]: dkgOptions is required');
3122
- }
3123
- // encrypt bitstring - case: symmetric
3124
- const { encryptedString: symmetricEncryptionCiphertext, stringHash: symmetricEncryptionStringHash, symmetricKey, } = await v6_js_1.LitProtocol.encryptDirect((0, uint8arrays_1.fromString)(bitstring, 'base64url'));
3125
- // instantiate dkg-threshold client, in which case lit-protocol is used
3126
- const lit = (await options.publishOptions.instantiateDkgClient);
3127
- // construct access control conditions and payment conditions tuple
3128
- const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
3129
- ? await (async function () {
3130
- // define payment conditions, give precedence to top-level args
3131
- const paymentConditions = topArgs?.paymentConditions ||
3132
- publishedList.metadata.paymentConditions;
3133
- // return access control conditions and payment conditions tuple
3134
- return [
3135
- await Promise.all(paymentConditions.map(async (condition) => {
3136
- switch (condition.type) {
3137
- case exports.AccessControlConditionTypes.timelockPayment:
3138
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
3139
- key: '$.tx_responses.*.timestamp',
3140
- comparator: '<=',
3141
- value: `${condition.intervalInSeconds}`,
3142
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
3143
- default:
3144
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
3145
- }
3146
- })),
3147
- paymentConditions,
3148
- ];
3149
- })()
3150
- : await (async function () {
3151
- // validate paymentConditions
3152
- if (!topArgs?.paymentConditions) {
3153
- throw new Error('[did-provider-cheqd]: paymentConditions is required');
3154
- }
3155
- // return access control conditions and payment conditions tuple
3156
- return [
3157
- await Promise.all(topArgs.paymentConditions.map(async (condition) => {
3158
- switch (condition.type) {
3159
- case exports.AccessControlConditionTypes.timelockPayment:
3160
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
3161
- key: '$.tx_responses.*.timestamp',
3162
- comparator: '<=',
3163
- value: `${condition.intervalInSeconds}`,
3164
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
3165
- default:
3166
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
3167
- }
3168
- })),
3169
- topArgs.paymentConditions,
3170
- ];
3171
- })();
3172
- // encrypt bitstring - case: threshold
3173
- const { encryptedString: thresholdEncryptionCiphertext, stringHash: thresholdEncryptionStringHash, } = await lit.encrypt((0, uint8arrays_1.fromString)(bitstring, 'base64url'), unifiedAccessControlConditionsTuple[0]);
3174
- // construct encoded list
3175
- const encodedList = `${await (0, helpers_js_1.blobToHexString)(symmetricEncryptionCiphertext)}-${(0, uint8arrays_1.toString)(thresholdEncryptionCiphertext, 'hex')}`;
3176
- // define status list content
3177
- const content = {
3178
- StatusList2021: {
3179
- statusPurpose: publishedList.StatusList2021.statusPurpose,
3180
- encodedList,
3181
- validFrom: publishedList.StatusList2021.validFrom,
3182
- validUntil: options?.publishOptions?.statusListValidUntil ||
3183
- publishedList.StatusList2021.validUntil,
3184
- },
3185
- metadata: {
3186
- type: publishedList.metadata.type,
3187
- encrypted: true,
3188
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
3189
- statusListHash: symmetricEncryptionStringHash === thresholdEncryptionStringHash
3190
- ? symmetricEncryptionStringHash
3191
- : (function () {
3192
- throw new Error('[did-provider-cheqd]: suspension: symmetricEncryptionStringHash and thresholdEncryptionStringHash do not match');
3193
- })(),
3194
- paymentConditions: unifiedAccessControlConditionsTuple[1],
3195
- },
3196
- };
3197
- // return tuple of publish result and encryption relevant metadata
3198
- return [
3199
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
3200
- {
3201
- symmetricEncryptionCiphertext,
3202
- thresholdEncryptionCiphertext,
3203
- stringHash: symmetricEncryptionStringHash,
3204
- symmetricKey,
3205
- },
3206
- ];
3207
- })()
3208
- : await (async function () {
3209
- // validate encoding, if provided
3210
- if (options?.publishOptions?.statusListEncoding &&
3211
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
3212
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list encoding');
3213
- }
3214
- // validate validUntil, if provided
3215
- if (options?.publishOptions?.statusListValidUntil) {
3216
- // validate validUntil as string
3217
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
3218
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be string)');
3219
- // validate validUntil as date
3220
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
3221
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be date)');
3222
- // validate validUntil as future date
3223
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
3224
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be future date)');
3225
- // validate validUntil towards validFrom
3226
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
3227
- new Date(publishedList.StatusList2021.validFrom))
3228
- throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be after validFrom)');
3229
- }
3230
- // define status list content
3231
- const content = {
3232
- StatusList2021: {
3233
- statusPurpose: publishedList.StatusList2021.statusPurpose,
3234
- encodedList: publishedList.metadata.encoding === 'base64url'
3235
- ? bitstring
3236
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options.publishOptions
3237
- .statusListEncoding),
3238
- validFrom: publishedList.StatusList2021.validFrom,
3239
- validUntil: options?.publishOptions?.statusListValidUntil ||
3240
- publishedList.StatusList2021.validUntil,
3241
- },
3242
- metadata: {
3243
- type: publishedList.metadata.type,
3244
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
3245
- encrypted: false,
3246
- },
3247
- };
3248
- // return tuple of publish result and encryption relevant metadata
3249
- return [
3250
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
3251
- undefined,
3252
- ];
3253
- })();
3254
- // early exit, if publish failed
3255
- if (!scoped[0])
3256
- throw new Error('[did-provider-cheqd]: suspension: Failed to publish status list 2021');
3257
- // return publish result
3258
- return scoped;
3259
- })()
3260
- : undefined;
3261
- return {
3262
- suspended: suspended.map((result) => (result.status === 'fulfilled' ? result.value.suspended : false)),
3263
- published: topArgs?.publish ? true : undefined,
3264
- statusList: topArgs?.returnUpdatedStatusList
3265
- ? (await Cheqd.fetchStatusList2021(credentials[0]))
3266
- : undefined,
3267
- symmetricKey: topArgs?.returnSymmetricKey
3268
- ? (0, uint8arrays_1.toString)(published?.[1]?.symmetricKey, 'hex')
3269
- : undefined,
3270
- resourceMetadata: topArgs?.returnStatusListMetadata
3271
- ? await Cheqd.fetchStatusList2021Metadata(credentials[0])
3272
- : undefined,
3273
- };
3274
- }
3275
- catch (error) {
3276
- // silent fail + early exit
3277
- console.error(error);
3278
- return { suspended: [], error: error };
3279
- }
3280
- }
3281
- static async unsuspendCredential(credential, options) {
3282
- try {
3283
- // validate status purpose
3284
- if (credential?.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension)
3285
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status purpose');
3286
- // fetch status list 2021
3287
- const publishedList = (await Cheqd.fetchStatusList2021(credential));
3288
- // early return, if encrypted and no decryption key provided
3289
- if (publishedList.metadata.encrypted && !options?.topArgs?.symmetricKey)
3290
- throw new Error('[did-provider-cheqd]: unsuspension: symmetricKey is required, if status list 2021 is encrypted');
3291
- // fetch status list 2021 inscribed in credential
3292
- const statusList2021 = options?.topArgs?.fetchList
3293
- ? await (async function () {
3294
- // if not encrypted, return bitstring
3295
- if (!publishedList.metadata.encrypted)
3296
- return publishedList.metadata.encoding === 'base64url'
3297
- ? publishedList.StatusList2021.encodedList
3298
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
3299
- // decrypt + return bitstring, if qualified for migration
3300
- if (publishedList.metadata.encryptedSymmetricKey)
3301
- return await v2_js_1.LitProtocolV2.decryptDirect(await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021
3302
- .encodedList, 'hex')), (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
3303
- // validate encoded list
3304
- if (!(0, helpers_js_1.isEncodedList)(publishedList.StatusList2021.encodedList))
3305
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid encoded list');
3306
- // otherwise, decrypt and return raw bitstring
3307
- const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)((0, helpers_js_1.getEncodedList)(publishedList.StatusList2021.encodedList, false)[0], 'hex'));
3308
- // decrypt
3309
- return (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
3310
- })()
3311
- : await (async function () {
3312
- // transcode to base64url, if needed
3313
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
3314
- ? publishedList.StatusList2021.encodedList
3315
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
3316
- // if status list 2021 is not fetched, read from file
3317
- if (options?.statusListFile) {
3318
- // if not encrypted, return bitstring
3319
- if (!publishedList.metadata.encrypted) {
3320
- // construct encoded status list
3321
- const encoded = new vc_status_list_1.StatusList({
3322
- buffer: await Cheqd.getFile(options.statusListFile),
3323
- }).encode();
3324
- // validate against published list
3325
- if (encoded !== publishedListTranscoded)
3326
- throw new Error('[did-provider-cheqd]: unsuspension: statusListFile does not match published status list 2021');
3327
- // return encoded
3328
- return encoded;
3329
- }
3330
- // otherwise, decrypt and return bitstring
3331
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
3332
- // decrypt
3333
- const decrypted = (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
3334
- // validate against published list
3335
- if (decrypted !== publishedListTranscoded)
3336
- throw new Error('[did-provider-cheqd]: unsuspension: statusListFile does not match published status list 2021');
3337
- // return decrypted
3338
- return decrypted;
3339
- }
3340
- if (!options?.statusListInlineBitstring)
3341
- throw new Error('[did-provider-cheqd]: unsuspension: statusListInlineBitstring is required, if statusListFile is not provided');
3342
- // validate against published list
3343
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
3344
- throw new Error('[did-provider-cheqd]: unsuspension: statusListInlineBitstring does not match published status list 2021');
3345
- // otherwise, read from inline bitstring
3346
- return options?.statusListInlineBitstring;
3347
- })();
3348
- // parse status list 2021
3349
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: statusList2021 });
3350
- // early exit, if already unsuspended
3351
- if (!statusList.getStatus(Number(credential.credentialStatus.statusListIndex)))
3352
- return { unsuspended: true };
3353
- // update suspension status
3354
- statusList.setStatus(Number(credential.credentialStatus.statusListIndex), false);
3355
- // set in-memory status list ref
3356
- const bitstring = (await statusList.encode());
3357
- // cast top-level args
3358
- const topArgs = options?.topArgs;
3359
- // write status list 2021 to file, if provided
3360
- if (topArgs?.writeToFile) {
3361
- await Cheqd.writeFile((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options?.statusListFile);
3362
- }
3363
- // publish status list 2021, if provided
3364
- const published = topArgs?.publish
3365
- ? await (async function () {
3366
- // fetch status list 2021 metadata
3367
- const statusListMetadata = await Cheqd.fetchStatusList2021Metadata(credential);
3368
- // publish status list 2021 as new version
3369
- const scoped = topArgs.publishEncrypted
3370
- ? await (async function () {
3371
- // validate encoding, if provided
3372
- if (options?.publishOptions?.statusListEncoding &&
3373
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
3374
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list encoding');
3375
- }
3376
- // validate validUntil, if provided
3377
- if (options?.publishOptions?.statusListValidUntil) {
3378
- // validate validUntil as string
3379
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
3380
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be string)');
3381
- // validate validUntil as date
3382
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
3383
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be date)');
3384
- // validate validUntil as future date
3385
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
3386
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be future date)');
3387
- // validate validUntil towards validFrom
3388
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
3389
- new Date(publishedList.StatusList2021.validFrom))
3390
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be after validFrom)');
3391
- }
3392
- // validate paymentConditions, if provided
3393
- if (topArgs?.paymentConditions) {
3394
- if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress &&
3395
- condition.feePaymentAmount &&
3396
- condition.intervalInSeconds)) {
3397
- throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
3398
- }
3399
- if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' &&
3400
- typeof condition.feePaymentAmount === 'string' &&
3401
- typeof condition.intervalInSeconds === 'number')) {
3402
- throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
3403
- }
3404
- if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
3405
- throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
3406
- }
3407
- }
3408
- // validate dkgOptions
3409
- if (!topArgs?.dkgOptions ||
3410
- !topArgs?.dkgOptions?.chain ||
3411
- !topArgs?.dkgOptions?.network) {
3412
- throw new Error('[did-provider-cheqd]: dkgOptions is required');
3413
- }
3414
- // encrypt bitstring - case: symmetric
3415
- const { encryptedString: symmetricEncryptionCiphertext, stringHash: symmetricEncryptionStringHash, symmetricKey, } = await v6_js_1.LitProtocol.encryptDirect((0, uint8arrays_1.fromString)(bitstring, 'base64url'));
3416
- // instantiate dkg-threshold client, in which case lit-protocol is used
3417
- const lit = (await options.publishOptions.instantiateDkgClient);
3418
- // construct access control conditions and payment conditions tuple
3419
- const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
3420
- ? await (async function () {
3421
- // define payment conditions, give precedence to top-level args
3422
- const paymentConditions = topArgs?.paymentConditions ||
3423
- publishedList.metadata.paymentConditions;
3424
- // return access control conditions and payment conditions tuple
3425
- return [
3426
- await Promise.all(paymentConditions.map(async (condition) => {
3427
- switch (condition.type) {
3428
- case exports.AccessControlConditionTypes.timelockPayment:
3429
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
3430
- key: '$.tx_responses.*.timestamp',
3431
- comparator: '<=',
3432
- value: `${condition.intervalInSeconds}`,
3433
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
3434
- default:
3435
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
3436
- }
3437
- })),
3438
- paymentConditions,
3439
- ];
3440
- })()
3441
- : await (async function () {
3442
- // validate paymentConditions
3443
- if (!topArgs?.paymentConditions) {
3444
- throw new Error('[did-provider-cheqd]: paymentConditions is required');
3445
- }
3446
- // return access control conditions and payment conditions tuple
3447
- return [
3448
- await Promise.all(topArgs.paymentConditions.map(async (condition) => {
3449
- switch (condition.type) {
3450
- case exports.AccessControlConditionTypes.timelockPayment:
3451
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
3452
- key: '$.tx_responses.*.timestamp',
3453
- comparator: '<=',
3454
- value: `${condition.intervalInSeconds}`,
3455
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
3456
- default:
3457
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
3458
- }
3459
- })),
3460
- topArgs.paymentConditions,
3461
- ];
3462
- })();
3463
- // encrypt bitstring - case: threshold
3464
- const { encryptedString: thresholdEncryptionCiphertext, stringHash: thresholdEncryptionStringHash, } = await lit.encrypt((0, uint8arrays_1.fromString)(bitstring, 'base64url'), unifiedAccessControlConditionsTuple[0]);
3465
- // construct encoded list
3466
- const encodedList = `${await (0, helpers_js_1.blobToHexString)(symmetricEncryptionCiphertext)}-${(0, uint8arrays_1.toString)(thresholdEncryptionCiphertext, 'hex')}`;
3467
- // define status list content
3468
- const content = {
3469
- StatusList2021: {
3470
- statusPurpose: publishedList.StatusList2021.statusPurpose,
3471
- encodedList,
3472
- validFrom: publishedList.StatusList2021.validFrom,
3473
- validUntil: options?.publishOptions?.statusListValidUntil ||
3474
- publishedList.StatusList2021.validUntil,
3475
- },
3476
- metadata: {
3477
- type: publishedList.metadata.type,
3478
- encrypted: true,
3479
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
3480
- statusListHash: symmetricEncryptionStringHash === thresholdEncryptionStringHash
3481
- ? symmetricEncryptionStringHash
3482
- : (function () {
3483
- throw new Error('[did-provider-cheqd]: unsuspension: symmetricEncryptionStringHash and thresholdEncryptionStringHash do not match');
3484
- })(),
3485
- paymentConditions: unifiedAccessControlConditionsTuple[1],
3486
- },
3487
- };
3488
- // return tuple of publish result and encryption relevant metadata
3489
- return [
3490
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
3491
- {
3492
- symmetricEncryptionCiphertext,
3493
- thresholdEncryptionCiphertext,
3494
- stringHash: symmetricEncryptionStringHash,
3495
- symmetricKey,
3496
- },
3497
- ];
3498
- })()
3499
- : await (async function () {
3500
- // validate encoding, if provided
3501
- if (options?.publishOptions?.statusListEncoding &&
3502
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
3503
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list encoding');
3504
- }
3505
- // validate validUntil, if provided
3506
- if (options?.publishOptions?.statusListValidUntil) {
3507
- // validate validUntil as string
3508
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
3509
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be string)');
3510
- // validate validUntil as date
3511
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
3512
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be date)');
3513
- // validate validUntil as future date
3514
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
3515
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be future date)');
3516
- // validate validUntil towards validFrom
3517
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
3518
- new Date(publishedList.StatusList2021.validFrom))
3519
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be after validFrom)');
3520
- }
3521
- // define status list content
3522
- const content = {
3523
- StatusList2021: {
3524
- statusPurpose: publishedList.StatusList2021.statusPurpose,
3525
- encodedList: publishedList.metadata.encoding === 'base64url'
3526
- ? bitstring
3527
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options.publishOptions
3528
- .statusListEncoding),
3529
- validFrom: publishedList.StatusList2021.validFrom,
3530
- validUntil: options?.publishOptions?.statusListValidUntil ||
3531
- publishedList.StatusList2021.validUntil,
3532
- },
3533
- metadata: {
3534
- type: publishedList.metadata.type,
3535
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
3536
- encrypted: false,
3537
- },
3538
- };
3539
- // return tuple of publish result and encryption relevant metadata
3540
- return [
3541
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
3542
- undefined,
3543
- ];
3544
- })();
3545
- // early exit, if publish failed
3546
- if (!scoped[0])
3547
- throw new Error('[did-provider-cheqd]: unsuspension: Failed to publish status list 2021');
3548
- // return publish result
3549
- return scoped;
3550
- })()
3551
- : undefined;
3552
- return {
3553
- unsuspended: true,
3554
- published: topArgs?.publish ? true : undefined,
3555
- statusList: topArgs?.returnUpdatedStatusList
3556
- ? (await Cheqd.fetchStatusList2021(credential))
3557
- : undefined,
3558
- symmetricKey: topArgs?.returnSymmetricKey
3559
- ? (0, uint8arrays_1.toString)(published?.[1]?.symmetricKey, 'hex')
3560
- : undefined,
3561
- resourceMetadata: topArgs?.returnStatusListMetadata
3562
- ? await Cheqd.fetchStatusList2021Metadata(credential)
3563
- : undefined,
3564
- };
3565
- }
3566
- catch (error) {
3567
- // silent fail + early exit
3568
- console.error(error);
3569
- return { unsuspended: false, error: error };
3570
- }
3571
- }
3572
- static async unsuspendCredentials(credentials, options) {
3573
- // validate credentials - case: empty
3574
- if (!credentials.length || credentials.length === 0)
3575
- throw new Error('[did-provider-cheqd]: unsuspension: No credentials provided');
3576
- // validate credentials - case: consistent issuer
3577
- if (credentials
3578
- .map((credential) => {
3579
- return credential.issuer.id
3580
- ? credential.issuer.id
3581
- : credential.issuer;
3582
- })
3583
- .filter((value, _, self) => value && value !== self[0]).length > 0)
3584
- throw new Error('[did-provider-cheqd]: unsuspension: Credentials must be issued by the same issuer');
3585
- // validate credentials - case: status list index
3586
- if (credentials
3587
- .map((credential) => credential.credentialStatus.statusListIndex)
3588
- .filter((value, index, self) => self.indexOf(value) !== index).length > 0)
3589
- throw new Error('[did-provider-cheqd]: unsuspension: Credentials must have unique status list index');
3590
- // validate credentials - case: status purpose
3591
- if (!credentials.every((credential) => credential.credentialStatus?.statusPurpose === cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension))
3592
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status purpose');
3593
- // validate credentials - case: status list id
3594
- const remote = credentials[0].credentialStatus?.id
3595
- ? credentials[0].credentialStatus.id.split('#')[0]
3596
- : (function () {
3597
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list id');
3598
- })();
3599
- // validate credentials - case: status list id format
3600
- if (!exports.RemoteListPattern.test(remote))
3601
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list id format: expected: https://<optional_subdomain>.<sld>.<tld>/1.0/identifiers/<did:cheqd:<namespace>:<method_specific_id>>?resourceName=<resource_name>&resourceType=<resource_type>');
3602
- if (!credentials.every((credential) => {
3603
- return credential.credentialStatus.id.split('#')[0] === remote;
3604
- }))
3605
- throw new Error('[did-provider-cheqd]: unsuspension: Credentials must belong to the same status list');
3606
- // validate credentials - case: status list type
3607
- if (!credentials.every((credential) => credential.credentialStatus?.type === 'StatusList2021Entry'))
3608
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list type');
3609
- try {
3610
- // fetch status list 2021
3611
- const publishedList = (await Cheqd.fetchStatusList2021(credentials[0]));
3612
- // early return, if encrypted and no decryption key provided
3613
- if (publishedList.metadata.encrypted && !options?.topArgs?.symmetricKey)
3614
- throw new Error('[did-provider-cheqd]: unsuspension: symmetricKey is required, if status list 2021 is encrypted');
3615
- // fetch status list 2021 inscribed in credential
3616
- const statusList2021 = options?.topArgs?.fetchList
3617
- ? await (async function () {
3618
- // if not encrypted, return bitstring
3619
- if (!publishedList.metadata.encrypted)
3620
- return publishedList.metadata.encoding === 'base64url'
3621
- ? publishedList.StatusList2021.encodedList
3622
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
3623
- // decrypt + return bitstring, if qualified for migration
3624
- if (publishedList.metadata.encryptedSymmetricKey)
3625
- return await v2_js_1.LitProtocolV2.decryptDirect(await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021
3626
- .encodedList, 'hex')), (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
3627
- // validate encoded list
3628
- if (!(0, helpers_js_1.isEncodedList)(publishedList.StatusList2021.encodedList))
3629
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid encoded list');
3630
- // otherwise, decrypt and return raw bitstring
3631
- const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)((0, helpers_js_1.getEncodedList)(publishedList.StatusList2021.encodedList, false)[0], 'hex'));
3632
- // decrypt
3633
- return (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
3634
- })()
3635
- : await (async function () {
3636
- // transcode to base64url, if needed
3637
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
3638
- ? publishedList.StatusList2021.encodedList
3639
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
3640
- // if status list 2021 is not fetched, read from file
3641
- if (options?.statusListFile) {
3642
- // if not encrypted, return bitstring
3643
- if (!publishedList.metadata.encrypted) {
3644
- // construct encoded status list
3645
- const encoded = new vc_status_list_1.StatusList({
3646
- buffer: await Cheqd.getFile(options.statusListFile),
3647
- }).encode();
3648
- // validate against published list
3649
- if (encoded !== publishedListTranscoded)
3650
- throw new Error('[did-provider-cheqd]: unsuspension: statusListFile does not match published status list 2021');
3651
- // return encoded
3652
- return encoded;
3653
- }
3654
- // otherwise, decrypt and return bitstring
3655
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
3656
- // decrypt
3657
- const decrypted = (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
3658
- // validate against published list
3659
- if (decrypted !== publishedListTranscoded)
3660
- throw new Error('[did-provider-cheqd]: unsuspension: statusListFile does not match published status list 2021');
3661
- // return decrypted
3662
- return decrypted;
3663
- }
3664
- if (!options?.statusListInlineBitstring)
3665
- throw new Error('[did-provider-cheqd]: unsuspension: statusListInlineBitstring is required, if statusListFile is not provided');
3666
- // validate against published list
3667
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
3668
- throw new Error('[did-provider-cheqd]: unsuspension: statusListInlineBitstring does not match published status list 2021');
3669
- // otherwise, read from inline bitstring
3670
- return options?.statusListInlineBitstring;
3671
- })();
3672
- // parse status list 2021
3673
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: statusList2021 });
3674
- // initiate bulk unsuspension
3675
- const unsuspended = (await Promise.allSettled(credentials.map((credential) => {
3676
- return (async function () {
3677
- // early return, if no credential status
3678
- if (!credential.credentialStatus)
3679
- return { unsuspended: false };
3680
- // early exit, if credential is already unsuspended
3681
- if (!statusList.getStatus(Number(credential.credentialStatus.statusListIndex)))
3682
- return { unsuspended: true };
3683
- // update unsuspension status
3684
- statusList.setStatus(Number(credential.credentialStatus.statusListIndex), false);
3685
- // return unsuspension status
3686
- return { unsuspended: true };
3687
- })();
3688
- })));
3689
- // revert bulk ops, if some failed
3690
- if (unsuspended.some((result) => result.status === 'fulfilled' && !result.value.unsuspended))
3691
- throw new Error(`[did-provider-cheqd]: unsuspension: Bulk unsuspension failed: already unsuspended credentials in unsuspension bundle: raw log: ${JSON.stringify(unsuspended.map((result) => ({
3692
- unsuspended: result.status === 'fulfilled' ? result.value.unsuspended : false,
3693
- })))}`);
3694
- // set in-memory status list ref
3695
- const bitstring = (await statusList.encode());
3696
- // cast top-level args
3697
- const topArgs = options?.topArgs;
3698
- // write status list 2021 to file, if provided
3699
- if (topArgs?.writeToFile) {
3700
- await Cheqd.writeFile((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options?.statusListFile);
3701
- }
3702
- // publish status list 2021, if provided
3703
- const published = topArgs?.publish
3704
- ? await (async function () {
3705
- // fetch status list 2021 metadata
3706
- const statusListMetadata = await Cheqd.fetchStatusList2021Metadata(credentials[0]);
3707
- // publish status list 2021 as new version
3708
- const scoped = topArgs.publishEncrypted
3709
- ? await (async function () {
3710
- // validate encoding, if provided
3711
- if (options?.publishOptions?.statusListEncoding &&
3712
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
3713
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list encoding');
3714
- }
3715
- // validate validUntil, if provided
3716
- if (options?.publishOptions?.statusListValidUntil) {
3717
- // validate validUntil as string
3718
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
3719
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be string)');
3720
- // validate validUntil as date
3721
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
3722
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be date)');
3723
- // validate validUntil as future date
3724
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
3725
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be future date)');
3726
- // validate validUntil towards validFrom
3727
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
3728
- new Date(publishedList.StatusList2021.validFrom))
3729
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be after validFrom)');
3730
- }
3731
- // validate paymentConditions, if provided
3732
- if (topArgs?.paymentConditions) {
3733
- if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress &&
3734
- condition.feePaymentAmount &&
3735
- condition.intervalInSeconds)) {
3736
- throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
3737
- }
3738
- if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' &&
3739
- typeof condition.feePaymentAmount === 'string' &&
3740
- typeof condition.intervalInSeconds === 'number')) {
3741
- throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
3742
- }
3743
- if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
3744
- throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
3745
- }
3746
- }
3747
- // validate dkgOptions
3748
- if (!topArgs?.dkgOptions ||
3749
- !topArgs?.dkgOptions?.chain ||
3750
- !topArgs?.dkgOptions?.network) {
3751
- throw new Error('[did-provider-cheqd]: dkgOptions is required');
3752
- }
3753
- // encrypt bitstring - case: symmetric
3754
- const { encryptedString: symmetricEncryptionCiphertext, stringHash: symmetricEncryptionStringHash, symmetricKey, } = await v6_js_1.LitProtocol.encryptDirect((0, uint8arrays_1.fromString)(bitstring, 'base64url'));
3755
- // instantiate dkg-threshold client, in which case lit-protocol is used
3756
- const lit = (await options.publishOptions.instantiateDkgClient);
3757
- // construct access control conditions and payment conditions tuple
3758
- const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
3759
- ? await (async function () {
3760
- // define payment conditions, give precedence to top-level args
3761
- const paymentConditions = topArgs?.paymentConditions ||
3762
- publishedList.metadata.paymentConditions;
3763
- // return access control conditions and payment conditions tuple
3764
- return [
3765
- await Promise.all(paymentConditions.map(async (condition) => {
3766
- switch (condition.type) {
3767
- case exports.AccessControlConditionTypes.timelockPayment:
3768
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
3769
- key: '$.tx_responses.*.timestamp',
3770
- comparator: '<=',
3771
- value: `${condition.intervalInSeconds}`,
3772
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
3773
- default:
3774
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
3775
- }
3776
- })),
3777
- paymentConditions,
3778
- ];
3779
- })()
3780
- : await (async function () {
3781
- // validate paymentConditions
3782
- if (!topArgs?.paymentConditions) {
3783
- throw new Error('[did-provider-cheqd]: paymentConditions is required');
3784
- }
3785
- // return access control conditions and payment conditions tuple
3786
- return [
3787
- await Promise.all(topArgs.paymentConditions.map(async (condition) => {
3788
- switch (condition.type) {
3789
- case exports.AccessControlConditionTypes.timelockPayment:
3790
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
3791
- key: '$.tx_responses.*.timestamp',
3792
- comparator: '<=',
3793
- value: `${condition.intervalInSeconds}`,
3794
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
3795
- default:
3796
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
3797
- }
3798
- })),
3799
- topArgs.paymentConditions,
3800
- ];
3801
- })();
3802
- // encrypt bitstring - case: threshold
3803
- const { encryptedString: thresholdEncryptionCiphertext, stringHash: thresholdEncryptionStringHash, } = await lit.encrypt((0, uint8arrays_1.fromString)(bitstring, 'base64url'), unifiedAccessControlConditionsTuple[0]);
3804
- // construct encoded list
3805
- const encodedList = `${await (0, helpers_js_1.blobToHexString)(symmetricEncryptionCiphertext)}-${(0, uint8arrays_1.toString)(thresholdEncryptionCiphertext, 'hex')}`;
3806
- // define status list content
3807
- const content = {
3808
- StatusList2021: {
3809
- statusPurpose: publishedList.StatusList2021.statusPurpose,
3810
- encodedList,
3811
- validFrom: publishedList.StatusList2021.validFrom,
3812
- validUntil: options?.publishOptions?.statusListValidUntil ||
3813
- publishedList.StatusList2021.validUntil,
3814
- },
3815
- metadata: {
3816
- type: publishedList.metadata.type,
3817
- encrypted: true,
3818
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
3819
- statusListHash: symmetricEncryptionStringHash === thresholdEncryptionStringHash
3820
- ? symmetricEncryptionStringHash
3821
- : (function () {
3822
- throw new Error('[did-provider-cheqd]: unsuspension: symmetricEncryptionStringHash and thresholdEncryptionStringHash do not match');
3823
- })(),
3824
- paymentConditions: unifiedAccessControlConditionsTuple[1],
3825
- },
3826
- };
3827
- // return tuple of publish result and encryption relevant metadata
3828
- return [
3829
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
3830
- {
3831
- symmetricEncryptionCiphertext,
3832
- thresholdEncryptionCiphertext,
3833
- stringHash: symmetricEncryptionStringHash,
3834
- symmetricKey,
3835
- },
3836
- ];
3837
- })()
3838
- : await (async function () {
3839
- // validate encoding, if provided
3840
- if (options?.publishOptions?.statusListEncoding &&
3841
- !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
3842
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list encoding');
3843
- }
3844
- // validate validUntil, if provided
3845
- if (options?.publishOptions?.statusListValidUntil) {
3846
- // validate validUntil as string
3847
- if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
3848
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be string)');
3849
- // validate validUntil as date
3850
- if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
3851
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be date)');
3852
- // validate validUntil as future date
3853
- if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
3854
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be future date)');
3855
- // validate validUntil towards validFrom
3856
- if (new Date(options?.publishOptions?.statusListValidUntil) <=
3857
- new Date(publishedList.StatusList2021.validFrom))
3858
- throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be after validFrom)');
3859
- }
3860
- // define status list content
3861
- const content = {
3862
- StatusList2021: {
3863
- statusPurpose: publishedList.StatusList2021.statusPurpose,
3864
- encodedList: publishedList.metadata.encoding === 'base64url'
3865
- ? bitstring
3866
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(bitstring, 'base64url'), options.publishOptions
3867
- .statusListEncoding),
3868
- validFrom: publishedList.StatusList2021.validFrom,
3869
- validUntil: options?.publishOptions?.statusListValidUntil ||
3870
- publishedList.StatusList2021.validUntil,
3871
- },
3872
- metadata: {
3873
- type: publishedList.metadata.type,
3874
- encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
3875
- encrypted: false,
3876
- },
3877
- };
3878
- // return tuple of publish result and encryption relevant metadata
3879
- return [
3880
- await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
3881
- undefined,
3882
- ];
3883
- })();
3884
- // early exit, if publish failed
3885
- if (!scoped[0])
3886
- throw new Error('[did-provider-cheqd]: unsuspension: Failed to publish status list 2021');
3887
- // return publish result
3888
- return scoped;
3889
- })()
3890
- : undefined;
3891
- return {
3892
- unsuspended: unsuspended.map((result) => result.status === 'fulfilled' ? result.value.unsuspended : false),
3893
- published: topArgs?.publish ? true : undefined,
3894
- statusList: topArgs?.returnUpdatedStatusList
3895
- ? (await Cheqd.fetchStatusList2021(credentials[0]))
3896
- : undefined,
3897
- symmetricKey: topArgs?.returnSymmetricKey
3898
- ? (0, uint8arrays_1.toString)(published?.[1]?.symmetricKey, 'hex')
3899
- : undefined,
3900
- resourceMetadata: topArgs?.returnStatusListMetadata
3901
- ? await Cheqd.fetchStatusList2021Metadata(credentials[0])
3902
- : undefined,
3903
- };
3904
- }
3905
- catch (error) {
3906
- // silent fail + early exit
3907
- console.error(error);
3908
- return { unsuspended: [], error: error };
3909
- }
3910
- }
3911
- static async checkRevoked(credential, options = { fetchList: true }) {
3912
- // validate status purpose
3913
- if (credential.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation) {
3914
- throw new Error(`[did-provider-cheqd]: check: revocation: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
3915
- }
3916
- // validate dkgOptions
3917
- if (!options?.topArgs?.dkgOptions) {
3918
- throw new Error('[did-provider-cheqd]: dkgOptions is required');
3919
- }
3920
- // fetch status list 2021
3921
- const publishedList = (await Cheqd.fetchStatusList2021(credential));
3922
- // route to non-migrated action, if applicable
3923
- if (publishedList.metadata.encryptedSymmetricKey)
3924
- return await this.checkRevokedNonMigrated(credential, publishedList, options);
3925
- // fetch status list 2021 inscribed in credential
3926
- const statusList2021 = options?.topArgs?.fetchList
3927
- ? await (async function () {
3928
- // if not encrypted, return bitstring
3929
- if (!publishedList.metadata.encrypted)
3930
- return publishedList.metadata.encoding === 'base64url'
3931
- ? publishedList.StatusList2021.encodedList
3932
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
3933
- // validate encoded list
3934
- if (!(0, helpers_js_1.isEncodedList)(publishedList.StatusList2021.encodedList))
3935
- throw new Error('[did-provider-cheqd]: check: revocation: Invalid encoded list');
3936
- // otherwise, decrypt and return raw bitstring
3937
- const thresholdEncryptionCiphertext = (0, helpers_js_1.getEncodedList)(publishedList.StatusList2021.encodedList, false)[1];
3938
- // instantiate dkg-threshold client, in which case lit-protocol is used
3939
- const lit = (await options.instantiateDkgClient);
3940
- // construct access control conditions
3941
- const unifiedAccessControlConditions = await Promise.all(publishedList.metadata.paymentConditions.map(async (condition) => {
3942
- switch (condition.type) {
3943
- case exports.AccessControlConditionTypes.timelockPayment:
3944
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
3945
- key: '$.tx_responses.*.timestamp',
3946
- comparator: '<=',
3947
- value: `${condition.intervalInSeconds}`,
3948
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, options?.topArgs?.dkgOptions?.chain);
3949
- default:
3950
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
3951
- }
3952
- }));
3953
- // decrypt
3954
- return await lit.decrypt(thresholdEncryptionCiphertext, publishedList.metadata.statusListHash, unifiedAccessControlConditions, options?.topArgs?.dkgOptions?.capacityDelegationAuthSignature);
3955
- })()
3956
- : await (async function () {
3957
- // transcode to base64url, if needed
3958
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
3959
- ? publishedList.StatusList2021.encodedList
3960
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
3961
- // if status list 2021 is not fetched, read from file
3962
- if (options?.statusListFile) {
3963
- // if not encrypted, return bitstring
3964
- if (!publishedList.metadata.encrypted) {
3965
- // construct encoded status list
3966
- const encoded = new vc_status_list_1.StatusList({
3967
- buffer: await Cheqd.getFile(options.statusListFile),
3968
- }).encode();
3969
- // validate against published list
3970
- if (encoded !== publishedListTranscoded)
3971
- throw new Error('[did-provider-cheqd]: check: revocation: statusListFile does not match published status list 2021');
3972
- // return encoded
3973
- return encoded;
3974
- }
3975
- // otherwise, decrypt and return bitstring
3976
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
3977
- // decrypt
3978
- const decrypted = (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
3979
- // validate against published list
3980
- if (decrypted !== publishedListTranscoded)
3981
- throw new Error('[did-provider-cheqd]: check: revocation: statusListFile does not match published status list 2021');
3982
- // return decrypted
3983
- return decrypted;
3984
- }
3985
- if (!options?.statusListInlineBitstring)
3986
- throw new Error('[did-provider-cheqd]: check: revocation: statusListInlineBitstring is required, if statusListFile is not provided');
3987
- // validate against published list
3988
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
3989
- throw new Error('[did-provider-cheqd]: check: revocation: statusListInlineBitstring does not match published status list 2021');
3990
- // otherwise, read from inline bitstring
3991
- return options?.statusListInlineBitstring;
3992
- })();
3993
- // transcode, if needed
3994
- const transcodedStatusList2021 = publishedList.metadata.encoding === 'base64url'
3995
- ? statusList2021
3996
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(statusList2021, publishedList.metadata.encoding), 'base64url');
3997
- // parse status list 2021
3998
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: transcodedStatusList2021 });
3999
- // get status by index
4000
- return !!statusList.getStatus(Number(credential.credentialStatus.statusListIndex));
4001
- }
4002
- static async checkSuspended(credential, options = { fetchList: true }) {
4003
- // validate status purpose
4004
- if (credential.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension) {
4005
- throw new Error(`[did-provider-cheqd]: check: suspension: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
4006
- }
4007
- // validate dkgOptions
4008
- if (!options?.topArgs?.dkgOptions) {
4009
- throw new Error('[did-provider-cheqd]: dkgOptions is required');
4010
- }
4011
- // fetch status list 2021
4012
- const publishedList = (await Cheqd.fetchStatusList2021(credential));
4013
- // route to non-migrated action, if applicable
4014
- if (publishedList.metadata.encryptedSymmetricKey)
4015
- return await this.checkSuspendedNonMigrated(credential, publishedList, options);
4016
- // fetch status list 2021 inscribed in credential
4017
- const statusList2021 = options?.topArgs?.fetchList
4018
- ? await (async function () {
4019
- // if not encrypted, return bitstring
4020
- if (!publishedList.metadata.encrypted)
4021
- return publishedList.metadata.encoding === 'base64url'
4022
- ? publishedList.StatusList2021.encodedList
4023
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
4024
- // otherwise, decrypt and return bitstring
4025
- const thresholdEncryptionCiphertext = (0, helpers_js_1.getEncodedList)(publishedList.StatusList2021.encodedList, false)[1];
4026
- // instantiate dkg-threshold client, in which case lit-protocol is used
4027
- const lit = (await options.instantiateDkgClient);
4028
- // construct access control conditions
4029
- const unifiedAccessControlConditions = await Promise.all(publishedList.metadata.paymentConditions.map(async (condition) => {
4030
- switch (condition.type) {
4031
- case exports.AccessControlConditionTypes.timelockPayment:
4032
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
4033
- key: '$.tx_responses.*.timestamp',
4034
- comparator: '<=',
4035
- value: `${condition.intervalInSeconds}`,
4036
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, options?.topArgs?.dkgOptions?.chain);
4037
- default:
4038
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
4039
- }
4040
- }));
4041
- // decrypt
4042
- return await lit.decrypt(thresholdEncryptionCiphertext, publishedList.metadata.statusListHash, unifiedAccessControlConditions, options?.topArgs?.dkgOptions?.capacityDelegationAuthSignature);
4043
- })()
4044
- : await (async function () {
4045
- // transcode to base64url, if needed
4046
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
4047
- ? publishedList.StatusList2021.encodedList
4048
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
4049
- // if status list 2021 is not fetched, read from file
4050
- if (options?.statusListFile) {
4051
- // if not encrypted, return bitstring
4052
- if (!publishedList.metadata.encrypted) {
4053
- // construct encoded status list
4054
- const encoded = new vc_status_list_1.StatusList({
4055
- buffer: await Cheqd.getFile(options.statusListFile),
4056
- }).encode();
4057
- // validate against published list
4058
- if (encoded !== publishedListTranscoded)
4059
- throw new Error('[did-provider-cheqd]: check: suspension: statusListFile does not match published status list 2021');
4060
- // return encoded
4061
- return encoded;
4062
- }
4063
- // otherwise, decrypt and return bitstring
4064
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
4065
- // decrypt
4066
- const decrypted = (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
4067
- // validate against published list
4068
- if (decrypted !== publishedListTranscoded)
4069
- throw new Error('[did-provider-cheqd]: check: suspension: statusListFile does not match published status list 2021');
4070
- // return decrypted
4071
- return decrypted;
4072
- }
4073
- if (!options?.statusListInlineBitstring)
4074
- throw new Error('[did-provider-cheqd]: check: suspension: statusListInlineBitstring is required, if statusListFile is not provided');
4075
- // validate against published list
4076
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
4077
- throw new Error('[did-provider-cheqd]: check: suspension: statusListInlineBitstring does not match published status list 2021');
4078
- // otherwise, read from inline bitstring
4079
- return options?.statusListInlineBitstring;
4080
- })();
4081
- // parse status list 2021
4082
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: statusList2021 });
4083
- // get status by index
4084
- return !!statusList.getStatus(Number(credential.credentialStatus.statusListIndex));
4085
- }
4086
- static async checkRevokedNonMigrated(credential, associatedStatusList, options = { fetchList: true }) {
4087
- // validate status purpose
4088
- if (credential.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation) {
4089
- throw new Error(`[did-provider-cheqd]: check: revocation: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
4090
- }
4091
- // fetch status list 2021
4092
- const publishedList = associatedStatusList ||
4093
- (await Cheqd.fetchStatusList2021(credential));
4094
- // validate migrated
4095
- if (!publishedList.metadata.encryptedSymmetricKey)
4096
- throw new Error('[did-provider-cheqd]: check: revocation: Invalid migrated status list');
4097
- // fetch status list 2021 inscribed in credential
4098
- const statusList2021 = options?.topArgs?.fetchList
4099
- ? await (async function () {
4100
- // if not encrypted, return bitstring
4101
- if (!publishedList.metadata.encrypted)
4102
- return publishedList.metadata.encoding === 'base64url'
4103
- ? publishedList.StatusList2021.encodedList
4104
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
4105
- // otherwise, decrypt and return raw bitstring
4106
- const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
4107
- // instantiate dkg-threshold client, in which case lit-protocol is used
4108
- const lit = await v2_js_1.LitProtocolV2.create({
4109
- chain: options?.topArgs?.dkgOptions?.chain,
4110
- litNetwork: v2_js_1.LitNetworksV2.serrano,
4111
- });
4112
- // construct access control conditions
4113
- const unifiedAccessControlConditions = await Promise.all(publishedList.metadata.paymentConditions.map(async (condition) => {
4114
- switch (condition.type) {
4115
- case exports.AccessControlConditionTypes.timelockPayment:
4116
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
4117
- key: '$.tx_responses.*.timestamp',
4118
- comparator: '<=',
4119
- value: `${condition.intervalInSeconds}`,
4120
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, options?.topArgs?.dkgOptions?.chain);
4121
- default:
4122
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
4123
- }
4124
- }));
4125
- // decrypt
4126
- return await lit.decrypt(scopedRawBlob, publishedList.metadata.encryptedSymmetricKey, unifiedAccessControlConditions);
4127
- })()
4128
- : await (async function () {
4129
- // transcode to base64url, if needed
4130
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
4131
- ? publishedList.StatusList2021.encodedList
4132
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
4133
- // if status list 2021 is not fetched, read from file
4134
- if (options?.statusListFile) {
4135
- // if not encrypted, return bitstring
4136
- if (!publishedList.metadata.encrypted) {
4137
- // construct encoded status list
4138
- const encoded = new vc_status_list_1.StatusList({
4139
- buffer: await Cheqd.getFile(options.statusListFile),
4140
- }).encode();
4141
- // validate against published list
4142
- if (encoded !== publishedListTranscoded)
4143
- throw new Error('[did-provider-cheqd]: check: revocation: statusListFile does not match published status list 2021');
4144
- // return encoded
4145
- return encoded;
4146
- }
4147
- // otherwise, decrypt and return bitstring
4148
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
4149
- // decrypt
4150
- const decrypted = await v2_js_1.LitProtocolV2.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
4151
- // validate against published list
4152
- if (decrypted !== publishedListTranscoded)
4153
- throw new Error('[did-provider-cheqd]: check: revocation: statusListFile does not match published status list 2021');
4154
- // return decrypted
4155
- return decrypted;
4156
- }
4157
- if (!options?.statusListInlineBitstring)
4158
- throw new Error('[did-provider-cheqd]: check: revocation: statusListInlineBitstring is required, if statusListFile is not provided');
4159
- // validate against published list
4160
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
4161
- throw new Error('[did-provider-cheqd]: check: revocation: statusListInlineBitstring does not match published status list 2021');
4162
- // otherwise, read from inline bitstring
4163
- return options?.statusListInlineBitstring;
4164
- })();
4165
- // transcode, if needed
4166
- const transcodedStatusList2021 = publishedList.metadata.encoding === 'base64url'
4167
- ? statusList2021
4168
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(statusList2021, publishedList.metadata.encoding), 'base64url');
4169
- // parse status list 2021
4170
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: transcodedStatusList2021 });
4171
- // get status by index
4172
- return !!statusList.getStatus(Number(credential.credentialStatus.statusListIndex));
4173
- }
4174
- static async checkSuspendedNonMigrated(credential, associatedStatusList, options = { fetchList: true }) {
4175
- // validate status purpose
4176
- if (credential.credentialStatus?.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension) {
4177
- throw new Error(`[did-provider-cheqd]: check: suspension: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
4178
- }
4179
- // fetch status list 2021
4180
- const publishedList = associatedStatusList ||
4181
- (await Cheqd.fetchStatusList2021(credential));
4182
- // validate migrated
4183
- if (!publishedList.metadata.encryptedSymmetricKey)
4184
- throw new Error('[did-provider-cheqd]: check: suspension: Invalid migrated status list');
4185
- // fetch status list 2021 inscribed in credential
4186
- const statusList2021 = options?.topArgs?.fetchList
4187
- ? await (async function () {
4188
- // if not encrypted, return bitstring
4189
- if (!publishedList.metadata.encrypted)
4190
- return publishedList.metadata.encoding === 'base64url'
4191
- ? publishedList.StatusList2021.encodedList
4192
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
4193
- // otherwise, decrypt and return raw bitstring
4194
- const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
4195
- // instantiate dkg-threshold client, in which case lit-protocol is used
4196
- const lit = await v2_js_1.LitProtocolV2.create({
4197
- chain: options?.topArgs?.dkgOptions?.chain,
4198
- litNetwork: v2_js_1.LitNetworksV2.serrano,
4199
- });
4200
- // construct access control conditions
4201
- const unifiedAccessControlConditions = await Promise.all(publishedList.metadata.paymentConditions.map(async (condition) => {
4202
- switch (condition.type) {
4203
- case exports.AccessControlConditionTypes.timelockPayment:
4204
- return await v6_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
4205
- key: '$.tx_responses.*.timestamp',
4206
- comparator: '<=',
4207
- value: `${condition.intervalInSeconds}`,
4208
- }, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, options?.topArgs?.dkgOptions?.chain);
4209
- default:
4210
- throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
4211
- }
4212
- }));
4213
- // decrypt
4214
- return await lit.decrypt(scopedRawBlob, publishedList.metadata.encryptedSymmetricKey, unifiedAccessControlConditions);
4215
- })()
4216
- : await (async function () {
4217
- // transcode to base64url, if needed
4218
- const publishedListTranscoded = publishedList.metadata.encoding === 'base64url'
4219
- ? publishedList.StatusList2021.encodedList
4220
- : (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
4221
- // if status list 2021 is not fetched, read from file
4222
- if (options?.statusListFile) {
4223
- // if not encrypted, return bitstring
4224
- if (!publishedList.metadata.encrypted) {
4225
- // construct encoded status list
4226
- const encoded = new vc_status_list_1.StatusList({
4227
- buffer: await Cheqd.getFile(options.statusListFile),
4228
- }).encode();
4229
- // validate against published list
4230
- if (encoded !== publishedListTranscoded)
4231
- throw new Error('[did-provider-cheqd]: check: suspension: statusListFile does not match published status list 2021');
4232
- // return encoded
4233
- return encoded;
4234
- }
4235
- // otherwise, decrypt and return bitstring
4236
- const scopedRawBlob = await (0, helpers_js_1.toBlob)(await Cheqd.getFile(options.statusListFile));
4237
- // decrypt
4238
- const decrypted = (0, uint8arrays_1.toString)(await v6_js_1.LitProtocol.decryptDirect(scopedRawBlob, await (0, helpers_js_1.safeDeserialise)(options?.topArgs?.symmetricKey, uint8arrays_1.fromString, ['hex'], 'Invalid symmetric key')), 'base64url');
4239
- // validate against published list
4240
- if (decrypted !== publishedListTranscoded)
4241
- throw new Error('[did-provider-cheqd]: check: suspension: statusListFile does not match published status list 2021');
4242
- // return decrypted
4243
- return decrypted;
4244
- }
4245
- if (!options?.statusListInlineBitstring)
4246
- throw new Error('[did-provider-cheqd]: check: suspension: statusListInlineBitstring is required, if statusListFile is not provided');
4247
- // validate against published list
4248
- if (options?.statusListInlineBitstring !== publishedListTranscoded)
4249
- throw new Error('[did-provider-cheqd]: check: suspension: statusListInlineBitstring does not match published status list 2021');
4250
- // otherwise, read from inline bitstring
4251
- return options?.statusListInlineBitstring;
4252
- })();
4253
- // parse status list 2021
4254
- const statusList = await vc_status_list_1.StatusList.decode({ encodedList: statusList2021 });
4255
- // get status by index
4256
- return !!statusList.getStatus(Number(credential.credentialStatus.statusListIndex));
4257
- }
4258
- static async publishStatusList2021(statusList2021Raw, statusList2021Metadata, options) {
4259
- // construct status list 2021 payload from previous version + new version
4260
- const payload = {
4261
- collectionId: statusList2021Metadata.resourceCollectionId,
4262
- id: options?.resourceId || (0, uuid_1.v4)(),
4263
- name: statusList2021Metadata.resourceName,
4264
- version: options?.resourceVersion || new Date().toISOString(),
4265
- alsoKnownAs: options?.resourceAlsoKnownAs || [],
4266
- resourceType: statusList2021Metadata.resourceType,
4267
- data: statusList2021Raw,
4268
- };
4269
- return await options.context.agent[exports.BroadcastStatusList2021MethodName]({
4270
- kms: (await options.context.agent.keyManagerGetKeyManagementSystems())[0],
4271
- payload,
4272
- network: statusList2021Metadata.resourceURI.split(':')[2],
4273
- signInputs: options?.signInputs,
4274
- fee: options?.fee,
4275
- });
4276
- }
4277
- static async fetchStatusList2021(credential, returnRaw = false) {
4278
- // validate credential status
4279
- if (!credential.credentialStatus)
4280
- throw new Error('[did-provider-cheqd]: fetch status list: Credential status is not present');
4281
- // validate credential status type
4282
- if (credential.credentialStatus.type !== 'StatusList2021Entry')
4283
- throw new Error('[did-provider-cheqd]: fetch status list: Credential status type is not valid');
4284
- // validate credential status list status purpose
4285
- if (credential.credentialStatus.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation &&
4286
- credential.credentialStatus.statusPurpose !== cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension)
4287
- throw new Error('[did-provider-cheqd]: fetch status list: Credential status purpose is not valid');
4288
- // fetch status list 2021
4289
- const content = (await (await fetch(credential.credentialStatus.id.split('#')[0])).json());
4290
- if (!(content.StatusList2021 &&
4291
- content.metadata &&
4292
- content.StatusList2021.encodedList &&
4293
- content.StatusList2021.statusPurpose &&
4294
- content.metadata.encoding)) {
4295
- throw new Error(`'[did-provider-cheqd]: fetch status list: Status List resource content is not valid'`);
4296
- }
4297
- // return raw if requested
4298
- if (returnRaw) {
4299
- return (0, uint8arrays_1.fromString)(content.StatusList2021.encodedList, content.metadata.encoding);
4300
- }
4301
- // otherwise, return content
4302
- return content;
4303
- }
4304
- static async fetchStatusList2021Metadata(credential) {
4305
- // get base url
4306
- const baseUrl = new URL(credential.credentialStatus.id.split('#')[0]);
4307
- // get resource name
4308
- const resourceName = baseUrl.searchParams.get('resourceName');
4309
- // get resource type
4310
- const resourceType = baseUrl.searchParams.get('resourceType');
4311
- // unset resource name
4312
- baseUrl.searchParams.delete('resourceName');
4313
- // unset resource type
4314
- baseUrl.searchParams.delete('resourceType');
4315
- // construct metadata url
4316
- const metadataUrl = `${baseUrl.toString()}/metadata`;
4317
- // fetch collection metadata
4318
- const collectionMetadata = (await (await fetch(metadataUrl)).json());
4319
- // early exit if no linked resources
4320
- if (!collectionMetadata?.contentStream?.linkedResourceMetadata)
4321
- throw new Error('[did-provider-cheqd]: fetch status list metadata: No linked resources found');
4322
- // find relevant resources by resource name
4323
- const resourceVersioning = collectionMetadata.contentStream.linkedResourceMetadata.filter((resource) => resource.resourceName === resourceName && resource.resourceType === resourceType);
4324
- // early exit if no relevant resources
4325
- if (!resourceVersioning.length || resourceVersioning.length === 0)
4326
- throw new Error(`[did-provider-cheqd]: fetch status list metadata: No relevant resources found by resource name ${resourceName}`);
4327
- // get latest resource version by nextVersionId null pointer, or by latest created date as fallback
4328
- return (resourceVersioning.find((resource) => !resource.nextVersionId) ||
4329
- resourceVersioning.sort((a, b) => new Date(b.created).getTime() - new Date(a.created).getTime())[0]);
4330
- }
4331
- static async getProviderFromDidUrl(didUrl, providers, message) {
4332
- const provider = providers.find((provider) => didUrl.includes(`${exports.DidPrefix}:${exports.CheqdDidMethod}:${provider.network}:`));
4333
- if (!provider) {
4334
- throw new Error(message ||
4335
- `[did-provider-cheqd]: no relevant providers found for did url ${didUrl}: loaded providers: ${providers.map((provider) => `${exports.DidPrefix}:${exports.CheqdDidMethod}:${provider.network}`).join(', ')}`);
4336
- }
4337
- return provider;
4338
- }
4339
- static async getProviderFromNetwork(network, providers, message) {
4340
- const provider = providers.find((provider) => provider.network === network);
4341
- if (!provider) {
4342
- throw new Error(message ||
4343
- `[did-provider-cheqd]: no relevant providers found for network ${network}: loaded providers: ${providers.map((provider) => `${exports.DidPrefix}:${exports.CheqdDidMethod}:${provider.network}`).join(', ')}`);
4344
- }
4345
- return provider;
4346
- }
4347
- static generateProviderId(namespace) {
4348
- return `${exports.DidPrefix}:${exports.CheqdDidMethod}:${namespace}`;
4349
- }
4350
- static async getFile(filename) {
4351
- if (typeof filename !== 'string') {
4352
- throw new Error('[did-provider-cheqd]: filename is required');
4353
- }
4354
- if (!fs_1.default.existsSync(filename)) {
4355
- debug(`[did-provider-cheqd]: File ${filename} not found`);
4356
- throw new Error(`[did-provider-cheqd]: File ${filename} not found`);
4357
- }
4358
- return new Promise((resolve, reject) => {
4359
- const content = fs_1.default.readFileSync(filename);
4360
- if (!content) {
4361
- reject(new Error(`[did-provider-cheqd]: File ${filename} is empty`));
4362
- }
4363
- resolve(new Uint8Array(content));
4364
- });
4365
- }
4366
- static async writeFile(content, filename) {
4367
- if (!filename) {
4368
- filename = `statusList2021-${(0, uuid_1.v4)()}`;
4369
- }
4370
- // alert if file exists
4371
- if (fs_1.default.existsSync(filename)) {
4372
- debug(`[did-provider-cheqd]: File ${filename} already exists`);
4373
- console.warn(`[did-provider-cheqd]: File ${filename} already exists. Overwriting...`);
4374
- }
4375
- return new Promise((resolve, reject) => {
4376
- fs_1.default.writeFile(filename, content, (err) => {
4377
- if (err) {
4378
- reject(new Error(`[did-provider-cheqd]: Error writing file ${filename}: reason: ${err}`));
4379
- }
4380
- resolve();
4381
- });
4382
- });
4383
- }
4384
- static async decodeCredentialJWT(jwt) {
4385
- const decodedCredential = (0, did_jwt_1.decodeJWT)(jwt);
4386
- // validate credential payload
4387
- if (!decodedCredential.payload)
4388
- throw new Error('[did-provider-cheqd]: decode jwt: decodedCredential.payload is required');
4389
- // validate credential payload vc property as VerifiableCredential
4390
- if (!decodedCredential.payload.vc)
4391
- throw new Error('[did-provider-cheqd]: decode jwt: decodedCredential.payload.vc is required');
4392
- return {
4393
- ...decodedCredential.payload.vc,
4394
- issuer: decodedCredential.payload.iss,
4395
- };
4396
- }
4397
- }
4398
- exports.Cheqd = Cheqd;
4399
- //# sourceMappingURL=ICheqd.js.map