@cheqd/did-provider-cheqd 3.5.0 → 3.6.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.
- package/build/cjs/agent/ICheqd.d.ts +98 -129
- package/build/cjs/agent/ICheqd.d.ts.map +1 -1
- package/build/cjs/agent/ICheqd.js +916 -246
- package/build/cjs/agent/ICheqd.js.map +1 -1
- package/build/cjs/did-manager/cheqd-did-provider.d.ts +14 -1
- package/build/cjs/did-manager/cheqd-did-provider.d.ts.map +1 -1
- package/build/cjs/did-manager/cheqd-did-provider.js +17 -4
- package/build/cjs/did-manager/cheqd-did-provider.js.map +1 -1
- package/build/cjs/dkg-threshold/lit-protocol.d.ts +4 -1
- package/build/cjs/dkg-threshold/lit-protocol.d.ts.map +1 -1
- package/build/cjs/dkg-threshold/lit-protocol.js +10 -0
- package/build/cjs/dkg-threshold/lit-protocol.js.map +1 -1
- package/build/esm/agent/ICheqd.d.ts +98 -129
- package/build/esm/agent/ICheqd.d.ts.map +1 -1
- package/build/esm/agent/ICheqd.js +918 -248
- package/build/esm/agent/ICheqd.js.map +1 -1
- package/build/esm/did-manager/cheqd-did-provider.d.ts +14 -1
- package/build/esm/did-manager/cheqd-did-provider.d.ts.map +1 -1
- package/build/esm/did-manager/cheqd-did-provider.js +16 -3
- package/build/esm/did-manager/cheqd-did-provider.js.map +1 -1
- package/build/esm/dkg-threshold/lit-protocol.d.ts +4 -1
- package/build/esm/dkg-threshold/lit-protocol.d.ts.map +1 -1
- package/build/esm/dkg-threshold/lit-protocol.js +10 -0
- package/build/esm/dkg-threshold/lit-protocol.js.map +1 -1
- package/build/tsconfig.cjs.tsbuildinfo +1 -1
- package/build/tsconfig.esm.tsbuildinfo +1 -1
- package/build/tsconfig.types.tsbuildinfo +1 -1
- package/build/types/agent/ICheqd.d.ts +98 -129
- package/build/types/agent/ICheqd.d.ts.map +1 -1
- package/build/types/did-manager/cheqd-did-provider.d.ts +14 -1
- package/build/types/did-manager/cheqd-did-provider.d.ts.map +1 -1
- package/build/types/dkg-threshold/lit-protocol.d.ts +4 -1
- package/build/types/dkg-threshold/lit-protocol.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/agent/ICheqd.ts +1101 -351
- package/src/did-manager/cheqd-did-provider.ts +32 -6
- package/src/dkg-threshold/lit-protocol.ts +15 -2
|
@@ -34,7 +34,6 @@ const GenerateDidDocWithLinkedResourceMethodName = 'cheqdGenerateDidDocWithLinke
|
|
|
34
34
|
const GenerateKeyPairMethodName = 'cheqdGenerateIdentityKeys';
|
|
35
35
|
const GenerateVersionIdMethodName = 'cheqdGenerateVersionId';
|
|
36
36
|
const GenerateStatusList2021MethodName = 'cheqdGenerateStatusList2021';
|
|
37
|
-
const GenerateEncryptedStatusList2021MethodName = 'cheqdGenerateEncryptedStatusList2021';
|
|
38
37
|
const IssueRevocableCredentialWithStatusList2021MethodName = 'cheqdIssueRevocableCredentialWithStatusList2021';
|
|
39
38
|
const IssueSuspendableCredentialWithStatusList2021MethodName = 'cheqdIssueSuspendableCredentialWithStatusList2021';
|
|
40
39
|
const VerifyCredentialMethodName = 'cheqdVerifyCredential';
|
|
@@ -46,8 +45,8 @@ const SuspendCredentialMethodName = 'cheqdSuspendCredential';
|
|
|
46
45
|
const SuspendCredentialsMethodName = 'cheqdSuspendCredentials';
|
|
47
46
|
const UnsuspendCredentialMethodName = 'cheqdUnsuspendCredential';
|
|
48
47
|
const UnsuspendCredentialsMethodName = 'cheqdUnsuspendCredentials';
|
|
49
|
-
const
|
|
50
|
-
const
|
|
48
|
+
const TransactSendTokensMethodName = 'cheqdTransactSendTokens';
|
|
49
|
+
const ObservePaymentConditionMethodName = 'cheqdObservePaymentCondition';
|
|
51
50
|
const DidPrefix = 'did';
|
|
52
51
|
const CheqdDidMethod = 'cheqd';
|
|
53
52
|
class Cheqd {
|
|
@@ -245,24 +244,6 @@ class Cheqd {
|
|
|
245
244
|
"type": "string"
|
|
246
245
|
}
|
|
247
246
|
},
|
|
248
|
-
"cheqdGenerateEncryptedStatusList2021": {
|
|
249
|
-
"description": "Generate a new encrypted Status List 2021",
|
|
250
|
-
"arguments": {
|
|
251
|
-
"type": "object",
|
|
252
|
-
"properties": {
|
|
253
|
-
"args": {
|
|
254
|
-
"type": "object",
|
|
255
|
-
"description": "A cheqdGenerateEncryptedStatusList2021Args object as any for extensibility"
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
|
-
"required": [
|
|
259
|
-
"args"
|
|
260
|
-
]
|
|
261
|
-
},
|
|
262
|
-
"returnType": {
|
|
263
|
-
"type": "string"
|
|
264
|
-
}
|
|
265
|
-
},
|
|
266
247
|
"cheqdIssueRevocableCredentialWithStatusList2021": {
|
|
267
248
|
"description": "Issue a revocable credential with a Status List 2021 as credential status registry",
|
|
268
249
|
"arguments": {
|
|
@@ -461,14 +442,14 @@ class Cheqd {
|
|
|
461
442
|
"type": "array"
|
|
462
443
|
}
|
|
463
444
|
},
|
|
464
|
-
"
|
|
465
|
-
"description": "
|
|
445
|
+
"cheqdTransactSendTokens": {
|
|
446
|
+
"description": "Send tokens from one account to another",
|
|
466
447
|
"arguments": {
|
|
467
448
|
"type": "object",
|
|
468
449
|
"properties": {
|
|
469
450
|
"args": {
|
|
470
451
|
"type": "object",
|
|
471
|
-
"description": "A
|
|
452
|
+
"description": "A cheqdTransactSendTokensArgs object as any for extensibility"
|
|
472
453
|
}
|
|
473
454
|
},
|
|
474
455
|
"required": [
|
|
@@ -479,14 +460,14 @@ class Cheqd {
|
|
|
479
460
|
"type": "object"
|
|
480
461
|
}
|
|
481
462
|
},
|
|
482
|
-
"
|
|
483
|
-
"description": "Observe
|
|
463
|
+
"cheqdObservePaymentCondition": {
|
|
464
|
+
"description": "Observe payment conditions for a given set of payment conditions",
|
|
484
465
|
"arguments": {
|
|
485
466
|
"type": "object",
|
|
486
467
|
"properties": {
|
|
487
468
|
"args": {
|
|
488
469
|
"type": "object",
|
|
489
|
-
"description": "
|
|
470
|
+
"description": "cheqdObservePaymentConditionArgs object as any for extensibility"
|
|
490
471
|
}
|
|
491
472
|
},
|
|
492
473
|
"required": [
|
|
@@ -525,7 +506,6 @@ class Cheqd {
|
|
|
525
506
|
[GenerateKeyPairMethodName]: this.GenerateIdentityKeys.bind(this),
|
|
526
507
|
[GenerateVersionIdMethodName]: this.GenerateVersionId.bind(this),
|
|
527
508
|
[GenerateStatusList2021MethodName]: this.GenerateStatusList2021.bind(this),
|
|
528
|
-
[GenerateEncryptedStatusList2021MethodName]: this.GenerateEncryptedStatusList2021.bind(this),
|
|
529
509
|
[IssueRevocableCredentialWithStatusList2021MethodName]: this.IssueRevocableCredentialWithStatusList2021.bind(this),
|
|
530
510
|
[IssueSuspendableCredentialWithStatusList2021MethodName]: this.IssueSuspendableCredentialWithStatusList2021.bind(this),
|
|
531
511
|
[VerifyCredentialMethodName]: this.VerifyCredentialWithStatusList2021.bind(this),
|
|
@@ -537,8 +517,8 @@ class Cheqd {
|
|
|
537
517
|
[SuspendCredentialsMethodName]: this.SuspendBulkCredentialsWithStatusList2021.bind(this),
|
|
538
518
|
[UnsuspendCredentialMethodName]: this.UnsuspendCredentialWithStatusList2021.bind(this),
|
|
539
519
|
[UnsuspendCredentialsMethodName]: this.UnsuspendBulkCredentialsWithStatusList2021.bind(this),
|
|
540
|
-
[
|
|
541
|
-
[
|
|
520
|
+
[TransactSendTokensMethodName]: this.TransactSendTokens.bind(this),
|
|
521
|
+
[ObservePaymentConditionMethodName]: this.ObservePaymentCondition.bind(this),
|
|
542
522
|
};
|
|
543
523
|
}
|
|
544
524
|
async CreateIdentifier(args, context) {
|
|
@@ -686,11 +666,11 @@ class Cheqd {
|
|
|
686
666
|
if (!args?.paymentConditions || !args?.paymentConditions?.length || !Array.isArray(args?.paymentConditions) || args?.paymentConditions.length === 0) {
|
|
687
667
|
throw new Error('[did-provider-cheqd]: paymentConditions is required');
|
|
688
668
|
}
|
|
689
|
-
if (!args?.paymentConditions?.every((condition) => condition.feePaymentAddress && condition.feePaymentAmount)) {
|
|
690
|
-
throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount');
|
|
669
|
+
if (!args?.paymentConditions?.every((condition) => condition.feePaymentAddress && condition.feePaymentAmount && condition.intervalInSeconds)) {
|
|
670
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
|
|
691
671
|
}
|
|
692
|
-
if (!args?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' && typeof condition.feePaymentAmount === 'string')) {
|
|
693
|
-
throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string');
|
|
672
|
+
if (!args?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' && typeof condition.feePaymentAmount === 'string' && typeof condition.intervalInSeconds === 'number')) {
|
|
673
|
+
throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
|
|
694
674
|
}
|
|
695
675
|
if (!args?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
|
|
696
676
|
throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
|
|
@@ -700,42 +680,111 @@ class Cheqd {
|
|
|
700
680
|
const network = args.issuerDid.split(':')[2];
|
|
701
681
|
// generate bitstring
|
|
702
682
|
const bitstring = await context.agent[GenerateStatusList2021MethodName]({ length: args?.statusListLength || Cheqd.defaultStatusList2021Length, bitstringEncoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url });
|
|
703
|
-
// construct data
|
|
683
|
+
// construct data and metadata tuple
|
|
704
684
|
const data = args.encrypted
|
|
705
|
-
? (await (async function () {
|
|
706
|
-
//
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
685
|
+
? (await (async function (that) {
|
|
686
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
687
|
+
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
688
|
+
chain: args?.dkgOptions?.chain || that.didProvider.dkgOptions.chain,
|
|
689
|
+
litNetwork: args?.dkgOptions?.network || that.didProvider.dkgOptions.network,
|
|
690
|
+
});
|
|
691
|
+
// construct access control conditions
|
|
692
|
+
const unifiedAccessControlConditions = await Promise.all(args.paymentConditions.map(async (condition) => {
|
|
693
|
+
switch (condition.type) {
|
|
694
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
695
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
696
|
+
key: '$.tx_responses.*.timestamp',
|
|
697
|
+
comparator: '<=',
|
|
698
|
+
value: `${condition.intervalInSeconds}`,
|
|
699
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, args?.dkgOptions?.chain || that.didProvider.dkgOptions.chain);
|
|
700
|
+
default:
|
|
701
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
702
|
+
}
|
|
703
|
+
}));
|
|
704
|
+
// encrypt bitstring
|
|
705
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, unifiedAccessControlConditions, true);
|
|
706
|
+
// return result tuple
|
|
710
707
|
switch (args.statusPurpose) {
|
|
711
708
|
case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation:
|
|
712
|
-
return {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
709
|
+
return [{
|
|
710
|
+
StatusList2021: {
|
|
711
|
+
statusPurpose: args.statusPurpose,
|
|
712
|
+
encodedList: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
713
|
+
validFrom: new Date().toISOString(),
|
|
714
|
+
validUntil: args?.validUntil
|
|
715
|
+
},
|
|
716
|
+
metadata: {
|
|
717
|
+
type: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.revocation,
|
|
718
|
+
encrypted: true,
|
|
719
|
+
encoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url,
|
|
720
|
+
encryptedSymmetricKey,
|
|
721
|
+
paymentConditions: args.paymentConditions
|
|
722
|
+
}
|
|
718
723
|
},
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
724
|
+
{
|
|
725
|
+
symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex'),
|
|
726
|
+
encryptedSymmetricKey,
|
|
727
|
+
encryptedString: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
723
728
|
}
|
|
724
|
-
|
|
729
|
+
];
|
|
725
730
|
case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension:
|
|
726
|
-
return {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
731
|
+
return [{
|
|
732
|
+
StatusList2021: {
|
|
733
|
+
statusPurpose: args.statusPurpose,
|
|
734
|
+
encodedList: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
735
|
+
validFrom: new Date().toISOString(),
|
|
736
|
+
validUntil: args?.validUntil
|
|
737
|
+
},
|
|
738
|
+
metadata: {
|
|
739
|
+
type: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension,
|
|
740
|
+
encrypted: true,
|
|
741
|
+
encoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url,
|
|
742
|
+
encryptedSymmetricKey,
|
|
743
|
+
paymentConditions: args.paymentConditions
|
|
744
|
+
}
|
|
732
745
|
},
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
746
|
+
{
|
|
747
|
+
symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex'),
|
|
748
|
+
encryptedSymmetricKey,
|
|
749
|
+
encryptedString: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
737
750
|
}
|
|
738
|
-
|
|
751
|
+
];
|
|
752
|
+
default:
|
|
753
|
+
throw new Error(`[did-provider-cheqd]: status purpose is not valid ${args.statusPurpose}`);
|
|
754
|
+
}
|
|
755
|
+
}(this)))
|
|
756
|
+
: (await (async function () {
|
|
757
|
+
switch (args.statusPurpose) {
|
|
758
|
+
case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.revocation:
|
|
759
|
+
return [{
|
|
760
|
+
StatusList2021: {
|
|
761
|
+
statusPurpose: args.statusPurpose,
|
|
762
|
+
encodedList: bitstring,
|
|
763
|
+
validFrom: new Date().toISOString(),
|
|
764
|
+
validUntil: args?.validUntil
|
|
765
|
+
},
|
|
766
|
+
metadata: {
|
|
767
|
+
type: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.revocation,
|
|
768
|
+
encrypted: false,
|
|
769
|
+
encoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url,
|
|
770
|
+
}
|
|
771
|
+
},
|
|
772
|
+
undefined];
|
|
773
|
+
case cheqd_did_provider_js_1.DefaultStatusList2021StatusPurposeTypes.suspension:
|
|
774
|
+
return [{
|
|
775
|
+
StatusList2021: {
|
|
776
|
+
statusPurpose: args.statusPurpose,
|
|
777
|
+
encodedList: bitstring,
|
|
778
|
+
validFrom: new Date().toISOString(),
|
|
779
|
+
validUntil: args?.validUntil
|
|
780
|
+
},
|
|
781
|
+
metadata: {
|
|
782
|
+
type: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes.suspension,
|
|
783
|
+
encrypted: false,
|
|
784
|
+
encoding: args?.statusListEncoding || cheqd_did_provider_js_1.DefaultStatusList2021Encodings.base64url,
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
undefined];
|
|
739
788
|
default:
|
|
740
789
|
throw new Error('[did-provider-cheqd]: statusPurpose is not valid');
|
|
741
790
|
}
|
|
@@ -748,13 +797,15 @@ class Cheqd {
|
|
|
748
797
|
resourceType: cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes[args.statusPurpose],
|
|
749
798
|
version: args?.resourceVersion || new Date().toISOString(),
|
|
750
799
|
alsoKnownAs: args?.alsoKnownAs || [],
|
|
751
|
-
data: (0, uint8arrays_1.fromString)(JSON.stringify(data), 'utf-8'),
|
|
800
|
+
data: (0, uint8arrays_1.fromString)(JSON.stringify(data[0]), 'utf-8'),
|
|
752
801
|
};
|
|
753
802
|
// return result
|
|
754
803
|
return {
|
|
755
804
|
created: await context.agent[BroadcastStatusList2021MethodName]({ kms: args.kms, payload, network: network }),
|
|
756
|
-
|
|
757
|
-
resourceMetadata: await Cheqd.fetchStatusList2021Metadata({ credentialStatus: { id: `${cheqd_did_resolver_js_1.resolverUrl}${args.issuerDid}?resourceName=${args.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes[args.statusPurpose]}`, type: 'StatusList2021Entry' } })
|
|
805
|
+
resource: data[0],
|
|
806
|
+
resourceMetadata: await Cheqd.fetchStatusList2021Metadata({ credentialStatus: { id: `${cheqd_did_resolver_js_1.resolverUrl}${args.issuerDid}?resourceName=${args.statusListName}&resourceType=${cheqd_did_provider_js_1.DefaultStatusList2021ResourceTypes[args.statusPurpose]}`, type: 'StatusList2021Entry' } }),
|
|
807
|
+
encrypted: args.encrypted,
|
|
808
|
+
symmetricKey: args?.returnSymmetricKey ? data[1]?.symmetricKey : undefined,
|
|
758
809
|
};
|
|
759
810
|
}
|
|
760
811
|
async BroadcastStatusList2021(args, context) {
|
|
@@ -881,54 +932,6 @@ class Cheqd {
|
|
|
881
932
|
return encoded;
|
|
882
933
|
}
|
|
883
934
|
}
|
|
884
|
-
async GenerateEncryptedStatusList2021(args, context) {
|
|
885
|
-
// validate encryptionOptions
|
|
886
|
-
if (!args.encryptionOptions) {
|
|
887
|
-
throw new Error('[did-provider-cheqd]: encryptionOptions is required');
|
|
888
|
-
}
|
|
889
|
-
// validate encryptionOptions.accessControlConditions
|
|
890
|
-
if (!args.encryptionOptions.accessControlConditions) {
|
|
891
|
-
throw new Error('[did-provider-cheqd]: encryptionOptions.accessControlConditions is required');
|
|
892
|
-
}
|
|
893
|
-
// generate status list
|
|
894
|
-
const statusList = args?.buffer
|
|
895
|
-
? new vc_status_list_1.StatusList({ buffer: args.buffer })
|
|
896
|
-
: new vc_status_list_1.StatusList({ length: args?.length || Cheqd.defaultStatusList2021Length });
|
|
897
|
-
// encode status list
|
|
898
|
-
const encoded = await statusList.encode();
|
|
899
|
-
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
900
|
-
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
901
|
-
chain: args.bootstrapOptions.chain,
|
|
902
|
-
litNetwork: args.bootstrapOptions.litNetwork,
|
|
903
|
-
});
|
|
904
|
-
// construct access control conditions
|
|
905
|
-
const unifiedAccessControlConditions = await Promise.all(args.encryptionOptions.accessControlConditions.map(async (condition) => {
|
|
906
|
-
switch (condition.type) {
|
|
907
|
-
case exports.AccessControlConditionTypes.memoNonce:
|
|
908
|
-
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionTransactionMemo({
|
|
909
|
-
key: '$.txs.*.body.memo',
|
|
910
|
-
comparator: 'contains',
|
|
911
|
-
value: condition?.specificNonce || await lit_protocol_js_1.LitProtocol.generateTxNonce(condition?.nonceFormat)
|
|
912
|
-
}, condition.amountObserved, condition.senderAddressObserved, condition.recipientAddressObserved, args.bootstrapOptions.chain);
|
|
913
|
-
case exports.AccessControlConditionTypes.balance:
|
|
914
|
-
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionBalance({
|
|
915
|
-
key: '$.balances[0].amount',
|
|
916
|
-
comparator: condition.comparator,
|
|
917
|
-
value: condition.amountObserved
|
|
918
|
-
}, args.bootstrapOptions.chain, condition.addressObserved);
|
|
919
|
-
default:
|
|
920
|
-
throw new Error(`[did-provider-cheqd]: accessControlCondition type is not supported`);
|
|
921
|
-
}
|
|
922
|
-
}));
|
|
923
|
-
// encrypt data
|
|
924
|
-
const { encryptedString, encryptedSymmetricKey } = await lit.encrypt(encoded, unifiedAccessControlConditions);
|
|
925
|
-
// return result
|
|
926
|
-
return {
|
|
927
|
-
encryptedStatusList2021: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
928
|
-
encryptedSymmetricKey,
|
|
929
|
-
unifiedAccessControlConditions
|
|
930
|
-
};
|
|
931
|
-
}
|
|
932
935
|
async IssueRevocableCredentialWithStatusList2021(args, context) {
|
|
933
936
|
// generate index
|
|
934
937
|
const statusListIndex = args.statusOptions.statusListIndex || await (0, helpers_js_1.randomFromRange)(args.statusOptions.statusListRangeStart || 0, (args.statusOptions.statusListRangeEnd || Cheqd.defaultStatusList2021Length) - 1, args.statusOptions.indexNotIn || []);
|
|
@@ -1027,6 +1030,8 @@ class Cheqd {
|
|
|
1027
1030
|
}
|
|
1028
1031
|
// if jwt credential, decode it
|
|
1029
1032
|
const credential = typeof args.credential === 'string' ? await Cheqd.decodeCredentialJWT(args.credential) : args.credential;
|
|
1033
|
+
// define dkg options, if provided
|
|
1034
|
+
args.dkgOptions ||= this.didProvider.dkgOptions;
|
|
1030
1035
|
// verify credential status
|
|
1031
1036
|
switch (credential.credentialStatus?.statusPurpose) {
|
|
1032
1037
|
case 'revocation':
|
|
@@ -1055,8 +1060,11 @@ class Cheqd {
|
|
|
1055
1060
|
if (!verificationResult.verified) {
|
|
1056
1061
|
return { verified: false, error: verificationResult.error };
|
|
1057
1062
|
}
|
|
1063
|
+
// early return if no verifiable credentials are provided
|
|
1058
1064
|
if (!args.presentation.verifiableCredential)
|
|
1059
1065
|
throw new Error('[did-provider-cheqd]: verify presentation: presentation.verifiableCredential is required');
|
|
1066
|
+
// define dkg options, if provided
|
|
1067
|
+
args.dkgOptions ||= this.didProvider.dkgOptions;
|
|
1060
1068
|
// verify credential(s) status(es)
|
|
1061
1069
|
for (let credential of args.presentation.verifiableCredential) {
|
|
1062
1070
|
// if jwt credential, decode it
|
|
@@ -1129,6 +1137,8 @@ class Cheqd {
|
|
|
1129
1137
|
throw new Error('[did-provider-cheqd]: revocation: credential is required');
|
|
1130
1138
|
// if jwt credential, decode it
|
|
1131
1139
|
const credential = typeof args.credential === 'string' ? await Cheqd.decodeCredentialJWT(args.credential) : args.credential;
|
|
1140
|
+
// define dkg options, if provided
|
|
1141
|
+
args.dkgOptions ||= this.didProvider.dkgOptions;
|
|
1132
1142
|
switch (credential.credentialStatus?.statusPurpose) {
|
|
1133
1143
|
case 'revocation':
|
|
1134
1144
|
if (await Cheqd.checkRevoked(credential, { ...args.options, topArgs: args }))
|
|
@@ -1209,6 +1219,8 @@ class Cheqd {
|
|
|
1209
1219
|
if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
|
|
1210
1220
|
throw new Error('[did-provider-cheqd]: revocation: publish requires statusListFile or statusList, if fetchList is disabled');
|
|
1211
1221
|
}
|
|
1222
|
+
// define dkg options, if provided
|
|
1223
|
+
args.dkgOptions ||= this.didProvider.dkgOptions;
|
|
1212
1224
|
// revoke credential
|
|
1213
1225
|
return await Cheqd.revokeCredential(credential, {
|
|
1214
1226
|
...args.options,
|
|
@@ -1291,6 +1303,8 @@ class Cheqd {
|
|
|
1291
1303
|
if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
|
|
1292
1304
|
throw new Error('[did-provider-cheqd]: revocation: publish requires statusListFile or statusList, if fetchList is disabled');
|
|
1293
1305
|
}
|
|
1306
|
+
// define dkg options, if provided
|
|
1307
|
+
args.dkgOptions ||= this.didProvider.dkgOptions;
|
|
1294
1308
|
// revoke credentials
|
|
1295
1309
|
return await Cheqd.revokeCredentials(credentials, {
|
|
1296
1310
|
...args.options,
|
|
@@ -1631,13 +1645,13 @@ class Cheqd {
|
|
|
1631
1645
|
}
|
|
1632
1646
|
});
|
|
1633
1647
|
}
|
|
1634
|
-
async
|
|
1648
|
+
async TransactSendTokens(args, context) {
|
|
1635
1649
|
try {
|
|
1636
1650
|
// delegate to provider
|
|
1637
1651
|
const transactionResult = await this.didProvider.transactSendTokens({
|
|
1638
1652
|
recipientAddress: args.recipientAddress,
|
|
1639
1653
|
amount: args.amount,
|
|
1640
|
-
|
|
1654
|
+
memo: args.memo,
|
|
1641
1655
|
txBytes: args.txBytes,
|
|
1642
1656
|
});
|
|
1643
1657
|
// return transaction result
|
|
@@ -1657,9 +1671,27 @@ class Cheqd {
|
|
|
1657
1671
|
};
|
|
1658
1672
|
}
|
|
1659
1673
|
}
|
|
1660
|
-
async
|
|
1661
|
-
// verify with raw unified access control
|
|
1674
|
+
async ObservePaymentCondition(args, context) {
|
|
1675
|
+
// verify with raw unified access control condition, if any
|
|
1662
1676
|
if (args?.unifiedAccessControlCondition) {
|
|
1677
|
+
// validate args - case: unifiedAccessControlCondition.chain
|
|
1678
|
+
if (!args.unifiedAccessControlCondition.chain || !Object.values(lit_protocol_js_1.LitCompatibleCosmosChains).includes(args.unifiedAccessControlCondition.chain))
|
|
1679
|
+
throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.chain is required and must be a valid Lit-compatible chain');
|
|
1680
|
+
// validate args - case: unifiedAccessControlCondition.path
|
|
1681
|
+
if (!args.unifiedAccessControlCondition.path)
|
|
1682
|
+
throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.path is required');
|
|
1683
|
+
// validate args - case: unifiedAccessControlCondition.conditionType
|
|
1684
|
+
if (args.unifiedAccessControlCondition.conditionType !== 'cosmos')
|
|
1685
|
+
throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.conditionType must be cosmos');
|
|
1686
|
+
// validate args - case: unifiedAccessControlCondition.method
|
|
1687
|
+
if (args.unifiedAccessControlCondition.method !== 'timelock')
|
|
1688
|
+
throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.method must be timelock');
|
|
1689
|
+
// validate args - case: unifiedAccessControlCondition.parameters
|
|
1690
|
+
if (!args.unifiedAccessControlCondition.parameters || !Array.isArray(args.unifiedAccessControlCondition.parameters) || args.unifiedAccessControlCondition.parameters.length === 0 || args.unifiedAccessControlCondition.parameters.length > 1)
|
|
1691
|
+
throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.parameters is required and must be an array of length 1 of type string content');
|
|
1692
|
+
// validate args - case: unifiedAccessControlCondition.returnValueTest
|
|
1693
|
+
if (!args.unifiedAccessControlCondition.returnValueTest || !args.unifiedAccessControlCondition.returnValueTest.comparator || !args.unifiedAccessControlCondition.returnValueTest.key || !args.unifiedAccessControlCondition.returnValueTest.value)
|
|
1694
|
+
throw new Error('[did-provider-cheqd]: observe: unifiedAccessControlCondition.returnValueTest is required');
|
|
1663
1695
|
try {
|
|
1664
1696
|
// define network
|
|
1665
1697
|
const network = (function () {
|
|
@@ -1672,12 +1704,39 @@ class Cheqd {
|
|
|
1672
1704
|
throw new Error(`[did-provider-cheqd]: observe: Unsupported chain: ${args.unifiedAccessControlCondition.chain}`);
|
|
1673
1705
|
}
|
|
1674
1706
|
}());
|
|
1707
|
+
// get block height url
|
|
1708
|
+
const blockHeightUrl = function () {
|
|
1709
|
+
switch (args.unifiedAccessControlCondition.parameters[0]) {
|
|
1710
|
+
case 'latest':
|
|
1711
|
+
return `${cheqd_did_provider_js_1.DefaultRESTUrls[network]}/cosmos/base/tendermint/v1beta1/blocks/latest`;
|
|
1712
|
+
default:
|
|
1713
|
+
return `${cheqd_did_provider_js_1.DefaultRESTUrls[network]}/cosmos/base/tendermint/v1beta1/blocks/${args.unifiedAccessControlCondition.parameters[0]}`;
|
|
1714
|
+
}
|
|
1715
|
+
}();
|
|
1716
|
+
// fetch block response
|
|
1717
|
+
const blockHeightResponse = await (await fetch(blockHeightUrl)).json();
|
|
1718
|
+
// get timestamp from block response
|
|
1719
|
+
const blockTimestamp = Date.parse(blockHeightResponse.block.header.time);
|
|
1675
1720
|
// construct url
|
|
1676
1721
|
const url = `${cheqd_did_provider_js_1.DefaultRESTUrls[network]}${args.unifiedAccessControlCondition.path}`;
|
|
1677
1722
|
// fetch relevant txs
|
|
1678
1723
|
const txs = await (await fetch(url)).json();
|
|
1679
|
-
// skim through txs for relevant events, in which case
|
|
1680
|
-
const meetsConditionTxIndex = txs?.
|
|
1724
|
+
// skim through txs for relevant events, in which case the transaction timestamp is within the defined interval in seconds, from the block timestamp
|
|
1725
|
+
const meetsConditionTxIndex = txs?.tx_responses?.findIndex((tx) => {
|
|
1726
|
+
// get tx timestamp
|
|
1727
|
+
const txTimestamp = Date.parse(tx.timestamp);
|
|
1728
|
+
// calculate diff in seconds
|
|
1729
|
+
const diffInSeconds = Math.floor((blockTimestamp - txTimestamp) / 1000);
|
|
1730
|
+
// return meets condition
|
|
1731
|
+
switch (args.unifiedAccessControlCondition.returnValueTest.comparator) {
|
|
1732
|
+
case '<':
|
|
1733
|
+
return diffInSeconds < parseInt(args.unifiedAccessControlCondition.returnValueTest.value);
|
|
1734
|
+
case '<=':
|
|
1735
|
+
return diffInSeconds <= parseInt(args.unifiedAccessControlCondition.returnValueTest.value);
|
|
1736
|
+
default:
|
|
1737
|
+
throw new Error(`[did-provider-cheqd]: observe: Unsupported comparator: ${args.unifiedAccessControlCondition.returnValueTest.comparator}`);
|
|
1738
|
+
}
|
|
1739
|
+
});
|
|
1681
1740
|
// define meetsCondition
|
|
1682
1741
|
const meetsCondition = (typeof meetsConditionTxIndex !== 'undefined' && meetsConditionTxIndex !== -1);
|
|
1683
1742
|
// return observation result
|
|
@@ -1699,10 +1758,6 @@ class Cheqd {
|
|
|
1699
1758
|
};
|
|
1700
1759
|
}
|
|
1701
1760
|
}
|
|
1702
|
-
// validate access control conditions components - case: senderAddress
|
|
1703
|
-
if (!args.senderAddress) {
|
|
1704
|
-
throw new Error('[did-provider-cheqd]: observation: senderAddress is required');
|
|
1705
|
-
}
|
|
1706
1761
|
// validate access control conditions components - case: recipientAddress
|
|
1707
1762
|
if (!args.recipientAddress) {
|
|
1708
1763
|
throw new Error('[did-provider-cheqd]: observation: recipientAddress is required');
|
|
@@ -1711,21 +1766,54 @@ class Cheqd {
|
|
|
1711
1766
|
if (!args.amount || !args.amount.amount || !args.amount.denom || args.amount.denom !== 'ncheq') {
|
|
1712
1767
|
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`');
|
|
1713
1768
|
}
|
|
1714
|
-
// validate access control conditions components - case:
|
|
1715
|
-
if (!args.
|
|
1716
|
-
throw new Error('[did-provider-cheqd]: observation:
|
|
1769
|
+
// validate access control conditions components - case: intervalInSeconds
|
|
1770
|
+
if (!args.intervalInSeconds) {
|
|
1771
|
+
throw new Error('[did-provider-cheqd]: observation: intervalInSeconds is required');
|
|
1772
|
+
}
|
|
1773
|
+
// validate access control conditions components - case: comparator
|
|
1774
|
+
if (!args.comparator || (args.comparator !== '<' && args.comparator !== '<=')) {
|
|
1775
|
+
throw new Error('[did-provider-cheqd]: observation: comparator is required and must be either `<` or `<=`');
|
|
1717
1776
|
}
|
|
1718
1777
|
// validate access control conditions components - case: network
|
|
1719
1778
|
if (!args.network) {
|
|
1720
1779
|
throw new Error('[did-provider-cheqd]: observation: network is required');
|
|
1721
1780
|
}
|
|
1781
|
+
// define block height, if not provided
|
|
1782
|
+
args.blockHeight ||= 'latest';
|
|
1722
1783
|
try {
|
|
1784
|
+
// get block height url
|
|
1785
|
+
const blockHeightUrl = function () {
|
|
1786
|
+
switch (args.blockHeight) {
|
|
1787
|
+
case 'latest':
|
|
1788
|
+
return `${cheqd_did_provider_js_1.DefaultRESTUrls[args.network]}/cosmos/base/tendermint/v1beta1/blocks/latest`;
|
|
1789
|
+
default:
|
|
1790
|
+
return `${cheqd_did_provider_js_1.DefaultRESTUrls[args.network]}/cosmos/base/tendermint/v1beta1/blocks/${args.blockHeight}`;
|
|
1791
|
+
}
|
|
1792
|
+
}();
|
|
1793
|
+
// fetch block response
|
|
1794
|
+
const blockHeightResponse = await (await fetch(blockHeightUrl)).json();
|
|
1795
|
+
// get timestamp from block response
|
|
1796
|
+
const blockTimestamp = Date.parse(blockHeightResponse.block.header.time);
|
|
1723
1797
|
// otherwise, construct url, as per components
|
|
1724
|
-
const url = `${cheqd_did_provider_js_1.DefaultRESTUrls[args.network]}/cosmos/tx/v1beta1/txs?events=transfer.recipient='${args.recipientAddress}'&events=transfer.
|
|
1798
|
+
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`;
|
|
1725
1799
|
// fetch relevant txs
|
|
1726
1800
|
const txs = await (await fetch(url)).json();
|
|
1727
|
-
// skim through txs for relevant events, in which case
|
|
1728
|
-
const meetsConditionTxIndex = txs?.
|
|
1801
|
+
// skim through txs for relevant events, in which case the transaction timestamp is within the defined interval in seconds, from the block timestamp
|
|
1802
|
+
const meetsConditionTxIndex = txs?.tx_responses?.findIndex((tx) => {
|
|
1803
|
+
// get tx timestamp
|
|
1804
|
+
const txTimestamp = Date.parse(tx.timestamp);
|
|
1805
|
+
// calculate diff in seconds
|
|
1806
|
+
const diffInSeconds = Math.floor((blockTimestamp - txTimestamp) / 1000);
|
|
1807
|
+
// return meets condition
|
|
1808
|
+
switch (args.comparator) {
|
|
1809
|
+
case '<':
|
|
1810
|
+
return diffInSeconds < args.intervalInSeconds;
|
|
1811
|
+
case '<=':
|
|
1812
|
+
return diffInSeconds <= args.intervalInSeconds;
|
|
1813
|
+
default:
|
|
1814
|
+
throw new Error(`[did-provider-cheqd]: observe: Unsupported comparator: ${args.unifiedAccessControlCondition.returnValueTest.comparator}`);
|
|
1815
|
+
}
|
|
1816
|
+
});
|
|
1729
1817
|
// define meetsCondition
|
|
1730
1818
|
const meetsCondition = (typeof meetsConditionTxIndex !== 'undefined' && meetsConditionTxIndex !== -1);
|
|
1731
1819
|
// return observation result
|
|
@@ -1765,8 +1853,8 @@ class Cheqd {
|
|
|
1765
1853
|
return publishedList.metadata.encoding === 'base64url'
|
|
1766
1854
|
? publishedList.StatusList2021.encodedList
|
|
1767
1855
|
: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
|
|
1768
|
-
// otherwise, decrypt and return bitstring
|
|
1769
|
-
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList,
|
|
1856
|
+
// otherwise, decrypt and return raw bitstring
|
|
1857
|
+
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
|
|
1770
1858
|
// decrypt
|
|
1771
1859
|
return await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
1772
1860
|
}())
|
|
@@ -1828,16 +1916,111 @@ class Cheqd {
|
|
|
1828
1916
|
// publish status list 2021 as new version
|
|
1829
1917
|
const scoped = topArgs.publishEncrypted
|
|
1830
1918
|
? (await async function () {
|
|
1919
|
+
// validate encoding, if provided
|
|
1920
|
+
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
1921
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list encoding');
|
|
1922
|
+
}
|
|
1923
|
+
// validate validUntil, if provided
|
|
1924
|
+
if (options?.publishOptions?.statusListValidUntil) {
|
|
1925
|
+
// validate validUntil as string
|
|
1926
|
+
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
1927
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be string)');
|
|
1928
|
+
// validate validUntil as date
|
|
1929
|
+
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
1930
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be date)');
|
|
1931
|
+
// validate validUntil as future date
|
|
1932
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
1933
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be future date)');
|
|
1934
|
+
// validate validUntil towards validFrom
|
|
1935
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
1936
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be after validFrom)');
|
|
1937
|
+
}
|
|
1938
|
+
// validate paymentConditions, if provided
|
|
1939
|
+
if (topArgs?.paymentConditions) {
|
|
1940
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress && condition.feePaymentAmount && condition.intervalInSeconds)) {
|
|
1941
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
|
|
1942
|
+
}
|
|
1943
|
+
if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' && typeof condition.feePaymentAmount === 'string' && typeof condition.intervalInSeconds === 'number')) {
|
|
1944
|
+
throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
|
|
1945
|
+
}
|
|
1946
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
|
|
1947
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
// validate dkgOptions
|
|
1951
|
+
if (!topArgs?.dkgOptions || !topArgs?.dkgOptions?.chain || !topArgs?.dkgOptions?.network) {
|
|
1952
|
+
throw new Error('[did-provider-cheqd]: dkgOptions is required');
|
|
1953
|
+
}
|
|
1831
1954
|
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
1832
1955
|
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
1833
|
-
chain:
|
|
1834
|
-
litNetwork:
|
|
1956
|
+
chain: topArgs?.dkgOptions?.chain,
|
|
1957
|
+
litNetwork: topArgs?.dkgOptions?.network
|
|
1835
1958
|
});
|
|
1836
|
-
//
|
|
1837
|
-
const
|
|
1959
|
+
// construct access control conditions and payment conditions tuple
|
|
1960
|
+
const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
|
|
1961
|
+
? (await (async function () {
|
|
1962
|
+
// define payment conditions, give precedence to top-level args
|
|
1963
|
+
const paymentConditions = topArgs?.paymentConditions || publishedList.metadata.paymentConditions;
|
|
1964
|
+
// return access control conditions and payment conditions tuple
|
|
1965
|
+
return [
|
|
1966
|
+
await Promise.all(paymentConditions.map(async (condition) => {
|
|
1967
|
+
switch (condition.type) {
|
|
1968
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
1969
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
1970
|
+
key: '$.tx_responses.*.timestamp',
|
|
1971
|
+
comparator: '<=',
|
|
1972
|
+
value: `${condition.intervalInSeconds}`,
|
|
1973
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
|
|
1974
|
+
default:
|
|
1975
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
1976
|
+
}
|
|
1977
|
+
})),
|
|
1978
|
+
paymentConditions
|
|
1979
|
+
];
|
|
1980
|
+
}()))
|
|
1981
|
+
: (await (async function () {
|
|
1982
|
+
// validate paymentConditions
|
|
1983
|
+
if (!topArgs?.paymentConditions) {
|
|
1984
|
+
throw new Error('[did-provider-cheqd]: paymentConditions is required');
|
|
1985
|
+
}
|
|
1986
|
+
// return access control conditions and payment conditions tuple
|
|
1987
|
+
return [
|
|
1988
|
+
await Promise.all(topArgs.paymentConditions.map(async (condition) => {
|
|
1989
|
+
switch (condition.type) {
|
|
1990
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
1991
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
1992
|
+
key: '$.tx_responses.*.timestamp',
|
|
1993
|
+
comparator: '<=',
|
|
1994
|
+
value: `${condition.intervalInSeconds}`,
|
|
1995
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
|
|
1996
|
+
default:
|
|
1997
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
1998
|
+
}
|
|
1999
|
+
})),
|
|
2000
|
+
topArgs.paymentConditions
|
|
2001
|
+
];
|
|
2002
|
+
}()));
|
|
2003
|
+
// encrypt bitstring
|
|
2004
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, unifiedAccessControlConditionsTuple[0], true);
|
|
2005
|
+
// define status list content
|
|
2006
|
+
const content = {
|
|
2007
|
+
StatusList2021: {
|
|
2008
|
+
statusPurpose: publishedList.StatusList2021.statusPurpose,
|
|
2009
|
+
encodedList: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
2010
|
+
validFrom: publishedList.StatusList2021.validFrom,
|
|
2011
|
+
validUntil: options?.publishOptions?.statusListValidUntil || publishedList.StatusList2021.validUntil
|
|
2012
|
+
},
|
|
2013
|
+
metadata: {
|
|
2014
|
+
type: publishedList.metadata.type,
|
|
2015
|
+
encrypted: true,
|
|
2016
|
+
encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
|
|
2017
|
+
encryptedSymmetricKey,
|
|
2018
|
+
paymentConditions: unifiedAccessControlConditionsTuple[1]
|
|
2019
|
+
}
|
|
2020
|
+
};
|
|
1838
2021
|
// return tuple of publish result and encryption relevant metadata
|
|
1839
2022
|
return [
|
|
1840
|
-
await Cheqd.publishStatusList2021(
|
|
2023
|
+
await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
|
|
1841
2024
|
{ encryptedString, encryptedSymmetricKey, symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex') }
|
|
1842
2025
|
];
|
|
1843
2026
|
}())
|
|
@@ -1892,8 +2075,6 @@ class Cheqd {
|
|
|
1892
2075
|
revoked: true,
|
|
1893
2076
|
published: topArgs?.publish ? true : undefined,
|
|
1894
2077
|
statusList: topArgs?.returnUpdatedStatusList ? await Cheqd.fetchStatusList2021(credential) : undefined,
|
|
1895
|
-
encryptedStatusList: topArgs?.returnUpdatedEncryptedStatusList ? await (0, helpers_js_1.blobToHexString)(published?.[1]?.encryptedString) : undefined,
|
|
1896
|
-
encryptedSymmetricKey: topArgs?.returnEncryptedSymmetricKey ? published?.[1]?.encryptedSymmetricKey : undefined,
|
|
1897
2078
|
symmetricKey: topArgs?.returnSymmetricKey ? published?.[1]?.symmetricKey : undefined,
|
|
1898
2079
|
resourceMetadata: topArgs?.returnStatusListMetadata ? await Cheqd.fetchStatusList2021Metadata(credential) : undefined
|
|
1899
2080
|
};
|
|
@@ -1951,8 +2132,8 @@ class Cheqd {
|
|
|
1951
2132
|
return publishedList.metadata.encoding === 'base64url'
|
|
1952
2133
|
? publishedList.StatusList2021.encodedList
|
|
1953
2134
|
: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
|
|
1954
|
-
// otherwise, decrypt and return bitstring
|
|
1955
|
-
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList,
|
|
2135
|
+
// otherwise, decrypt and return raw bitstring
|
|
2136
|
+
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
|
|
1956
2137
|
// decrypt
|
|
1957
2138
|
return await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
1958
2139
|
}())
|
|
@@ -2027,16 +2208,111 @@ class Cheqd {
|
|
|
2027
2208
|
// publish status list 2021 as new version
|
|
2028
2209
|
const scoped = topArgs.publishEncrypted
|
|
2029
2210
|
? (await async function () {
|
|
2211
|
+
// validate encoding, if provided
|
|
2212
|
+
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
2213
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list encoding');
|
|
2214
|
+
}
|
|
2215
|
+
// validate validUntil, if provided
|
|
2216
|
+
if (options?.publishOptions?.statusListValidUntil) {
|
|
2217
|
+
// validate validUntil as string
|
|
2218
|
+
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
2219
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be string)');
|
|
2220
|
+
// validate validUntil as date
|
|
2221
|
+
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
2222
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be date)');
|
|
2223
|
+
// validate validUntil as future date
|
|
2224
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
2225
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be future date)');
|
|
2226
|
+
// validate validUntil towards validFrom
|
|
2227
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
2228
|
+
throw new Error('[did-provider-cheqd]: revocation: Invalid status list validUntil (must be after validFrom)');
|
|
2229
|
+
}
|
|
2230
|
+
// validate paymentConditions, if provided
|
|
2231
|
+
if (topArgs?.paymentConditions) {
|
|
2232
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress && condition.feePaymentAmount && condition.intervalInSeconds)) {
|
|
2233
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
|
|
2234
|
+
}
|
|
2235
|
+
if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' && typeof condition.feePaymentAmount === 'string' && typeof condition.intervalInSeconds === 'number')) {
|
|
2236
|
+
throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
|
|
2237
|
+
}
|
|
2238
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
|
|
2239
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
// validate dkgOptions
|
|
2243
|
+
if (!topArgs?.dkgOptions || !topArgs?.dkgOptions?.chain || !topArgs?.dkgOptions?.network) {
|
|
2244
|
+
throw new Error('[did-provider-cheqd]: dkgOptions is required');
|
|
2245
|
+
}
|
|
2030
2246
|
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2031
2247
|
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
2032
|
-
chain:
|
|
2033
|
-
litNetwork:
|
|
2248
|
+
chain: topArgs?.dkgOptions?.chain,
|
|
2249
|
+
litNetwork: topArgs?.dkgOptions?.network
|
|
2034
2250
|
});
|
|
2035
|
-
//
|
|
2036
|
-
const
|
|
2251
|
+
// construct access control conditions and payment conditions tuple
|
|
2252
|
+
const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
|
|
2253
|
+
? (await (async function () {
|
|
2254
|
+
// define payment conditions, give precedence to top-level args
|
|
2255
|
+
const paymentConditions = topArgs?.paymentConditions || publishedList.metadata.paymentConditions;
|
|
2256
|
+
// return access control conditions and payment conditions tuple
|
|
2257
|
+
return [
|
|
2258
|
+
await Promise.all(paymentConditions.map(async (condition) => {
|
|
2259
|
+
switch (condition.type) {
|
|
2260
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
2261
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
2262
|
+
key: '$.tx_responses.*.timestamp',
|
|
2263
|
+
comparator: '<=',
|
|
2264
|
+
value: `${condition.intervalInSeconds}`,
|
|
2265
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
|
|
2266
|
+
default:
|
|
2267
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
2268
|
+
}
|
|
2269
|
+
})),
|
|
2270
|
+
paymentConditions
|
|
2271
|
+
];
|
|
2272
|
+
}()))
|
|
2273
|
+
: (await (async function () {
|
|
2274
|
+
// validate paymentConditions
|
|
2275
|
+
if (!topArgs?.paymentConditions) {
|
|
2276
|
+
throw new Error('[did-provider-cheqd]: paymentConditions is required');
|
|
2277
|
+
}
|
|
2278
|
+
// return access control conditions and payment conditions tuple
|
|
2279
|
+
return [
|
|
2280
|
+
await Promise.all(topArgs.paymentConditions.map(async (condition) => {
|
|
2281
|
+
switch (condition.type) {
|
|
2282
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
2283
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
2284
|
+
key: '$.tx_responses.*.timestamp',
|
|
2285
|
+
comparator: '<=',
|
|
2286
|
+
value: `${condition.intervalInSeconds}`,
|
|
2287
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
|
|
2288
|
+
default:
|
|
2289
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
2290
|
+
}
|
|
2291
|
+
})),
|
|
2292
|
+
topArgs.paymentConditions
|
|
2293
|
+
];
|
|
2294
|
+
}()));
|
|
2295
|
+
// encrypt bitstring
|
|
2296
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, unifiedAccessControlConditionsTuple[0], true);
|
|
2297
|
+
// define status list content
|
|
2298
|
+
const content = {
|
|
2299
|
+
StatusList2021: {
|
|
2300
|
+
statusPurpose: publishedList.StatusList2021.statusPurpose,
|
|
2301
|
+
encodedList: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
2302
|
+
validFrom: publishedList.StatusList2021.validFrom,
|
|
2303
|
+
validUntil: options?.publishOptions?.statusListValidUntil || publishedList.StatusList2021.validUntil
|
|
2304
|
+
},
|
|
2305
|
+
metadata: {
|
|
2306
|
+
type: publishedList.metadata.type,
|
|
2307
|
+
encrypted: true,
|
|
2308
|
+
encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
|
|
2309
|
+
encryptedSymmetricKey,
|
|
2310
|
+
paymentConditions: unifiedAccessControlConditionsTuple[1]
|
|
2311
|
+
}
|
|
2312
|
+
};
|
|
2037
2313
|
// return tuple of publish result and encryption relevant metadata
|
|
2038
2314
|
return [
|
|
2039
|
-
await Cheqd.publishStatusList2021(
|
|
2315
|
+
await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
|
|
2040
2316
|
{ encryptedString, encryptedSymmetricKey, symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex') }
|
|
2041
2317
|
];
|
|
2042
2318
|
}())
|
|
@@ -2091,8 +2367,6 @@ class Cheqd {
|
|
|
2091
2367
|
revoked: revoked.map((result) => result.status === 'fulfilled' ? result.value.revoked : false),
|
|
2092
2368
|
published: topArgs?.publish ? true : undefined,
|
|
2093
2369
|
statusList: topArgs?.returnUpdatedStatusList ? await Cheqd.fetchStatusList2021(credentials[0]) : undefined,
|
|
2094
|
-
encryptedStatusList: topArgs?.returnUpdatedEncryptedStatusList ? await (0, helpers_js_1.blobToHexString)(published?.[1]?.encryptedString) : undefined,
|
|
2095
|
-
encryptedSymmetricKey: topArgs?.returnEncryptedSymmetricKey ? published?.[1]?.encryptedSymmetricKey : undefined,
|
|
2096
2370
|
symmetricKey: topArgs?.returnSymmetricKey ? published?.[1]?.symmetricKey : undefined,
|
|
2097
2371
|
resourceMetadata: topArgs?.returnStatusListMetadata ? await Cheqd.fetchStatusList2021Metadata(credentials[0]) : undefined
|
|
2098
2372
|
};
|
|
@@ -2121,8 +2395,8 @@ class Cheqd {
|
|
|
2121
2395
|
return publishedList.metadata.encoding === 'base64url'
|
|
2122
2396
|
? publishedList.StatusList2021.encodedList
|
|
2123
2397
|
: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
|
|
2124
|
-
// otherwise, decrypt and return bitstring
|
|
2125
|
-
const scopedRawBlob = await (0, helpers_js_1.toBlob)(
|
|
2398
|
+
// otherwise, decrypt and return raw bitstring
|
|
2399
|
+
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
|
|
2126
2400
|
// decrypt
|
|
2127
2401
|
return await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2128
2402
|
}())
|
|
@@ -2139,7 +2413,7 @@ class Cheqd {
|
|
|
2139
2413
|
const encoded = new vc_status_list_1.StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode();
|
|
2140
2414
|
// validate against published list
|
|
2141
2415
|
if (encoded !== publishedListTranscoded)
|
|
2142
|
-
throw new Error('[did-provider-cheqd]:
|
|
2416
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListFile does not match published status list 2021');
|
|
2143
2417
|
// return encoded
|
|
2144
2418
|
return encoded;
|
|
2145
2419
|
}
|
|
@@ -2149,15 +2423,15 @@ class Cheqd {
|
|
|
2149
2423
|
const decrypted = await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2150
2424
|
// validate against published list
|
|
2151
2425
|
if (decrypted !== publishedListTranscoded)
|
|
2152
|
-
throw new Error('[did-provider-cheqd]:
|
|
2426
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListFile does not match published status list 2021');
|
|
2153
2427
|
// return decrypted
|
|
2154
2428
|
return decrypted;
|
|
2155
2429
|
}
|
|
2156
2430
|
if (!options?.statusListInlineBitstring)
|
|
2157
|
-
throw new Error('[did-provider-cheqd]:
|
|
2431
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListInlineBitstring is required, if statusListFile is not provided');
|
|
2158
2432
|
// validate against published list
|
|
2159
2433
|
if (options?.statusListInlineBitstring !== publishedListTranscoded)
|
|
2160
|
-
throw new Error('[did-provider-cheqd]:
|
|
2434
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListInlineBitstring does not match published status list 2021');
|
|
2161
2435
|
// otherwise, read from inline bitstring
|
|
2162
2436
|
return options?.statusListInlineBitstring;
|
|
2163
2437
|
}());
|
|
@@ -2184,38 +2458,133 @@ class Cheqd {
|
|
|
2184
2458
|
// publish status list 2021 as new version
|
|
2185
2459
|
const scoped = topArgs.publishEncrypted
|
|
2186
2460
|
? (await async function () {
|
|
2461
|
+
// validate encoding, if provided
|
|
2462
|
+
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
2463
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list encoding');
|
|
2464
|
+
}
|
|
2465
|
+
// validate validUntil, if provided
|
|
2466
|
+
if (options?.publishOptions?.statusListValidUntil) {
|
|
2467
|
+
// validate validUntil as string
|
|
2468
|
+
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
2469
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be string)');
|
|
2470
|
+
// validate validUntil as date
|
|
2471
|
+
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
2472
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be date)');
|
|
2473
|
+
// validate validUntil as future date
|
|
2474
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
2475
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be future date)');
|
|
2476
|
+
// validate validUntil towards validFrom
|
|
2477
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
2478
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be after validFrom)');
|
|
2479
|
+
}
|
|
2480
|
+
// validate paymentConditions, if provided
|
|
2481
|
+
if (topArgs?.paymentConditions) {
|
|
2482
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress && condition.feePaymentAmount && condition.intervalInSeconds)) {
|
|
2483
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
|
|
2484
|
+
}
|
|
2485
|
+
if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' && typeof condition.feePaymentAmount === 'string' && typeof condition.intervalInSeconds === 'number')) {
|
|
2486
|
+
throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
|
|
2487
|
+
}
|
|
2488
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
|
|
2489
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
// validate dkgOptions
|
|
2493
|
+
if (!topArgs?.dkgOptions || !topArgs?.dkgOptions?.chain || !topArgs?.dkgOptions?.network) {
|
|
2494
|
+
throw new Error('[did-provider-cheqd]: dkgOptions is required');
|
|
2495
|
+
}
|
|
2187
2496
|
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2188
2497
|
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
2189
|
-
chain:
|
|
2190
|
-
litNetwork:
|
|
2498
|
+
chain: topArgs?.dkgOptions?.chain,
|
|
2499
|
+
litNetwork: topArgs?.dkgOptions?.network
|
|
2191
2500
|
});
|
|
2192
|
-
//
|
|
2193
|
-
const
|
|
2501
|
+
// construct access control conditions and payment conditions tuple
|
|
2502
|
+
const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
|
|
2503
|
+
? (await (async function () {
|
|
2504
|
+
// define payment conditions, give precedence to top-level args
|
|
2505
|
+
const paymentConditions = topArgs?.paymentConditions || publishedList.metadata.paymentConditions;
|
|
2506
|
+
// return access control conditions and payment conditions tuple
|
|
2507
|
+
return [
|
|
2508
|
+
await Promise.all(paymentConditions.map(async (condition) => {
|
|
2509
|
+
switch (condition.type) {
|
|
2510
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
2511
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
2512
|
+
key: '$.tx_responses.*.timestamp',
|
|
2513
|
+
comparator: '<=',
|
|
2514
|
+
value: `${condition.intervalInSeconds}`,
|
|
2515
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
|
|
2516
|
+
default:
|
|
2517
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
2518
|
+
}
|
|
2519
|
+
})),
|
|
2520
|
+
paymentConditions
|
|
2521
|
+
];
|
|
2522
|
+
}()))
|
|
2523
|
+
: (await (async function () {
|
|
2524
|
+
// validate paymentConditions
|
|
2525
|
+
if (!topArgs?.paymentConditions) {
|
|
2526
|
+
throw new Error('[did-provider-cheqd]: paymentConditions is required');
|
|
2527
|
+
}
|
|
2528
|
+
// return access control conditions and payment conditions tuple
|
|
2529
|
+
return [
|
|
2530
|
+
await Promise.all(topArgs.paymentConditions.map(async (condition) => {
|
|
2531
|
+
switch (condition.type) {
|
|
2532
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
2533
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
2534
|
+
key: '$.tx_responses.*.timestamp',
|
|
2535
|
+
comparator: '<=',
|
|
2536
|
+
value: `${condition.intervalInSeconds}`,
|
|
2537
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
|
|
2538
|
+
default:
|
|
2539
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
2540
|
+
}
|
|
2541
|
+
})),
|
|
2542
|
+
topArgs.paymentConditions
|
|
2543
|
+
];
|
|
2544
|
+
}()));
|
|
2545
|
+
// encrypt bitstring
|
|
2546
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, unifiedAccessControlConditionsTuple[0], true);
|
|
2547
|
+
// define status list content
|
|
2548
|
+
const content = {
|
|
2549
|
+
StatusList2021: {
|
|
2550
|
+
statusPurpose: publishedList.StatusList2021.statusPurpose,
|
|
2551
|
+
encodedList: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
2552
|
+
validFrom: publishedList.StatusList2021.validFrom,
|
|
2553
|
+
validUntil: options?.publishOptions?.statusListValidUntil || publishedList.StatusList2021.validUntil
|
|
2554
|
+
},
|
|
2555
|
+
metadata: {
|
|
2556
|
+
type: publishedList.metadata.type,
|
|
2557
|
+
encrypted: true,
|
|
2558
|
+
encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
|
|
2559
|
+
encryptedSymmetricKey,
|
|
2560
|
+
paymentConditions: unifiedAccessControlConditionsTuple[1]
|
|
2561
|
+
}
|
|
2562
|
+
};
|
|
2194
2563
|
// return tuple of publish result and encryption relevant metadata
|
|
2195
2564
|
return [
|
|
2196
|
-
await Cheqd.publishStatusList2021(
|
|
2565
|
+
await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
|
|
2197
2566
|
{ encryptedString, encryptedSymmetricKey, symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex') }
|
|
2198
2567
|
];
|
|
2199
2568
|
}())
|
|
2200
2569
|
: (await async function () {
|
|
2201
2570
|
// validate encoding, if provided
|
|
2202
2571
|
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
2203
|
-
throw new Error('[did-provider-cheqd]:
|
|
2572
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list encoding');
|
|
2204
2573
|
}
|
|
2205
2574
|
// validate validUntil, if provided
|
|
2206
2575
|
if (options?.publishOptions?.statusListValidUntil) {
|
|
2207
2576
|
// validate validUntil as string
|
|
2208
2577
|
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
2209
|
-
throw new Error('[did-provider-cheqd]:
|
|
2578
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be string)');
|
|
2210
2579
|
// validate validUntil as date
|
|
2211
2580
|
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
2212
|
-
throw new Error('[did-provider-cheqd]:
|
|
2581
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be date)');
|
|
2213
2582
|
// validate validUntil as future date
|
|
2214
2583
|
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
2215
|
-
throw new Error('[did-provider-cheqd]:
|
|
2584
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be future date)');
|
|
2216
2585
|
// validate validUntil towards validFrom
|
|
2217
2586
|
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
2218
|
-
throw new Error('[did-provider-cheqd]:
|
|
2587
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be after validFrom)');
|
|
2219
2588
|
}
|
|
2220
2589
|
// define status list content
|
|
2221
2590
|
const content = {
|
|
@@ -2248,8 +2617,6 @@ class Cheqd {
|
|
|
2248
2617
|
suspended: true,
|
|
2249
2618
|
published: topArgs?.publish ? true : undefined,
|
|
2250
2619
|
statusList: topArgs?.returnUpdatedStatusList ? await Cheqd.fetchStatusList2021(credential) : undefined,
|
|
2251
|
-
encryptedStatusList: topArgs?.returnUpdatedEncryptedStatusList ? await (0, helpers_js_1.blobToHexString)(published?.[1]?.encryptedString) : undefined,
|
|
2252
|
-
encryptedSymmetricKey: topArgs?.returnEncryptedSymmetricKey ? published?.[1]?.encryptedSymmetricKey : undefined,
|
|
2253
2620
|
symmetricKey: topArgs?.returnSymmetricKey ? published?.[1]?.symmetricKey : undefined,
|
|
2254
2621
|
resourceMetadata: topArgs?.returnStatusListMetadata ? await Cheqd.fetchStatusList2021Metadata(credential) : undefined
|
|
2255
2622
|
};
|
|
@@ -2307,8 +2674,8 @@ class Cheqd {
|
|
|
2307
2674
|
return publishedList.metadata.encoding === 'base64url'
|
|
2308
2675
|
? publishedList.StatusList2021.encodedList
|
|
2309
2676
|
: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
|
|
2310
|
-
// otherwise, decrypt and return bitstring
|
|
2311
|
-
const scopedRawBlob = await (0, helpers_js_1.toBlob)(
|
|
2677
|
+
// otherwise, decrypt and return raw bitstring
|
|
2678
|
+
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
|
|
2312
2679
|
// decrypt
|
|
2313
2680
|
return await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2314
2681
|
}())
|
|
@@ -2325,7 +2692,7 @@ class Cheqd {
|
|
|
2325
2692
|
const encoded = new vc_status_list_1.StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode();
|
|
2326
2693
|
// validate against published list
|
|
2327
2694
|
if (encoded !== publishedListTranscoded)
|
|
2328
|
-
throw new Error('[did-provider-cheqd]:
|
|
2695
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListFile does not match published status list 2021');
|
|
2329
2696
|
// return encoded
|
|
2330
2697
|
return encoded;
|
|
2331
2698
|
}
|
|
@@ -2335,15 +2702,15 @@ class Cheqd {
|
|
|
2335
2702
|
const decrypted = await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2336
2703
|
// validate against published list
|
|
2337
2704
|
if (decrypted !== publishedListTranscoded)
|
|
2338
|
-
throw new Error('[did-provider-cheqd]:
|
|
2705
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListFile does not match published status list 2021');
|
|
2339
2706
|
// return decrypted
|
|
2340
2707
|
return decrypted;
|
|
2341
2708
|
}
|
|
2342
2709
|
if (!options?.statusListInlineBitstring)
|
|
2343
|
-
throw new Error('[did-provider-cheqd]:
|
|
2710
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListInlineBitstring is required, if statusListFile is not provided');
|
|
2344
2711
|
// validate against published list
|
|
2345
2712
|
if (options?.statusListInlineBitstring !== publishedListTranscoded)
|
|
2346
|
-
throw new Error('[did-provider-cheqd]:
|
|
2713
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListInlineBitstring does not match published status list 2021');
|
|
2347
2714
|
// otherwise, read from inline bitstring
|
|
2348
2715
|
return options?.statusListInlineBitstring;
|
|
2349
2716
|
}());
|
|
@@ -2383,38 +2750,133 @@ class Cheqd {
|
|
|
2383
2750
|
// publish status list 2021 as new version
|
|
2384
2751
|
const scoped = topArgs.publishEncrypted
|
|
2385
2752
|
? (await async function () {
|
|
2753
|
+
// validate encoding, if provided
|
|
2754
|
+
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
2755
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list encoding');
|
|
2756
|
+
}
|
|
2757
|
+
// validate validUntil, if provided
|
|
2758
|
+
if (options?.publishOptions?.statusListValidUntil) {
|
|
2759
|
+
// validate validUntil as string
|
|
2760
|
+
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
2761
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be string)');
|
|
2762
|
+
// validate validUntil as date
|
|
2763
|
+
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
2764
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be date)');
|
|
2765
|
+
// validate validUntil as future date
|
|
2766
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
2767
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be future date)');
|
|
2768
|
+
// validate validUntil towards validFrom
|
|
2769
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
2770
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be after validFrom)');
|
|
2771
|
+
}
|
|
2772
|
+
// validate paymentConditions, if provided
|
|
2773
|
+
if (topArgs?.paymentConditions) {
|
|
2774
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress && condition.feePaymentAmount && condition.intervalInSeconds)) {
|
|
2775
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
|
|
2776
|
+
}
|
|
2777
|
+
if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' && typeof condition.feePaymentAmount === 'string' && typeof condition.intervalInSeconds === 'number')) {
|
|
2778
|
+
throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
|
|
2779
|
+
}
|
|
2780
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
|
|
2781
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
// validate dkgOptions
|
|
2785
|
+
if (!topArgs?.dkgOptions || !topArgs?.dkgOptions?.chain || !topArgs?.dkgOptions?.network) {
|
|
2786
|
+
throw new Error('[did-provider-cheqd]: dkgOptions is required');
|
|
2787
|
+
}
|
|
2386
2788
|
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2387
2789
|
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
2388
|
-
chain:
|
|
2389
|
-
litNetwork:
|
|
2790
|
+
chain: topArgs?.dkgOptions?.chain,
|
|
2791
|
+
litNetwork: topArgs?.dkgOptions?.network
|
|
2390
2792
|
});
|
|
2391
|
-
//
|
|
2392
|
-
const
|
|
2793
|
+
// construct access control conditions and payment conditions tuple
|
|
2794
|
+
const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
|
|
2795
|
+
? (await (async function () {
|
|
2796
|
+
// define payment conditions, give precedence to top-level args
|
|
2797
|
+
const paymentConditions = topArgs?.paymentConditions || publishedList.metadata.paymentConditions;
|
|
2798
|
+
// return access control conditions and payment conditions tuple
|
|
2799
|
+
return [
|
|
2800
|
+
await Promise.all(paymentConditions.map(async (condition) => {
|
|
2801
|
+
switch (condition.type) {
|
|
2802
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
2803
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
2804
|
+
key: '$.tx_responses.*.timestamp',
|
|
2805
|
+
comparator: '<=',
|
|
2806
|
+
value: `${condition.intervalInSeconds}`,
|
|
2807
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
|
|
2808
|
+
default:
|
|
2809
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
2810
|
+
}
|
|
2811
|
+
})),
|
|
2812
|
+
paymentConditions
|
|
2813
|
+
];
|
|
2814
|
+
}()))
|
|
2815
|
+
: (await (async function () {
|
|
2816
|
+
// validate paymentConditions
|
|
2817
|
+
if (!topArgs?.paymentConditions) {
|
|
2818
|
+
throw new Error('[did-provider-cheqd]: paymentConditions is required');
|
|
2819
|
+
}
|
|
2820
|
+
// return access control conditions and payment conditions tuple
|
|
2821
|
+
return [
|
|
2822
|
+
await Promise.all(topArgs.paymentConditions.map(async (condition) => {
|
|
2823
|
+
switch (condition.type) {
|
|
2824
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
2825
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
2826
|
+
key: '$.tx_responses.*.timestamp',
|
|
2827
|
+
comparator: '<=',
|
|
2828
|
+
value: `${condition.intervalInSeconds}`,
|
|
2829
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
|
|
2830
|
+
default:
|
|
2831
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
2832
|
+
}
|
|
2833
|
+
})),
|
|
2834
|
+
topArgs.paymentConditions
|
|
2835
|
+
];
|
|
2836
|
+
}()));
|
|
2837
|
+
// encrypt bitstring
|
|
2838
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, unifiedAccessControlConditionsTuple[0], true);
|
|
2839
|
+
// define status list content
|
|
2840
|
+
const content = {
|
|
2841
|
+
StatusList2021: {
|
|
2842
|
+
statusPurpose: publishedList.StatusList2021.statusPurpose,
|
|
2843
|
+
encodedList: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
2844
|
+
validFrom: publishedList.StatusList2021.validFrom,
|
|
2845
|
+
validUntil: options?.publishOptions?.statusListValidUntil || publishedList.StatusList2021.validUntil
|
|
2846
|
+
},
|
|
2847
|
+
metadata: {
|
|
2848
|
+
type: publishedList.metadata.type,
|
|
2849
|
+
encrypted: true,
|
|
2850
|
+
encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
|
|
2851
|
+
encryptedSymmetricKey,
|
|
2852
|
+
paymentConditions: unifiedAccessControlConditionsTuple[1]
|
|
2853
|
+
}
|
|
2854
|
+
};
|
|
2393
2855
|
// return tuple of publish result and encryption relevant metadata
|
|
2394
2856
|
return [
|
|
2395
|
-
await Cheqd.publishStatusList2021(
|
|
2857
|
+
await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
|
|
2396
2858
|
{ encryptedString, encryptedSymmetricKey, symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex') }
|
|
2397
2859
|
];
|
|
2398
2860
|
}())
|
|
2399
2861
|
: (await async function () {
|
|
2400
2862
|
// validate encoding, if provided
|
|
2401
2863
|
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
2402
|
-
throw new Error('[did-provider-cheqd]:
|
|
2864
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list encoding');
|
|
2403
2865
|
}
|
|
2404
2866
|
// validate validUntil, if provided
|
|
2405
2867
|
if (options?.publishOptions?.statusListValidUntil) {
|
|
2406
2868
|
// validate validUntil as string
|
|
2407
2869
|
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
2408
|
-
throw new Error('[did-provider-cheqd]:
|
|
2870
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be string)');
|
|
2409
2871
|
// validate validUntil as date
|
|
2410
2872
|
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
2411
|
-
throw new Error('[did-provider-cheqd]:
|
|
2873
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be date)');
|
|
2412
2874
|
// validate validUntil as future date
|
|
2413
2875
|
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
2414
|
-
throw new Error('[did-provider-cheqd]:
|
|
2876
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be future date)');
|
|
2415
2877
|
// validate validUntil towards validFrom
|
|
2416
2878
|
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
2417
|
-
throw new Error('[did-provider-cheqd]:
|
|
2879
|
+
throw new Error('[did-provider-cheqd]: suspension: Invalid status list validUntil (must be after validFrom)');
|
|
2418
2880
|
}
|
|
2419
2881
|
// define status list content
|
|
2420
2882
|
const content = {
|
|
@@ -2447,8 +2909,6 @@ class Cheqd {
|
|
|
2447
2909
|
suspended: suspended.map((result) => result.status === 'fulfilled' ? result.value.suspended : false),
|
|
2448
2910
|
published: topArgs?.publish ? true : undefined,
|
|
2449
2911
|
statusList: topArgs?.returnUpdatedStatusList ? await Cheqd.fetchStatusList2021(credentials[0]) : undefined,
|
|
2450
|
-
encryptedStatusList: topArgs?.returnUpdatedEncryptedStatusList ? await (0, helpers_js_1.blobToHexString)(published?.[1]?.encryptedString) : undefined,
|
|
2451
|
-
encryptedSymmetricKey: topArgs?.returnEncryptedSymmetricKey ? published?.[1]?.encryptedSymmetricKey : undefined,
|
|
2452
2912
|
symmetricKey: topArgs?.returnSymmetricKey ? published?.[1]?.symmetricKey : undefined,
|
|
2453
2913
|
resourceMetadata: topArgs?.returnStatusListMetadata ? await Cheqd.fetchStatusList2021Metadata(credentials[0]) : undefined
|
|
2454
2914
|
};
|
|
@@ -2468,7 +2928,7 @@ class Cheqd {
|
|
|
2468
2928
|
const publishedList = (await Cheqd.fetchStatusList2021(credential));
|
|
2469
2929
|
// early return, if encrypted and no decryption key provided
|
|
2470
2930
|
if (publishedList.metadata.encrypted && !options?.topArgs?.symmetricKey)
|
|
2471
|
-
throw new Error('[did-provider-cheqd]:
|
|
2931
|
+
throw new Error('[did-provider-cheqd]: unsuspension: symmetricKey is required, if status list 2021 is encrypted');
|
|
2472
2932
|
// fetch status list 2021 inscribed in credential
|
|
2473
2933
|
const statusList2021 = options?.topArgs?.fetchList
|
|
2474
2934
|
? (await async function () {
|
|
@@ -2477,8 +2937,8 @@ class Cheqd {
|
|
|
2477
2937
|
return publishedList.metadata.encoding === 'base64url'
|
|
2478
2938
|
? publishedList.StatusList2021.encodedList
|
|
2479
2939
|
: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
|
|
2480
|
-
// otherwise, decrypt and return bitstring
|
|
2481
|
-
const scopedRawBlob = await (0, helpers_js_1.toBlob)(
|
|
2940
|
+
// otherwise, decrypt and return raw bitstring
|
|
2941
|
+
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
|
|
2482
2942
|
// decrypt
|
|
2483
2943
|
return await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2484
2944
|
}())
|
|
@@ -2495,7 +2955,7 @@ class Cheqd {
|
|
|
2495
2955
|
const encoded = new vc_status_list_1.StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode();
|
|
2496
2956
|
// validate against published list
|
|
2497
2957
|
if (encoded !== publishedListTranscoded)
|
|
2498
|
-
throw new Error('[did-provider-cheqd]:
|
|
2958
|
+
throw new Error('[did-provider-cheqd]: unsuspension: statusListFile does not match published status list 2021');
|
|
2499
2959
|
// return encoded
|
|
2500
2960
|
return encoded;
|
|
2501
2961
|
}
|
|
@@ -2505,15 +2965,15 @@ class Cheqd {
|
|
|
2505
2965
|
const decrypted = await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2506
2966
|
// validate against published list
|
|
2507
2967
|
if (decrypted !== publishedListTranscoded)
|
|
2508
|
-
throw new Error('[did-provider-cheqd]:
|
|
2968
|
+
throw new Error('[did-provider-cheqd]: unsuspension: statusListFile does not match published status list 2021');
|
|
2509
2969
|
// return decrypted
|
|
2510
2970
|
return decrypted;
|
|
2511
2971
|
}
|
|
2512
2972
|
if (!options?.statusListInlineBitstring)
|
|
2513
|
-
throw new Error('[did-provider-cheqd]:
|
|
2973
|
+
throw new Error('[did-provider-cheqd]: unsuspension: statusListInlineBitstring is required, if statusListFile is not provided');
|
|
2514
2974
|
// validate against published list
|
|
2515
2975
|
if (options?.statusListInlineBitstring !== publishedListTranscoded)
|
|
2516
|
-
throw new Error('[did-provider-cheqd]:
|
|
2976
|
+
throw new Error('[did-provider-cheqd]: unsuspension: statusListInlineBitstring does not match published status list 2021');
|
|
2517
2977
|
// otherwise, read from inline bitstring
|
|
2518
2978
|
return options?.statusListInlineBitstring;
|
|
2519
2979
|
}());
|
|
@@ -2540,38 +3000,133 @@ class Cheqd {
|
|
|
2540
3000
|
// publish status list 2021 as new version
|
|
2541
3001
|
const scoped = topArgs.publishEncrypted
|
|
2542
3002
|
? (await async function () {
|
|
3003
|
+
// validate encoding, if provided
|
|
3004
|
+
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
3005
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list encoding');
|
|
3006
|
+
}
|
|
3007
|
+
// validate validUntil, if provided
|
|
3008
|
+
if (options?.publishOptions?.statusListValidUntil) {
|
|
3009
|
+
// validate validUntil as string
|
|
3010
|
+
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
3011
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be string)');
|
|
3012
|
+
// validate validUntil as date
|
|
3013
|
+
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
3014
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be date)');
|
|
3015
|
+
// validate validUntil as future date
|
|
3016
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
3017
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be future date)');
|
|
3018
|
+
// validate validUntil towards validFrom
|
|
3019
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
3020
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be after validFrom)');
|
|
3021
|
+
}
|
|
3022
|
+
// validate paymentConditions, if provided
|
|
3023
|
+
if (topArgs?.paymentConditions) {
|
|
3024
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress && condition.feePaymentAmount && condition.intervalInSeconds)) {
|
|
3025
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
|
|
3026
|
+
}
|
|
3027
|
+
if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' && typeof condition.feePaymentAmount === 'string' && typeof condition.intervalInSeconds === 'number')) {
|
|
3028
|
+
throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
|
|
3029
|
+
}
|
|
3030
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
|
|
3031
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
// validate dkgOptions
|
|
3035
|
+
if (!topArgs?.dkgOptions || !topArgs?.dkgOptions?.chain || !topArgs?.dkgOptions?.network) {
|
|
3036
|
+
throw new Error('[did-provider-cheqd]: dkgOptions is required');
|
|
3037
|
+
}
|
|
2543
3038
|
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2544
3039
|
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
2545
|
-
chain:
|
|
2546
|
-
litNetwork:
|
|
3040
|
+
chain: topArgs?.dkgOptions?.chain,
|
|
3041
|
+
litNetwork: topArgs?.dkgOptions?.network
|
|
2547
3042
|
});
|
|
2548
|
-
//
|
|
2549
|
-
const
|
|
3043
|
+
// construct access control conditions and payment conditions tuple
|
|
3044
|
+
const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
|
|
3045
|
+
? (await (async function () {
|
|
3046
|
+
// define payment conditions, give precedence to top-level args
|
|
3047
|
+
const paymentConditions = topArgs?.paymentConditions || publishedList.metadata.paymentConditions;
|
|
3048
|
+
// return access control conditions and payment conditions tuple
|
|
3049
|
+
return [
|
|
3050
|
+
await Promise.all(paymentConditions.map(async (condition) => {
|
|
3051
|
+
switch (condition.type) {
|
|
3052
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
3053
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
3054
|
+
key: '$.tx_responses.*.timestamp',
|
|
3055
|
+
comparator: '<=',
|
|
3056
|
+
value: `${condition.intervalInSeconds}`,
|
|
3057
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
|
|
3058
|
+
default:
|
|
3059
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
3060
|
+
}
|
|
3061
|
+
})),
|
|
3062
|
+
paymentConditions
|
|
3063
|
+
];
|
|
3064
|
+
}()))
|
|
3065
|
+
: (await (async function () {
|
|
3066
|
+
// validate paymentConditions
|
|
3067
|
+
if (!topArgs?.paymentConditions) {
|
|
3068
|
+
throw new Error('[did-provider-cheqd]: paymentConditions is required');
|
|
3069
|
+
}
|
|
3070
|
+
// return access control conditions and payment conditions tuple
|
|
3071
|
+
return [
|
|
3072
|
+
await Promise.all(topArgs.paymentConditions.map(async (condition) => {
|
|
3073
|
+
switch (condition.type) {
|
|
3074
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
3075
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
3076
|
+
key: '$.tx_responses.*.timestamp',
|
|
3077
|
+
comparator: '<=',
|
|
3078
|
+
value: `${condition.intervalInSeconds}`,
|
|
3079
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
|
|
3080
|
+
default:
|
|
3081
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
3082
|
+
}
|
|
3083
|
+
})),
|
|
3084
|
+
topArgs.paymentConditions
|
|
3085
|
+
];
|
|
3086
|
+
}()));
|
|
3087
|
+
// encrypt bitstring
|
|
3088
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, unifiedAccessControlConditionsTuple[0], true);
|
|
3089
|
+
// define status list content
|
|
3090
|
+
const content = {
|
|
3091
|
+
StatusList2021: {
|
|
3092
|
+
statusPurpose: publishedList.StatusList2021.statusPurpose,
|
|
3093
|
+
encodedList: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
3094
|
+
validFrom: publishedList.StatusList2021.validFrom,
|
|
3095
|
+
validUntil: options?.publishOptions?.statusListValidUntil || publishedList.StatusList2021.validUntil
|
|
3096
|
+
},
|
|
3097
|
+
metadata: {
|
|
3098
|
+
type: publishedList.metadata.type,
|
|
3099
|
+
encrypted: true,
|
|
3100
|
+
encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
|
|
3101
|
+
encryptedSymmetricKey,
|
|
3102
|
+
paymentConditions: unifiedAccessControlConditionsTuple[1]
|
|
3103
|
+
}
|
|
3104
|
+
};
|
|
2550
3105
|
// return tuple of publish result and encryption relevant metadata
|
|
2551
3106
|
return [
|
|
2552
|
-
await Cheqd.publishStatusList2021(
|
|
3107
|
+
await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
|
|
2553
3108
|
{ encryptedString, encryptedSymmetricKey, symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex') }
|
|
2554
3109
|
];
|
|
2555
3110
|
}())
|
|
2556
3111
|
: (await async function () {
|
|
2557
3112
|
// validate encoding, if provided
|
|
2558
3113
|
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
2559
|
-
throw new Error('[did-provider-cheqd]:
|
|
3114
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list encoding');
|
|
2560
3115
|
}
|
|
2561
3116
|
// validate validUntil, if provided
|
|
2562
3117
|
if (options?.publishOptions?.statusListValidUntil) {
|
|
2563
3118
|
// validate validUntil as string
|
|
2564
3119
|
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
2565
|
-
throw new Error('[did-provider-cheqd]:
|
|
3120
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be string)');
|
|
2566
3121
|
// validate validUntil as date
|
|
2567
3122
|
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
2568
|
-
throw new Error('[did-provider-cheqd]:
|
|
3123
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be date)');
|
|
2569
3124
|
// validate validUntil as future date
|
|
2570
3125
|
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
2571
|
-
throw new Error('[did-provider-cheqd]:
|
|
3126
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be future date)');
|
|
2572
3127
|
// validate validUntil towards validFrom
|
|
2573
3128
|
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
2574
|
-
throw new Error('[did-provider-cheqd]:
|
|
3129
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be after validFrom)');
|
|
2575
3130
|
}
|
|
2576
3131
|
// define status list content
|
|
2577
3132
|
const content = {
|
|
@@ -2604,8 +3159,6 @@ class Cheqd {
|
|
|
2604
3159
|
unsuspended: true,
|
|
2605
3160
|
published: topArgs?.publish ? true : undefined,
|
|
2606
3161
|
statusList: topArgs?.returnUpdatedStatusList ? await Cheqd.fetchStatusList2021(credential) : undefined,
|
|
2607
|
-
encryptedStatusList: topArgs?.returnUpdatedEncryptedStatusList ? await (0, helpers_js_1.blobToHexString)(published?.[1]?.encryptedString) : undefined,
|
|
2608
|
-
encryptedSymmetricKey: topArgs?.returnEncryptedSymmetricKey ? published?.[1]?.encryptedSymmetricKey : undefined,
|
|
2609
3162
|
symmetricKey: topArgs?.returnSymmetricKey ? published?.[1]?.symmetricKey : undefined,
|
|
2610
3163
|
resourceMetadata: topArgs?.returnStatusListMetadata ? await Cheqd.fetchStatusList2021Metadata(credential) : undefined
|
|
2611
3164
|
};
|
|
@@ -2663,8 +3216,8 @@ class Cheqd {
|
|
|
2663
3216
|
return publishedList.metadata.encoding === 'base64url'
|
|
2664
3217
|
? publishedList.StatusList2021.encodedList
|
|
2665
3218
|
: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
|
|
2666
|
-
// otherwise, decrypt and return bitstring
|
|
2667
|
-
const scopedRawBlob = await (0, helpers_js_1.toBlob)(
|
|
3219
|
+
// otherwise, decrypt and return raw bitstring
|
|
3220
|
+
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
|
|
2668
3221
|
// decrypt
|
|
2669
3222
|
return await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2670
3223
|
}())
|
|
@@ -2681,7 +3234,7 @@ class Cheqd {
|
|
|
2681
3234
|
const encoded = new vc_status_list_1.StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode();
|
|
2682
3235
|
// validate against published list
|
|
2683
3236
|
if (encoded !== publishedListTranscoded)
|
|
2684
|
-
throw new Error('[did-provider-cheqd]:
|
|
3237
|
+
throw new Error('[did-provider-cheqd]: unsuspension: statusListFile does not match published status list 2021');
|
|
2685
3238
|
// return encoded
|
|
2686
3239
|
return encoded;
|
|
2687
3240
|
}
|
|
@@ -2691,15 +3244,15 @@ class Cheqd {
|
|
|
2691
3244
|
const decrypted = await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2692
3245
|
// validate against published list
|
|
2693
3246
|
if (decrypted !== publishedListTranscoded)
|
|
2694
|
-
throw new Error('[did-provider-cheqd]:
|
|
3247
|
+
throw new Error('[did-provider-cheqd]: unsuspension: statusListFile does not match published status list 2021');
|
|
2695
3248
|
// return decrypted
|
|
2696
3249
|
return decrypted;
|
|
2697
3250
|
}
|
|
2698
3251
|
if (!options?.statusListInlineBitstring)
|
|
2699
|
-
throw new Error('[did-provider-cheqd]:
|
|
3252
|
+
throw new Error('[did-provider-cheqd]: unsuspension: statusListInlineBitstring is required, if statusListFile is not provided');
|
|
2700
3253
|
// validate against published list
|
|
2701
3254
|
if (options?.statusListInlineBitstring !== publishedListTranscoded)
|
|
2702
|
-
throw new Error('[did-provider-cheqd]:
|
|
3255
|
+
throw new Error('[did-provider-cheqd]: unsuspension: statusListInlineBitstring does not match published status list 2021');
|
|
2703
3256
|
// otherwise, read from inline bitstring
|
|
2704
3257
|
return options?.statusListInlineBitstring;
|
|
2705
3258
|
}());
|
|
@@ -2739,38 +3292,133 @@ class Cheqd {
|
|
|
2739
3292
|
// publish status list 2021 as new version
|
|
2740
3293
|
const scoped = topArgs.publishEncrypted
|
|
2741
3294
|
? (await async function () {
|
|
3295
|
+
// validate encoding, if provided
|
|
3296
|
+
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
3297
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list encoding');
|
|
3298
|
+
}
|
|
3299
|
+
// validate validUntil, if provided
|
|
3300
|
+
if (options?.publishOptions?.statusListValidUntil) {
|
|
3301
|
+
// validate validUntil as string
|
|
3302
|
+
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
3303
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be string)');
|
|
3304
|
+
// validate validUntil as date
|
|
3305
|
+
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
3306
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be date)');
|
|
3307
|
+
// validate validUntil as future date
|
|
3308
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
3309
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be future date)');
|
|
3310
|
+
// validate validUntil towards validFrom
|
|
3311
|
+
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
3312
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be after validFrom)');
|
|
3313
|
+
}
|
|
3314
|
+
// validate paymentConditions, if provided
|
|
3315
|
+
if (topArgs?.paymentConditions) {
|
|
3316
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.feePaymentAddress && condition.feePaymentAmount && condition.intervalInSeconds)) {
|
|
3317
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must contain feePaymentAddress and feeAmount and intervalInSeconds');
|
|
3318
|
+
}
|
|
3319
|
+
if (!topArgs?.paymentConditions?.every((condition) => typeof condition.feePaymentAddress === 'string' && typeof condition.feePaymentAmount === 'string' && typeof condition.intervalInSeconds === 'number')) {
|
|
3320
|
+
throw new Error('[did-provider-cheqd]: feePaymentAddress and feePaymentAmount must be string and intervalInSeconds must be number');
|
|
3321
|
+
}
|
|
3322
|
+
if (!topArgs?.paymentConditions?.every((condition) => condition.type === exports.AccessControlConditionTypes.timelockPayment)) {
|
|
3323
|
+
throw new Error('[did-provider-cheqd]: paymentConditions must be of type timelockPayment');
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
// validate dkgOptions
|
|
3327
|
+
if (!topArgs?.dkgOptions || !topArgs?.dkgOptions?.chain || !topArgs?.dkgOptions?.network) {
|
|
3328
|
+
throw new Error('[did-provider-cheqd]: dkgOptions is required');
|
|
3329
|
+
}
|
|
2742
3330
|
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2743
3331
|
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
2744
|
-
chain:
|
|
2745
|
-
litNetwork:
|
|
3332
|
+
chain: topArgs?.dkgOptions?.chain,
|
|
3333
|
+
litNetwork: topArgs?.dkgOptions?.network
|
|
2746
3334
|
});
|
|
2747
|
-
//
|
|
2748
|
-
const
|
|
3335
|
+
// construct access control conditions and payment conditions tuple
|
|
3336
|
+
const unifiedAccessControlConditionsTuple = publishedList.metadata.encrypted
|
|
3337
|
+
? (await (async function () {
|
|
3338
|
+
// define payment conditions, give precedence to top-level args
|
|
3339
|
+
const paymentConditions = topArgs?.paymentConditions || publishedList.metadata.paymentConditions;
|
|
3340
|
+
// return access control conditions and payment conditions tuple
|
|
3341
|
+
return [
|
|
3342
|
+
await Promise.all(paymentConditions.map(async (condition) => {
|
|
3343
|
+
switch (condition.type) {
|
|
3344
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
3345
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
3346
|
+
key: '$.tx_responses.*.timestamp',
|
|
3347
|
+
comparator: '<=',
|
|
3348
|
+
value: `${condition.intervalInSeconds}`,
|
|
3349
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, topArgs?.dkgOptions?.chain);
|
|
3350
|
+
default:
|
|
3351
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
3352
|
+
}
|
|
3353
|
+
})),
|
|
3354
|
+
paymentConditions
|
|
3355
|
+
];
|
|
3356
|
+
}()))
|
|
3357
|
+
: (await (async function () {
|
|
3358
|
+
// validate paymentConditions
|
|
3359
|
+
if (!topArgs?.paymentConditions) {
|
|
3360
|
+
throw new Error('[did-provider-cheqd]: paymentConditions is required');
|
|
3361
|
+
}
|
|
3362
|
+
// return access control conditions and payment conditions tuple
|
|
3363
|
+
return [
|
|
3364
|
+
await Promise.all(topArgs.paymentConditions.map(async (condition) => {
|
|
3365
|
+
switch (condition.type) {
|
|
3366
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
3367
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
3368
|
+
key: '$.tx_responses.*.timestamp',
|
|
3369
|
+
comparator: '<=',
|
|
3370
|
+
value: `${condition.intervalInSeconds}`,
|
|
3371
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight);
|
|
3372
|
+
default:
|
|
3373
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
3374
|
+
}
|
|
3375
|
+
})),
|
|
3376
|
+
topArgs.paymentConditions
|
|
3377
|
+
];
|
|
3378
|
+
}()));
|
|
3379
|
+
// encrypt bitstring
|
|
3380
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, unifiedAccessControlConditionsTuple[0], true);
|
|
3381
|
+
// define status list content
|
|
3382
|
+
const content = {
|
|
3383
|
+
StatusList2021: {
|
|
3384
|
+
statusPurpose: publishedList.StatusList2021.statusPurpose,
|
|
3385
|
+
encodedList: await (0, helpers_js_1.blobToHexString)(encryptedString),
|
|
3386
|
+
validFrom: publishedList.StatusList2021.validFrom,
|
|
3387
|
+
validUntil: options?.publishOptions?.statusListValidUntil || publishedList.StatusList2021.validUntil
|
|
3388
|
+
},
|
|
3389
|
+
metadata: {
|
|
3390
|
+
type: publishedList.metadata.type,
|
|
3391
|
+
encrypted: true,
|
|
3392
|
+
encoding: options?.publishOptions?.statusListEncoding || publishedList.metadata.encoding,
|
|
3393
|
+
encryptedSymmetricKey,
|
|
3394
|
+
paymentConditions: unifiedAccessControlConditionsTuple[1]
|
|
3395
|
+
}
|
|
3396
|
+
};
|
|
2749
3397
|
// return tuple of publish result and encryption relevant metadata
|
|
2750
3398
|
return [
|
|
2751
|
-
await Cheqd.publishStatusList2021(
|
|
3399
|
+
await Cheqd.publishStatusList2021((0, uint8arrays_1.fromString)(JSON.stringify(content), 'utf-8'), statusListMetadata, options?.publishOptions),
|
|
2752
3400
|
{ encryptedString, encryptedSymmetricKey, symmetricKey: (0, uint8arrays_1.toString)(symmetricKey, 'hex') }
|
|
2753
3401
|
];
|
|
2754
3402
|
}())
|
|
2755
3403
|
: (await async function () {
|
|
2756
3404
|
// validate encoding, if provided
|
|
2757
3405
|
if (options?.publishOptions?.statusListEncoding && !Object.values(cheqd_did_provider_js_1.DefaultStatusList2021Encodings).includes(options?.publishOptions?.statusListEncoding)) {
|
|
2758
|
-
throw new Error('[did-provider-cheqd]:
|
|
3406
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list encoding');
|
|
2759
3407
|
}
|
|
2760
3408
|
// validate validUntil, if provided
|
|
2761
3409
|
if (options?.publishOptions?.statusListValidUntil) {
|
|
2762
3410
|
// validate validUntil as string
|
|
2763
3411
|
if (typeof options?.publishOptions?.statusListValidUntil !== 'string')
|
|
2764
|
-
throw new Error('[did-provider-cheqd]:
|
|
3412
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be string)');
|
|
2765
3413
|
// validate validUntil as date
|
|
2766
3414
|
if (isNaN(Date.parse(options?.publishOptions?.statusListValidUntil)))
|
|
2767
|
-
throw new Error('[did-provider-cheqd]:
|
|
3415
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be date)');
|
|
2768
3416
|
// validate validUntil as future date
|
|
2769
3417
|
if (new Date(options?.publishOptions?.statusListValidUntil) < new Date())
|
|
2770
|
-
throw new Error('[did-provider-cheqd]:
|
|
3418
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be future date)');
|
|
2771
3419
|
// validate validUntil towards validFrom
|
|
2772
3420
|
if (new Date(options?.publishOptions?.statusListValidUntil) <= new Date(publishedList.StatusList2021.validFrom))
|
|
2773
|
-
throw new Error('[did-provider-cheqd]:
|
|
3421
|
+
throw new Error('[did-provider-cheqd]: unsuspension: Invalid status list validUntil (must be after validFrom)');
|
|
2774
3422
|
}
|
|
2775
3423
|
// define status list content
|
|
2776
3424
|
const content = {
|
|
@@ -2803,8 +3451,6 @@ class Cheqd {
|
|
|
2803
3451
|
unsuspended: unsuspended.map((result) => result.status === 'fulfilled' ? result.value.unsuspended : false),
|
|
2804
3452
|
published: topArgs?.publish ? true : undefined,
|
|
2805
3453
|
statusList: topArgs?.returnUpdatedStatusList ? await Cheqd.fetchStatusList2021(credentials[0]) : undefined,
|
|
2806
|
-
encryptedStatusList: topArgs?.returnUpdatedEncryptedStatusList ? await (0, helpers_js_1.blobToHexString)(published?.[1]?.encryptedString) : undefined,
|
|
2807
|
-
encryptedSymmetricKey: topArgs?.returnEncryptedSymmetricKey ? published?.[1]?.encryptedSymmetricKey : undefined,
|
|
2808
3454
|
symmetricKey: topArgs?.returnSymmetricKey ? published?.[1]?.symmetricKey : undefined,
|
|
2809
3455
|
resourceMetadata: topArgs?.returnStatusListMetadata ? await Cheqd.fetchStatusList2021Metadata(credentials[0]) : undefined
|
|
2810
3456
|
};
|
|
@@ -2818,13 +3464,10 @@ class Cheqd {
|
|
|
2818
3464
|
static async checkRevoked(credential, options = { fetchList: true }) {
|
|
2819
3465
|
// validate status purpose
|
|
2820
3466
|
if (credential.credentialStatus?.statusPurpose !== 'revocation') {
|
|
2821
|
-
throw new Error(`[did-provider-cheqd]: revocation: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
|
|
3467
|
+
throw new Error(`[did-provider-cheqd]: check: revocation: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
|
|
2822
3468
|
}
|
|
2823
3469
|
// fetch status list 2021
|
|
2824
3470
|
const publishedList = (await Cheqd.fetchStatusList2021(credential));
|
|
2825
|
-
// early return, if encrypted and decryption key is not provided
|
|
2826
|
-
if (publishedList.metadata.encrypted && !options?.topArgs?.encryptedSymmetricKey)
|
|
2827
|
-
throw new Error('[did-provider-cheqd]: revocation: encryptedSymmetricKey is required, if status list 2021 is encrypted');
|
|
2828
3471
|
// fetch status list 2021 inscribed in credential
|
|
2829
3472
|
const statusList2021 = options?.topArgs?.fetchList
|
|
2830
3473
|
? (await async function () {
|
|
@@ -2833,15 +3476,28 @@ class Cheqd {
|
|
|
2833
3476
|
return publishedList.metadata.encoding === 'base64url'
|
|
2834
3477
|
? publishedList.StatusList2021.encodedList
|
|
2835
3478
|
: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
|
|
2836
|
-
// otherwise, decrypt and return bitstring
|
|
2837
|
-
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList,
|
|
3479
|
+
// otherwise, decrypt and return raw bitstring
|
|
3480
|
+
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
|
|
2838
3481
|
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2839
3482
|
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
2840
|
-
chain: options?.topArgs?.
|
|
2841
|
-
litNetwork: options?.topArgs?.
|
|
3483
|
+
chain: options?.topArgs?.dkgOptions?.chain,
|
|
3484
|
+
litNetwork: options?.topArgs?.dkgOptions?.network
|
|
2842
3485
|
});
|
|
3486
|
+
// construct access control conditions
|
|
3487
|
+
const unifiedAccessControlConditions = await Promise.all(publishedList.metadata.paymentConditions.map(async (condition) => {
|
|
3488
|
+
switch (condition.type) {
|
|
3489
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
3490
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
3491
|
+
key: '$.tx_responses.*.timestamp',
|
|
3492
|
+
comparator: '<=',
|
|
3493
|
+
value: `${condition.intervalInSeconds}`,
|
|
3494
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, options?.topArgs?.dkgOptions?.chain);
|
|
3495
|
+
default:
|
|
3496
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
3497
|
+
}
|
|
3498
|
+
}));
|
|
2843
3499
|
// decrypt
|
|
2844
|
-
return await lit.decrypt(scopedRawBlob,
|
|
3500
|
+
return await lit.decrypt(scopedRawBlob, publishedList.metadata.encryptedSymmetricKey, unifiedAccessControlConditions);
|
|
2845
3501
|
}())
|
|
2846
3502
|
: (await async function () {
|
|
2847
3503
|
// transcode to base64url, if needed
|
|
@@ -2856,7 +3512,7 @@ class Cheqd {
|
|
|
2856
3512
|
const encoded = new vc_status_list_1.StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode();
|
|
2857
3513
|
// validate against published list
|
|
2858
3514
|
if (encoded !== publishedListTranscoded)
|
|
2859
|
-
throw new Error('[did-provider-cheqd]: revocation: statusListFile does not match published status list 2021');
|
|
3515
|
+
throw new Error('[did-provider-cheqd]: check: revocation: statusListFile does not match published status list 2021');
|
|
2860
3516
|
// return encoded
|
|
2861
3517
|
return encoded;
|
|
2862
3518
|
}
|
|
@@ -2866,33 +3522,34 @@ class Cheqd {
|
|
|
2866
3522
|
const decrypted = await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2867
3523
|
// validate against published list
|
|
2868
3524
|
if (decrypted !== publishedListTranscoded)
|
|
2869
|
-
throw new Error('[did-provider-cheqd]: revocation: statusListFile does not match published status list 2021');
|
|
3525
|
+
throw new Error('[did-provider-cheqd]: check: revocation: statusListFile does not match published status list 2021');
|
|
2870
3526
|
// return decrypted
|
|
2871
3527
|
return decrypted;
|
|
2872
3528
|
}
|
|
2873
3529
|
if (!options?.statusListInlineBitstring)
|
|
2874
|
-
throw new Error('[did-provider-cheqd]: revocation: statusListInlineBitstring is required, if statusListFile is not provided');
|
|
3530
|
+
throw new Error('[did-provider-cheqd]: check: revocation: statusListInlineBitstring is required, if statusListFile is not provided');
|
|
2875
3531
|
// validate against published list
|
|
2876
3532
|
if (options?.statusListInlineBitstring !== publishedListTranscoded)
|
|
2877
|
-
throw new Error('[did-provider-cheqd]: revocation: statusListInlineBitstring does not match published status list 2021');
|
|
3533
|
+
throw new Error('[did-provider-cheqd]: check: revocation: statusListInlineBitstring does not match published status list 2021');
|
|
2878
3534
|
// otherwise, read from inline bitstring
|
|
2879
3535
|
return options?.statusListInlineBitstring;
|
|
2880
3536
|
}());
|
|
3537
|
+
// transcode, if needed
|
|
3538
|
+
const transcodedStatusList2021 = publishedList.metadata.encoding === 'base64url'
|
|
3539
|
+
? statusList2021
|
|
3540
|
+
: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(statusList2021, publishedList.metadata.encoding), 'base64url');
|
|
2881
3541
|
// parse status list 2021
|
|
2882
|
-
const statusList = await vc_status_list_1.StatusList.decode({ encodedList:
|
|
3542
|
+
const statusList = await vc_status_list_1.StatusList.decode({ encodedList: transcodedStatusList2021 });
|
|
2883
3543
|
// get status by index
|
|
2884
3544
|
return !!statusList.getStatus(Number(credential.credentialStatus.statusListIndex));
|
|
2885
3545
|
}
|
|
2886
3546
|
static async checkSuspended(credential, options = { fetchList: true }) {
|
|
2887
3547
|
// validate status purpose
|
|
2888
3548
|
if (credential.credentialStatus?.statusPurpose !== 'suspension') {
|
|
2889
|
-
throw new Error(`[did-provider-cheqd]: suspension: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
|
|
3549
|
+
throw new Error(`[did-provider-cheqd]: check: suspension: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`);
|
|
2890
3550
|
}
|
|
2891
3551
|
// fetch status list 2021
|
|
2892
3552
|
const publishedList = (await Cheqd.fetchStatusList2021(credential));
|
|
2893
|
-
// early return, if encrypted and decryption key is not provided
|
|
2894
|
-
if (publishedList.metadata.encrypted && !options?.topArgs?.encryptedSymmetricKey)
|
|
2895
|
-
throw new Error('[did-provider-cheqd]: revocation: encryptedSymmetricKey is required, if status list 2021 is encrypted');
|
|
2896
3553
|
// fetch status list 2021 inscribed in credential
|
|
2897
3554
|
const statusList2021 = options?.topArgs?.fetchList
|
|
2898
3555
|
? (await async function () {
|
|
@@ -2902,14 +3559,27 @@ class Cheqd {
|
|
|
2902
3559
|
? publishedList.StatusList2021.encodedList
|
|
2903
3560
|
: (0, uint8arrays_1.toString)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, publishedList.metadata.encoding), 'base64url');
|
|
2904
3561
|
// otherwise, decrypt and return bitstring
|
|
2905
|
-
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList,
|
|
3562
|
+
const scopedRawBlob = await (0, helpers_js_1.toBlob)((0, uint8arrays_1.fromString)(publishedList.StatusList2021.encodedList, 'hex'));
|
|
2906
3563
|
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2907
3564
|
const lit = await lit_protocol_js_1.LitProtocol.create({
|
|
2908
|
-
chain: options?.topArgs?.
|
|
2909
|
-
litNetwork: options?.topArgs?.
|
|
3565
|
+
chain: options?.topArgs?.dkgOptions?.chain,
|
|
3566
|
+
litNetwork: options?.topArgs?.dkgOptions?.network
|
|
2910
3567
|
});
|
|
3568
|
+
// construct access control conditions
|
|
3569
|
+
const unifiedAccessControlConditions = await Promise.all(publishedList.metadata.paymentConditions.map(async (condition) => {
|
|
3570
|
+
switch (condition.type) {
|
|
3571
|
+
case exports.AccessControlConditionTypes.timelockPayment:
|
|
3572
|
+
return await lit_protocol_js_1.LitProtocol.generateCosmosAccessControlConditionInverseTimelock({
|
|
3573
|
+
key: '$.tx_responses.*.timestamp',
|
|
3574
|
+
comparator: '<=',
|
|
3575
|
+
value: `${condition.intervalInSeconds}`,
|
|
3576
|
+
}, condition.feePaymentAmount, condition.feePaymentAddress, condition?.blockHeight, options?.topArgs?.dkgOptions?.chain);
|
|
3577
|
+
default:
|
|
3578
|
+
throw new Error(`[did-provider-cheqd]: unsupported access control condition type ${condition.type}`);
|
|
3579
|
+
}
|
|
3580
|
+
}));
|
|
2911
3581
|
// decrypt
|
|
2912
|
-
return await lit.decrypt(scopedRawBlob,
|
|
3582
|
+
return await lit.decrypt(scopedRawBlob, publishedList.metadata.encryptedSymmetricKey, unifiedAccessControlConditions);
|
|
2913
3583
|
}())
|
|
2914
3584
|
: (await async function () {
|
|
2915
3585
|
// transcode to base64url, if needed
|
|
@@ -2924,7 +3594,7 @@ class Cheqd {
|
|
|
2924
3594
|
const encoded = new vc_status_list_1.StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode();
|
|
2925
3595
|
// validate against published list
|
|
2926
3596
|
if (encoded !== publishedListTranscoded)
|
|
2927
|
-
throw new Error('[did-provider-cheqd]:
|
|
3597
|
+
throw new Error('[did-provider-cheqd]: check: suspension: statusListFile does not match published status list 2021');
|
|
2928
3598
|
// return encoded
|
|
2929
3599
|
return encoded;
|
|
2930
3600
|
}
|
|
@@ -2934,15 +3604,15 @@ class Cheqd {
|
|
|
2934
3604
|
const decrypted = await lit_protocol_js_1.LitProtocol.decryptDirect(scopedRawBlob, (0, uint8arrays_1.fromString)(options?.topArgs?.symmetricKey, 'hex'));
|
|
2935
3605
|
// validate against published list
|
|
2936
3606
|
if (decrypted !== publishedListTranscoded)
|
|
2937
|
-
throw new Error('[did-provider-cheqd]:
|
|
3607
|
+
throw new Error('[did-provider-cheqd]: check: suspension: statusListFile does not match published status list 2021');
|
|
2938
3608
|
// return decrypted
|
|
2939
3609
|
return decrypted;
|
|
2940
3610
|
}
|
|
2941
3611
|
if (!options?.statusListInlineBitstring)
|
|
2942
|
-
throw new Error('[did-provider-cheqd]:
|
|
3612
|
+
throw new Error('[did-provider-cheqd]: check: suspension: statusListInlineBitstring is required, if statusListFile is not provided');
|
|
2943
3613
|
// validate against published list
|
|
2944
3614
|
if (options?.statusListInlineBitstring !== publishedListTranscoded)
|
|
2945
|
-
throw new Error('[did-provider-cheqd]:
|
|
3615
|
+
throw new Error('[did-provider-cheqd]: check: suspension: statusListInlineBitstring does not match published status list 2021');
|
|
2946
3616
|
// otherwise, read from inline bitstring
|
|
2947
3617
|
return options?.statusListInlineBitstring;
|
|
2948
3618
|
}());
|