Skip to content

Commit 37afdec

Browse files
authored
Merge 03c37ae into fbd8a99
2 parents fbd8a99 + 03c37ae commit 37afdec

File tree

24 files changed

+1565
-157
lines changed

24 files changed

+1565
-157
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2020-2023 IOTA Stiftung
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import {
5+
CredentialV2,
6+
EdDSAJwsVerifier,
7+
FailFast,
8+
JwsSignatureOptions,
9+
JwtCredentialValidationOptions,
10+
JwtCredentialValidator,
11+
} from "@iota/identity-wasm/node";
12+
import { IotaClient } from "@iota/iota-sdk/client";
13+
import { createDocumentForNetwork, getFundedClient, getMemstorage, NETWORK_URL } from "../util";
14+
15+
/**
16+
* This example shows how to create a Verifiable Credential and validate it.
17+
* In this example, Alice takes the role of the subject, while we also have an issuer.
18+
* The issuer signs a UniversityDegreeCredential type verifiable credential with Alice's name and DID.
19+
* This Verifiable Credential can be verified by anyone, allowing Alice to take control of it and share it with whomever they please.
20+
*/
21+
export async function createVC() {
22+
// create new client to connect to IOTA network
23+
const iotaClient = new IotaClient({ url: NETWORK_URL });
24+
const network = await iotaClient.getChainIdentifier();
25+
26+
// Create an identity for the issuer with one verification method `key-1`, and publish DID document for it.
27+
const issuerStorage = getMemstorage();
28+
const issuerClient = await getFundedClient(issuerStorage);
29+
const [unpublishedIssuerDocument, issuerFragment] = await createDocumentForNetwork(issuerStorage, network);
30+
const { output: issuerIdentity } = await issuerClient
31+
.createIdentity(unpublishedIssuerDocument)
32+
.finish()
33+
.buildAndExecute(issuerClient);
34+
const issuerDocument = issuerIdentity.didDocument();
35+
36+
// Create an identity for the holder, and publish DID document for it, in this case also the subject.
37+
const aliceStorage = getMemstorage();
38+
const aliceClient = await getFundedClient(aliceStorage);
39+
const [unpublishedAliceDocument] = await createDocumentForNetwork(aliceStorage, network);
40+
const { output: aliceIdentity } = await aliceClient
41+
.createIdentity(unpublishedAliceDocument)
42+
.finish()
43+
.buildAndExecute(aliceClient);
44+
const aliceDocument = aliceIdentity.didDocument();
45+
46+
// Create a credential subject indicating the degree earned by Alice, linked to their DID.
47+
const subject = {
48+
id: aliceDocument.id(),
49+
name: "Alice",
50+
degreeName: "Bachelor of Science and Arts",
51+
degreeType: "BachelorDegree",
52+
GPA: "4.0",
53+
};
54+
55+
// Create an unsigned `UniversityDegree` credential for Alice
56+
const unsignedVc = new CredentialV2({
57+
id: "https://example.edu/credentials/3732",
58+
type: "UniversityDegreeCredential",
59+
issuer: issuerDocument.id(),
60+
credentialSubject: subject,
61+
});
62+
63+
// Create signed JWT credential.
64+
const credentialJwt = await issuerDocument.createCredentialJwt(
65+
issuerStorage,
66+
issuerFragment,
67+
unsignedVc,
68+
new JwsSignatureOptions(),
69+
);
70+
console.log(`Credential JWT > ${credentialJwt.toString()}`);
71+
72+
// Before sending this credential to the holder the issuer wants to validate that some properties
73+
// of the credential satisfy their expectations.
74+
75+
// Validate the credential's signature, the credential's semantic structure,
76+
// check that the issuance date is not in the future and that the expiration date is not in the past.
77+
// Note that the validation returns an object containing the decoded credential.
78+
const decoded_credential = new JwtCredentialValidator(new EdDSAJwsVerifier()).validateV2(
79+
credentialJwt,
80+
issuerDocument,
81+
new JwtCredentialValidationOptions(),
82+
FailFast.FirstError,
83+
);
84+
85+
// Since `validate` did not throw any errors we know that the credential was successfully validated.
86+
console.log(`VC successfully validated`);
87+
88+
// The issuer is now sure that the credential they are about to issue satisfies their expectations.
89+
// Note that the credential is NOT published to the IOTA Tangle. It is sent and stored off-chain.
90+
console.log(`Issued credential: ${JSON.stringify(decoded_credential.intoCredential(), null, 2)}`);
91+
}

bindings/wasm/identity_wasm/src/credential/credential_builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ impl TryFrom<ICredential> for CredentialBuilder {
108108

109109
#[wasm_bindgen]
110110
extern "C" {
111+
#[derive(Clone)]
111112
#[wasm_bindgen(typescript_type = "ICredential")]
112113
pub type ICredential;
113114
}

0 commit comments

Comments
 (0)