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 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}