This example shows how to create a Rust application with rebase that uses TreeLDR to define a simple DNS witness flow VC. The program will consist of:
a TreeLDR schema defining the credential type,
an implementation of Rebase's SchemaType trait for the credential schema.
Project Creation
First, create a new Rust project using cargo:
cargo new dns-example
cd dns-example
The src directory will contain the sources of our application. For now, it only contains a main.rs file with a dummy main function definition.
Credential Definition in TreeLDR
Create a new src/dns.tldr file that will contain the VC definition:
base <https://example.com/>;
use <http://www.w3.org/2000/01/rdf-schema#> as rdfs;
use <http://www.w3.org/2001/XMLSchema#> as xs;
use <https://treeldr.org/> as tldr;
use <https://www.w3.org/2018/credentials#> as vc;
/// DNS Verification Message.
type DnsVerificationMessage {
// Include the type inside the layout as `@type`.
// This will force TreeLDR to generate a type scoped context
// for `DnsVerificationMessage` when generating the
// JSON-LD context.
rdf:type as @type: required multiple &rdfs:Class,
timestamp: required xs:dateTime,
dnsServer: required xs:string
}
/// DNS Verification Subject.
layout DnsVerificationSubject for rdfs:Resource {
tldr:self as id: required &rdfs:Resource,
schema:sameAs: &rdfs:Resource
}
/// DNS Verification VC.
type DnsVerification =
vc:VerifiableCredential &
all vc:credentialSubject: (rdfs:Resource with DnsVerificationSubject) &
all vc:evidence: DnsVerificationMessage;
The DnsVerification type is a vc:VerifiableCredential where the credential subject is any resource represented with the DnsVerificationSubject layout, and evidences are any DnsVerificationMessage.
We will embed the previous schema definition into the Rust program as a type definition using the #[tldr] procedural macro attribute provided by the treeldr-rust-macros crate. This crate rely on the treeldr-rust-prelude crate. First, add those two crates to the dependencies of the Rust program by adding the following lines to the Cargo.toml file under the [dependencies] section:
Contrarily to the "Basic Post" example, SchemaType will not directly be implemented for the credential subject type (here DnsVerificationMessage). Instead, we create a dedicated Schema type that will generate the credential subjects and evidence. Add the following items in the src/main.rs file:
The subject of the VC, a DnsVerifiactionSubject, is derived from the key type. We use schema::example::DnsVerificationSubject to build the subject and convert it into a serde_json::Value. Replace the todo!() in the subject method with:
The evidence is a DnsVerificationMessage, however we will not be able to use the schema::example::DnsVerificationMessage type defined by TreeLDR since rebase expect an ssi::vc::Evidence instance. Instead we will closely follow the structure of a DnsVerificationMessage to build the evidence by hand. Replace the todo!() in the evidence method with: