import { TokenListStatus, Vc, } from '../shared/dto/decodedVerifiableCredential.dto.js'; import { CredentialStatus } from '../shared/dto/jsonCredential.dto.js'; export enum StatusListType { TokenStatusList = 'TokenStatusList', BitstringStatusList = 'BitstringStatusList', StatusList2021 = 'StatusList2021', RevocationList2021 = 'RevocationList2021', } export function parseStatusReferenceType( value: string | undefined, ): StatusListType { if (Object.values(StatusListType).includes(value as StatusListType)) { return value as StatusListType; } throw new Error(`StatusListType not supported: ${value}`); } export class StatusListReference { constructor( private readonly uri: string, private readonly index: number, private readonly type: StatusListType, ) {} static fromVc(input: Vc): StatusListReference { const isTokenStatusList = !!input?.status?.status_list; const isCredentialStatus = !!input?.credentialStatus; if (isTokenStatusList && isCredentialStatus) { throw new Error( 'Invalid status reference: both TokenStatusList and CredentialStatus present', ); } if (isTokenStatusList) { return StatusListReference.fromTokenStatusList(input.status); } if (isCredentialStatus) { return StatusListReference.fromCredentialStatus(input.credentialStatus); } throw new Error('Unsupported status reference format'); } private static fromTokenStatusList( status: TokenListStatus, ): StatusListReference { const entry = status.status_list; if (typeof entry.uri !== 'string') { throw new Error('Invalid TokenStatusList: missing uri'); } if (!Number.isInteger(entry.idx)) { throw new Error('Invalid TokenStatusList: idx must be integer'); } return new StatusListReference( entry.uri, entry.idx, StatusListType.TokenStatusList, ); } private static fromCredentialStatus( status: CredentialStatus, ): StatusListReference { const uri = status?.statusListCredential; const rawIndex = status?.statusListIndex; const type = status?.type as StatusListType; if (typeof uri !== 'string') { throw new Error('Invalid CredentialStatus: missing uri'); } if (rawIndex === undefined || rawIndex === null) { throw new Error('Invalid CredentialStatus: missing index'); } const index = Number(rawIndex); if (!Number.isInteger(index)) { throw new Error('Invalid CredentialStatus: index must be integer'); } return new StatusListReference(uri, index, type); } getUri(): string { return this.uri; } getIndex(): number { return this.index; } getType(): StatusListType { return this.type; } }