# Introduction to SSI

Enterprise Decentralized Identity

## Identity Remains an Unsolved Problem

> "The Internet was not built with an identity layer."

Digital identity has been one of the biggest problems of the internet. While there have been many solutions developed over the decades, internet identity remains an unsolved problem.

#### Human Identity

There are currently 7.5 billion humans on Earth. At a bare minimum, we need an identity system that is capable of supporting identities for all individuals. A person could also have multiple identities, where each requires its own management.

#### Identity of Things

Human identity is just the tip of the iceberg. There is an entire world of both tangible and virtual entities that need identities. This includes pets, building, organizations, devices, machines, softwares and much more.

## Self Sovereign Identity

So far, the internet has been dominantly relying on usernames and passwords for identifying and authenticating individuals. However, usernames and passwords are managed by centralized authorities, such as governments and corporates. This model presents a single point of failure that is often exploited by hackers and identity thieves. More importantly, usernames and passwords also cannot be shared with others, leaving individuals no option to freely and independently assert online identities.&#x20;

[Self-sovereign identity](https://sovrin.org/faq/what-is-self-sovereign-identity/) (SSI) is a concept that individuals should be the one controlling their digital identities without intervening authorities. SSI decentralizes the identity layer in the digital world and empowers individuals to (i) assert, (ii) own and (iii) share their digital identities, as follows:

* The ability to assert identity with a [Decentralized Identifier](https://www.w3.org/TR/did-core/) (DID).
* The ability to own identity in the form of a [Verifiable Credential](https://www.w3.org/TR/vc-data-model/) (VC).
* The ability to securely and privately share identity in a decentralized manner with a [Decentralized Public Key Infrastructure](https://www.weboftrust.info/downloads/dpki.pdf) (DPKI).

![](https://4096870634-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8AbX1b_Hf9_vGR03P0%2F-MIUYV0VWt2d1uYSr_gH%2F-MIUYc3_8WQTdi5CDrJk%2FScreen%20Shot%202020-09-30%20at%2019.01.27.png?alt=media\&token=24e7dfd2-7921-4f50-be62-54fc862b5b66)

## Decentralized Identifier

A [Decentralized Identifier](https://www.w3.org/TR/did-core/) (DID) is a new type of globally unique identifier (URI) that enables a verfiable and decentralized digital identity. A DID could identifies any entity—including a human, an organization, an animal and a device—without a centralized registration authority.&#x20;

As formalized by [W3C](https://www.w3.org/TR/did-core/), a DID consists of three parts:

1. URL scheme identifier (`did`).
2. Identifier for the [DID method](https://www.w3.org/TR/did-core/#dfn-did-methods).
3. DID method-specific identifier.

Here, we call our DID method `idin` and use a SHA-256 hash as an identifier, i.e. with 64 characters in hexadecimal. A example DID address in a IDIN platform is shown below:

![](https://4096870634-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8AbX1b_Hf9_vGR03P0%2F-MHR6DQFyGI42nkscid2%2F-MHRBL0CgDwcJ9myVbQP%2FScreen%20Shot%202020-09-17%20at%2020.11.42.png?alt=media\&token=a005a114-10c2-4bcf-96e6-a0789ba431fd)

A DID is also accompanied by a [DID document ](https://www.w3.org/TR/did-core/#dfn-did-documents)that describes the DID. This includes its DID address, the list of its public keys and its registered VCs. An example DID document in the JSON-LD format is shown below:

```
{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:idin:9cd19d4cbab9ca1d6f4c6a4b9117fb8904f250b47307cf4f484424f44e0c8370",
  "authentication": [{
    "id": "did:idin:9cd19d4cbab9ca1d6f4c6a4b9117fb8904f250b47307cf4f484424f44e0c8370#keys-1",
    "type": "Ed25519VerificationKey2018",
    "controller": "did:idin:76a6t0465cd3bd268163eee1927bfb99efe03e3cbf279f6b1772aaae09e09fqw",
    "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
  }],
  "service": [{
    "id":"did:idin:03e450465cd3bd268163dde7223bfb99efe03e3cbf279f6b1772050e09e09fbf#vcs",
    "type": "VerifiableCredentialService",
    "serviceEndpoint": "https://example.com/vc/"
  }]
}
```

## Verifiable Credential

In the physical world, we receive, own and share our identities in the form of paper/plastic credentials such as national ID cards, driving licenses, birth certificates, university transcripts, etc. However, these physical credentials are often easy to fake and difficult to verify.&#x20;

A [Verifiable Credential](https://www.w3.org/TR/vc-data-model/) (VC) is a digitized credential that can be easily and accurately verified. A VC can represent all of the same information that a physical credential holds. It is also defined to always answer the following questions:

1. Who is the credential issuer?
2. Who is the credential owner?
3. Is the credential valid?
4. Has the credential been tampered with?

In the IDIN platform, all VCs are digitally signed and verified by digital signatures, making VCs tamper-evident and more trustworthy than their physical counterparts.&#x20;

An example VC for a digital transcript is shown below. It contains, for example, the credential ID, its issuer DID, issurance date, expiration date, etc. The field `"credentialSubject"` contains the credential's details such as the GPA, university and department.

```
{
    "@context": [
        "https://www.w3.org/2018/credentials/v1"
    ],
    "type": [
        "Education Transcript"
    ],
    "id": "c498bdd8a72811eabca70242c0a82004",
    "credentialSubject": {
        "GPA": "3.64",
        "university": "Example University",
        "department: "Example Department"
    },
    "expirationDate": "2024-05-12T13:38:08+07:00",
    "issuanceDate": "2020-05-13T13:38:08+07:00",
    "issuer": "did:idin:9cd19d4cbab9ca1d6f4c6a4b9117fb8904f250b47307cf4f484424f44e0c8370",
    "proof": {
        "created": "2020-05-13T13:38:08+07:00",
        "proofPurpose": "assertionMethod",
        "signature": "deb250d461d724d5bf69ef0a380df8a763c94460b4bf8ee36b631f8bab358a6bfd8deb44ae021cc687bf89952d8c56ed3e5eb10e73751e2d23286914dd94b16e",
        "type": "Secp256r1Signature2018",
        "verificationMethod": "did:idin:03e450465cd3bd268163dde7223bfb99efe03e3cbf279f6b1772050e09e09fbf"
    }
}
```

A VC can be shared in the form of a [verifiable presentation](https://www.w3.org/TR/vc-data-model/#presentations) (VP). Holders of VCs can generate VPs and then share them with others. With the help of a blockchain, VCs and VPs can also be rapidly shared and verified over a distance, making them much more convenient than their physical counterparts.

![](https://4096870634-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8AbX1b_Hf9_vGR03P0%2F-MHR6DQFyGI42nkscid2%2F-MHR8V2njXJUUZDUx0KY%2FScreen%20Shot%202020-09-17%20at%2019.59.16.png?alt=media\&token=d17cfd69-082e-4cf7-b50e-f415a4d9b148)

## Decentralized Public Key Infrastructure

Secure communications over the internet require effcient processes of encryptions and decryptions with cryptographic keys. In [hypertext transfer protocol secure](https://www.cloudflare.com/learning/ssl/what-is-https/) (HTTPS), for example, secure communications are achieved by using public and private key pairs. Private keys are used for decryption and are always kept secret. On the other hand, public keys are used for encryption and are kept in public domain. As a result, public keys are prone to impersonation by hackers, leaving internet communications vulnerable to, e.g., [man-in-the-middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) (MITM) attacks. Secure communications, hence, require an entity to manage and assure the validity of public keys. Such a system is called a [public key infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure) (PKI).

### Centralized PKI

Traditionally, a PKI relies on a centralized third party, called certification authority (CA), to issues digital certificates that certify the ownership of public keys. In this model, digital identities are owned by trusted authorities, not the users.&#x20;

There are in fact two types of centralized PKIs, namely public and private PKIs. A public PKI relies on a publically accessible root CA that is hosted by a trusted external organization. Although a public root CA helps offload the cost for purchasing and maintaining relevant hardware and software, issuing digital certificates at a large scale is often inflexible and expensive. On the other hand, a private PKI hosts an internal root CA that provides flexibility in terms of issuance and deployment. However, the cost for maintaining relevant hardware and software is often cost-prohibitive for small businesses.&#x20;

A centralized PKI also poses a single point of failure that can be exploited. As a result, centralized PKIs are struggling to keep up with the ever evolving technological landscape. The modern society is in a desperate need for a revolutionary approach to PKIs.

### Decentralized PKI

A Decentralized Public Key Infrastructure (DPKI) is an alternative approach to designing better a PKI system by utilizing the blockchain technology. A blockchain provides a immutable storage for public keys and could distribute ledgers of public keys over a decentralized network. The blockchain technology also enables a decentralized management and assurance of public keys that eliminates the need for centralized authorities. Hence, a DPKI offers flexible and affordable solutions to digital identities for enterprises of all sizes. It also allows interoperability between different networks of blockchains, combining the advantages of both private and public PKIs.&#x20;

An identity platform built upon a DPKI establishes a common trust point—called an [Identity Trust Fabric](https://www.gartner.com/smarterwithgartner/the-beginners-guide-to-decentralized-identity/) (ITF)—in the digital world. This allows individuals to share their identity securely and privately in a decentralized manner.&#x20;


# IDIN Platform

The IDIN platform is a Self Sovereign Identity (SSI) platform built upon a Decentralized Public Key Infrastructure (DPKI) that consists of the following main components:

* **IDIN Blockchain** — a decentralized ledger for immutably storing the records of Decentralized Identifiers (DIDs), Verifiable Credentials (VCs) and public keys.
* **IDIN e-ID wallet** — a digital wallet for securely storing VCs and managing private keys.&#x20;
* **IDIN SDK** — a software development kit (SDK) for submitting transactions to the IDIN blockchain and exchanging valid VCs.

![](https://4096870634-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8AbX1b_Hf9_vGR03P0%2F-M9SpDYSf5ZwWui98WRC%2F-M9SpXronImGE6eqRm5G%2FDev1.png?alt=media\&token=a60784f8-da65-486d-9b1b-a416770d9ef5)

## IDIN Blockchain

The IDIN blockchain is built with [Tendermint](https://tendermint.com/) that performs the [Byzantine Fault Tolerant](https://docs.tendermint.com/master/introduction/what-is-tendermint.html#consensus-overview) (BFT) consensus protocol. Tendermint is a software for securely and consistently replicating a deterministic state machine to multiple distributed nodes. Tendermint works even if up to 1/3 of all nodes fail in arbitrary ways, including failures from malicious behaviors. This means it requires at least 4 nodes for a reliable usage.

The IDIN blockchain immutably records all valid transactions—initiated by IDIN e-ID wallets—that involve DIDs, VCs and public keys. It is important to note that only Credential IDs (CIDs) of VCs are recorded in the blockchain. The VCs themselves could contain sensitive personal information and are securely stored in IDIN e-ID wallets.

## IDIN e-ID Wallet

A IDIN e-ID wallet securely stores VCs and provides an access to private keys that are kept in secure storages such as an [iOS secure enclave](https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave) or an [Android keystore](https://developer.android.com/training/articles/keystore), depending on its user's operating system. The wallet is also protected and only becomes accessible with valid biometric authentication. The IDIN SDK is installed inside all e-ID wallets and provides an interface to the IDIN blockchain.

## IDIN SDK

The IDIN software development kit (SDK) provides [APIs](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9Wv2fqeQKU55VC9YTc/api-tutorials/did-api) to the IDIN blockchain. It has the following functionalities:

1. Submitting transactions to the IDIN blockchain. The types of valid transactions include (see [IDIN Key Management](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9SVPB52LP8fgIcnGmy/idin-key-management) for more details):
   * DID registration.
   * DID reset.
   * Key series addition.
   * Key series revocation.
   * VC registration.
   * VC revocation.
   * Resetter registration.
   * Resetter revocation.
   * Resetter approval.
2. Exchanging VCs between different e-ID wallets. This include:
   * Requesting for a VC.
   * Generating a Verifiable Presentation (VP) from a VC.
   * Presenting a VP.
   * Verifying a VP with the IDIN blockchain.
3. Performing cryptographic protocols, including:
   * Generating a digital signature from a private key.
   * Generating a zero-knowledge proof.
   * Performing selective disclosure.

For ease of development, SDKs are available in many languages including but not limited to Javascript, Golang, Python, Swift and Kotlin. SDKs for other languages are available upon request.

## User Journey

![](https://4096870634-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8AbX1b_Hf9_vGR03P0%2F-MOKZCM5S3Jgiw_K0rKC%2F-MOKZN3s-VB7jsaWnamM%2FScreen%20Shot%202020-12-12%20at%2013.04.21.png?alt=media\&token=5dd278a8-16e5-4849-8607-dcdc82470256)

In the IDIN platform, issuance and verification of a VC involve three parties, namely:

* Holder — a credential holder.
* Issuer — a trusted organization that issues a VC to Holder.&#x20;
* Verifier — a service provider that trusts Issuer and provides a service to Holder.&#x20;

An example journey is outlined as follows:

1. Issuer registers their public key to the IDIN Blockchain.
2. Holder requests for a VC from Issuer.
   * Issuer generates and sign the VC with Issuer's private key.
   * Issuer registers the VC on the IDIN Blockchain.
   * Issuer sends the VC to Holder's IDIN e-ID wallet.
3. Holder registers their public key to the IDIN Blockchain.
4. Holder presents the VC to Verifier (online or offline).
   * Holder generates a VP from the VC and then signs it with Holder's private key.
   * Holder sends the VP to Verifier.
5. Verifier verifies the presented VP with the IDIN platform.
   * Verifier verifies Issuer's digital signature to check that the VC is valid and has not been tampered.
   * Verifier verifies Holder's digital signature to check that Holder is really the valid holder of the VC.

After a successful presentation, Verifier is certain that Holder really possesses a valid credential from Issuer. Verifier then trusts Holder for a business transaction.


# IDIN Key Management

## Digital Signature

A digital signature is a cryptographic scheme for signing and verifying authenticity of digital messages and documents. It enables cryptographic trusts and forms the core of any decentralized identity platform, ensuring privacy and security of all identity transactions and exchanges.

In the IDIN platform, all HTTP requests to the IDIN blockchain and all VCs are cryptographically signed and verified by [elliptic-curve digital signature algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) (ECDSA) with [secp256r1](https://www.secg.org/sec2-v2.pdf)(P-256) curve. In this signature protocol, private keys are used for signing whereas public keys are used for verification. The sizes of public keys, private keys and digital signatures in the IDIN platform are summarized below.

| Key         | Size (hex) | Size (bit) |
| ----------- | ---------- | ---------- |
| Public key  | 130        | 520        |
| Private key | 64         | 256        |
| Signature   | 128        | 512        |

## IDIN Key Management

To ensure security and privacy of identity transactions while preserving seamless user experience, the IDIN platform provides a management system for cryptographic keys. All private keys are securely kept in secure storages—such as [iOS secure enclaves](https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave) and [Android keystores](https://developer.android.com/training/articles/keystore)—and can be accessed from IDIN e-ID wallets. On the other hand, public keys are immutably recorded in the IDIN blockchain. This provides a common trust point where all identity transactions can be reliably verified.

#### DID Registration

Every key series is associated with a DID, and every DID must always have at least one active key series. During a registration of a new DID with the [`did_register`](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9Wv2fqeQKU55VC9YTc/api-tutorials/did-api/register-did) operation, a new key series must also be specified.

#### Key Series Addition

A DID is allowed to have multiple key series. This function allows a DID owner to organize her transactions by, e.g., signing different types of transactions with different key series. Adding a new key series requires another active key series to sign the [`did_add`](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9Wv2fqeQKU55VC9YTc/api-tutorials/did-api/add-key) operation.

#### Key Series Revocation

Active key series can be revoked and become inactive. To revoke a key series, another active key series must be used to sign the [`did_revoke`](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9Wv2fqeQKU55VC9YTc/api-tutorials/did-api/revoke-key) operation. A key series cannot be used to revoke itself since every DID must always have at least one active key series.

## Key Recovery

If a DID owner loses her device (e.g. smart phone) and loses an access to all of her private keys, she will no longer be able to commit another transaction to the IDIN blockchain. As a result, the IDIN platform provides a **DID** **reset** operation that revokes all key series of the reset DID and then gives it a new key series. The holder can then use the new key series to commit further transactions, including adding more key series.

To prevent a malicious user from resetting another user's DID, the reset operation are performed by a set of trusted entities, called **DID resetters**. When a DID reset operation is initiated, the resetters must vote whether to allow the reset operation. If approval votes exceed a predetermined threshold (set by DID owner), the consensus is reached, and the IDIN platform will carry out the reset operation.

#### Resetter Registration

First, a DID owner must register a set of other DIDs as her resetters with the [`did_register_resetters`](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9Wv2fqeQKU55VC9YTc/api-tutorials/did-api/register-resetters) operation. The resetters must then approve the registration before they become active resetters of that DID. During the registration, the DID owner must also allocate voting powers to the resetters and specify the threshold for a acceptable number of voting powers.

#### Resetter Approval

Once the registration is complete, the DID owner could then initiate the DID reset operation. For the DID reset operation to be complete, the resetters must vote with the [`did_resetter_approve`](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9Wv2fqeQKU55VC9YTc/api-tutorials/did-api/resetter-approve) operation and then reach a consensus, i.e. the combined voting powers exceeding the threshold.&#x20;

![](https://4096870634-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8AbX1b_Hf9_vGR03P0%2F-MHQdrS7i6p3GKi-jk8y%2F-MHQeHOVsQRSqNqT_7Rs%2Fidin1.png?alt=media\&token=483a39cf-b2e9-4f10-8259-c857fadd669c)

#### Resetter Revocation

The DID owner could also revoke the current set of resetters with the [`did_revoke_resetters`](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9Wv2fqeQKU55VC9YTc/api-tutorials/did-api/revoke-resetters) operation. However, for the revocation to be complete, the current resetters must vote with the [`did_resetter_approve`](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9Wv2fqeQKU55VC9YTc/api-tutorials/did-api/resetter-approve) operation and then reach a consensus, similar to the reset operation. After the old set of resetters are revoked, the DID owner could register a new set of resetters.

![](https://4096870634-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8AbX1b_Hf9_vGR03P0%2F-MHQdrS7i6p3GKi-jk8y%2F-MHQfbJUlYu7YtSuYuq1%2Fidin2.png?alt=media\&token=75a39d0c-12bf-4cbf-ac30-f0064c4bf2d1)

**Reset Request**

The DID owner cannot submit a request to reset her DID herself. To invoke the reset operation, she must contact each of her resetters individually and ask them to submit a reset request with the [`did_resetter_approve`](https://app.gitbook.com/@balll/s/finema-documentation/~/drafts/-M9Wv2fqeQKU55VC9YTc/api-tutorials/did-api/resetter-approve) operation. For the reset operation to be complete, the combined voting powers from all resetters must surpass the threshold.

![](https://4096870634-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M8AbX1b_Hf9_vGR03P0%2F-MHQdrS7i6p3GKi-jk8y%2F-MHQhWzJiiZiI4rbyZR6%2FScreen%20Shot%202020-09-17%20at%2017.57.01.png?alt=media\&token=ce974ab9-f053-411f-b90e-1fae2685b463)


# DID API

## Overview

The DID [API](https://en.wikipedia.org/wiki/Application_programming_interface) provides a collection of [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) request methods that underpin IDIN blockchain's functionality. The DID API includes HTTP methods for registration of a Decentralized Identifier (DID), key series management and resetter management. HTTP requests to the IDIN server must be in the JSON format with the following two attributes:

1. `"message"`: The request message that is encoded in the [Base64](https://en.wikipedia.org/wiki/Base64) format.
2. `"signature"`: The signature of the Base64-encoded request message. The encoded message is signed by a private key.

```
{
    "message": "eyJuZXdfa2V5X2hhc2giOiAiMmEzN2I5ZWRmZjc4ZTZjMGQ1ZWY5MDg4OGIyOWZhNjQ5NDk4MDk0YTQ5NzBhNjYwYWRjZDVlMGIzMTYxZTY2ZiIsICJjdXJyZW50X2tleSI6ICItLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxuTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFdTdab25EWVlFbkNUdlBBOUg4ZU05SnhhUUdIQlxuTXpMZ3hVTW81OFNYb0pLSXp0OTNrUUsvYmh3ZFBuRmFFZlFoaUxCNVZrT0ZnbjJxS2dTY2RJY1hWdz09XG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0iLCAibmV4dF9rZXlfaGFzaCI6ICJjY2NhNmMxMWNmYTQwZjI2Njk2OGY2YTcxYmJhNDk1YmM3M2U5N2Q4ODJlYjc0NTIzNzg0NzY5ZDQzMTc1Y2Q1IiwgIm9wZXJhdGlvbiI6ICJkaWRfYWRkIiwgImRpZF9hZGRyZXNzIjogImRpZDppZGluOmFmYjdiYTg4Yzc2ZWRiZGE1NWMzNDRiNzBhZTBjZjA1NTZkNzcwZWMyNTY4MjBkNzE4NTAwMGRlMzk1MzkxYjUiLCAibm9uY2UiOiAxfQ==",
    "signature": "MEUCIQCfZqZodAu7pTgb9xLHdi+DWTrwbCjI4z18RXAQFcXp0AIgf3VyAP86Yr6gMqUiMg97YJRx67ELwlaKFhh9Bolj3cY="
}
```

There are several types of requests, such as registering a new DID address and adding a new key series to a DID. The request messages are also in the JSON format with a number of attributes depending on the request types. With the exception of registering a new DID, all request messages contain the following five attributes:&#x20;

1. `"operation"`: The request method's name that tells the server to execute the right operation.
2. `"did_address"`: The DID address of which a key series is used to sign and verify the request.
3. `"current_key"`: The public key in the [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail) format for verifying the request's signature. It is the current public key in the key series and is the public key pair of the private key that signs the request.
4. `"next_key_hash"`: The SHA-256 hash of the next public key in [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail) format in the key series.
5. `"nonce"`: The request nonce that is bound to the given DID address. It starts at one and then increases by one for every request, and as a result it counts to the total number of requests that the DID has made.

The code snippet below shows an example request message for revoking the current set of resetters.

```
{
    "operation": "did_add",
    "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu7ZonDYYEnCTvPA9H8eM9JxaQGHB\nMzLgxUMo58SXoJKIzt93kQK/bhwdPnFaEfQhiLB5VkOFgn2qKgScdIcXVw==\n-----END PUBLIC KEY-----",
    "next_key_hash": "ccca6c11cfa40f266968f6a71bba495bc73e97d882eb74523784769d43175cd5",
    "new_key_hash": "2a37b9edff78e6c0d5ef90888b29fa649498094a4970a660adcd5e0b3161e66f",
    "nonce": 1
}

```

{% hint style="warning" %}
The DID registration request is the only request method that does not contain `"did_address"` and`"nonce"` since these two attributes must be bound to a DID.
{% endhint %}

When the server receives a HTTP request from a client, the server first decodes the request message (`"message"`), check whether all attributes are valid and then uses the verifying public key (`"current_key"`) to verify the request's signature (`"signature"`). If `"did_address"` is in the request message, the server will also check whether the `"current_key"` is a valid current public key in any of the DID's key series.

## DID Requests

The table below summarizes all DID-related HTTP requests to the IDIN server.

| Request Method                                                                                                                    | Description                                   | HTTP Method |
| --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | :---------: |
| [`did_register`](https://app.gitbook.com/@balll/s/finema-docs/~/drafts/-M8ExDvnDBnoTJneay9S/api/register-a-new-did)               | Register a new DID address.                   |     POST    |
| [`did_add`](https://app.gitbook.com/@balll/s/finema-docs/~/drafts/-M8ExDvnDBnoTJneay9S/api/add-a-new-public-key-series)           | Add a new key series to a DID.                |     POST    |
| [`did_revoke`](https://app.gitbook.com/@balll/s/finema-docs/~/drafts/-M8ExDvnDBnoTJneay9S/api/revoke-a-public-key-series)         | Revoke a key series from a DID.               |    DELETE   |
| [`did_register_resetters`](https://app.gitbook.com/@balll/s/finema-docs/~/drafts/-M8ExDvnDBnoTJneay9S/api/register-new-resetters) | Register a new set of resetters for a DID.    |     POST    |
| [`did_revoke_resetters`](https://app.gitbook.com/@balll/s/finema-docs/~/drafts/-M8ExDvnDBnoTJneay9S/api/resetter-consensus)       | Revoke the current set of resetters of a DID. |    DELETE   |
| [`did_resetter_approve`](https://app.gitbook.com/@balll/s/finema-docs/~/drafts/-M8UVvX5b_pfm7VawJl3/api/resetter-consensus)       | Approve a resetter request.                   |     POST    |
|                                                                                                                                   | Get the current nonce of a DID.               |     GET     |


# DID Registration

Every DID is associated with at least one key series. Apart from registering a new DID, every other type of request is associated with a DID address (`"did_address"`) and one of the DID's key series. The client specifies the attribute `"operation"` according to the name of the request method. The current public key (`"current_key"`) in the series and the SHA-256 hash of the next public key (`"next_key_hash"`) is part of the request message whereas the current private key is used to sign the Base64 encoded request message.

To register for a new DID, a client must specify a new key series when she registers for a new DID address with `did_register` operation. The client generates the first and second public-private key pairs in the new key series. In the request message, the client then specifies the first public key (`"current_key"`) and the SHA-256 hash of the second public key (`"next_key_hash"`).  The request message is then encoded in Base64 and signed by the first private key.

## did\_register

<mark style="color:green;">`POST`</mark> `https://test-network.finema.co/did/`

#### Request Body

| Name            | Type   | Description                                                                       |
| --------------- | ------ | --------------------------------------------------------------------------------- |
| operation       | string | The method's name that is "did\_register".                                        |
| current\_key    | string | The first public key in the series. It is used to verify the request's signature. |
| next\_key\_hash | string | The SHA-256 hash of the next public key in the series.                            |

{% tabs %}
{% tab title="200 The operation name and DID address for the registered DID will be given as the response. The DID address is derived from the current public key ("current\_key")." %}

```
{
    "operation": "did_register",
    "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5"
 
}
```

{% endtab %}

{% tab title="422 " %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Example Message and Request

```
{
    "operation": "did_register",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWquJ9+BEBDQTA/xRmx5uAHOgKMue\nw1QoAGk+2mLVWGvFBW5D3BMPYOFtGM/tvubVjwY3tr9iRI+erSQUmFIvRg==\n-----END PUBLIC KEY-----",
    "next_key_hash": "2775f71ed2bef2f395acf8781d43d0f538bf693b7c62a5bc27ec46cc839d272c"
}
```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "eyJjdXJyZW50X2tleSI6ICItLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxuTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFV3F1SjkrQkVCRFFUQS94Um14NXVBSE9nS011ZVxudzFRb0FHaysybUxWV0d2RkJXNUQzQk1QWU9GdEdNL3R2dWJWandZM3RyOWlSSStlclNRVW1GSXZSZz09XG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0iLCAibmV4dF9rZXlfaGFzaCI6ICIyNzc1ZjcxZWQyYmVmMmYzOTVhY2Y4NzgxZDQzZDBmNTM4YmY2OTNiN2M2MmE1YmMyN2VjNDZjYzgzOWQyNzJjIiwgIm9wZXJhdGlvbiI6ICJkaWRfcmVnaXN0ZXIifQ==",
    "signature": "MEUCIQCIP/oFaQ8HKyOVNb2UGGoecC7t8F9DqLPLTvptWb6Q/wIgddkJPlh938hmFU6H9GrojIFh6NFWK0TeUkPQEBqE0jI="
}
```


# Key Series Addition

Once a DID is registered, its owner has the option to add more key series with `did_add` operation. This operation requires another active key series to sign and verify its HTTP request. In the `did_add` request, the client must specify the SHA-256 hash of the first public key in the new series must be given.

{% hint style="warning" %}
A new key series cannot be used to sign and verify its own addition.&#x20;
{% endhint %}

## did\_add

<mark style="color:green;">`POST`</mark> `https://test-network.finema.co/did/<did_address>/key`

#### Request Body

| Name            | Type   | Description                                                                         |
| --------------- | ------ | ----------------------------------------------------------------------------------- |
| operation       | string | The method's name that is "did\_add".                                               |
| did\_address    | string | The DID address.                                                                    |
| current\_key    | string | The current public key in the series. It is used to verify the request's signature. |
| next\_key\_hash | string | The SHA-256 hash of the next public key in the series.                              |
| new\_key\_hash  | string | The SHA256 hash of the first public key in the new series.                          |
| nonce           | number | The request nonce.                                                                  |

{% tabs %}
{% tab title="200 The operation name, DID address (\<did\_address>) and a unique ID for the added key series will be given as the response." %}

```
{
     "operation": "did_add",
     "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
     "key_id": "f975e5f2e4a06fced2d65bd59e12c33c901814555b026264b8377ace79cee60a"
}
```

{% endtab %}

{% tab title="422 " %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Example Message and Request

```
{
    "operation": "did_add",
    "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEu7ZonDYYEnCTvPA9H8eM9JxaQGHB\nMzLgxUMo58SXoJKIzt93kQK/bhwdPnFaEfQhiLB5VkOFgn2qKgScdIcXVw==\n-----END PUBLIC KEY-----",
    "next_key_hash": "ccca6c11cfa40f266968f6a71bba495bc73e97d882eb74523784769d43175cd5",
    "new_key_hash": "2a37b9edff78e6c0d5ef90888b29fa649498094a4970a660adcd5e0b3161e66f",
    "nonce": 1
}

```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "eyJuZXdfa2V5X2hhc2giOiAiMmEzN2I5ZWRmZjc4ZTZjMGQ1ZWY5MDg4OGIyOWZhNjQ5NDk4MDk0YTQ5NzBhNjYwYWRjZDVlMGIzMTYxZTY2ZiIsICJjdXJyZW50X2tleSI6ICItLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxuTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFdTdab25EWVlFbkNUdlBBOUg4ZU05SnhhUUdIQlxuTXpMZ3hVTW81OFNYb0pLSXp0OTNrUUsvYmh3ZFBuRmFFZlFoaUxCNVZrT0ZnbjJxS2dTY2RJY1hWdz09XG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0iLCAibmV4dF9rZXlfaGFzaCI6ICJjY2NhNmMxMWNmYTQwZjI2Njk2OGY2YTcxYmJhNDk1YmM3M2U5N2Q4ODJlYjc0NTIzNzg0NzY5ZDQzMTc1Y2Q1IiwgIm9wZXJhdGlvbiI6ICJkaWRfYWRkIiwgImRpZF9hZGRyZXNzIjogImRpZDppZGluOmFmYjdiYTg4Yzc2ZWRiZGE1NWMzNDRiNzBhZTBjZjA1NTZkNzcwZWMyNTY4MjBkNzE4NTAwMGRlMzk1MzkxYjUiLCAibm9uY2UiOiAxfQ==",
    "signature": "MEUCIQCfZqZodAu7pTgb9xLHdi+DWTrwbCjI4z18RXAQFcXp0AIgf3VyAP86Yr6gMqUiMg97YJRx67ELwlaKFhh9Bolj3cY="
}
```


# Key Series Revocation

A client can revoke any existing key series in a DID with `did_revoke` operation by specifying the ID of the revoked key series. Similar to `did_add`, this operation requires another active key series to sign and verify its HTTP request.

{% hint style="info" %}
A private-public key pair is always required to sign and verify a request. Hence, every DID must always have at least one active key series.
{% endhint %}

{% hint style="warning" %}
A key series cannot be used to revoke itself.
{% endhint %}

## did\_revoke

<mark style="color:red;">`DELETE`</mark> `https://test-network.finema.co/did/<did_address>/key/<key_id>`

#### Request Body

| Name            | Type   | Description                                                                         |
| --------------- | ------ | ----------------------------------------------------------------------------------- |
| operation       | string | The method's name that is "did\_revoke".                                            |
| did\_address    | string | The DID address.                                                                    |
| current\_key    | string | The current public key in the series. It is used to verify the request's signature. |
| next\_key\_hash | string | The SHA-256 hash of the next public key in the series.                              |
| key\_id         | string | The ID of the revoked key series.                                                   |
| nonce           | number | The request nonce.                                                                  |

{% tabs %}
{% tab title="200 The operation name, DID address (\<did\_address>) and the ID of the revoked key series will be given as" %}

```
{
    "operation": "did_revoke",
    "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
    "key_id": "f975e5f2e4a06fced2d65bd59e12c33c901814555b026264b8377ace79cee60a"
}
```

{% endtab %}

{% tab title="422 " %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Example Message and Request

```
{
    "operation": "did_revoke",
    "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEA2UzvDva55MhIv8PY/OZ8kThIzxR\nQrDpv1f67ZrzADKLpQj47qE2VlQMTgTpMx/4BnEhzDJXnzxZz66s7Gke9A==\n-----END PUBLIC KEY-----",
    "next_key_hash": "18c87792d69ad938b3dde8346628363807735a8d1644c5750aad35d2e153d580",
    "key_id": "f975e5f2e4a06fced2d65bd59e12c33c901814555b026264b8377ace79cee60a",
    "nonce": 2
}
```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "eyJrZXlfaWQiOiAiZjk3NWU1ZjJlNGEwNmZjZWQyZDY1YmQ1OWUxMmMzM2M5MDE4MTQ1NTViMDI2MjY0YjgzNzdhY2U3OWNlZTYwYSIsICJjdXJyZW50X2tleSI6ICItLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxuTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFQTJVenZEdmE1NU1oSXY4UFkvT1o4a1RoSXp4UlxuUXJEcHYxZjY3WnJ6QURLTHBRajQ3cUUyVmxRTVRnVHBNeC80Qm5FaHpESlhuenhaejY2czdHa2U5QT09XG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0iLCAibmV4dF9rZXlfaGFzaCI6ICIxOGM4Nzc5MmQ2OWFkOTM4YjNkZGU4MzQ2NjI4MzYzODA3NzM1YThkMTY0NGM1NzUwYWFkMzVkMmUxNTNkNTgwIiwgIm9wZXJhdGlvbiI6ICJkaWRfcmV2b2tlIiwgImRpZF9hZGRyZXNzIjogImRpZDppZGluOmFmYjdiYTg4Yzc2ZWRiZGE1NWMzNDRiNzBhZTBjZjA1NTZkNzcwZWMyNTY4MjBkNzE4NTAwMGRlMzk1MzkxYjUiLCAibm9uY2UiOiAyfQ==",
    "signature": "MEUCIQCGnSfpv5RHQwwKM6eyelaGUTNbuvs5dMlr6jQSx3+hWAIgR3aBRhHERxJHmSRW9zyD2Tf5UTCkIxQ/aqURrZh7IN4="
}
```


# Resetter Registration

In the case that a client loses all of her private keys, the client has an option to **reset** her DID, i.e. revoking all of her key series in that DID, with the approval of her resetters.

To invoke the reset operation, a list of resetters must be first registered with `did_register_resetters` operation. All  resetters must also approve the registration themselves before the reset operation becomes available. In the resetter registration request, the client must specify (i) each resetter's *DID address* ("`did_address`") and (ii) each resetter's *vote power* (`"vote_power"`) and (iii) the acceptable number of combined voting powers (`"acceptable_votes"`) for approving the reset operation.

Note that the client cannot submit a request to reset her DID herself. To reset all key series in a DID, the client must contact each of her resetters individually and ask them to submit a reset request.  For the reset operation to be complete, the combined voting powers from all resetters must surpass the threshold.

{% hint style="info" %}
For a set resetters to become active, all resetters in the set must respond and approve the registration.&#x20;
{% endhint %}

## did\_register\_resetters

<mark style="color:green;">`POST`</mark> `https://test-network.finema.co/did/<did_address>/reset`

#### Request Body

| Name              | Type   | Description                                                                                             |
| ----------------- | ------ | ------------------------------------------------------------------------------------------------------- |
| operation         | string | The method's name that is "did\_register\_resetters".                                                   |
| did\_address      | string | The DID address.                                                                                        |
| current\_key      | string | The current public key in the series. It is used to verify the request's signature.                     |
| next\_key\_hash   | string | The SHA-256 hash of the next public key in the series.                                                  |
| resetters         | string | The list of the resetters. Each element in the list contains a resetter's DID address and voting power. |
| acceptable\_votes | string | The voting power threshold in a resetter consensus.                                                     |
| nonce             | number | The request nonce.                                                                                      |

{% tabs %}
{% tab title="200 The operation name and DID address (\<did\_address>) will be given as the response." %}

```
{
    "operation": "did_register_resetters",
    "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
}
```

{% endtab %}

{% tab title="422 " %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Example Message and Request

```
{
    "operation": "did_register_resetters",
   "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbqWnPp+v+a3QfT1rpJUfMxma0oFY\nc/7m07qWVr7Uf158jIon0teT+SHt9ChncFDVbUp5fYo+EDRjiEnygkpxJQ==\n-----END PUBLIC KEY-----",
    "next_key_hash": "665267b5854fd3a81b97850c696eb745448f57e53c93e05edb2e8b85e377dde5",
    "resetters": [
        {
            "did_address": "did:idin:14cd5183f730afe756a5e43f794c66ea72bd0e90095dfa84a46631371f3c3a88",
            "vote_power": 1
        },
        {
            "did_address": "did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0",
            "vote_power": 2
        },
        {
            "did_address": "did:idin:37c92d742a1fac53588a4d7918d12275540c0cacd19b56036f6720dcf7da0b2c",
            "vote_power": 3
        }
    ],
    "acceptable_votes": 3,
    "nonce": 3
}
```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "eyJyZXNldHRlcnMiOiBbeyJkaWRfYWRkcmVzcyI6ICJkaWQ6aWRpbjoxNGNkNTE4M2Y3MzBhZmU3NTZhNWU0M2Y3OTRjNjZlYTcyYmQwZTkwMDk1ZGZhODRhNDY2MzEzNzFmM2MzYTg4IiwgInZvdGVfcG93ZXIiOiAxfSwgeyJkaWRfYWRkcmVzcyI6ICJkaWQ6aWRpbjowNDhjYTIzYzdlZGZiNzE2NTVjYjZkYzU2MjhjODMyNzgxNmVkZmNiMzc3OTYzZGVlY2JhM2EzZTkxZTVmOGIwIiwgInZvdGVfcG93ZXIiOiAyfSwgeyJkaWRfYWRkcmVzcyI6ICJkaWQ6aWRpbjozN2M5MmQ3NDJhMWZhYzUzNTg4YTRkNzkxOGQxMjI3NTU0MGMwY2FjZDE5YjU2MDM2ZjY3MjBkY2Y3ZGEwYjJjIiwgInZvdGVfcG93ZXIiOiAzfV0sICJhY2NlcHRhYmxlX3ZvdGVzIjogMywgImN1cnJlbnRfa2V5IjogIi0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXG5NRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVicVduUHArdithM1FmVDFycEpVZk14bWEwb0ZZXG5jLzdtMDdxV1ZyN1VmMTU4aklvbjB0ZVQrU0h0OUNobmNGRFZiVXA1ZllvK0VEUmppRW55Z2tweEpRPT1cbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLSIsICJuZXh0X2tleV9oYXNoIjogIjY2NTI2N2I1ODU0ZmQzYTgxYjk3ODUwYzY5NmViNzQ1NDQ4ZjU3ZTUzYzkzZTA1ZWRiMmU4Yjg1ZTM3N2RkZTUiLCAib3BlcmF0aW9uIjogImRpZF9yZWdpc3Rlcl9yZXNldHRlcnMiLCAiZGlkX2FkZHJlc3MiOiAiZGlkOmlkaW46YWZiN2JhODhjNzZlZGJkYTU1YzM0NGI3MGFlMGNmMDU1NmQ3NzBlYzI1NjgyMGQ3MTg1MDAwZGUzOTUzOTFiNSIsICJub25jZSI6IDN9",
    "signature": "MEYCIQDcF+eiEcPdvJgI3Ab2c+Cy9f2VhG2fYP6aIfMnZCn/LwIhAK1OdOKTqiKAUA4rZhdRPOYrE6ew5Cp220p4+vjgxq8C"
}
```


# Resetter Revocation

Once a list of resetters are registered and approved, the client could also revoke the current set of resetters with `did_revoke_resetters` operation. However, the client still needs to get approvals from the current resetters. For the revocation to be complete, the combined voting powers from all resetters must surpass the threshold of `"acceptable_votes"`.

{% hint style="info" %}
For a revoke request to get approved, not all resetters need to respond to the request. The approval only requires that the combined vote powers of responding resetters surpass the threshold of`"acceptable_votes"`.
{% endhint %}

{% hint style="warning" %}
A DID can only have one list of resetters at a time. To register a new set of resetters, the old one must be first revoked.
{% endhint %}

{% hint style="info" %}
When a set of resetters are registered, if not all of those resetters approve the registration, this set of resetters will remain inactive. In this case, the client could revoke these inactive resetters without their approvals and then register a new set.
{% endhint %}

## did\_revoke\_resetters

<mark style="color:red;">`DELETE`</mark> `https://test-network.finema.co/did/<did_address>/reset`

#### Request Body

| Name            | Type   | Description                                                                         |
| --------------- | ------ | ----------------------------------------------------------------------------------- |
| operation       | string | The method's name that is "did\_revoke\_resetters".                                 |
| did\_address    | string | The DID address.                                                                    |
| current\_key    | string | The current public key in the series. It is used to verify the request's signature. |
| next\_key\_hash | string | The SHA-256 hash of the next public key in the series.                              |
| nonce           | number | The request nonce.                                                                  |

{% tabs %}
{% tab title="200 The operation name and DID address (\<did\_address>) will be given as the response." %}

```
{
    "operation": "did_revoke_resetters",
    "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5"
}
```

{% endtab %}

{% tab title="422 " %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Example Message and Request

```
{
    "operation": "did_revoke_resetters",
    "did_address": "did:idin:9cd19d4cbab9ca1d6f4c6a4b9117fb8904f250b47307cf4f484424f44e0c8370",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeR8NhQeHPT7l1yMyvkZMacPpibjH\n7mp5IRyO2J2kuE97h/fzu1c/7DFsO23qUN6/OezYglMEkoVo5Ob1b6k53A==\n-----END PUBLIC KEY-----",
    "next_key_hash": "a18b790a92683ad00d3562de385ca9e07d20a729809c782e72412f57dd847105"
    "nonce": 4
}
```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "ewogICAgIm9wZXJhdGlvbiI6ICJkaWRfcmVnaXN0ZXJfcmVzZXR0ZXJzIiwKICAgICJkaWRfYWRkcmVzcyI6ICJkaWQ6aWRpbjo5Y2QxOWQ0Y2JhYjljYTFkNmY0YzZhNGI5MTE3ZmI4OTA0ZjI1MGI0NzMwN2NmNGY0ODQ0MjRmNDRlMGM4MzcwIiwKICAgICJjdXJyZW50X2tleSI6ICItLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxuTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZVI4TmhRZUhQVDdsMXlNeXZrWk1hY1BwaWJqSFxuN21wNUlSeU8ySjJrdUU5N2gvZnp1MWMvN0RGc08yM3FVTjYvT2V6WWdsTUVrb1ZvNU9iMWI2azUzQT09XG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0iLAogICAgIm5leHRfa2V5X2hhc2giOiAiYTE4Yjc5MGE5MjY4M2FkMDBkMzU2MmRlMzg1Y2E5ZTA3ZDIwYTcyOTgwOWM3ODJlNzI0MTJmNTdkZDg0NzEwNSIKICAgICJub25jZSI6IDEKfQ==",
    "signature": "OTI3MzgyNDgzNTQ3NTU5ODMyNTM1NzYwMDc2MTEwNzYwMTUzMjAzMzQ2NzQ5MDU4NzIwMzM4ODUzNjc4OTE2MTI2NzA2NzQyODgyMDcsIDQ1MjE2NzEwMzM3MjI5NjEzOTc3MjYxMzY2MjUwODYxOTA5MzY2MDU1MDg2Mjk0NzEyMDAwMTU3MjU4ODYxNTQ3ODUzNDc3NTY2ODQw"
}
```


# Resetter Approval

Any client could take a resetter role for another client and respond to her client's request with `did_resetter_approve` operation. The server will take the **consensus** of all resetters and decide whether to approve or reject the request.

{% hint style="danger" %}
In practice, a client could register multiple DIDs and use her own DIDs to be resetters of another DID. This is discouraged since a client could lose all private keys of all of her DIDs.
{% endhint %}

{% hint style="warning" %}
Unlike the `did_register_resetters` and `did_revoke_resetters` operations that are initiated by the DID owner, the `did_resetter_approve` is initiated by a DID resetter.
{% endhint %}

As a resetter, there are three consensus types:

1. `did_register_resetters` approves a resetter registration for a DID. A set of resetters will become active after all resetters in the set approve the registration.
2. `did_revoke_resetters` approves a resetter revocation for a DID. A set of resetters will be revoked, i.e. become deactivated, if the combined voting powers of all resetters surpass `"acceptable_votes"`.
3. `did_reset` approves a DID reset, i.e. resetting all key series in the DID. The reset will take place if the combined voting powers of all resetters surpass `"acceptable_votes"`.

In the HTTP request for `did_resetter_approve`, a resetter must specify the attribute `"consensus"` that contains (i) the consensus type, (ii) DID address of the target client and (iii) the DID address of the resetter who makes this HTTP request, which are seperated by `|` as follows:

```
"consensus": "consensus_name|target_did_address|resetter_did_address"
```

{% hint style="info" %}
For a reset request to get approved, not all resetters need to respond to the request. The approval only requires that the combined vote powers of responding resetters surpass the theshold of`"acceptable_votes"`.
{% endhint %}

## did\_resetter\_approve

<mark style="color:green;">`POST`</mark> `https://test-network.finema.co/did/<resetter_did_address>/approve`

#### Request Body

| Name            | Type   | Description                                                                         |
| --------------- | ------ | ----------------------------------------------------------------------------------- |
| operation       | string | The method's name that is "did\_resetter\_approve".                                 |
| did\_address    | string | The DID address.                                                                    |
| current\_key    | string | The current public key in the series. It is used to verify the request's signature. |
| next\_key\_hash | string | The SHA-256 hash of the next public key in the series.                              |
| consensus       | string | The name of the invoked resetter consensus.                                         |
| new\_key\_hash  | string | The SHA-256 hash of the first public key in the new series.                         |
| nonce           | number | The request nonce.                                                                  |

{% tabs %}
{% tab title="200 The operation name, resetter's DID address (\<resetter\_did\_address>) and "consensus" are given as the response. Depending on the request, consensus\_name could be either (i) did\_register\_resetters, (ii) did\_revoke\_resetters or (iii) did\_reset." %}

```
{
    "operation": "did_resetter_approve",
    "did_address": "did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0",
    "consensus": "consensus_name|did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5|did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0"
}
```

{% endtab %}

{% tab title="422 " %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Example Messages and Requests

If that the resetter DID is `did:idin:03e450465cd3bd268163dde7223bfb99efe03e3cbf279f6b1772050e09e09fbf`and the target DID address is `did:idin:9cd19d4cbab9ca1d6f4c6a4b9117fb8904f250b47307cf4f484424f44e0c8370` , then the field "consensus" must have the following form:

```
"consensus": "consensus_name|did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5|did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0"
```

where `consensus_name` could be either (i) `did_register_resetters`, (ii) `did_revoke_resetters` or (iii) `did_reset`.

### 1. Approve a resetter registration:

```
{
    "consensus": "did_register_resetters|did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5|did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIefmMIcLLop4og/YYR8NrcZTS378\nRfODoXU27dtXV7jJ+opms04VPgTuqLLlVyPr6hgU213ei2M37sHNOQt74A==\n-----END PUBLIC KEY-----",
    "next_key_hash": "b410dd10dbe4c582583776c943e37613ecff16a51385fbc65b57b85474f4d1ca",
    "operation": "did_resetter_approve",
    "did_address": "did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0",
    "nonce": 1
}
```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "eyJjb25zZW5zdXMiOiAiZGlkX3JlZ2lzdGVyX3Jlc2V0dGVyc3xkaWQ6aWRpbjphZmI3YmE4OGM3NmVkYmRhNTVjMzQ0YjcwYWUwY2YwNTU2ZDc3MGVjMjU2ODIwZDcxODUwMDBkZTM5NTM5MWI1fGRpZDppZGluOjA0OGNhMjNjN2VkZmI3MTY1NWNiNmRjNTYyOGM4MzI3ODE2ZWRmY2IzNzc5NjNkZWVjYmEzYTNlOTFlNWY4YjAiLCAiY3VycmVudF9rZXkiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRUllZm1NSWNMTG9wNG9nL1lZUjhOcmNaVFMzNzhcblJmT0RvWFUyN2R0WFY3akorb3BtczA0VlBnVHVxTExsVnlQcjZoZ1UyMTNlaTJNMzdzSE5PUXQ3NEE9PVxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tIiwgIm5leHRfa2V5X2hhc2giOiAiYjQxMGRkMTBkYmU0YzU4MjU4Mzc3NmM5NDNlMzc2MTNlY2ZmMTZhNTEzODVmYmM2NWI1N2I4NTQ3NGY0ZDFjYSIsICJvcGVyYXRpb24iOiAiZGlkX3Jlc2V0dGVyX2FwcHJvdmUiLCAiZGlkX2FkZHJlc3MiOiAiZGlkOmlkaW46MDQ4Y2EyM2M3ZWRmYjcxNjU1Y2I2ZGM1NjI4YzgzMjc4MTZlZGZjYjM3Nzk2M2RlZWNiYTNhM2U5MWU1ZjhiMCIsICJub25jZSI6IDF9",
    "signature": "MEUCIQCOKd+bLX69VEmLV8PA7X9/22el2X56WplZG+iCHV+hdAIgZnLZDi6yQ2/siv7VEhb1TeeGCvU/7Db22zSPzAD/GZQ="
}
```

### 2. Approves a resetter revocation:

```
{
    "operation": "did_resetter_approve",
    "did_address": "did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEh0qHd7FcTODcLPj6Hy4QB8EXPq01\nL0yNT0aynCtrqee4fLKkWcOk5N2vz0TQ6yvogkNFD+N7fyHbcuEvnu5/ow==\n-----END PUBLIC KEY-----",
    "next_key_hash": "7b8fa478e5f445bac96c2960b71b4a6dbdf5bcedf14fd56915399e71d590c07b",
    "consensus": "did_revoke_resetters|did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5|did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0",
    "nonce": 6
}
```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "eyJjb25zZW5zdXMiOiAiZGlkX3Jldm9rZV9yZXNldHRlcnN8ZGlkOmlkaW46YWZiN2JhODhjNzZlZGJkYTU1YzM0NGI3MGFlMGNmMDU1NmQ3NzBlYzI1NjgyMGQ3MTg1MDAwZGUzOTUzOTFiNXxkaWQ6aWRpbjowNDhjYTIzYzdlZGZiNzE2NTVjYjZkYzU2MjhjODMyNzgxNmVkZmNiMzc3OTYzZGVlY2JhM2EzZTkxZTVmOGIwIiwgImN1cnJlbnRfa2V5IjogIi0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXG5NRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVoMHFIZDdGY1RPRGNMUGo2SHk0UUI4RVhQcTAxXG5MMHlOVDBheW5DdHJxZWU0ZkxLa1djT2s1TjJ2ejBUUTZ5dm9na05GRCtON2Z5SGJjdUV2bnU1L293PT1cbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLSIsICJuZXh0X2tleV9oYXNoIjogIjdiOGZhNDc4ZTVmNDQ1YmFjOTZjMjk2MGI3MWI0YTZkYmRmNWJjZWRmMTRmZDU2OTE1Mzk5ZTcxZDU5MGMwN2IiLCAib3BlcmF0aW9uIjogImRpZF9yZXNldHRlcl9hcHByb3ZlIiwgImRpZF9hZGRyZXNzIjogImRpZDppZGluOjA0OGNhMjNjN2VkZmI3MTY1NWNiNmRjNTYyOGM4MzI3ODE2ZWRmY2IzNzc5NjNkZWVjYmEzYTNlOTFlNWY4YjAiLCAibm9uY2UiOiAyfQ==",
    "signature": "MEQCIC3/LHAO4W6J4hXxnFyjLBcuGPGrdq5ksyrbxcJcZO8TAiAwnn2UyKXYcFlxUDxTmMA9dHxFnzDCXDA7somw21Z3jA=="
}
```

### 3. Approve a DID reset:

```
{
    "consensus": "did_reset|did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5|did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0",
    "new_key_hash": "0874c5673691f7d08a6846fbfeb1f08595ea07c7002e18b2c382f3d4be7fc3f1",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEB1w2xiPd6UPTMd5zM3qLb66yNPVL\nkRwq7qM5Gmgf4+NDeJBWWxy/u8bL9VwTdPXhm9f91aHwPu5/BMln05SxPA==\n-----END PUBLIC KEY-----",
    "next_key_hash": "f91ce1eabfd805562d4c58ea59674129ef17a510022b2ade24593ca73d8c08b4",
    "operation": "did_resetter_approve",
    "did_address": "did:idin:048ca23c7edfb71655cb6dc5628c8327816edfcb377963deecba3a3e91e5f8b0",
    "nonce": 4
}
```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "eyJjb25zZW5zdXMiOiAiZGlkX3Jldm9rZV9yZXNldHRlcnN8ZGlkOmlkaW46YWZiN2JhODhjNzZlZGJkYTU1YzM0NGI3MGFlMGNmMDU1NmQ3NzBlYzI1NjgyMGQ3MTg1MDAwZGUzOTUzOTFiNXxkaWQ6aWRpbjowNDhjYTIzYzdlZGZiNzE2NTVjYjZkYzU2MjhjODMyNzgxNmVkZmNiMzc3OTYzZGVlY2JhM2EzZTkxZTVmOGIwIiwgImN1cnJlbnRfa2V5IjogIi0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXG5NRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVRRlZNNktNMDlzWjRVWm8zUE1tYkRlMSt6am5OXG5BcmF1TjlEUjBDTmVRb20ybi9COUFDVHZRT3pua0VCTTNiRW4xdmtkeWRiZExVcC9lcXRVWFdhbDlnPT1cbi0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLSIsICJuZXh0X2tleV9oYXNoIjogImZmMjM4NThlYTAzYmZmZGQ0NTA2MjI3NGVlNzQ2ZmI4ZWFiOGU0ZmFkYTcyYzA0YmM1MjZjZmU5MjdjYzFlNDMiLCAib3BlcmF0aW9uIjogImRpZF9yZXNldHRlcl9hcHByb3ZlIiwgImRpZF9hZGRyZXNzIjogImRpZDppZGluOjA0OGNhMjNjN2VkZmI3MTY1NWNiNmRjNTYyOGM4MzI3ODE2ZWRmY2IzNzc5NjNkZWVjYmEzYTNlOTFlNWY4YjAiLCAibm9uY2UiOiAzfQ==",
    "signature": "MEQCIDdve4Sa1O52Dl3IoI1x9pkSssYP//qJps8RDH4ZCRVJAiApNRuwiT0zD3rUtaSE9KArV4OAs4qYkgbwAwZPvKNkCA=="
}
```


# GET DID Nonce

With the exception of DID registration (`did_register`), each HTTP request to the IDIN server must contain a request nonce (`"nonce"`). A nonce is bound to a DID address and starts at one for the first HTTP request after the DID registration. The DID nonce then increases by one for every request, and as a result it counts to the total number of requests that the DID has made.

The current nonce of a DID (`<did_address>`) can be obtained with a GET request.

{% hint style="danger" %}
If the input nonce (`"nonce"`) in a HTTP request does not match the current nonce of the given DID, the request will be rejected by the IDIN server.
{% endhint %}

<mark style="color:blue;">`GET`</mark> `https://test-network.finema.co/did/<did_address>/nonce`

{% tabs %}
{% tab title="200 The current nonce of the DID (\<did\_address>) will be given as the response." %}

```
{
    "did_address": "did:idin:9cd19d4cbab9ca1d6f4c6a4b9117fb8904f250b47307cf4f484424f44e0c8370",
    "nonce": 17
}
```

{% endtab %}

{% tab title="422 The error message will be given as the response if the given DID address does not exist." %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}


# VC API

## Overview

The VC API provides a collection of [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) request methods that involves Verifiable Credentials (VCs). This API allows a credential issuer to register a new VC with the `vc_register` operation or revoke an exisiting VC the `vc_revoke` operation. When a credential holder presents a VC to a credential verifier, the verifier could then obtain the VC's verification key with a GET request.

In the same way as the [DID API](https://app.gitbook.com/@balll/s/finema-docs/api-tutorials/api), HTTP requests to a IDIN server must be in the JSON format with two attributes `"message"` and `"signature"`. One distinction to the DID API is the GET method for a VC's verification key that requires no request body.

```
{
    "message": "eyJjdXJyZW50X2tleSI6ICItLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxuTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFdDBha0ZjUXE2eklacXpXV3FHY01mMUxIRXNtTVxuanlyb2Vla0lVbVZkRnkzMTVsZHhjbjJmUHpQcXlqSlZvbEpSdm9SYVZvWlpaalpDQnp5NHlBU3hxdz09XG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0iLCAibmV4dF9rZXlfaGFzaCI6ICI1MThiN2U5ZTRmY2EzNjVkZmY3YjZmNmQ0NTA5YmJlMjk5MDAzN2E4OGQ3NjMzZWYwZmFhYWRlYmEzNTEyM2VkIiwgIm9wZXJhdGlvbiI6ICJ2Y19yZWdpc3RlciIsICJkaWRfYWRkcmVzcyI6ICJkaWQ6aWRpbjphZmI3YmE4OGM3NmVkYmRhNTVjMzQ0YjcwYWUwY2YwNTU2ZDc3MGVjMjU2ODIwZDcxODUwMDBkZTM5NTM5MWI1IiwgIm5vbmNlIjogNX0=",
    "signature": "MEUCIFSbmMEUcyjSYwq4QOXWZewn+xS/Jih04DRGKwNKlkQnAiEAuH3Es1opQ3LTTYbwyTJylskbaZOl7vSAF9RFp2Qn3TI="
}
```

## Types of Requests

The table below summarizes all VC-related HTTP requests to the IDIN server.

| Request Method                                                                                                            | Description                     | HTTP Method |
| ------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | :---------: |
| [`vc_register`](https://app.gitbook.com/@balll/s/finema-docs/~/drafts/-M8ExDvnDBnoTJneay9S/api/register-a-new-did)        | Register a new VC.              |     POST    |
| [`vc_revoke`](https://app.gitbook.com/@balll/s/finema-docs/~/drafts/-M8ExDvnDBnoTJneay9S/api/add-a-new-public-key-series) | Revoke a VC.                    |    DELETE   |
|                                                                                                                           | Get a verification key of a VC. |     GET     |


# VC Registration

A credential issuer can register a new VC with `vc_register` operation. In the request message, the credential issuer must specify the current public key (`"current_key"`) in a valid key series and the SHA-256 hash of the next public key (`"next_key_hash"`).  The request message is then encoded in Base64 and signed by the current private key. Once the VC is registered, the server will respond with the VC's unique CID.

Once the credential issuer obtains a CID from the IDIN server, the issuer can then generate and send a VC with that CID to the credential holder.

{% hint style="info" %}
The private key that is used to sign a `vc_register` request must be the same key that is used to sign the VC. This ensures the VC can be verified with `"current_key"` that is recorded in the IDIN blockchain.
{% endhint %}

## vc\_register

<mark style="color:green;">`POST`</mark> `https://test-network.finema.co/vc`

#### Request Body

| Name            | Type   | Description                                                                         |
| --------------- | ------ | ----------------------------------------------------------------------------------- |
| operation       | string | The method's name that is "vc\_register".                                           |
| did\_address    | string | The DID address.                                                                    |
| current\_key    | string | The current public key in the series. It is used to verify the request's signature. |
| next\_key\_hash | string | The SHA-256 hash of the next public key in the series.                              |
| nonce           | number | The request nonce.                                                                  |

{% tabs %}
{% tab title="200 The operation name, DID address and the CID for the added VC will be given as the response." %}

```
{
  "operation": "vc_register",
  "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
  "cid": "c118304cfcc011eaaca30242c0a83005"
}
```

{% endtab %}

{% tab title="422 " %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Example Message and Request

```
{
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEt0akFcQq6zIZqzWWqGcMf1LHEsmM\njyroeekIUmVdFy315ldxcn2fPzPqyjJVolJRvoRaVoZZZjZCBzy4yASxqw==\n-----END PUBLIC KEY-----",
    "next_key_hash": "518b7e9e4fca365dff7b6f6d4509bbe2990037a88d7633ef0faaadeba35123ed",
    "operation": "vc_register",
    "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
    "nonce": 5
}
```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "eyJjdXJyZW50X2tleSI6ICItLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLVxuTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFdDBha0ZjUXE2eklacXpXV3FHY01mMUxIRXNtTVxuanlyb2Vla0lVbVZkRnkzMTVsZHhjbjJmUHpQcXlqSlZvbEpSdm9SYVZvWlpaalpDQnp5NHlBU3hxdz09XG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0iLCAibmV4dF9rZXlfaGFzaCI6ICI1MThiN2U5ZTRmY2EzNjVkZmY3YjZmNmQ0NTA5YmJlMjk5MDAzN2E4OGQ3NjMzZWYwZmFhYWRlYmEzNTEyM2VkIiwgIm9wZXJhdGlvbiI6ICJ2Y19yZWdpc3RlciIsICJkaWRfYWRkcmVzcyI6ICJkaWQ6aWRpbjphZmI3YmE4OGM3NmVkYmRhNTVjMzQ0YjcwYWUwY2YwNTU2ZDc3MGVjMjU2ODIwZDcxODUwMDBkZTM5NTM5MWI1IiwgIm5vbmNlIjogNX0=",
    "signature": "MEUCIFSbmMEUcyjSYwq4QOXWZewn+xS/Jih04DRGKwNKlkQnAiEAuH3Es1opQ3LTTYbwyTJylskbaZOl7vSAF9RFp2Qn3TI="
}
```


# VC Revocation

A credential issuer can revoke any of her issued VCs with `vc_revoke` operation by specifying the CID (`<cid>`) of the revoked VC.

## vc\_revoke

<mark style="color:red;">`DELETE`</mark> `https://test-network.finema.co/vc/<cid>`

#### Request Body

| Name            | Type   | Description                                                                         |
| --------------- | ------ | ----------------------------------------------------------------------------------- |
| operation       | string | The method's name that is "add\_key".                                               |
| did\_address    | string | The DID address.                                                                    |
| current\_key    | string | The current public key in the series. It is used to verify the request's signature. |
| next\_key\_hash | string | The SHA-256 hash of the next public key in the series.                              |
| cid             | string | The CID of the revoked VC.                                                          |
| nonce           | number | The request nonce.                                                                  |

{% tabs %}
{% tab title="200 The operation name, DID address (\<did\_address>) and the CID for the revoked VC will be given as the response." %}

```
{
  "operation": "vc_revoke",
  "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
  "cid": "c118304cfcc011eaaca30242c0a83005"

}
```

{% endtab %}

{% tab title="422 " %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Example Message and Request

```
{
    "operation": "vc_revoke",
    "did_address": "did:idin:afb7ba88c76edbda55c344b70ae0cf0556d770ec256820d7185000de395391b5",
    "current_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5HqmOXLJKDEbUahls2jFWsPSSPIL\n+HchIT2ScHdKqrPzRIiS/Wz13s9gAdtd5ayygxnVW2RLQsq0kxq6FS05Jw==\n-----END PUBLIC KEY-----",
    "next_key_hash": "cd950c9074f7dd6f7b549bb6dcd8d443db440492c1c75c6cf63958494f60ce43",
    "cid": "c118304cfcc011eaaca30242c0a83005",
    "nonce": 6
}
```

The above message can then be encoded in Base64 and signed with ECDSA to obtain the following HTTP request

```
{
    "message": "eyJjaWQiOiAiYzExODMwNGNmY2MwMTFlYWFjYTMwMjQyYzBhODMwMDUiLCAiY3VycmVudF9rZXkiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRTVIcW1PWExKS0RFYlVhaGxzMmpGV3NQU1NQSUxcbitIY2hJVDJTY0hkS3FyUHpSSWlTL1d6MTNzOWdBZHRkNWF5eWd4blZXMlJMUXNxMGt4cTZGUzA1Snc9PVxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tIiwgIm5leHRfa2V5X2hhc2giOiAiY2Q5NTBjOTA3NGY3ZGQ2ZjdiNTQ5YmI2ZGNkOGQ0NDNkYjQ0MDQ5MmMxYzc1YzZjZjYzOTU4NDk0ZjYwY2U0MyIsICJvcGVyYXRpb24iOiAidmNfcmV2b2tlIiwgImRpZF9hZGRyZXNzIjogImRpZDppZGluOmFmYjdiYTg4Yzc2ZWRiZGE1NWMzNDRiNzBhZTBjZjA1NTZkNzcwZWMyNTY4MjBkNzE4NTAwMGRlMzk1MzkxYjUiLCAibm9uY2UiOiA2fQ==",
    "signature": "MEUCIQDUBm3n9ZrchAl/5QQYzFlhQXlQ9lI9yhJePAmvUnJ8yQIgBoJ5HcZjv/9PnJ4dSyiLFqsTPlX6y3L2f5Z3Lp9hjlA="
}
```


# GET VC Verification Key

To verify a VC, a verifier could use the VC's CID (`<cid>`) to request for a verification key of the VC with a GET request method. The verification key can then be used to decrypt the VC's digital signature to obtain a hash value. The verifier can be certained that the VC has not been tempered if the obtained hash matches with the VC's hash.

<mark style="color:blue;">`GET`</mark> `https://test-network.finema.co/vc/<cid>`

{% tabs %}
{% tab title="200 The issuer DID address, the CID (<cid>) of the VC and its verification key will be given as the response." %}

```
{
    "did_address": "did:idin:9cd19d4cbab9ca1d6f4c6a4b9117fb8904f250b47307cf4f484424f44e0c8370",
    "cid": "c498bdd8a72811eabca70242c0a82004",
    "verification_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeR8NhQeHPT7l1yMyvkZMacPpibjH\n7mp5IRyO2J2kuE97h/fzu1c/7DFsO23qUN6/OezYglMEkoVo5Ob1b6k53A==\n-----END PUBLIC KEY-----"
}
```

{% endtab %}

{% tab title="422 The error message will given as the response if given CID does not exist or if the VC has been revoked." %}

```
{
    "errors": [
        {
           "status": 422,
            "title": "Invalid Attribute",
            "detail": "the server cannot process the request",
        }
    ]
}
```

{% endtab %}
{% endtabs %}

##


