diff --git a/contracts/okp4-dataverse/src/registrar/credential.rs b/contracts/okp4-dataverse/src/registrar/credential.rs index 3f462872..4e094240 100644 --- a/contracts/okp4-dataverse/src/registrar/credential.rs +++ b/contracts/okp4-dataverse/src/registrar/credential.rs @@ -1,9 +1,10 @@ use crate::credential::rdf_marker::IRI_VC_TYPE; use crate::credential::vc::VerifiableCredential; +use crate::registrar::rdf::VC_CLAIM; use crate::ContractError; use cosmwasm_std::Addr; use itertools::Itertools; -use okp4_rdf::dataset::Dataset; +use rio_api::model::{BlankNode, NamedNode, Subject, Term, Triple}; #[derive(Debug, PartialEq)] pub struct DataverseCredential<'a> { @@ -14,7 +15,7 @@ pub struct DataverseCredential<'a> { pub valid_from: &'a str, pub valid_until: Option<&'a str>, pub subject: &'a str, - pub claim: &'a Dataset<'a>, + pub claim: Vec>, } impl<'a> DataverseCredential<'a> { @@ -33,16 +34,46 @@ impl<'a> DataverseCredential<'a> { fn extract_vc_claim( vc: &'a VerifiableCredential<'a>, - ) -> Result<(&'a str, &'a Dataset<'a>), ContractError> { - vc.claims + ) -> Result<(&'a str, Vec>), ContractError> { + //todo: use the canon identifier issuer instead and rename all blank nodes + let claim_node = BlankNode { id: "c0" }; + + let claim = vc.claims.iter().exactly_one().map_err(|_| { + ContractError::UnsupportedCredential( + "credential is expected to contain exactly one claim".to_string(), + ) + })?; + + let mut triples = claim + .content .iter() - .exactly_one() - .map(|claim| (claim.id, &(claim.content))) - .map_err(|_| { - ContractError::UnsupportedCredential( - "credential is expected to contain exactly one claim".to_string(), - ) + .map(|q| { + let subject = match q.subject { + Subject::NamedNode(n) => { + if n.iri != claim.id { + Err(ContractError::UnsupportedCredential( + "claim hierarchy can be forge only through blank nodes".to_string(), + ))?; + } + Subject::BlankNode(claim_node) + } + _ => q.subject, + }; + Ok(Triple { + subject, + predicate: q.predicate, + object: q.object, + }) }) + .collect::>, ContractError>>()?; + + triples.push(Triple { + subject: Subject::NamedNode(NamedNode { iri: vc.id }), + predicate: VC_CLAIM, + object: Term::BlankNode(BlankNode { id: "c0" }), + }); + + Ok((claim.id, triples)) } } diff --git a/contracts/okp4-dataverse/src/registrar/rdf.rs b/contracts/okp4-dataverse/src/registrar/rdf.rs index 03685cca..42160981 100644 --- a/contracts/okp4-dataverse/src/registrar/rdf.rs +++ b/contracts/okp4-dataverse/src/registrar/rdf.rs @@ -3,7 +3,7 @@ use crate::registrar::credential::DataverseCredential; use crate::ContractError; use cosmwasm_std::{Binary, StdError}; use okp4_rdf::serde::{DataFormat, TripleWriter}; -use rio_api::model::{BlankNode, Literal, NamedNode, Subject, Term, Triple}; +use rio_api::model::{Literal, NamedNode, Subject, Term, Triple}; pub const VC_SUBMITTER_ADDRESS: NamedNode<'_> = NamedNode { iri: "dataverse:credential#submitterAddress", @@ -27,13 +27,9 @@ pub const VC_CLAIM: NamedNode<'_> = NamedNode { iri: "dataverse:credential#claim", }; -impl<'a> TryFrom<&'a DataverseCredential<'a>> for Vec> { - type Error = ContractError; - - fn try_from(credential: &'a DataverseCredential<'a>) -> Result { +impl<'a> From<&'a DataverseCredential<'a>> for Vec> { + fn from(credential: &'a DataverseCredential<'a>) -> Self { let c_subject = Subject::NamedNode(NamedNode { iri: credential.id }); - //todo: use the canon identifier issuer instead and rename all blank nodes - let claim_node = BlankNode { id: "c0" }; let mut triples = vec![ Triple { @@ -72,26 +68,9 @@ impl<'a> TryFrom<&'a DataverseCredential<'a>> for Vec> { iri: credential.subject, }), }, - Triple { - subject: c_subject, - predicate: VC_CLAIM, - object: Term::BlankNode(claim_node), - }, ]; - triples.extend(credential.claim.iter().map(|q| { - let subject = match q.subject { - Subject::NamedNode(n) if n.iri == credential.subject => { - Subject::BlankNode(claim_node) - } - _ => q.subject, - }; - Triple { - subject, - predicate: q.predicate, - object: q.object, - } - })); + triples.extend(credential.claim.as_slice()); if let Some(valid_until) = credential.valid_until { triples.push(Triple { @@ -104,7 +83,7 @@ impl<'a> TryFrom<&'a DataverseCredential<'a>> for Vec> { }); } - Ok(triples) + triples } } @@ -112,7 +91,7 @@ pub fn serialize( credential: &DataverseCredential<'_>, format: DataFormat, ) -> Result { - let triples: Vec> = credential.try_into()?; + let triples: Vec> = credential.into(); let out: Vec = Vec::default(); let mut writer = TripleWriter::new(&format, out); for triple in triples {