import { Injectable, InternalServerErrorException, NotFoundException, } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import { RekammedisService } from '../rekammedis/rekammedis.service'; import { groth16, wtns } from 'snarkjs'; import path from 'path'; 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, private logService: LogService, ) {} 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 }; } async getProof(requestProofDto: RequestProofDto) { const age = await this.rekamMedisService.getAgeByIdVisit( requestProofDto.id_visit, ); if (!age) { throw new NotFoundException('ID Visit tidak ditemukan'); } // 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.", // ); // } // const { proof, publicSignals } = await this.generateProof(); const { proof, publicSignals } = await groth16.fullProve( { age: age, threshold: 18, }, this.wasmPath, this.zkeyPath, ); return { proof: proof, publicSignals: publicSignals, }; } 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; } }