@sphereon/ssi-sdk.vc-status-list 0.34.1-feature.SSISDK.17.bitstring.sl.9 → 0.34.1-feature.disable.test.8

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.
@@ -1,7 +1,6 @@
1
1
  import type { IAgentContext, ICredentialPlugin } from '@veramo/core'
2
2
  import type { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution'
3
- import {
4
- BitstringStatus,
3
+ import type {
5
4
  CheckStatusIndexArgs,
6
5
  CreateStatusListArgs,
7
6
  Status2021,
@@ -34,7 +33,7 @@ export interface IStatusList {
34
33
  /**
35
34
  * Checks the status at a given index in the status list
36
35
  */
37
- checkStatusIndex(args: CheckStatusIndexArgs): Promise<number | Status2021 | StatusOAuth | BitstringStatus>
36
+ checkStatusIndex(args: CheckStatusIndexArgs): Promise<number | Status2021 | StatusOAuth>
38
37
 
39
38
  /**
40
39
  * Collects the status list details
@@ -1,5 +1,5 @@
1
1
  import type { IAgentContext, ICredentialPlugin, IKeyManager } from '@veramo/core'
2
- import { type CompactJWT, type CredentialProofFormat, type CWT, StatusListType } from '@sphereon/ssi-types'
2
+ import { type CompactJWT, type CWT, type CredentialProofFormat, StatusListType } from '@sphereon/ssi-types'
3
3
  import type {
4
4
  CheckStatusIndexArgs,
5
5
  CreateStatusListArgs,
@@ -10,7 +10,7 @@ import type {
10
10
  UpdateStatusListFromEncodedListArgs,
11
11
  UpdateStatusListIndexArgs,
12
12
  } from '../types'
13
- import { determineProofFormat, ensureDate, getAssertedValue, getAssertedValues } from '../utils'
13
+ import { determineProofFormat, getAssertedValue, getAssertedValues } from '../utils'
14
14
  import type { IStatusList } from './IStatusList'
15
15
  import { StatusList } from '@sd-jwt/jwt-status-list'
16
16
  import type { IJwtService } from '@sphereon/ssi-sdk-ext.jwt-service'
@@ -20,7 +20,7 @@ import { createSignedCbor, decodeStatusListCWT } from './encoding/cbor'
20
20
 
21
21
  type IRequiredContext = IAgentContext<ICredentialPlugin & IJwtService & IIdentifierResolution & IKeyManager>
22
22
 
23
- export const DEFAULT_BITS_PER_STATUS = 1 // 1 bit is sufficient for 0x00 - "VALID" 0x01 - "INVALID" saving space in the process
23
+ export const DEFAULT_BITS_PER_STATUS = 1 // 1 bit is sufficient for 0x00 - "VALID" 0x01 - "INVALID" saving space in the process
24
24
  export const DEFAULT_LIST_LENGTH = 250000
25
25
  export const DEFAULT_PROOF_FORMAT = 'jwt' as CredentialProofFormat
26
26
 
@@ -32,8 +32,7 @@ export class OAuthStatusListImplementation implements IStatusList {
32
32
 
33
33
  const proofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT
34
34
  const { issuer, id, oauthStatusList, keyRef } = args
35
- const { bitsPerStatus } = oauthStatusList
36
- const expiresAt = ensureDate(oauthStatusList.expiresAt)
35
+ const { bitsPerStatus, expiresAt } = oauthStatusList
37
36
  const length = args.length ?? DEFAULT_LIST_LENGTH
38
37
  const issuerString = typeof issuer === 'string' ? issuer : issuer.id
39
38
  const correlationId = getAssertedValue('correlationId', args.correlationId)
@@ -57,8 +56,7 @@ export class OAuthStatusListImplementation implements IStatusList {
57
56
  }
58
57
 
59
58
  async updateStatusListIndex(args: UpdateStatusListIndexArgs, context: IRequiredContext): Promise<StatusListResult> {
60
- const { statusListCredential, value, keyRef } = args
61
- const expiresAt = ensureDate(oauthStatusList.expiresAt)
59
+ const { statusListCredential, value, expiresAt, keyRef } = args
62
60
  if (typeof statusListCredential !== 'string') {
63
61
  return Promise.reject('statusListCredential in neither JWT nor CWT')
64
62
  }
@@ -72,10 +70,6 @@ export class OAuthStatusListImplementation implements IStatusList {
72
70
  throw new Error('Status list index out of bounds')
73
71
  }
74
72
 
75
- if (typeof value !== 'number') {
76
- throw new Error('Status list values should be of type number')
77
- }
78
-
79
73
  statusList.setStatus(index, value)
80
74
  const { statusListCredential: signedCredential, encodedList } = await this.createSignedStatusList(
81
75
  proofFormat,
@@ -108,15 +102,15 @@ export class OAuthStatusListImplementation implements IStatusList {
108
102
  throw new Error('OAuthStatusList options are required for type OAuthStatusList')
109
103
  }
110
104
  const { proofFormat, oauthStatusList, keyRef } = args
111
- const { bitsPerStatus } = oauthStatusList
112
- const expiresAt = ensureDate(oauthStatusList.expiresAt)
105
+ const { bitsPerStatus, expiresAt } = oauthStatusList
113
106
 
114
107
  const { issuer, id } = getAssertedValues(args)
115
108
  const issuerString = typeof issuer === 'string' ? issuer : issuer.id
116
109
 
117
110
  const listToUpdate = StatusList.decompressStatusList(args.encodedList, bitsPerStatus ?? DEFAULT_BITS_PER_STATUS)
118
111
  const index = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
119
- listToUpdate.setStatus(index, args.value)
112
+ // FIXME: See above.
113
+ listToUpdate.setStatus(index, args.value ? 1 : 0)
120
114
 
121
115
  const { statusListCredential, encodedList } = await this.createSignedStatusList(
122
116
  proofFormat ?? DEFAULT_PROOF_FORMAT,
@@ -144,7 +138,7 @@ export class OAuthStatusListImplementation implements IStatusList {
144
138
  }
145
139
  }
146
140
 
147
- private buildContentType(proofFormat: CredentialProofFormat | undefined) {
141
+ private buildContentType(proofFormat: 'jwt' | 'lds' | 'EthereumEip712Signature2021' | 'cbor' | undefined) {
148
142
  return `application/statuslist+${proofFormat === 'cbor' ? 'cwt' : 'jwt'}`
149
143
  }
150
144
 
@@ -159,7 +153,7 @@ export class OAuthStatusListImplementation implements IStatusList {
159
153
 
160
154
  const index = typeof statusListIndex === 'number' ? statusListIndex : parseInt(statusListIndex)
161
155
  if (index < 0 || index >= statusList.statusList.length) {
162
- throw new Error(`Status list index out of bounds, has ${statusList.statusList.length} items, requested ${index}`)
156
+ throw new Error('Status list index out of bounds')
163
157
  }
164
158
 
165
159
  return statusList.getStatus(index)
@@ -190,7 +184,7 @@ export class OAuthStatusListImplementation implements IStatusList {
190
184
  }
191
185
 
192
186
  private async createSignedStatusList(
193
- proofFormat: CredentialProofFormat,
187
+ proofFormat: 'jwt' | 'lds' | 'EthereumEip712Signature2021' | 'cbor',
194
188
  context: IAgentContext<ICredentialPlugin & IJwtService & IIdentifierResolution & IKeyManager>,
195
189
  statusList: StatusList,
196
190
  issuerString: string,
@@ -24,7 +24,7 @@ import { Status2021 } from '../types'
24
24
  import { assertValidProofType, getAssertedProperty, getAssertedValue, getAssertedValues } from '../utils'
25
25
 
26
26
  export const DEFAULT_LIST_LENGTH = 250000
27
- export const DEFAULT_PROOF_FORMAT = 'lds' as CredentialProofFormat
27
+ export const DEFAULT_PROOF_FORMAT = 'lds' as VeramoProofFormat
28
28
 
29
29
  export class StatusList2021Implementation implements IStatusList {
30
30
  async createNewStatusList(
@@ -126,7 +126,7 @@ export class StatusList2021Implementation implements IStatusList {
126
126
  const { issuer, id } = getAssertedValues(args)
127
127
  const statusList = await StatusList.decode({ encodedList: args.encodedList })
128
128
  const index = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
129
- statusList.setStatus(index, args.value !== 0)
129
+ statusList.setStatus(index, args.value)
130
130
 
131
131
  const newEncodedList = await statusList.encode()
132
132
  const credential = await this.createVerifiableCredential(
@@ -234,7 +234,7 @@ export class StatusList2021Implementation implements IStatusList {
234
234
  return CredentialMapper.toWrappedVerifiableCredential(verifiableCredential as StatusListCredential).original as StatusListCredential
235
235
  }
236
236
 
237
- private buildContentType(proofFormat: CredentialProofFormat | undefined) {
237
+ private buildContentType(proofFormat: 'jwt' | 'lds' | 'EthereumEip712Signature2021' | 'cbor' | undefined) {
238
238
  switch (proofFormat) {
239
239
  case 'jwt':
240
240
  return `application/statuslist+jwt`
@@ -2,7 +2,6 @@ import type { IStatusList } from './IStatusList'
2
2
  import { StatusList2021Implementation } from './StatusList2021'
3
3
  import { OAuthStatusListImplementation } from './OAuthStatusList'
4
4
  import { StatusListType } from '@sphereon/ssi-types'
5
- import { BitstringStatusListImplementation } from './BitstringStatusListImplementation'
6
5
 
7
6
  export class StatusListFactory {
8
7
  private static instance: StatusListFactory
@@ -12,7 +11,6 @@ export class StatusListFactory {
12
11
  this.implementations = new Map()
13
12
  this.implementations.set(StatusListType.StatusList2021, new StatusList2021Implementation())
14
13
  this.implementations.set(StatusListType.OAuthStatusList, new OAuthStatusListImplementation())
15
- this.implementations.set(StatusListType.BitstringStatusList, new BitstringStatusListImplementation())
16
14
  }
17
15
 
18
16
  public static getInstance(): StatusListFactory {
@@ -1,11 +1,11 @@
1
1
  import type { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution'
2
2
  import {
3
- type CredentialProofFormat,
4
3
  type ICredential,
5
4
  type ICredentialStatus,
6
5
  type IIssuer,
7
6
  type IVerifiableCredential,
8
7
  type OrPromise,
8
+ type CredentialProofFormat,
9
9
  type StatusListCredential,
10
10
  StatusListCredentialIdMode,
11
11
  StatusListDriverType,
@@ -26,7 +26,6 @@ import { DataSource } from 'typeorm'
26
26
  import type { BitsPerStatus } from '@sd-jwt/jwt-status-list'
27
27
  import type { SdJwtVcPayload } from '@sd-jwt/sd-jwt-vc'
28
28
  import type { StatusListOpts } from '@sphereon/oid4vci-common'
29
- import { BitstringStatusPurpose } from '@4sure-tech/vc-bitstring-status-lists'
30
29
 
31
30
  export enum StatusOAuth {
32
31
  Valid = 0,
@@ -39,8 +38,6 @@ export enum Status2021 {
39
38
  Invalid = 1,
40
39
  }
41
40
 
42
- export type BitstringStatus = number
43
-
44
41
  export type StatusList2021Args = {
45
42
  indexingDirection: StatusListIndexingDirection
46
43
  statusPurpose?: StatusPurpose2021
@@ -52,14 +49,6 @@ export type OAuthStatusListArgs = {
52
49
  expiresAt?: Date
53
50
  }
54
51
 
55
- export type BitstringStatusListArgs = {
56
- statusPurpose: BitstringStatusPurpose
57
- bitsPerStatus: number
58
- ttl?: number
59
- validFrom?: Date
60
- validUntil?: Date
61
- }
62
-
63
52
  export type BaseCreateNewStatusListArgs = {
64
53
  type: StatusListType
65
54
  id: string
@@ -70,7 +59,6 @@ export type BaseCreateNewStatusListArgs = {
70
59
  keyRef?: string
71
60
  statusList2021?: StatusList2021Args
72
61
  oauthStatusList?: OAuthStatusListArgs
73
- bitstringStatusList?: BitstringStatusListArgs
74
62
  driverType?: StatusListDriverType
75
63
  }
76
64
 
@@ -83,18 +71,10 @@ export type UpdateOAuthStatusListArgs = {
83
71
  expiresAt?: Date
84
72
  }
85
73
 
86
- export type UpdateBitstringStatusListArgs = {
87
- statusPurpose: BitstringStatusPurpose
88
- bitsPerStatus: number
89
- validFrom?: Date
90
- validUntil?: Date
91
- ttl?: number
92
- }
93
-
94
74
  export interface UpdateStatusListFromEncodedListArgs {
95
75
  type?: StatusListType
96
76
  statusListIndex: number | string
97
- value: number
77
+ value: boolean
98
78
  proofFormat?: CredentialProofFormat
99
79
  keyRef?: string
100
80
  correlationId?: string
@@ -103,14 +83,13 @@ export interface UpdateStatusListFromEncodedListArgs {
103
83
  id: string
104
84
  statusList2021?: UpdateStatusList2021Args
105
85
  oauthStatusList?: UpdateOAuthStatusListArgs
106
- bitstringStatusList?: UpdateBitstringStatusListArgs
107
86
  }
108
87
 
109
88
  export interface UpdateStatusListFromStatusListCredentialArgs {
110
89
  statusListCredential: StatusListCredential // | CompactJWT
111
90
  keyRef?: string
112
91
  statusListIndex: number | string
113
- value: number | Status2021 | StatusOAuth | BitstringStatus
92
+ value: number | Status2021 | StatusOAuth
114
93
  }
115
94
 
116
95
  export interface StatusListResult {
@@ -124,7 +103,6 @@ export interface StatusListResult {
124
103
  issuer: string | IIssuer
125
104
  statusList2021?: StatusList2021Details
126
105
  oauthStatusList?: OAuthStatusDetails
127
- bitstringStatusList?: BitstringStatusDetails
128
106
 
129
107
  // These cannot be deduced from the VC, so they are present when callers pass in these values as params
130
108
  correlationId?: string
@@ -142,14 +120,6 @@ interface OAuthStatusDetails {
142
120
  expiresAt?: Date
143
121
  }
144
122
 
145
- interface BitstringStatusDetails {
146
- statusPurpose: BitstringStatusPurpose
147
- bitsPerStatus: number
148
- validFrom?: Date
149
- validUntil?: Date
150
- ttl?: number
151
- }
152
-
153
123
  export interface StatusList2021EntryCredentialStatus extends ICredentialStatus {
154
124
  type: 'StatusList2021Entry'
155
125
  statusPurpose: StatusPurpose2021
@@ -165,16 +135,6 @@ export interface StatusListOAuthEntryCredentialStatus extends ICredentialStatus
165
135
  expiresAt?: Date
166
136
  }
167
137
 
168
- export interface BitstringStatusListEntryCredentialStatus extends ICredentialStatus {
169
- type: 'BitstringStatusListEntry'
170
- statusPurpose: BitstringStatusPurpose | BitstringStatusPurpose[]
171
- statusListIndex: string
172
- statusListCredential: string
173
- bitsPerStatus?: number
174
- statusMessage?: Array<BitstringStatus>
175
- statusReference?: string | string[]
176
- }
177
-
178
138
  export interface StatusList2021ToVerifiableCredentialArgs {
179
139
  issuer: string | IIssuer
180
140
  id: string
@@ -194,14 +154,12 @@ export interface CreateStatusListArgs {
194
154
  length?: number
195
155
  statusList2021?: StatusList2021Args
196
156
  oauthStatusList?: OAuthStatusListArgs
197
- bitstringStatusList?: BitstringStatusListArgs
198
157
  }
199
158
 
200
159
  export interface UpdateStatusListIndexArgs {
201
160
  statusListCredential: StatusListCredential // | CompactJWT
202
161
  statusListIndex: number | string
203
- value: number | Status2021 | StatusOAuth | BitstringStatus
204
- bitsPerStatus?: number
162
+ value: number | Status2021 | StatusOAuth
205
163
  keyRef?: string
206
164
  expiresAt?: Date
207
165
  }
@@ -209,14 +167,12 @@ export interface UpdateStatusListIndexArgs {
209
167
  export interface CheckStatusIndexArgs {
210
168
  statusListCredential: StatusListCredential // | CompactJWT
211
169
  statusListIndex: string | number
212
- bitsPerStatus?: number
213
170
  }
214
171
 
215
172
  export interface ToStatusListDetailsArgs {
216
173
  statusListPayload: StatusListCredential
217
174
  correlationId?: string
218
175
  driverType?: StatusListDriverType
219
- bitsPerStatus?: number
220
176
  }
221
177
 
222
178
  /**
package/src/utils.ts CHANGED
@@ -11,7 +11,7 @@ import { jwtDecode } from 'jwt-decode'
11
11
 
12
12
  export function getAssertedStatusListType(type?: StatusListType) {
13
13
  const assertedType = type ?? StatusListType.StatusList2021
14
- if (![StatusListType.StatusList2021, StatusListType.OAuthStatusList, StatusListType.BitstringStatusList].includes(assertedType)) {
14
+ if (![StatusListType.StatusList2021, StatusListType.OAuthStatusList].includes(assertedType)) {
15
15
  throw Error(`StatusList type ${assertedType} is not supported (yet)`)
16
16
  }
17
17
  return assertedType
@@ -39,9 +39,8 @@ export function getAssertedProperty<T extends object>(propertyName: string, obj:
39
39
  }
40
40
 
41
41
  const ValidProofTypeMap = new Map<StatusListType, CredentialProofFormat[]>([
42
- [StatusListType.StatusList2021, ['jwt', 'lds']],
42
+ [StatusListType.StatusList2021, ['jwt', 'lds', 'EthereumEip712Signature2021']],
43
43
  [StatusListType.OAuthStatusList, ['jwt', 'cbor']],
44
- [StatusListType.BitstringStatusList, ['lds']],
45
44
  ])
46
45
 
47
46
  export function assertValidProofType(type: StatusListType, proofFormat: CredentialProofFormat) {
@@ -94,35 +93,3 @@ export function determineProofFormat(credential: StatusListCredential): Credenti
94
93
  throw Error('Cannot determine credential payload type')
95
94
  }
96
95
  }
97
-
98
- /**
99
- * Ensures a value is converted to a Date object if it's a valid date string,
100
- * otherwise returns the original value or undefined
101
- *
102
- * @param value - The value to convert to Date (can be Date, string, or undefined)
103
- * @returns Date object, undefined, or the original value if conversion fails
104
- */
105
- export function ensureDate(value: Date | string | undefined): Date | undefined {
106
- if (value === undefined || value === null) {
107
- return undefined
108
- }
109
-
110
- if (value instanceof Date) {
111
- return value
112
- }
113
-
114
- if (typeof value === 'string') {
115
- if (value.trim() === '') {
116
- return undefined
117
- }
118
-
119
- const date = new Date(value)
120
- // Check if the date is valid
121
- if (isNaN(date.getTime())) {
122
- return undefined
123
- }
124
- return date
125
- }
126
-
127
- return undefined
128
- }
@@ -1,301 +0,0 @@
1
- import type { IAgentContext, ICredentialPlugin, ProofFormat as VeramoProofFormat } from '@veramo/core'
2
- import type { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution'
3
- import {
4
- CredentialMapper,
5
- type CredentialProofFormat,
6
- DocumentFormat,
7
- type IIssuer,
8
- type StatusListCredential,
9
- StatusListType,
10
- } from '@sphereon/ssi-types'
11
-
12
- import type { IStatusList } from './IStatusList'
13
- import {
14
- BitstringStatus,
15
- CheckStatusIndexArgs,
16
- CreateStatusListArgs,
17
- StatusListResult,
18
- ToStatusListDetailsArgs,
19
- UpdateStatusListFromEncodedListArgs,
20
- UpdateStatusListIndexArgs,
21
- } from '../types'
22
-
23
- import { assertValidProofType, ensureDate, getAssertedProperty, getAssertedValue, getAssertedValues } from '../utils'
24
- import { BitstringStatusListCredential } from '../types/BitstringStatusList'
25
- import { BitstreamStatusList, BitstringStatusPurpose, createStatusListCredential } from '@4sure-tech/vc-bitstring-status-lists'
26
-
27
- export const DEFAULT_LIST_LENGTH = 131072 // W3C spec minimum
28
- export const DEFAULT_PROOF_FORMAT = 'lds' as CredentialProofFormat
29
- export const DEFAULT_STATUS_PURPOSE: BitstringStatusPurpose = 'revocation'
30
-
31
- export class BitstringStatusListImplementation implements IStatusList {
32
- async createNewStatusList(
33
- args: CreateStatusListArgs,
34
- context: IAgentContext<ICredentialPlugin & IIdentifierResolution>,
35
- ): Promise<StatusListResult> {
36
- if (!args.bitstringStatusList) {
37
- throw new Error('BitstringStatusList options are required for type BitstringStatusList')
38
- }
39
-
40
- const length = args?.length ?? DEFAULT_LIST_LENGTH
41
- const proofFormat: CredentialProofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT
42
- assertValidProofType(StatusListType.BitstringStatusList, proofFormat)
43
- const veramoProofFormat: VeramoProofFormat = proofFormat as VeramoProofFormat
44
-
45
- const { issuer, id } = args
46
- const correlationId = getAssertedValue('correlationId', args.correlationId)
47
- const { statusPurpose, bitsPerStatus, validFrom, validUntil, ttl } = args.bitstringStatusList
48
- const statusListCredential = await this.createVerifiableCredential(
49
- {
50
- ...args,
51
- proofFormat: veramoProofFormat,
52
- statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
53
- validFrom: ensureDate(validFrom),
54
- validUntil: ensureDate(validUntil),
55
- ttl,
56
- },
57
- context,
58
- )
59
-
60
- return {
61
- encodedList: statusListCredential.credentialSubject.encodedList,
62
- statusListCredential: statusListCredential,
63
- bitstringStatusList: {
64
- statusPurpose: statusPurpose ?? DEFAULT_STATUS_PURPOSE,
65
- ...(statusListCredential.validFrom && { validFrom: new Date(statusListCredential.validFrom) }),
66
- ...(statusListCredential.validUntil && { validUntil: new Date(statusListCredential.validUntil) }),
67
- ttl,
68
- bitsPerStatus,
69
- },
70
- length,
71
- type: StatusListType.BitstringStatusList,
72
- proofFormat,
73
- id,
74
- correlationId,
75
- issuer,
76
- statuslistContentType: this.buildContentType(proofFormat),
77
- }
78
- }
79
-
80
- async updateStatusListIndex(
81
- args: UpdateStatusListIndexArgs,
82
- context: IAgentContext<ICredentialPlugin & IIdentifierResolution>,
83
- ): Promise<StatusListResult> {
84
- if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
85
- return Promise.reject('bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListIndex)')
86
- }
87
-
88
- const credential = args.statusListCredential
89
- const uniform = CredentialMapper.toUniformCredential(credential)
90
- const { issuer, credentialSubject } = uniform
91
- const id = getAssertedValue('id', uniform.id)
92
- const origEncodedList = getAssertedProperty('encodedList', credentialSubject)
93
-
94
- const index = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
95
- const statusList: BitstreamStatusList = await BitstreamStatusList.decode({ encodedList: origEncodedList, statusSize: args.bitsPerStatus })
96
- statusList.setStatus(index, args.value)
97
-
98
- const proofFormat = CredentialMapper.detectDocumentType(credential) === DocumentFormat.JWT ? 'jwt' : 'lds'
99
-
100
- const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject
101
-
102
- const statusPurpose = getAssertedProperty('statusPurpose', credSubject)
103
-
104
- const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : undefined
105
- const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : undefined
106
- const ttl = credSubject.ttl
107
-
108
- const updatedCredential = await this.createVerifiableCredential(
109
- {
110
- ...args,
111
- id,
112
- issuer,
113
- statusList,
114
- proofFormat: proofFormat,
115
- statusPurpose,
116
- ttl,
117
- validFrom,
118
- validUntil,
119
- },
120
- context,
121
- )
122
-
123
- return {
124
- statusListCredential: updatedCredential,
125
- encodedList: updatedCredential.credentialSubject.encodedList,
126
- bitstringStatusList: {
127
- statusPurpose,
128
- ...(updatedCredential.validFrom && { validFrom: new Date(updatedCredential.validFrom) }),
129
- ...(updatedCredential.validUntil && { validUntil: new Date(updatedCredential.validUntil) }),
130
- bitsPerStatus: args.bitsPerStatus,
131
- ttl,
132
- },
133
- length: statusList.getLength(),
134
- type: StatusListType.BitstringStatusList,
135
- proofFormat: proofFormat,
136
- id,
137
- issuer,
138
- statuslistContentType: this.buildContentType(proofFormat),
139
- }
140
- }
141
-
142
- async updateStatusListFromEncodedList(
143
- args: UpdateStatusListFromEncodedListArgs,
144
- context: IAgentContext<ICredentialPlugin & IIdentifierResolution>,
145
- ): Promise<StatusListResult> {
146
- if (!args.bitstringStatusList) {
147
- throw new Error('bitstringStatusList options required for type BitstringStatusList')
148
- }
149
-
150
- if (args.bitstringStatusList.bitsPerStatus < 1) {
151
- return Promise.reject('bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (updateStatusListFromEncodedList)')
152
- }
153
-
154
- const { statusPurpose, bitsPerStatus, ttl, validFrom, validUntil } = args.bitstringStatusList
155
-
156
- const proofFormat: CredentialProofFormat = args?.proofFormat ?? DEFAULT_PROOF_FORMAT
157
- assertValidProofType(StatusListType.BitstringStatusList, proofFormat)
158
- const veramoProofFormat: VeramoProofFormat = proofFormat as VeramoProofFormat
159
-
160
- const { issuer, id } = getAssertedValues(args)
161
- const statusList: BitstreamStatusList = await BitstreamStatusList.decode({ encodedList: args.encodedList, statusSize: bitsPerStatus })
162
- const index = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
163
- statusList.setStatus(index, args.value)
164
-
165
- const credential = await this.createVerifiableCredential(
166
- {
167
- id,
168
- issuer,
169
- statusList,
170
- proofFormat: veramoProofFormat,
171
- keyRef: args.keyRef,
172
- statusPurpose,
173
- validFrom: ensureDate(validFrom),
174
- validUntil: ensureDate(validUntil),
175
- ttl,
176
- },
177
- context,
178
- )
179
-
180
- return {
181
- type: StatusListType.BitstringStatusList,
182
- statusListCredential: credential,
183
- encodedList: credential.credentialSubject.encodedList,
184
- bitstringStatusList: {
185
- statusPurpose,
186
- bitsPerStatus,
187
- ...(credential.validFrom && { validFrom: new Date(credential.validFrom) }),
188
- ...(credential.validUntil && { validUntil: new Date(credential.validUntil) }),
189
- ttl,
190
- },
191
- length: statusList.getLength(),
192
- proofFormat: args.proofFormat ?? 'lds',
193
- id: id,
194
- issuer: issuer,
195
- statuslistContentType: this.buildContentType(proofFormat),
196
- }
197
- }
198
-
199
- async checkStatusIndex(args: CheckStatusIndexArgs): Promise<BitstringStatus> {
200
- if (!args.bitsPerStatus || args.bitsPerStatus < 1) {
201
- return Promise.reject('bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (checkStatusIndex)')
202
- }
203
-
204
- const uniform = CredentialMapper.toUniformCredential(args.statusListCredential)
205
- const { credentialSubject } = uniform
206
- const encodedList = getAssertedProperty('encodedList', credentialSubject)
207
-
208
- const statusSize = args.bitsPerStatus
209
- const statusList = await BitstreamStatusList.decode({ encodedList, statusSize })
210
-
211
- const numIndex = typeof args.statusListIndex === 'number' ? args.statusListIndex : parseInt(args.statusListIndex)
212
- if (statusList.getLength() <= numIndex) {
213
- throw new Error(`Status list index out of bounds, has ${statusList.getLength()} entries, requested ${numIndex}`)
214
- }
215
- return statusList.getStatus(numIndex)
216
- }
217
-
218
- async toStatusListDetails(args: ToStatusListDetailsArgs): Promise<StatusListResult> {
219
- const { statusListPayload, bitsPerStatus } = args
220
- if (!bitsPerStatus || bitsPerStatus < 1) {
221
- return Promise.reject('bitsPerStatus must be set for bitstring status lists and must be 1 or higher. (toStatusListDetails)')
222
- }
223
-
224
- const uniform = CredentialMapper.toUniformCredential(statusListPayload)
225
- const { issuer, credentialSubject } = uniform
226
- const id = getAssertedValue('id', uniform.id)
227
- const encodedList = getAssertedProperty('encodedList', credentialSubject)
228
- const proofFormat: CredentialProofFormat = CredentialMapper.detectDocumentType(statusListPayload) === DocumentFormat.JWT ? 'jwt' : 'lds'
229
- const credSubject = Array.isArray(credentialSubject) ? credentialSubject[0] : credentialSubject
230
- const statusPurpose = getAssertedProperty('statusPurpose', credSubject)
231
- const validFrom = uniform.validFrom ? new Date(uniform.validFrom) : undefined
232
- const validUntil = uniform.validUntil ? new Date(uniform.validUntil) : undefined
233
- const ttl = credSubject.ttl
234
- const statuslistLength: number = BitstreamStatusList.getStatusListLength(encodedList, bitsPerStatus)
235
-
236
- return {
237
- id,
238
- encodedList,
239
- issuer,
240
- type: StatusListType.BitstringStatusList,
241
- proofFormat,
242
- length: statuslistLength,
243
- statusListCredential: statusListPayload,
244
- statuslistContentType: this.buildContentType(proofFormat),
245
- bitstringStatusList: {
246
- statusPurpose,
247
- bitsPerStatus,
248
- validFrom,
249
- validUntil,
250
- ttl,
251
- },
252
- ...(args.correlationId && { correlationId: args.correlationId }),
253
- ...(args.driverType && { driverType: args.driverType }),
254
- }
255
- }
256
-
257
- private async createVerifiableCredential(
258
- args: {
259
- id: string
260
- issuer: string | IIssuer
261
- statusList?: BitstreamStatusList
262
- proofFormat: VeramoProofFormat
263
- statusPurpose: BitstringStatusPurpose
264
- validFrom?: Date
265
- validUntil?: Date
266
- ttl?: number
267
- keyRef?: string
268
- },
269
- context: IAgentContext<ICredentialPlugin & IIdentifierResolution>,
270
- ): Promise<BitstringStatusListCredential> {
271
- const identifier = await context.agent.identifierManagedGet({
272
- identifier: typeof args.issuer === 'string' ? args.issuer : args.issuer.id,
273
- vmRelationship: 'assertionMethod',
274
- offlineWhenNoDIDRegistered: true,
275
- })
276
-
277
- const unsignedCredential = await createStatusListCredential(args)
278
-
279
- const verifiableCredential = await context.agent.createVerifiableCredential({
280
- credential: unsignedCredential,
281
- keyRef: args.keyRef ?? identifier.kmsKeyRef,
282
- proofFormat: args.proofFormat,
283
- fetchRemoteContexts: true,
284
- })
285
-
286
- return CredentialMapper.toWrappedVerifiableCredential(verifiableCredential as StatusListCredential).original as BitstringStatusListCredential
287
- }
288
-
289
- private buildContentType(proofFormat: CredentialProofFormat | undefined) {
290
- switch (proofFormat) {
291
- case 'jwt':
292
- return `application/statuslist+jwt`
293
- case 'cbor':
294
- return `application/statuslist+cwt`
295
- case 'lds':
296
- return 'application/statuslist+ld+json'
297
- default:
298
- throw Error(`Unsupported content type '${proofFormat}' for status lists`)
299
- }
300
- }
301
- }
@@ -1,4 +0,0 @@
1
- import { StatusListCredential } from '@sphereon/ssi-types'
2
- import { BitstringStatusListCredentialUnsigned } from '../../../../../vc-bitstring-status-lists'
3
-
4
- export type BitstringStatusListCredential = BitstringStatusListCredentialUnsigned & StatusListCredential