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

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 CredentialMapper4, DocumentFormat as DocumentFormat4, StatusListType as StatusListType6 } from "@sphereon/ssi-types";
18
+ import { CredentialMapper as CredentialMapper4, StatusListType as StatusListType6 } from "@sphereon/ssi-types";
19
19
  import { checkStatus } from "@sphereon/vc-status-list";
20
20
 
21
21
  // src/utils.ts
@@ -76,7 +76,8 @@ var ValidProofTypeMap = /* @__PURE__ */ new Map([
76
76
  [
77
77
  StatusListType.BitstringStatusList,
78
78
  [
79
- "lds"
79
+ "lds",
80
+ "vc+jwt"
80
81
  ]
81
82
  ]
82
83
  ]);
@@ -91,29 +92,50 @@ function determineStatusListType(credential) {
91
92
  const proofFormat = determineProofFormat(credential);
92
93
  switch (proofFormat) {
93
94
  case "jwt":
94
- const payload = jwtDecode(credential);
95
- const keys = Object.keys(payload);
96
- if (keys.includes("status_list")) {
97
- return StatusListType.OAuthStatusList;
98
- } else if (keys.includes("vc")) {
99
- return StatusListType.StatusList2021;
100
- }
101
- break;
95
+ return determineJwtStatusListType(credential);
102
96
  case "lds":
103
- const uniform = CredentialMapper.toUniformCredential(credential);
104
- const type = uniform.type.find((t) => {
105
- return Object.values(StatusListType).some((statusType) => t.includes(statusType));
106
- });
107
- if (!type) {
108
- throw new Error("Invalid status list credential type");
109
- }
110
- return type.replace("Credential", "");
97
+ return determineLdsStatusListType(credential);
111
98
  case "cbor":
112
99
  return StatusListType.OAuthStatusList;
100
+ default:
101
+ throw new Error("Cannot determine status list type from credential payload");
113
102
  }
114
- throw new Error("Cannot determine status list type from credential payload");
115
103
  }
116
104
  __name(determineStatusListType, "determineStatusListType");
