diff --git a/samples/cliConfig.json b/samples/cliConfig.json index 105845d7..6743b9b4 100644 --- a/samples/cliConfig.json +++ b/samples/cliConfig.json @@ -19,7 +19,7 @@ "indyNamespace": "indicio:demonet" }, { - "genesisTransactions": "https://raw.githubusercontent.com/bcgov/von-network/main/BCovrin/genesis_test", + "genesisTransactions": "https://test.bcovrin.vonx.io/genesis", "indyNamespace": "bcovrin:testnet" } ], diff --git a/src/cliAgent.ts b/src/cliAgent.ts index 2b044cb7..25cecab8 100644 --- a/src/cliAgent.ts +++ b/src/cliAgent.ts @@ -1,6 +1,7 @@ // Note: For now we need to import askar-nodejs at the top to handle the undefined askar issue // Refer from: https://github.com/credebl/mobile-sdk/blob/main/packages/ssi/src/wallet/wallet.ts import '@openwallet-foundation/askar-nodejs' +import '@hyperledger/indy-vdr-nodejs' import type { AskarModuleConfigStoreOptions } from '@credo-ts/askar' import type { InitConfig } from '@credo-ts/core' import type { IndyVdrPoolConfig } from '@credo-ts/indy-vdr' @@ -193,10 +194,6 @@ const getModules = ( w3cCredentials: new W3cCredentialsModule(), didcomm: new DidCommModule({ processDidCommMessagesConcurrently: true, - anoncreds: new AnonCredsModule({ - registries: [new IndyVdrAnonCredsRegistry()], - anoncreds, - }), mediationRecipient: true, messagePickup: true, mediator: false, diff --git a/src/controllers/anoncreds/cred-def/CredentialDefinitionController.ts b/src/controllers/anoncreds/cred-def/CredentialDefinitionController.ts index 57f47061..663bec90 100644 --- a/src/controllers/anoncreds/cred-def/CredentialDefinitionController.ts +++ b/src/controllers/anoncreds/cred-def/CredentialDefinitionController.ts @@ -1,142 +1,148 @@ -// import type { RestAgentModules } from '../../../cliAgent' -// import type { SchemaId } from '../../examples' +import type { RestAgentModules } from '../../../cliAgent' +import type { SchemaId } from '../../examples' -// import { getUnqualifiedCredentialDefinitionId, parseIndyCredentialDefinitionId } from '@credo-ts/anoncreds' -// import { Agent } from '@credo-ts/core' -// import { Request as Req } from 'express' -// import { Body, Controller, Example, Get, Path, Post, Route, Tags, Security, Response, Request } from 'tsoa' -// import { injectable } from 'tsyringe' +import { getUnqualifiedCredentialDefinitionId, parseIndyCredentialDefinitionId } from '@credo-ts/anoncreds' +import { Agent } from '@credo-ts/core' +import { Request as Req } from 'express' +import { Body, Controller, Example, Get, Path, Post, Route, Tags, Security, Response, Request } from 'tsoa' +import { injectable } from 'tsyringe' -// import { CredentialEnum, EndorserMode, SchemaError, SCOPES } from '../../../enums' -// import ErrorHandlingService from '../../../errorHandlingService' -// import { ENDORSER_DID_NOT_PRESENT } from '../../../errorMessages' -// import { BadRequestError, InternalServerError, NotFoundError } from '../../../errors/errors' -// import { CredentialDefinitionExample, CredentialDefinitionId } from '../../examples' +import { CredentialEnum, EndorserMode, SchemaError, SCOPES } from '../../../enums' +import ErrorHandlingService from '../../../errorHandlingService' +import { ENDORSER_DID_NOT_PRESENT } from '../../../errorMessages' +import { BadRequestError, InternalServerError, NotFoundError } from '../../../errors/errors' +import { CredentialDefinitionExample, CredentialDefinitionId } from '../../examples' +import { + CredentialDefinitionStates, + GetCredentialDefinitionReturn, + RegisterCredentialDefinitionReturn, +} from '../../types' -// @Tags('Anoncreds - Credential Definitions') -// @Route('/anoncreds/credential-definitions') -// @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT]) -// @injectable() -// export class CredentialDefinitionController extends Controller { -// /** -// * Retrieve credential definition by credential definition id -// * -// * @param credentialDefinitionId -// * @returns CredDef -// */ -// @Example(CredentialDefinitionExample) -// @Get('/:credentialDefinitionId') -// public async getCredentialDefinitionById( -// @Request() request: Req, -// @Path('credentialDefinitionId') credentialDefinitionId: CredentialDefinitionId, -// ) { -// try { -// const credentialDefinitionResult = -// await request.agent.modules.anoncreds.getCredentialDefinition(credentialDefinitionId) +@Tags('Anoncreds - Credential Definitions') +@Route('/anoncreds/credential-definitions') +@Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT]) +@injectable() +export class CredentialDefinitionController extends Controller { + /** + * Retrieve credential definition by credential definition id + * + * @param credentialDefinitionId + * @returns CredDef + */ + @Example(CredentialDefinitionExample) + @Get('/:credentialDefinitionId') + public async getCredentialDefinitionById( + @Request() request: Req, + @Path('credentialDefinitionId') credentialDefinitionId: CredentialDefinitionId, + ): Promise { + try { + const credentialDefinitionResult = + await request.agent.modules.anoncreds.getCredentialDefinition(credentialDefinitionId) -// if (credentialDefinitionResult.resolutionMetadata?.error === SchemaError.NotFound) { -// throw new NotFoundError(credentialDefinitionResult.resolutionMetadata.message) -// } -// const error = credentialDefinitionResult.resolutionMetadata?.error + if (credentialDefinitionResult.resolutionMetadata?.error === SchemaError.NotFound) { + throw new NotFoundError(credentialDefinitionResult.resolutionMetadata.message) + } + const error = credentialDefinitionResult.resolutionMetadata?.error -// if (error === 'invalid' || error === SchemaError.UnSupportedAnonCredsMethod) { -// throw new BadRequestError(credentialDefinitionResult.resolutionMetadata.message) -// } + if (error === 'invalid' || error === SchemaError.UnSupportedAnonCredsMethod) { + throw new BadRequestError(credentialDefinitionResult.resolutionMetadata.message) + } -// if (error !== undefined || credentialDefinitionResult.credentialDefinition === undefined) { -// throw new InternalServerError(credentialDefinitionResult.resolutionMetadata.message) -// } + if (error !== undefined || credentialDefinitionResult.credentialDefinition === undefined) { + throw new InternalServerError(credentialDefinitionResult.resolutionMetadata.message) + } -// return credentialDefinitionResult -// } catch (error) { -// throw ErrorHandlingService.handle(error) -// } -// } + return credentialDefinitionResult + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } -// /** -// * Creates a new credential definition. -// * -// * @param credentialDefinitionRequest -// * @returns CredDef -// */ -// @Example(CredentialDefinitionExample) -// @Response(200, 'Action required') -// @Response(202, 'Wait for action to complete') -// @Post('/') -// public async createCredentialDefinition( -// @Request() request: Req, -// @Body() -// credentialDefinitionRequest: { -// issuerId: string -// schemaId: SchemaId -// tag: string -// endorse?: boolean -// endorserDid?: string -// }, -// ) { -// try { -// const { issuerId, schemaId, tag, endorse, endorserDid } = credentialDefinitionRequest -// credentialDefinitionRequest.endorse = credentialDefinitionRequest.endorse -// ? credentialDefinitionRequest.endorse -// : false -// const credDef = { -// issuerId, -// schemaId, -// tag, -// type: 'CL', -// } -// const credentialDefinitionPayload = { -// credentialDefinition: credDef, -// options: { -// endorserMode: '', -// endorserDid: '', -// supportRevocation: false, -// }, -// } -// if (!endorse) { -// credentialDefinitionPayload.options.endorserMode = EndorserMode.Internal -// credentialDefinitionPayload.options.endorserDid = issuerId -// } else { -// if (!endorserDid) { -// throw new BadRequestError(ENDORSER_DID_NOT_PRESENT) -// } -// credentialDefinitionPayload.options.endorserMode = EndorserMode.External -// credentialDefinitionPayload.options.endorserDid = endorserDid ? endorserDid : '' -// } + /** + * Creates a new credential definition. + * + * @param credentialDefinitionRequest + * @returns CredDef + */ + @Example(CredentialDefinitionExample) + @Response(200, 'Action required') + @Response(202, 'Wait for action to complete') + @Post('/') + public async createCredentialDefinition( + @Request() request: Req, + @Body() + credentialDefinitionRequest: { + issuerId: string + schemaId: SchemaId + tag: string + endorse?: boolean + endorserDid?: string + }, + ): Promise { + try { + const { issuerId, schemaId, tag, endorse, endorserDid } = credentialDefinitionRequest + credentialDefinitionRequest.endorse = credentialDefinitionRequest.endorse + ? credentialDefinitionRequest.endorse + : false + const credDef = { + issuerId, + schemaId, + tag, + type: 'CL', + } + const credentialDefinitionPayload = { + credentialDefinition: credDef, + options: { + endorserMode: '', + endorserDid: '', + supportRevocation: false, + }, + } + if (!endorse) { + credentialDefinitionPayload.options.endorserMode = EndorserMode.Internal + credentialDefinitionPayload.options.endorserDid = issuerId + } else { + if (!endorserDid) { + throw new BadRequestError(ENDORSER_DID_NOT_PRESENT) + } + credentialDefinitionPayload.options.endorserMode = EndorserMode.External + credentialDefinitionPayload.options.endorserDid = endorserDid ? endorserDid : '' + } -// const registerCredentialDefinitionResult = -// await request.agent.modules.anoncreds.registerCredentialDefinition(credentialDefinitionPayload) + const registerCredentialDefinitionResult = + await request.agent.modules.anoncreds.registerCredentialDefinition(credentialDefinitionPayload) -// if (registerCredentialDefinitionResult.credentialDefinitionState.state === CredentialEnum.Failed) { -// throw new InternalServerError('Falied to register credef on ledger') -// } + if (registerCredentialDefinitionResult.credentialDefinitionState.state === CredentialEnum.Failed) { + const failureReason = registerCredentialDefinitionResult.credentialDefinitionState?.reason ?? 'Failed to register credential definition on ledger' + throw new InternalServerError(failureReason) + } -// if (registerCredentialDefinitionResult.credentialDefinitionState.state === CredentialEnum.Wait) { -// // The request has been accepted for processing, but the processing has not been completed. -// this.setStatus(202) -// return registerCredentialDefinitionResult -// } + if (registerCredentialDefinitionResult.credentialDefinitionState.state === CredentialEnum.Wait) { + // The request has been accepted for processing, but the processing has not been completed. + this.setStatus(202) + return registerCredentialDefinitionResult + } -// if (registerCredentialDefinitionResult.credentialDefinitionState.state === CredentialEnum.Action) { -// return registerCredentialDefinitionResult -// } + if (registerCredentialDefinitionResult.credentialDefinitionState.state === CredentialEnum.Action) { + return registerCredentialDefinitionResult + } -// // TODO: Return uniform response for both Internally and Externally endorsed Schemas -// if (!endorse) { -// const indyCredDefId = parseIndyCredentialDefinitionId( -// registerCredentialDefinitionResult.credentialDefinitionState.credentialDefinitionId as string, -// ) -// const getCredentialDefinitionId = await getUnqualifiedCredentialDefinitionId( -// indyCredDefId.namespaceIdentifier, -// indyCredDefId.schemaSeqNo, -// indyCredDefId.tag, -// ) -// registerCredentialDefinitionResult.credentialDefinitionState.credentialDefinitionId = getCredentialDefinitionId -// return registerCredentialDefinitionResult.credentialDefinitionState -// } -// return registerCredentialDefinitionResult -// } catch (error) { -// throw ErrorHandlingService.handle(error) -// } -// } -// } + // TODO: Return uniform response for both Internally and Externally endorsed Schemas + if (!endorse) { + const indyCredDefId = parseIndyCredentialDefinitionId( + registerCredentialDefinitionResult.credentialDefinitionState.credentialDefinitionId as string, + ) + const getCredentialDefinitionId = await getUnqualifiedCredentialDefinitionId( + indyCredDefId.namespaceIdentifier, + indyCredDefId.schemaSeqNo, + indyCredDefId.tag, + ) + registerCredentialDefinitionResult.credentialDefinitionState.credentialDefinitionId = getCredentialDefinitionId + return registerCredentialDefinitionResult.credentialDefinitionState + } + return registerCredentialDefinitionResult + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } +} diff --git a/src/controllers/anoncreds/schema/SchemaController.ts b/src/controllers/anoncreds/schema/SchemaController.ts index 7a1e8577..9bb1f9fb 100644 --- a/src/controllers/anoncreds/schema/SchemaController.ts +++ b/src/controllers/anoncreds/schema/SchemaController.ts @@ -1,125 +1,133 @@ -// import { getUnqualifiedSchemaId, parseIndySchemaId } from '@credo-ts/anoncreds' -// import { Request as Req } from 'express' -// import { Example, Get, Post, Route, Tags, Security, Path, Body, Controller, Request } from 'tsoa' -// import { injectable } from 'tsyringe' +import { getUnqualifiedSchemaId, parseIndySchemaId, RegisterSchemaReturnStateFinished } from '@credo-ts/anoncreds' +import { Request as Req } from 'express' +import { Example, Get, Post, Route, Tags, Security, Path, Body, Controller, Request } from 'tsoa' +import { injectable } from 'tsyringe' -// import { CredentialEnum, EndorserMode, SchemaError, SCOPES } from '../../../enums' -// import ErrorHandlingService from '../../../errorHandlingService' -// import { ENDORSER_DID_NOT_PRESENT } from '../../../errorMessages' -// import { BadRequestError, InternalServerError, NotFoundError } from '../../../errors/errors' -// import { CreateSchemaSuccessful, SchemaExample, SchemaId } from '../../examples' -// import { CreateSchemaInput } from '../../types' +import { CredentialEnum, EndorserMode, SchemaError, SCOPES } from '../../../enums' +import ErrorHandlingService from '../../../errorHandlingService' +import { ENDORSER_DID_NOT_PRESENT } from '../../../errorMessages' +import { BadRequestError, InternalServerError, NotFoundError } from '../../../errors/errors' +import { CreateSchemaSuccessful, SchemaExample, SchemaId } from '../../examples' +import { CreateSchemaInput, RegisterSchemaReturn, SchemaResponseDTO } from '../../types' -// @Tags('Anoncreds - Schemas') -// @Route('/anoncreds/schemas') -// @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT]) -// @injectable() -// export class SchemaController extends Controller { -// /** -// * Get schema by schemaId -// * @param schemaId -// * @param notFoundErrormessage -// * @param forbiddenError -// * @param badRequestError -// * @param internalServerError -// * @returns get schema by Id -// */ -// @Example(SchemaExample) -// @Get('/:schemaId') -// public async getSchemaById(@Request() request: Req, @Path('schemaId') schemaId: SchemaId) { -// try { -// const schemBySchemaId = await request.agent.modules.anoncreds.getSchema(schemaId) +@Tags('Anoncreds - Schemas') +@Route('/anoncreds/schemas') +@Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT]) +@injectable() +export class SchemaController extends Controller { + /** + * Get schema by schemaId + * @param schemaId + * @param notFoundErrormessage + * @param forbiddenError + * @param badRequestError + * @param internalServerError + * @returns get schema by Id + */ + @Example(SchemaExample) + @Get('/:schemaId') + public async getSchemaById( + @Request() request: Req, + @Path('schemaId') schemaId: SchemaId, + ): Promise { + try { + const schemBySchemaId = await request.agent.modules.anoncreds.getSchema(schemaId) -// if ( -// (schemBySchemaId && -// schemBySchemaId?.resolutionMetadata && -// schemBySchemaId?.resolutionMetadata?.error === SchemaError.NotFound) || -// schemBySchemaId?.resolutionMetadata?.error === SchemaError.UnSupportedAnonCredsMethod -// ) { -// throw new NotFoundError( -// schemBySchemaId?.resolutionMetadata?.message || `schema details with schema id "${schemaId}" not found.`, -// ) -// } + if ( + (schemBySchemaId && + schemBySchemaId?.resolutionMetadata && + schemBySchemaId?.resolutionMetadata?.error === SchemaError.NotFound) || + schemBySchemaId?.resolutionMetadata?.error === SchemaError.UnSupportedAnonCredsMethod + ) { + throw new NotFoundError( + schemBySchemaId?.resolutionMetadata?.message || `schema details with schema id "${schemaId}" not found.`, + ) + } -// return schemBySchemaId -// } catch (error) { -// throw ErrorHandlingService.handle(error) -// } -// } + return schemBySchemaId + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } -// /** -// * Create schema -// * @param schema -// * @param notFoundError -// * @param forbiddenError -// * @param badRequestError -// * @param internalServerError -// * @returns get schema -// */ -// @Post('/') -// @Example(CreateSchemaSuccessful) -// public async createSchema(@Request() request: Req, @Body() schema: CreateSchemaInput) { -// try { -// const { issuerId, name, version, attributes } = schema + /** + * Create schema + * @param schema + * @param notFoundError + * @param forbiddenError + * @param badRequestError + * @param internalServerError + * @returns get schema + */ + @Post('/') + @Example(CreateSchemaSuccessful) + public async createSchema( + @Request() request: Req, + @Body() schema: CreateSchemaInput, + ): Promise { + try { + const { issuerId, name, version, attributes } = schema -// const schemaPayload = { -// issuerId, -// name, -// version, -// attrNames: attributes, -// } -// const createSchemaPayload = { -// schema: schemaPayload, -// options: { -// endorserMode: '', -// endorserDid: '', -// }, -// } + const schemaPayload = { + issuerId, + name, + version, + attrNames: attributes, + } + const createSchemaPayload = { + schema: schemaPayload, + options: { + endorserMode: '', + endorserDid: '', + }, + } -// if (!schema.endorse) { -// createSchemaPayload.options.endorserMode = EndorserMode.Internal -// createSchemaPayload.options.endorserDid = issuerId -// } else { -// if (!schema.endorserDid) { -// throw new BadRequestError(ENDORSER_DID_NOT_PRESENT) -// } -// createSchemaPayload.options.endorserMode = EndorserMode.External -// createSchemaPayload.options.endorserDid = schema.endorserDid -// } + if (!schema.endorse) { + createSchemaPayload.options.endorserMode = EndorserMode.Internal + createSchemaPayload.options.endorserDid = issuerId + } else { + if (!schema.endorserDid) { + throw new BadRequestError(ENDORSER_DID_NOT_PRESENT) + } + createSchemaPayload.options.endorserMode = EndorserMode.External + createSchemaPayload.options.endorserDid = schema.endorserDid + } -// const createSchemaTxResult = await request.agent.modules.anoncreds.registerSchema(createSchemaPayload) + const createSchemaTxResult = await request.agent.modules.anoncreds.registerSchema(createSchemaPayload) -// if (createSchemaTxResult.schemaState.state === CredentialEnum.Failed) { -// throw new InternalServerError(`Schema creation failed. Reason: ${createSchemaTxResult.schemaState.reason}`) -// } + if (createSchemaTxResult.schemaState.state === CredentialEnum.Failed) { + throw new InternalServerError(`Schema creation failed. Reason: ${createSchemaTxResult.schemaState.reason}`) + } -// if (createSchemaTxResult.schemaState.state === CredentialEnum.Wait) { -// this.setStatus(202) -// return createSchemaTxResult -// } + if (createSchemaTxResult.schemaState.state === CredentialEnum.Wait) { + this.setStatus(202) + return createSchemaTxResult + } -// if (createSchemaTxResult.schemaState.state === CredentialEnum.Action) { -// return createSchemaTxResult -// } + if (createSchemaTxResult.schemaState.state === CredentialEnum.Action) { + return createSchemaTxResult + } -// if (createSchemaTxResult.schemaState.state === CredentialEnum.Finished) { -// // TODO: Return uniform response for both Internally and Externally endorsed Schemas -// if (!schema.endorse) { -// const indySchemaId = parseIndySchemaId(createSchemaTxResult.schemaState.schemaId as string) + if (createSchemaTxResult.schemaState.state === CredentialEnum.Finished) { + // TODO: Return uniform response for both Internally and Externally endorsed Schemas + if (!schema.endorse) { + const indySchemaId = parseIndySchemaId(createSchemaTxResult.schemaState.schemaId as string) -// const getSchemaUnqualifiedId = await getUnqualifiedSchemaId( -// indySchemaId.namespaceIdentifier, -// indySchemaId.schemaName, -// indySchemaId.schemaVersion, -// ) + const getSchemaUnqualifiedId = await getUnqualifiedSchemaId( + indySchemaId.namespaceIdentifier, + indySchemaId.schemaName, + indySchemaId.schemaVersion, + ) -// createSchemaTxResult.schemaState.schemaId = getSchemaUnqualifiedId -// return createSchemaTxResult.schemaState -// } -// return createSchemaTxResult -// } -// } catch (error) { -// throw ErrorHandlingService.handle(error) -// } -// } -// } + createSchemaTxResult.schemaState.schemaId = getSchemaUnqualifiedId + return createSchemaTxResult.schemaState + } + return createSchemaTxResult + } + // If none of the above conditions are met, throw an error or return a default value + throw new InternalServerError('Unexpected schema creation state.') + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } +} diff --git a/src/controllers/did/DidController.ts b/src/controllers/did/DidController.ts index 682c12bf..f5c56ce3 100644 --- a/src/controllers/did/DidController.ts +++ b/src/controllers/did/DidController.ts @@ -200,7 +200,9 @@ export class DidController extends Controller { } if (createDidOptions?.role?.toLowerCase() === Role.Endorser) { if (createDidOptions.did) { - await this.importDid(agent, didMethod, createDidOptions.did, createDidOptions.seed) + // Hint: Bcovrin uses seed as private key when creating key. But seed is written as a NYM transaction + // Triage: Make sure what to use, seed or privateKey when accepting from API itself + await this.importDid(agent, didMethod, createDidOptions.did, '', createDidOptions.seed) const getDid = await agent.dids.getCreatedDids({ method: createDidOptions.method, did: `did:${createDidOptions.method}:${createDidOptions.network}:${createDidOptions.did}`, @@ -224,7 +226,7 @@ export class DidController extends Controller { seed: createDidOptions.seed, }) const { did } = res?.data || {} - await this.importDid(agent, didMethod, did, createDidOptions.seed) + await this.importDid(agent, didMethod, did, '', createDidOptions.seed) const didRecord = await agent.dids.getCreatedDids({ method: DidMethod.Indy, did: `did:${DidMethod.Indy}:${Network.Bcovrin_Testnet}:${res.data.did}`, @@ -270,11 +272,11 @@ export class DidController extends Controller { didDocument: didDocument, } } else { - const key = await this.createIndicioKey(agent, createDidOptions) + const { keyId, ...key } = await this.createIndicioKey(agent, createDidOptions) const INDICIO_NYM_URL = process.env.INDICIO_NYM_URL as string const res = await axios.post(INDICIO_NYM_URL, key) if (res.data.statusCode === 200) { - await this.importDid(agent, didMethod, key.did, createDidOptions.seed) + await this.importDid(agent, didMethod, key.did, createDidOptions.seed, undefined, keyId) const didRecord = await agent.dids.getCreatedDids({ method: DidMethod.Indy, did: `${didMethod}:${key.did}`, @@ -326,34 +328,39 @@ export class DidController extends Controller { // const buffer = TypedArrayEncoder.fromBase58(key.publicKeyBase58) // const did = TypedArrayEncoder.toBase58(buffer.slice(0, 16)) - const _verificationKey = ( - await agent.kms.createKey({ - type: { - kty: 'OKP', - crv: 'Ed25519', - }, - }) - ).publicJwk + const privateJwk = transformSeedToPrivateJwk({ + seed: TypedArrayEncoder.fromString(createDidOptions.seed), + type: { + crv: 'Ed25519', + kty: 'OKP', + }, + }).privateJwk - const verificationKey = Kms.PublicJwk.fromPublicJwk(_verificationKey) as Kms.PublicJwk + const key = await agent.kms.importKey({ + privateJwk, + }) + + const verificationKey = Kms.PublicJwk.fromPublicJwk(key.publicJwk) as Kms.PublicJwk // Create a new key and calculate did according to the rules for indy did method - const buffer = Hasher.hash(verificationKey.publicKey.publicKey, 'sha-256') + const publicKeyBytes = verificationKey.publicKey.publicKey - const did = TypedArrayEncoder.toBase58(buffer.slice(0, 16)) + const did = TypedArrayEncoder.toBase58(publicKeyBytes.slice(0, 16)) let body if (createDidOptions.network === Network.Indicio_Testnet) { body = { network: 'testnet', did, - verkey: TypedArrayEncoder.toBase58(buffer), + verkey: TypedArrayEncoder.toBase58(publicKeyBytes), + keyId: key.keyId, } } else if (createDidOptions.network === Network.Indicio_Demonet) { body = { network: 'demonet', did, - verkey: TypedArrayEncoder.toBase58(buffer), + verkey: TypedArrayEncoder.toBase58(publicKeyBytes), + keyId: key.keyId, } } else { throw new BadRequestError('Please provide a valid did method') @@ -361,36 +368,53 @@ export class DidController extends Controller { return body } - private async importDid(agent: AgentType, didMethod: string, did: string, seed: string) { - // TODO: Remove comments afterwards - // await agent.dids.import({ - // did: `${didMethod}:${did}`, - // overwrite: true, - // privateKeys: [ - // { - // keyType: KeyAlgorithm.Ed25519, - // privateKey: TypedArrayEncoder.fromString(seed), - // }, - // ], - // }) - - const { privateJwk } = transformSeedToPrivateJwk({ - type: { - crv: 'Ed25519', - kty: 'OKP', - }, - seed: TypedArrayEncoder.fromString(seed), - }) + private async importDid( + agent: AgentType, + didMethod: string, + did: string, + seed: string, + privateKey?: string, + keyId?: string, + ) { + let _keyId: string + + if (!keyId) { + const { privateJwk } = privateKey + ? transformPrivateKeyToPrivateJwk({ + type: { + crv: 'Ed25519', + kty: 'OKP', + }, + privateKey: TypedArrayEncoder.fromString(privateKey), + }) + : seed + ? transformSeedToPrivateJwk({ + seed: TypedArrayEncoder.fromString(seed), + type: { + crv: 'Ed25519', + kty: 'OKP', + }, + }) + : { + privateJwk: undefined, + } + + if (!privateJwk) { + throw new Error('Either privateKey or seed is required') + } - const key = await agent.kms.importKey({ privateJwk }) + const key = await agent.kms.importKey({ privateJwk }) + _keyId = key.keyId + } else { + _keyId = keyId + } - const publicJwk = Kms.PublicJwk.fromPublicJwk(key.publicJwk) const completeDid = `${didMethod}:${did}` await agent.dids.import({ did: completeDid, keys: [ { - kmsKeyId: key.keyId, + kmsKeyId: _keyId, didDocumentRelativeKeyId: verkey, }, ], diff --git a/src/controllers/types.ts b/src/controllers/types.ts index 19e4c635..23ea0e8d 100644 --- a/src/controllers/types.ts +++ b/src/controllers/types.ts @@ -1,5 +1,17 @@ import type { RecordId } from './examples' -import type { AnonCredsDidCommCredentialFormat, LegacyIndyCredentialFormat } from '@credo-ts/anoncreds' +import type { + AnonCredsCredentialDefinition, + AnonCredsDidCommCredentialFormat, + LegacyIndyCredentialFormat, + RegisterCredentialDefinitionReturnStateAction, + RegisterCredentialDefinitionReturnStateFailed, + RegisterCredentialDefinitionReturnStateFinished, + RegisterCredentialDefinitionReturnStateWait, + RegisterSchemaReturnStateAction, + RegisterSchemaReturnStateFailed, + RegisterSchemaReturnStateFinished, + RegisterSchemaReturnStateWait, +} from '@credo-ts/anoncreds' import type { DidResolutionMetadata, DidDocumentMetadata, @@ -493,3 +505,46 @@ export type EcType = { kty: 'EC' crv: 'P-256' | 'P-384' | 'P-521' | 'secp256k1' } + +export interface SchemaResponseDTO { + schemaId: string + schema?: { + issuerId: string + name: string + version: string + attrNames: string[] + } + resolutionMetadata: Record // Use Record or explicitly define what you need + schemaMetadata: Record +} + +export interface RegisterSchemaReturn { + jobId?: string + schemaState: + | RegisterSchemaReturnStateWait + | RegisterSchemaReturnStateAction + | RegisterSchemaReturnStateFinished + | RegisterSchemaReturnStateFailed + schemaMetadata: Record + registrationMetadata: Record +} + +export interface GetCredentialDefinitionReturn { + credentialDefinition?: AnonCredsCredentialDefinition + credentialDefinitionId: string + resolutionMetadata: Record + credentialDefinitionMetadata: Record +} + +export type CredentialDefinitionStates = + | RegisterCredentialDefinitionReturnStateWait + | RegisterCredentialDefinitionReturnStateAction + | RegisterCredentialDefinitionReturnStateFinished + | RegisterCredentialDefinitionReturnStateFailed + +export interface RegisterCredentialDefinitionReturn { + jobId?: string + credentialDefinitionState: CredentialDefinitionStates + credentialDefinitionMetadata: Record + registrationMetadata: Record +} diff --git a/src/enums/enum.ts b/src/enums/enum.ts index b58196a2..ed45ac7b 100644 --- a/src/enums/enum.ts +++ b/src/enums/enum.ts @@ -44,7 +44,11 @@ export enum NetworkTypes { export enum IndicioAcceptanceMechanism { Wallet_Agreement = 'wallet_agreement', - Accept = 'accept', + At_Submission = 'at_submission', + For_Session = 'for_session', + On_File = 'on_file', + Product_Eula = 'product_eula', + Service_Agreement = 'service_agreement', } export enum EndorserMode { diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 55f296e3..6af71e35 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -30,6 +30,10 @@ import { AuthController } from './../controllers/auth/AuthController'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { AgentController } from './../controllers/agent/AgentController'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa +import { SchemaController } from './../controllers/anoncreds/schema/SchemaController'; +// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa +import { CredentialDefinitionController } from './../controllers/anoncreds/cred-def/CredentialDefinitionController'; +// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { VerifierController } from './../controllers/openid4vc/verifiers/verifier.Controller'; import { expressAuthentication } from './../authentication'; // @ts-ignore - no great way to install types from subpackage @@ -1540,6 +1544,185 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "SchemaResponseDTO": { + "dataType": "refObject", + "properties": { + "schemaId": {"dataType":"string","required":true}, + "schema": {"dataType":"nestedObjectLiteral","nestedProperties":{"attrNames":{"dataType":"array","array":{"dataType":"string"},"required":true},"version":{"dataType":"string","required":true},"name":{"dataType":"string","required":true},"issuerId":{"dataType":"string","required":true}}}, + "resolutionMetadata": {"ref":"Record_string.unknown_","required":true}, + "schemaMetadata": {"ref":"Record_string.unknown_","required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "SchemaId": { + "dataType": "refAlias", + "type": {"dataType":"string","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AnonCredsSchema": { + "dataType": "refObject", + "properties": { + "issuerId": {"dataType":"string","required":true}, + "name": {"dataType":"string","required":true}, + "version": {"dataType":"string","required":true}, + "attrNames": {"dataType":"array","array":{"dataType":"string"},"required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterSchemaReturnStateWait": { + "dataType": "refObject", + "properties": { + "state": {"dataType":"enum","enums":["wait"],"required":true}, + "schema": {"ref":"AnonCredsSchema"}, + "schemaId": {"dataType":"string"}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterSchemaReturnStateAction": { + "dataType": "refObject", + "properties": { + "state": {"dataType":"enum","enums":["action"],"required":true}, + "action": {"dataType":"string","required":true}, + "schema": {"ref":"AnonCredsSchema","required":true}, + "schemaId": {"dataType":"string","required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterSchemaReturnStateFinished": { + "dataType": "refObject", + "properties": { + "state": {"dataType":"enum","enums":["finished"],"required":true}, + "schema": {"ref":"AnonCredsSchema","required":true}, + "schemaId": {"dataType":"string","required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterSchemaReturnStateFailed": { + "dataType": "refObject", + "properties": { + "state": {"dataType":"enum","enums":["failed"],"required":true}, + "reason": {"dataType":"string","required":true}, + "schema": {"ref":"AnonCredsSchema"}, + "schemaId": {"dataType":"string"}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterSchemaReturn": { + "dataType": "refObject", + "properties": { + "jobId": {"dataType":"string"}, + "schemaState": {"dataType":"union","subSchemas":[{"ref":"RegisterSchemaReturnStateWait"},{"ref":"RegisterSchemaReturnStateAction"},{"ref":"RegisterSchemaReturnStateFinished"},{"ref":"RegisterSchemaReturnStateFailed"}],"required":true}, + "schemaMetadata": {"ref":"Record_string.unknown_","required":true}, + "registrationMetadata": {"ref":"Record_string.unknown_","required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "CreateSchemaInput": { + "dataType": "refObject", + "properties": { + "issuerId": {"dataType":"string","required":true}, + "name": {"dataType":"string","required":true}, + "version": {"dataType":"string","required":true}, + "attributes": {"dataType":"array","array":{"dataType":"string"},"required":true}, + "endorse": {"dataType":"boolean"}, + "endorserDid": {"dataType":"string"}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AnonCredsCredentialDefinition": { + "dataType": "refObject", + "properties": { + "issuerId": {"dataType":"string","required":true}, + "schemaId": {"dataType":"string","required":true}, + "type": {"dataType":"enum","enums":["CL"],"required":true}, + "tag": {"dataType":"string","required":true}, + "value": {"dataType":"nestedObjectLiteral","nestedProperties":{"revocation":{"dataType":"any"},"primary":{"ref":"Record_string.unknown_","required":true}},"required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "GetCredentialDefinitionReturn": { + "dataType": "refObject", + "properties": { + "credentialDefinition": {"ref":"AnonCredsCredentialDefinition"}, + "credentialDefinitionId": {"dataType":"string","required":true}, + "resolutionMetadata": {"ref":"Record_string.unknown_","required":true}, + "credentialDefinitionMetadata": {"ref":"Record_string.unknown_","required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "CredentialDefinitionId": { + "dataType": "refAlias", + "type": {"dataType":"string","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterCredentialDefinitionReturnStateWait": { + "dataType": "refObject", + "properties": { + "state": {"dataType":"enum","enums":["wait"],"required":true}, + "credentialDefinition": {"ref":"AnonCredsCredentialDefinition"}, + "credentialDefinitionId": {"dataType":"string"}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterCredentialDefinitionReturnStateAction": { + "dataType": "refObject", + "properties": { + "state": {"dataType":"enum","enums":["action"],"required":true}, + "action": {"dataType":"string","required":true}, + "credentialDefinitionId": {"dataType":"string","required":true}, + "credentialDefinition": {"ref":"AnonCredsCredentialDefinition","required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterCredentialDefinitionReturnStateFinished": { + "dataType": "refObject", + "properties": { + "state": {"dataType":"enum","enums":["finished"],"required":true}, + "credentialDefinition": {"ref":"AnonCredsCredentialDefinition","required":true}, + "credentialDefinitionId": {"dataType":"string","required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterCredentialDefinitionReturnStateFailed": { + "dataType": "refObject", + "properties": { + "state": {"dataType":"enum","enums":["failed"],"required":true}, + "reason": {"dataType":"string","required":true}, + "credentialDefinition": {"ref":"AnonCredsCredentialDefinition"}, + "credentialDefinitionId": {"dataType":"string"}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "CredentialDefinitionStates": { + "dataType": "refAlias", + "type": {"dataType":"union","subSchemas":[{"ref":"RegisterCredentialDefinitionReturnStateWait"},{"ref":"RegisterCredentialDefinitionReturnStateAction"},{"ref":"RegisterCredentialDefinitionReturnStateFinished"},{"ref":"RegisterCredentialDefinitionReturnStateFailed"}],"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "RegisterCredentialDefinitionReturn": { + "dataType": "refObject", + "properties": { + "jobId": {"dataType":"string"}, + "credentialDefinitionState": {"ref":"CredentialDefinitionStates","required":true}, + "credentialDefinitionMetadata": {"ref":"Record_string.unknown_","required":true}, + "registrationMetadata": {"ref":"Record_string.unknown_","required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "OpenId4VcVerifierRecord": { "dataType": "refAlias", "type": {"ref":"Record_string.unknown_","validators":{}}, @@ -4082,6 +4265,154 @@ export function RegisterRoutes(app: Router) { } }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + const argsSchemaController_getSchemaById: Record = { + request: {"in":"request","name":"request","required":true,"dataType":"object"}, + schemaId: {"in":"path","name":"schemaId","required":true,"ref":"SchemaId"}, + }; + app.get('/anoncreds/schemas/:schemaId', + authenticateMiddleware([{"jwt":["tenant","dedicated"]}]), + ...(fetchMiddlewares(SchemaController)), + ...(fetchMiddlewares(SchemaController.prototype.getSchemaById)), + + async function SchemaController_getSchemaById(request: ExRequest, response: ExResponse, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args: argsSchemaController_getSchemaById, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(SchemaController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'getSchemaById', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + const argsSchemaController_createSchema: Record = { + request: {"in":"request","name":"request","required":true,"dataType":"object"}, + schema: {"in":"body","name":"schema","required":true,"ref":"CreateSchemaInput"}, + }; + app.post('/anoncreds/schemas', + authenticateMiddleware([{"jwt":["tenant","dedicated"]}]), + ...(fetchMiddlewares(SchemaController)), + ...(fetchMiddlewares(SchemaController.prototype.createSchema)), + + async function SchemaController_createSchema(request: ExRequest, response: ExResponse, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args: argsSchemaController_createSchema, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(SchemaController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'createSchema', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + const argsCredentialDefinitionController_getCredentialDefinitionById: Record = { + request: {"in":"request","name":"request","required":true,"dataType":"object"}, + credentialDefinitionId: {"in":"path","name":"credentialDefinitionId","required":true,"ref":"CredentialDefinitionId"}, + }; + app.get('/anoncreds/credential-definitions/:credentialDefinitionId', + authenticateMiddleware([{"jwt":["tenant","dedicated"]}]), + ...(fetchMiddlewares(CredentialDefinitionController)), + ...(fetchMiddlewares(CredentialDefinitionController.prototype.getCredentialDefinitionById)), + + async function CredentialDefinitionController_getCredentialDefinitionById(request: ExRequest, response: ExResponse, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args: argsCredentialDefinitionController_getCredentialDefinitionById, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(CredentialDefinitionController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'getCredentialDefinitionById', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + const argsCredentialDefinitionController_createCredentialDefinition: Record = { + request: {"in":"request","name":"request","required":true,"dataType":"object"}, + credentialDefinitionRequest: {"in":"body","name":"credentialDefinitionRequest","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"endorserDid":{"dataType":"string"},"endorse":{"dataType":"boolean"},"tag":{"dataType":"string","required":true},"schemaId":{"ref":"SchemaId","required":true},"issuerId":{"dataType":"string","required":true}}}, + }; + app.post('/anoncreds/credential-definitions', + authenticateMiddleware([{"jwt":["tenant","dedicated"]}]), + ...(fetchMiddlewares(CredentialDefinitionController)), + ...(fetchMiddlewares(CredentialDefinitionController.prototype.createCredentialDefinition)), + + async function CredentialDefinitionController_createCredentialDefinition(request: ExRequest, response: ExResponse, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args: argsCredentialDefinitionController_createCredentialDefinition, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(CredentialDefinitionController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'createCredentialDefinition', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa const argsVerifierController_createVerifier: Record = { request: {"in":"request","name":"request","required":true,"dataType":"object"}, options: {"in":"body","name":"options","required":true,"ref":"OpenId4VcSiopCreateVerifierOptions"}, diff --git a/src/routes/swagger.json b/src/routes/swagger.json index 55f04345..787e08ae 100644 --- a/src/routes/swagger.json +++ b/src/routes/swagger.json @@ -3477,6 +3477,459 @@ "type": "object", "additionalProperties": false }, + "SchemaResponseDTO": { + "properties": { + "schemaId": { + "type": "string" + }, + "schema": { + "properties": { + "attrNames": { + "items": { + "type": "string" + }, + "type": "array" + }, + "version": { + "type": "string" + }, + "name": { + "type": "string" + }, + "issuerId": { + "type": "string" + } + }, + "required": [ + "attrNames", + "version", + "name", + "issuerId" + ], + "type": "object" + }, + "resolutionMetadata": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, + "schemaMetadata": { + "$ref": "#/components/schemas/Record_string.unknown_" + } + }, + "required": [ + "schemaId", + "resolutionMetadata", + "schemaMetadata" + ], + "type": "object", + "additionalProperties": false + }, + "SchemaId": { + "type": "string", + "example": "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0" + }, + "AnonCredsSchema": { + "properties": { + "issuerId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "attrNames": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "issuerId", + "name", + "version", + "attrNames" + ], + "type": "object", + "additionalProperties": false + }, + "RegisterSchemaReturnStateWait": { + "properties": { + "state": { + "type": "string", + "enum": [ + "wait" + ], + "nullable": false + }, + "schema": { + "$ref": "#/components/schemas/AnonCredsSchema" + }, + "schemaId": { + "type": "string" + } + }, + "required": [ + "state" + ], + "type": "object", + "additionalProperties": false + }, + "RegisterSchemaReturnStateAction": { + "properties": { + "state": { + "type": "string", + "enum": [ + "action" + ], + "nullable": false + }, + "action": { + "type": "string" + }, + "schema": { + "$ref": "#/components/schemas/AnonCredsSchema" + }, + "schemaId": { + "type": "string" + } + }, + "required": [ + "state", + "action", + "schema", + "schemaId" + ], + "type": "object", + "additionalProperties": false + }, + "RegisterSchemaReturnStateFinished": { + "properties": { + "state": { + "type": "string", + "enum": [ + "finished" + ], + "nullable": false + }, + "schema": { + "$ref": "#/components/schemas/AnonCredsSchema" + }, + "schemaId": { + "type": "string" + } + }, + "required": [ + "state", + "schema", + "schemaId" + ], + "type": "object", + "additionalProperties": false + }, + "RegisterSchemaReturnStateFailed": { + "properties": { + "state": { + "type": "string", + "enum": [ + "failed" + ], + "nullable": false + }, + "reason": { + "type": "string" + }, + "schema": { + "$ref": "#/components/schemas/AnonCredsSchema" + }, + "schemaId": { + "type": "string" + } + }, + "required": [ + "state", + "reason" + ], + "type": "object", + "additionalProperties": false + }, + "RegisterSchemaReturn": { + "properties": { + "jobId": { + "type": "string" + }, + "schemaState": { + "anyOf": [ + { + "$ref": "#/components/schemas/RegisterSchemaReturnStateWait" + }, + { + "$ref": "#/components/schemas/RegisterSchemaReturnStateAction" + }, + { + "$ref": "#/components/schemas/RegisterSchemaReturnStateFinished" + }, + { + "$ref": "#/components/schemas/RegisterSchemaReturnStateFailed" + } + ] + }, + "schemaMetadata": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, + "registrationMetadata": { + "$ref": "#/components/schemas/Record_string.unknown_" + } + }, + "required": [ + "schemaState", + "schemaMetadata", + "registrationMetadata" + ], + "type": "object", + "additionalProperties": false + }, + "CreateSchemaInput": { + "properties": { + "issuerId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "attributes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "endorse": { + "type": "boolean" + }, + "endorserDid": { + "type": "string" + } + }, + "required": [ + "issuerId", + "name", + "version", + "attributes" + ], + "type": "object", + "additionalProperties": false + }, + "AnonCredsCredentialDefinition": { + "properties": { + "issuerId": { + "type": "string" + }, + "schemaId": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "CL" + ], + "nullable": false + }, + "tag": { + "type": "string" + }, + "value": { + "properties": { + "revocation": {}, + "primary": { + "$ref": "#/components/schemas/Record_string.unknown_" + } + }, + "required": [ + "primary" + ], + "type": "object" + } + }, + "required": [ + "issuerId", + "schemaId", + "type", + "tag", + "value" + ], + "type": "object", + "additionalProperties": false + }, + "GetCredentialDefinitionReturn": { + "properties": { + "credentialDefinition": { + "$ref": "#/components/schemas/AnonCredsCredentialDefinition" + }, + "credentialDefinitionId": { + "type": "string" + }, + "resolutionMetadata": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, + "credentialDefinitionMetadata": { + "$ref": "#/components/schemas/Record_string.unknown_" + } + }, + "required": [ + "credentialDefinitionId", + "resolutionMetadata", + "credentialDefinitionMetadata" + ], + "type": "object", + "additionalProperties": false + }, + "CredentialDefinitionId": { + "type": "string", + "example": "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag" + }, + "RegisterCredentialDefinitionReturnStateWait": { + "properties": { + "state": { + "type": "string", + "enum": [ + "wait" + ], + "nullable": false + }, + "credentialDefinition": { + "$ref": "#/components/schemas/AnonCredsCredentialDefinition" + }, + "credentialDefinitionId": { + "type": "string" + } + }, + "required": [ + "state" + ], + "type": "object", + "additionalProperties": false + }, + "RegisterCredentialDefinitionReturnStateAction": { + "properties": { + "state": { + "type": "string", + "enum": [ + "action" + ], + "nullable": false + }, + "action": { + "type": "string" + }, + "credentialDefinitionId": { + "type": "string" + }, + "credentialDefinition": { + "$ref": "#/components/schemas/AnonCredsCredentialDefinition" + } + }, + "required": [ + "state", + "action", + "credentialDefinitionId", + "credentialDefinition" + ], + "type": "object", + "additionalProperties": false + }, + "RegisterCredentialDefinitionReturnStateFinished": { + "properties": { + "state": { + "type": "string", + "enum": [ + "finished" + ], + "nullable": false + }, + "credentialDefinition": { + "$ref": "#/components/schemas/AnonCredsCredentialDefinition" + }, + "credentialDefinitionId": { + "type": "string" + } + }, + "required": [ + "state", + "credentialDefinition", + "credentialDefinitionId" + ], + "type": "object", + "additionalProperties": false + }, + "RegisterCredentialDefinitionReturnStateFailed": { + "properties": { + "state": { + "type": "string", + "enum": [ + "failed" + ], + "nullable": false + }, + "reason": { + "type": "string" + }, + "credentialDefinition": { + "$ref": "#/components/schemas/AnonCredsCredentialDefinition" + }, + "credentialDefinitionId": { + "type": "string" + } + }, + "required": [ + "state", + "reason" + ], + "type": "object", + "additionalProperties": false + }, + "CredentialDefinitionStates": { + "anyOf": [ + { + "$ref": "#/components/schemas/RegisterCredentialDefinitionReturnStateWait" + }, + { + "$ref": "#/components/schemas/RegisterCredentialDefinitionReturnStateAction" + }, + { + "$ref": "#/components/schemas/RegisterCredentialDefinitionReturnStateFinished" + }, + { + "$ref": "#/components/schemas/RegisterCredentialDefinitionReturnStateFailed" + } + ] + }, + "RegisterCredentialDefinitionReturn": { + "properties": { + "jobId": { + "type": "string" + }, + "credentialDefinitionState": { + "$ref": "#/components/schemas/CredentialDefinitionStates" + }, + "credentialDefinitionMetadata": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, + "registrationMetadata": { + "$ref": "#/components/schemas/Record_string.unknown_" + } + }, + "required": [ + "credentialDefinitionState", + "credentialDefinitionMetadata", + "registrationMetadata" + ], + "type": "object", + "additionalProperties": false + }, "OpenId4VcVerifierRecord": { "$ref": "#/components/schemas/Record_string.unknown_", "description": "For OID4VC you need to expos metadata files. Each issuer needs to host this metadata. This is not the case for DIDComm where we can just have one /didcomm endpoint.\nSo we create a record per openid issuer/verifier that you want, and each tenant can create multiple issuers/verifiers which have different endpoints\nand metadata files" @@ -7402,6 +7855,306 @@ } } }, + "/anoncreds/schemas/{schemaId}": { + "get": { + "operationId": "GetSchemaById", + "responses": { + "200": { + "description": "get schema by Id", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SchemaResponseDTO" + }, + "examples": { + "Example 1": { + "value": { + "ver": "1.0", + "id": "WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0", + "name": "schema", + "version": "1.0", + "attrNames": [ + "string" + ], + "seqNo": 351936 + } + } + } + } + } + } + }, + "description": "Get schema by schemaId", + "tags": [ + "Anoncreds - Schemas" + ], + "security": [ + { + "jwt": [ + "tenant", + "dedicated" + ] + } + ], + "parameters": [ + { + "in": "path", + "name": "schemaId", + "required": true, + "schema": { + "$ref": "#/components/schemas/SchemaId" + } + } + ] + } + }, + "/anoncreds/schemas": { + "post": { + "operationId": "CreateSchema", + "responses": { + "200": { + "description": "get schema", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/RegisterSchemaReturn" + }, + { + "$ref": "#/components/schemas/RegisterSchemaReturnStateFinished" + } + ] + }, + "examples": { + "Example 1": { + "value": { + "state": "finished", + "schema": { + "issuerId": "did:indy:bcovrin:testnet:LRCUFcizUL74AGgLqdJHK7", + "name": "Test Schema", + "version": "1.0.0", + "attrNames": [ + "Name", + "Age" + ] + }, + "schemaId": "LRCUFcizUL74AGgLqdJHK7:2:Test Schema:1.0.0" + } + } + } + } + } + } + }, + "description": "Create schema", + "tags": [ + "Anoncreds - Schemas" + ], + "security": [ + { + "jwt": [ + "tenant", + "dedicated" + ] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSchemaInput" + } + } + } + } + } + }, + "/anoncreds/credential-definitions/{credentialDefinitionId}": { + "get": { + "operationId": "GetCredentialDefinitionById", + "responses": { + "200": { + "description": "CredDef", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetCredentialDefinitionReturn" + }, + "examples": { + "Example 1": { + "value": { + "ver": "1.0", + "id": "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "schemaId": "351936", + "type": "CL", + "tag": "definition", + "value": { + "primary": { + "n": "string", + "s": "string", + "r": { + "master_secret": "string", + "string": "string" + }, + "rctxt": "string", + "z": "string" + }, + "revocation": { + "g": "1 string", + "g_dash": "string", + "h": "string", + "h0": "string", + "h1": "string", + "h2": "string", + "htilde": "string", + "h_cap": "string", + "u": "string", + "pk": "string", + "y": "string" + } + } + } + } + } + } + } + } + }, + "description": "Retrieve credential definition by credential definition id", + "tags": [ + "Anoncreds - Credential Definitions" + ], + "security": [ + { + "jwt": [ + "tenant", + "dedicated" + ] + } + ], + "parameters": [ + { + "in": "path", + "name": "credentialDefinitionId", + "required": true, + "schema": { + "$ref": "#/components/schemas/CredentialDefinitionId" + } + } + ] + } + }, + "/anoncreds/credential-definitions": { + "post": { + "operationId": "CreateCredentialDefinition", + "responses": { + "200": { + "description": "CredDef", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/RegisterCredentialDefinitionReturn" + }, + { + "$ref": "#/components/schemas/CredentialDefinitionStates" + } + ] + }, + "examples": { + "Example 1": { + "value": { + "ver": "1.0", + "id": "WgWxqztrNooG92RXvxSTWv:3:CL:20:tag", + "schemaId": "351936", + "type": "CL", + "tag": "definition", + "value": { + "primary": { + "n": "string", + "s": "string", + "r": { + "master_secret": "string", + "string": "string" + }, + "rctxt": "string", + "z": "string" + }, + "revocation": { + "g": "1 string", + "g_dash": "string", + "h": "string", + "h0": "string", + "h1": "string", + "h2": "string", + "htilde": "string", + "h_cap": "string", + "u": "string", + "pk": "string", + "y": "string" + } + } + } + } + } + } + } + }, + "202": { + "description": "Wait for action to complete" + } + }, + "description": "Creates a new credential definition.", + "tags": [ + "Anoncreds - Credential Definitions" + ], + "security": [ + { + "jwt": [ + "tenant", + "dedicated" + ] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "endorserDid": { + "type": "string" + }, + "endorse": { + "type": "boolean" + }, + "tag": { + "type": "string" + }, + "schemaId": { + "$ref": "#/components/schemas/SchemaId" + }, + "issuerId": { + "type": "string" + } + }, + "required": [ + "tag", + "schemaId", + "issuerId" + ], + "type": "object" + } + } + } + } + } + }, "/openid4vc/verifier": { "post": { "operationId": "CreateVerifier",