Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper convert to nquads #85

Merged
merged 6 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions VERSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- these properties in payload are now optional:
- `issuer_public_key_did`
- `issuer_proving_key`
- add `helper_convert_credential_to_nquads` helper function

### Fixes

Expand Down
78 changes: 78 additions & 0 deletions src/api/vade_evan_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,84 @@ impl VadeEvan {
.map_err(|err| err.into())
}

/// Converts a Credential to canonized nquads
///
/// # Arguments
///
/// * `credential` - credential to be converted to nquads
///
/// # Example
///
/// ```
/// cfg_if::cfg_if! {
/// if #[cfg(not(all(feature = "c-lib", feature = "target-c-sdk")))] {
/// use anyhow::Result;
/// use vade_evan::{VadeEvan, VadeEvanConfig, DEFAULT_TARGET, DEFAULT_SIGNER};
///
/// async fn example() -> Result<()> {
/// let mut vade_evan = VadeEvan::new(VadeEvanConfig { target: DEFAULT_TARGET, signer: DEFAULT_SIGNER })?;
/// let credential = r###"{
/// "id": "uuid:70b7ec4e-f035-493e-93d3-2cf5be4c7f88",
/// "type": [
/// "VerifiableCredential"
/// ],
/// "proof": {
/// "type": "BbsBlsSignature2020",
/// "created": "2023-02-01T14:08:17.000Z",
/// "signature": "kvSyi40dnZ5S3/mSxbSUQGKLpyMXDQNLCPtwDGM9GsnNNKF7MtaFHXIbvXaVXku0EY/n2uNMQ2bmK2P0KEmzgbjRHtzUOWVdfAnXnVRy8/UHHIyJR471X6benfZk8KG0qVqy+w67z9g628xRkFGA5Q==",
/// "proofPurpose": "assertionMethod",
/// "verificationMethod": "did:evan:EiAee4ixDnSP0eWyp0YFV7Wt9yrZ3w841FNuv9NSLFSCVA#bbs-key-1",
/// "credentialMessageCount": 13,
/// "requiredRevealStatements": []
/// },
/// "issuer": "did:evan:EiAee4ixDnSP0eWyp0YFV7Wt9yrZ3w841FNuv9NSLFSCVA",
/// "@context": [
/// "https://www.w3.org/2018/credentials/v1",
/// "https://schema.org/",
/// "https://w3id.org/vc-revocation-list-2020/v1"
/// ],
/// "issuanceDate": "2023-02-01T14:08:09.849Z",
/// "credentialSchema": {
/// "id": "did:evan:EiCimsy3uWJ7PivWK0QUYSCkImQnjrx6fGr6nK8XIg26Kg",
/// "type": "EvanVCSchema"
/// },
/// "credentialStatus": {
/// "id": "did:evan:EiA0Ns-jiPwu2Pl4GQZpkTKBjvFeRXxwGgXRTfG1Lyi8aA#4",
/// "type": "RevocationList2020Status",
/// "revocationListIndex": "4",
/// "revocationListCredential": "did:evan:EiA0Ns-jiPwu2Pl4GQZpkTKBjvFeRXxwGgXRTfG1Lyi8aA"
/// },
/// "credentialSubject": {
/// "id": "did:evan:EiAee4ixDnSP0eWyp0YFV7Wt9yrZ3w841FNuv9NSLFSCVA",
/// "data": {
/// "bio": "biography"
/// }
/// }
/// }"###;
///
/// // convert the credential to nquads
/// vade_evan
/// .helper_convert_credential_to_nquads(credential)
/// .await?;
///
/// Ok(())
/// }
/// } else {
/// // currently no example for target-c-sdk and c-lib/target-java-lib
/// }
/// }
#[cfg(all(feature = "vc-zkp-bbs"))]
pub async fn helper_convert_credential_to_nquads(
&mut self,
credential: &str,
) -> Result<String, VadeEvanError> {
let credential_helper = Credential::new(self)?;
credential_helper
.convert_credential_to_nquads(credential)
.await
.map_err(|err| err.into())
}

/// Proposes to share a proof for a credential.
/// The proof proposal consists of the fields the prover wants to reveal per schema.
///
Expand Down
20 changes: 20 additions & 0 deletions src/c_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,26 @@ pub extern "C" fn execute_vade(
.map_err(stringify_vade_evan_error)
}
}),
#[cfg(all(feature = "vc-zkp-bbs"))]
"helper_convert_credential_to_nquads" => runtime.block_on({
async {
let mut vade_evan = get_vade_evan(
Some(&str_config),
#[cfg(all(feature = "c-lib", feature = "target-c-sdk"))]
ptr_request_list,
#[cfg(all(feature = "c-lib", feature = "target-c-sdk"))]
request_function_callback,
)
.map_err(stringify_generic_error)?;
vade_evan
.helper_convert_credential_to_nquads(
arguments_vec.get(0).unwrap_or_else(|| &no_args),
)
.await
.map_err(stringify_vade_evan_error)?;
Ok("".to_string())
}
}),
#[cfg(any(feature = "vc-zkp-bbs"))]
"run_custom_function" => runtime.block_on({
execute_vade_function!(
Expand Down
47 changes: 46 additions & 1 deletion src/helpers/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,13 +487,35 @@ impl<'a> Credential<'a> {
)),
}
}

