hbkr-rs 0.3.2

Hashblock Key Rotation
Documentation
//! hbkr-rs library crate

use std::str::FromStr;

use base64::encode_config;
use basic::Basic;
use basicpre::BasicPrefix;
// use chrono::{DateTime, Local};

use errors::KrError;
use event::Event;
use event_data::EventData;
use event_message::EventMessage;
use event_msg_builder::EventMsgBuilder;
use identifier_prefix::IdentifierPrefix;
use identifier_state::IdentifierState;

use key_manage::{key_vec_to_prefix_vec, KeySet};
// use key_event_message::KeyEvent;

use said::SelfAddressingPrefix;
use said_event::SaidEvent;
use serde::{Deserialize, Serialize};
use threshold::SignatureThreshold;

pub type HBKResult<T> = std::result::Result<T, KrError>;
pub mod attached_signature;
pub mod basic;
pub mod basicpre;
pub mod derivation;
pub mod dummy_event;
pub mod error_ser;
pub mod errors;
pub mod event;
pub mod event_data;
pub mod event_message;
pub mod event_msg_builder;
pub mod identifier_prefix;
pub mod identifier_state;
pub mod key_config;
pub mod key_event_message;
pub mod key_manage;
pub mod said;
pub mod said_event;
pub mod seal;
pub mod self_signing_pre;
pub mod self_signinig;
pub mod serialization_info;
pub mod serializer;
pub mod signed_event_message;
pub mod threshold;
pub mod witness_config;

/// incept generates an inception event for a KeySet
#[deprecated(since = "0.3.0", note = "please use `inception` function instead")]
pub fn incept(
    key_set: &dyn KeySet,
    keytype: Basic,
    threshold: u64,
) -> HBKResult<EventMessage<SaidEvent<Event>>> {
    let builder = EventMsgBuilder::new(EventTypeTag::Icp)
        .with_keys(key_vec_to_prefix_vec(
            &key_set.current_public_keys(),
            keytype,
        ))
        .with_threshold(&SignatureThreshold::simple(threshold))
        .with_next_threshold(&SignatureThreshold::simple(threshold))
        .with_next_keys(key_vec_to_prefix_vec(&key_set.next_public_keys(), keytype));

    Ok(builder.build()?)
}

/// inception generates an inception event for KeySet
pub fn inception(
    key_set: &dyn KeySet,
    threshold: u64,
) -> HBKResult<EventMessage<SaidEvent<Event>>> {
    let builder = EventMsgBuilder::new(EventTypeTag::Icp)
        .with_keys(key_vec_to_prefix_vec(
            &key_set.current_public_keys(),
            key_set.key_type(),
        ))
        .with_threshold(&SignatureThreshold::simple(threshold))
        .with_next_threshold(&SignatureThreshold::simple(threshold))
        .with_next_keys(key_vec_to_prefix_vec(
            &key_set.next_public_keys(),
            key_set.key_type(),
        ));

    Ok(builder.build()?)
}

/// delegated_incept generates a delegation KeySet inception event
#[deprecated(
    since = "0.3.0",
    note = "please use `delegated_inception` function instead"
)]
pub fn delegated_incept(
    key_set: &dyn KeySet,
    keytype: Basic,
    threshold: u64,
    delegator: &IdentifierPrefix,
) -> HBKResult<EventMessage<SaidEvent<Event>>> {
    let builder = EventMsgBuilder::new(EventTypeTag::Dip)
        .with_keys(key_vec_to_prefix_vec(
            &key_set.current_public_keys(),
            keytype,
        ))
        .with_delegator(delegator)
        .with_threshold(&SignatureThreshold::simple(threshold))
        .with_next_threshold(&SignatureThreshold::simple(threshold))
        .with_next_keys(key_vec_to_prefix_vec(&key_set.next_public_keys(), keytype));

    Ok(builder.build()?)
}

/// delegated_inception generates a delegation KeySet inception event
pub fn delegated_inception(
    key_set: &dyn KeySet,
    threshold: u64,
    delegator: &IdentifierPrefix,
) -> HBKResult<EventMessage<SaidEvent<Event>>> {
    let builder = EventMsgBuilder::new(EventTypeTag::Dip)
        .with_keys(key_vec_to_prefix_vec(
            &key_set.current_public_keys(),
            key_set.key_type(),
        ))
        .with_delegator(delegator)
        .with_threshold(&SignatureThreshold::simple(threshold))
        .with_next_threshold(&SignatureThreshold::simple(threshold))
        .with_next_keys(key_vec_to_prefix_vec(
            &key_set.next_public_keys(),
            key_set.key_type(),
        ));

    Ok(builder.build()?)
}

