# Introduction

zCloak is a web3 privacy identity company focused on exploring and building the RWI (Real-World Identity) infrastructure in the Web3 world. We aim to transfer user data sovereignty from centralized data centers to the users themselves at the storage and computation level. Our team consists of professional cryptographers and developers with a strong pioneering spirit, continuously exploring the field of privacy identity with a focus on BUIDL.

Our motivation stems from the realization of self-sovereign digital identities in Web3. In the system we build, we enable the creation, use, and management of an entity's identity, independent and unconstrained by centralized organizations or states. Motivated by this, and in line with W3C standards, we have proposed solutions involving DID (Decentralized Identity Document), VC (Verifiable Credentials), and ZKP (Zero-Knowledge Proof). Users need not worry about personal data leaks; all private data remains in their control. When personal data is required, users can demonstrate their compliance with requirements using local zero-knowledge proof technology or VP (Verifiable Presentation), ensuring that no one, except the user, knows their data.

This document introduces our main infrastructure protocols and the related API usage. Through this document, you will understand our underlying protocols and how to use our accompanying SDK. In the SDK usage section, we provide various application scenarios to help you quickly get started and gain flexible mastery.

Welcome to join our journey, let's together create a realm of privacy in the Web3 world.


# Tech stack overview

In this section, I'll guide everyone through learning and understanding the overall technology stack architecture of zCloak. In the current design, we divide the overall architecture into four parts: the Identity Layer, the Storage Layer, the Computation Layer, and the Proof Layer. The relationship between these four layers is shown in Figure 1 below:

<figure><img src="https://967050719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeW0LAe3zF9y5q3OKwmiE%2Fuploads%2FIovVmjjacDBdLhvn4Paa%2Fimage.png?alt=media&amp;token=6990d514-9585-4741-b5db-198067d7ff95" alt=""><figcaption><p><em>Figure 1 zCloak Tech Stack Architecture</em></p></figcaption></figure>

**Identity Layer**

Let's delve into the first layer of the zCloak technology stack architecture - the Identity Layer. Our design intention is to build a personal privacy ecosystem in the Web3 world, enabling users to control their own data (referred to as self-carrying data). We aim to transform the usage scenarios of data into a transfer of trust, making the data usage process secure and reliable. Therefore, in choosing the technology stack for the Identity Layer, we have adopted concepts under the W3C standards, such as DID and VC.

DID, or Decentralized Identifier, can be understood as a unique identification ID for a device or an individual. VC, or Verifiable Credential, can be simply perceived as a card containing information, which is verified and endorsed, hence the term 'verifiable digital credential'. VP, or Verifiable Presentation, is a form of aggregating VCs for presentation and proving their correctness to others.

With a fixed identity identifier and a carrier for information, a communication channel is also needed, namely the message point-to-point encryption system. We utilize the KeyAgreement Key from DID to encrypt and decrypt the transmitted VC, ensuring that only the sender and receiver are privy to the specifics of the message; this point-to-point encrypted channel ensures the privacy and security of the communication.

**Storage Layer**

The second layer of the zCloak technology stack is the Storage Layer. Considering the need for backup of data related to the DID and VC systems to facilitate on-chain and off-chain indexing and queries, we have designed a storage architecture that combines the VDR (Verifiable Data Registry) structure from the W3C framework with Web3 scenarios. This design bifurcates storage into on-chain and off-chain components.

For the off-chain part, we have a database that acts as a caching layer. In tandem, we use Arweave for on-chain perpetual storage. The components involved in storage include ctype (Credential Type Structure), which allows users to freely create their own credentials. Additionally, the correspondence between DID and DID documents, as well as message data (point-to-point encrypted messages), are also stored.

This dual-layered storage approach ensures that essential data related to digital identities and credentials are securely backed up and easily accessible, both on-chain and off-chain, thereby enhancing the robustness and efficiency of the system.

**Computation Layer**

The third layer of the zCloak technology stack is the Computation Layer. Given the importance of securely using personal privacy data, we have adopted zero-knowledge proof computation as the method to ensure the security of data use. Specifically, for the ZK (Zero-Knowledge) VM (Virtual Machine), we utilize Polygon Miden, which is based on the STARK algorithm, along with the corresponding ZK programs.

In our design, the computation process related to ZK, including the generation of ZK Proofs, is centered around parameters selected from necessary fields within the VC (Verifiable Credentials). All these computations are carried out locally in the user's zkID-Wallet. This approach ensures that sensitive computations related to user privacy are processed in a secure and decentralized manner, right at the user level. By leveraging ZK proofs, we can validate data without exposing the underlying information, thus maintaining the user's privacy and data integrity.

**Proof Layer**

The fourth and final layer of the zCloak technology stack is the Proof Layer. In the previous Computation Layer, we have already obtained the ZK (Zero-Knowledge) Proofs through zero-knowledge proof computation. The design of this layer aims to create a closed loop for user operations, effectively utilizing the results of ZK Proofs.

In the Proof Layer, we use a zk-verifier program to validate the ZK Proofs. Following this validation, based on the outcomes, zkSBT (Zero-Knowledge Soulbound Tokens) are minted. These zkSBTs can then be used for various threshold operations by checking for the existence of such tokens.

An important aspect of this process is that users, through local computations, link the generated zkSBT with their VC (Verifiable Credentials). This is done without revealing specific details contained within the VC. Instead, they leverage zero-knowledge proof computation to demonstrate that their data meets certain conditions. This mechanism ensures that while user data compliance is verifiable, the privacy of the actual data remains intact.

Overall, this layer plays a crucial role in operationalizing the privacy and security features of the zCloak system, enabling users to interact in the Web3 environment with confidence in their data integrity and privacy.


# Protocol

The zCloak Network is currently implementing a DID (Decentralized Identity Document) and VC (Verifiable Credential) solution based on the W3C (World Wide Web Consortium) protocol standards. Building on this foundation, zCloak has further adapted and tailored these solutions to fit the specific scenarios and requirements of the Web3 environment. The following two documents will provide a detailed introduction to zCloak's DID and VC solutions from the protocol layer perspective. These documents will likely cover the technical aspects, implementation details, and the unique adaptations made by zCloak to align these solutions with the Web3 ecosystem.


# DID Specification

