diff --git a/contracts/okp4-dataverse/src/registrar/mod.rs b/contracts/okp4-dataverse/src/registrar/mod.rs new file mode 100644 index 00000000..767ae316 --- /dev/null +++ b/contracts/okp4-dataverse/src/registrar/mod.rs @@ -0,0 +1,3 @@ +pub mod credential; +mod rdf; +pub mod registry; diff --git a/contracts/okp4-dataverse/src/registrar/registry.rs b/contracts/okp4-dataverse/src/registrar/registry.rs new file mode 100644 index 00000000..72260733 --- /dev/null +++ b/contracts/okp4-dataverse/src/registrar/registry.rs @@ -0,0 +1,65 @@ +use crate::registrar::credential::DataverseCredential; +use crate::registrar::rdf::serialize; +use crate::state::DATAVERSE; +use crate::ContractError; +use cosmwasm_std::{DepsMut, StdResult, Storage, WasmMsg}; +use okp4_cognitarium::msg::{ + DataFormat, Node, SelectItem, SelectQuery, SimpleWhereCondition, TriplePattern, VarOrNode, + VarOrNodeOrLiteral, WhereCondition, IRI, +}; +use okp4_cognitarium_client::CognitariumClient; + +/// ClaimRegistrar is the entity responsible to manage claims (i.e. submission and revocation) into +/// the Dataverse, ensuring that any pre-condition criteria to an action is met, and any attached +/// logic is properly executed. +pub struct ClaimRegistrar { + triplestore: CognitariumClient, +} + +impl ClaimRegistrar { + const RDF_DATA_FORMAT: DataFormat = DataFormat::NTriples; + + pub fn try_new(storage: &dyn Storage) -> StdResult { + let dataverse = DATAVERSE.load(storage)?; + Ok(Self { + triplestore: CognitariumClient::new(dataverse.triplestore_address), + }) + } + + pub fn submit_claim( + &self, + deps: &DepsMut<'_>, + credential: &DataverseCredential<'_>, + ) -> Result { + let resp = self.triplestore.select( + deps.querier, + SelectQuery { + prefixes: vec![], + limit: Some(1u32), + select: vec![SelectItem::Variable("p".to_string())], + r#where: vec![WhereCondition::Simple(SimpleWhereCondition::TriplePattern( + TriplePattern { + subject: VarOrNode::Node(Node::NamedNode(IRI::Full( + credential.id.to_string(), + ))), + predicate: VarOrNode::Variable("p".to_string()), + object: VarOrNodeOrLiteral::Variable("o".to_string()), + }, + ))], + }, + )?; + + if !resp.results.bindings.is_empty() { + Err(ContractError::CredentialAlreadyExists( + credential.id.to_string(), + ))?; + } + + self.triplestore + .insert_data( + Some(Self::RDF_DATA_FORMAT), + serialize(credential, (&Self::RDF_DATA_FORMAT).into())?, + ) + .map_err(ContractError::from) + } +}