quartz-enclave-core 0.5.1

A Rust framework for building Intel SGX enclaves managed by a CosmWasm contract.
Documentation
use anyhow::{anyhow, Error as AnyhowError};
use cosmrs::AccountId;
use tendermint_rpc::event::Event as TmEvent;

use crate::{chain_client::ChainClient, handler::Handler};

/// An event wrapper used to parse the contract address for internal handling.
#[derive(Clone, Debug)]
pub struct QuartzEvent<E> {
    pub contract: AccountId,
    inner: E,
}

impl<E> TryFrom<TmEvent> for QuartzEvent<E>
where
    E: TryFrom<TmEvent, Error = AnyhowError>,
{
    type Error = AnyhowError;

    fn try_from(event: TmEvent) -> Result<Self, Self::Error> {
        let Some(events) = &event.events else {
            return Err(anyhow!("no events in tx"));
        };

        let contract = events
            .get("execute._contract_address")
            .ok_or_else(|| anyhow!("missing execute._contract_address in events"))?
            .first()
            .ok_or_else(|| anyhow!("execute._contract_address is empty"))?
            .parse::<AccountId>()
            .map_err(|e| anyhow!("failed to parse contract address: {}", e))?;

        Ok(QuartzEvent {
            contract,
            inner: event.try_into()?,
        })
    }
}

#[async_trait::async_trait]
impl<C, E> Handler<C> for QuartzEvent<E>
where
    C: ChainClient<Contract = AccountId>,
    E: Handler<C, Error = AnyhowError>,
{
    type Error = AnyhowError;
    type Response = <E as Handler<C>>::Response;

    async fn handle(self, ctx: &C) -> Result<Self::Response, Self::Error> {
        self.inner.handle(ctx).await
    }
}