@sphereon/ssi-sdk.vc-status-list-issuer-drivers 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.cjs +29 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -6
- package/dist/index.d.ts +34 -6
- package/dist/index.js +30 -26
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
- package/src/drivers.ts +65 -32
- package/src/types.ts +12 -15
package/dist/index.cjs
CHANGED
|
@@ -169,11 +169,12 @@ var AgentDataSourceStatusListDriver = class _AgentDataSourceStatusListDriver {
|
|
|
169
169
|
throw Error("Either a correlationId needs to be set as an option, or it needs to be provided when creating a status list. None found");
|
|
170
170
|
}
|
|
171
171
|
const credentialIdMode = args.credentialIdMode ?? import_ssi_types2.StatusListCredentialIdMode.ISSUANCE;
|
|
172
|
-
const implementationResult = await (0, import_ssi_sdk4.
|
|
173
|
-
|
|
172
|
+
const implementationResult = await (0, import_ssi_sdk4.toStatusListDetails)({
|
|
173
|
+
statusListCredential: args.statusListCredential,
|
|
174
|
+
statusListType: args.statusListType,
|
|
175
|
+
bitsPerStatus: args.bitsPerStatus,
|
|
174
176
|
correlationId,
|
|
175
|
-
driverType: this.getType()
|
|
176
|
-
bitsPerStatus: args.bitsPerStatus
|
|
177
|
+
driverType: this.getType()
|
|
177
178
|
});
|
|
178
179
|
const statusListArgs = {
|
|
179
180
|
...implementationResult,
|
|
@@ -187,24 +188,19 @@ var AgentDataSourceStatusListDriver = class _AgentDataSourceStatusListDriver {
|
|
|
187
188
|
}
|
|
188
189
|
async updateStatusList(args) {
|
|
189
190
|
const correlationId = args.correlationId ?? this.options.correlationId;
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
});
|
|
195
|
-
const entity = await (await this.statusListStore.getStatusListRepo(args.type)).findOne({
|
|
196
|
-
where: [
|
|
197
|
-
{
|
|
198
|
-
id: details.id
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
correlationId
|
|
202
|
-
}
|
|
203
|
-
]
|
|
191
|
+
const extractedDetails = await (0, import_ssi_sdk4.extractCredentialDetails)(args.statusListCredential);
|
|
192
|
+
const entity = await this.statusListStore.getStatusList({
|
|
193
|
+
id: extractedDetails.id,
|
|
194
|
+
correlationId
|
|
204
195
|
});
|
|
205
196
|
if (!entity) {
|
|
206
|
-
throw Error(`Status list ${
|
|
197
|
+
throw Error(`Status list ${extractedDetails.id}, correlationId ${correlationId} could not be found`);
|
|
207
198
|
}
|
|
199
|
+
entity.statusListCredential = args.statusListCredential;
|
|
200
|
+
const details = await (0, import_ssi_sdk4.toStatusListDetails)({
|
|
201
|
+
extractedDetails,
|
|
202
|
+
statusListEntity: entity
|
|
203
|
+
});
|
|
208
204
|
const updateArgs = {
|
|
209
205
|
...entity,
|
|
210
206
|
...details,
|
|
@@ -286,19 +282,27 @@ var AgentDataSourceStatusListDriver = class _AgentDataSourceStatusListDriver {
|
|
|
286
282
|
async getStatusList(args) {
|
|
287
283
|
const id = this.options.id;
|
|
288
284
|
const correlationId = args?.correlationId ?? this.options.correlationId;
|
|
289
|
-
|
|
285
|
+
const statusListEntity = await this.statusListStore.getStatusList({
|
|
290
286
|
id,
|
|
291
287
|
correlationId
|
|
292
|
-
})
|
|
288
|
+
});
|
|
289
|
+
return await (0, import_ssi_sdk4.toStatusListDetails)({
|
|
293
290
|
statusListCredential: statusListEntity.statusListCredential,
|
|
294
|
-
|
|
295
|
-
|
|
291
|
+
statusListType: statusListEntity.type,
|
|
292
|
+
bitsPerStatus: statusListEntity.bitsPerStatus,
|
|
293
|
+
correlationId: statusListEntity.correlationId,
|
|
294
|
+
driverType: statusListEntity.driverType
|
|
295
|
+
});
|
|
296
296
|
}
|
|
297
297
|
async getStatusLists() {
|
|
298
298
|
const statusLists = await this.statusListStore.getStatusLists({});
|
|
299
299
|
return Promise.all(statusLists.map(async (statusListEntity) => {
|
|
300
|
-
return (0, import_ssi_sdk4.
|
|
301
|
-
statusListCredential: statusListEntity.statusListCredential
|
|
300
|
+
return (0, import_ssi_sdk4.toStatusListDetails)({
|
|
301
|
+
statusListCredential: statusListEntity.statusListCredential,
|
|
302
|
+
statusListType: statusListEntity.type,
|
|
303
|
+
bitsPerStatus: statusListEntity.bitsPerStatus,
|
|
304
|
+
correlationId: statusListEntity.correlationId,
|
|
305
|
+
driverType: statusListEntity.driverType
|
|
302
306
|
});
|
|
303
307
|
}));
|
|
304
308
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/drivers.ts","../src/status-list-adapters.ts"],"sourcesContent":["/**\n * @public\n */\nexport * from './types'\nexport * from './drivers'\n","import { DataSources } from '@sphereon/ssi-sdk.agent-config'\nimport {\n IAddStatusListArgs,\n IAddStatusListEntryArgs,\n IBitstringStatusListEntryEntity,\n IGetStatusListEntryByCredentialIdArgs,\n IGetStatusListEntryByIndexArgs,\n IStatusListEntity,\n IStatusListEntryEntity,\n StatusListEntity,\n StatusListStore,\n} from '@sphereon/ssi-sdk.data-store'\nimport {\n BitstringStatusListEntryCredentialStatus,\n createCredentialStatusFromStatusList,\n StatusList2021EntryCredentialStatus,\n statusListCredentialToDetails,\n StatusListOAuthEntryCredentialStatus,\n StatusListResult,\n} from '@sphereon/ssi-sdk.vc-status-list'\nimport { StatusListCredential, StatusListCredentialIdMode, StatusListDriverType, StatusListType } from '@sphereon/ssi-types'\nimport { DataSource } from 'typeorm'\nimport { IStatusListDriver } from './types'\nimport { statusListResultToEntity } from './status-list-adapters'\n\nexport interface StatusListManagementOptions {\n id?: string\n correlationId?: string\n driverType: StatusListDriverType\n driverOptions?: DriverOptions\n}\n\nexport type DriverOptions = TypeORMOptions\n\nexport interface TypeORMOptions {\n dbName?: string\n}\n\nexport interface FilesystemOptions {\n path: string // The base path where statusList Credentials will be persisted. Should be a folder and thus not include the VC/StatusList itself\n}\n\nexport function getOptions(args: { id?: string; correlationId?: string; dbName: string }): StatusListManagementOptions {\n return {\n id: args.id,\n correlationId: args.correlationId,\n driverType: StatusListDriverType.AGENT_TYPEORM,\n driverOptions: { dbName: args.dbName },\n }\n}\n\nexport async function getDriver(args: {\n id?: string\n correlationId?: string\n dbName?: string\n dataSource?: DataSource\n dataSources?: DataSources\n}): Promise<IStatusListDriver> {\n const dbName = args.dbName ?? args.dataSource?.name\n if (!dbName) {\n throw Error(`Please provide either a DB name or data source`)\n }\n const dataSources = args.dataSources ?? DataSources.singleInstance()\n return await AgentDataSourceStatusListDriver.init(\n getOptions({\n ...args,\n dbName,\n }),\n { dataSource: args.dataSource ?? (await dataSources.getDbConnection(dbName)), dataSources },\n )\n}\n\nexport class AgentDataSourceStatusListDriver implements IStatusListDriver {\n private _statusListLength: number | undefined\n\n constructor(\n private _dataSource: DataSource,\n private _statusListStore: StatusListStore,\n private options: StatusListManagementOptions,\n ) {}\n\n public static async init(\n options: StatusListManagementOptions,\n dbArgs?: {\n dataSources?: DataSources\n dataSource?: DataSource\n },\n ): Promise<AgentDataSourceStatusListDriver> {\n if (options.driverType !== StatusListDriverType.AGENT_TYPEORM) {\n throw Error(`TypeORM driver can only be used when the TypeORM driver type is selected in the configuration. Got: ${options.driverType}`)\n } else if (!options.driverOptions) {\n throw Error(`TypeORM driver can only be used when the TypeORM options are provided.`)\n }\n let dataSource: DataSource\n let statusListStore: StatusListStore\n if (dbArgs?.dataSource) {\n dataSource = dbArgs.dataSource\n } else if (options.driverOptions.dbName) {\n if (dbArgs?.dataSources) {\n dataSource = await dbArgs.dataSources.getDbConnection(options.driverOptions.dbName)\n } else {\n dataSource = await DataSources.singleInstance().getDbConnection(options.driverOptions.dbName)\n }\n } else {\n return Promise.reject(Error(`Either a datasource or dbName needs to be provided`))\n }\n\n statusListStore = new StatusListStore(dataSource)\n return new AgentDataSourceStatusListDriver(dataSource, statusListStore, options)\n }\n\n get dataSource(): DataSource {\n if (!this._dataSource) {\n throw Error(`Datasource not available yet for ${this.options.driverOptions?.dbName}`)\n }\n return this._dataSource\n }\n\n get statusListStore(): StatusListStore {\n if (!this._statusListStore) {\n this._statusListStore = new StatusListStore(this.dataSource)\n }\n return this._statusListStore\n }\n\n getOptions(): DriverOptions {\n return this.options.driverOptions ?? {}\n }\n\n getType(): StatusListDriverType {\n return this.options.driverType\n }\n\n async createStatusList(args: {\n statusListCredential: StatusListCredential\n correlationId?: string\n credentialIdMode?: StatusListCredentialIdMode\n bitsPerStatus?: number\n }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n if (!correlationId) {\n throw Error('Either a correlationId needs to be set as an option, or it needs to be provided when creating a status list. None found')\n }\n const credentialIdMode = args.credentialIdMode ?? StatusListCredentialIdMode.ISSUANCE\n\n // Get implementation details\n const implementationResult = await statusListCredentialToDetails({\n ...args,\n correlationId,\n driverType: this.getType(),\n bitsPerStatus: args.bitsPerStatus,\n })\n\n // Add driver-specific fields to create complete entity\n const statusListArgs = {\n ...implementationResult,\n credentialIdMode,\n correlationId,\n driverType: this.getType(),\n } as IAddStatusListArgs\n\n await this.statusListStore.addStatusList(statusListArgs)\n this._statusListLength = implementationResult.length\n return implementationResult\n }\n async updateStatusList(args: {\n statusListCredential: StatusListCredential\n correlationId: string\n type: StatusListType\n }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n const details = await statusListCredentialToDetails({ ...args, correlationId, driverType: this.getType() })\n const entity = await (\n await this.statusListStore.getStatusListRepo(args.type)\n ).findOne({\n where: [\n {\n id: details.id,\n },\n {\n correlationId,\n },\n ],\n })\n if (!entity) {\n throw Error(`Status list ${details.id}, correlationId ${args.correlationId} could not be found`)\n }\n\n // Merge details with existing entity and driver properties\n const updateArgs = {\n ...entity,\n ...details,\n correlationId,\n driverType: this.getType(),\n } as IAddStatusListArgs\n\n await this.statusListStore.updateStatusList(updateArgs)\n this._statusListLength = details.length\n return { ...entity, ...details }\n }\n\n async deleteStatusList(): Promise<boolean> {\n await this.statusListStore.removeStatusList({ id: this.options.id, correlationId: this.options.correlationId })\n return Promise.resolve(true)\n }\n\n async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<{\n credentialStatus: StatusList2021EntryCredentialStatus | StatusListOAuthEntryCredentialStatus | BitstringStatusListEntryCredentialStatus\n statusListEntry: IStatusListEntryEntity | IBitstringStatusListEntryEntity\n }> {\n // Get status list entity\n const statusListEntity: StatusListEntity = statusListResultToEntity(await this.getStatusList())\n\n // Update the entry in the store\n const statusListEntry = await this.statusListStore.updateStatusListEntry({ ...args, statusListId: statusListEntity.id })\n\n // Use implementation to create the credential status - this moves type-specific logic to implementations\n const credentialStatus = await createCredentialStatusFromStatusList({\n statusList: statusListEntity,\n statusListEntry,\n statusListIndex: statusListEntry.statusListIndex,\n })\n\n return {\n credentialStatus,\n statusListEntry,\n }\n }\n\n async getStatusListEntryByCredentialId(\n args: IGetStatusListEntryByCredentialIdArgs,\n ): Promise<IStatusListEntryEntity | IBitstringStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByCredentialId(args)\n }\n\n async getStatusListEntryByIndex(\n args: IGetStatusListEntryByIndexArgs,\n ): Promise<IStatusListEntryEntity | IBitstringStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByIndex(args)\n }\n\n async getRandomNewStatusListIndex(args?: { correlationId?: string }): Promise<number> {\n let result = -1\n let tries = 0\n while (result < 0) {\n // no tries guard, because we will throw an error when they are exhausted anyway\n result = await this.getRandomNewStatusListIndexImpl(tries++, args)\n }\n return result\n }\n\n private async getRandomNewStatusListIndexImpl(tries: number, args?: { correlationId?: string }): Promise<number> {\n const statusListId = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n if (tries >= 10) {\n throw Error(`We could not find any random status list index that is available in the statuslist ${statusListId}`)\n }\n // TODO: Check against DB\n const length = await this.getStatusListLength(args)\n const statusListIndex = Array.from({ length: 20 }, () => Math.floor(Math.random() * length))\n const available = await this.statusListStore.availableStatusListEntries({\n statusListId,\n ...(correlationId && { correlationId }),\n statusListIndex,\n })\n if (available.length > 0) {\n return available[0] // doesn't matter we pick the first element, as they are all random anyway\n }\n return -1\n }\n\n async getStatusListLength(args?: { correlationId?: string }): Promise<number> {\n if (!this._statusListLength) {\n this._statusListLength = await this.getStatusList(args).then((details) => details.length)\n }\n return this._statusListLength!\n }\n\n async getStatusList(args?: { correlationId?: string }): Promise<StatusListResult> {\n const id = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n return await this.statusListStore.getStatusList({ id, correlationId }).then((statusListEntity: IStatusListEntity) =>\n statusListCredentialToDetails({\n statusListCredential: statusListEntity.statusListCredential!,\n bitsPerStatus: statusListEntity.bitsPerStatus,\n }),\n )\n }\n\n async getStatusLists(): Promise<Array<StatusListResult>> {\n const statusLists = await this.statusListStore.getStatusLists({})\n return Promise.all(\n statusLists.map(async (statusListEntity) => {\n return statusListCredentialToDetails({\n statusListCredential: statusListEntity.statusListCredential!,\n })\n }),\n )\n }\n\n isStatusListIndexInUse(): Promise<boolean> {\n return Promise.resolve(false)\n }\n}\n","import { StatusListType } from '@sphereon/ssi-types'\nimport { BitstringStatusListEntity, OAuthStatusListEntity, StatusList2021Entity } from '@sphereon/ssi-sdk.data-store'\nimport { StatusListResult } from '@sphereon/ssi-sdk.vc-status-list'\n\nexport function statusListResultToEntity(result: StatusListResult): StatusList2021Entity | OAuthStatusListEntity | BitstringStatusListEntity {\n const baseFields = {\n id: result.id,\n correlationId: result.correlationId,\n driverType: result.driverType,\n credentialIdMode: result.credentialIdMode,\n length: result.length,\n issuer: result.issuer,\n type: result.type,\n proofFormat: result.proofFormat,\n statusListCredential: result.statusListCredential,\n }\n\n if (result.type === StatusListType.StatusList2021) {\n if (!result.statusList2021) {\n throw new Error('Missing statusList2021 details')\n }\n return Object.assign(new StatusList2021Entity(), {\n ...baseFields,\n indexingDirection: result.statusList2021.indexingDirection,\n statusPurpose: result.statusList2021.statusPurpose,\n })\n } else if (result.type === StatusListType.OAuthStatusList) {\n if (!result.oauthStatusList) {\n throw new Error('Missing oauthStatusList details')\n }\n return Object.assign(new OAuthStatusListEntity(), {\n ...baseFields,\n bitsPerStatus: result.oauthStatusList.bitsPerStatus,\n expiresAt: result.oauthStatusList.expiresAt,\n })\n } else if (result.type === StatusListType.BitstringStatusList) {\n if (!result.bitstringStatusList) {\n throw new Error('Missing bitstringStatusList details')\n }\n return Object.assign(new BitstringStatusListEntity(), {\n ...baseFields,\n statusPurpose: result.bitstringStatusList.statusPurpose,\n ttl: result.bitstringStatusList.ttl,\n bitsPerStatus: result.bitstringStatusList.bitsPerStatus,\n validFrom: result.bitstringStatusList.validFrom,\n validUntil: result.bitstringStatusList.validUntil,\n })\n }\n throw new Error(`Unsupported status list type: ${result.type}`)\n}\n"],"mappings":"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","names":["import_ssi_sdk","import_ssi_types","statusListResultToEntity","result","baseFields","id","correlationId","driverType","credentialIdMode","length","issuer","type","proofFormat","statusListCredential","StatusListType","StatusList2021","statusList2021","Error","Object","assign","StatusList2021Entity","indexingDirection","statusPurpose","OAuthStatusList","oauthStatusList","OAuthStatusListEntity","bitsPerStatus","expiresAt","BitstringStatusList","bitstringStatusList","BitstringStatusListEntity","ttl","validFrom","validUntil","getOptions","args","id","correlationId","driverType","StatusListDriverType","AGENT_TYPEORM","driverOptions","dbName","getDriver","dataSource","name","Error","dataSources","DataSources","singleInstance","AgentDataSourceStatusListDriver","init","getDbConnection","_statusListLength","constructor","_dataSource","_statusListStore","options","dbArgs","statusListStore","Promise","reject","StatusListStore","getType","createStatusList","credentialIdMode","StatusListCredentialIdMode","ISSUANCE","implementationResult","statusListCredentialToDetails","bitsPerStatus","statusListArgs","addStatusList","length","updateStatusList","details","entity","getStatusListRepo","type","findOne","where","updateArgs","deleteStatusList","removeStatusList","resolve","updateStatusListEntry","statusListEntity","statusListResultToEntity","getStatusList","statusListEntry","statusListId","credentialStatus","createCredentialStatusFromStatusList","statusList","statusListIndex","getStatusListEntryByCredentialId","getStatusListEntryByIndex","getRandomNewStatusListIndex","result","tries","getRandomNewStatusListIndexImpl","getStatusListLength","Array","from","Math","floor","random","available","availableStatusListEntries","then","statusListCredential","getStatusLists","statusLists","all","map","isStatusListIndexInUse"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/drivers.ts","../src/status-list-adapters.ts"],"sourcesContent":["/**\n * @public\n */\nexport * from './types'\nexport * from './drivers'\n","/**\n * StatusList Driver Implementation for TypeORM/Agent Data Sources\n *\n * This module provides the database-backed implementation of the IStatusListDriver interface,\n * handling persistence and retrieval of status list credentials and entries using TypeORM.\n * It delegates status list format-specific operations to the functions layer while managing\n * database interactions, driver configuration, and entity lifecycle.\n *\n * Key responsibilities:\n * - Database connection and store management\n * - Status list CRUD operations\n * - Status list entry management\n * - Random index generation for new entries\n * - Integration with multiple data sources\n *\n * @author Sphereon International B.V.\n * @since 2024\n */\n\nimport { DataSources } from '@sphereon/ssi-sdk.agent-config'\nimport {\n BitstringStatusListEntryCredentialStatus,\n IAddStatusListArgs,\n IAddStatusListEntryArgs,\n IBitstringStatusListEntryEntity,\n IGetStatusListEntryByCredentialIdArgs,\n IGetStatusListEntryByIndexArgs,\n IStatusListEntryEntity,\n StatusListEntity,\n StatusListStore,\n} from '@sphereon/ssi-sdk.data-store'\nimport {\n createCredentialStatusFromStatusList,\n extractCredentialDetails,\n StatusList2021EntryCredentialStatus,\n StatusListOAuthEntryCredentialStatus,\n StatusListResult,\n toStatusListDetails,\n} from '@sphereon/ssi-sdk.vc-status-list'\nimport { StatusListCredential, StatusListCredentialIdMode, StatusListDriverType, StatusListType } from '@sphereon/ssi-types'\nimport { DataSource } from 'typeorm'\nimport { IStatusListDriver } from './types'\nimport { statusListResultToEntity } from './status-list-adapters'\n\nexport interface StatusListManagementOptions {\n id?: string\n correlationId?: string\n driverType: StatusListDriverType\n driverOptions?: DriverOptions\n}\n\nexport type DriverOptions = TypeORMOptions\n\nexport interface TypeORMOptions {\n dbName?: string\n}\n\nexport interface FilesystemOptions {\n path: string // The base path where statusList Credentials will be persisted. Should be a folder and thus not include the VC/StatusList itself\n}\n\nexport function getOptions(args: { id?: string; correlationId?: string; dbName: string }): StatusListManagementOptions {\n return {\n id: args.id,\n correlationId: args.correlationId,\n driverType: StatusListDriverType.AGENT_TYPEORM,\n driverOptions: { dbName: args.dbName },\n }\n}\n\nexport async function getDriver(args: {\n id?: string\n correlationId?: string\n dbName?: string\n dataSource?: DataSource\n dataSources?: DataSources\n}): Promise<IStatusListDriver> {\n const dbName = args.dbName ?? args.dataSource?.name\n if (!dbName) {\n throw Error(`Please provide either a DB name or data source`)\n }\n const dataSources = args.dataSources ?? DataSources.singleInstance()\n return await AgentDataSourceStatusListDriver.init(\n getOptions({\n ...args,\n dbName,\n }),\n { dataSource: args.dataSource ?? (await dataSources.getDbConnection(dbName)), dataSources },\n )\n}\n\n/**\n * TypeORM-based implementation of the IStatusListDriver interface\n *\n * Manages status list credentials and entries using a TypeORM data source.\n * Handles database operations while delegating format-specific logic to the functions layer.\n */\nexport class AgentDataSourceStatusListDriver implements IStatusListDriver {\n private _statusListLength: number | undefined\n\n constructor(\n private _dataSource: DataSource,\n private _statusListStore: StatusListStore,\n private options: StatusListManagementOptions,\n ) {}\n\n public static async init(\n options: StatusListManagementOptions,\n dbArgs?: {\n dataSources?: DataSources\n dataSource?: DataSource\n },\n ): Promise<AgentDataSourceStatusListDriver> {\n if (options.driverType !== StatusListDriverType.AGENT_TYPEORM) {\n throw Error(`TypeORM driver can only be used when the TypeORM driver type is selected in the configuration. Got: ${options.driverType}`)\n } else if (!options.driverOptions) {\n throw Error(`TypeORM driver can only be used when the TypeORM options are provided.`)\n }\n let dataSource: DataSource\n let statusListStore: StatusListStore\n if (dbArgs?.dataSource) {\n dataSource = dbArgs.dataSource\n } else if (options.driverOptions.dbName) {\n if (dbArgs?.dataSources) {\n dataSource = await dbArgs.dataSources.getDbConnection(options.driverOptions.dbName)\n } else {\n dataSource = await DataSources.singleInstance().getDbConnection(options.driverOptions.dbName)\n }\n } else {\n return Promise.reject(Error(`Either a datasource or dbName needs to be provided`))\n }\n\n statusListStore = new StatusListStore(dataSource)\n return new AgentDataSourceStatusListDriver(dataSource, statusListStore, options)\n }\n\n get dataSource(): DataSource {\n if (!this._dataSource) {\n throw Error(`Datasource not available yet for ${this.options.driverOptions?.dbName}`)\n }\n return this._dataSource\n }\n\n get statusListStore(): StatusListStore {\n if (!this._statusListStore) {\n this._statusListStore = new StatusListStore(this.dataSource)\n }\n return this._statusListStore\n }\n\n getOptions(): DriverOptions {\n return this.options.driverOptions ?? {}\n }\n\n getType(): StatusListDriverType {\n return this.options.driverType\n }\n\n async createStatusList(args: {\n statusListType: StatusListType\n statusListCredential: StatusListCredential\n correlationId?: string\n credentialIdMode?: StatusListCredentialIdMode\n bitsPerStatus?: number\n }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n if (!correlationId) {\n throw Error('Either a correlationId needs to be set as an option, or it needs to be provided when creating a status list. None found')\n }\n const credentialIdMode = args.credentialIdMode ?? StatusListCredentialIdMode.ISSUANCE\n\n // Convert credential to implementation details using CREATE/READ context\n const implementationResult = await toStatusListDetails({\n statusListCredential: args.statusListCredential,\n statusListType: args.statusListType,\n bitsPerStatus: args.bitsPerStatus,\n correlationId,\n driverType: this.getType(),\n })\n\n // Add driver-specific fields to create complete entity\n const statusListArgs = {\n ...implementationResult,\n credentialIdMode,\n correlationId,\n driverType: this.getType(),\n } as IAddStatusListArgs\n\n await this.statusListStore.addStatusList(statusListArgs)\n this._statusListLength = implementationResult.length\n return implementationResult\n }\n\n async updateStatusList(args: { statusListCredential: StatusListCredential; correlationId: string }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n\n const extractedDetails = await extractCredentialDetails(args.statusListCredential)\n const entity = await this.statusListStore.getStatusList({\n id: extractedDetails.id,\n correlationId,\n })\n if (!entity) {\n throw Error(`Status list ${extractedDetails.id}, correlationId ${correlationId} could not be found`)\n }\n\n entity.statusListCredential = args.statusListCredential\n\n const details = await toStatusListDetails({\n extractedDetails,\n statusListEntity: entity,\n })\n\n // Merge details with existing entity and driver properties\n const updateArgs = {\n ...entity,\n ...details,\n correlationId,\n driverType: this.getType(),\n } as IAddStatusListArgs\n\n await this.statusListStore.updateStatusList(updateArgs)\n this._statusListLength = details.length\n return { ...entity, ...details }\n }\n\n async deleteStatusList(): Promise<boolean> {\n await this.statusListStore.removeStatusList({ id: this.options.id, correlationId: this.options.correlationId })\n return Promise.resolve(true)\n }\n\n async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<{\n credentialStatus: StatusList2021EntryCredentialStatus | StatusListOAuthEntryCredentialStatus | BitstringStatusListEntryCredentialStatus\n statusListEntry: IStatusListEntryEntity | IBitstringStatusListEntryEntity\n }> {\n // Get status list entity\n const statusListEntity: StatusListEntity = statusListResultToEntity(await this.getStatusList())\n\n // Update the entry in the store\n const statusListEntry = await this.statusListStore.updateStatusListEntry({ ...args, statusListId: statusListEntity.id })\n\n // Use implementation to create the credential status - this moves type-specific logic to implementations\n const credentialStatus = await createCredentialStatusFromStatusList({\n statusList: statusListEntity,\n statusListEntry,\n statusListIndex: statusListEntry.statusListIndex,\n })\n\n return {\n credentialStatus,\n statusListEntry,\n }\n }\n\n async getStatusListEntryByCredentialId(\n args: IGetStatusListEntryByCredentialIdArgs,\n ): Promise<IStatusListEntryEntity | IBitstringStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByCredentialId(args)\n }\n\n async getStatusListEntryByIndex(\n args: IGetStatusListEntryByIndexArgs,\n ): Promise<IStatusListEntryEntity | IBitstringStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByIndex(args)\n }\n\n async getRandomNewStatusListIndex(args?: { correlationId?: string }): Promise<number> {\n let result = -1\n let tries = 0\n while (result < 0) {\n // no tries guard, because we will throw an error when they are exhausted anyway\n result = await this.getRandomNewStatusListIndexImpl(tries++, args)\n }\n return result\n }\n\n private async getRandomNewStatusListIndexImpl(tries: number, args?: { correlationId?: string }): Promise<number> {\n const statusListId = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n if (tries >= 10) {\n throw Error(`We could not find any random status list index that is available in the statuslist ${statusListId}`)\n }\n // TODO: Check against DB\n const length = await this.getStatusListLength(args)\n const statusListIndex = Array.from({ length: 20 }, () => Math.floor(Math.random() * length))\n const available = await this.statusListStore.availableStatusListEntries({\n statusListId,\n ...(correlationId && { correlationId }),\n statusListIndex,\n })\n if (available.length > 0) {\n return available[0] // doesn't matter we pick the first element, as they are all random anyway\n }\n return -1\n }\n\n async getStatusListLength(args?: { correlationId?: string }): Promise<number> {\n if (!this._statusListLength) {\n this._statusListLength = await this.getStatusList(args).then((details) => details.length)\n }\n return this._statusListLength!\n }\n\n async getStatusList(args?: { correlationId?: string }): Promise<StatusListResult> {\n const id = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n\n const statusListEntity = await this.statusListStore.getStatusList({ id, correlationId })\n\n // Convert entity to result using CREATE/READ context\n return await toStatusListDetails({\n statusListCredential: statusListEntity.statusListCredential!,\n statusListType: statusListEntity.type,\n bitsPerStatus: statusListEntity.bitsPerStatus,\n correlationId: statusListEntity.correlationId,\n driverType: statusListEntity.driverType,\n })\n }\n\n async getStatusLists(): Promise<Array<StatusListResult>> {\n const statusLists = await this.statusListStore.getStatusLists({})\n return Promise.all(\n statusLists.map(async (statusListEntity) => {\n return toStatusListDetails({\n statusListCredential: statusListEntity.statusListCredential!,\n statusListType: statusListEntity.type,\n bitsPerStatus: statusListEntity.bitsPerStatus,\n correlationId: statusListEntity.correlationId,\n driverType: statusListEntity.driverType,\n })\n }),\n )\n }\n\n isStatusListIndexInUse(): Promise<boolean> {\n return Promise.resolve(false)\n }\n}\n","import { StatusListType } from '@sphereon/ssi-types'\nimport { BitstringStatusListEntity, OAuthStatusListEntity, StatusList2021Entity } from '@sphereon/ssi-sdk.data-store'\nimport { StatusListResult } from '@sphereon/ssi-sdk.vc-status-list'\n\nexport function statusListResultToEntity(result: StatusListResult): StatusList2021Entity | OAuthStatusListEntity | BitstringStatusListEntity {\n const baseFields = {\n id: result.id,\n correlationId: result.correlationId,\n driverType: result.driverType,\n credentialIdMode: result.credentialIdMode,\n length: result.length,\n issuer: result.issuer,\n type: result.type,\n proofFormat: result.proofFormat,\n statusListCredential: result.statusListCredential,\n }\n\n if (result.type === StatusListType.StatusList2021) {\n if (!result.statusList2021) {\n throw new Error('Missing statusList2021 details')\n }\n return Object.assign(new StatusList2021Entity(), {\n ...baseFields,\n indexingDirection: result.statusList2021.indexingDirection,\n statusPurpose: result.statusList2021.statusPurpose,\n })\n } else if (result.type === StatusListType.OAuthStatusList) {\n if (!result.oauthStatusList) {\n throw new Error('Missing oauthStatusList details')\n }\n return Object.assign(new OAuthStatusListEntity(), {\n ...baseFields,\n bitsPerStatus: result.oauthStatusList.bitsPerStatus,\n expiresAt: result.oauthStatusList.expiresAt,\n })\n } else if (result.type === StatusListType.BitstringStatusList) {\n if (!result.bitstringStatusList) {\n throw new Error('Missing bitstringStatusList details')\n }\n return Object.assign(new BitstringStatusListEntity(), {\n ...baseFields,\n statusPurpose: result.bitstringStatusList.statusPurpose,\n ttl: result.bitstringStatusList.ttl,\n bitsPerStatus: result.bitstringStatusList.bitsPerStatus,\n validFrom: result.bitstringStatusList.validFrom,\n validUntil: result.bitstringStatusList.validUntil,\n })\n }\n throw new Error(`Unsupported status list type: ${result.type}`)\n}\n"],"mappings":"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","names":["import_ssi_sdk","import_ssi_types","statusListResultToEntity","result","baseFields","id","correlationId","driverType","credentialIdMode","length","issuer","type","proofFormat","statusListCredential","StatusListType","StatusList2021","statusList2021","Error","Object","assign","StatusList2021Entity","indexingDirection","statusPurpose","OAuthStatusList","oauthStatusList","OAuthStatusListEntity","bitsPerStatus","expiresAt","BitstringStatusList","bitstringStatusList","BitstringStatusListEntity","ttl","validFrom","validUntil","getOptions","args","id","correlationId","driverType","StatusListDriverType","AGENT_TYPEORM","driverOptions","dbName","getDriver","dataSource","name","Error","dataSources","DataSources","singleInstance","AgentDataSourceStatusListDriver","init","getDbConnection","_statusListLength","constructor","_dataSource","_statusListStore","options","dbArgs","statusListStore","Promise","reject","StatusListStore","getType","createStatusList","credentialIdMode","StatusListCredentialIdMode","ISSUANCE","implementationResult","toStatusListDetails","statusListCredential","statusListType","bitsPerStatus","statusListArgs","addStatusList","length","updateStatusList","extractedDetails","extractCredentialDetails","entity","getStatusList","details","statusListEntity","updateArgs","deleteStatusList","removeStatusList","resolve","updateStatusListEntry","statusListResultToEntity","statusListEntry","statusListId","credentialStatus","createCredentialStatusFromStatusList","statusList","statusListIndex","getStatusListEntryByCredentialId","getStatusListEntryByIndex","getRandomNewStatusListIndex","result","tries","getRandomNewStatusListIndexImpl","getStatusListLength","Array","from","Math","floor","random","available","availableStatusListEntries","then","type","getStatusLists","statusLists","all","map","isStatusListIndexInUse"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
import { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution';
|
|
2
|
-
import { StatusListStore, IAddStatusListEntryArgs, IStatusListEntryEntity, IBitstringStatusListEntryEntity, IGetStatusListEntryByCredentialIdArgs, IGetStatusListEntryByIndexArgs } from '@sphereon/ssi-sdk.data-store';
|
|
3
|
-
import { StatusListResult, StatusList2021EntryCredentialStatus, StatusListOAuthEntryCredentialStatus,
|
|
4
|
-
import { StatusListDriverType, StatusListCredential, StatusListCredentialIdMode
|
|
5
|
-
import { IDataStoreORM, IDIDManager, IKeyManager, ICredentialIssuer, ICredentialVerifier,
|
|
2
|
+
import { StatusListStore, IAddStatusListEntryArgs, BitstringStatusListEntryCredentialStatus, IStatusListEntryEntity, IBitstringStatusListEntryEntity, IGetStatusListEntryByCredentialIdArgs, IGetStatusListEntryByIndexArgs } from '@sphereon/ssi-sdk.data-store';
|
|
3
|
+
import { StatusListResult, StatusList2021EntryCredentialStatus, StatusListOAuthEntryCredentialStatus, IStatusListPlugin } from '@sphereon/ssi-sdk.vc-status-list';
|
|
4
|
+
import { StatusListDriverType, StatusListType, StatusListCredential, StatusListCredentialIdMode } from '@sphereon/ssi-types';
|
|
5
|
+
import { IDataStoreORM, IDIDManager, IKeyManager, ICredentialIssuer, ICredentialVerifier, IResolver, IAgentContext } from '@veramo/core';
|
|
6
6
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config';
|
|
7
7
|
import { DataSource } from 'typeorm';
|
|
8
|
+
import { IVcdmCredentialPlugin } from '@sphereon/ssi-sdk.credential-vcdm';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* StatusList Driver Implementation for TypeORM/Agent Data Sources
|
|
12
|
+
*
|
|
13
|
+
* This module provides the database-backed implementation of the IStatusListDriver interface,
|
|
14
|
+
* handling persistence and retrieval of status list credentials and entries using TypeORM.
|
|
15
|
+
* It delegates status list format-specific operations to the functions layer while managing
|
|
16
|
+
* database interactions, driver configuration, and entity lifecycle.
|
|
17
|
+
*
|
|
18
|
+
* Key responsibilities:
|
|
19
|
+
* - Database connection and store management
|
|
20
|
+
* - Status list CRUD operations
|
|
21
|
+
* - Status list entry management
|
|
22
|
+
* - Random index generation for new entries
|
|
23
|
+
* - Integration with multiple data sources
|
|
24
|
+
*
|
|
25
|
+
* @author Sphereon International B.V.
|
|
26
|
+
* @since 2024
|
|
27
|
+
*/
|
|
8
28
|
|
|
9
29
|
interface StatusListManagementOptions {
|
|
10
30
|
id?: string;
|
|
@@ -31,6 +51,12 @@ declare function getDriver(args: {
|
|
|
31
51
|
dataSource?: DataSource;
|
|
32
52
|
dataSources?: DataSources;
|
|
33
53
|
}): Promise<IStatusListDriver>;
|
|
54
|
+
/**
|
|
55
|
+
* TypeORM-based implementation of the IStatusListDriver interface
|
|
56
|
+
*
|
|
57
|
+
* Manages status list credentials and entries using a TypeORM data source.
|
|
58
|
+
* Handles database operations while delegating format-specific logic to the functions layer.
|
|
59
|
+
*/
|
|
34
60
|
declare class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
35
61
|
private _dataSource;
|
|
36
62
|
private _statusListStore;
|
|
@@ -46,6 +72,7 @@ declare class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
46
72
|
getOptions(): DriverOptions;
|
|
47
73
|
getType(): StatusListDriverType;
|
|
48
74
|
createStatusList(args: {
|
|
75
|
+
statusListType: StatusListType;
|
|
49
76
|
statusListCredential: StatusListCredential;
|
|
50
77
|
correlationId?: string;
|
|
51
78
|
credentialIdMode?: StatusListCredentialIdMode;
|
|
@@ -54,7 +81,6 @@ declare class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
54
81
|
updateStatusList(args: {
|
|
55
82
|
statusListCredential: StatusListCredential;
|
|
56
83
|
correlationId: string;
|
|
57
|
-
type: StatusListType;
|
|
58
84
|
}): Promise<StatusListResult>;
|
|
59
85
|
deleteStatusList(): Promise<boolean>;
|
|
60
86
|
updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<{
|
|
@@ -77,7 +103,7 @@ declare class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
77
103
|
isStatusListIndexInUse(): Promise<boolean>;
|
|
78
104
|
}
|
|
79
105
|
|
|
80
|
-
type IRequiredPlugins = IDataStoreORM & IDIDManager & IKeyManager & IIdentifierResolution & ICredentialIssuer & ICredentialVerifier &
|
|
106
|
+
type IRequiredPlugins = IDataStoreORM & IDIDManager & IKeyManager & IIdentifierResolution & ICredentialIssuer & ICredentialVerifier & IVcdmCredentialPlugin & IStatusListPlugin & IResolver;
|
|
81
107
|
type IRequiredContext = IAgentContext<IRequiredPlugins>;
|
|
82
108
|
interface IStatusListDriver {
|
|
83
109
|
statusListStore: StatusListStore;
|
|
@@ -87,6 +113,7 @@ interface IStatusListDriver {
|
|
|
87
113
|
correlationId?: string;
|
|
88
114
|
}): Promise<number>;
|
|
89
115
|
createStatusList(args: {
|
|
116
|
+
statusListType: StatusListType;
|
|
90
117
|
statusListCredential: StatusListCredential;
|
|
91
118
|
correlationId?: string;
|
|
92
119
|
bitsPerStatus?: number;
|
|
@@ -103,6 +130,7 @@ interface IStatusListDriver {
|
|
|
103
130
|
getStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<IStatusListEntryEntity | undefined>;
|
|
104
131
|
updateStatusList(args: {
|
|
105
132
|
statusListCredential: StatusListCredential;
|
|
133
|
+
correlationId: string;
|
|
106
134
|
}): Promise<StatusListResult>;
|
|
107
135
|
deleteStatusList(): Promise<boolean>;
|
|
108
136
|
getRandomNewStatusListIndex(args?: {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
import { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution';
|
|
2
|
-
import { StatusListStore, IAddStatusListEntryArgs, IStatusListEntryEntity, IBitstringStatusListEntryEntity, IGetStatusListEntryByCredentialIdArgs, IGetStatusListEntryByIndexArgs } from '@sphereon/ssi-sdk.data-store';
|
|
3
|
-
import { StatusListResult, StatusList2021EntryCredentialStatus, StatusListOAuthEntryCredentialStatus,
|
|
4
|
-
import { StatusListDriverType, StatusListCredential, StatusListCredentialIdMode
|
|
5
|
-
import { IDataStoreORM, IDIDManager, IKeyManager, ICredentialIssuer, ICredentialVerifier,
|
|
2
|
+
import { StatusListStore, IAddStatusListEntryArgs, BitstringStatusListEntryCredentialStatus, IStatusListEntryEntity, IBitstringStatusListEntryEntity, IGetStatusListEntryByCredentialIdArgs, IGetStatusListEntryByIndexArgs } from '@sphereon/ssi-sdk.data-store';
|
|
3
|
+
import { StatusListResult, StatusList2021EntryCredentialStatus, StatusListOAuthEntryCredentialStatus, IStatusListPlugin } from '@sphereon/ssi-sdk.vc-status-list';
|
|
4
|
+
import { StatusListDriverType, StatusListType, StatusListCredential, StatusListCredentialIdMode } from '@sphereon/ssi-types';
|
|
5
|
+
import { IDataStoreORM, IDIDManager, IKeyManager, ICredentialIssuer, ICredentialVerifier, IResolver, IAgentContext } from '@veramo/core';
|
|
6
6
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config';
|
|
7
7
|
import { DataSource } from 'typeorm';
|
|
8
|
+
import { IVcdmCredentialPlugin } from '@sphereon/ssi-sdk.credential-vcdm';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* StatusList Driver Implementation for TypeORM/Agent Data Sources
|
|
12
|
+
*
|
|
13
|
+
* This module provides the database-backed implementation of the IStatusListDriver interface,
|
|
14
|
+
* handling persistence and retrieval of status list credentials and entries using TypeORM.
|
|
15
|
+
* It delegates status list format-specific operations to the functions layer while managing
|
|
16
|
+
* database interactions, driver configuration, and entity lifecycle.
|
|
17
|
+
*
|
|
18
|
+
* Key responsibilities:
|
|
19
|
+
* - Database connection and store management
|
|
20
|
+
* - Status list CRUD operations
|
|
21
|
+
* - Status list entry management
|
|
22
|
+
* - Random index generation for new entries
|
|
23
|
+
* - Integration with multiple data sources
|
|
24
|
+
*
|
|
25
|
+
* @author Sphereon International B.V.
|
|
26
|
+
* @since 2024
|
|
27
|
+
*/
|
|
8
28
|
|
|
9
29
|
interface StatusListManagementOptions {
|
|
10
30
|
id?: string;
|
|
@@ -31,6 +51,12 @@ declare function getDriver(args: {
|
|
|
31
51
|
dataSource?: DataSource;
|
|
32
52
|
dataSources?: DataSources;
|
|
33
53
|
}): Promise<IStatusListDriver>;
|
|
54
|
+
/**
|
|
55
|
+
* TypeORM-based implementation of the IStatusListDriver interface
|
|
56
|
+
*
|
|
57
|
+
* Manages status list credentials and entries using a TypeORM data source.
|
|
58
|
+
* Handles database operations while delegating format-specific logic to the functions layer.
|
|
59
|
+
*/
|
|
34
60
|
declare class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
35
61
|
private _dataSource;
|
|
36
62
|
private _statusListStore;
|
|
@@ -46,6 +72,7 @@ declare class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
46
72
|
getOptions(): DriverOptions;
|
|
47
73
|
getType(): StatusListDriverType;
|
|
48
74
|
createStatusList(args: {
|
|
75
|
+
statusListType: StatusListType;
|
|
49
76
|
statusListCredential: StatusListCredential;
|
|
50
77
|
correlationId?: string;
|
|
51
78
|
credentialIdMode?: StatusListCredentialIdMode;
|
|
@@ -54,7 +81,6 @@ declare class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
54
81
|
updateStatusList(args: {
|
|
55
82
|
statusListCredential: StatusListCredential;
|
|
56
83
|
correlationId: string;
|
|
57
|
-
type: StatusListType;
|
|
58
84
|
}): Promise<StatusListResult>;
|
|
59
85
|
deleteStatusList(): Promise<boolean>;
|
|
60
86
|
updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<{
|
|
@@ -77,7 +103,7 @@ declare class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
77
103
|
isStatusListIndexInUse(): Promise<boolean>;
|
|
78
104
|
}
|
|
79
105
|
|
|
80
|
-
type IRequiredPlugins = IDataStoreORM & IDIDManager & IKeyManager & IIdentifierResolution & ICredentialIssuer & ICredentialVerifier &
|
|
106
|
+
type IRequiredPlugins = IDataStoreORM & IDIDManager & IKeyManager & IIdentifierResolution & ICredentialIssuer & ICredentialVerifier & IVcdmCredentialPlugin & IStatusListPlugin & IResolver;
|
|
81
107
|
type IRequiredContext = IAgentContext<IRequiredPlugins>;
|
|
82
108
|
interface IStatusListDriver {
|
|
83
109
|
statusListStore: StatusListStore;
|
|
@@ -87,6 +113,7 @@ interface IStatusListDriver {
|
|
|
87
113
|
correlationId?: string;
|
|
88
114
|
}): Promise<number>;
|
|
89
115
|
createStatusList(args: {
|
|
116
|
+
statusListType: StatusListType;
|
|
90
117
|
statusListCredential: StatusListCredential;
|
|
91
118
|
correlationId?: string;
|
|
92
119
|
bitsPerStatus?: number;
|
|
@@ -103,6 +130,7 @@ interface IStatusListDriver {
|
|
|
103
130
|
getStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<IStatusListEntryEntity | undefined>;
|
|
104
131
|
updateStatusList(args: {
|
|
105
132
|
statusListCredential: StatusListCredential;
|
|
133
|
+
correlationId: string;
|
|
106
134
|
}): Promise<StatusListResult>;
|
|
107
135
|
deleteStatusList(): Promise<boolean>;
|
|
108
136
|
getRandomNewStatusListIndex(args?: {
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
4
4
|
// src/drivers.ts
|
|
5
5
|
import { DataSources } from "@sphereon/ssi-sdk.agent-config";
|
|
6
6
|
import { StatusListStore } from "@sphereon/ssi-sdk.data-store";
|
|
7
|
-
import { createCredentialStatusFromStatusList,
|
|
7
|
+
import { createCredentialStatusFromStatusList, extractCredentialDetails, toStatusListDetails } from "@sphereon/ssi-sdk.vc-status-list";
|
|
8
8
|
import { StatusListCredentialIdMode, StatusListDriverType } from "@sphereon/ssi-types";
|
|
9
9
|
|
|
10
10
|
// src/status-list-adapters.ts
|
|
@@ -143,11 +143,12 @@ var AgentDataSourceStatusListDriver = class _AgentDataSourceStatusListDriver {
|
|
|
143
143
|
throw Error("Either a correlationId needs to be set as an option, or it needs to be provided when creating a status list. None found");
|
|
144
144
|
}
|
|
145
145
|
const credentialIdMode = args.credentialIdMode ?? StatusListCredentialIdMode.ISSUANCE;
|
|
146
|
-
const implementationResult = await
|
|
147
|
-
|
|
146
|
+
const implementationResult = await toStatusListDetails({
|
|
147
|
+
statusListCredential: args.statusListCredential,
|
|
148
|
+
statusListType: args.statusListType,
|
|
149
|
+
bitsPerStatus: args.bitsPerStatus,
|
|
148
150
|
correlationId,
|
|
149
|
-
driverType: this.getType()
|
|
150
|
-
bitsPerStatus: args.bitsPerStatus
|
|
151
|
+
driverType: this.getType()
|
|
151
152
|
});
|
|
152
153
|
const statusListArgs = {
|
|
153
154
|
...implementationResult,
|
|
@@ -161,24 +162,19 @@ var AgentDataSourceStatusListDriver = class _AgentDataSourceStatusListDriver {
|
|
|
161
162
|
}
|
|
162
163
|
async updateStatusList(args) {
|
|
163
164
|
const correlationId = args.correlationId ?? this.options.correlationId;
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
});
|
|
169
|
-
const entity = await (await this.statusListStore.getStatusListRepo(args.type)).findOne({
|
|
170
|
-
where: [
|
|
171
|
-
{
|
|
172
|
-
id: details.id
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
correlationId
|
|
176
|
-
}
|
|
177
|
-
]
|
|
165
|
+
const extractedDetails = await extractCredentialDetails(args.statusListCredential);
|
|
166
|
+
const entity = await this.statusListStore.getStatusList({
|
|
167
|
+
id: extractedDetails.id,
|
|
168
|
+
correlationId
|
|
178
169
|
});
|
|
179
170
|
if (!entity) {
|
|
180
|
-
throw Error(`Status list ${
|
|
171
|
+
throw Error(`Status list ${extractedDetails.id}, correlationId ${correlationId} could not be found`);
|
|
181
172
|
}
|
|
173
|
+
entity.statusListCredential = args.statusListCredential;
|
|
174
|
+
const details = await toStatusListDetails({
|
|
175
|
+
extractedDetails,
|
|
176
|
+
statusListEntity: entity
|
|
177
|
+
});
|
|
182
178
|
const updateArgs = {
|
|
183
179
|
...entity,
|
|
184
180
|
...details,
|
|
@@ -260,19 +256,27 @@ var AgentDataSourceStatusListDriver = class _AgentDataSourceStatusListDriver {
|
|
|
260
256
|
async getStatusList(args) {
|
|
261
257
|
const id = this.options.id;
|
|
262
258
|
const correlationId = args?.correlationId ?? this.options.correlationId;
|
|
263
|
-
|
|
259
|
+
const statusListEntity = await this.statusListStore.getStatusList({
|
|
264
260
|
id,
|
|
265
261
|
correlationId
|
|
266
|
-
})
|
|
262
|
+
});
|
|
263
|
+
return await toStatusListDetails({
|
|
267
264
|
statusListCredential: statusListEntity.statusListCredential,
|
|
268
|
-
|
|
269
|
-
|
|
265
|
+
statusListType: statusListEntity.type,
|
|
266
|
+
bitsPerStatus: statusListEntity.bitsPerStatus,
|
|
267
|
+
correlationId: statusListEntity.correlationId,
|
|
268
|
+
driverType: statusListEntity.driverType
|
|
269
|
+
});
|
|
270
270
|
}
|
|
271
271
|
async getStatusLists() {
|
|
272
272
|
const statusLists = await this.statusListStore.getStatusLists({});
|
|
273
273
|
return Promise.all(statusLists.map(async (statusListEntity) => {
|
|
274
|
-
return
|
|
275
|
-
statusListCredential: statusListEntity.statusListCredential
|
|
274
|
+
return toStatusListDetails({
|
|
275
|
+
statusListCredential: statusListEntity.statusListCredential,
|
|
276
|
+
statusListType: statusListEntity.type,
|
|
277
|
+
bitsPerStatus: statusListEntity.bitsPerStatus,
|
|
278
|
+
correlationId: statusListEntity.correlationId,
|
|
279
|
+
driverType: statusListEntity.driverType
|
|
276
280
|
});
|
|
277
281
|
}));
|
|
278
282
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/drivers.ts","../src/status-list-adapters.ts"],"sourcesContent":["import { DataSources } from '@sphereon/ssi-sdk.agent-config'\nimport {\n IAddStatusListArgs,\n IAddStatusListEntryArgs,\n IBitstringStatusListEntryEntity,\n IGetStatusListEntryByCredentialIdArgs,\n IGetStatusListEntryByIndexArgs,\n IStatusListEntity,\n IStatusListEntryEntity,\n StatusListEntity,\n StatusListStore,\n} from '@sphereon/ssi-sdk.data-store'\nimport {\n BitstringStatusListEntryCredentialStatus,\n createCredentialStatusFromStatusList,\n StatusList2021EntryCredentialStatus,\n statusListCredentialToDetails,\n StatusListOAuthEntryCredentialStatus,\n StatusListResult,\n} from '@sphereon/ssi-sdk.vc-status-list'\nimport { StatusListCredential, StatusListCredentialIdMode, StatusListDriverType, StatusListType } from '@sphereon/ssi-types'\nimport { DataSource } from 'typeorm'\nimport { IStatusListDriver } from './types'\nimport { statusListResultToEntity } from './status-list-adapters'\n\nexport interface StatusListManagementOptions {\n id?: string\n correlationId?: string\n driverType: StatusListDriverType\n driverOptions?: DriverOptions\n}\n\nexport type DriverOptions = TypeORMOptions\n\nexport interface TypeORMOptions {\n dbName?: string\n}\n\nexport interface FilesystemOptions {\n path: string // The base path where statusList Credentials will be persisted. Should be a folder and thus not include the VC/StatusList itself\n}\n\nexport function getOptions(args: { id?: string; correlationId?: string; dbName: string }): StatusListManagementOptions {\n return {\n id: args.id,\n correlationId: args.correlationId,\n driverType: StatusListDriverType.AGENT_TYPEORM,\n driverOptions: { dbName: args.dbName },\n }\n}\n\nexport async function getDriver(args: {\n id?: string\n correlationId?: string\n dbName?: string\n dataSource?: DataSource\n dataSources?: DataSources\n}): Promise<IStatusListDriver> {\n const dbName = args.dbName ?? args.dataSource?.name\n if (!dbName) {\n throw Error(`Please provide either a DB name or data source`)\n }\n const dataSources = args.dataSources ?? DataSources.singleInstance()\n return await AgentDataSourceStatusListDriver.init(\n getOptions({\n ...args,\n dbName,\n }),\n { dataSource: args.dataSource ?? (await dataSources.getDbConnection(dbName)), dataSources },\n )\n}\n\nexport class AgentDataSourceStatusListDriver implements IStatusListDriver {\n private _statusListLength: number | undefined\n\n constructor(\n private _dataSource: DataSource,\n private _statusListStore: StatusListStore,\n private options: StatusListManagementOptions,\n ) {}\n\n public static async init(\n options: StatusListManagementOptions,\n dbArgs?: {\n dataSources?: DataSources\n dataSource?: DataSource\n },\n ): Promise<AgentDataSourceStatusListDriver> {\n if (options.driverType !== StatusListDriverType.AGENT_TYPEORM) {\n throw Error(`TypeORM driver can only be used when the TypeORM driver type is selected in the configuration. Got: ${options.driverType}`)\n } else if (!options.driverOptions) {\n throw Error(`TypeORM driver can only be used when the TypeORM options are provided.`)\n }\n let dataSource: DataSource\n let statusListStore: StatusListStore\n if (dbArgs?.dataSource) {\n dataSource = dbArgs.dataSource\n } else if (options.driverOptions.dbName) {\n if (dbArgs?.dataSources) {\n dataSource = await dbArgs.dataSources.getDbConnection(options.driverOptions.dbName)\n } else {\n dataSource = await DataSources.singleInstance().getDbConnection(options.driverOptions.dbName)\n }\n } else {\n return Promise.reject(Error(`Either a datasource or dbName needs to be provided`))\n }\n\n statusListStore = new StatusListStore(dataSource)\n return new AgentDataSourceStatusListDriver(dataSource, statusListStore, options)\n }\n\n get dataSource(): DataSource {\n if (!this._dataSource) {\n throw Error(`Datasource not available yet for ${this.options.driverOptions?.dbName}`)\n }\n return this._dataSource\n }\n\n get statusListStore(): StatusListStore {\n if (!this._statusListStore) {\n this._statusListStore = new StatusListStore(this.dataSource)\n }\n return this._statusListStore\n }\n\n getOptions(): DriverOptions {\n return this.options.driverOptions ?? {}\n }\n\n getType(): StatusListDriverType {\n return this.options.driverType\n }\n\n async createStatusList(args: {\n statusListCredential: StatusListCredential\n correlationId?: string\n credentialIdMode?: StatusListCredentialIdMode\n bitsPerStatus?: number\n }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n if (!correlationId) {\n throw Error('Either a correlationId needs to be set as an option, or it needs to be provided when creating a status list. None found')\n }\n const credentialIdMode = args.credentialIdMode ?? StatusListCredentialIdMode.ISSUANCE\n\n // Get implementation details\n const implementationResult = await statusListCredentialToDetails({\n ...args,\n correlationId,\n driverType: this.getType(),\n bitsPerStatus: args.bitsPerStatus,\n })\n\n // Add driver-specific fields to create complete entity\n const statusListArgs = {\n ...implementationResult,\n credentialIdMode,\n correlationId,\n driverType: this.getType(),\n } as IAddStatusListArgs\n\n await this.statusListStore.addStatusList(statusListArgs)\n this._statusListLength = implementationResult.length\n return implementationResult\n }\n async updateStatusList(args: {\n statusListCredential: StatusListCredential\n correlationId: string\n type: StatusListType\n }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n const details = await statusListCredentialToDetails({ ...args, correlationId, driverType: this.getType() })\n const entity = await (\n await this.statusListStore.getStatusListRepo(args.type)\n ).findOne({\n where: [\n {\n id: details.id,\n },\n {\n correlationId,\n },\n ],\n })\n if (!entity) {\n throw Error(`Status list ${details.id}, correlationId ${args.correlationId} could not be found`)\n }\n\n // Merge details with existing entity and driver properties\n const updateArgs = {\n ...entity,\n ...details,\n correlationId,\n driverType: this.getType(),\n } as IAddStatusListArgs\n\n await this.statusListStore.updateStatusList(updateArgs)\n this._statusListLength = details.length\n return { ...entity, ...details }\n }\n\n async deleteStatusList(): Promise<boolean> {\n await this.statusListStore.removeStatusList({ id: this.options.id, correlationId: this.options.correlationId })\n return Promise.resolve(true)\n }\n\n async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<{\n credentialStatus: StatusList2021EntryCredentialStatus | StatusListOAuthEntryCredentialStatus | BitstringStatusListEntryCredentialStatus\n statusListEntry: IStatusListEntryEntity | IBitstringStatusListEntryEntity\n }> {\n // Get status list entity\n const statusListEntity: StatusListEntity = statusListResultToEntity(await this.getStatusList())\n\n // Update the entry in the store\n const statusListEntry = await this.statusListStore.updateStatusListEntry({ ...args, statusListId: statusListEntity.id })\n\n // Use implementation to create the credential status - this moves type-specific logic to implementations\n const credentialStatus = await createCredentialStatusFromStatusList({\n statusList: statusListEntity,\n statusListEntry,\n statusListIndex: statusListEntry.statusListIndex,\n })\n\n return {\n credentialStatus,\n statusListEntry,\n }\n }\n\n async getStatusListEntryByCredentialId(\n args: IGetStatusListEntryByCredentialIdArgs,\n ): Promise<IStatusListEntryEntity | IBitstringStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByCredentialId(args)\n }\n\n async getStatusListEntryByIndex(\n args: IGetStatusListEntryByIndexArgs,\n ): Promise<IStatusListEntryEntity | IBitstringStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByIndex(args)\n }\n\n async getRandomNewStatusListIndex(args?: { correlationId?: string }): Promise<number> {\n let result = -1\n let tries = 0\n while (result < 0) {\n // no tries guard, because we will throw an error when they are exhausted anyway\n result = await this.getRandomNewStatusListIndexImpl(tries++, args)\n }\n return result\n }\n\n private async getRandomNewStatusListIndexImpl(tries: number, args?: { correlationId?: string }): Promise<number> {\n const statusListId = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n if (tries >= 10) {\n throw Error(`We could not find any random status list index that is available in the statuslist ${statusListId}`)\n }\n // TODO: Check against DB\n const length = await this.getStatusListLength(args)\n const statusListIndex = Array.from({ length: 20 }, () => Math.floor(Math.random() * length))\n const available = await this.statusListStore.availableStatusListEntries({\n statusListId,\n ...(correlationId && { correlationId }),\n statusListIndex,\n })\n if (available.length > 0) {\n return available[0] // doesn't matter we pick the first element, as they are all random anyway\n }\n return -1\n }\n\n async getStatusListLength(args?: { correlationId?: string }): Promise<number> {\n if (!this._statusListLength) {\n this._statusListLength = await this.getStatusList(args).then((details) => details.length)\n }\n return this._statusListLength!\n }\n\n async getStatusList(args?: { correlationId?: string }): Promise<StatusListResult> {\n const id = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n return await this.statusListStore.getStatusList({ id, correlationId }).then((statusListEntity: IStatusListEntity) =>\n statusListCredentialToDetails({\n statusListCredential: statusListEntity.statusListCredential!,\n bitsPerStatus: statusListEntity.bitsPerStatus,\n }),\n )\n }\n\n async getStatusLists(): Promise<Array<StatusListResult>> {\n const statusLists = await this.statusListStore.getStatusLists({})\n return Promise.all(\n statusLists.map(async (statusListEntity) => {\n return statusListCredentialToDetails({\n statusListCredential: statusListEntity.statusListCredential!,\n })\n }),\n )\n }\n\n isStatusListIndexInUse(): Promise<boolean> {\n return Promise.resolve(false)\n }\n}\n","import { StatusListType } from '@sphereon/ssi-types'\nimport { BitstringStatusListEntity, OAuthStatusListEntity, StatusList2021Entity } from '@sphereon/ssi-sdk.data-store'\nimport { StatusListResult } from '@sphereon/ssi-sdk.vc-status-list'\n\nexport function statusListResultToEntity(result: StatusListResult): StatusList2021Entity | OAuthStatusListEntity | BitstringStatusListEntity {\n const baseFields = {\n id: result.id,\n correlationId: result.correlationId,\n driverType: result.driverType,\n credentialIdMode: result.credentialIdMode,\n length: result.length,\n issuer: result.issuer,\n type: result.type,\n proofFormat: result.proofFormat,\n statusListCredential: result.statusListCredential,\n }\n\n if (result.type === StatusListType.StatusList2021) {\n if (!result.statusList2021) {\n throw new Error('Missing statusList2021 details')\n }\n return Object.assign(new StatusList2021Entity(), {\n ...baseFields,\n indexingDirection: result.statusList2021.indexingDirection,\n statusPurpose: result.statusList2021.statusPurpose,\n })\n } else if (result.type === StatusListType.OAuthStatusList) {\n if (!result.oauthStatusList) {\n throw new Error('Missing oauthStatusList details')\n }\n return Object.assign(new OAuthStatusListEntity(), {\n ...baseFields,\n bitsPerStatus: result.oauthStatusList.bitsPerStatus,\n expiresAt: result.oauthStatusList.expiresAt,\n })\n } else if (result.type === StatusListType.BitstringStatusList) {\n if (!result.bitstringStatusList) {\n throw new Error('Missing bitstringStatusList details')\n }\n return Object.assign(new BitstringStatusListEntity(), {\n ...baseFields,\n statusPurpose: result.bitstringStatusList.statusPurpose,\n ttl: result.bitstringStatusList.ttl,\n bitsPerStatus: result.bitstringStatusList.bitsPerStatus,\n validFrom: result.bitstringStatusList.validFrom,\n validUntil: result.bitstringStatusList.validUntil,\n })\n }\n throw new Error(`Unsupported status list type: ${result.type}`)\n}\n"],"mappings":"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","names":["DataSources","StatusListStore","createCredentialStatusFromStatusList","statusListCredentialToDetails","StatusListCredentialIdMode","StatusListDriverType","StatusListType","BitstringStatusListEntity","OAuthStatusListEntity","StatusList2021Entity","statusListResultToEntity","result","baseFields","id","correlationId","driverType","credentialIdMode","length","issuer","type","proofFormat","statusListCredential","StatusListType","StatusList2021","statusList2021","Error","Object","assign","StatusList2021Entity","indexingDirection","statusPurpose","OAuthStatusList","oauthStatusList","OAuthStatusListEntity","bitsPerStatus","expiresAt","BitstringStatusList","bitstringStatusList","BitstringStatusListEntity","ttl","validFrom","validUntil","getOptions","args","id","correlationId","driverType","StatusListDriverType","AGENT_TYPEORM","driverOptions","dbName","getDriver","dataSource","name","Error","dataSources","DataSources","singleInstance","AgentDataSourceStatusListDriver","init","getDbConnection","_statusListLength","constructor","_dataSource","_statusListStore","options","dbArgs","statusListStore","Promise","reject","StatusListStore","getType","createStatusList","credentialIdMode","StatusListCredentialIdMode","ISSUANCE","implementationResult","statusListCredentialToDetails","bitsPerStatus","statusListArgs","addStatusList","length","updateStatusList","details","entity","getStatusListRepo","type","findOne","where","updateArgs","deleteStatusList","removeStatusList","resolve","updateStatusListEntry","statusListEntity","statusListResultToEntity","getStatusList","statusListEntry","statusListId","credentialStatus","createCredentialStatusFromStatusList","statusList","statusListIndex","getStatusListEntryByCredentialId","getStatusListEntryByIndex","getRandomNewStatusListIndex","result","tries","getRandomNewStatusListIndexImpl","getStatusListLength","Array","from","Math","floor","random","available","availableStatusListEntries","then","statusListCredential","getStatusLists","statusLists","all","map","isStatusListIndexInUse"]}
|
|
1
|
+
{"version":3,"sources":["../src/drivers.ts","../src/status-list-adapters.ts"],"sourcesContent":["/**\n * StatusList Driver Implementation for TypeORM/Agent Data Sources\n *\n * This module provides the database-backed implementation of the IStatusListDriver interface,\n * handling persistence and retrieval of status list credentials and entries using TypeORM.\n * It delegates status list format-specific operations to the functions layer while managing\n * database interactions, driver configuration, and entity lifecycle.\n *\n * Key responsibilities:\n * - Database connection and store management\n * - Status list CRUD operations\n * - Status list entry management\n * - Random index generation for new entries\n * - Integration with multiple data sources\n *\n * @author Sphereon International B.V.\n * @since 2024\n */\n\nimport { DataSources } from '@sphereon/ssi-sdk.agent-config'\nimport {\n BitstringStatusListEntryCredentialStatus,\n IAddStatusListArgs,\n IAddStatusListEntryArgs,\n IBitstringStatusListEntryEntity,\n IGetStatusListEntryByCredentialIdArgs,\n IGetStatusListEntryByIndexArgs,\n IStatusListEntryEntity,\n StatusListEntity,\n StatusListStore,\n} from '@sphereon/ssi-sdk.data-store'\nimport {\n createCredentialStatusFromStatusList,\n extractCredentialDetails,\n StatusList2021EntryCredentialStatus,\n StatusListOAuthEntryCredentialStatus,\n StatusListResult,\n toStatusListDetails,\n} from '@sphereon/ssi-sdk.vc-status-list'\nimport { StatusListCredential, StatusListCredentialIdMode, StatusListDriverType, StatusListType } from '@sphereon/ssi-types'\nimport { DataSource } from 'typeorm'\nimport { IStatusListDriver } from './types'\nimport { statusListResultToEntity } from './status-list-adapters'\n\nexport interface StatusListManagementOptions {\n id?: string\n correlationId?: string\n driverType: StatusListDriverType\n driverOptions?: DriverOptions\n}\n\nexport type DriverOptions = TypeORMOptions\n\nexport interface TypeORMOptions {\n dbName?: string\n}\n\nexport interface FilesystemOptions {\n path: string // The base path where statusList Credentials will be persisted. Should be a folder and thus not include the VC/StatusList itself\n}\n\nexport function getOptions(args: { id?: string; correlationId?: string; dbName: string }): StatusListManagementOptions {\n return {\n id: args.id,\n correlationId: args.correlationId,\n driverType: StatusListDriverType.AGENT_TYPEORM,\n driverOptions: { dbName: args.dbName },\n }\n}\n\nexport async function getDriver(args: {\n id?: string\n correlationId?: string\n dbName?: string\n dataSource?: DataSource\n dataSources?: DataSources\n}): Promise<IStatusListDriver> {\n const dbName = args.dbName ?? args.dataSource?.name\n if (!dbName) {\n throw Error(`Please provide either a DB name or data source`)\n }\n const dataSources = args.dataSources ?? DataSources.singleInstance()\n return await AgentDataSourceStatusListDriver.init(\n getOptions({\n ...args,\n dbName,\n }),\n { dataSource: args.dataSource ?? (await dataSources.getDbConnection(dbName)), dataSources },\n )\n}\n\n/**\n * TypeORM-based implementation of the IStatusListDriver interface\n *\n * Manages status list credentials and entries using a TypeORM data source.\n * Handles database operations while delegating format-specific logic to the functions layer.\n */\nexport class AgentDataSourceStatusListDriver implements IStatusListDriver {\n private _statusListLength: number | undefined\n\n constructor(\n private _dataSource: DataSource,\n private _statusListStore: StatusListStore,\n private options: StatusListManagementOptions,\n ) {}\n\n public static async init(\n options: StatusListManagementOptions,\n dbArgs?: {\n dataSources?: DataSources\n dataSource?: DataSource\n },\n ): Promise<AgentDataSourceStatusListDriver> {\n if (options.driverType !== StatusListDriverType.AGENT_TYPEORM) {\n throw Error(`TypeORM driver can only be used when the TypeORM driver type is selected in the configuration. Got: ${options.driverType}`)\n } else if (!options.driverOptions) {\n throw Error(`TypeORM driver can only be used when the TypeORM options are provided.`)\n }\n let dataSource: DataSource\n let statusListStore: StatusListStore\n if (dbArgs?.dataSource) {\n dataSource = dbArgs.dataSource\n } else if (options.driverOptions.dbName) {\n if (dbArgs?.dataSources) {\n dataSource = await dbArgs.dataSources.getDbConnection(options.driverOptions.dbName)\n } else {\n dataSource = await DataSources.singleInstance().getDbConnection(options.driverOptions.dbName)\n }\n } else {\n return Promise.reject(Error(`Either a datasource or dbName needs to be provided`))\n }\n\n statusListStore = new StatusListStore(dataSource)\n return new AgentDataSourceStatusListDriver(dataSource, statusListStore, options)\n }\n\n get dataSource(): DataSource {\n if (!this._dataSource) {\n throw Error(`Datasource not available yet for ${this.options.driverOptions?.dbName}`)\n }\n return this._dataSource\n }\n\n get statusListStore(): StatusListStore {\n if (!this._statusListStore) {\n this._statusListStore = new StatusListStore(this.dataSource)\n }\n return this._statusListStore\n }\n\n getOptions(): DriverOptions {\n return this.options.driverOptions ?? {}\n }\n\n getType(): StatusListDriverType {\n return this.options.driverType\n }\n\n async createStatusList(args: {\n statusListType: StatusListType\n statusListCredential: StatusListCredential\n correlationId?: string\n credentialIdMode?: StatusListCredentialIdMode\n bitsPerStatus?: number\n }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n if (!correlationId) {\n throw Error('Either a correlationId needs to be set as an option, or it needs to be provided when creating a status list. None found')\n }\n const credentialIdMode = args.credentialIdMode ?? StatusListCredentialIdMode.ISSUANCE\n\n // Convert credential to implementation details using CREATE/READ context\n const implementationResult = await toStatusListDetails({\n statusListCredential: args.statusListCredential,\n statusListType: args.statusListType,\n bitsPerStatus: args.bitsPerStatus,\n correlationId,\n driverType: this.getType(),\n })\n\n // Add driver-specific fields to create complete entity\n const statusListArgs = {\n ...implementationResult,\n credentialIdMode,\n correlationId,\n driverType: this.getType(),\n } as IAddStatusListArgs\n\n await this.statusListStore.addStatusList(statusListArgs)\n this._statusListLength = implementationResult.length\n return implementationResult\n }\n\n async updateStatusList(args: { statusListCredential: StatusListCredential; correlationId: string }): Promise<StatusListResult> {\n const correlationId = args.correlationId ?? this.options.correlationId\n\n const extractedDetails = await extractCredentialDetails(args.statusListCredential)\n const entity = await this.statusListStore.getStatusList({\n id: extractedDetails.id,\n correlationId,\n })\n if (!entity) {\n throw Error(`Status list ${extractedDetails.id}, correlationId ${correlationId} could not be found`)\n }\n\n entity.statusListCredential = args.statusListCredential\n\n const details = await toStatusListDetails({\n extractedDetails,\n statusListEntity: entity,\n })\n\n // Merge details with existing entity and driver properties\n const updateArgs = {\n ...entity,\n ...details,\n correlationId,\n driverType: this.getType(),\n } as IAddStatusListArgs\n\n await this.statusListStore.updateStatusList(updateArgs)\n this._statusListLength = details.length\n return { ...entity, ...details }\n }\n\n async deleteStatusList(): Promise<boolean> {\n await this.statusListStore.removeStatusList({ id: this.options.id, correlationId: this.options.correlationId })\n return Promise.resolve(true)\n }\n\n async updateStatusListEntry(args: IAddStatusListEntryArgs): Promise<{\n credentialStatus: StatusList2021EntryCredentialStatus | StatusListOAuthEntryCredentialStatus | BitstringStatusListEntryCredentialStatus\n statusListEntry: IStatusListEntryEntity | IBitstringStatusListEntryEntity\n }> {\n // Get status list entity\n const statusListEntity: StatusListEntity = statusListResultToEntity(await this.getStatusList())\n\n // Update the entry in the store\n const statusListEntry = await this.statusListStore.updateStatusListEntry({ ...args, statusListId: statusListEntity.id })\n\n // Use implementation to create the credential status - this moves type-specific logic to implementations\n const credentialStatus = await createCredentialStatusFromStatusList({\n statusList: statusListEntity,\n statusListEntry,\n statusListIndex: statusListEntry.statusListIndex,\n })\n\n return {\n credentialStatus,\n statusListEntry,\n }\n }\n\n async getStatusListEntryByCredentialId(\n args: IGetStatusListEntryByCredentialIdArgs,\n ): Promise<IStatusListEntryEntity | IBitstringStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByCredentialId(args)\n }\n\n async getStatusListEntryByIndex(\n args: IGetStatusListEntryByIndexArgs,\n ): Promise<IStatusListEntryEntity | IBitstringStatusListEntryEntity | undefined> {\n return await this.statusListStore.getStatusListEntryByIndex(args)\n }\n\n async getRandomNewStatusListIndex(args?: { correlationId?: string }): Promise<number> {\n let result = -1\n let tries = 0\n while (result < 0) {\n // no tries guard, because we will throw an error when they are exhausted anyway\n result = await this.getRandomNewStatusListIndexImpl(tries++, args)\n }\n return result\n }\n\n private async getRandomNewStatusListIndexImpl(tries: number, args?: { correlationId?: string }): Promise<number> {\n const statusListId = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n if (tries >= 10) {\n throw Error(`We could not find any random status list index that is available in the statuslist ${statusListId}`)\n }\n // TODO: Check against DB\n const length = await this.getStatusListLength(args)\n const statusListIndex = Array.from({ length: 20 }, () => Math.floor(Math.random() * length))\n const available = await this.statusListStore.availableStatusListEntries({\n statusListId,\n ...(correlationId && { correlationId }),\n statusListIndex,\n })\n if (available.length > 0) {\n return available[0] // doesn't matter we pick the first element, as they are all random anyway\n }\n return -1\n }\n\n async getStatusListLength(args?: { correlationId?: string }): Promise<number> {\n if (!this._statusListLength) {\n this._statusListLength = await this.getStatusList(args).then((details) => details.length)\n }\n return this._statusListLength!\n }\n\n async getStatusList(args?: { correlationId?: string }): Promise<StatusListResult> {\n const id = this.options.id\n const correlationId = args?.correlationId ?? this.options.correlationId\n\n const statusListEntity = await this.statusListStore.getStatusList({ id, correlationId })\n\n // Convert entity to result using CREATE/READ context\n return await toStatusListDetails({\n statusListCredential: statusListEntity.statusListCredential!,\n statusListType: statusListEntity.type,\n bitsPerStatus: statusListEntity.bitsPerStatus,\n correlationId: statusListEntity.correlationId,\n driverType: statusListEntity.driverType,\n })\n }\n\n async getStatusLists(): Promise<Array<StatusListResult>> {\n const statusLists = await this.statusListStore.getStatusLists({})\n return Promise.all(\n statusLists.map(async (statusListEntity) => {\n return toStatusListDetails({\n statusListCredential: statusListEntity.statusListCredential!,\n statusListType: statusListEntity.type,\n bitsPerStatus: statusListEntity.bitsPerStatus,\n correlationId: statusListEntity.correlationId,\n driverType: statusListEntity.driverType,\n })\n }),\n )\n }\n\n isStatusListIndexInUse(): Promise<boolean> {\n return Promise.resolve(false)\n }\n}\n","import { StatusListType } from '@sphereon/ssi-types'\nimport { BitstringStatusListEntity, OAuthStatusListEntity, StatusList2021Entity } from '@sphereon/ssi-sdk.data-store'\nimport { StatusListResult } from '@sphereon/ssi-sdk.vc-status-list'\n\nexport function statusListResultToEntity(result: StatusListResult): StatusList2021Entity | OAuthStatusListEntity | BitstringStatusListEntity {\n const baseFields = {\n id: result.id,\n correlationId: result.correlationId,\n driverType: result.driverType,\n credentialIdMode: result.credentialIdMode,\n length: result.length,\n issuer: result.issuer,\n type: result.type,\n proofFormat: result.proofFormat,\n statusListCredential: result.statusListCredential,\n }\n\n if (result.type === StatusListType.StatusList2021) {\n if (!result.statusList2021) {\n throw new Error('Missing statusList2021 details')\n }\n return Object.assign(new StatusList2021Entity(), {\n ...baseFields,\n indexingDirection: result.statusList2021.indexingDirection,\n statusPurpose: result.statusList2021.statusPurpose,\n })\n } else if (result.type === StatusListType.OAuthStatusList) {\n if (!result.oauthStatusList) {\n throw new Error('Missing oauthStatusList details')\n }\n return Object.assign(new OAuthStatusListEntity(), {\n ...baseFields,\n bitsPerStatus: result.oauthStatusList.bitsPerStatus,\n expiresAt: result.oauthStatusList.expiresAt,\n })\n } else if (result.type === StatusListType.BitstringStatusList) {\n if (!result.bitstringStatusList) {\n throw new Error('Missing bitstringStatusList details')\n }\n return Object.assign(new BitstringStatusListEntity(), {\n ...baseFields,\n statusPurpose: result.bitstringStatusList.statusPurpose,\n ttl: result.bitstringStatusList.ttl,\n bitsPerStatus: result.bitstringStatusList.bitsPerStatus,\n validFrom: result.bitstringStatusList.validFrom,\n validUntil: result.bitstringStatusList.validUntil,\n })\n }\n throw new Error(`Unsupported status list type: ${result.type}`)\n}\n"],"mappings":"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","names":["DataSources","StatusListStore","createCredentialStatusFromStatusList","extractCredentialDetails","toStatusListDetails","StatusListCredentialIdMode","StatusListDriverType","StatusListType","BitstringStatusListEntity","OAuthStatusListEntity","StatusList2021Entity","statusListResultToEntity","result","baseFields","id","correlationId","driverType","credentialIdMode","length","issuer","type","proofFormat","statusListCredential","StatusListType","StatusList2021","statusList2021","Error","Object","assign","StatusList2021Entity","indexingDirection","statusPurpose","OAuthStatusList","oauthStatusList","OAuthStatusListEntity","bitsPerStatus","expiresAt","BitstringStatusList","bitstringStatusList","BitstringStatusListEntity","ttl","validFrom","validUntil","getOptions","args","id","correlationId","driverType","StatusListDriverType","AGENT_TYPEORM","driverOptions","dbName","getDriver","dataSource","name","Error","dataSources","DataSources","singleInstance","AgentDataSourceStatusListDriver","init","getDbConnection","_statusListLength","constructor","_dataSource","_statusListStore","options","dbArgs","statusListStore","Promise","reject","StatusListStore","getType","createStatusList","credentialIdMode","StatusListCredentialIdMode","ISSUANCE","implementationResult","toStatusListDetails","statusListCredential","statusListType","bitsPerStatus","statusListArgs","addStatusList","length","updateStatusList","extractedDetails","extractCredentialDetails","entity","getStatusList","details","statusListEntity","updateArgs","deleteStatusList","removeStatusList","resolve","updateStatusListEntry","statusListResultToEntity","statusListEntry","statusListId","credentialStatus","createCredentialStatusFromStatusList","statusList","statusListIndex","getStatusListEntryByCredentialId","getStatusListEntryByIndex","getRandomNewStatusListIndex","result","tries","getRandomNewStatusListIndexImpl","getStatusListLength","Array","from","Math","floor","random","available","availableStatusListEntries","then","type","getStatusLists","statusLists","all","map","isStatusListIndexInUse"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sphereon/ssi-sdk.vc-status-list-issuer-drivers",
|
|
3
3
|
"description": "Sphereon SSI-SDK plugin for Status List management, like StatusList2021. Issuer drivers module",
|
|
4
|
-
"version": "0.34.1-feature.SSISDK.17.bitstring.sl.
|
|
4
|
+
"version": "0.34.1-feature.SSISDK.17.bitstring.sl.14+35c8ca99",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.cjs",
|
|
@@ -22,14 +22,15 @@
|
|
|
22
22
|
"build": "tsup --config ../../tsup.config.ts --tsconfig ../../tsconfig.tsup.json"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@sphereon/ssi-express-support": "0.34.1-feature.SSISDK.17.bitstring.sl.
|
|
25
|
+
"@sphereon/ssi-express-support": "0.34.1-feature.SSISDK.17.bitstring.sl.14+35c8ca99",
|
|
26
26
|
"@sphereon/ssi-sdk-ext.did-utils": "0.29.0",
|
|
27
27
|
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.29.0",
|
|
28
|
-
"@sphereon/ssi-sdk.agent-config": "0.34.1-feature.SSISDK.17.bitstring.sl.
|
|
29
|
-
"@sphereon/ssi-sdk.core": "0.34.1-feature.SSISDK.17.bitstring.sl.
|
|
30
|
-
"@sphereon/ssi-sdk.
|
|
31
|
-
"@sphereon/ssi-sdk.
|
|
32
|
-
"@sphereon/ssi-
|
|
28
|
+
"@sphereon/ssi-sdk.agent-config": "0.34.1-feature.SSISDK.17.bitstring.sl.14+35c8ca99",
|
|
29
|
+
"@sphereon/ssi-sdk.core": "0.34.1-feature.SSISDK.17.bitstring.sl.14+35c8ca99",
|
|
30
|
+
"@sphereon/ssi-sdk.credential-vcdm": "0.34.1-feature.SSISDK.17.bitstring.sl.14+35c8ca99",
|
|
31
|
+
"@sphereon/ssi-sdk.data-store": "0.34.1-feature.SSISDK.17.bitstring.sl.14+35c8ca99",
|
|
32
|
+
"@sphereon/ssi-sdk.vc-status-list": "0.34.1-feature.SSISDK.17.bitstring.sl.14+35c8ca99",
|
|
33
|
+
"@sphereon/ssi-types": "0.34.1-feature.SSISDK.17.bitstring.sl.14+35c8ca99",
|
|
33
34
|
"@sphereon/vc-status-list": "7.0.0-next.0",
|
|
34
35
|
"@veramo/core": "4.2.0",
|
|
35
36
|
"debug": "^4.3.5",
|
|
@@ -60,5 +61,5 @@
|
|
|
60
61
|
"SSI",
|
|
61
62
|
"StatusList2021"
|
|
62
63
|
],
|
|
63
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "35c8ca99b499927dfffd929ae709750a7337b017"
|
|
64
65
|
}
|
package/src/drivers.ts
CHANGED
|
@@ -1,22 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StatusList Driver Implementation for TypeORM/Agent Data Sources
|
|
3
|
+
*
|
|
4
|
+
* This module provides the database-backed implementation of the IStatusListDriver interface,
|
|
5
|
+
* handling persistence and retrieval of status list credentials and entries using TypeORM.
|
|
6
|
+
* It delegates status list format-specific operations to the functions layer while managing
|
|
7
|
+
* database interactions, driver configuration, and entity lifecycle.
|
|
8
|
+
*
|
|
9
|
+
* Key responsibilities:
|
|
10
|
+
* - Database connection and store management
|
|
11
|
+
* - Status list CRUD operations
|
|
12
|
+
* - Status list entry management
|
|
13
|
+
* - Random index generation for new entries
|
|
14
|
+
* - Integration with multiple data sources
|
|
15
|
+
*
|
|
16
|
+
* @author Sphereon International B.V.
|
|
17
|
+
* @since 2024
|
|
18
|
+
*/
|
|
19
|
+
|
|
1
20
|
import { DataSources } from '@sphereon/ssi-sdk.agent-config'
|
|
2
21
|
import {
|
|
22
|
+
BitstringStatusListEntryCredentialStatus,
|
|
3
23
|
IAddStatusListArgs,
|
|
4
24
|
IAddStatusListEntryArgs,
|
|
5
25
|
IBitstringStatusListEntryEntity,
|
|
6
26
|
IGetStatusListEntryByCredentialIdArgs,
|
|
7
27
|
IGetStatusListEntryByIndexArgs,
|
|
8
|
-
IStatusListEntity,
|
|
9
28
|
IStatusListEntryEntity,
|
|
10
29
|
StatusListEntity,
|
|
11
30
|
StatusListStore,
|
|
12
31
|
} from '@sphereon/ssi-sdk.data-store'
|
|
13
32
|
import {
|
|
14
|
-
BitstringStatusListEntryCredentialStatus,
|
|
15
33
|
createCredentialStatusFromStatusList,
|
|
34
|
+
extractCredentialDetails,
|
|
16
35
|
StatusList2021EntryCredentialStatus,
|
|
17
|
-
statusListCredentialToDetails,
|
|
18
36
|
StatusListOAuthEntryCredentialStatus,
|
|
19
37
|
StatusListResult,
|
|
38
|
+
toStatusListDetails,
|
|
20
39
|
} from '@sphereon/ssi-sdk.vc-status-list'
|
|
21
40
|
import { StatusListCredential, StatusListCredentialIdMode, StatusListDriverType, StatusListType } from '@sphereon/ssi-types'
|
|
22
41
|
import { DataSource } from 'typeorm'
|
|
@@ -70,6 +89,12 @@ export async function getDriver(args: {
|
|
|
70
89
|
)
|
|
71
90
|
}
|
|
72
91
|
|
|
92
|
+
/**
|
|
93
|
+
* TypeORM-based implementation of the IStatusListDriver interface
|
|
94
|
+
*
|
|
95
|
+
* Manages status list credentials and entries using a TypeORM data source.
|
|
96
|
+
* Handles database operations while delegating format-specific logic to the functions layer.
|
|
97
|
+
*/
|
|
73
98
|
export class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
74
99
|
private _statusListLength: number | undefined
|
|
75
100
|
|
|
@@ -132,6 +157,7 @@ export class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
132
157
|
}
|
|
133
158
|
|
|
134
159
|
async createStatusList(args: {
|
|
160
|
+
statusListType: StatusListType
|
|
135
161
|
statusListCredential: StatusListCredential
|
|
136
162
|
correlationId?: string
|
|
137
163
|
credentialIdMode?: StatusListCredentialIdMode
|
|
@@ -143,12 +169,13 @@ export class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
143
169
|
}
|
|
144
170
|
const credentialIdMode = args.credentialIdMode ?? StatusListCredentialIdMode.ISSUANCE
|
|
145
171
|
|
|
146
|
-
//
|
|
147
|
-
const implementationResult = await
|
|
148
|
-
|
|
172
|
+
// Convert credential to implementation details using CREATE/READ context
|
|
173
|
+
const implementationResult = await toStatusListDetails({
|
|
174
|
+
statusListCredential: args.statusListCredential,
|
|
175
|
+
statusListType: args.statusListType,
|
|
176
|
+
bitsPerStatus: args.bitsPerStatus,
|
|
149
177
|
correlationId,
|
|
150
178
|
driverType: this.getType(),
|
|
151
|
-
bitsPerStatus: args.bitsPerStatus,
|
|
152
179
|
})
|
|
153
180
|
|
|
154
181
|
// Add driver-specific fields to create complete entity
|
|
@@ -163,29 +190,26 @@ export class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
163
190
|
this._statusListLength = implementationResult.length
|
|
164
191
|
return implementationResult
|
|
165
192
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
correlationId: string
|
|
169
|
-
type: StatusListType
|
|
170
|
-
}): Promise<StatusListResult> {
|
|
193
|
+
|
|
194
|
+
async updateStatusList(args: { statusListCredential: StatusListCredential; correlationId: string }): Promise<StatusListResult> {
|
|
171
195
|
const correlationId = args.correlationId ?? this.options.correlationId
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
{
|
|
178
|
-
id: details.id,
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
correlationId,
|
|
182
|
-
},
|
|
183
|
-
],
|
|
196
|
+
|
|
197
|
+
const extractedDetails = await extractCredentialDetails(args.statusListCredential)
|
|
198
|
+
const entity = await this.statusListStore.getStatusList({
|
|
199
|
+
id: extractedDetails.id,
|
|
200
|
+
correlationId,
|
|
184
201
|
})
|
|
185
202
|
if (!entity) {
|
|
186
|
-
throw Error(`Status list ${
|
|
203
|
+
throw Error(`Status list ${extractedDetails.id}, correlationId ${correlationId} could not be found`)
|
|
187
204
|
}
|
|
188
205
|
|
|
206
|
+
entity.statusListCredential = args.statusListCredential
|
|
207
|
+
|
|
208
|
+
const details = await toStatusListDetails({
|
|
209
|
+
extractedDetails,
|
|
210
|
+
statusListEntity: entity,
|
|
211
|
+
})
|
|
212
|
+
|
|
189
213
|
// Merge details with existing entity and driver properties
|
|
190
214
|
const updateArgs = {
|
|
191
215
|
...entity,
|
|
@@ -279,20 +303,29 @@ export class AgentDataSourceStatusListDriver implements IStatusListDriver {
|
|
|
279
303
|
async getStatusList(args?: { correlationId?: string }): Promise<StatusListResult> {
|
|
280
304
|
const id = this.options.id
|
|
281
305
|
const correlationId = args?.correlationId ?? this.options.correlationId
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
306
|
+
|
|
307
|
+
const statusListEntity = await this.statusListStore.getStatusList({ id, correlationId })
|
|
308
|
+
|
|
309
|
+
// Convert entity to result using CREATE/READ context
|
|
310
|
+
return await toStatusListDetails({
|
|
311
|
+
statusListCredential: statusListEntity.statusListCredential!,
|
|
312
|
+
statusListType: statusListEntity.type,
|
|
313
|
+
bitsPerStatus: statusListEntity.bitsPerStatus,
|
|
314
|
+
correlationId: statusListEntity.correlationId,
|
|
315
|
+
driverType: statusListEntity.driverType,
|
|
316
|
+
})
|
|
288
317
|
}
|
|
289
318
|
|
|
290
319
|
async getStatusLists(): Promise<Array<StatusListResult>> {
|
|
291
320
|
const statusLists = await this.statusListStore.getStatusLists({})
|
|
292
321
|
return Promise.all(
|
|
293
322
|
statusLists.map(async (statusListEntity) => {
|
|
294
|
-
return
|
|
323
|
+
return toStatusListDetails({
|
|
295
324
|
statusListCredential: statusListEntity.statusListCredential!,
|
|
325
|
+
statusListType: statusListEntity.type,
|
|
326
|
+
bitsPerStatus: statusListEntity.bitsPerStatus,
|
|
327
|
+
correlationId: statusListEntity.correlationId,
|
|
328
|
+
driverType: statusListEntity.driverType,
|
|
296
329
|
})
|
|
297
330
|
}),
|
|
298
331
|
)
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IIdentifierResolution } from '@sphereon/ssi-sdk-ext.identifier-resolution'
|
|
2
2
|
import {
|
|
3
|
+
BitstringStatusListEntryCredentialStatus,
|
|
3
4
|
IAddStatusListEntryArgs,
|
|
4
5
|
IGetStatusListEntryByCredentialIdArgs,
|
|
5
6
|
IGetStatusListEntryByIndexArgs,
|
|
@@ -7,24 +8,15 @@ import {
|
|
|
7
8
|
StatusListStore,
|
|
8
9
|
} from '@sphereon/ssi-sdk.data-store'
|
|
9
10
|
import {
|
|
10
|
-
BitstringStatusListEntryCredentialStatus,
|
|
11
11
|
IStatusListPlugin,
|
|
12
12
|
StatusList2021EntryCredentialStatus,
|
|
13
13
|
StatusListOAuthEntryCredentialStatus,
|
|
14
14
|
StatusListResult,
|
|
15
15
|
} from '@sphereon/ssi-sdk.vc-status-list'
|
|
16
|
-
import { StatusListCredential, StatusListDriverType } from '@sphereon/ssi-types'
|
|
17
|
-
import {
|
|
18
|
-
IAgentContext,
|
|
19
|
-
ICredentialIssuer,
|
|
20
|
-
ICredentialPlugin,
|
|
21
|
-
ICredentialVerifier,
|
|
22
|
-
IDataStoreORM,
|
|
23
|
-
IDIDManager,
|
|
24
|
-
IKeyManager,
|
|
25
|
-
IResolver,
|
|
26
|
-
} from '@veramo/core'
|
|
16
|
+
import { StatusListCredential, StatusListDriverType, StatusListType } from '@sphereon/ssi-types'
|
|
17
|
+
import { IAgentContext, ICredentialIssuer, ICredentialVerifier, IDataStoreORM, IDIDManager, IKeyManager, IResolver } from '@veramo/core'
|
|
27
18
|
import { DriverOptions } from './drivers'
|
|
19
|
+
import { IVcdmCredentialPlugin } from '@sphereon/ssi-sdk.credential-vcdm'
|
|
28
20
|
|
|
29
21
|
export type IRequiredPlugins = IDataStoreORM &
|
|
30
22
|
IDIDManager &
|
|
@@ -32,7 +24,7 @@ export type IRequiredPlugins = IDataStoreORM &
|
|
|
32
24
|
IIdentifierResolution &
|
|
33
25
|
ICredentialIssuer &
|
|
34
26
|
ICredentialVerifier &
|
|
35
|
-
|
|
27
|
+
IVcdmCredentialPlugin &
|
|
36
28
|
IStatusListPlugin &
|
|
37
29
|
IResolver
|
|
38
30
|
export type IRequiredContext = IAgentContext<IRequiredPlugins>
|
|
@@ -46,7 +38,12 @@ export interface IStatusListDriver {
|
|
|
46
38
|
|
|
47
39
|
getStatusListLength(args?: { correlationId?: string }): Promise<number>
|
|
48
40
|
|
|
49
|
-
createStatusList(args: {
|
|
41
|
+
createStatusList(args: {
|
|
42
|
+
statusListType: StatusListType
|
|
43
|
+
statusListCredential: StatusListCredential
|
|
44
|
+
correlationId?: string
|
|
45
|
+
bitsPerStatus?: number
|
|
46
|
+
}): Promise<StatusListResult>
|
|
50
47
|
|
|
51
48
|
getStatusList(args?: { correlationId?: string }): Promise<StatusListResult>
|
|
52
49
|
|
|
@@ -61,7 +58,7 @@ export interface IStatusListDriver {
|
|
|
61
58
|
|
|
62
59
|
getStatusListEntryByIndex(args: IGetStatusListEntryByIndexArgs): Promise<IStatusListEntryEntity | undefined>
|
|
63
60
|
|
|
64
|
-
updateStatusList(args: { statusListCredential: StatusListCredential }): Promise<StatusListResult>
|
|
61
|
+
updateStatusList(args: { statusListCredential: StatusListCredential; correlationId: string }): Promise<StatusListResult>
|
|
65
62
|
|
|
66
63
|
deleteStatusList(): Promise<boolean>
|
|
67
64
|
|