use std::marker::PhantomData;
use serde::{Deserialize, Serialize};
use crate::sidetree::{json_canonicalization_scheme, DIDSuffix, Delta, Sidetree, SidetreeDID};
use super::{PartialVerificationError, SidetreeOperation};
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct CreateOperation {
pub suffix_data: SuffixData,
pub delta: Delta,
}
impl CreateOperation {
pub fn to_sidetree_did<S: Sidetree>(&self) -> SidetreeDID<S> {
let op_json = json_canonicalization_scheme(self).unwrap();
let op_string = S::data_encoding_scheme(op_json.as_bytes());
let did_suffix = S::serialize_suffix_data(&self.suffix_data);
SidetreeDID::Long {
did_suffix,
create_operation_data: op_string,
_marker: PhantomData,
}
}
}
impl SidetreeOperation for CreateOperation {
type PartiallyVerifiedForm = PartiallyVerifiedCreateOperation;
fn partial_verify<S: Sidetree>(
self,
) -> Result<PartiallyVerifiedCreateOperation, PartialVerificationError> {
let did: SidetreeDID<S> = self.to_sidetree_did();
let did_suffix = DIDSuffix::from(did);
let delta_string = json_canonicalization_scheme(&self.delta).unwrap();
let delta_hash = S::hash(delta_string.as_bytes());
if delta_hash != self.suffix_data.delta_hash {
return Err(PartialVerificationError::DeltaHashMismatch);
}
Ok(PartiallyVerifiedCreateOperation {
did_suffix,
r#type: self.suffix_data.r#type,
recovery_commitment: self.suffix_data.recovery_commitment,
anchor_origin: self.suffix_data.anchor_origin,
hashed_delta: self.delta,
})
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct PartiallyVerifiedCreateOperation {
pub did_suffix: DIDSuffix,
pub r#type: Option<String>,
pub recovery_commitment: String,
pub anchor_origin: Option<String>,
pub hashed_delta: Delta,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SuffixData {
#[serde(skip_serializing_if = "Option::is_none")]
pub r#type: Option<String>,
pub delta_hash: String,
pub recovery_commitment: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub anchor_origin: Option<String>,
}