105
+ function determineJwtStatusListType(credential) {
106
+ const payload = jwtDecode(credential);
107
+ if ("status_list" in payload) {
108
+ return StatusListType.OAuthStatusList;
109
+ }
110
+ if ("credentialSubject" in payload) {
111
+ return getStatusListTypeFromSubject(payload.credentialSubject);
112
+ }
113
+ if ("vc" in payload && "credentialSubject" in payload.vc) {
114
+ return getStatusListTypeFromSubject(payload.vc.credentialSubject);
115
+ }
116
+ throw new Error("Invalid status list credential: credentialSubject not found");
117
+ }
118
+ __name(determineJwtStatusListType, "determineJwtStatusListType");
119
+ function determineLdsStatusListType(credential) {
120
+ const uniform = CredentialMapper.toUniformCredential(credential);
121
+ const statusListType = uniform.type.find((type) => Object.values(StatusListType).some((statusType) => type.includes(statusType)));
122
+ if (!statusListType) {
123
+ throw new Error("Invalid status list credential type");
124
+ }
125
+ return statusListType.replace("Credential", "");
126
+ }
127
+ __name(determineLdsStatusListType, "determineLdsStatusListType");
128
+ function getStatusListTypeFromSubject(credentialSubject) {
129
+ switch (credentialSubject.type) {
130
+ case "StatusList2021":
131
+ return StatusListType.StatusList2021;
132
+ case "BitstringStatusList":
133
+ return StatusListType.BitstringStatusList;
134
+ default:
135
+ throw new Error(`Unknown credential subject type: ${credentialSubject.type}`);
136
+ }
137
+ }
138
+ __name(getStatusListTypeFromSubject, "getStatusListTypeFromSubject");
117
139
  function determineProofFormat(credential) {
118
140
  const type = CredentialMapper.detectDocumentType(credential);
119
141
  switch (type) {
@@ -275,46 +297,73 @@ var StatusList2021Implementation = class {
275
297
  const status = statusList.getStatus(typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex));
276
298
  return status ? Status2021.Invalid : Status2021.Valid;
277
299
  }
278
- async toStatusListDetails(args) {
279
- const { statusListPayload } = args;
280
- const uniform = CredentialMapper2.toUniformCredential(statusListPayload);
300
+ async extractCredentialDetails(credential) {
301
+ const uniform = CredentialMapper2.toUniformCredential(credential);
281
302
  const { issuer, credentialSubject } = uniform;
282
- const id = getAssertedValue("id", uniform.id);
283
- const encodedList = getAssertedProperty("encodedList", credentialSubject);
284
- const proofFormat = CredentialMapper2.detectDocumentType(statusListPayload) === DocumentFormat2.JWT ? "jwt" : "lds";
285
- const statusPurpose = getAssertedProperty("statusPurpose", credentialSubject);
286
- const indexingDirection = "rightToLeft";
287
- const list = await StatusList.decode({
288
- encodedList
289
- });
303
+ const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
290
304
  return {
291
- // Base implementation fields
292
- id,
293
- encodedList,
305
+ id: getAssertedValue("id", uniform.id),
294
306
  issuer,
295
- type: StatusListType2.StatusList2021,
296
- proofFormat,
297
- length: list.length,
298
- statusListCredential: statusListPayload,
299
- statuslistContentType: this.buildContentType(proofFormat),
300
- correlationId: args.correlationId,
301
- driverType: args.driverType,
302
- // Flattened StatusList2021-specific fields
303
- indexingDirection,
304
- statusPurpose,
305
- // Legacy nested structure for backward compatibility
306
- statusList2021: {
307
- indexingDirection,
307
+ encodedList: getAssertedProperty("encodedList", subject)
308
+ };
309
+ }
310
+ async toStatusListDetails(args) {
311
+ if ("statusListCredential" in args) {
312
+ const { statusListCredential, correlationId, driverType } = args;
313
+ const uniform = CredentialMapper2.toUniformCredential(statusListCredential);
314
+ const { issuer, credentialSubject } = uniform;
315
+ const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
316
+ const id = getAssertedValue("id", uniform.id);
317
+ const encodedList = getAssertedProperty("encodedList", subject);
318
+ const statusPurpose = getAssertedProperty("statusPurpose", subject);
319
+ const proofFormat = CredentialMapper2.detectDocumentType(statusListCredential) === DocumentFormat2.JWT ? "jwt" : "lds";
320
+ const list = await StatusList.decode({
321
+ encodedList
322
+ });
323
+ return {
324
+ id,
325
+ encodedList,
326
+ issuer,
327
+ type: StatusListType2.StatusList2021,
328
+ proofFormat,
329
+ length: list.length,
330
+ statusListCredential,
331
+ statuslistContentType: this.buildContentType(proofFormat),
332
+ correlationId,
333
+ driverType,
334
+ indexingDirection: "rightToLeft",
308
335
  statusPurpose,
309
- // Optional fields from args
310
- ...args.correlationId && {
311
- correlationId: args.correlationId
312
- },
313
- ...args.driverType && {
314
- driverType: args.driverType
336
+ statusList2021: {
337
+ indexingDirection: "rightToLeft",
338
+ statusPurpose
315
339
  }
316
- }
317
- };
340
+ };
341
+ } else {
342
+ const { extractedDetails, statusListEntity } = args;
343
+ const statusList2021Entity = statusListEntity;
344
+ const proofFormat = CredentialMapper2.detectDocumentType(statusListEntity.statusListCredential) === DocumentFormat2.JWT ? "jwt" : "lds";
345
+ const list = await StatusList.decode({
346
+ encodedList: extractedDetails.encodedList
347
+ });
348
+ return {
349
+ id: extractedDetails.id,
350
+ encodedList: extractedDetails.encodedList,
351
+ issuer: extractedDetails.issuer,
352
+ type: StatusListType2.StatusList2021,
353
+ proofFormat,
354
+ length: list.length,
355
+ statusListCredential: statusListEntity.statusListCredential,
356
+ statuslistContentType: this.buildContentType(proofFormat),
357
+ correlationId: statusListEntity.correlationId,
358
+ driverType: statusListEntity.driverType,
359
+ indexingDirection: statusList2021Entity.indexingDirection,
360
+ statusPurpose: statusList2021Entity.statusPurpose,
361
+ statusList2021: {
362
+ indexingDirection: statusList2021Entity.indexingDirection,
363
+ statusPurpose: statusList2021Entity.statusPurpose
364
+ }
365
+ };
366
+ }
318
367
  }
319
368
  async createCredentialStatus(args) {
320
369
  const { statusList, statusListIndex } = args;
@@ -716,45 +765,80 @@ var OAuthStatusListImplementation = class {
716
765
  }
717
766
  return statusList.getStatus(index);
718
767
  }
719
- async toStatusListDetails(args) {
720
- const { statusListPayload } = args;
721
- const proofFormat = determineProofFormat(statusListPayload);
722
- const decoded = proofFormat === "jwt" ? decodeStatusListJWT(statusListPayload) : decodeStatusListCWT(statusListPayload);
723
- const { statusList, issuer, id, exp } = decoded;
724
- const bitsPerStatus = statusList.getBitsPerStatus();
725
- const expiresAt = exp ? new Date(exp * 1e3) : void 0;
768
+ async extractCredentialDetails(credential) {
769
+ if (typeof credential !== "string") {
770
+ return Promise.reject("statusListCredential must be a JWT or CWT string");
771
+ }
772
+ const proofFormat = determineProofFormat(credential);
773
+ const decoded = proofFormat === "jwt" ? decodeStatusListJWT(credential) : decodeStatusListCWT(credential);
726
774
  return {
727
- // Base implementation fields
728
- id,
729
- encodedList: statusList.compressStatusList(),
730
- issuer,
731
- type: StatusListType3.OAuthStatusList,
732
- proofFormat,
733
- length: statusList.statusList.length,
734
- statusListCredential: statusListPayload,
735
- statuslistContentType: this.buildContentType(proofFormat),
736
- correlationId: args.correlationId,
737
- driverType: args.driverType,
738
- // Flattened OAuth-specific fields
739
- bitsPerStatus,
740
- ...expiresAt && {
741
- expiresAt
742
- },
743
- // Legacy nested structure for backward compatibility
744
- oauthStatusList: {
775
+ id: decoded.id,
776
+ issuer: decoded.issuer,
777
+ encodedList: decoded.statusList.compressStatusList(),
778
+ decodedPayload: decoded
779
+ };
780
+ }
781
+ async toStatusListDetails(args) {
782
+ if ("statusListCredential" in args) {
783
+ const { statusListCredential, bitsPerStatus, correlationId, driverType } = args;
784
+ if (!bitsPerStatus || bitsPerStatus < 1) {
785
+ return Promise.reject(Error("bitsPerStatus must be set for OAuth status lists and must be 1 or higher"));
786
+ }
787
+ const proofFormat = determineProofFormat(statusListCredential);
788
+ const decoded = proofFormat === "jwt" ? decodeStatusListJWT(statusListCredential) : decodeStatusListCWT(statusListCredential);
789
+ const { statusList, issuer, id, exp } = decoded;
790
+ const expiresAt = exp ? new Date(exp * 1e3) : void 0;
791
+ return {
792
+ id,
793
+ encodedList: statusList.compressStatusList(),
794
+ issuer,
795
+ type: StatusListType3.OAuthStatusList,
796
+ proofFormat,
797
+ length: statusList.statusList.length,
798
+ statusListCredential,
799
+ statuslistContentType: this.buildContentType(proofFormat),
800
+ correlationId,
801
+ driverType,
745
802
  bitsPerStatus,
746
803
  ...expiresAt && {
747
804
  expiresAt
805
+ },
806
+ oauthStatusList: {
807
+ bitsPerStatus,
808
+ ...expiresAt && {
809
+ expiresAt
810
+ }
748
811
  }
749
- },
750
- // Optional fields from args
751
- ...args.correlationId && {
752
- correlationId: args.correlationId
753
- },
754
- ...args.driverType && {
755
- driverType: args.driverType
756
- }
757
- };
812
+ };
813
+ } else {
814
+ const { extractedDetails, statusListEntity } = args;
815
+ const oauthEntity = statusListEntity;
816
+ const decoded = extractedDetails.decodedPayload;
817
+ const proofFormat = determineProofFormat(statusListEntity.statusListCredential);
818
+ const expiresAt = decoded.exp ? new Date(decoded.exp * 1e3) : void 0;
819
+ return {
820
+ id: extractedDetails.id,
821
+ encodedList: extractedDetails.encodedList,
822
+ issuer: extractedDetails.issuer,
823
+ type: StatusListType3.OAuthStatusList,
824
+ proofFormat,
825
+ length: decoded.statusList.statusList.length,
826
+ statusListCredential: statusListEntity.statusListCredential,
827
+ statuslistContentType: this.buildContentType(proofFormat),
828
+ correlationId: statusListEntity.correlationId,
829
+ driverType: statusListEntity.driverType,
830
+ bitsPerStatus: oauthEntity.bitsPerStatus,
831
+ ...expiresAt && {
832
+ expiresAt
833
+ },
834
+ oauthStatusList: {
835
+ bitsPerStatus: oauthEntity.bitsPerStatus,
836
+ ...expiresAt && {
837
+ expiresAt
838
+ }
839
+ }
840
+ };
841
+ }
758
842
  }
759
843
  async createCredentialStatus(args) {
760
844
  const { statusList, statusListIndex } = args;
@@ -792,12 +876,19 @@ import { StatusListType as StatusListType5 } from "@sphereon/ssi-types";
792
876
  import { CredentialMapper as CredentialMapper3, DocumentFormat as DocumentFormat3, StatusListType as StatusListType4 } from "@sphereon/ssi-types";
793
877
  import { BitstreamStatusList, createStatusListCredential } from "@4sure-tech/vc-bitstring-status-lists";
794
878
  var DEFAULT_LIST_LENGTH3 = 131072;
795
- var DEFAULT_PROOF_FORMAT3 = "lds";
879
+ var DEFAULT_PROOF_FORMAT3 = "vc+jwt";
796
880
  var DEFAULT_STATUS_PURPOSE = "revocation";
797
881
  var BitstringStatusListImplementation = class {
798
882
  static {
799
883
  __name(this, "BitstringStatusListImplementation");
800
884
  }
885
+ /**
886
+ * Creates a new bitstring status list with the specified configuration
887
+ *
888
+ * @param args - Configuration for the new status list including issuer, purpose, and size
889
+ * @param context - Veramo agent context for credential operations
890
+ * @returns Promise resolving to the created status list details
891
+ */
801
892
  async createNewStatusList(args, context) {
802
893
  if (!args.bitstringStatusList) {
803
894
  throw new Error("BitstringStatusList options are required for type BitstringStatusList");
@@ -805,28 +896,34 @@ var BitstringStatusListImplementation = class {
805
896
  const length = args?.length ?? DEFAULT_LIST_LENGTH3;
806
897
  const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT3;
807
898
  assertValidProofType(StatusListType4.BitstringStatusList, proofFormat);
808
- const veramoProofFormat = proofFormat;
809
899
  const { issuer, id } = args;
810
900
  const correlationId = getAssertedValue("correlationId", args.correlationId);
811
901
  const { statusPurpose, bitsPerStatus, validFrom, validUntil, ttl } = args.bitstringStatusList;
812
- const statusListCredential = await this.createVerifiableCredential({
813
- ...args,
814
- proofFormat: veramoProofFormat,
902
+ const unsignedCredential = await createStatusListCredential({
903
+ id,
904
+ issuer,
815
905
  statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
816
906
  validFrom: ensureDate(validFrom),
817
907
  validUntil: ensureDate(validUntil),
818
908
  ttl
909
+ });
910
+ const statusListCredential = await this.createVerifiableCredential({
911
+ unsignedCredential,
912
+ id,
913
+ issuer,
914
+ proofFormat,
915
+ keyRef: args.keyRef
819
916
  }, context);
820
917
  return {
821
- encodedList: statusListCredential.credentialSubject.encodedList,
918
+ encodedList: unsignedCredential.credentialSubject.encodedList,
822
919
  statusListCredential,
823
920
  bitstringStatusList: {
824
921
  statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
825
- ...statusListCredential.validFrom && {
826
- validFrom: new Date(statusListCredential.validFrom)
922
+ ...unsignedCredential.validFrom && {
923
+ validFrom: new Date(unsignedCredential.validFrom)
827
924
  },
828
- ...statusListCredential.validUntil && {
829
- validUntil: new Date(statusListCredential.validUntil)
925
+ ...unsignedCredential.validUntil && {
926
+ validUntil: new Date(unsignedCredential.validUntil)
830
927
  },
831
928
  ttl,
832
929
  bitsPerStatus
@@ -840,9 +937,16 @@ var BitstringStatusListImplementation = class {
840
937
  statuslistContentType: this.buildContentType(proofFormat)
841
938
  };
842
939
  }
940
+ /**
941
+ * Updates the status of a specific credential in an existing status list
942
+ *
943
+ * @param args - Update parameters including the status list credential, index, and new value
944
+ * @param context - Veramo agent context for credential operations
945
+ * @returns Promise resolving to the updated status list details
946
+ */
843
947
  async updateStatusListIndex(args, context) {
844
948
  if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
845
- return Promise.reject("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListIndex)");
949
+ return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListIndex)"));
846
950
  }
847
951
  const credential = args.statusListCredential;
848
952
  const uniform = CredentialMapper3.toUniformCredential(credential);
@@ -854,34 +958,40 @@ var BitstringStatusListImplementation = class {
854
958
  encodedList: origEncodedList,
855
959
  statusSize: args.bitsPerStatus
856
960
  });
857
- statusList.setStatus(index, args.value);
858
- const proofFormat = CredentialMapper3.detectDocumentType(credential) === DocumentFormat3.JWT ? "jwt" : "lds";
961
+ const bitstringStatusId = args.value;
962
+ statusList.setStatus(index, bitstringStatusId);
963
+ const proofFormat = CredentialMapper3.detectDocumentType(credential) === DocumentFormat3.JWT ? "vc+jwt" : "lds";
859
964
  const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
860
965
  const statusPurpose = getAssertedProperty("statusPurpose", credSubject);
861
966
  const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : void 0;
862
967
  const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : void 0;
863
968
  const ttl = credSubject.ttl;
864
- const updatedCredential = await this.createVerifiableCredential({
865
- ...args,
969
+ const unsignedCredential = await createStatusListCredential({
866
970
  id,
867
971
  issuer,
868
972
  statusList,
973
+ statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
974
+ validFrom: ensureDate(validFrom),
975
+ validUntil: ensureDate(validUntil),
976
+ ttl
977
+ });
978
+ const updatedCredential = await this.createVerifiableCredential({
979
+ unsignedCredential,
980
+ id,
981
+ issuer,
869
982
  proofFormat,
870
- statusPurpose,
871
- ttl,
872
- validFrom,
873
- validUntil
983
+ keyRef: args.keyRef
874
984
  }, context);
875
985
  return {
876
986
  statusListCredential: updatedCredential,
877
- encodedList: updatedCredential.credentialSubject.encodedList,
987
+ encodedList: unsignedCredential.credentialSubject.encodedList,
878
988
  bitstringStatusList: {
879
989
  statusPurpose,
880
- ...updatedCredential.validFrom && {
881
- validFrom: new Date(updatedCredential.validFrom)
990
+ ...unsignedCredential.validFrom && {
991
+ validFrom: new Date(unsignedCredential.validFrom)
882
992
  },
883
- ...updatedCredential.validUntil && {
884
- validUntil: new Date(updatedCredential.validUntil)
993
+ ...unsignedCredential.validUntil && {
994
+ validUntil: new Date(unsignedCredential.validUntil)
885
995
  },
886
996
  bitsPerStatus: args.bitsPerStatus,
887
997
  ttl
@@ -894,17 +1004,23 @@ var BitstringStatusListImplementation = class {
894
1004
  statuslistContentType: this.buildContentType(proofFormat)
895
1005
  };
896
1006
  }
1007
+ /**
1008
+ * Updates a status list by decoding an encoded list, modifying it, and re-encoding
1009
+ *
1010
+ * @param args - Update parameters including encoded list, index, and new value
1011
+ * @param context - Veramo agent context for credential operations
1012
+ * @returns Promise resolving to the updated status list details
1013
+ */
897
1014
  async updateStatusListFromEncodedList(args, context) {
898
1015
  if (!args.bitstringStatusList) {
899
1016
  throw new Error("bitstringStatusList options required for type BitstringStatusList");
900
1017
  }
901
1018
  if (args.bitstringStatusList.bitsPerStatus < 1) {
902
- return Promise.reject("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListFromEncodedList)");
1019
+ return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListFromEncodedList)"));
903
1020
  }
904
1021
  const { statusPurpose, bitsPerStatus, ttl, validFrom, validUntil } = args.bitstringStatusList;
905
1022
  const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT3;
906
1023
  assertValidProofType(StatusListType4.BitstringStatusList, proofFormat);
907
- const veramoProofFormat = proofFormat;
908
1024
  const { issuer, id } = getAssertedValues(args);
909
1025
  const statusList = await BitstreamStatusList.decode({
910
1026
  encodedList: args.encodedList,
@@ -912,29 +1028,34 @@ var BitstringStatusListImplementation = class {
912
1028
  });
913
1029
  const index = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
914
1030
  statusList.setStatus(index, args.value);
915
- const credential = await this.createVerifiableCredential({
1031
+ const unsignedCredential = await createStatusListCredential({
916
1032
  id,
917
1033
  issuer,
918
1034
  statusList,
919
- proofFormat: veramoProofFormat,
920
- keyRef: args.keyRef,
921
- statusPurpose,
1035
+ statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
922
1036
  validFrom: ensureDate(validFrom),
923
1037
  validUntil: ensureDate(validUntil),
924
1038
  ttl
1039
+ });
1040
+ const credential = await this.createVerifiableCredential({
1041
+ unsignedCredential,
1042
+ id,
1043
+ issuer,
1044
+ proofFormat,
1045
+ keyRef: args.keyRef
925
1046
  }, context);
926
1047
  return {
927
1048
  type: StatusListType4.BitstringStatusList,
928
1049
  statusListCredential: credential,
929
- encodedList: credential.credentialSubject.encodedList,
1050
+ encodedList: unsignedCredential.credentialSubject.encodedList,
930
1051
  bitstringStatusList: {
931
1052
  statusPurpose,
932
1053
  bitsPerStatus,
933
- ...credential.validFrom && {
934
- validFrom: new Date(credential.validFrom)
1054
+ ...unsignedCredential.validFrom && {
1055
+ validFrom: new Date(unsignedCredential.validFrom)
935
1056
  },
936
- ...credential.validUntil && {
937
- validUntil: new Date(credential.validUntil)
1057
+ ...unsignedCredential.validUntil && {
1058
+ validUntil: new Date(unsignedCredential.validUntil)
938
1059
  },
939
1060
  ttl
940
1061
  },
@@ -945,17 +1066,22 @@ var BitstringStatusListImplementation = class {
945
1066
  statuslistContentType: this.buildContentType(proofFormat)
946
1067
  };
947
1068
  }
1069
+ /**
1070
+ * Checks the status of a specific credential by its index in the status list
1071
+ *
1072
+ * @param args - Check parameters including the status list credential and index
1073
+ * @returns Promise resolving to the status value at the specified index
1074
+ */
948
1075
  async checkStatusIndex(args) {
949
1076
  if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
950
- return Promise.reject("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (checkStatusIndex)");
1077
+ return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (checkStatusIndex)"));
951
1078
  }
952
1079
  const uniform = CredentialMapper3.toUniformCredential(args.statusListCredential);
953
1080
  const { credentialSubject } = uniform;
954
1081
  const encodedList = getAssertedProperty("encodedList", credentialSubject);
955
- const statusSize = args.bitsPerStatus;
956
1082
  const statusList = await BitstreamStatusList.decode({
957
1083
  encodedList,
958
- statusSize
1084
+ statusSize: args.bitsPerStatus
959
1085
  });
960
1086
  const numIndex = typeof args.statusListIndex === "number" ? args.statusListIndex : parseInt(args.statusListIndex);
961
1087
  if (statusList.getLength() <= numIndex) {
@@ -963,48 +1089,44 @@ var BitstringStatusListImplementation = class {
963
1089
  }
964
1090
  return statusList.getStatus(numIndex);
965
1091
  }
966
- async toStatusListDetails(args) {
967
- const { statusListPayload, bitsPerStatus } = args;
968
- if (!bitsPerStatus || bitsPerStatus < 1) {
969
- return Promise.reject("bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (toStatusListDetails)");
970
- }
971
- const uniform = CredentialMapper3.toUniformCredential(statusListPayload);
1092
+ async extractCredentialDetails(credential) {
1093
+ const uniform = CredentialMapper3.toUniformCredential(credential);
972
1094
  const { issuer, credentialSubject } = uniform;
973
- const id = getAssertedValue("id", uniform.id);
974
- const encodedList = getAssertedProperty("encodedList", credentialSubject);
975
- const proofFormat = CredentialMapper3.detectDocumentType(statusListPayload) === DocumentFormat3.JWT ? "jwt" : "lds";
976
- const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
977
- const statusPurpose = getAssertedProperty("statusPurpose", credSubject);
978
- const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : void 0;
979
- const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : void 0;
980
- const ttl = credSubject.ttl;
981
- const statuslistLength = BitstreamStatusList.getStatusListLength(encodedList, bitsPerStatus);
1095
+ const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
982
1096
  return {
983
- // Base implementation fields
984
- id,
985
- encodedList,
1097
+ id: getAssertedValue("id", uniform.id),
986
1098
  issuer,
987
- type: StatusListType4.BitstringStatusList,
988
- proofFormat,
989
- length: statuslistLength,
990
- statusListCredential: statusListPayload,
991
- statuslistContentType: this.buildContentType(proofFormat),
992
- correlationId: args.correlationId,
993
- driverType: args.driverType,
994
- // Flattened Bitstring-specific fields
995
- statusPurpose,
996
- bitsPerStatus,
997
- ...validFrom && {
998
- validFrom
999
- },
1000
- ...validUntil && {
1001
- validUntil
1002
- },
1003
- ...ttl && {
1004
- ttl
1005
- },
1006
- // Legacy nested structure for backward compatibility
1007
- bitstringStatusList: {
1099
+ encodedList: getAssertedProperty("encodedList", subject)
1100
+ };
1101
+ }
1102
+ async toStatusListDetails(args) {
1103
+ if ("statusListCredential" in args) {
1104
+ const { statusListCredential, bitsPerStatus, correlationId, driverType } = args;
1105
+ if (!bitsPerStatus || bitsPerStatus < 1) {
1106
+ return Promise.reject(Error("bitsPerStatus must be set for bitstring status lists and must be 1 or higher"));
1107
+ }
1108
+ const uniform = CredentialMapper3.toUniformCredential(statusListCredential);
1109
+ const { issuer, credentialSubject } = uniform;
1110
+ const subject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject;
1111
+ const id = getAssertedValue("id", uniform.id);
1112
+ const encodedList = getAssertedProperty("encodedList", subject);
1113
+ const statusPurpose = getAssertedProperty("statusPurpose", subject);
1114
+ const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : void 0;
1115
+ const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : void 0;
1116
+ const ttl = subject.ttl;
1117
+ const proofFormat = CredentialMapper3.detectDocumentType(statusListCredential) === DocumentFormat3.JWT ? "vc+jwt" : "lds";
1118
+ const statuslistLength = BitstreamStatusList.getStatusListLength(encodedList, bitsPerStatus);
1119
+ return {
1120
+ id,
1121
+ encodedList,
1122
+ issuer,
1123
+ type: StatusListType4.BitstringStatusList,
1124
+ proofFormat,
1125
+ length: statuslistLength,
1126
+ statusListCredential,
1127
+ statuslistContentType: this.buildContentType(proofFormat),
1128
+ correlationId,
1129
+ driverType,
1008
1130
  statusPurpose,
1009
1131
  bitsPerStatus,
1010
1132
  ...validFrom && {
@@ -1015,56 +1137,124 @@ var BitstringStatusListImplementation = class {
1015
1137
  },
1016
1138
  ...ttl && {
1017
1139
  ttl
1140
+ },
1141
+ bitstringStatusList: {
1142
+ statusPurpose,
1143
+ bitsPerStatus,
1144
+ ...validFrom && {
1145
+ validFrom
1146
+ },
1147
+ ...validUntil && {
1148
+ validUntil
1149
+ },
1150
+ ...ttl && {
1151
+ ttl
1152
+ }
1018
1153
  }
1019
- },
1020
- // Optional fields from args
1021
- ...args.correlationId && {
1022
- correlationId: args.correlationId
1023
- },
1024
- ...args.driverType && {
1025
- driverType: args.driverType
1154
+ };
1155
+ } else {
1156
+ const { extractedDetails, statusListEntity } = args;
1157
+ const bitstringEntity = statusListEntity;
1158
+ if (!bitstringEntity.bitsPerStatus) {
1159
+ return Promise.reject(Error("bitsPerStatus must be present for a bitstring status list"));
1026
1160
  }
1027
- };
1161
+ const proofFormat = CredentialMapper3.detectDocumentType(statusListEntity.statusListCredential) === DocumentFormat3.JWT ? "vc+jwt" : "lds";
1162
+ const statuslistLength = BitstreamStatusList.getStatusListLength(extractedDetails.encodedList, bitstringEntity.bitsPerStatus);
1163
+ return {
1164
+ id: extractedDetails.id,
1165
+ encodedList: extractedDetails.encodedList,
1166
+ issuer: extractedDetails.issuer,
1167
+ type: StatusListType4.BitstringStatusList,
1168
+ proofFormat,
1169
+ length: statuslistLength,
1170
+ statusListCredential: statusListEntity.statusListCredential,
1171
+ statuslistContentType: this.buildContentType(proofFormat),
1172
+ correlationId: statusListEntity.correlationId,
1173
+ driverType: statusListEntity.driverType,
1174
+ statusPurpose: bitstringEntity.statusPurpose,
1175
+ bitsPerStatus: bitstringEntity.bitsPerStatus,
1176
+ ...bitstringEntity.validFrom && {
1177
+ validFrom: bitstringEntity.validFrom
1178
+ },
1179
+ ...bitstringEntity.validUntil && {
1180
+ validUntil: bitstringEntity.validUntil
1181
+ },
1182
+ ...bitstringEntity.ttl && {
1183
+ ttl: bitstringEntity.ttl
1184
+ },
1185
+ bitstringStatusList: {
1186
+ statusPurpose: bitstringEntity.statusPurpose,
1187
+ bitsPerStatus: bitstringEntity.bitsPerStatus,
1188
+ ...bitstringEntity.validFrom && {
1189
+ validFrom: bitstringEntity.validFrom
1190
+ },
1191
+ ...bitstringEntity.validUntil && {
1192
+ validUntil: bitstringEntity.validUntil
1193
+ },
1194
+ ...bitstringEntity.ttl && {
1195
+ ttl: bitstringEntity.ttl
1196
+ }
1197
+ }
1198
+ };
1199
+ }
1028
1200
  }
1201
+ /**
1202
+ * Creates a credential status entry for a specific credential in a status list
1203
+ *
1204
+ * @param args - Parameters including the status list, entry details, and index
1205
+ * @returns Promise resolving to the credential status entry
1206
+ */
1029
1207
  async createCredentialStatus(args) {
1030
1208
  const { statusList, statusListEntry, statusListIndex } = args;
1031
- const isBitstringEntry = /* @__PURE__ */ __name((entry) => {
1032
- return "statusPurpose" in entry;
1033
- }, "isBitstringEntry");
1034
- if (!isBitstringEntry(statusListEntry)) {
1035
- throw new Error("Expected bitstring status list entry for bitstring status list");
1036
- }
1037
1209
  const bitstringStatusList = statusList;
1210
+ const bitstringStatusListEntry = statusListEntry;
1038
1211
  return {
1039
1212
  id: `${statusList.id}#${statusListIndex}`,
1040
1213
  type: "BitstringStatusListEntry",
1041
- statusPurpose: statusListEntry.statusPurpose,
1214
+ statusPurpose: bitstringStatusListEntry.statusPurpose,
1042
1215
  statusListIndex: "" + statusListIndex,
1043
1216
  statusListCredential: statusList.id,
1044
- bitsPerStatus: bitstringStatusList.bitsPerStatus
1217
+ bitsPerStatus: bitstringStatusList.bitsPerStatus,
1218
+ statusMessage: bitstringStatusListEntry.statusMessage,
1219
+ statusReference: bitstringStatusListEntry.statusReference
1045
1220
  };
1046
1221
  }
1222
+ /**
1223
+ * Creates a signed verifiable credential from an unsigned status list credential
1224
+ *
1225
+ * @param args - Parameters including the unsigned credential and signing details
1226
+ * @param context - Veramo agent context for credential operations
1227
+ * @returns Promise resolving to the signed credential
1228
+ */
1047
1229
  async createVerifiableCredential(args, context) {
1230
+ const { unsignedCredential, issuer, proofFormat, keyRef } = args;
1048
1231
  const identifier = await context.agent.identifierManagedGet({
1049
- identifier: typeof args.issuer === "string" ? args.issuer : args.issuer.id,
1232
+ identifier: typeof issuer === "string" ? issuer : issuer.id,
1050
1233
  vmRelationship: "assertionMethod",
1051
1234
  offlineWhenNoDIDRegistered: true
1052
1235
  });
1053
- const unsignedCredential = await createStatusListCredential(args);
1054
1236
  const verifiableCredential = await context.agent.createVerifiableCredential({
1055
1237
  credential: unsignedCredential,
1056
- keyRef: args.keyRef ?? identifier.kmsKeyRef,
1057
- proofFormat: args.proofFormat,
1238
+ keyRef: keyRef ?? identifier.kmsKeyRef,
1239
+ proofFormat,
1058
1240
  fetchRemoteContexts: true
1059
1241
  });
1060
1242
  return CredentialMapper3.toWrappedVerifiableCredential(verifiableCredential).original;
1061
1243
  }
1244
+ /**
1245
+ * Builds the appropriate content type string for a given proof format
1246
+ *
1247
+ * @param proofFormat - The proof format to build content type for
1248
+ * @returns The corresponding content type string
1249
+ */
1062
1250
  buildContentType(proofFormat) {
1063
1251
  switch (proofFormat) {
1064
1252
  case "jwt":
1065
- return `application/statuslist+jwt`;
1253
+ return "application/statuslist+jwt";
1066
1254
  case "cbor":
1067
- return `application/statuslist+cwt`;
1255
+ return "application/statuslist+cwt";
1256
+ case "vc+jwt":
1257
+ return "application/statuslist+vc+jwt";
1068
1258
  case "lds":
1069
1259
  return "application/statuslist+ld+json";
1070
1260
  default:
@@ -1220,37 +1410,24 @@ async function updateStatusIndexFromStatusListCredential(args, context) {
1220
1410
  return implementation.updateStatusListIndex(args, context);
1221
1411
  }
1222
1412
  __name(updateStatusIndexFromStatusListCredential, "updateStatusIndexFromStatusListCredential");
1223
- async function statusListCredentialToDetails({ correlationId, driverType, statusListCredential, bitsPerStatus }) {
1224
- const credential = getAssertedValue("statusListCredential", statusListCredential);
1225
- let statusListType;
1226
- const documentFormat = CredentialMapper4.detectDocumentType(credential);
1227
- if (documentFormat === DocumentFormat4.JWT) {
1228
- const [header] = credential.split(".");
1229
- const decodedHeader = JSON.parse(Buffer.from(header, "base64").toString());
1230
- if (decodedHeader.typ === "statuslist+jwt") {
1231
- statusListType = StatusListType6.OAuthStatusList;
1232
- }
1233
- } else if (documentFormat === DocumentFormat4.MSO_MDOC) {
1234
- statusListType = StatusListType6.OAuthStatusList;
1235
- }
1236
- if (!statusListType) {
1237
- const uniform = CredentialMapper4.toUniformCredential(credential);
1238
- const type = uniform.type.find((t) => t.includes("StatusList2021") || t.includes("OAuth2StatusList") || t.includes("BitstringStatusList"));
1239
- if (!type) {
1240
- throw new Error("Invalid status list credential type");
1241
- }
1242
- statusListType = type.replace("Credential", "");
1243
- }
1413
+ async function extractCredentialDetails(statusListCredential) {
1414
+ const statusListType = determineStatusListType(statusListCredential);
1244
1415
  const implementation = getStatusListImplementation(statusListType);
1245
- const result = await implementation.toStatusListDetails({
1246
- statusListPayload: credential,
1247
- correlationId,
1248
- driverType,
1249
- bitsPerStatus
1250
- });
1251
- return result;
1416
+ return implementation.extractCredentialDetails(statusListCredential);
1417
+ }
1418
+ __name(extractCredentialDetails, "extractCredentialDetails");
1419
+ async function toStatusListDetails(args) {
1420
+ if ("statusListCredential" in args) {
1421
+ const statusListType = args.statusListType;
1422
+ const implementation = getStatusListImplementation(statusListType);
1423
+ return implementation.toStatusListDetails(args);
1424
+ } else {
1425
+ const statusListType = args.statusListEntity.type;
1426
+ const implementation = getStatusListImplementation(statusListType);
1427
+ return implementation.toStatusListDetails(args);
1428
+ }
1252
1429
  }
1253
- __name(statusListCredentialToDetails, "statusListCredentialToDetails");
1430
+ __name(toStatusListDetails, "toStatusListDetails");
1254
1431
  async function createCredentialStatusFromStatusList(args) {
1255
1432
  const { statusList, statusListEntry, statusListIndex } = args;
1256
1433
  const statusListType = determineStatusListType(statusList.statusListCredential);
@@ -1315,11 +1492,13 @@ export {
1315
1492
  checkStatusIndexFromStatusListCredential,
1316
1493
  createCredentialStatusFromStatusList,
1317
1494
  createNewStatusList,
1495
+ determineStatusListType,
1496
+ extractCredentialDetails,
1318
1497
  fetchStatusListCredential,
1319
1498
  simpleCheckStatusFromStatusListUrl,
1320
1499
  statusList2021ToVerifiableCredential,
1321
- statusListCredentialToDetails,
1322
1500
  statusPluginStatusFunction,
1501
+ toStatusListDetails,
1323
1502
  updateStatusIndexFromStatusListCredential,
1324
1503
  updateStatusListIndexFromEncodedList,
1325
1504
  vcLibCheckStatusFunction