Data Holder

The Data Holder should follow four steps to integrate with zkPass:

Sample Implementation

Sample codes for the Data Holder implementation follow. Each step is explained in detail in the subsections. The code is also available on the zkpass-sdk repo, as shown here:

https://github.com/gl-zkPass/zkpass-sdk/blob/main/rust/zkpass-demo/src/data_holder.rs
/*
 * data_holder.rs
 * Simulating the Data Holder process for the zkPass Demo
 *
 * ---
 * References:
 *   https://docs.ssi.id/zkpass/zkpass-developers-guide/privacy-apps/dvr/dvr-client-roles/data-holder
 * ---
 * Copyright (c) 2024 PT Darta Media Indonesia. All rights reserved.
 */
use crate::{
    data_issuer::DataIssuer,
    proof_verifier::ProofVerifier,
    lib_loader::generate_zkpass_proof,
};
use client_utils::interface::PrivacyAppCredentialsFfi;
use std::{ collections::HashMap, time::Instant, ffi::CString };
use tracing::info;
use zkpass_query_types::OutputReader;

pub struct DataHolder;

impl DataHolder {
    ///
    /// Starts the Data Holder process.
    ///
    pub async fn start(&self, zkvm: &str, data_files: HashMap<String, String>, dvr_file: &str) {
        //
        //  Get the user data from the data issuer
        //
        let data_issuer = DataIssuer;
        let user_data_tokens_map = data_issuer.get_user_data_tokens(data_files);
        let user_data_tags_list: Vec<&String> = user_data_tokens_map.keys().collect();
        let user_data_tokens = serde_json::to_string(&user_data_tokens_map).unwrap();

        //
        //  Get the dvr from the verifier
        //
        let mut proof_verifier = ProofVerifier::default();
        let dvr_token = proof_verifier.get_dvr_token(zkvm, dvr_file, user_data_tags_list);

        let zkpass_service_url = std::env
            ::var("ZKPASS_URL")
            .unwrap_or("https://staging-zkpass.ssi.id".to_string());
        info!("service_url={}", zkpass_service_url);
        println!("\n#### starting zkpass proof generation...");
        let start = Instant::now();

        //
        //  Data Holder's integration points with the zkpass-client SDK library
        //

        //
        // Step 1: Call the dvr client's generate_zk_pass_proof
        //         to get the zkpass_proof_token.
        //
        let credentials = self.generate_credential();
        let zkpass_proof_token = unsafe {
            generate_zkpass_proof(credentials, user_data_tokens, dvr_token)
        };

        let duration = start.elapsed();
        println!("#### generation completed [time={:?}]", duration);

        //
        //  Step 2: Send the zkpass_proof_token to the Proof Verifier
        //          to get the proof verified and retrieve the query result.
        //
        let query_result = proof_verifier.verify_zkpass_proof(zkvm, &zkpass_proof_token).await;

        println!("json-result={}", OutputReader::pretty_print(&query_result));
        let output_reader = OutputReader::from_json(&query_result).unwrap();
        println!(">> output list:");
        for entry in output_reader.enumerate() {
            println!("key={}, value={:?}", entry.key, entry.val);
        }
        println!("<< end of list");

        let val = output_reader.find_bool("result").unwrap();
        println!("the query result is {}", val);
    }

    ///
    /// Generates the privacy app credentials.
    ///
    fn generate_credential(&self) -> PrivacyAppCredentialsFfi {
        let base_url = std::env
            ::var("ZKPASS_URL")
            .unwrap_or("https://staging-zkpass.ssi.id".to_string());
        let api_key = std::env::var("API_KEY").expect("API_KEY must be set");
        let secret_api_key = std::env::var("SECRET_API_KEY").expect("SECRET_API_KEY must be set");

        PrivacyAppCredentialsFfi {
            base_url: CString::new(base_url).unwrap().into_raw(),
            api_key: CString::new(api_key).unwrap().into_raw(),
            secret_api_key: CString::new(secret_api_key).unwrap().into_raw(),
            using_queue: true,
        }
    }
}

Last updated