This demo, implemented with NestJS, is a backend that supports the issuance and verification flows of verifiable credentials using the OpenID4VCI and SIOPv2 standards. The goal is to demonstrate how an issuing entity (such as a fictional university called Melon University) can issue diplomas as verifiable credentials and how another verifying entity (such as a fictional corporation called Mango Corp) can validate these credentials.
This demo is based on the implementation of several open-source libraries that are part of the KayDev project. These libraries are fundamental for managing the issuance and verification flows of verifiable credentials:
-
@kaytrust/did-near
Implements support for the decentralized identity (DID) method on the NEAR blockchain. -
@kaytrust/did-ethr
Provides support for the DID method on the Ethereum blockchain. -
@kaytrust/did-near-resolver
Allows resolving DID documents on the NEAR blockchain. -
@kaytrust/openid4vci
Implements the OpenID4VCI standard for issuing verifiable credentials. -
@kaytrust/prooftypes
Provides types and validations for cryptographic proofs in verifiable credentials.
These libraries are essential for implementing the flows in this demo, as they enable the management of decentralized identities and verifiable credentials in a standardized and secure manner.
- Prerequisites
- Installation and Configuration
- Running the Project
- Project Structure
- Main Modules
- Environment Variables
- Implemented Flows
- Testing
- Additional Resources
Before starting, make sure you have the following installed:
git clone https://github.com/kaytrust/demo-acme-frutas-back.git
cd demo-acme-frutas-backyarn installCreate a .env file in the project's root directory and define the necessary environment variables. You can use the .env.example file as a reference:
cp .env.example .envEdit the .env file to configure the variables according to your needs. Below, all available variables are described.
The project uses several environment variables defined in the configuration files within src/configs/*.config.ts. These variables allow you to customize the application's behavior. Below is a list of all variables, indicating which are mandatory and which have default values.
| Variable | Description | Mandatory | Default Value | Example |
|---|---|---|---|---|
NODE_ENV |
Execution environment (development, production, etc.) |
No | production |
development |
PORT |
Port on which the application will run | No | 3000 |
4000 |
FORCE_HTTPS |
Force the use of HTTPS for requests | No | false |
true |
ORIGINS |
List of allowed URLs for CORS, separated by commas | No | http://localhost:4200 |
http://example.com,http://localhost:4200 |
| Variable | Description | Mandatory | Default Value | Example |
|---|---|---|---|---|
AUTHORIZATION_SERVER |
URL of the authorization server for OpenID4VCI | Yes | N/A | https://auth.example.com/auth/realms/demo |
MELON_PRIVATE_KEY |
Issuer's private key (Melon University) | Yes | N/A | 0xca3e19805a1e71d557346f4aa66f4b17d9f4bd9c2e1f2d6fbfd9a4ff8118ce6e |
MELON_ISSUER_NAME |
Issuer's name | No | melon_university |
melon_university |
MELON_ETHR_DID |
Issuer's DID for the ethr method |
No | Automatically generated | did:ethr:0x1234567890abcdef |
MELON_NEAR_DID |
Issuer's DID for the near method |
No | Automatically generated | did:near:example.testnet |
| Variable | Description | Mandatory | Default Value | Example |
|---|---|---|---|---|
JWKS_URI |
URL of the JWKS server to validate JWT tokens | Yes | N/A | https://auth.example.com/protocol/openid-connect/certs |
USERINFO_URI |
URL of the Keycloak userinfo endpoint to fetch user details | Yes | N/A | https://auth.example.com/protocol/openid-connect/userinfo |
| Variable | Description | Mandatory | Default Value | Example |
|---|---|---|---|---|
ETHR_RPC_URL |
RPC node URL for the Ethereum network | Yes | N/A | https://mainnet.infura.io/v3/YOUR-PROJECT-ID |
ETHR_CHAIN_ID |
Ethereum chain ID | No | 80002 |
1 |
ETHR_REGISTRY |
Registry contract address for ethr DID |
No | 0xBC56d0883ef228b2B16420E9002Ece0A46c893F8 |
0xdCa7EF03e98e0DC2B855bE647C39ABe984fcF21B |
| Variable | Description | Mandatory | Default Value | Example |
|---|---|---|---|---|
FRONTEND_BASE_URL |
Base URL of the frontend | No | http://localhost:4200 |
http://example.com |
yarn start:dev-
Compile the project:
yarn build
-
Start the server:
yarn start:prod
The project is organized into modules, each with specific responsibilities. Below are the main modules:
- Loads the configurations defined in
src/configs/*.config.ts. - Centralizes environment variables and allows access throughout the application.
- Manages authentication using JWT.
- Validates tokens sent in the
Authorizationheader of requests.
- Manages the database connection (default is SQLite).
- Automatically creates the database if it does not exist.
- Implements a WebSocket server for real-time communications.
- Allows notifying the client of events, such as the receipt of verifiable credentials.
- Intercepts logs generated in the application.
- Saves logs to files to facilitate debugging in production.
- Implements the OpenID4VCI flow for issuing verifiable credentials.
- Main routes:
GET :issuer_name/.well-known/openid-credential-issuer: Returns all supported credentials by the issuer, including formats and credential types. For example, if the issuer supports 5 types of credentials, this route will list them all.GET :issuer_name/credential-offer: Returns a subset of credentials that the issuer is offering to the user at that moment. For example, out of the 5 supported types, it may offer only 1 or 2 based on the user's needs.POST :issuer_name/credential/issue: Issues a verifiable credential after validating the user's request.
- Implements the SIOPv2 flow for verifying shared credentials.
- Verifies that the credentials are valid and redirects to the frontend with the result.
- The client requests the supported credentials (
GET :issuer_name/.well-known/openid-credential-issuer). - The client requests the credentials the issuer is offering (
GET :issuer_name/credential-offer). - The client sends a request to issue a credential (
POST :issuer_name/credential/issue). - The server validates the request and issues the credential in JWT format.
- The client shares a verifiable credential with the verifier.
- The server validates the credential and its cryptographic proof.
- If the credential is valid, it redirects to the frontend with a success message; otherwise, it redirects with an error message.
yarn testyarn test:cov