This document assumes that the readers already have some knowledge of W3C standards. For more information about the W3C DID (Decentralized Identity Document) aspect, readers can refer to this document: [W3C DID Core Specification](https://www.w3.org/TR/did-core/). (<https://www.w3.org/TR/did-core/>)

## **DID Architecture**

In this section, let's review the W3C standard's introduction to DID (Decentralized Identifier). DID represents a verifiable decentralized digital identity identifier, characterized by its globally unique and distinct nature. This concept is different from that of an Identity. An Identity emphasizes the concept tied to an individual, while an Identifier emphasizes a symbol or a sign. For example, an ID card can be seen as an Identity, whereas the unique ID number on the card is the Identifier - the specific element used to distinguish one person from another.

Now, let's get acquainted with the key components that make up the DID system:

**DID and DID URL**: A Decentralized Identifier, or DID, consists of three parts: the scheme header 'did', the DID method name, and a unique identifier specified by the DID method. The specific structure is illustrated in Figure 2.

<figure><img src="https://967050719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeW0LAe3zF9y5q3OKwmiE%2Fuploads%2FyTs90UiaSfERj2F5O0lc%2Fimage.png?alt=media&amp;token=e5154341-612f-43c4-b909-a2edd80f0c9f" alt=""><figcaption><p><em>Figure 1 Example of a DID</em></p></figcaption></figure>

In zCloak's DID design scheme, we have introduced our own DID method named "zk," hence the ZK DID. The identifier in this method is represented by a blockchain address. In our system, this results in two forms of DID presentation:

**DID for EVM (Ethereum Virtual Machine) Ecosystem:** This is similar to `did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea`. Here, the `zk` method is combined with an EVM-compatible blockchain address.

\
**DID for Non-EVM Ecosystems:** For ZK DIDs that are not part of the EVM ecosystem, the format is slightly different, such as `did:zk:sui:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea`. In this case, an additional segment (`sui` in this example) is included to specify the particular non-EVM blockchain or network.

A DID URL is an extension of the DID syntax, which includes additional components like paths, queries, and fragments. These are used to facilitate the location of specific resources. In the context of ZK DID, the most common form of DID URL is one that includes a fragment. For example, `did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0`. In ZK DID, such a URL is used to pinpoint a verification method, typically for executing various cryptographic functions.

**DID Subject**：DID Subject: The DID subject is the entity that is identified by the DID. It refers to the entity represented by the DID, which might or might not be the actual controller of the DID. In DID documents, this is indicated by the `id` attribute:

```json
{
    "id": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea"
}
```

**DID Document:** A DID document contains information about the DID, specifying the verification methods and services related to interactions with the DID subject. In the context of ZK DID, the document primarily expresses the verification methods associated with the DID subject, which typically include various public and private keys for different scenarios.

**DID Controller:** The DID controller is the entity that actually controls the DID, and this controller has the capability to modify the DID document. It's important to note that a DID can have multiple controllers, and the DID subject can be the controller of the DID or one of its controllers. In ZK DID, the design aligns the DID controller with the DID subject as a single entity. This means that the ZK DID has only one controller, who is also the subject of the ZK DID. In a DID document, the controller is identified using the `controller` attribute:

```json
{
    "id": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea",
    "controller": ["did:zk:0x0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea"]
}
```

**Verifiable Data Registry (VDR):** A VDR is a system designed to return the corresponding DID document based on a given DID. It can be any type of carrier, such as a database or some underlying systems. In the design of ZK DID, we use a combination of off-chain database caching and on-chain perpetual storage with Arweave to store the mapping relationships between DIDs and DID documents.

\
Based on the components described above, we can derive a DID architecture and a diagram illustrating the relationships between these components:

<figure><img src="https://967050719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeW0LAe3zF9y5q3OKwmiE%2Fuploads%2F94Os0VPSAED1zD6bBYJ7%2Fimage.png?alt=media&amp;token=4f1a2544-10df-4b67-93af-96780564096a" alt=""><figcaption><p><em>Figure</em> 2 <em>DID Architecture Overview and Component Relationships</em></p></figcaption></figure>

In the aforementioned diagram, we can see that the DID represents the DID subject, and structurally, the DID is a part of the DID URL, but it serves as a unique identifier for the DID subject. The most crucial content related to the DID is carried within the DID document. The mapping and linking relationship between the DID and the DID document are managed and stored by the Verifiable Data Registry (VDR). Considering that the DID subject may not always be the actual controller of the DID document, the role of the DID controller is distinctly outlined.

## **DID Document Core Concepts**

In DID architecture, the role of the DID document is pivotal, and understanding its concepts is fundamental to grasping the entire system. This section will introduce the core fields in the DID document, as understanding these will help in comprehending various actions related to DID and its interactions with VCs (Verifiable Credentials).

**Id:** This field is used to specify the DID of a particular DID subject.

**controller**：The actual controller of the DID, who is authorized to make changes to the DID document. In the design of ZK DID, both the `id` and `controller` fields use the DID of the DID subject.

**verificationMethod**：This is a set of cryptographic verification methods for specific scenarios, essentially a list of public keys that can be used to verify signatures and encrypt information. The value of this field includes the following sub-fields:

* id: Presented as a DID fragment.
* controller: The actual DID of the DID controller.
* type: The type of the current key. Currently supported types include `EcdsaSecp256k1VerificationKey2019`, `Ed25519VerificationKey2020`, and `X25519KeyAgreementKey2019`.
* publicKeyMultibase: The serialized public key in MULTIBASE data format.

For example, a `verificationMethod` entry might look like this:

```json
{
    "verificationMethod": [
        {
            "id": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0",
            "controller": [
                "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea"
            ],
            "type": "EcdsaSecp256k1VerificationKey2019",
            "publicKeyMultibase": "zcogm66QdXZm93BAcU7bLuaRJvJqegnDmSqQwUtZLP1zw"
        },
        {
            "id": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-1",
            "controller": [
                "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea"
            ],
            "type": "X25519KeyAgreementKey2019",
            "publicKeyMultibase": "zAymQAUELdLDq77H49NKmNs9kbuWbo2Ak23fJBzpNW3FQ"
        }
    ]
}
```

**authentication (optional)**：This relationship specifies how the DID subject can authenticate themselves, commonly used for logging into websites or participating in challenge-response protocols. If present, it must be a collection of one or more verification methods. In ZK DID, it's referenced by the `id` of a verification method, for example:

```json
{
    "authentication": [
        "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0"
    ]
}
```

**assertionMethod (optional)**：This relationship explains how the DID subject can express VC Claims, generally used in scenarios where an Attester issues a verifiable credential. Like `authentication`, it must be a collection of one or more verification methods if present, referenced by `id` in ZK DID, for example:

```json
{
    "assertionMethod": [
        "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0"
    ]
}
```

**keyAgreement (optional):** This relationship is used to establish encrypted communication channels for transmitting encrypted information. If present, it should be a collection of one or more verification methods, referenced by `id` in ZK DID, for example:

```json
{
    "keyAgreement": [
        "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-1"
    ]
}
```

**capabilityInvocation (optional):** This relationship indicates capabilities or permissions that can be invoked, such as executing specific operations or accessing certain resources, which could be external. For example, it specifies the methods used to update the DID document. In ZK DID, it's also a collection of one or more verification methods, referenced by `id`, for example:

```json
{
    "capabilityInvocation": [
        "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0"
    ]
}
```

\
**capabilityDelegation (optional)**：This relationship is used to delegate cryptographic capabilities to another party, such as delegating access to a specific HTTP API to a subordinate. It specifies the verification methods for the delegate and, like the others, is a collection of one or more verification methods in ZK DID, referenced by `id`, for example:

```json
{
    "capabilityDelegation": [
        "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0"
    ]
}
```

## **DID Application**

### Message System

In the W3C introduction to DID, the use of the keyAgreement key is described as constructing a message channel between DID and DID, in which the keyAgreement key pairs of the message sender and receiver are used, and the process involves the ECDH (Elliptic-curve Diffie-Hellman Key Exchange) process, which is shown in the following figure:

<figure><img src="https://967050719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeW0LAe3zF9y5q3OKwmiE%2Fuploads%2F4F3M4b6ZcLG6JDVeK3Ka%2Fimage.png?alt=media&amp;token=385949ca-9aae-4e09-8c64-52c00e7cf022" alt=""><figcaption><p>Figure 3 Explanation of Message channel principle</p></figcaption></figure>

First of all, it is clear that the Message channel is set up for transferring VC, VP and other data between DIDs. After clarifying the purpose, we can see from the above figure that when the sender encrypts the data, it will first use its own keyAgreement private key and the receiver's keyAgreement public key to compute a shared key k, and then encrypt the message to be delivered by this shared key k, and then send the encrypted message to the receiver. After receiving the encrypted data, the receiver will first use its own keyAgreement private key and the sender's keyAgreement public key to calculate a shared key k, and then decrypt the encrypted message with the shared key. The above process is the underlying principle of the Message channel between DIDs.

## **ZK DID Example**

* EVM-based DID in ABNF:

```Plain
did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea
```

* non-EVM-based DID in ABNF:

```Plain
did:zk:sui:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea
```

* ZK DID Document:

```json
{
            "@context": [
                "https://www.w3.org/ns/did/v1"
            ],
            "id": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea",
            "controller": [
                "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea"
            ],
            "verificationMethod": [
                {
                    "id": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0",
                    "controller": [
                        "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea"
                    ],
                    "type": "EcdsaSecp256k1VerificationKey2019",
                    "publicKeyMultibase": "zcogm66QdXZm93BAcU7bLuaRJvJqegnDmSqQwUtZLP1zw"
                },
                {
                    "id": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-1",
                    "controller": [
                        "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea"
                    ],
                    "type": "X25519KeyAgreementKey2019",
                    "publicKeyMultibase": "zAymQAUELdLDq77H49NKmNs9kbuWbo2Ak23fJBzpNW3FQ"
                }
            ],
            "authentication": [
                "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0"
            ],
            "assertionMethod": [
                "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0"
            ],
            "keyAgreement": [
                "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-1"
            ],
            "capabilityInvocation": [
                "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0"
            ],
            "capabilityDelegation": [
                "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea#key-0"
            ],
            "service": [],
}
```


# VC Specification

Before diving into this section, understanding VC (Verifiable Credential) necessitates familiarity with the DID concept. Therefore, please ensure you are acquainted with the relevant chapters and content about DID.

&#x20;Note: the VCs mentioned here are assumed to be Private VCs by default. The main difference between Private and Public VCs is in the construction of the user data Merkle tree; the leaf nodes in Public VCs are not salted, and Public VCs are intended for public display purposes, hence they are not elaborated on extensively here.

## **Overview**

Before exploring VC, let's briefly discuss the concept of credentials. Credentials are common in our daily lives. In the physical world, they can be a driver's license to prove driving skills, a diploma to certify educational level, or an ID card to verify legal identity in a country. However, in the digital world, it's challenging to represent these physical credentials, leading to a gap in the convenience that real-world certificates offer.

To address this, the W3C proposed a standard for credentials in the digital realm that are secure, privacy-respecting, and machine-verifiable, known as Verifiable Credentials.

In the privacy identity world built by zCloak, these data are referred to as self-carried data, meaning only the user themselves actually possess the VC, fully transferring data ownership to the user. For the Web3 context, VCs are adapted to blockchain application scenarios based on W3C standards. In simple terms, VCs can be understood as various cards in the blockchain world. A VC could be a POAP (Proof of Attendance Protocol), an NFT (Non-Fungible Token), or even just a simple card. However, each card follows a set of digital signatures that validate the data as endorsed by the issuer and verify its authenticity. To align with the Ethereum ecosystem, the cryptographic applications used in VCs are also adapted for Ethereum compatibility.

## **VC Architecture**

Continuing with the W3C standard's interpretation of VC (Verifiable Credentials), our VCs at zCloak also adopt a similar structure. The basic structure of a VC as per our implementation is depicted in the following Figure 1.

<figure><img src="https://967050719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeW0LAe3zF9y5q3OKwmiE%2Fuploads%2FycEHIR42rsSwcHHmskGZ%2Fimage.png?alt=media&amp;token=ceae7971-46d9-44c0-9195-9712757b5170" alt="" width="375"><figcaption><p><em>Figure1 VC Architecture under W3C Standards</em></p></figcaption></figure>

From the basic structure outlined above, we can see that a VC (Verifiable Credential) primarily comprises three parts:

1. VC Metadata: This section includes the basic information of the VC, such as:
   1. Context (context): The standards or protocols that the VC adheres to.
   2. Issuer (issuer): The address of the entity that issues the VC.
   3. Type (type): The type or category of the VC.
   4. Issuance Date (issuanceDate): The date when the VC was issued.
2. VC Claim: This part expresses the specific claims made by the VC. The content here is often presented in a name-value format. The structure of this part is typically represented using the Credential Subject structure, detailing the specific attributes or claims about the credential subject (the individual or entity the VC pertains to).
3. Proof: The proof section is critical as it transforms an ordinary credential into a verifiable one. The Proof mainly contains the digital signature of the VC issuer. The signature algorithm is aligned with Ethereum rules, utilizing the ECDSA (Elliptic Curve Digital Signature Algorithm) for generation. This ensures the integrity and authenticity of the VC, allowing for secure verification.

## **VC Core Concepts**

Let's briefly introduce some of the core fields in VC (Verifiable Credentials), with adaptations specific to Web3 use cases, as compared to the standard W3C model.**ctype (Credential Type):** In the original W3C VC standard, this is represented by the `type` field, but in our adaptation, we have transformed it into the `ctype` field. There are two main differences from the W3C standard:

1. **Emphasis on Type Entity:** We emphasize the structured content of the credential. For each distinct `ctype`, there is a unique `ctypehash` derived from hashing the necessary fields of the `ctype` structure. Since `ctype` is a global concept, the complete `ctype` structure can be retrieved using the `ctypehash`.
2. **Publisher Endorsement:** We introduce the concept of publisher endorsement in the issuance of `ctype`. Each publisher is required to sign the `ctype` hash before issuing it, using the ECDSA (Elliptic Curve Digital Signature Algorithm) which is consistent with Ethereum's algorithm. In our VCs, the `type` field is replaced by `ctype`, with its value being the `ctypehash`.

These adaptations make the VC more suitable for Web3 scenarios, ensuring that the credential is not only verifiable but also carries a structured and endorsed type that is recognizable and consistent within the decentralized ecosystem.

**credentialSubject**：This is the main subject part of the credential. It expresses one or more subjects' claims in a key-value pair format. For example:

```json
{
    "credentialSubject": {
        "name": "vss-claimer",
        "age": 23,
        "company_name": "Test"
    },
}
```

**digest**：This serves as the unique identifier of the VC, corresponding to the `id` field in the W3C VC standard. Unlike a typical UUID, the calculation of `digest` is more practical and unique. The digest considers the credential subject, holder DID, ctype, expiration date, and issuance date. When generating the proof signature for the VC, the digest is a core component of the signature message.

\
**credentialSubjectHashes**：These are the salted hash values of the leaf nodes in the Merkle tree built from the user data in the credential subject. For instance:

```json
{
    "credentialSubject": {
        "name": "vss-claimer",
        "age": 23,
        "company_name": "Test"
    },
    "credentialSubjectHashes": [
        "0x9c9a50d930a46ef4fa884de415e250200ee8aec0524c9fded3c5e9c499ffc987",
        "0x982225bf5561e4e35e71472b09f4eac29f2fa227383df6764011cb3bf5d94789",
        "0x9083230a121ae6e136050ccf21a9a479aa812ad65318a68325f2e839e1cd6336"
    ],
}
```

**credentialSubjectNonceMap**：This maps the **encoded user data** to its nonce. The nonce is used for salting user data to generate leaf nodes in the construction of the Merkle tree.

```json
{
    "credentialSubject": {
        "name": "vss-claimer",
        "age": 23,
        "company_name": "Test"
    },
    "credentialSubjectHashes": [
        "0x9c9a50d930a46ef4fa884de415e250200ee8aec0524c9fded3c5e9c499ffc987",
        "0x982225bf5561e4e35e71472b09f4eac29f2fa227383df6764011cb3bf5d94789",
        "0x9083230a121ae6e136050ccf21a9a479aa812ad65318a68325f2e839e1cd6336"
    ],
    "credentialSubjectNonceMap": {
        "0x8e60375533557ac1f3235750024e04c194c4b7732b81a6a92d033a8167b85763": "0xb5744ef1a613765da5960e4aae74ff4672e4d71c9bd404f0d5a9b5c1aa89ec35",
        "0x2d4e0ae8a576732fa15b0bdb0c7d7c36284657a18fdae95ee32439383dfe720b": "0x9920b9dd7d4165b655f3a03e57df58905a33e1a1257a7595fbc60c54eceb6365",
        "0x121af31876dce595e939b017837a144c953fe633f132f99e36e0f66a486dd134": "0x2d0b24fa725bc2d1fd27b891bc9a00f9a6f715125af3ff90e960e64d56a26fac"
    }
}
```

**Hasher**：This cryptographic hash method includes an array of two hash methods. The first hash method is used to encode credentialSubject data and build the VC Merkle tree, while the second is used for computing the hash for the VC digest.

```json
{
    "hasher": [
        "RescuePrimeOptimized",
        "Keccak256"
    ],
}
```

\
**Verifiable Data Registry (VDR):** Similar to the VDR design in the DID system, this is used for backing up encrypted VCs. In the zCloak VC system, the VDR is designed as a point-to-point asymmetric encrypted message system. This message channel is primarily used for transmitting VCs and VPs, but it also supports the transfer of other data types.

**VC Merkle Tree**：The Merkle tree for VC fields is built using the data in the credentialSubject to highlight the VC's verifiability and tamper-proof nature.To further illustrate the construction of the VC Merkle Tree, let's use the example VC mentioned earlier:

```json
{
    "@context": [
        "https://www.w3.org/2018/credentials/v1"
    ],
    "version": "2",
    "ctype": "0xca9b3d79ca4326d0c05caf60d9b6a0a405bacc2fabf61c230f3f2cc0addd4593",
    "issuanceDate": 1700790481800,
    "credentialSubject": {
        "name": "vss-claimer",
        "age": 23,
        "company_name": "Test"
    },
    "issuer": [
        "did:zk:0xB16FEfFaED0630F4C580a58ae0349C68609A6fDc"
    ],
    "holder": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea",
    "hasher": [
        "RescuePrimeOptimized",
        "Keccak256"
    ],
    "digest": "0xad8c4ad09320db11d6b5bd2266ab93a9b92c7fff39c6821e951017b1a31f9001",
    "proof": [
        {
            "type": "EcdsaSecp256k1SignatureEip191",
            "created": 1700790481841,
            "verificationMethod": "did:zk:0xB16FEfFaED0630F4C580a58ae0349C68609A6fDc#key-0",
            "proofPurpose": "assertionMethod",
            "proofValue": "z9kmgzHe2fhSH5NFTeFRNfTfKr3bLYkXvpxJhYkqTfWWStUwPrRUhU7Kr2UiZ12LyHeGkF2bjEYYs23BAFesDU52zb"
        }
    ],
    "credentialSubjectHashes": [
        "0x9c9a50d930a46ef4fa884de415e250200ee8aec0524c9fded3c5e9c499ffc987",
        "0x982225bf5561e4e35e71472b09f4eac29f2fa227383df6764011cb3bf5d94789",
        "0x9083230a121ae6e136050ccf21a9a479aa812ad65318a68325f2e839e1cd6336"
    ],
    "credentialSubjectNonceMap": {
        "0x8e60375533557ac1f3235750024e04c194c4b7732b81a6a92d033a8167b85763": "0xb5744ef1a613765da5960e4aae74ff4672e4d71c9bd404f0d5a9b5c1aa89ec35",
        "0x2d4e0ae8a576732fa15b0bdb0c7d7c36284657a18fdae95ee32439383dfe720b": "0x9920b9dd7d4165b655f3a03e57df58905a33e1a1257a7595fbc60c54eceb6365",
        "0x121af31876dce595e939b017837a144c953fe633f132f99e36e0f66a486dd134": "0x2d0b24fa725bc2d1fd27b891bc9a00f9a6f715125af3ff90e960e64d56a26fac"
    }
}
```

Based on the description of the `credentialSubject`, `credentialSubjectNonceMap`, and `credentialSubjectHashes` fields, let's look at the rules for constructing the Merkle tree:

1. **Extracting Values from credentialSubject**: Take each value from the `credentialSubject`, and use the order of fields in `credentialSubject` (from front to back) to determine the left-to-right order for building the Merkle tree.
2. **Encoding and Mapping**: Encode each extracted value into HexString format. These encoded values correspond to each key in `credentialSubjectNonceMap`.
3. **Creating Leaf Nodes with Nonces and Hashing**: For each encoded data, find its corresponding nonce (randomly generated and mapped in `credentialSubjectNonceMap`). Concatenate the encoded data with its nonce and hash this concatenated value using the first hash method specified in `Hasher`. The result of this hashing process forms the leaf nodes of the Merkle tree.
4. **Building the Tree**: Use the same hashing method as in the previous step to construct the other nodes, combining them to form a complete Merkle tree.

Following these rules, we can construct the Merkle tree as shown in the figure below (Figure 2):

<figure><img src="https://967050719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeW0LAe3zF9y5q3OKwmiE%2Fuploads%2Fo7Vr2bcji64kzoNrsSle%2Fimage.png?alt=media&amp;token=4bf11aa7-23f0-40c6-a834-8d7ba5167bea" alt=""><figcaption><p><em>Figure2 (Private) VC Merkle Tree</em></p></figcaption></figure>

From the process of constructing the Merkle tree as described, we can understand that the Merkle tree is a crucial structure in a VC (Verifiable Credential). This is reflected at the field level as `roothash`, which is the root hash of the tree. The `roothash` provides a snapshot that represents the data behind each leaf node. In the context of the zCloak system, this `roothash` plays a significant role in the computation of the `digest` field of the VC.

\
The calculation of the `digest` field is multifaceted. It includes not only the `roothash` but also incorporates the holder's DID, the expiration date, `ctypeHash`, and the issuance date. This comprehensive inclusion gives the `digest` field a multi-dimensional meaning, reflecting various aspects of the VC such as its origin, validity, and content. Therefore, the `digest` serves as a unique identifier for the VC.

**presentations**：The concept of VP (Verifiable Presentation) is explained by the W3C as "data derived from one or more verifiable credentials, issued by one or more issuers and shared with a verifier." Simply put, it's a structure for presenting credentials, designed to aggregate and present multiple verifiable credentials. The typical use case of a VP is in its verifiable form, where it's utilized to collect multiple verifiable credentials. I'll briefly explain its workflow with the help of an illustration (Figure 3):

<figure><img src="https://967050719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeW0LAe3zF9y5q3OKwmiE%2Fuploads%2FyNGqayCDfqp8N56z53Bo%2Fimage.png?alt=media&amp;token=68147cdc-ec08-4eaa-bbab-6626939b85e2" alt=""><figcaption><p><em>Figure 3: Issuing VC and Presenting VP Process</em></p></figcaption></figure>

Imagine a scenario as depicted in the illustration. A Holder, who is a graduate of a university, receives a graduation certificate VC from the university (the Issuer) on their graduation day. This certificate contains all relevant graduation information about the Holder. One day, the university invites its alumni to attend a post-season basketball game. The Verifier in this scenario is the university's security guard. When the Holder presents their graduation certificate VC in the form of a VP to the Verifier, the Verifier, upon verifying that the VC is a genuine graduation certificate issued by the university, allows the Holder to enter.

\
From this description, it's evident that VP is specifically used for presenting VCs. Under the W3C standards, two types of VP are defined: VP and VP\_SelectiveDisclosure. For enhanced privacy protection, we propose a third type: VP\_Digest.

* VP: This type presents the entire VC to the Verifier, meaning all information in the Holder's VC is disclosed.
* VP\_SelectiveDisclosure: This type allows for selective disclosure, revealing only parts of the credentialSubject information in the VC to the Verifier.
* VP\_Digest: This type presents only the VC's digest to the Verifier. Combined with checking the ctype, it verifies that the Holder possesses a certain type of VC without disclosing the VC's content.

\
Each of these presentation types serves different purposes and offers varying levels of privacy and information disclosure, making the system flexible and adaptable to various verification needs.

## **Concrete Lifecycle**

In this section, you'll learn about the usage lifecycle of VCs (Verifiable Credentials) within the VC system. There are two primary modes of VC usage: the request mode and the issue mode. Despite their differences, both modes typically follow a common trajectory in their usage:

1. **Issuing One or More VCs:** The initial step involves the creation and issuance of one or more VCs by an issuer. These VCs contain specific claims about the credential subject (the holder).
2. **Storing VCs in a VC Repository:** Once issued, these VCs are stored in a VC repository, which could be a digital wallet or another form of secure storage. This repository ensures the safekeeping and accessibility of the VCs for future use.
3. **Combining VCs into a VP for Verification:** When needed, the holder combines one or more VCs into a VP (Verifiable Presentation). This VP is then provided to a verifier. The VP can be tailored to the specific verification requirements, such as including full disclosure, selective disclosure, or just the digest of the VCs, depending on the level of privacy and information needed.
4. **Verification of the Received VP by the Verifier:** The final step involves the verifier checking the received VP. This verification process confirms the authenticity and validity of the claims made in the VCs contained within the VP.

To provide a detailed explanation of the entire lifecycle, let's delve into these two different usage modes:

### **Request Mode**

<figure><img src="https://967050719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeW0LAe3zF9y5q3OKwmiE%2Fuploads%2F4PbZTk4Me0nHtTsRLPpB%2Fimage.png?alt=media&amp;token=bcbb781e-520d-4df9-b215-9a7496ca442e" alt=""><figcaption><p><em>Figure 4 VC Request Mode</em></p></figcaption></figure>

In the Request Mode, the user (Holder) assumes the role of a Claimer, initiating a request for a VC (Verifiable Credential). The Attester decides whether to issue the VC to the Claimer, using the `assertionMethod` in their DID for issuance. The Verifier is responsible for verifying the correctness of the VP (Verifiable Presentation) sent by the Claimer.

**Request Mode Workflow:**

1. **Claimer Submits Request:** The Claimer fills in personal data and sends a request to the Attester.
2. **Attester's Decision:** Upon receiving the request, the Attester reviews the Claimer's data, decides whether to issue the VC, and then sends an affirmative response with the VC or a rejection response.
3. **Claimer Prepares VP:** The Claimer, upon receiving the VC, combines it into a VP and sends it to the Verifier.
4. **Verifier Validates VP:** The Verifier checks the VP and communicates the results to the Claimer.

This mode can be applied in DAO (Decentralized Autonomous Organization) governance, where users submit their blockchain addresses and names to DAO administrators. The administrators verify the identities and issue appropriate permission VCs to qualified DAO members. These VCs can then serve as entry requirements for participating in DAO activities.

### **Issue Mode**

<figure><img src="https://967050719-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FeW0LAe3zF9y5q3OKwmiE%2Fuploads%2F5hRbDp5UsdjPKVKSe69M%2Fimage.png?alt=media&amp;token=f95f6faf-bed8-44e5-aaa5-2eb88829640c" alt=""><figcaption><p><em>Figure 5 VC Issue Mode</em></p></figcaption></figure>

In the Issue Mode, the user's role as a Holder remains the same, but they passively receive the VC and construct a VP. The Issuer fills in the VC Claim, sends the VC directly to the Holder without requiring a request, and the Verifier checks the VP sent by the Holder and provides feedback on the validation.

**Issue Mode Workflow:**

1. **Issuer Creates VC:** The Issuer fills in the VC Claim, constructs the VC, and sends it to the Holder.
2. **Holder Receives and Prepares VP:** The Holder receives the VC, creates a VP, and sends it to the Verifier.
3. **Verifier Validates VP:** The Verifier checks the VP and informs the Holder of the results.

Compared to the Request Mode, the Issue Mode is more straightforward, directly delivering the VC to the Holder. It is well-suited for issuing POAPs, membership cards, and can be applied in scenarios like proof of attendance for DAO-governed events. The VC can also be used for benefits in future events, such as attendance discounts.

## **VC Application**

### **zkID Card**

The zkID Card is an upper-level application of VC, which can be prepared and issued through the zkID Card Center. In the Card Center platform, each Card is essentially a VC. In the Card Maker, each template created is a structure containing ctype, along with other setting fields for the template. The purpose of designing this application is to facilitate users to better use and understand our product. In this system, the template corresponds to ctype, and the card corresponds to VC. This approach simplifies the user experience by providing a clear, visual representation of VCs and their types.

### **zkSBT**

zkSBT is a post-operation based on VC, working in conjunction with our zkID Wallet to perform zero-knowledge proof validation locally at the user's end. The result of this validation is used to generate a corresponding SBT (Soulbound Token). Let's delve into an example to understand this process better:

Alice undergoes a KYC process on a platform. The KYC provider issues her a VC containing her KYC information. She then plans to participate in an adult-only DeFi activity, which requires an adult zkSBT as an entry threshold. Using her zkID Wallet, Alice generates a zero-knowledge proof (zkp), which calculates necessary fields from her KYC VC, such as age. After completing the zero-knowledge proof process, the zkID Wallet produces outputs related to the zkVM and a verdict on whether she is over 18. Alice then runs a zero-knowledge proof validation program on her local machine. Once verified, the application automatically mints a zkSBT for Alice, indicating she is an adult. With this zkSBT, Alice can happily participate in the DeFi activity.

All computations and certifications related to zkp in the above process are performed locally on the user's device. The zero-knowledge proof program is also embedded in the user's local wallet. Managing this process is entirely under the user's control, similar to managing a wallet, and is executed locally, ensuring privacy and security.

## **VC Example**

1. Private VC

```json
{
    "@context": [
        "https://www.w3.org/2018/credentials/v1"
    ],
    "version": "2",
    "ctype": "0xca9b3d79ca4326d0c05caf60d9b6a0a405bacc2fabf61c230f3f2cc0addd4593",
    "issuanceDate": 1700790481800,
    "credentialSubject": {
        "name": "vss-claimer",
        "age": 23,
        "company_name": "Test"
    },
    "issuer": [
        "did:zk:0xB16FEfFaED0630F4C580a58ae0349C68609A6fDc"
    ],
    "holder": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea",
    "hasher": [
        "RescuePrimeOptimized",
        "Keccak256"
    ],
    "digest": "0xad8c4ad09320db11d6b5bd2266ab93a9b92c7fff39c6821e951017b1a31f9001",
    "proof": [
        {
            "type": "EcdsaSecp256k1SignatureEip191",
            "created": 1700790481841,
            "verificationMethod": "did:zk:0xB16FEfFaED0630F4C580a58ae0349C68609A6fDc#key-0",
            "proofPurpose": "assertionMethod",
            "proofValue": "z9kmgzHe2fhSH5NFTeFRNfTfKr3bLYkXvpxJhYkqTfWWStUwPrRUhU7Kr2UiZ12LyHeGkF2bjEYYs23BAFesDU52zb"
        }
    ],
    "credentialSubjectHashes": [
        "0x9c9a50d930a46ef4fa884de415e250200ee8aec0524c9fded3c5e9c499ffc987",
        "0x982225bf5561e4e35e71472b09f4eac29f2fa227383df6764011cb3bf5d94789",
        "0x9083230a121ae6e136050ccf21a9a479aa812ad65318a68325f2e839e1cd6336"
    ],
    "credentialSubjectNonceMap": {
        "0x8e60375533557ac1f3235750024e04c194c4b7732b81a6a92d033a8167b85763": "0xb5744ef1a613765da5960e4aae74ff4672e4d71c9bd404f0d5a9b5c1aa89ec35",
        "0x2d4e0ae8a576732fa15b0bdb0c7d7c36284657a18fdae95ee32439383dfe720b": "0x9920b9dd7d4165b655f3a03e57df58905a33e1a1257a7595fbc60c54eceb6365",
        "0x121af31876dce595e939b017837a144c953fe633f132f99e36e0f66a486dd134": "0x2d0b24fa725bc2d1fd27b891bc9a00f9a6f715125af3ff90e960e64d56a26fac"
    }
}
```

2. Public VC

```json
{
    "@context": [
        "https://www.w3.org/2018/credentials/v1"
    ],
    "version": "2",
    "ctype": "0xca9b3d79ca4326d0c05caf60d9b6a0a405bacc2fabf61c230f3f2cc0addd4593",
    "issuanceDate": 1700637199861,
    "credentialSubject": {
        "name": "vss-claimer",
        "age": 23,
        "company_name": "Test"
    },
    "issuer": [
        "did:zk:0xB16FEfFaED0630F4C580a58ae0349C68609A6fDc"
    ],
    "holder": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea",
    "hasher": [
        "Keccak256",
        "Keccak256"
    ],
    "digest": "0x736d5b904fa700d9ab58d215b45b1e512fce56b1279fc647f48d414509463d47",
    "proof": [
        {
            "type": "EcdsaSecp256k1SignatureEip191",
            "created": 1700637199899,
            "verificationMethod": "did:zk:0xB16FEfFaED0630F4C580a58ae0349C68609A6fDc#key-0",
            "proofPurpose": "assertionMethod",
            "proofValue": "z4GsH1Kzn5iZrP6s42dPHtub4mFS6Ze9ZTRSdv5ZGuSE9zDmUKD4hDtJZwcKsraV7UncMYQTC3hPDjzzDT2yFgQiqM"
        }
    ]
}
```

3. VP

```json
{
    "@context": [
        "https://www.w3.org/2018/credentials/v1"
    ],
    "version": "1",
    "type": [
        "VP"
    ],
    "verifiableCredential": [
        {
            "@context": [
                "https://www.w3.org/2018/credentials/v1"
            ],
            "version": "2",
            "ctype": "0xca9b3d79ca4326d0c05caf60d9b6a0a405bacc2fabf61c230f3f2cc0addd4593",
            "issuanceDate": 1700790481800,
            "credentialSubject": {
                "name": "vss-claimer",
                "age": 23,
                "company_name": "Test"
            },
            "issuer": [
                "did:zk:0xB16FEfFaED0630F4C580a58ae0349C68609A6fDc"
            ],
            "holder": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea",
            "hasher": [
                "RescuePrimeOptimized",
                "Keccak256"
            ],
            "digest": "0xad8c4ad09320db11d6b5bd2266ab93a9b92c7fff39c6821e951017b1a31f9001",
            "proof": [
                {
                    "type": "EcdsaSecp256k1SignatureEip191",
                    "created": 1700790481841,
                    "verificationMethod": "did:zk:0xB16FEfFaED0630F4C580a58ae0349C68609A6fDc#key-0",
                    "proofPurpose": "assertionMethod",
                    "proofValue": "z9kmgzHe2fhSH5NFTeFRNfTfKr3bLYkXvpxJhYkqTfWWStUwPrRUhU7Kr2UiZ12LyHeGkF2bjEYYs23BAFesDU52zb"
                }
            ],
            "credentialSubjectHashes": [
                "0x9c9a50d930a46ef4fa884de415e250200ee8aec0524c9fded3c5e9c499ffc987",
                "0x982225bf5561e4e35e71472b09f4eac29f2fa227383df6764011cb3bf5d94789",
                "0x9083230a121ae6e136050ccf21a9a479aa812ad65318a68325f2e839e1cd6336"
            ],
            "credentialSubjectNonceMap": {
                "0x8e60375533557ac1f3235750024e04c194c4b7732b81a6a92d033a8167b85763": "0xb5744ef1a613765da5960e4aae74ff4672e4d71c9bd404f0d5a9b5c1aa89ec35",
                "0x2d4e0ae8a576732fa15b0bdb0c7d7c36284657a18fdae95ee32439383dfe720b": "0x9920b9dd7d4165b655f3a03e57df58905a33e1a1257a7595fbc60c54eceb6365",
                "0x121af31876dce595e939b017837a144c953fe633f132f99e36e0f66a486dd134": "0x2d0b24fa725bc2d1fd27b891bc9a00f9a6f715125af3ff90e960e64d56a26fac"
            }
        }
    ],
    "id": "0xc7d3fc7516c46e96f1b3a2e06b5b82f8ad381188809a874c607bb1f27c4787f3",
    "proof": {
        "type": "EcdsaSecp256k1SignatureEip191",
        "created": 1700790916674,
        "verificationMethod": "did:zk:0xE5b8641d32a434BF3B5E6Ea6AFfdA1B56c558eea",
        "proofPurpose": "controller",
        "proofValue": "zNm9H3ZQxabMnqiddNVamqph9avfkNGv5MQuQBBBAKbo4phgqA1sUSPupgFLhBbCAZDzXJFf99snEYFFDj2nXoF9ZJ",
        "challenge": "0xb457f6bf088fa4bce7019f9395a31285d7aadb2517eb1b34c38586f419a17539"
    },
    "hasher": [
        "Keccak256"
    ]
}
```


# Glossary

## DID

DID (Decentralized Identification) is a verifiable decentralized digital identity identifier that represents its globally unique and unique characteristics. Similar to student ID.

## VC

VC (Verifiable Credential) is a verifiable digital credential, which is a descriptive statement issued by an entity (such as a trusted organization, DAO organization, government system, or business organization) to endorse certain attributes of another entity, in order to prove that certain attributes of its owner are true and trustworthy. VC is similar to a student card issued by a university, which is issued to students by the school.

## VP

VP (Verifiable Presentation) is a verifiable presentation used to aggregate one or more verifiable credentials. VP is a data structure that aggregates VC and is used to present VC related information to others. VP includes three types: full-text presentation, selective presentation, and abstract presentation. VP is similar to a student ticket for a sports game, containing some student information.

## CType

CType (CredentialType) refers to the credential type, where cType specifies which fields the credential contains and the configuration information (type, etc.) of these fields. CType is similar to the specific field structure that forms a student card, used for the process of printing student cards before students enter school.

## Holder

Holder is the holder of VC, and the applicable context is the Issue mode of VC. Holder is similar to the student themselves, holding a student card issued by the school.

## Issuer

Issuer is the issuer of a VC, usually played by trusted organizations such as DAOs, governments, and industry associations, and its context is generally used in the issue model of a VC. The issuer is the endorser of the VC and is responsible for the issued VC. Issuers are similar to school organizations that issue student ID cards to students in their own school.

## Claimer

Claimer is the requester of VC, and can also be the holder of VC, applicable to the request mode of VC. Claimer pre-fills in the content for issuing VC and submits it to the Attender for review. After the Attender approves the review, they will provide it to the,Claimer issues VC. Claimer is similar to an intern, requesting the internship company to issue an internship certificate after the internship period ends.

## Attester

Attester is the reviewing party of the Claim request and the issuing party of the VC, usually played by trusted organizations such as DAOs, governments, etc. The applicable context of the Attender is the VC Request model. Attester is similar to a company where interns intern. After completing their internship, the intern will request the company to issue an internship certificate. The internship company will review the intern's situation and decide whether to issue the internship certificate.

## Verifier

Verifier is the verifier and receiver of the VP, and will verify the correctness of the VP. The holder of the VC shares it with the Verifier in the form of a VP for verification, to indicate that they hold the VC. The applicable context of Verifier is VP sharing. Verifier is similar to a school gatekeeper. Students who want to enter the school need to present their student ID card (VC) to the gatekeeper in some form, and the gatekeeper verifies the student's identity before releasing them.

## Message

A point-to-point asymmetric encryption channel used for transmitting VC, VP, and other data structures between two DID entities, where the transmitted data will be encrypted by the keyAgreement public key of the receiver DID.

## Card

ZkID Card is a concrete embodiment of VC structure. Cards can be issued and prepared in Card Center. Users can participate in the entire lifecycle of VC as any identity in Card Center.

## Template

Template is an extension structure of the CType structure. Setting a template is a prerequisite step when issuing a card, and the process can also be completed in Card Center.


# Guides

In this section, the document walks you through different scenarios for using our SDK, and the scenarios that appear in each of the following subsections are the ones that appear most frequently in our protocols, and will help you solve most of your problems. All code blocks in the following tutorials are coming from this repository: [zkid-sdk-example](https://github.com/zCloak-Network/zkid-sdk-example).


# did

In this tutorial, you will learn how to generate DIDs by generating randomized mnemonics and uploading the DID documents to the VDR via the interface.

> Complete code example: [zkid-sdk-example /src/did/createDID.ts](https://github.com/zCloak-Network/zkid-sdk-example/blob/sdk-v2/src/did/createDID.ts)

## Tutorial

1. Initialize @noble cryptographic library and wasm;

```typescript
await initCrypto();
```

2. Generate random mnemonics;

```typescript
const mnemonic = mnemonicGenerate(12);
```

3. Generate DID through mnemonics;

```typescript
const keyring = new Keyring();
const did = keys.fromMnemonic(keyring, mnemonic, "ecdsa");
```

In the process of generating DIDs from mnemonic, the controller key and the key pairs of two different verification methods need to be managed by keyring structure.

4. Upload DID Document to VDR;

```typescript
const doc = await did.getPublish();
await registerDidDoc(doc);

// src/utils/didHelpers.ts
export async function registerDidDoc(
  didDoc: DidDocument,
  url = process.env.BASE_URL
) {
  const res = await axios.post(`${url}/did`, { didDocument: didDoc });

  if (res.data.code === 200) {
    console.log(`Success: DID Document Registerd (${didDoc.controller})`);
  } else {
    console.log(`ERROR: ${res.data.message}`);
  }
}
```

Uploading a DID document to the VDR requires two steps. First of all, you need to use your own controller key to sign the DID document, and the signature-related information will be appended to the back of the DID document structure, and then initiate a request to the RESTful API interface to send the structure to the server for storage and processing, which will be deposited into the database with Arweave.

Well, through the above steps, you will have mastered how to generate a DID and store it into VDR.


# vc operation


# claim-attest

Assume a scenario where if you are the initiator of a contest, a contestant can claim an entry ticket, the contestant fills out the entry information and then initiates a review request to you, and you review and approve the contestant and issue an entry ticket to the contestant who meets the requirements.

So in the above scenario, the contestant is Claimer and you (the initiator of the contest) are in the role of Attester. Claimer fills out the request and initiates a request to Attester to award a VC, and Attester reviews the request and decides whether or not to award a VC to Claimer.

The VC issuance scenario described in the above procedure is the request mode of VC. In the following tutorials, you will learn how to initiate a VC issuance request to an Attester as a Claimer, respond to the request and construct a VC as an Attester, and endorse a VC as an Attester in conjunction with other Attesters. The following is a three-part introduction to each of the above three scenarios.


# claim

In this tutorial, we will simulate a Claimer to make a VC issuance request to a specified Attester with the help of SDK.

> Complete code example: [zkid-sdk-example /src/claim-attest/claim.ts](https://github.com/zCloak-Network/zkid-sdk-example/blob/sdk-v2/src/claim-attest/claim.ts)

## Tutorial

1. Initialize @noble cryptographic library and wasm;

```typescript
await initCrypto();
```

2. Get the DID objects of claimer and attester;

```typescript
// get claimer DID object from mnemonic
const keyring = new Keyring();
const claimer = keys.fromMnemonic(
  keyring,
  process.env.CLAIMER_MNEMONIC as string,
  "ecdsa"
);

// get attester DID object from DidDocument
const attesterDidDoc = await resolver.resolve(attesterDidUrl);
const attester = fromDidDocument(attesterDidDoc);

// src/utils/resolverHelper.ts
export const resolver = new ArweaveDidResolver();
```

The above sample code presents the ways to recover the DID object are: through the mnemonic recovery and through the DID document recovery. The main APIs involved are:

* `fromMnemonic`, which recovers the DID object by means of a mnemonic, takes as mandatory arguments a keyring and a mnemonic in the form of a string, the keyring being the structure that manages the keypair;

```typescript
fromMnemonic(keyring: KeyringInstance, mnemonic: string, signingKeyType?: 'ecdsa' | 'ed25519', index?: number)
```

* `fromDidDocument`, which recovers the DID object by means of a DID document, takes didDocuemnt as mandatory arguments. DID documents are obtained through the resolver's `resolve` API;

```typescript
fromDidDocument(document: DidDocument, keyring?: KeyringInstance)
```

3. Get ctype object from ctype hash;

```typescript
const ctype: CType = await getCtypeFromHash(ctypeHash);

// src/utils/ctypeHelper.ts
export async function getCtypeFromHash(
  hash: string | undefined,
  url = process.env.BASE_URL
): Promise<CType> {
  if (hash === undefined) {
    throw new Error("ctype hash undefined !!!");
  }

  const res = await axios.get(`${url}/ctype?${qs.stringify({ id: hash })}`);
  if (res.status !== 200) {
    throw new Error(`ctype query failed ${hash}`);
  }
  const ctype: CType = res.data.data.rawData;
  return ctype;
}
```

In this step, ctypeHash will be used as the query parameter of the HTTP GET request to get the ctype object.

4. Build the `Raw` object. In this step, we build a Raw object which is used for the subsequent construction of the RawCredential. The following explains each property of the Raw object:
   1. **contents**: The body of the credential;
   2. **owner**: claimer/holder, credential receiver;
   3. **ctype**: The ctype object used for this credential;
   4. **hashType**: Encryption algorithm type, here choose Keccak256 (we also support Blake2, Blake3, RescuePrimeOptimized and other encryption algorithms. Note: Considering that Keccak256 has the highest hash efficiency on chain, it is recommended to use Keccak256 as the hash when building Raw if your vc usage scenario does not include zk computation, otherwise use RescuePrimeOptimized hash).

```typescript
const raw = new Raw({
  contents: {
    id: 9870456,
    name: "vss-claimer",
  },
  owner: claimerDidUrl,
  ctype: ctype,
  hashType: "Keccak256",
});
```

5. Build the `RawCredential` object. In this step, we call `toRawCredential` API to generate RawCredential object based on the Raw object generated in the previous step. The encryption algorithm used in this step is Keccak256 by default (meanwhile, we also support other encryption algorithms, which are the same as the ones available for building Raw);

```typescript
const rawCredential: RawCredential = raw.toRawCredential("Keccak256");
```

6. Construct an encrypted message of type Request\_Attestation using RawCredential as the message data. We will generate the encrypted message using the `encryptMessage` API with the following parameters:
   1. **type**: Message type, In VC's request mode, the message type for a claim scenario is "Request\_Attestation";
   2. **data**: Message data, here is RawCredential;
   3. **sender**: Message sender's DID object, here is claimer;
   4. **receiverUrl**: Message receiver's keyAgreement DID URL;
   5. **reply**: Prefixed message id, this parameter is only used for responding to message scenarios;
   6. **resolver**: DID resolver.

```typescript
// encrypt Request_Attestation message
const message = await encryptMessage(
  "Request_Attestation",
  rawCredential,
  claimer,
  attester.getKeyUrl("keyAgreement"),
  undefined,
  resolver
);
```

7. Send the encrypted message to the server. This process initiates an HTTP POST request.

```typescript
// 'message' => server => attester
await sendMessage2Server(message);

// src/utils/messageHelper.ts
export async function sendMessage2Server(
  message: any,
  templateId = -1,
  token = null,
  url = process.env.BASE_URL
): Promise<void> {
  const sendRes = await axios.post(`${url}/message`, {
    templateId,
    msg: message,
    token,
  });
  if (sendRes.status === 200) {
    console.log(`SUCCESS: send encrypted message to server`);
  } else {
    console.log(`send encrypted message response status: ${sendRes.status}`);
  }
}
```

Well, with the above introduction, you will learn how to use our SDK as a claimer to make a request to one of the attester you specified. So far, this is only half of the VC request mode, so let's focus on the attester's perspective and explore how to respond to a request and send a VC.


# attest

In the previous post, we, as Claimer, made a request to Attester to issue a VC. This time we will be responding to the previous request as Attester, so are you ready, Attesters? Let's get going.

> Complete code example: [zkid-sdk-example /src/claim-attest/attest.ts](https://github.com/zCloak-Network/zkid-sdk-example/blob/sdk-v2/src/claim-attest/attest.ts)

## Tutorial

1. Initialize @noble cryptographic library and wasm;

```typescript
await initCrypto();
```

2. Get attester's DID object from mnemonic;

```typescript
const mnemonic = process.env.ATTESTER_MNEMONIC as string;
const keyring = new Keyring();
const attester = keys.fromMnemonic(keyring, mnemonic, "ecdsa");
```

The method used to recover a DID object from a mnemonic is `fromMnemonic`, which takes two mandatory arguments, a keyring object and a string mnemonic, where the keyring object is used to manage the keypair;

```typescript
fromMnemonic(keyring: KeyringInstance, mnemonic: string, signingKeyType?: 'ecdsa' | 'ed25519', index?: number)
```

3. Get the latest message from the server with receiver is attester and message type is Request\_Attestation;

```typescript
// get latest message
const serverMsg = await getMessage(attester, "Request_Attestation");

// src/utils/messageHelper.ts
export async function getMessage(
  receiver: Did,
  msgType: string,
  page = 1,
  size = 1,
  url = process.env.BASE_URL
) {
  const param = qs.stringify({
    page,
    size,
    receiver: receiver.getKeyUrl("keyAgreement"),
    msgType: msgType,
  });
  const res = await axios.get(`${url}/message/page?${param}`);

  return res.data.data.items.map((value: any) => value.rawData) as Array<
    Message<MessageType>
  >;
}
```

4. The attester decrypts the encrypted message obtained from the previous step and gets the RawCredential object wrapped by the claimer;

```typescript
// decrypt claim message
const decrypted = await decryptMessage(serverMsg[0], attester);

// get rawCredential from decrypt return value
const rawCredential: RawCredential = decrypted.data;
```

5. Get the ctype object via ctypeHash in RawCredential;

```typescript
const ctype = await getCtypeFromHash(rawCredential.ctype);

// src/utils/ctypeHelper.ts
export async function getCtypeFromHash(
  hash: string | undefined,
  url = process.env.BASE_URL
): Promise<CType> {
  if (hash === undefined) {
    throw new Error("ctype hash undefined !!!");
  }

  const res = await axios.get(`${url}/ctype?${qs.stringify({ id: hash })}`);
  if (res.status !== 200) {
    throw new Error(`ctype query failed ${hash}`);
  }
  const ctype: CType = res.data.data.rawData;
  return ctype;
}
```

6. Build the `vcBuilder` object. In this step, we build a vcBuilder object from which subsequent VCs can be built. vcBuilder provides several methods. For general purpose VCs, it is usually set to never expire and the issue time is set to the current time;

```typescript
const vcBuilder = VerifiableCredentialBuilder.fromRawCredential(
    rawCredential,
    ctype
  )
    .setExpirationDate(null)
    .setIssuanceDate(Date.now());
```

7. Build the `VC` object. In this step, you will use the `build` API in vcBuilder to build the VC. The two parameters of this API are described below:
   1. **issuer**: issuer's DID object;&#x20;
   2. **isPublic**: true/false. When this parameter is false, the generated VC is private VC. If it is true, then public VC is generated.

```typescript
const vc: VerifiableCredential<false> = await vcBuilder.build(
  attester,
  false
);
```

8. If the claim request is approved, the VC is used as the message data to construct the encrypted message, and the corresponding message type is "Response\_Approve\_Attestation", and if the request is rejected, the "data" field is set to empty and the message type is set to "Response\_Reject\_Attestation". When constructing the encrypted message, we will use the `encryptMessage` interface to generate the encrypted message with the following interface parameters:
   1. **type**: Message type, approval to issue VC corresponds to message type "Response\_Approve\_Attestation";
   2. **data**: Message data, here is VC;
   3. **sender**: Message sender's DID object, here is Attester;
   4. **receiverUrl**: Message receiver's keyAgreement DID URL;
   5. **reply**: Prefixed message id, this parameter is only used for responding to message scenarios, here is decrypted message id;
   6. **resolver**: DID resolver.

```typescript
const message = await encryptMessage(
  "Response_Approve_Attestation",
  vc,
  attester,
  decrypted.sender,
  decrypted.id
);
```

9. Send the encrypted message to the server. This process initiates an HTTP POST request.

```typescript
await sendMessage2Server(message);

// src/utils/messageHelper.ts
export async function sendMessage2Server(
  message: any,
  templateId = -1,
  token = null,
  url = process.env.BASE_URL
): Promise<void> {
  const sendRes = await axios.post(`${url}/message`, {
    templateId,
    msg: message,
    token,
  });
  if (sendRes.status === 200) {
    console.log(`SUCCESS: send encrypted message to server`);
  } else {
    console.log(`send encrypted message response status: ${sendRes.status}`);
  }
}
```

Well, with the introduction of this tutorial, we have learned how to respond to a claimer's request from the Attester's perspective. For general VC usage scenarios, a trusted Attester will suffice, but for decentralized and high-trust scenarios, we'll need to see how multiple Attenders can work together to endorse a VC. In the next tutorial, you will learn how to make multiple endorsements to a VC.


# multi attest


# issue

In this tutorial, you will learn how to send a VC to a specific 'holder'. The process of sending VC is VC Issue mode.

> Complete code example: [zkid-sdk-example /src/issue/issue.ts](https://github.com/zCloak-Network/zkid-sdk-example/blob/sdk-v2/src/issue/issue.ts)

## Tutorial

1. Initialize @noble cryptographic library and wasm;

```typescript
await initCrypto();
```

2. Get DID object of holder and attester;

```typescript
// get holder DID from DidDocument
const holderDidDoc = await resolver.resolve(holderDidUrl);
const holder = fromDidDocument(holderDidDoc);

// get attester DID from DID-Keys-file
const keyring = new Keyring();
const json = readDidKeysFile();
const password = "12345678"; // password to decrypt your DID-keys-file
const attester = restore(keyring, json, password);
  
// src/utils/resolverHelper.ts
export const resolver = new ArweaveDidResolver();

// src/utils/didHelper.ts
export function readDidKeysFile() {
  const attesterKeysFile = fs.readFileSync(
    path.resolve(__dirname, "../../attester-DID-keys-file.json"),
    { encoding: "utf-8" }
  );
  return JSON.parse(attesterKeysFile) as DidKeys$Json;
}
```

In the above process, the use of the following three APIs is mainly involved:

* Get resolver object, using `resolve` method get DID document from DID URL; The `resolver` can be some APIs parameters. For this kind of API, developers should explicitly specify `resolver` in their use, especially if you are developing in our development environment. This is because our `resolver` connects to the production environment by default, and if you don't specify a `resolver`, it may occurs the DID Method won't be found problem.

```typescript
const resolver = new ArweaveDidResolver();
const holderDidDoc = await resolver.resolve(holderDidUrl);
```

* Recover DID object by DID Document. The corresponding method is `fromDidDocument`. The DID document is obtained through the resolver's `resolve` interface.

```typescript
fromDidDocument(document: DidDocument, keyring?: KeyringInstance)
```

* Recover DID object by DID-keys-file. The corresponding method is `restore`. This method recovers DID object by inputing corresponding DID-keys-file contents and password where the password parameter is the password set when backing up the DID-keys-file;

```typescript
 restore(keyring: Keyring, json: DidKeys$Json, password: string)
```

tips: In addition to recovering the DID using the above methods, we also provide an API to recover the DID via mnemonics:

```typescript
fromMnemonic(keyring: KeyringInstance, mnemonic: string, signingKeyType?: 'ecdsa' | 'ed25519', index?: number)
```

3. Get ctype object from ctype hash;

```typescript
const ctype: CType = await getCtypeFromHash(ctypeHash);

// src/utils/ctypeHelper.ts
export async function getCtypeFromHash(
  hash: string | undefined,
  url = process.env.BASE_URL
): Promise<CType> {
  if (hash === undefined) {
    throw new Error("ctype hash undefined !!!");
  }

  const res = await axios.get(`${url}/ctype?${qs.stringify({ id: hash })}`);
  if (res.status !== 200) {
    throw new Error(`ctype query failed ${hash}`);
  }
  const ctype: CType = res.data.data.rawData;
  return ctype;
}
```

In this step, `ctypeHash` will be used as the query parameter of the HTTP GET request to get the ctype object.

4. Build the `Raw` object. In this step, we build a Raw object which is used for the subsequent construction of the RawCredential. The following explains each property of the Raw object:
   1. **contents**: The body of the credential;
   2. **owner**: holder/claimer, credential receiver;
   3. **ctype**: The ctype object used for this credential;
   4. **hashType**: Encryption algorithm type, here choose Keccak256 (we also support Blake2, Blake3, RescuePrimeOptimized and other encryption algorithms. Note: Considering that Keccak256 has the highest hash efficiency on chain, it is recommended to use Keccak256 as the hash when building Raw if your vc usage scenario does not include zk computation, otherwise use RescuePrimeOptimized hash).

```typescript
const raw = new Raw({
  contents: {
    id: 9870456,
    name: "vss-holder",
  },
  owner: holderDidUrl,
  ctype: ctype,
  hashType: "Keccak256",
});
```

5. Build the `RawCredential` object. In this step, we call `toRawCredential` API to generate RawCredential object based on the Raw object generated in the previous step. The encryption algorithm used in this step is Keccak256 by default (meanwhile, we also support other encryption algorithms, which are the same as the ones available for building Raw);

```typescript
const rawCredential: RawCredential = raw.toRawCredential("Keccak256");
```

6. Build the `vcBuilder` object. In this step, we build a vcBuilder object from which subsequent VCs can be built. vcBuilder provides several methods. For general purpose VCs, it is usually set to never expire and the issue time is set to the current time;

```typescript
const vcBuilder = VerifiableCredentialBuilder.fromRawCredential(
    rawCredential,
    ctype
  )
    .setExpirationDate(null)
    .setIssuanceDate(Date.now());
```

7. Build the `VC` object. In this step, you will use the `build` API in vcBuilder to build the VC. The two parameters of this API are described below:
   1. **issuer**: issuer's DID object;
   2. **isPublic**: true/false, when this parameter is false, the generated VC is private VC. If it is true, then public VC is generated.

```typescript
const vc: VerifiableCredential<false> = await vcBuilder.build(
  attester,
  false
);
```

8. Constructing encrypted messages using VC as message data. We will use the `encryptMessage` API to generate encrypted messages with the API parameters:
   1. **type**: Message type, corresponding to the VC's issue mode, is "Send\_issuedVC";
   2. **data**: Message data, here is VC;
   3. **sender**: Message sender's DID object, here is VC issuer;
   4. **receiverUrl**: Message receiver's keyAgreement DID URL;
   5. **reply**: Prefixed message id, this parameter is only used for responding to message scenarios;
   6. **resolver**: DID resolver.

```typescript
const message = await encryptMessage(
    "Send_issuedVC",
    vc,
    attester,
    holder.getKeyUrl("keyAgreement"),
    undefined,
    resolver
  );
```

9. Send the encrypted message to the server. This process initiates an HTTP POST request.

```typescript
await sendMessage2Server(message);

// src/utils/messageHelper.ts
export async function sendMessage2Server(
  message: any,
  templateId = -1,
  token = null,
  url = process.env.BASE_URL
): Promise<void> {
  const sendRes = await axios.post(`${url}/message`, {
    templateId,
    msg: message,
    token,
  });
  if (sendRes.status === 200) {
    console.log(`SUCCESS: send encrypted message to server`);
  } else {
    console.log(`send encrypted message response status: ${sendRes.status}`);
  }
}
```

Well, by following the 9 steps above, you will learn how to utilize the Issue mode of VC to issue a VC directly to the target user.


# API Reference

## DID

[fromDidDocument()](/developer-hub/api-reference/did#fromdiddocument)

[getDocument()](/developer-hub/api-reference/did#getdocument)


# DID

## fromDidDocument()

<pre class="language-typescript"><code class="lang-typescript"><strong>public fromDidDocument(xxx): xxx {
</strong>    // -- snip --
}
</code></pre>

## getDocument()

```typescript
public getDocument(): DidDocument {
    // -- snip --
}
```


# VC


# VP


# message


# zkp

zkp


# login/providers

login/providers


# Developer Tool


# CLI


# Ongoing Developer Event


# Developer Education


# Media Pack


# FAQs


