keri_core/event_message/
event_msg_builder.rs

1use crate::{
2    error::Error,
3    event::sections::key_config::nxt_commitment,
4    event::{
5        event_data::{
6            delegated::DelegatedInceptionEvent, interaction::InteractionEvent,
7            rotation::RotationEvent,
8        },
9        sections::{
10            key_config::NextKeysData, threshold::SignatureThreshold, RotationWitnessConfig,
11        },
12    },
13    event::{
14        event_data::{inception::InceptionEvent, EventData},
15        receipt::Receipt,
16        sections::seal::Seal,
17        sections::InceptionWitnessConfig,
18        sections::KeyConfig,
19        KeyEvent,
20    },
21    keys::PublicKey,
22    prefix::{BasicPrefix, IdentifierPrefix},
23};
24use ed25519_dalek::SigningKey;
25use rand::rngs::OsRng;
26use said::version::format::SerializationFormats;
27use said::{
28    derivation::{HashFunction, HashFunctionCode},
29    SelfAddressingIdentifier,
30};
31
32use super::{msg::KeriEvent, EventTypeTag};
33
34pub struct EventMsgBuilder {
35    event_type: EventTypeTag,
36    prefix: IdentifierPrefix,
37    sn: u64,
38    key_threshold: SignatureThreshold,
39    next_key_threshold: SignatureThreshold,
40    keys: Vec<BasicPrefix>,
41    next_keys: Vec<BasicPrefix>,
42    next_keys_hashes: Option<Vec<SelfAddressingIdentifier>>,
43    prev_event: SelfAddressingIdentifier,
44    data: Vec<Seal>,
45    delegator: IdentifierPrefix,
46    witness_threshold: SignatureThreshold,
47    witnesses: Vec<BasicPrefix>,
48    witness_to_add: Vec<BasicPrefix>,
49    witness_to_remove: Vec<BasicPrefix>,
50    format: SerializationFormats,
51    derivation: HashFunction,
52}
53
54impl EventMsgBuilder {
55    pub fn new(event_type: EventTypeTag) -> Self {
56        let mut rng = OsRng {};
57        let kp = SigningKey::generate(&mut rng);
58        let nkp = SigningKey::generate(&mut rng);
59        let pk = PublicKey::new(kp.verifying_key().to_bytes().to_vec());
60        let npk = PublicKey::new(nkp.verifying_key().to_bytes().to_vec());
61        let hash_function: HashFunction = HashFunctionCode::Blake3_256.into();
62        let basic_pref = BasicPrefix::Ed25519(pk);
63        EventMsgBuilder {
64            event_type,
65            prefix: IdentifierPrefix::default(),
66            keys: vec![basic_pref],
67            next_keys: vec![BasicPrefix::Ed25519(npk)],
68            key_threshold: SignatureThreshold::default(),
69            next_key_threshold: SignatureThreshold::default(),
70            sn: 1,
71            prev_event: hash_function.derive(&[0u8; 32]),
72            data: vec![],
73            delegator: IdentifierPrefix::default(),
74            witness_threshold: SignatureThreshold::Simple(0),
75            witnesses: vec![],
76            witness_to_add: vec![],
77            witness_to_remove: vec![],
78            format: SerializationFormats::JSON,
79            derivation: hash_function,
80            next_keys_hashes: None,
81        }
82    }
83
84    pub fn with_prefix(self, prefix: &IdentifierPrefix) -> Self {
85        EventMsgBuilder {
86            prefix: prefix.clone(),
87            ..self
88        }
89    }
90
91    pub fn with_keys(self, keys: Vec<BasicPrefix>) -> Self {
92        EventMsgBuilder { keys, ..self }
93    }
94
95    pub fn with_next_keys(self, next_keys: Vec<BasicPrefix>) -> Self {
96        EventMsgBuilder { next_keys, ..self }
97    }
98
99    pub fn with_next_keys_hashes(self, next_keys: Vec<SelfAddressingIdentifier>) -> Self {
100        EventMsgBuilder {
101            next_keys_hashes: Some(next_keys),
102            ..self
103        }
104    }
105
106    pub fn with_sn(self, sn: u64) -> Self {
107        EventMsgBuilder { sn, ..self }
108    }
109    pub fn with_previous_event(self, prev_event: &SelfAddressingIdentifier) -> Self {
110        EventMsgBuilder {
111            prev_event: prev_event.clone(),
112            ..self
113        }
114    }
115
116    pub fn with_seal(mut self, seals: Vec<Seal>) -> Self {
117        self.data.extend(seals);
118        EventMsgBuilder { ..self }
119    }
120
121    pub fn with_delegator(self, delegator: &IdentifierPrefix) -> Self {
122        EventMsgBuilder {
123            delegator: delegator.clone(),
124            ..self
125        }
126    }
127
128    pub fn with_threshold(self, threshold: &SignatureThreshold) -> Self {
129        EventMsgBuilder {
130            key_threshold: threshold.clone(),
131            ..self
132        }
133    }
134
135    pub fn with_next_threshold(self, threshold: &SignatureThreshold) -> Self {
136        EventMsgBuilder {
137            next_key_threshold: threshold.clone(),
138            ..self
139        }
140    }
141
142    pub fn with_witness_list(self, witnesses: &[BasicPrefix]) -> Self {
143        EventMsgBuilder {
144            witnesses: witnesses.to_vec(),
145            ..self
146        }
147    }
148
149    pub fn with_witness_to_add(self, witness_to_add: &[BasicPrefix]) -> Self {
150        EventMsgBuilder {
151            witness_to_add: witness_to_add.to_vec(),
152            ..self
153        }
154    }
155
156    pub fn with_witness_to_remove(self, witness_to_remove: &[BasicPrefix]) -> Self {
157        EventMsgBuilder {
158            witness_to_remove: witness_to_remove.to_vec(),
159            ..self
160        }
161    }
162
163    pub fn with_witness_threshold(self, witness_threshold: &SignatureThreshold) -> Self {
164        EventMsgBuilder {
165            witness_threshold: witness_threshold.clone(),
166            ..self
167        }
168    }
169
170    pub fn build(self) -> Result<KeriEvent<KeyEvent>, Error> {
171        let next_key_hash = if let Some(hashes) = self.next_keys_hashes {
172            NextKeysData::new(self.next_key_threshold, hashes)
173        } else {
174            nxt_commitment(self.next_key_threshold, &self.next_keys, &self.derivation)
175        };
176        let key_config = KeyConfig::new(self.keys, next_key_hash, Some(self.key_threshold));
177        let prefix = if self.prefix == IdentifierPrefix::default() {
178            let icp_data = InceptionEvent::new(key_config.clone(), None, None)
179                .incept_self_addressing(self.derivation.clone(), self.format)?;
180            icp_data.data.get_prefix()
181        } else {
182            self.prefix
183        };
184
185        Ok(match self.event_type {
186            EventTypeTag::Icp => {
187                let icp_event = InceptionEvent {
188                    key_config,
189                    witness_config: InceptionWitnessConfig {
190                        tally: self.witness_threshold,
191                        initial_witnesses: self.witnesses,
192                    },
193                    inception_configuration: vec![],
194                    data: vec![],
195                };
196
197                match prefix {
198                    IdentifierPrefix::Basic(_) => {
199                        KeyEvent::new(prefix, 0, EventData::Icp(icp_event))
200                            .to_message(self.format, self.derivation)?
201                    }
202                    IdentifierPrefix::SelfAddressing(_) => {
203                        icp_event.incept_self_addressing(self.derivation, self.format)?
204                    }
205                    _ => todo!(),
206                }
207            }
208
209            EventTypeTag::Rot => KeyEvent::new(
210                prefix,
211                self.sn,
212                EventData::Rot(RotationEvent::new(
213                    self.prev_event,
214                    key_config,
215                    RotationWitnessConfig {
216                        tally: self.witness_threshold,
217                        prune: self.witness_to_remove,
218                        graft: self.witness_to_add,
219                    },
220                    self.data,
221                )),
222            )
223            .to_message(self.format, self.derivation)?,
224            EventTypeTag::Ixn => KeyEvent::new(
225                prefix,
226                self.sn,
227                EventData::Ixn(InteractionEvent::new(self.prev_event.into(), self.data)),
228            )
229            .to_message(self.format, self.derivation)?,
230            EventTypeTag::Dip => {
231                let icp_data = InceptionEvent {
232                    key_config,
233                    witness_config: InceptionWitnessConfig {
234                        tally: self.witness_threshold,
235                        initial_witnesses: self.witnesses,
236                    },
237                    inception_configuration: vec![],
238                    data: vec![],
239                };
240                DelegatedInceptionEvent {
241                    inception_data: icp_data,
242                    delegator: self.delegator,
243                }
244                .incept_self_addressing(self.derivation, self.format)?
245            }
246            EventTypeTag::Drt => {
247                let rotation_data = RotationEvent::new(
248                    self.prev_event,
249                    key_config,
250                    RotationWitnessConfig::default(),
251                    self.data,
252                );
253                KeyEvent::new(prefix, self.sn, EventData::Drt(rotation_data))
254                    .to_message(self.format, self.derivation)?
255            }
256            _ => return Err(Error::SemanticError("Not key event".into())),
257        })
258    }
259}
260
261pub struct ReceiptBuilder {
262    format: SerializationFormats,
263    receipted_event: KeriEvent<KeyEvent>,
264}
265
266impl Default for ReceiptBuilder {
267    fn default() -> Self {
268        let default_event = EventMsgBuilder::new(EventTypeTag::Icp).build().unwrap();
269        Self {
270            format: SerializationFormats::JSON,
271            receipted_event: default_event,
272        }
273    }
274}
275
276impl ReceiptBuilder {
277    pub fn with_format(self, format: SerializationFormats) -> Self {
278        Self { format, ..self }
279    }
280
281    pub fn with_receipted_event(self, receipted_event: KeriEvent<KeyEvent>) -> Self {
282        Self {
283            receipted_event,
284            ..self
285        }
286    }
287
288    pub fn build(&self) -> Result<Receipt, Error> {
289        let prefix = self.receipted_event.data.get_prefix();
290        let sn = self.receipted_event.data.get_sn();
291        let receipted_event_digest = self.receipted_event.digest()?;
292        Ok(Receipt::new(
293            self.format,
294            receipted_event_digest,
295            prefix,
296            sn,
297        ))
298    }
299}
300
301#[test]
302fn test_multisig_prefix_derivation() {
303    // Keys taken from keripy: keripy/tests/core/test_eventing.py::test_multisig_digprefix (line 2255)
304    let expected_event = br#"{"v":"KERI10JSON0001e7_","t":"icp","d":"EBfxc4RiVY6saIFmUfEtETs1FcqmktZW88UkbnOg0Qen","i":"EBfxc4RiVY6saIFmUfEtETs1FcqmktZW88UkbnOg0Qen","s":"0","kt":"2","k":["DErocgXD2RGSyvn3MObcx59jeOsEQhv2TqHirVkzrp0Q","DFXLiTjiRdSBPLL6hLa0rskIxk3dh4XwJLfctkJFLRSS","DE9YgIQVgpLwocTVrG8tidKScsQSMWwLWywNC48fhq4f"],"nt":"2","n":["EDJk5EEpC4-tQ7YDwBiKbpaZahh1QCyQOnZRF7p2i8k8","EAXfDjKvUFRj-IEB_o4y-Y_qeJAjYfZtOMD9e7vHNFss","EN8l6yJC2PxribTN0xfri6bLz34Qvj-x3cNwcV3DvT2m"],"bt":"0","b":[],"c":[],"a":[]}"#;
305
306    let keys: Vec<BasicPrefix> = vec![
307        "DErocgXD2RGSyvn3MObcx59jeOsEQhv2TqHirVkzrp0Q"
308            .parse()
309            .unwrap(),
310        "DFXLiTjiRdSBPLL6hLa0rskIxk3dh4XwJLfctkJFLRSS"
311            .parse()
312            .unwrap(),
313        "DE9YgIQVgpLwocTVrG8tidKScsQSMWwLWywNC48fhq4f"
314            .parse()
315            .unwrap(),
316    ];
317    let next_keys: Vec<BasicPrefix> = vec![
318        "DCjxOXniUc5EUzDqERlXdptfKPHy6jNo_ZGsS4Vd8fAE"
319            .parse()
320            .unwrap(),
321        "DNZHARO4dCJlluv0qezEMRmErIWWc-lzOzolBOQ15tHV"
322            .parse()
323            .unwrap(),
324        "DOCQ4KN1jUlKbfjRteDYt9fxgpq1NK9_MqO5IA7shpED"
325            .parse()
326            .unwrap(),
327    ];
328
329    let msg_builder = EventMsgBuilder::new(EventTypeTag::Icp)
330        .with_keys(keys)
331        .with_next_keys(next_keys)
332        .with_threshold(&SignatureThreshold::Simple(2))
333        .with_next_threshold(&SignatureThreshold::Simple(2));
334    let msg = msg_builder.build().unwrap();
335
336    assert_eq!(expected_event.to_vec(), msg.encode().unwrap());
337}