signer-remote 0.4.1

Signer remote communication package.
Documentation
use serde::{Deserialize, Serialize};
use signer_core::{SignerCrypted, SignerKeys, SignerUser};
use signer_crdt::{view::CrdtEventVO, errors::ViewError};

use crate::{
    error::{RemoteError, RemoteResult},
    remote::{HttpClient, HttpClientConfig},
};

/// CRDT 加密事件视图对象
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CrdtCryptedEventVO {
    pub clock: i32,
    pub peer: String,
    pub data: SignerCrypted<CrdtEventVO>,
}

/// POST CRDT 事件请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PostCrdtEventsRequest {
    /// 数据
    pub data: Vec<CrdtCryptedEventVO>,
}

/// 获取 CRDT 事件响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetCrdtEventsResponse {
    /// 数据
    pub data: Vec<CrdtCryptedEventVO>,
}

impl CrdtCryptedEventVO {
    /// 从 signer-crdt 的 CrdtEventVO 创建加密事件
    pub fn encrypt(
        keys: &SignerKeys,
        data: &CrdtEventVO,
    ) -> Result<Self, ViewError> {
        // 移除 crdt_event 中的 revert 字段内容
        let data = CrdtEventVO {
            revert: None,
            ..data.clone()
        };

        Ok(Self {
            clock: data.clock,
            peer: data.peer.clone(),
            data: SignerCrypted::create(keys, &keys.pub_key, data)?,
        })
    }

    /// 解密事件为 signer-crdt 的 CrdtEventVO
    pub fn decrypt(
        &self,
        keys: &SignerKeys,
    ) -> Result<CrdtEventVO, ViewError> {
        let data = self.data.decrypt(keys)?;
        Ok(CrdtEventVO {
            revert: None,
            ..data
        })
    }

    /// 推送 CRDT 事件到服务器
    pub async fn push(
        events: Vec<CrdtCryptedEventVO>,
        addr: &str,
        keys: &SignerKeys,
        user: &SignerUser,
    ) -> RemoteResult<()> {
        if events.is_empty() {
            return Ok(());
        }

        let req = PostCrdtEventsRequest { data: events };

        let config = HttpClientConfig::new(keys.clone(), user.clone(), addr.to_string());
        let client = HttpClient::new(config);

        let _: serde_json::Value = client
            .post("/api/crdt-events", &req)
            .await
            .map_err(|e| RemoteError::Internal(format!("推送 CRDT 事件失败: {}", e)))?;

        Ok(())
    }

    /// 从服务器拉取 CRDT 事件
    pub async fn pull(
        addr: &str,
        keys: &SignerKeys,
        user: &SignerUser,
        frontiers: &str, // JSON 字符串形式的前沿信息
    ) -> RemoteResult<Vec<CrdtCryptedEventVO>> {
        let config = HttpClientConfig::new(keys.clone(), user.clone(), addr.to_string());
        let client = HttpClient::new(config);

        #[derive(serde::Serialize)]
        struct QueryParams {
            frontiers: Option<String>,
        }

        let query = QueryParams {
            frontiers: Some(frontiers.to_string()),
        };

        let r: GetCrdtEventsResponse = client
            .get_with_query("/api/crdt-events", &query)
            .await
            .map_err(|e| RemoteError::Internal(format!("拉取 CRDT 事件失败: {}", e)))?;

        Ok(r.data)
    }
}