web5-rust 1.1.9

A rust crate for interacting with Web5
Documentation
use super::Error;

use super::structs::{
    DMCreateRequest,
    DMReadRequest,
    DwnRequest,
    DwnItem,
    Action,
    Type
};

use super::permission::PermissionSet;
use super::traits::Router;

use chrono::{DateTime, Utc};

use simple_crypto::SecretKey;

use crate::dids::signing::SignedObject;
use crate::dids::{DidResolver, DidKeyPair, Did};

use either::Either;

use std::collections::BTreeSet;

#[derive(Debug, Clone)]
pub struct DMClient {
    signer: DidKeyPair,
    com_key: SecretKey,
    router: Box<dyn Router>,
    did_resolver: Box<dyn DidResolver>,
}

impl DMClient {
    pub fn new(
        signer: DidKeyPair,
        com_key: SecretKey,
        router: Box<dyn Router>,
        did_resolver: Box<dyn DidResolver>,
    ) -> Self {
        DMClient{signer, com_key, router, did_resolver}
    }

    pub async fn create(
        &self,
        recipient: &Did,
        permission: PermissionSet,
    ) -> Result<(), Error> {
        let (_, rec_com_key) = self.did_resolver.resolve_dwn_keys(recipient).await?;
        let signed = SignedObject::from_keypair(&self.signer, permission)?;
        let payload = rec_com_key.encrypt(&serde_json::to_vec(&signed)?)?;
        let request: DMCreateRequest = DwnItem::new(rec_com_key, None, payload);
        let request = DwnRequest::new(Type::DM, Action::Create, serde_json::to_vec(&request)?);

        self.router.handle_request(&request, &[recipient]).await?;
        Ok(())
    }

    pub async fn read(
        &self,
        timestamp: DateTime<Utc>
    ) -> Result<Vec<(Did, PermissionSet)>, Error> {
        let request: DMReadRequest = SignedObject::from_key(&self.com_key, timestamp)?;
        let request = DwnRequest::new(Type::DM, Action::Read, serde_json::to_vec(&request)?);

        let items = BTreeSet::from_iter(self.router.handle_request(&request, &[&self.signer.public.did]).await?
            .into_iter().flat_map(|data|
                serde_json::from_slice::<Vec<DwnItem>>(&data).ok()
            ).flatten()
        ).into_iter().collect::<Vec<DwnItem>>();

        let mut results: Vec<(Did, PermissionSet)> = Vec::new();

        for item in items {
            if item.discover != self.com_key.public_key() || item.delete.is_some() {continue;}
            if let Ok(dc) = self.com_key.decrypt(&item.payload) {
                if let Ok(signed) = serde_json::from_slice::<SignedObject<PermissionSet>>(&dc) {
                    if let Ok(Either::Left(sender)) = signed.verify(&*self.did_resolver, None).await {
                        results.push((sender, signed.unwrap()));
                    }
                }
            }
        }
        Ok(results)
    }
}