use crate::{
basicpre::BasicPrefix,
dummy_event::DelegatedInceptionEvent,
errors::KrError,
event::{Event, KrInceptionEvent, KrRotationEvent},
event_data::EventData,
event_message::EventMessage,
identifier_prefix::IdentifierPrefix,
key_config::{nxt_commitment, KeyConfig},
key_event_message::KeyEvent,
said::{SelfAddressing, SelfAddressingPrefix},
seal::Seal,
serialization_info::SerializationFormats,
threshold::SignatureThreshold,
witness_config::{InceptionWitnessConfig, WitnessConfig},
EventTypeTag,
};
#[derive(Debug)]
pub struct EventMsgBuilder {
event_type: EventTypeTag,
prefix: IdentifierPrefix,
sn: u64,
key_threshold: SignatureThreshold,
next_key_threshold: SignatureThreshold,
keys: Vec<BasicPrefix>,
next_keys: Vec<BasicPrefix>,
prev_event: SelfAddressingPrefix,
data: Vec<Seal>,
delegator: IdentifierPrefix,
witness_threshold: u64,
witnesses: Vec<BasicPrefix>,
witness_to_add: Vec<BasicPrefix>,
witness_to_remove: Vec<BasicPrefix>,
format: SerializationFormats,
derivation: SelfAddressing,
}
impl EventMsgBuilder {
pub fn new(event_type: EventTypeTag) -> Self {
EventMsgBuilder {
event_type,
prefix: IdentifierPrefix::default(),
keys: vec![],
next_keys: vec![],
key_threshold: SignatureThreshold::default(),
next_key_threshold: SignatureThreshold::default(),
sn: 1,
prev_event: SelfAddressing::Blake3_256.derive(&[0u8; 32]),
data: vec![],
delegator: IdentifierPrefix::default(),
witness_threshold: 0,
witnesses: vec![],
witness_to_add: vec![],
witness_to_remove: vec![],
format: SerializationFormats::JSON,
derivation: SelfAddressing::Blake3_256,
}
}
pub fn with_prefix(self, prefix: &IdentifierPrefix) -> Self {
EventMsgBuilder {
prefix: prefix.clone(),
..self
}
}
pub fn with_keys(self, keys: Vec<BasicPrefix>) -> Self {
EventMsgBuilder { keys, ..self }
}
pub fn with_next_keys(self, next_keys: Vec<BasicPrefix>) -> Self {
EventMsgBuilder { next_keys, ..self }
}
pub fn with_sn(self, sn: u64) -> Self {
EventMsgBuilder { sn, ..self }
}
pub fn with_previous_event(self, prev_event: &SelfAddressingPrefix) -> Self {
EventMsgBuilder {
prev_event: prev_event.clone(),
..self
}
}
pub fn with_seal(mut self, seals: Vec<Seal>) -> Self {
self.data.extend(seals);
EventMsgBuilder { ..self }
}
pub fn with_delegator(self, delegator: &IdentifierPrefix) -> Self {
EventMsgBuilder {
delegator: delegator.clone(),
..self
}
}
pub fn with_threshold(self, threshold: &SignatureThreshold) -> Self {
EventMsgBuilder {
key_threshold: threshold.clone(),
..self
}
}
pub fn with_next_threshold(self, threshold: &SignatureThreshold) -> Self {
EventMsgBuilder {
next_key_threshold: threshold.clone(),
..self
}
}
pub fn with_witness_list(self, witnesses: &[BasicPrefix]) -> Self {
EventMsgBuilder {
witnesses: witnesses.to_vec(),
..self
}
}
pub fn with_witness_to_add(self, witness_to_add: &[BasicPrefix]) -> Self {
EventMsgBuilder {
witness_to_add: witness_to_add.to_vec(),
..self
}
}
pub fn with_witness_to_remove(self, witness_to_remove: &[BasicPrefix]) -> Self {
EventMsgBuilder {
witness_to_remove: witness_to_remove.to_vec(),
..self
}
}
pub fn build(self) -> Result<EventMessage<KeyEvent>, KrError> {
let next_key_hash =
nxt_commitment(&self.next_key_threshold, &self.next_keys, &self.derivation);
let key_config = KeyConfig::new(self.keys, Some(next_key_hash), Some(self.key_threshold));
let prefix = if self.prefix == IdentifierPrefix::default() {
if key_config.public_keys.len() == 1 {
IdentifierPrefix::Basic(key_config.public_keys[0].clone())
} else {
let icp_data = KrInceptionEvent::new(key_config.clone(), None, None)
.incept_self_addressing(self.derivation.clone(), self.format)?;
icp_data.event.get_prefix()
}
} else {
self.prefix
};
Ok(match self.event_type {
EventTypeTag::Icp => {
let icp_event = KrInceptionEvent {
key_config,
witness_config: InceptionWitnessConfig {
tally: self.witness_threshold,
initial_witnesses: self.witnesses,
},
inception_configuration: vec![],
data: vec![],
};
match prefix {
IdentifierPrefix::Basic(_) => Event::new(prefix, 0, EventData::Icp(icp_event))
.to_message(self.format, &self.derivation)?,
IdentifierPrefix::SelfAddressing(_) => {
icp_event.incept_self_addressing(self.derivation, self.format)?
}
_ => todo!(),
}
}
EventTypeTag::Rot => Event::new(
prefix,
self.sn,
EventData::Rot(KrRotationEvent {
previous_event_hash: self.prev_event,
key_config,
witness_config: WitnessConfig {
tally: self.witness_threshold,
prune: self.witness_to_remove,
graft: self.witness_to_add,
},
data: self.data,
}),
)
.to_message(self.format, &self.derivation)?,
// EventTypeTag::Ixn => Event::new(
// prefix,
// self.sn,
// EventData::Ixn(InteractionEvent {
// previous_event_hash: self.prev_event,
// data: self.data,
// }),
// )
// .to_message(self.format, &self.derivation)?,
EventTypeTag::Dip => {
let icp_data = KrInceptionEvent {
key_config,
witness_config: InceptionWitnessConfig::default(),
inception_configuration: vec![],
data: vec![],
};
DelegatedInceptionEvent {
inception_data: icp_data,
delegator: self.delegator,
}
.incept_self_addressing(self.derivation, self.format)?
}
EventTypeTag::Drt => {
let rotation_data = KrRotationEvent {
previous_event_hash: self.prev_event,
key_config,
witness_config: WitnessConfig::default(),
data: self.data,
};
Event::new(prefix, self.sn, EventData::Drt(rotation_data))
.to_message(self.format, &self.derivation)?
}
_ => return Err(KrError::SemanticError("Not key event".into())),
})
}
}
// #[cfg(test)]
// mod tests_builder {
// use crate::basicpre::BasicPrefix;
// use crate::event::Event;
// use crate::event_message::EventMessage;
// use crate::event_msg_builder::EventMsgBuilder;
// use crate::key_manage::{Privatekey, Publickey};
// use crate::said_event::SaidEvent;
// use crate::threshold::SignatureThreshold;
// use crate::{basic::Basic, key_manage::KeySet};
// use crate::{delegated_incept, delegated_rotate, incept, rotate, EventTypeTag, HBKResult};
// use hbpasta_rs::Keypair as PastaKP;
// #[derive(Clone, Debug)]
// pub struct PastaKeySet {
// current: Vec<PastaKP>,
// next: Vec<PastaKP>,
// }
// impl PastaKeySet {
// /// Create a default set for one (1) current and next KeyPairs for KeySet
// // pub fn new() -> Self {
// // let mut curr_vec = Vec::<PastaKP>::new();
// // curr_vec.push(PastaKP::new());
// // let mut next_vec = Vec::<PastaKP>::new();
// // next_vec.push(PastaKP::new());
// // Self {
// // current: curr_vec,
// // next: next_vec,
// // }
// // }
// /// Create a KeySet for count (1-255) current next KeyPairs
// pub fn new_for(count: u8) -> Self {
// let mut current = Vec::<PastaKP>::new();
// let mut next = Vec::<PastaKP>::new();
// for _ in 0..count {
// current.push(PastaKP::new());
// next.push(PastaKP::new());
// }
// Self { current, next }
// }
// // pub fn with_current_keypair(in_vec: Vec<PastaKP>) -> Self {
// // Self {
// // current: in_vec.clone(),
// // next: in_vec
// // .iter()
// // .map(|_| PastaKP::new())
// // .collect::<Vec<PastaKP>>(),
// // }
// // }
// // pub fn with_current_and_next_keypairs(
// // in_current: Vec<PastaKP>,
// // in_next: Vec<PastaKP>,
// // ) -> Self {
// // Self {
// // current: in_current,
// // next: in_next,
// // }
// // }
// // pub fn from_file(fpath: &Path) -> Self {
// // todo!()
// // }
// // pub fn to_file(&self, fpath: &Path) {
// // todo!()
// // }
// }
// impl KeySet for PastaKeySet {
// fn rotate(&mut self) {
// self.current = self.next.clone();
// self.next = self
// .current
// .iter()
// .map(|_| PastaKP::new())
// .collect::<Vec<PastaKP>>()
// }
// fn current_private_keys(&self) -> Vec<Privatekey> {
// self.current
// .iter()
// .map(|x| Privatekey::new(x.private_key().to_bytes().to_vec()))
// .collect::<Vec<Privatekey>>()
// }
// fn next_private_keys(&self) -> Vec<Privatekey> {
// self.next
// .iter()
// .map(|x| Privatekey::new(x.private_key().to_bytes().to_vec()))
// .collect::<Vec<Privatekey>>()
// }
// fn current_public_keys(&self) -> Vec<Publickey> {
// self.current
// .iter()
// .map(|x| Publickey::new(x.private_key().pubkey().to_bytes().to_vec()))
// .collect::<Vec<Publickey>>()
// }
// fn next_public_keys(&self) -> Vec<Publickey> {
// self.next
// .iter()
// .map(|x| Publickey::new(x.private_key().pubkey().to_bytes().to_vec()))
// .collect::<Vec<Publickey>>()
// }
// }
// fn to_json(title: &str, event: &EventMessage<SaidEvent<Event>>) {
// print!("{title}\n{}\n", serde_json::to_string(event).unwrap());
// }
// #[test]
// fn test_basic_pass() -> HBKResult<()> {
// // Keys 1
// let count = 2u8;
// let mut kset1 = PastaKeySet::new_for(count);
// // Inception
// let icp_event = incept(&kset1, Basic::PASTA, 1u64)?;
// // println!("{:?}\n", icp_event);
// to_json("Icp-0 JSON", &icp_event);
// println!("\n");
// // Rotate the keys
// let rot1_event = rotate(&icp_event, &mut kset1, Basic::PASTA, 1u64)?;
// to_json("Rot-1 JSON", &rot1_event);
// println!("\n");
// Ok(())
// }
// #[test]
// fn test_delegation_pass() -> HBKResult<()> {
// // Keys 1
// let count = 2u8;
// let mut kset1 = PastaKeySet::new_for(count);
// let kset2 = PastaKeySet::new_for(count);
// let delegate = incept(&kset2, Basic::PASTA, 1u64)?;
// let delegator = &delegate.event.get_prefix();
// // Delegated Inception
// let icp_event = delegated_incept(&kset1, Basic::PASTA, 1u64, delegator)?;
// println!("{:?}", icp_event);
// println!("\n");
// to_json("Dip-0 JSON", &icp_event);
// println!("\n");
// // Delegated Rotation
// let rot1_event = delegated_rotate(&icp_event, &mut kset1, Basic::PASTA, 1u64).unwrap();
// to_json("Drt-1 JSON", &rot1_event);
// println!("\n");
// Ok(())
// }
// #[test]
// fn test_multisig_prefix_derivation() {
// // Keys taken from keripy: keripy/tests/core/test_eventing.py::test_multisig_digprefix (line 2255)
// let expected_event = br#"{"v":"KERI10JSON0001e7_","t":"icp","d":"EZrJQSdhdiyXNpEzHo-dR0EEbLfcIopBSImdLnQGOKkg","i":"EZrJQSdhdiyXNpEzHo-dR0EEbLfcIopBSImdLnQGOKkg","s":"0","kt":"2","k":["DSuhyBcPZEZLK-fcw5tzHn2N46wRCG_ZOoeKtWTOunRA","DVcuJOOJF1IE8svqEtrSuyQjGTd2HhfAkt9y2QkUtFJI","DT1iAhBWCkvChxNWsby2J0pJyxBIxbAtbLA0Ljx-Grh8"],"nt":"2","n":["E_IkdcjsIFrFba-LS1sJDjpec_4vM3XtIPa6D51GcUIw","EU28GjHFKeXzncPxgwlHQZ0iO7f09Y89vy-3VkZ23bBI","E2PRzip7UZ5UTA_1ucb5eoAzxeRS3sIThrSbZhdRaZY8"],"bt":"0","b":[],"c":[],"a":[]}"#;
// let keys: Vec<BasicPrefix> = vec![
// "DSuhyBcPZEZLK-fcw5tzHn2N46wRCG_ZOoeKtWTOunRA"
// .parse()
// .unwrap(),
// "DVcuJOOJF1IE8svqEtrSuyQjGTd2HhfAkt9y2QkUtFJI"
// .parse()
// .unwrap(),
// "DT1iAhBWCkvChxNWsby2J0pJyxBIxbAtbLA0Ljx-Grh8"
// .parse()
// .unwrap(),
// ];
// let next_keys: Vec<BasicPrefix> = vec![
// "DKPE5eeJRzkRTMOoRGVd2m18o8fLqM2j9kaxLhV3x8AQ"
// .parse()
// .unwrap(),
// "D1kcBE7h0ImWW6_Sp7MQxGYSshZZz6XM7OiUE5DXm0dU"
// .parse()
// .unwrap(),
// "D4JDgo3WNSUpt-NG14Ni31_GCmrU0r38yo7kgDuyGkQM"
// .parse()
// .unwrap(),
// ];
// let msg_builder = EventMsgBuilder::new(EventTypeTag::Icp)
// .with_keys(keys)
// .with_next_keys(next_keys)
// .with_threshold(&SignatureThreshold::Simple(2))
// .with_next_threshold(&SignatureThreshold::Simple(2));
// let msg = msg_builder.build().unwrap();
// println!("{:?}", msg.serialize().unwrap());
// println!("{:?}", expected_event.to_vec());
// // assert_eq!(expected_event.to_vec(), msg.serialize().unwrap());
// }
// }