rave_engine 0.8.0

A secure and efficient JSON Schema validation and Rhai script execution engine
Documentation
use super::utils::*;
use crate::rhai_engine::RhaiEngine;
use hdi::prelude::{debug, verify_signature};
use rhai::{Array, Dynamic, EvalAltResult, Map, Position};

/// Helper functions for HDI (Holochain Development Interface).
/// This module provides utility functions for signature verification and other HDI-related operations.
///
/// Verifies the signature of a Holochain Record.
///
/// # Arguments
///
/// * `record` - A Map containing the record data to be verified
///
/// # Returns
///
/// * `Result<bool, Box<EvalAltResult>>` - Returns true if signature is valid,
///   or an error if verification fails
///
/// # Details
///
/// This function performs the following operations:
/// 1. Converts the input Map to a Record type
/// 2. Extracts the signature, signed data, and signer from the record
/// 3. Verifies the signature using HDI's verify_signature function
///
/// # Errors
///
/// Returns an error if:
/// * The record cannot be converted to a Record type
/// * The signature verification fails
pub fn hdi_verify_record_signature(record: Map) -> Result<bool, Box<EvalAltResult>> {
    // Convert the input Map to a Record type
    let record = try_into_record(record)?;

    // Extract signature components from the record
    let signature = record.signature().to_owned();
    let data = record.signed_action().hashed.content.to_owned();
    let signer = record.action().author().to_owned();

    // Verify the signature using HDI's verify_signature function
    verify_signature(signer, signature, data).map_err(|e| {
        Box::new(EvalAltResult::ErrorRuntime(
            format!("Signature verification failed: {e}").into(),
            Position::NONE,
        ))
    })
}

/// Verifies a signature against provided data and signer.
///
/// # Arguments
///
/// * `signature` - An Array containing the signature to verify
/// * `data` - A Map containing the data that was signed
/// * `signer` - An Array containing the public key of the signer
///
/// # Returns
///
/// * `Result<bool, Box<EvalAltResult>>` - Returns true if signature is valid,
///   or an error if verification fails
///
/// # Details
///
/// This function performs the following operations:
/// 1. Converts the input Arrays to appropriate types (Signature and AgentPubKey)
/// 2. Converts the data Map to a format that can be serialized
/// 3. Uses msgpack to serialize the data the same way it was signed
/// 4. Verifies the signature using HDI's verify_signature function
///
/// # Errors
///
/// Returns an error if:
/// * The signature cannot be converted to the correct type
/// * The signer cannot be converted to an AgentPubKey
/// * The signature verification fails
pub fn hdi_verify_signature(
    signer: String,
    signature: Array,
    data: Dynamic,
) -> Result<bool, Box<EvalAltResult>> {
    // Convert input types to their appropriate formats
    let signer = try_from_string_to_agent_pubkey(signer)?;
    let signature = try_into_signature(signature)?;
    let payload = RhaiEngine::rhai_dynamic_to_json(data);

    // debug!("signer: {:?}", signer);
    // debug!("signature: {:?}", signature);
    // debug!("serialized bytes: {:?}", payload);

    // Verify the signature using HDI's verify_signature function
    let result = verify_signature(signer, signature, payload).map_err(|e| {
        Box::new(EvalAltResult::ErrorRuntime(
            format!("Signature verification failed: {e}").into(),
            Position::NONE,
        ))
    })?;

    debug!("Result of hdi_verify_signature: {:?}", result);
    Ok(result)
}