hospital-log/backend/api/src/modules/proof/proof.service.ts

106 lines
2.9 KiB
TypeScript
Raw Normal View History

2025-11-13 07:06:16 +00:00
import {
Injectable,
InternalServerErrorException,
NotFoundException,
} from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { RekammedisService } from '../rekammedis/rekammedis.service';
2025-11-13 07:06:16 +00:00
import { groth16, wtns } from 'snarkjs';
import path from 'path';
2025-11-13 09:18:29 +00:00
import { RequestProofDto } from './dto/request-proof.dto';
import { LogProofDto } from './dto/log-proof.dto';
import { sha256 } from '@api/common/crypto/hash';
import { LogService } from '../log/log.service';
@Injectable()
export class ProofService {
constructor(
private prismaService: PrismaService,
private rekamMedisService: RekammedisService,
2025-11-13 09:18:29 +00:00
private logService: LogService,
) {}
2025-11-13 07:06:16 +00:00
buildDir = path.join(__dirname, '../../../', 'dist');
publicDir = path.join(__dirname, '../../../../', '/api/public');
wasmPath = path.join(this.publicDir, 'circuit.wasm');
zkeyPath = path.join(this.publicDir, 'circuit_final.zkey');
vkeyPath = path.join(this.publicDir, 'verification_key.json');
witnessPath = path.join(this.buildDir, 'witness.wtns');
async calculateWitness(age: number) {
const inputs = {
age: age,
threshold: 18,
};
await wtns.calculate(inputs, this.wasmPath, this.witnessPath);
}
async generateProof() {
const { proof, publicSignals } = await groth16.prove(
this.zkeyPath,
this.witnessPath,
);
return { proof, publicSignals };
}
2025-11-13 09:18:29 +00:00
async getProof(requestProofDto: RequestProofDto) {
const age = await this.rekamMedisService.getAgeByIdVisit(
requestProofDto.id_visit,
);
2025-11-13 07:06:16 +00:00
if (!age) {
throw new NotFoundException('ID Visit tidak ditemukan');
}
2025-11-13 09:18:29 +00:00
// try {
// await this.calculateWitness(age);
// } catch (error) {
// console.log('Error during witness calculation:', error);
// throw new InternalServerErrorException(
// "Can't generate proof from input based on constraint. Please check the input data and try again.",
// );
// }
2025-11-13 07:06:16 +00:00
2025-11-13 09:18:29 +00:00
// const { proof, publicSignals } = await this.generateProof();
const { proof, publicSignals } = await groth16.fullProve(
{
age: age,
threshold: 18,
},
this.wasmPath,
this.zkeyPath,
);
2025-11-13 07:06:16 +00:00
return {
proof: proof,
publicSignals: publicSignals,
};
}
2025-11-13 09:18:29 +00:00
async logVerificationProof(logProofDto: LogProofDto) {
const payload = {
id_visit: logProofDto.id_visit || null,
proofHash: logProofDto.proofHash || null,
proofResult: logProofDto.proofResult || null,
};
const payloadHash = sha256(JSON.stringify(payload));
const response = {
id: `PROOF_${payload.id_visit}`,
event: 'proof_verification_logged',
user_id: 'External',
payload: payloadHash,
};
// const response = await this.logService.storeLog({
// id: `PROOF_${payload.id_visit}`,
// event: 'proof_verification_logged',
// user_id: 'External',
// payload: payloadHash,
// });
return response;
}
}