@sphereon/ssi-sdk.vc-status-list 0.34.0 → 0.34.1-feature.SSISDK.17.bitstring.sl.7

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/dist/index.js CHANGED
@@ -15,7 +15,7 @@ var Status2021 = /* @__PURE__ */ function(Status20212) {
15
15
  }({});
16
16
 
17
17
  // src/functions.ts
18
- import { CredentialMapper as CredentialMapper3, DocumentFormat as DocumentFormat3, StatusListType as StatusListType5 } from "@sphereon/ssi-types";
18
+ import { CredentialMapper as CredentialMapper4, DocumentFormat as DocumentFormat4, StatusListType as StatusListType6 } from "@sphereon/ssi-types";
19
19
  import { checkStatus } from "@sphereon/vc-status-list";
20
20
 
21
21
  // src/utils.ts
@@ -25,7 +25,8 @@ function getAssertedStatusListType(type) {
25
25
  const assertedType = type ?? StatusListType.StatusList2021;
26
26
  if (![
27
27
  StatusListType.StatusList2021,
28
- StatusListType.OAuthStatusList
28
+ StatusListType.OAuthStatusList,
29
+ StatusListType.BitstringStatusList
29
30
  ].includes(assertedType)) {
30
31
  throw Error(`StatusList type ${assertedType} is not supported (yet)`);
31
32
  }
@@ -62,8 +63,7 @@ var ValidProofTypeMap = /* @__PURE__ */ new Map([
62
63
  StatusListType.StatusList2021,
63
64
  [
64
65
  "jwt",
65
- "lds",
66
- "EthereumEip712Signature2021"
66
+ "lds"
67
67
  ]
68
68
  ],
69
69
  [
@@ -72,6 +72,12 @@ var ValidProofTypeMap = /* @__PURE__ */ new Map([
72
72
  "jwt",
73
73
  "cbor"
74
74
  ]
75
+ ],
76
+ [
77
+ StatusListType.BitstringStatusList,
78
+ [
79
+ "lds"
80
+ ]
75
81
  ]
76
82
  ]);
77
83
  function assertValidProofType(type, proofFormat) {
@@ -214,7 +220,7 @@ var StatusList2021Implementation = class {
214
220
  encodedList: args.encodedList
215
221
  });
216
222
  const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
217
- statusList.setStatus(index, args.value);
223
+ statusList.setStatus(index, args.value !== 0);
218
224
  const newEncodedList = await statusList.encode();
219
225
  const credential = await this.createVerifiableCredential({
220
226
  id,
@@ -606,6 +612,9 @@ var OAuthStatusListImplementation = class {
606
612
  if (index < 0 || index >= statusList.statusList.length) {
607
613
  throw new Error("Status list index out of bounds");
608
614
  }
615
+ if (typeof value !== "number") {
616
+ throw new Error("Status list values should be of type number");
617
+ }
609
618
  statusList.setStatus(index, value);
610
619
  const { statusListCredential: signedCredential, encodedList } = await this.createSignedStatusList(proofFormat, context, statusList, issuer, id, expiresAt, keyRef);
611
620
  return {
@@ -633,7 +642,7 @@ var OAuthStatusListImplementation = class {
633
642
  const issuerString = typeof issuer === "string" ? issuer : issuer.id;
634
643
  const listToUpdate = StatusList4.decompressStatusList(args.encodedList, bitsPerStatus ?? DEFAULT_BITS_PER_STATUS);
635
644
  const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
636
- listToUpdate.setStatus(index, args.value ? 1 : 0);
645
+ listToUpdate.setStatus(index, args.value);
637
646
  const { statusListCredential, encodedList } = await this.createSignedStatusList(proofFormat ?? DEFAULT_PROOF_FORMAT2, context, listToUpdate, issuerString, id, expiresAt, keyRef);
638
647
  return {
639
648
  encodedList,
@@ -662,7 +671,7 @@ var OAuthStatusListImplementation = class {
662
671
  const { statusList } = proofFormat === "jwt" ? decodeStatusListJWT(statusListCredential) : decodeStatusListCWT(statusListCredential);
663
672
  const index = typeof statusListIndex === "number" ? statusListIndex : parseInt(statusListIndex);
664
673
  if (index < 0 || index >= statusList.statusList.length) {
665
- throw new Error("Status list index out of bounds");
674
+ throw new Error(`Status list index out of bounds, has ${statusList.statusList.length} items, requested ${index}`);
666
675
  }
667
676
  return statusList.getStatus(index);
668
677
  }
@@ -709,7 +718,253 @@ var OAuthStatusListImplementation = class {
709
718
  };
710
719
 
711
720
  // src/impl/StatusListFactory.ts
712
- import { StatusListType as StatusListType4 } from "@sphereon/ssi-types";
721
+ import { StatusListType as StatusListType5 } from "@sphereon/ssi-types";
722
+
723
+ // src/impl/BitstringStatusListImplementation.ts
724
+ import { CredentialMapper as CredentialMapper3, DocumentFormat as DocumentFormat3, StatusListType as StatusListType4 } from "@sphereon/ssi-types";
725
+ import { BitstreamStatusList, createStatusListCredential } from "@4sure-tech/vc-bitstring-status-lists";
726
+ var DEFAULT_LIST_LENGTH3 = 131072;
727
+ var DEFAULT_PROOF_FORMAT3 = "lds";
728
+ var DEFAULT_STATUS_PURPOSE = "revocation";
729
+ var BitstringStatusListImplementation = class {
730
+ static {
731
+ __name(this, "BitstringStatusListImplementation");
732
+ }
733
+ async createNewStatusList(args, context) {
734
+ if (!args.bitstringStatusList) {
735
+ throw new Error("BitstringStatusList options are required for type BitstringStatusList");
736
+ }
737
+ const length = args?.length ?? DEFAULT_LIST_LENGTH3;
738
+ const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT3;
739
+ assertValidProofType(StatusListType4.BitstringStatusList, proofFormat);
740
+ const veramoProofFormat = proofFormat;
741
+ const { issuer, id } = args;
742
+ const correlationId = getAssertedValue("correlationId", args.correlationId);
743
+ const { statusPurpose, bitsPerStatus, validFrom, validUntil, ttl } = args.bitstringStatusList;
744
+ const statusListCredential = await this.createVerifiableCredential({
745
+ ...args,
746
+ proofFormat: veramoProofFormat,
747
+ statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
748
+ validFrom,
749
+ validUntil,
750
+ ttl
751
+ }, context);
752
+ return {
753
+ encodedList: statusListCredential.credentialSubject.encodedList,
754
+ statusListCredential,
755
+ bitstringStatusList: {
756
+ statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
757
+ ...statusListCredential.validFrom && {
758
+ validFrom: new Date(statusListCredential.validFrom)
759
+ },
760
+ ...statusListCredential.validUntil && {
761
+ validUntil: new Date(statusListCredential.validUntil)
762
+ },
763
+ ttl,
764
+ bitsPerStatus
765
+ },
766
+ length,
767
+ type: StatusListType4.BitstringStatusList,
768
+ proofFormat,
769
+ id,
770
+ correlationId,
771
+ issuer,
772
+ statuslistContentType: this.buildContentType(proofFormat)
773
+ };
774
+ }
775
+ async updateStatusListIndex(args, context) {
776
+ if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
777
+ return Promise.reject("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListIndex)");
778
+ }
779
+ const credential = args.statusListCredential;
780
+ const uniform = CredentialMapper3.toUniformCredential(credential);
781
+ const { issuer, credentialSubject } = uniform;
782
+ const id = getAssertedValue("id", uniform.id);
783
+ const origEncodedList = getAssertedProperty("encodedList", credentialSubject);
784
+ const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
785
+ const statusList = await BitstreamStatusList.decode({
786
+ encodedList: origEncodedList,
787
+ statusSize: args.bitsPerStatus
788
+ });
789
+ statusList.setStatus(index, args.value);
790
+ const proofFormat = CredentialMapper3.detectDocumentType(credential) === DocumentFormat3.JWT ? "jwt" : "lds";
791
+ const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
792
+ const statusPurpose = getAssertedProperty("statusPurpose", credSubject);
793
+ const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : void 0;
794
+ const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : void 0;
795
+ const ttl = credSubject.ttl;
796
+ const updatedCredential = await this.createVerifiableCredential({
797
+ ...args,
798
+ id,
799
+ issuer,
800
+ statusList,
801
+ proofFormat,
802
+ statusPurpose,
803
+ ttl,
804
+ validFrom,
805
+ validUntil
806
+ }, context);
807
+ return {
808
+ statusListCredential: updatedCredential,
809
+ encodedList: updatedCredential.credentialSubject.encodedList,
810
+ bitstringStatusList: {
811
+ statusPurpose,
812
+ ...updatedCredential.validFrom && {
813
+ validFrom: new Date(updatedCredential.validFrom)
814
+ },
815
+ ...updatedCredential.validUntil && {
816
+ validUntil: new Date(updatedCredential.validUntil)
817
+ },
818
+ bitsPerStatus: args.bitsPerStatus,
819
+ ttl
820
+ },
821
+ length: statusList.getLength(),
822
+ type: StatusListType4.BitstringStatusList,
823
+ proofFormat,
824
+ id,
825
+ issuer,
826
+ statuslistContentType: this.buildContentType(proofFormat)
827
+ };
828
+ }
829
+ async updateStatusListFromEncodedList(args, context) {
830
+ if (!args.bitstringStatusList) {
831
+ throw new Error("bitstringStatusList options required for type BitstringStatusList");
832
+ }
833
+ if (args.bitstringStatusList.bitsPerStatus < 1) {
834
+ return Promise.reject("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListFromEncodedList)");
835
+ }
836
+ const { statusPurpose, bitsPerStatus, ttl, validFrom, validUntil } = args.bitstringStatusList;
837
+ const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT3;
838
+ assertValidProofType(StatusListType4.BitstringStatusList, proofFormat);
839
+ const veramoProofFormat = proofFormat;
840
+ const { issuer, id } = getAssertedValues(args);
841
+ const statusList = await BitstreamStatusList.decode({
842
+ encodedList: args.encodedList,
843
+ statusSize: bitsPerStatus
844
+ });
845
+ const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
846
+ statusList.setStatus(index, args.value);
847
+ const credential = await this.createVerifiableCredential({
848
+ id,
849
+ issuer,
850
+ statusList,
851
+ proofFormat: veramoProofFormat,
852
+ keyRef: args.keyRef,
853
+ statusPurpose,
854
+ validFrom,
855
+ validUntil,
856
+ ttl
857
+ }, context);
858
+ return {
859
+ type: StatusListType4.BitstringStatusList,
860
+ statusListCredential: credential,
861
+ encodedList: credential.credentialSubject.encodedList,
862
+ bitstringStatusList: {
863
+ statusPurpose,
864
+ bitsPerStatus,
865
+ ...credential.validFrom && {
866
+ validFrom: new Date(credential.validFrom)
867
+ },
868
+ ...credential.validUntil && {
869
+ validUntil: new Date(credential.validUntil)
870
+ },
871
+ ttl
872
+ },
873
+ length: statusList.getLength(),
874
+ proofFormat: args.proofFormat ?? "lds",
875
+ id,
876
+ issuer,
877
+ statuslistContentType: this.buildContentType(proofFormat)
878
+ };
879
+ }
880
+ async checkStatusIndex(args) {
881
+ if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
882
+ return Promise.reject("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (checkStatusIndex)");
883
+ }
884
+ const uniform = CredentialMapper3.toUniformCredential(args.statusListCredential);
885
+ const { credentialSubject } = uniform;
886
+ const encodedList = getAssertedProperty("encodedList", credentialSubject);
887
+ const statusSize = args.bitsPerStatus;
888
+ const statusList = await BitstreamStatusList.decode({
889
+ encodedList,
890
+ statusSize
891
+ });
892
+ const numIndex = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
893
+ if (statusList.getLength() <= numIndex) {
894
+ throw new Error(`Status list index out of bounds, has ${statusList.getLength()} entries, requested ${numIndex}`);
895
+ }
896
+ return statusList.getStatus(numIndex);
897
+ }
898
+ async toStatusListDetails(args) {
899
+ const { statusListPayload, bitsPerStatus } = args;
900
+ if (!bitsPerStatus || bitsPerStatus < 1) {
901
+ return Promise.reject("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (toStatusListDetails)");
902
+ }
903
+ const uniform = CredentialMapper3.toUniformCredential(statusListPayload);
904
+ const { issuer, credentialSubject } = uniform;
905
+ const id = getAssertedValue("id", uniform.id);
906
+ const encodedList = getAssertedProperty("encodedList", credentialSubject);
907
+ const proofFormat = CredentialMapper3.detectDocumentType(statusListPayload) === DocumentFormat3.JWT ? "jwt" : "lds";
908
+ const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
909
+ const statusPurpose = getAssertedProperty("statusPurpose", credSubject);
910
+ const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : void 0;
911
+ const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : void 0;
912
+ const ttl = credSubject.ttl;
913
+ const statuslistLength = BitstreamStatusList.getStatusListLength(encodedList, bitsPerStatus);
914
+ return {
915
+ id,
916
+ encodedList,
917
+ issuer,
918
+ type: StatusListType4.BitstringStatusList,
919
+ proofFormat,
920
+ length: statuslistLength,
921
+ statusListCredential: statusListPayload,
922
+ statuslistContentType: this.buildContentType(proofFormat),
923
+ bitstringStatusList: {
924
+ statusPurpose,
925
+ bitsPerStatus,
926
+ validFrom,
927
+ validUntil,
928
+ ttl
929
+ },
930
+ ...args.correlationId && {
931
+ correlationId: args.correlationId
932
+ },
933
+ ...args.driverType && {
934
+ driverType: args.driverType
935
+ }
936
+ };
937
+ }
938
+ async createVerifiableCredential(args, context) {
939
+ const identifier = await context.agent.identifierManagedGet({
940
+ identifier: typeof args.issuer === "string" ? args.issuer : args.issuer.id,
941
+ vmRelationship: "assertionMethod",
942
+ offlineWhenNoDIDRegistered: true
943
+ });
944
+ const unsignedCredential = await createStatusListCredential(args);
945
+ const verifiableCredential = await context.agent.createVerifiableCredential({
946
+ credential: unsignedCredential,
947
+ keyRef: args.keyRef ?? identifier.kmsKeyRef,
948
+ proofFormat: args.proofFormat,
949
+ fetchRemoteContexts: true
950
+ });
951
+ return CredentialMapper3.toWrappedVerifiableCredential(verifiableCredential).original;
952
+ }
953
+ buildContentType(proofFormat) {
954
+ switch (proofFormat) {
955
+ case "jwt":
956
+ return `application/statuslist+jwt`;
957
+ case "cbor":
958
+ return `application/statuslist+cwt`;
959
+ case "lds":
960
+ return "application/statuslist+ld+json";
961
+ default:
962
+ throw Error(`Unsupported content type '${proofFormat}' for status lists`);
963
+ }
964
+ }
965
+ };
966
+
967
+ // src/impl/StatusListFactory.ts
713
968
  var StatusListFactory = class _StatusListFactory {
714
969
  static {
715
970
  __name(this, "StatusListFactory");
@@ -718,8 +973,9 @@ var StatusListFactory = class _StatusListFactory {
718
973
  implementations;
719
974
  constructor() {
720
975
  this.implementations = /* @__PURE__ */ new Map();
721
- this.implementations.set(StatusListType4.StatusList2021, new StatusList2021Implementation());
722
- this.implementations.set(StatusListType4.OAuthStatusList, new OAuthStatusListImplementation());
976
+ this.implementations.set(StatusListType5.StatusList2021, new StatusList2021Implementation());
977
+ this.implementations.set(StatusListType5.OAuthStatusList, new OAuthStatusListImplementation());
978
+ this.implementations.set(StatusListType5.BitstringStatusList, new BitstringStatusListImplementation());
723
979
  }
724
980
  static getInstance() {
725
981
  if (!_StatusListFactory.instance) {
@@ -792,7 +1048,7 @@ __name(vcLibCheckStatusFunction, "vcLibCheckStatusFunction");
792
1048
  async function checkStatusForCredential(args) {
793
1049
  const verifyStatusListCredential = args.verifyStatusListCredential ?? true;
794
1050
  const verifyMatchingIssuers = args.verifyMatchingIssuers ?? true;
795
- const uniform = CredentialMapper3.toUniformCredential(args.credential);
1051
+ const uniform = CredentialMapper4.toUniformCredential(args.credential);
796
1052
  if (!("credentialStatus" in uniform) || !uniform.credentialStatus) {
797
1053
  if (args.mandatoryCredentialStatus) {
798
1054
  const error = "No credential status object found in the Verifiable Credential and it is mandatory";
@@ -807,7 +1063,7 @@ async function checkStatusForCredential(args) {
807
1063
  };
808
1064
  }
809
1065
  if ("credentialStatus" in uniform && uniform.credentialStatus) {
810
- if (uniform.credentialStatus.type === "StatusList2021Entry") {
1066
+ if (uniform.credentialStatus.type === "StatusList2021Entry" || uniform.credentialStatus.type === "BitstringStatusListEntry") {
811
1067
  return checkStatus({
812
1068
  ...args,
813
1069
  verifyStatusListCredential,
@@ -855,22 +1111,22 @@ async function updateStatusIndexFromStatusListCredential(args, context) {
855
1111
  return implementation.updateStatusListIndex(args, context);
856
1112
  }
857
1113
  __name(updateStatusIndexFromStatusListCredential, "updateStatusIndexFromStatusListCredential");
858
- async function statusListCredentialToDetails(args) {
859
- const credential = getAssertedValue("statusListCredential", args.statusListCredential);
1114
+ async function statusListCredentialToDetails({ correlationId, driverType, statusListCredential, bitsPerStatus }) {
1115
+ const credential = getAssertedValue("statusListCredential", statusListCredential);
860
1116
  let statusListType;
861
- const documentFormat = CredentialMapper3.detectDocumentType(credential);
862
- if (documentFormat === DocumentFormat3.JWT) {
1117
+ const documentFormat = CredentialMapper4.detectDocumentType(credential);
1118
+ if (documentFormat === DocumentFormat4.JWT) {
863
1119
  const [header] = credential.split(".");
864
1120
  const decodedHeader = JSON.parse(Buffer.from(header, "base64").toString());
865
1121
  if (decodedHeader.typ === "statuslist+jwt") {
866
- statusListType = StatusListType5.OAuthStatusList;
1122
+ statusListType = StatusListType6.OAuthStatusList;
867
1123
  }
868
- } else if (documentFormat === DocumentFormat3.MSO_MDOC) {
869
- statusListType = StatusListType5.OAuthStatusList;
1124
+ } else if (documentFormat === DocumentFormat4.MSO_MDOC) {
1125
+ statusListType = StatusListType6.OAuthStatusList;
870
1126
  }
871
1127
  if (!statusListType) {
872
- const uniform = CredentialMapper3.toUniformCredential(credential);
873
- const type = uniform.type.find((t) => t.includes("StatusList2021") || t.includes("OAuth2StatusList"));
1128
+ const uniform = CredentialMapper4.toUniformCredential(credential);
1129
+ const type = uniform.type.find((t) => t.includes("StatusList2021") || t.includes("OAuth2StatusList") || t.includes("BitstringStatusList"));
874
1130
  if (!type) {
875
1131
  throw new Error("Invalid status list credential type");
876
1132
  }
@@ -879,8 +1135,9 @@ async function statusListCredentialToDetails(args) {
879
1135
  const implementation = getStatusListImplementation(statusListType);
880
1136
  return await implementation.toStatusListDetails({
881
1137
  statusListPayload: credential,
882
- correlationId: args.correlationId,
883
- driverType: args.driverType
1138
+ correlationId,
1139
+ driverType,
1140
+ bitsPerStatus
884
1141
  });
885
1142
  }
886
1143
  __name(statusListCredentialToDetails, "statusListCredentialToDetails");
@@ -898,7 +1155,7 @@ async function statusList2021ToVerifiableCredential(args, context) {
898
1155
  offlineWhenNoDIDRegistered: true
899
1156
  });
900
1157
  const proofFormat = args?.proofFormat ?? "lds";
901
- assertValidProofType(StatusListType5.StatusList2021, proofFormat);
1158
+ assertValidProofType(StatusListType6.StatusList2021, proofFormat);
902
1159
  const veramoProofFormat = proofFormat;
903
1160
  const encodedList = getAssertedValue("encodedList", args.encodedList);
904
1161
  const statusPurpose = getAssertedValue("statusPurpose", args.statusPurpose);
@@ -927,7 +1184,7 @@ async function statusList2021ToVerifiableCredential(args, context) {
927
1184
  proofFormat: veramoProofFormat,
928
1185
  fetchRemoteContexts: true
929
1186
  });
930
- return CredentialMapper3.toWrappedVerifiableCredential(verifiableCredential).original;
1187
+ return CredentialMapper4.toWrappedVerifiableCredential(verifiableCredential).original;
931
1188
  }
932
1189
  __name(statusList2021ToVerifiableCredential, "statusList2021ToVerifiableCredential");
933
1190
  export {