Vade - evan.network Plugins

crates.io Documentation Apache-2 licensed

About

This project is providing two plugins to be used with the [vade] library. These plugins offer functionalities to work with VCs and DIDs on [evan.network].

Usage

Plugins from this project can be used within the [vade] library as described in its own documentation. To give you a jump start, here is how you can retrieve VC documents:

```rust extern crate vade; extern crate vade_evan;

use vade::Vade; use vadeevan::plugin::rustvcresolver_evan::RustVcResolverEvan;

const EXAMPLEVCNAME_REMOTE: &str = "vc:evan:testcore:0x6e90a3e2bf3823e52eceb0f81373eb58b1a0a238965f0d4388ab9ce9ceeddfd3";

[tokio::test]

async fn canfetchavcdocument() { let rde = RustVcResolverEvan::new(); let mut vade = Vade::new(); vade.registervcresolver(Box::from(rde));

let _vc = vade.get_vc_document(&EXAMPLE_VC_NAME_REMOTE).await.unwrap();

} ```

Plugins

Plugins are described below shotly, for more details see respective [API documentation].

VC Resolver

Allows to work with VCs on [evan.network], currently includes:

Retrieving VCs

Existing VCs from [evan.network] can be retrieved with vade's [get_vc_document] function:

```rust use vade::Vade; use vadeevan::plugin::rustvcresolver_evan::RustVcResolverEvan;

async fn example() { let vcr = RustVcResolverEvan::new(); let mut vade = Vade::new(); vade.registervcresolver(Box::from(vcr));

let vc = vade.get_vc_document("vc:evan:testcore:0x75956ef9b3ea7d7230cf007b8ee042bcaa2a4dad8c043fa77ecf51262ee4f7a9").await.unwrap();

} ```

Result is returned as a JSON String and can easily be parsed with libraries like [serde_json] for further processing, e.g.:

rust let parsed: Value = serde_json::from_str(&vc).unwrap();

Validating VCs

Taken from our tests:

```rust use vade::Vade; use vade::plugin::ruststoragecache::RustStorageCache; use vadeevan::plugin::rustvcresolver_evan::RustVcResolverEvan;

async fn example() -> std::result::Result<(), Box> { // create a vc resolver with attached did resolver in a vade instance let vcrdidr = RustStorageCache::new(); let mut vcrvade = Vade::new(); vcrvade.registerdidresolver(Box::from(vcrdidr)); // add did document to vcr's did resolver let didid = "did:evan:testcore:0x0ef0e584c714564a4fc0c6c367edccb0c1cbf65f"; let diddocument = "{...}"; vcrvade.setdiddocument(&didid, &diddocument).await?; let mut vcr = RustVcResolverEvan::new(); vcr.vade = Some(Box::from(vcrvade));

// create vade to work with, attach vc resolver
let mut vade = Vade::new();
vade.register_vc_resolver(Box::from(vcr));

// test VC document
let vc_name = "vc:evan:testcore:0x8b078ee6cfb208dca52bf89ab7178e0f11323f4363c1a6ad18321275e6d07fcb";
let vc_document = "{...}";
let vc_result = vade.check_vc(&vc_name, &vc_document).await;
match vc_result {
    Ok(_) => (),
    Err(e) => panic!(format!("{}", e)),
};
Ok(())

} ```

Note that the setup for the [RustVcResolver] instance differs a bit, as we - create a separate [Vade] instance - configure a [DidResolver] for it in this case an in-memory resolver for our test DID - register it as vade in our [RustVcResolver] instance

This allows us to validate the proof property in our VC document.

Creating VCs

Creating a VC currently has three requirements:

As an example take this test function:

```rust use serdejson::Value; use vadeevan::plugin::rustvcresolverevan::{ RustVcResolverEvan, VCDEFAULTTYPE, VCW3CMANDATORY_CONTEXT, };

async fn vcresolvercancreatenewvcs() -> std::result::Result<(), Box> { // issuer of the new VC let veriissuer = "did:evan:testcore:0x0ef0e584c714564a4fc0c6c367edccb0c1cbf65f"; // verification method of the VC (can be considered "key id" for the key used to create proof) let verimethod = "did:evan:testcore:0x0ef0e584c714564a4fc0c6c367edccb0c1cbf65f#key-1"; // Ethereum private key used to create proof let veripkey = "01734663843202e2245e5796cb120510506343c67915eb4f9348ac0d8c2cf22a"; // sample data, id is required, credentialSubject is optional and holds tests data let partialvcdata =r###" { "id": "foo-bar-vc", "credentialSubject": { "foo": "bar" } } "###;

let vcr = RustVcResolverEvan::new();

let vc: String = vcr.create_vc(partial_vc_data, &veri_method, &veri_pkey).await.unwrap();

let parsed: Value = serde_json::from_str(&vc).unwrap();

assert!(parsed["credentialSubject"]["foo"].as_str() == Some("bar"));
assert!(parsed["@context"].as_array().unwrap().len() == 1);
assert!(parsed["@context"].as_array().unwrap().iter().any(|v| v == VC_W3C_MANDATORY_CONTEXT));
assert!(parsed["type"].as_str() == Some(VC_DEFAULT_TYPE));
assert!(parsed["issuer"].as_str() == Some(veri_issuer));
assert!(parsed["validFrom"].as_str() != None);
assert!(parsed["proof"].as_object() != None);

Ok(())

} ```

Have a look at the assert block at the end of the test. Here you can see the properties, that are added automatically: - @context - type - issuer - validFrom - proof

These are added automatically if not provided in partial_vc_data.

DID Resolver

Allows to work with DIDs on [evan.network], currently includes:

Retrieving DIDs

Fetching DIDs via [RustDidResolver] fetches them from [evan.network] and returns them as str, e.g.:

```rust use vade::Vade; use vadeevan::plugin::rustdidresolverevan::RustDidResolverEvan; let rde = RustDidResolverEvan::new(); let mut vade = Vade::new(); vade.registerdid_resolver(Box::from(rde));

let did = vade.getdiddocument("did:evan:testcore:0x0ef0e584c714564a4fc0c6c367edccb0c1cbf65f").await.unwrap(); ```