/// Create a rotation event from a given inception or other event
pub fn rotation(
    for_prefix: &String,
    previous_digest: &String,
    sequence_num: u64,
    key_set: &dyn KeySet,
    threshold: u64,
) -> HBKResult<EventMessage<SaidEvent<Event>>> {
    // Build the event
    let builder = EventMsgBuilder::new(EventTypeTag::Rot)
        .with_prefix(&IdentifierPrefix::SelfAddressing(
            SelfAddressingPrefix::from_str(&for_prefix)?,
        ))
        .with_sn(sequence_num + 1)
        .with_previous_event(&SelfAddressingPrefix::from_str(&previous_digest)?)
        // .with_previous_event(&prev_event.get_digest())
        .with_next_threshold(&SignatureThreshold::simple(threshold))
        .with_keys(key_vec_to_prefix_vec(
            &key_set.current_public_keys(),
            key_set.key_type(),
        ))
        .with_next_keys(key_vec_to_prefix_vec(
            &key_set.next_public_keys(),
            key_set.key_type(),
        ));

    Ok(builder.build()?)
}

pub fn delegated_rotation(
    for_prefix: &String,
    previous_digest: &String,
    sequence_num: u64,
    key_set: &dyn KeySet,
    threshold: u64,
) -> HBKResult<EventMessage<SaidEvent<Event>>> {
    // Get previous event prefix

    // Build the rotation
    let builder = EventMsgBuilder::new(EventTypeTag::Drt)
        .with_prefix(&IdentifierPrefix::SelfAddressing(
            SelfAddressingPrefix::from_str(&for_prefix)?,
        ))
        .with_sn(sequence_num + 1)
        .with_previous_event(&SelfAddressingPrefix::from_str(&previous_digest)?)
        .with_next_threshold(&SignatureThreshold::simple(threshold))
        .with_keys(key_vec_to_prefix_vec(
            &key_set.current_public_keys(),
            key_set.key_type(),
        ))
        .with_next_keys(key_vec_to_prefix_vec(
            &key_set.next_public_keys(),
            key_set.key_type(),
        ));

    Ok(builder.build()?)
}

/// Terminate further events happening for a keyset
pub fn termnate() {}

pub trait Prefix: FromStr<Err = KrError> {
    fn derivative(&self) -> Vec<u8>;
    fn derivation_code(&self) -> String;
    fn to_str(&self) -> String {
        // empty data cannot be prefixed!
        match self.derivative().len() {
            0 => "".to_string(),
            _ => {
                let dc = self.derivation_code();
                let ec = encode_config(self.derivative(), base64::URL_SAFE_NO_PAD);
                [dc, ec].join("")
            }
        }
    }
}

pub trait Typeable {
    fn get_type(&self) -> EventTypeTag;
}
pub trait Digestible {
    fn get_digest(&self) -> SelfAddressingPrefix;
}
///
/// Describes an interface for applying the semantic rule of an event to the state of an Identifier
pub trait EventSemantics {
    fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, KrError> {
        // default impl is the identity transition
        Ok(state)
    }
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum EventTypeTag {
    Icp,
    Rot,
    Ixn,
    Dip,
    Drt,
    Rct,
    // #[cfg(feature = "query")]
    // Rpy,
    // #[cfg(feature = "query")]
    // Qry,
}

impl EventTypeTag {
    pub fn is_establishment_event(&self) -> bool {
        matches!(
            self,
            EventTypeTag::Icp | EventTypeTag::Rot | EventTypeTag::Dip | EventTypeTag::Drt
        )
    }
}

impl From<&EventData> for EventTypeTag {
    fn from(ed: &EventData) -> Self {
        match ed {
            EventData::Icp(_) => EventTypeTag::Icp,
            EventData::Rot(_) => EventTypeTag::Rot,
            // EventData::Ixn(_) => EventTypeTag::Ixn,
            EventData::Dip(_) => EventTypeTag::Dip,
            EventData::Drt(_) => EventTypeTag::Drt,
        }
    }
}