Skip to content

Commit

Permalink
feat: initial presentation controller
Browse files Browse the repository at this point in the history
  • Loading branch information
genaris committed May 7, 2024
1 parent d408818 commit 9a382a1
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CredentialTypesController } from './controllers/credentials/CredentialT
import { InvitationController } from './controllers/invitation/InvitationController'
import { QrController } from './controllers/invitation/QrController'
import { MessageController } from './controllers/message/MessageController'
import { PresentationsController } from './controllers/presentations/PresentationsController'
import { AgentService } from './services/AgentService'
import { UrlShorteningService } from './services/UrlShorteningService'
import { ServiceAgent } from './utils/ServiceAgent'
Expand All @@ -20,6 +21,7 @@ export class ServiceAgentModule {
ConnectionController,
CredentialTypesController,
MessageController,
PresentationsController,
InvitationController,
QrController,
],
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/invitation/InvitationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export class InvitationController {
const shortUrl = `${process.env.PUBLIC_API_BASE_URL ?? 'http://localhost:3001'}/s?id=${shortUrlId}`

return {
presentationRequestId: request.proofRecord.id,
proofExchangeId: request.proofRecord.id,
url,
shortUrl,
}
Expand Down Expand Up @@ -191,7 +191,7 @@ export class InvitationController {
const shortUrl = `${process.env.PUBLIC_API_BASE_URL ?? 'http://localhost:3001'}/s?id=${shortUrlId}`

return {
credentialOfferId: request.credentialRecord.id,
credentialExchangeId: request.credentialRecord.id,
url,
shortUrl,
}
Expand Down
122 changes: 122 additions & 0 deletions src/controllers/presentations/PresentationsController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import {
BadRequestException,
Controller,
Delete,
Get,
InternalServerErrorException,
Logger,
NotFoundException,
Param,
} from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger'

import { Claim } from '../../model'
import { AgentService } from '../../services/AgentService'
import { CredentialTypeInfo } from '../types'

@ApiTags('presentations')
@Controller({
path: 'presentations',
version: '1',
})
export class PresentationsController {
private readonly logger = new Logger(PresentationsController.name)

constructor(private readonly agentService: AgentService) {}

/**
* Get all created credential types
*
* @returns
*/
@Get('/')
public async getAllCredentialTypes(): Promise<CredentialTypeInfo[]> {
const agent = await this.agentService.getAgent()

const credentialDefinitions = await agent.modules.anoncreds.getCreatedCredentialDefinitions({})

return Promise.all(
credentialDefinitions.map(async record => {
const schemaResult = await agent.modules.anoncreds.getSchema(record.credentialDefinition.schemaId)

const schema = schemaResult.schema

return {
id: record.credentialDefinitionId,
name: (record.getTag('name') as string) ?? schema?.name,
version: (record.getTag('version') as string) ?? schema?.version,
attributes: schema?.attrNames || [],
}
}),
)
}

/**
* Delete a presentation exchange record
*
* @param proofExchangeId Proof Exchange Id
*/
@Delete('/:proofExchangeId')
public async deleteProofExchangeById(@Param('proofExchangeId') proofExchangeId: string) {
const agent = await this.agentService.getAgent()
await agent.proofs.deleteById(proofExchangeId, { deleteAssociatedDidCommMessages: true })
}

/**
* Export a credential type, including its underlying cryptographic data for importing it in another instance
*
* @param credentialTypeId Credential Type Id
* @returns ConnectionRecord
*/
@Get('/:proofExchangeId')
public async getPresentationById(@Param('proofExchangeId') proofExchangeId: string) {
const agent = await this.agentService.getAgent()

if (!proofExchangeId) {
throw new BadRequestException({ reason: 'proofExchangeId is required' })
}

const record = await agent.proofs.findById(proofExchangeId)

if (!record) {
throw new NotFoundException({ reason: `proof exchange with id "${proofExchangeId}" not found.` })
}

try {
const formatData = await agent.proofs.getFormatData(record.id)

const revealedAttributes =
formatData.presentation?.anoncreds?.requested_proof.revealed_attrs ??
formatData.presentation?.indy?.requested_proof.revealed_attrs

const revealedAttributeGroups =
formatData.presentation?.anoncreds?.requested_proof?.revealed_attr_groups ??
formatData.presentation?.indy?.requested_proof.revealed_attr_groups

const claims: Claim[] = []
if (revealedAttributes) {
for (const [name, value] of Object.entries(revealedAttributes)) {
claims.push(new Claim({ name, value: value.raw }))
}
}

if (revealedAttributeGroups) {
for (const [, groupAttributes] of Object.entries(revealedAttributeGroups)) {
for (const attrName in groupAttributes.values) {
claims.push(new Claim({ name: attrName, value: groupAttributes.values[attrName].raw }))
}
}
}
return {
claims,
verified: record.isVerified ?? false,
state: record.state,
proofExchangeId: record.id,
threadId: record.threadId,
updatedAt: record.updatedAt,
}
} catch (error) {
throw new InternalServerErrorException(error)
}
}
}
4 changes: 2 additions & 2 deletions src/controllers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export type RequestedCredential = {
}

export interface CreatePresentationRequestResult {
presentationRequestId: string
proofExchangeId: string
url: string
shortUrl: string
}
Expand All @@ -70,7 +70,7 @@ export interface CreateCredentialOfferOptions {
}

export interface CreateCredentialOfferResult {
credentialOfferId: string
credentialExchangeId: string
url: string
shortUrl: string
}
Expand Down

0 comments on commit 9a382a1

Please sign in to comment.