/// Converts a Credential to canonized nquads
///
/// # Arguments
/// * `credential_str` - Credential to be converted
///
/// # Returns
/// * `nquads` - Vec of canonized nquads
pub async fn convert_credential_to_nquads(
&self,
credential_str: &str,
) -> Result<String, CredentialError> {
// get nquads
let mut parsed_credential: Map<String, Value> = serde_json::from_str(credential_str)?;
// remove proof if exists
if parsed_credential.contains_key("proof") {
parsed_credential.remove("proof");
}
let credential_without_proof = serde_json::to_string(&parsed_credential)?;
let did_doc_nquads = convert_to_nquads(&credential_without_proof).await?;
Ok(serde_json::to_string(&did_doc_nquads)?)
}
}

#[cfg(test)]
#[cfg(not(all(feature = "c-lib", feature = "target-c-sdk")))]
mod tests {
use crate::helpers::credential::is_revoked;

const ADDITIONAL_HIDDEN_MESSAGES_COUNT: usize = 1;
cfg_if::cfg_if! {
if #[cfg(feature = "did-sidetree")] {
use anyhow::Result;
Expand Down Expand Up @@ -978,4 +1000,27 @@ mod tests {

Ok(())
}

#[tokio::test]
#[cfg(feature = "did-sidetree")]
async fn helper_can_convert_to_nquads() -> Result<()> {
let mut vade_evan = VadeEvan::new(crate::VadeEvanConfig {
target: DEFAULT_TARGET,
signer: DEFAULT_SIGNER,
})?;

let credential_helper = Credential::new(&mut vade_evan)?;
let credential: BbsCredential = serde_json::from_str(CREDENTIAL_ACTIVE)?;
// verify the credential issuer
let nquads_result = credential_helper
.convert_credential_to_nquads(CREDENTIAL_ACTIVE)
.await;
assert!(nquads_result.is_ok());
let nquads: Vec<String> = serde_json::from_str(&nquads_result?)?;
assert_eq!(
nquads.len() + ADDITIONAL_HIDDEN_MESSAGES_COUNT,
credential.proof.credential_message_count
);
Ok(())
}
}
21 changes: 21 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,17 @@ async fn main() -> Result<()> {
)
.await?
}
#[cfg(all(feature = "vc-zkp-bbs"))]
("convert_credential_to_nquads", Some(sub_m)) => {
get_vade_evan(sub_m)?
.helper_convert_credential_to_nquads(get_argument_value(
sub_m,
"credential",
None,
))
.await?;
"".to_string()
}
#[cfg(all(feature = "vc-zkp-bbs", feature = "did-sidetree"))]
("create_self_issued_credential", Some(sub_m)) => {
get_vade_evan(sub_m)?
Expand Down Expand Up @@ -422,6 +433,16 @@ fn add_subcommand_helper<'a>(app: App<'a, 'a>) -> Result<App<'a, 'a>> {
} else {}
}

cfg_if::cfg_if! {
if #[cfg(all(feature = "vc-zkp-bbs"))] {
subcommand = subcommand.subcommand(
SubCommand::with_name("convert_credential_to_nquads")
.about("Converts a given credential to nquads vector.")
.arg(get_clap_argument("credential")?)
);
} else {}
}

cfg_if::cfg_if! {
if #[cfg(all(feature = "vc-zkp-bbs", feature = "did-sidetree"))] {
subcommand = subcommand.subcommand(
Expand Down
30 changes: 30 additions & 0 deletions src/wasm_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ struct HelperVerifyPresentationPayload {
pub presentation_str: String,
pub proof_request_str: String,
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct HelperConvertCredentialToNquads {
pub credential_str: String,
}


#[wasm_bindgen]
pub fn set_panic_hook() {
Expand Down Expand Up @@ -441,6 +447,20 @@ cfg_if::cfg_if! {
.map_err(jsify_vade_evan_error)?)
}

#[cfg(all(feature = "vc-zkp-bbs"))]
#[wasm_bindgen]
pub async fn helper_convert_credential_to_nquads(
credential: String,
) -> Result<String, JsValue> {
let mut vade_evan = get_vade_evan(None).map_err(jsify_generic_error)?;
vade_evan
.helper_convert_credential_to_nquads(
&credential,
).await
.map_err(jsify_vade_evan_error)?;
Ok("".to_string())
}

#[cfg(all(feature = "vc-zkp-bbs", feature = "did-sidetree"))]
#[wasm_bindgen]
pub async fn helper_create_proof_proposal(
Expand Down Expand Up @@ -790,6 +810,16 @@ pub async fn execute_vade(
Err(error) => Err(get_parsing_error_message(&error, &payload)),
}
}
#[cfg(all(feature = "vc-zkp-bbs"))]
"helper_convert_credential_to_nquads" => {
let payload_result = parse::<HelperConvertCredentialToNquads>(&payload);
match payload_result {
Ok(payload) => {
helper_convert_credential_to_nquads(payload.credential_str).await
}
Err(error) => Err(get_parsing_error_message(&error, &payload)),
}
}
#[cfg(all(feature = "vc-zkp-bbs", feature = "did-sidetree"))]
"helper_create_proof_proposal" => {
let payload_result = parse::<HelperCreateProofProposalPayload>(&payload);
Expand Down
Loading