anttp 0.26.0

AntTP is an HTTP server for the Autonomi Network
#![allow(dead_code)]

use rmcp::{handler::server::{
    wrapper::Parameters,
}, schemars, tool, tool_router, ErrorData};
use rmcp::model::CallToolResult;
use rmcp::schemars::JsonSchema;
use serde::Deserialize;
use serde_json::json;
use std::collections::HashMap;
use crate::service::crypto_service::{Crypto as ServiceCrypto, CryptoContent as ServiceCryptoContent};
use crate::tool::McpTool;

#[derive(Debug, Deserialize, JsonSchema)]
struct CryptoVerifyRequest {
    #[schemars(description = "Public key as hex string")]
    public_key: String,
    #[schemars(description = "Map of data hex to signature hex")]
    crypto_map: HashMap<String, String>,
}

#[derive(Debug, Deserialize, JsonSchema)]
struct CryptoSignRequest {
    #[schemars(description = "List of data hex strings to sign")]
    data: Vec<String>,
}

#[derive(Debug, Deserialize, JsonSchema)]
struct CryptoEncryptRequest {
    #[schemars(description = "Public key as hex string")]
    public_key: String,
    #[schemars(description = "List of base64 data strings to encrypt")]
    data: Vec<String>,
}

#[derive(Debug, Deserialize, JsonSchema)]
struct CryptoDecryptRequest {
    #[schemars(description = "List of base64 encrypted data strings to decrypt")]
    data: Vec<String>,
}

#[tool_router(router = crypto_tool_router, vis = "pub")]
impl McpTool {

    #[tool(description = "Verify signatures of data using a public key")]
    async fn verify_signatures(
        &self,
        Parameters(CryptoVerifyRequest { public_key, crypto_map }): Parameters<CryptoVerifyRequest>,
    ) -> Result<CallToolResult, ErrorData> {
        let mut data_map = HashMap::new();
        for (data_hex, signature_hex) in crypto_map {
            data_map.insert(data_hex, ServiceCrypto {
                signature: Some(signature_hex),
                verified: None,
            });
        }

        let result = self.crypto_service.verify_map(public_key, data_map);
        Ok(CallToolResult::structured(json!(result)))
    }

    #[tool(description = "Sign data using the application's secret key")]
    async fn create_signatures(
        &self,
        Parameters(CryptoSignRequest { data }): Parameters<CryptoSignRequest>,
    ) -> Result<CallToolResult, ErrorData> {
        let mut data_map = HashMap::new();
        for data_hex in data {
            data_map.insert(data_hex, ServiceCrypto {
                signature: None,
                verified: None,
            });
        }

        let result = self.crypto_service.sign_map(data_map);
        Ok(CallToolResult::structured(json!(result)))
    }

    /*#[tool(description = "Encrypt data using a public key")]
    async fn encrypt(
        &self,
        Parameters(CryptoEncryptRequest { public_key, data }): Parameters<CryptoEncryptRequest>,
    ) -> Result<CallToolResult, ErrorData> {
        let mut data_map = HashMap::new();
        for data_base64 in data {
            data_map.insert(data_base64, ServiceCryptoContent {
                content: None,
            });
        }

        let result = self.crypto_service.encrypt_map(public_key, data_map);
        Ok(CallToolResult::structured(json!(result)))
    }*/

    /*#[tool(description = "Decrypt data using the application's secret key")]
    async fn decrypt(
        &self,
        Parameters(CryptoDecryptRequest { data }): Parameters<CryptoDecryptRequest>,
    ) -> Result<CallToolResult, ErrorData> {
        let mut data_map = HashMap::new();
        for data_base64 in data {
            data_map.insert(data_base64, ServiceCryptoContent {
                content: None,
            });
        }

        let result = self.crypto_service.decrypt_map(data_map);
        Ok(CallToolResult::structured(json!(result)))
    }*/
}

/*#[cfg(test)]
mod tests {
    use super::*;
    use clap::Parser;
    use crate::service::crypto_service::CryptoService;
    use actix_web::web::Data;
    use blsttc::SecretKey;
    use base64::Engine;

    #[tokio::test]
    async fn test_verify_signatures_tool() {
        let secret_key = SecretKey::random();
        let public_key = hex::encode(secret_key.public_key().to_bytes());
        let data = b"test data";
        let data_hex = hex::encode(data);
        let signature = hex::encode(secret_key.sign(data).to_bytes());

        let ant_tp_config = crate::config::anttp_config::AntTpConfig::parse_from(&["anttp"]);
        let crypto_service = Data::new(CryptoService::new(ant_tp_config));
        
        let result = crypto_service.verify_map(public_key, {
            let mut data_map = HashMap::new();
            data_map.insert(data_hex.clone(), ServiceCrypto {
                signature: Some(signature.clone()),
                verified: None,
            });
            data_map
        });

        assert!(result.get(&data_hex).unwrap().verified.unwrap());
    }

    #[tokio::test]
    async fn test_create_signatures_tool() {
        let secret_key = SecretKey::random();
        let app_private_key_hex = secret_key.to_hex();
        let data_hex = hex::encode(b"hello world");

        let ant_tp_config = crate::config::anttp_config::AntTpConfig::parse_from(&["anttp", "--app-private-key", &app_private_key_hex]);
        let crypto_service = Data::new(CryptoService::new(ant_tp_config));
        
        let result = crypto_service.sign_map({
            let mut data_map = HashMap::new();
            data_map.insert(data_hex.clone(), ServiceCrypto {
                signature: None,
                verified: None,
            });
            data_map
        });

        assert!(result.get(&data_hex).unwrap().verified.unwrap());
        assert!(result.get(&data_hex).unwrap().signature.is_some());
    }

    #[tokio::test]
    async fn test_encrypt_tool() {
        let secret_key = SecretKey::random();
        let public_key = hex::encode(secret_key.public_key().to_bytes());
        let data = b"hello world";
        let data_base64 = base64::engine::general_purpose::STANDARD.encode(data);

        let ant_tp_config = crate::config::anttp_config::AntTpConfig::parse_from(&["anttp"]);
        let crypto_service = Data::new(CryptoService::new(ant_tp_config));
        
        let result = crypto_service.encrypt_map(public_key, {
            let mut data_map = HashMap::new();
            data_map.insert(data_base64.clone(), ServiceCryptoContent {
                content: None,
            });
            data_map
        });

        assert!(result.contains_key(&data_base64));
        assert!(result.get(&data_base64).unwrap().content.is_some());
    }

    #[tokio::test]
    async fn test_decrypt_tool() {
        let secret_key = SecretKey::random();
        let app_private_key_hex = secret_key.to_hex();
        let data = b"hello world";
        let encrypted_data = secret_key.public_key().encrypt(data).to_bytes();
        let encrypted_data_base64 = base64::engine::general_purpose::STANDARD.encode(encrypted_data);

        let ant_tp_config = crate::config::anttp_config::AntTpConfig::parse_from(&["anttp", "--app-private-key", &app_private_key_hex]);
        let crypto_service = Data::new(CryptoService::new(ant_tp_config));
        
        let result = crypto_service.decrypt_map({
            let mut data_map = HashMap::new();
            data_map.insert(encrypted_data_base64.clone(), ServiceCryptoContent {
                content: None,
            });
            data_map
        });

        assert!(result.contains_key(&encrypted_data_base64));
        let decrypted_base64 = result.get(&encrypted_data_base64).unwrap().content.as_ref().unwrap();
        let decrypted_bytes = base64::engine::general_purpose::STANDARD.decode(decrypted_base64).unwrap();
        assert_eq!(decrypted_bytes, data);
    }
}
*/