conxius-enclave-sdk 2.0.11

Hardware-backed security primitives for the broader Conxian ecosystem. Provides high-integrity root of trust for security-sensitive wallet, signing, attestation, and policy flows.
Documentation
use crate::{
    enclave::{EnclaveManager, SignRequest, SigningAlgorithm},
    ConclaveError, ConclaveResult,
};
use sha2::{Digest, Sha256};

#[derive(Debug, Clone)]
pub struct StacksTransactionIntent {
    pub payload: Vec<u8>,
    pub message_hash: Vec<u8>,
}

pub struct StacksManager<'a> {
    enclave: &'a dyn EnclaveManager,
}

impl<'a> StacksManager<'a> {
    pub fn new(enclave: &'a dyn EnclaveManager) -> Self {
        Self { enclave }
    }

    pub fn prepare_transaction(&self, payload: &[u8]) -> Result<StacksTransactionIntent, String> {
        if payload.is_empty() {
            return Err("Payload cannot be empty".to_string());
        }

        let mut hasher = Sha256::new();
        hasher.update(payload);
        let hash1 = hasher.finalize();

        let mut hasher2 = Sha256::new();
        hasher2.update(hash1);
        let message_hash = hasher2.finalize().to_vec();

        Ok(StacksTransactionIntent {
            payload: payload.to_vec(),
            message_hash,
        })
    }

    pub fn sign_prepared_transaction(
        &self,
        intent: StacksTransactionIntent,
        key_id: &str,
    ) -> ConclaveResult<String> {
        let request = SignRequest {
            algorithm: SigningAlgorithm::EcdsaSecp256k1,
            message_hash: intent.message_hash,
            derivation_path: "m/44'/5757'/0'/0/0".to_string(),
            key_id: key_id.to_string(),
            taproot_tweak: None,
        };

        let response = self.enclave.sign(request)?;
        Ok(response.signature_hex)
    }

    pub fn sign_message(&self, message: &str, key_id: &str) -> ConclaveResult<String> {
        if message.is_empty() {
            return Err(ConclaveError::InvalidPayload);
        }

        let prefix = "\x17Stacks Signed Message:\n";
        let mut hasher = Sha256::new();
        hasher.update(prefix.as_bytes());
        hasher.update(format!("{}", message.len()).as_bytes());
        hasher.update(message.as_bytes());
        let message_hash = hasher.finalize().to_vec();

        let request = SignRequest {
            algorithm: SigningAlgorithm::EcdsaSecp256k1,
            message_hash,
            derivation_path: "m/44'/5757'/0'/0/0".to_string(),
            key_id: key_id.to_string(),
            taproot_tweak: None,
        };

        let response = self.enclave.sign(request)?;
        Ok(response.signature_hex)
    }
}