This is a ready-to-use reference app that showcases usage of Affinidi API for issuing, sharing, verifying and storing verifiable credentials in the wallet.
Certification & Verification app allows you to issue, verify and store VCs in your wallet.
You can take a role of an issuer, verifier or holder entity.
With this app it's possible to create flows without ever storing user's data, while still being able to verify it.
Users are responsible for their data and can store it in any way they want.
The app has multiple implementations which are designed for industry-specific use cases, making it an end-to-end example of a real app that you can deploy and use right away.
Setting up the reference app is easy, just follow these steps:
-
Clone the repo:
$ git clone git@github.com:affinidi/reference-app-certification-and-verification.git $ cd reference-app-certification-and-verification $ cd use-cases/{use-case}
-
Install the dependencies:
$ npm install
-
Create a
.env
file:$ cp .env.example .env
Enter values for
NEXT_PUBLIC_PROJECT_ID
,NEXT_PUBLIC_PROJECT_DID
andNEXT_PUBLIC_API_KEY_HASH
from your Affinidi project properties.For all aps u can find two variables:
ISSUER_LOGIN
andISSUER_HASH_PASSWORD
. This is only an example of usage, and it should be replaced with appropriate auth mechanism (e.g. OAuth or any other match your requirements). To create/updateISSUER_HASH_PASSWORD
you should encode your password withbcrypt
algorithm and additional salt/rounds.const bcrypt = require("bcrypt"); function hashPassword(password, salt) { return bcrypt.hashSync(password, salt); }
-
Launch the app:
$ npm run dev
App will be available locally on http://localhost:3000.
Note: To log in as issuer, use these credentials (customizable in the
.env
file):
Login: issuer
Password: test
We have created multiple implementations of the same app for you to use.
These are called "use cases" and they're adapted for a specific industry.
Issue, verify and store tickets for events, such as concerts, conferences, meetups, etc.
As a ticket seller (issuer), you can enter details of the event and generate a ticket for a participant (holder).
The concert attendee (holder) can then store that ticket in their wallet and share it as a QR code with the security guard at the entrance of the event (verifier).
When the event starts, security guard (verifier) can quickly verify that the ticket is valid by scanning the QR code.
Issue, verify and store prescriptions for medications.
As a doctor (issuer), you can enter details of the medications (dosage, frequency, etc.) and generate a prescription for a patient (holder).
The patient (holder) can then store that prescription in their wallet and share it as a QR code with the pharmacist when collecting their medications from the pharmacy (verifier).
The pharmacist (verifier) can quickly verify that the prescription is valid by scanning the QR code.
Issue, verify and store course certificates.
As an educational institute (issuer), you can enter details of a certification and generate a certificate for a student (holder).
The student (holder) can then store that certificate in their wallet and share it as a QR code with a recruiter or interviewer (verifier).
A recruiter or interviewer (verifier) can quickly verify that the certificate is valid by scanning the QR code.
There are three flows in the app: issuer, verifier and holder.
- Authenticate into your Affinidi account,
- Enter credential subject details and holder information,
- Click "Issue".
Claim link will be sent to the holder's email address.
- Open the offer email in your inbox,
- Click on the claim link,
- Authenticate into your wallet,
- Claim the credential and store it your wallet.
Note: You need to claim at least one VC to perform this flow.
- Authenticate into your wallet,
- Select a VC that you want to share,
- Show the QR code to the verifier.
Verifier can then read the QR code and determine whether your VC is valid or not.
- Open the scanner page,
- Hold the QR code in front of the camera to scan it,
- Check the results of the verification.
Verifiable Credential (VC) – a tamper-evident credential that has authorship that can be cryptographically verified.
In this app, tickets, prescriptions and certificates are the subjects of the issued verifiable credentials.
Read W3C specification.
Holder – an entity that owns the verifiable credential. Usually, a holder is the subject of the credential that they hold.
A holder in the app is a person who stores issued VCs in their wallet.
Issuer – an entity that issues the verifiable credential to the holder.
Issuer in this app is the entity that owns the app itself and signs the credentials. For example: a university, a clinic or a ticket sales company.
Verifier – an entity that accepts verifiable credentials to verify their validity and authorship.
Verifier is an entity that accepts the VCs and verifies their authorship and validity.
Wallet (Cloud Wallet) – a service that provides functionality to sign credentials (for issuers) and to store credentials in the wallet (for holders).
This app uses the Affinidi Cloud Wallet API for authentication, holder credential storage and credential issuance.
Issuance API – a service that provides functionality to offer VCs by sending a claim link to the holder's email address. Holder then opens the link and stores the issued VC in their wallet.
This app uses the Affinidi VC Issuance API for performing the Claim Flow.
Learn more about VCs, trust triangle and Decentralized Identifiers (DIDs).
You might want to install an extension to view these Mermaid diagrams.
We'll use "Health" use case as an example.
sequenceDiagram; autonumber
actor Issuer
participant App
participant Issuance as Issuance API
participant IW as Issuer's Wallet
actor Holder
Issuer->>App: Enters medicine (name, dosage, frequency)<br/>and patient details (name, email)
App->>Issuance: Initiates claim flow with provided details<br/>and patient's email (holder)
Issuance->>Issuance: Stores the offer with provided details (credential subject)
Issuance-->>IW: Generates a credential offer request token
IW-->>Issuance: Credential offer request token
Issuance-->>Holder: Sends an email with a claim link including the credential offer request token
Issuance->>App: (ok)
App->>Issuer: (ok)
sequenceDiagram; autonumber
actor Holder
participant App
participant HW as Holder's Wallet
participant Issuance as Issuance API
participant IW as Issuer's Wallet
Holder->>App: Follows the claim link
App->>HW: Claim the credential<br/>with the credential offer request token
HW->>HW: Generate a credential offer response token<br/>with the holder's DID
HW->>Issuance: Claim VC using the credential offer response token
Issuance-->>Issuance: Build the VC with Holder's DID<br/>and provided credential subject
Issuance-->>IW: Sign the VC
IW-->>Issuance: Signed VC
Issuance->>HW: Signed VC
HW->>HW: Store the VC
HW->>App: (ok)
App->>Holder: Show the claimed VC
sequenceDiagram
autonumber
actor Holder
participant App
participant HW as Holder's Wallet
Holder->>App: Select a VC to share
App->>HW: Generate a QR code for sharing the VC
HW->>App: QR code
App->>Holder: Show the QR code
sequenceDiagram
autonumber
actor Holder
actor Verifier
participant App
participant CW as Cloud Wallet
participant VerifierAPI as Verifier API
Holder-->>Verifier: Show the QR code
Verifier->>App: Scan the QR code<br/>and extract credential share token
App->>CW: Fetch the shared VC<br/>using the credential share token
CW->>App: Shared VC
App->>VerifierAPI: Verify the VC
VerifierAPI->>App: Verification result
App->>Verifier: Verification result
This project is built with NextJS framework, which allows you to quickly build apps using TypeScript and React. NextJS has built-in router, server-side rendering and backend support. Read NextJS docs, React docs.
We also use Styled Components and Tailwind CSS to build the UI.
Read Styled Components docs, Tailwind CSS docs.
To make API requests, axios library is used.
Read axios docs.
Backend requests are validated with zod and logged with pino.
Read Zod docs, pino docs.
Affinidi collects usage data to improve our products and services. For information on what data we collect and how we use your data, please refer to our Privacy Policy.
Click here to create a ticket and we will get on it right away. If you are facing technical or other issues, you can reach out to us on Discord.
Affinidi Developer Tools are currently in the open beta phase and we are refining our product every day. The Affinidi Developer Tools may be incomplete and may contain errors – they may be unstable and may cause a loss of functionality and data. Use of the Affinidi Developer Tools will be at your own risk. As our engineers seek to improve our platform, we would not have the resources to provide any maintenance or tech support at this time. Please bear with us as we continue to improve the platform.
You are only limited by your imagination! Affinidi Developer Tools is a toolbox with which you can build software apps for personal or commercial use.
We only provide the tools - how you use them is largely up to you. We have no control over what you develop with our tools - but please use our tools responsibly!
We hope that you would not develop anything that contravenes any applicable laws or regulations. Your projects should also not infringe on Affinidi’s or any third party’s intellectual property (for instance, misusing other parties’ data, code, logos, etc).
Please ensure that you have in place your own terms and conditions, privacy policies, and other safeguards to ensure that the projects you build are secure for your end users.
If you are processing personal data, please protect the privacy and other legal rights of your end-users and store their personal or sensitive information securely.
Some of our components would also require you to incorporate our end-user notices into your terms and conditions.
Affinidi Developer Tools are free during the open beta phase, so come onboard and experiment with our tools and see what you can build! We may bill for certain components in the future, but we will inform you beforehand.
We may from time to time impose limits on your use of the Affinidi Developer Tools, such as limiting the number of API requests that you may make in a given duration. This is to ensure the smooth operation of the Affinidi Developer Tools so that you and all our other users can have a pleasant experience as we continue to scale and improve the Affinidi Developer Tools.
From time to time, we may request certain information from you to ensure that you are complying with the Terms of Use.
When you create a developer’s account with us, we will issue you your private login credentials. Please do not share this with anyone else, as you would be responsible for activities that happen under your account. If you have friends who are interested, ask them to sign up – let's build together!
Please note that this FAQ is provided for informational purposes only and is not to be considered a legal document. For the legal terms and conditions governing your use of the Affinidi Developer Tools, please refer to our Terms of Use.