diff --git a/event/src/args.rs b/event/src/args.rs index 159b7ace6..0dfae1ad7 100644 --- a/event/src/args.rs +++ b/event/src/args.rs @@ -21,7 +21,7 @@ pub struct EventArgs<'a, S: Signer> { signer: &'a S, controllers: Vec<&'a DidDocument>, parent: &'a StreamId, - sep: &'a str, + sep: &'static str, } impl<'a, S: Signer> EventArgs<'a, S> { @@ -57,17 +57,24 @@ impl<'a, S: Signer> EventArgs<'a, S> { Ok(evt) } + /// Create an init event from these arguments with a unique header + pub fn init_with_unique(&self) -> Result { + let evt = UnsignedEvent::<()>::init_with_unique(self)?; + let evt = DeterministicInitEvent::new(&evt)?; + Ok(evt) + } + /// Create an init event from these arguments with data pub async fn init_with_data(&self, data: &T) -> Result { let evt = UnsignedEvent::init_with_data(self, data)?; - let evt = Event::new(&evt, self.signer).await?; + let evt = Event::new(evt, self.signer).await?; Ok(evt) } /// Create an update event from these arguments pub async fn update(&self, current: &Cid, prev: &Cid, data: &T) -> Result { - let evt = UnsignedEvent::update(self, current, prev, data)?; - let evt = Event::new(&evt, self.signer).await?; + let evt = UnsignedEvent::update(self, *current, *prev, data)?; + let evt = Event::new(evt, self.signer).await?; Ok(evt) } @@ -78,54 +85,68 @@ impl<'a, S: Signer> EventArgs<'a, S> { } #[derive(Serialize)] -struct UnsignedEventHeader<'a> { - controllers: Vec<&'a str>, +struct UnsignedEventHeader { + controllers: Vec, #[serde(rename = "model")] parent: Bytes, - sep: &'a str, + sep: &'static str, #[serde(skip_serializing_if = "Option::is_none")] unique: Option>, } /// An unsigned event, which can be used to create a events #[derive(Serialize)] -pub struct UnsignedEvent<'a, T: Serialize> { +pub struct UnsignedEvent { #[serde(skip_serializing_if = "Option::is_none")] - data: Option<&'a T>, + data: Option, #[serde(skip_serializing_if = "Option::is_none")] - header: Option>, + header: Option, #[serde(skip_serializing_if = "Option::is_none")] - prev: Option<&'a Cid>, + prev: Option, #[serde(skip_serializing_if = "Option::is_none")] - id: Option<&'a Cid>, + id: Option, +} + +fn create_unique() -> Result> { + let mut rng = rand::thread_rng(); + let mut unique = [0u32; 12]; + unique.try_fill(&mut rng)?; + Ok(unique.to_vec()) } -impl<'a, T: Serialize> UnsignedEvent<'a, T> { +impl UnsignedEvent { /// Initialize a new unsigned event from event arguments - pub fn init(args: &'a EventArgs) -> Result { + pub fn init(args: &EventArgs) -> Result { create_unsigned_event(args, CreateArgs::Init) } + /// Initialize a new unsigned event from event arguments with unique field + pub fn init_with_unique(args: &EventArgs) -> Result { + create_unsigned_event( + args, + CreateArgs::InitWithUnique { + unique: create_unique()?, + }, + ) + } + /// Initialize a new unsigned event from event arguments with data - pub fn init_with_data(args: &'a EventArgs, data: &'a T) -> Result { - let mut rng = rand::thread_rng(); - let mut unique = [0u32; 12]; - unique.try_fill(&mut rng)?; + pub fn init_with_data(args: &EventArgs, data: T) -> Result { create_unsigned_event( args, CreateArgs::InitWithData { data, - unique: unique.to_vec(), + unique: create_unique()?, }, ) } /// Create an update unsigned event from event arguments pub fn update( - args: &'a EventArgs, - current: &'a Cid, - prev: &'a Cid, - data: &'a T, + args: &EventArgs, + current: Cid, + prev: Cid, + data: T, ) -> Result { create_unsigned_event( args, @@ -138,27 +159,21 @@ impl<'a, T: Serialize> UnsignedEvent<'a, T> { } } -enum CreateArgs<'a, T: Serialize> { +enum CreateArgs { Init, - InitWithData { - data: &'a T, - unique: Vec, - }, - Update { - current: &'a Cid, - prev: &'a Cid, - data: &'a T, - }, + InitWithUnique { unique: Vec }, + InitWithData { data: T, unique: Vec }, + Update { current: Cid, prev: Cid, data: T }, } -fn create_unsigned_event<'a, S: Signer, T: Serialize>( - event_args: &'a EventArgs<'a, S>, - create_args: CreateArgs<'a, T>, -) -> Result> { - let controllers: Vec<&str> = event_args +fn create_unsigned_event( + event_args: &EventArgs, + create_args: CreateArgs, +) -> Result> { + let controllers: Vec<_> = event_args .controllers .iter() - .map(|d| d.id.as_ref()) + .map(|d| d.id.to_string()) .collect(); let (header, data, prev, id) = match create_args { CreateArgs::Init => ( @@ -172,6 +187,17 @@ fn create_unsigned_event<'a, S: Signer, T: Serialize>( None, None, ), + CreateArgs::InitWithUnique { unique } => ( + Some(UnsignedEventHeader { + controllers, + parent: event_args.parent.try_into()?, + sep: event_args.sep, + unique: Some(unique), + }), + None, + None, + None, + ), CreateArgs::InitWithData { data, unique } => ( Some(UnsignedEventHeader { controllers, diff --git a/event/src/deterministic_init_event.rs b/event/src/deterministic_init_event.rs index 77ca9545b..29dbe1fd0 100644 --- a/event/src/deterministic_init_event.rs +++ b/event/src/deterministic_init_event.rs @@ -5,14 +5,16 @@ use serde::Serialize; use std::fmt::Formatter; /// A deterministic init event, where it will always hash the same way +#[derive(Serialize)] pub struct DeterministicInitEvent { /// The encoded event + #[serde(flatten)] pub encoded: DagCborEncoded, } impl DeterministicInitEvent { /// Create a deterministic init event from an unsigned event - pub fn new(evt: &UnsignedEvent<'_, T>) -> Result { + pub fn new(evt: &UnsignedEvent<()>) -> Result { let data = DagCborEncoded::new(&evt)?; Ok(Self { encoded: data }) } diff --git a/event/src/event.rs b/event/src/event.rs index 8819a7fd6..e72949a4f 100644 --- a/event/src/event.rs +++ b/event/src/event.rs @@ -19,8 +19,8 @@ pub struct Event { impl Event { /// Create a new event from an unsigned event, signer, and jwk - pub async fn new<'a, T: Serialize>( - unsigned: &'a UnsignedEvent<'a, T>, + pub async fn new( + unsigned: UnsignedEvent, signer: &impl Signer, ) -> Result { // encode our event with dag cbor, hashing that to create cid