---
url: 'https://www.corbado.com/hi/blog/digital-credential-verifier-kaise-banaye'
title: 'डिजिटल क्रेडेंशियल वेरिफ़ायर कैसे बनाएँ (डेवलपर गाइड)'
description: 'Next.js, OpenID4VP, और ISO mDoc का उपयोग करके शुरुआत से डिजिटल क्रेडेंशियल वेरिफ़ायर बनाना सीखें। यह चरण-दर-चरण डेवलपर गाइड दिखाता है कि एक ऐसा वेरिफ़ायर कैसे बनाया जाए जो मोबाइल ड्राइविंग लाइसेंस और अन्य डिजिटल क्रेडेंशियल का अनुरोध, प्राप्त और मान्य कर '
lang: 'hi'
author: 'Amine'
date: '2025-08-20T15:39:29.865Z'
lastModified: '2026-03-25T10:07:36.863Z'
keywords: 'डिजिटल क्रेडेंशियल वेरिफ़ायर, ट्यूटोरियल वेरिफ़ायर, वेरिफ़ायर बनाएँ'
category: 'Digital Credentials'
---

# डिजिटल क्रेडेंशियल वेरिफ़ायर कैसे बनाएँ (डेवलपर गाइड)

## 1. परिचय

ऑनलाइन पहचान साबित करना एक लगातार चुनौती बनी हुई है, जिसके कारण हम पासवर्ड पर निर्भर रहते
हैं और असुरक्षित चैनलों पर संवेदनशील दस्तावेज़ साझा करते हैं। इसने व्यवसायों के लिए पहचान
सत्यापन को एक धीमी, महंगी और धोखाधड़ी-प्रवण प्रक्रिया बना दिया है। डिजिटल क्रेडेंशियल एक
नया दृष्टिकोण प्रदान करते हैं, जो उपयोगकर्ताओं को उनके डेटा का नियंत्रण वापस देते हैं। वे
एक भौतिक वॉलेट के डिजिटल समकक्ष हैं, जिसमें ड्राइविंग लाइसेंस से लेकर विश्वविद्यालय की
डिग्री तक सब कुछ होता है, लेकिन क्रिप्टोग्राफ़िक रूप से सुरक्षित, गोपनीयता-संरक्षित और
तुरंत सत्यापन योग्य होने के अतिरिक्त लाभों के साथ।

यह गाइड डेवलपर्स को डिजिटल क्रेडेंशियल के लिए एक वेरिफ़ायर बनाने के लिए एक व्यावहारिक,
चरण-दर-चरण ट्यूटोरियल प्रदान करता है। हालाँकि मानक मौजूद हैं, लेकिन उन्हें लागू करने के
बारे में बहुत कम मार्गदर्शन है। यह ट्यूटोरियल उस कमी को पूरा करता है, यह दिखाता है कि
ब्राउज़र के नेटिव डिजिटल क्रेडेंशियल API, प्रेजेंटेशन प्रोटोकॉल के लिए
[OpenID4VP](https://www.corbado.com/glossary/open-id-4-vp) और क्रेडेंशियल प्रारूप के रूप में ISO
[mDoc](https://www.corbado.com/glossary/mdoc) (जैसे, मोबाइल ड्राइविंग लाइसेंस) का उपयोग करके एक वेरिफ़ायर कैसे
बनाया जाए।

अंतिम परिणाम एक सरल लेकिन कार्यात्मक [Next.js](https://www.corbado.com/blog/nextjs-passkeys) एप्लिकेशन होगा जो एक
संगत मोबाइल वॉलेट से एक डिजिटल क्रेडेंशियल का अनुरोध, प्राप्त और सत्यापित कर सकता है।

यहाँ अंतिम एप्लिकेशन का एक त्वरित अवलोकन है। इस प्रक्रिया में चार मुख्य चरण शामिल हैं:

**चरण 1: प्रारंभिक पृष्ठ** उपयोगकर्ता प्रारंभिक पृष्ठ पर आता है और प्रक्रिया शुरू करने के
लिए "डिजिटल पहचान के साथ सत्यापित करें" पर क्लिक करता है।
![सत्यापन अनुरोध के लिए प्रारंभिक पृष्ठ](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/Screenshot_2025_07_25_at_11_00_33_5217b35c96.png)

**चरण 2: ट्रस्ट प्रॉम्प्ट** ब्राउज़र उपयोगकर्ता से विश्वास के लिए पूछता है। उपयोगकर्ता आगे
बढ़ने के लिए "जारी रखें" पर क्लिक करता है।
![ब्राउज़र ट्रस्ट प्रॉम्प्ट](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/Screenshot_2025_07_25_at_11_00_39_ba390a8097.png)

**चरण 3: QR कोड स्कैन** एक QR कोड प्रदर्शित होता है, जिसे उपयोगकर्ता अपने संगत वॉलेट
एप्लिकेशन के साथ स्कैन करता है।
![स्कैनिंग के लिए QR कोड](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/Screenshot_2025_07_25_at_11_00_45_3b30669a10.png)

**चरण 4: डीकोडेड क्रेडेंशियल** सफल सत्यापन के बाद, एप्लिकेशन डीकोडेड क्रेडेंशियल डेटा
प्रदर्शित करता है।
![डीकोडेड क्रेडेंशियल परिणाम](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/Screenshot_2025_07_25_at_11_01_36_684f7489cd.png)

### 1.1 यह कैसे काम करता है

डिजिटल क्रेडेंशियल के पीछे का जादू एक सरल लेकिन शक्तिशाली "**ट्रस्ट ट्रायंगल**" मॉडल में
निहित है जिसमें तीन प्रमुख खिलाड़ी शामिल हैं:

- **Issuer (जारीकर्ता):** एक विश्वसनीय प्राधिकरण (जैसे, एक
  [सरकारी](https://www.corbado.com/passkeys-for-public-sector) एजेंसी, विश्वविद्यालय, या बैंक) जो
  क्रिप्टोग्राफ़िक रूप से एक क्रेडेंशियल पर हस्ताक्षर करता है और उसे एक उपयोगकर्ता को जारी
  करता है।
- **Holder (धारक):** उपयोगकर्ता, जो क्रेडेंशियल प्राप्त करता है और उसे अपने डिवाइस पर एक
  व्यक्तिगत डिजिटल वॉलेट में सुरक्षित रूप से संग्रहीत करता है।
- **Verifier (वेरिफ़ायर):** एक एप्लिकेशन या सेवा जिसे उपयोगकर्ता के क्रेडेंशियल की जाँच
  करने की आवश्यकता होती है।

![W3C वेरिफ़ाएबल क्रेडेंशियल इकोसिस्टम](https://www.w3.org/TR/vc-data-model/diagrams/ecosystem.svg)

जब कोई उपयोगकर्ता किसी सेवा तक पहुँचना चाहता है, तो वे अपने वॉलेट से क्रेडेंशियल प्रस्तुत
करते हैं। वेरिफ़ायर तब सीधे मूल जारीकर्ता से संपर्क किए बिना तुरंत उसकी प्रामाणिकता की
जाँच कर सकता है।

### 1.2 वेरिफ़ायर क्यों आवश्यक हैं (और आप यहाँ क्यों हैं)

इस **विकेंद्रीकृत पहचान पारिस्थितिकी तंत्र** के फलने-फूलने के लिए, **वेरिफ़ायर** की भूमिका
बिल्कुल महत्वपूर्ण है। वे इस नए विश्वास
[बुनियादी ढाँचे](https://www.corbado.com/passkeys-for-critical-infrastructure) के द्वारपाल हैं, जो क्रेडेंशियल का
उपभोग करते हैं और उन्हें वास्तविक दुनिया में उपयोगी बनाते हैं। जैसा कि नीचे दिए गए चित्र
में दिखाया गया है, एक वेरिफ़ायर धारक से क्रेडेंशियल का अनुरोध, प्राप्त और सत्यापन करके
ट्रस्ट ट्रायंगल को पूरा करता है।

यदि आप एक डेवलपर हैं, तो यह सत्यापन करने के लिए एक सेवा का निर्माण सुरक्षित और
उपयोगकर्ता-केंद्रित अनुप्रयोगों की अगली पीढ़ी के लिए एक मौलिक कौशल है। यह गाइड आपको ठीक
उसी प्रक्रिया के माध्यम से ले जाने के लिए डिज़ाइन किया गया है। हम आपको **अपना खुद का
वेरिफ़ाएबल क्रेडेंशियल वेरिफ़ायर बनाने** के लिए आवश्यक सब कुछ कवर करेंगे, मूल अवधारणाओं और
मानकों से लेकर हस्ताक्षरों को मान्य करने और क्रेडेंशियल स्थिति की जाँच करने के चरण-दर-चरण
कार्यान्वयन विवरण तक।

> **आगे बढ़ना चाहते हैं?** आप इस ट्यूटोरियल के लिए पूर्ण, समाप्त परियोजना GitHub पर पा
> सकते हैं। इसे क्लोन करने और स्वयं आज़माने के लिए स्वतंत्र महसूस करें:
> [https://github.com/corbado/digital-credentials-example](https://github.com/corbado/digital-credentials-example)

चलिए शुरू करते हैं।

## 2. वेरिफ़ायर बनाने के लिए आवश्यक शर्तें

शुरू करने से पहले, सुनिश्चित करें कि आपके पास है:

1. **डिजिटल क्रेडेंशियल और mdoc की बुनियादी समझ**
    - यह ट्यूटोरियल **ISO mDoc** प्रारूप (जैसे, मोबाइल ड्राइविंग लाइसेंस के लिए) पर
      केंद्रित है और W3C वेरिफ़ाएबल क्रेडेंशियल (VCs) जैसे अन्य प्रारूपों को कवर नहीं करता
      है। [mdoc](https://www.corbado.com/glossary/mdoc) की मूल अवधारणाओं से परिचित होना सहायक होगा।
2. **Docker और Docker Compose**
    - हमारी परियोजना OIDC सत्र स्थिति को प्रबंधित करने के लिए एक Docker कंटेनर में एक
      [MySQL](https://www.corbado.com/blog/passkey-webauthn-database-guide) डेटाबेस का उपयोग करती है। सुनिश्चित
      करें कि आपके पास दोनों स्थापित और चल रहे हैं।
3. **चुना हुआ प्रोटोकॉल: OpenID4VP**
    - हम क्रेडेंशियल एक्सचेंज प्रवाह के लिए **OpenID4VP** (OpenID for Verifiable
      Presentations) प्रोटोकॉल का उपयोग करेंगे।
4. **टेक स्टैक तैयार**
    - बैकएंड लॉजिक के लिए **TypeScript** (Node.js) का उपयोग करें।
    - बैकएंड (API रूट) और फ्रंटएंड (UI) दोनों के लिए **Next.js** का उपयोग करें।
    - मुख्य लाइब्रेरी: [mdoc](https://www.corbado.com/glossary/mdoc) पार्सिंग के लिए [CBOR](https://www.corbado.com/glossary/cbor)
      डीकोडिंग लाइब्रेरी और एक [MySQL](https://www.corbado.com/blog/passkey-webauthn-database-guide) क्लाइंट।
5. **टेस्ट क्रेडेंशियल और वॉलेट**
    - हम
      **[CMWallet](https://github.com/digitalcredentialsdev/CMWallet/actions/runs/16407676816/artifacts/3574255220)**
      का उपयोग करेंगे जो [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) के लिए है, जो
      [OpenID4VP](https://www.corbado.com/glossary/open-id-4-vp) अनुरोधों को समझता है और mdoc क्रेडेंशियल
      प्रस्तुत कर सकता है।
6. **बुनियादी क्रिप्टोग्राफी ज्ञान**
    - डिजिटल हस्ताक्षर और सार्वजनिक/निजी कुंजी अवधारणाओं को समझें क्योंकि वे mdoc और OIDC
      प्रवाह से संबंधित हैं।

---

अब हम इनमें से प्रत्येक पूर्वापेक्षा को विस्तार से देखेंगे, जिसकी शुरुआत मानकों और
प्रोटोकॉल से होगी जो इस mdoc-आधारित वेरिफ़ायर का आधार हैं।

### 2.1 प्रोटोकॉल विकल्प

हमारा वेरिफ़ायर निम्नलिखित के लिए बनाया गया है:

| मानक / प्रोटोकॉल                                                                          | विवरण                                                                                                                                                                                                                |
| :---------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **[W3C VC](https://www.w3.org/TR/vc-data-model/)**                                        | W3C वेरिफ़ाएबल क्रेडेंशियल डेटा मॉडल। यह डिजिटल क्रेडेंशियल के लिए मानक संरचना को परिभाषित करता है, जिसमें दावे, मेटाडेटा और सबूत शामिल हैं।                                                                         |
| **[SD-JWT](https://datatracker.ietf.org/doc/draft-ietf-oauth-selective-disclosure-jwt/)** | JWTs के लिए चयनात्मक प्रकटीकरण। JSON वेब टोकन पर आधारित VCs के लिए एक प्रारूप जो धारकों को एक क्रेडेंशियल से केवल विशिष्ट दावों को चुनिंदा रूप से प्रकट करने की अनुमति देता है, जिससे गोपनीयता बढ़ती है।             |
| **[ISO mDoc](https://www.iso.org/standard/69084.html)**                                   | ISO/IEC 18013-5। मोबाइल ड्राइविंग लाइसेंस (mDLs) और अन्य मोबाइल आईडी के लिए अंतर्राष्ट्रीय मानक, जो ऑफ़लाइन और ऑनलाइन उपयोग के लिए डेटा संरचनाओं और संचार प्रोटोकॉल को परिभाषित करता है।                             |
| **OpenID4VP**                                                                             | वेरिफ़ाएबल प्रेजेंटेशन के लिए OpenID। OAuth 2.0 पर बना एक इंटरऑपरेबल प्रेजेंटेशन प्रोटोकॉल। यह परिभाषित करता है कि एक वेरिफ़ायर क्रेडेंशियल का अनुरोध कैसे करता है और एक धारक का वॉलेट उन्हें कैसे प्रस्तुत करता है। |

इस ट्यूटोरियल के लिए, हम विशेष रूप से उपयोग करते हैं:

- **OpenID4VP** क्रेडेंशियल का अनुरोध करने और प्राप्त करने के लिए प्रोटोकॉल के रूप में।
- **ISO mDoc** क्रेडेंशियल प्रारूप के रूप में (जैसे, मोबाइल ड्राइविंग लाइसेंस के लिए)।

> **स्कोप पर ध्यान दें:** जबकि हम व्यापक संदर्भ प्रदान करने के लिए संक्षेप में W3C VC और
> SD-JWT का परिचय देते हैं, यह ट्यूटोरियल विशेष रूप से [OpenID4VP](https://www.corbado.com/glossary/open-id-4-vp)
> के माध्यम से ISO mDoc क्रेडेंशियल को लागू करता है। W3C-आधारित VCs इस उदाहरण के दायरे से
> बाहर हैं।

#### 2.1.1 ISO mDoc (मोबाइल दस्तावेज़)

ISO/IEC 18013-5 mDoc मानक मोबाइल दस्तावेज़ों जैसे मोबाइल ड्राइविंग लाइसेंस (mDLs) के लिए
संरचना और एन्कोडिंग को परिभाषित करता है। mDoc क्रेडेंशियल [CBOR](https://www.corbado.com/glossary/cbor)-एन्कोडेड,
क्रिप्टोग्राफ़िक रूप से हस्ताक्षरित होते हैं, और सत्यापन के लिए डिजिटल रूप से प्रस्तुत किए
जा सकते हैं। हमारा वेरिफ़ायर इन mdoc क्रेडेंशियल को डीकोड करने और मान्य करने पर ध्यान
केंद्रित करेगा।

#### 2.1.2 OpenID4VP (वेरिफ़ाएबल प्रेजेंटेशन के लिए OpenID)

OpenID4VP डिजिटल क्रेडेंशियल का अनुरोध करने और प्रस्तुत करने के लिए एक इंटरऑपरेबल
प्रोटोकॉल है, जो [OAuth 2.0](https://www.corbado.com/glossary/oauth2) और OpenID कनेक्ट के शीर्ष पर बनाया गया है।
इस कार्यान्वयन में, OpenID4VP का उपयोग किया जाता है:

- क्रेडेंशियल प्रेजेंटेशन प्रवाह शुरू करने के लिए (QR कोड या ब्राउज़र API के माध्यम से)
- उपयोगकर्ता के वॉलेट से mdoc क्रेडेंशियल प्राप्त करने के लिए
- सुरक्षित, स्टेटफुल और गोपनीयता-संरक्षण क्रेडेंशियल एक्सचेंज सुनिश्चित करने के लिए

### 2.2 टेक स्टैक विकल्प

अब जब हमें मानकों और प्रोटोकॉल की स्पष्ट समझ है, तो हमें अपना वेरिफ़ायर बनाने के लिए सही
टेक स्टैक चुनने की आवश्यकता है। हमारे विकल्प मजबूती, डेवलपर अनुभव और आधुनिक वेब
पारिस्थितिकी तंत्र के साथ संगतता के लिए डिज़ाइन किए गए हैं।

#### 2.2.1 भाषा: TypeScript

हम अपने फ्रंटएंड और बैकएंड कोड दोनों के लिए **TypeScript** का उपयोग करेंगे। जावास्क्रिप्ट
के एक सुपरसेट के रूप में, यह स्टैटिक टाइपिंग जोड़ता है, जो त्रुटियों को जल्दी पकड़ने में
मदद करता है, कोड की गुणवत्ता में सुधार करता है, और जटिल अनुप्रयोगों को प्रबंधित करना आसान
बनाता है। क्रेडेंशियल सत्यापन जैसे सुरक्षा-संवेदनशील संदर्भ में, टाइप सुरक्षा एक बहुत बड़ा
लाभ है।

#### 2.2.2 फ्रेमवर्क: Next.js

**Next.js** हमारी पसंद का फ्रेमवर्क है क्योंकि यह फुल-स्टैक एप्लिकेशन बनाने के लिए एक सहज,
एकीकृत अनुभव प्रदान करता है।

- **फ्रंटएंड के लिए:** हम [Next.js](https://www.corbado.com/blog/nextjs-passkeys) का उपयोग
  [React](https://www.corbado.com/blog/react-passkeys) के साथ यूजर इंटरफेस बनाने के लिए करेंगे जहाँ सत्यापन
  प्रक्रिया शुरू की जाती है (जैसे, एक QR कोड प्रदर्शित करना)।
- **बैकएंड के लिए:** हम सर्वर-साइड एंडपॉइंट बनाने के लिए **Next.js API रूट्स** का लाभ
  उठाएंगे। ये एंडपॉइंट मान्य OpenID4VP अनुरोध बनाने और CMWallet से अंतिम प्रतिक्रिया को
  सुरक्षित रूप से प्राप्त करने और सत्यापित करने के लिए `redirect_uri` के रूप में कार्य
  करने के लिए जिम्मेदार हैं।

#### 2.2.3 मुख्य लाइब्रेरी

हमारा कार्यान्वयन फ्रंटएंड और बैकएंड के लिए पुस्तकालयों के एक विशिष्ट सेट पर निर्भर करता
है:

- **next**: [Next.js](https://www.corbado.com/blog/nextjs-passkeys) फ्रेमवर्क, जिसका उपयोग बैकएंड API रूट और
  फ्रंटएंड UI दोनों के लिए किया जाता है।
- **react** और **react-dom**: फ्रंटएंड यूजर इंटरफेस को शक्ति प्रदान करते हैं।
- **cbor-web**: [CBOR](https://www.corbado.com/glossary/cbor)-एन्कोडेड mdoc क्रेडेंशियल को प्रयोग करने योग्य
  जावास्क्रिप्ट ऑब्जेक्ट में डीकोड करने के लिए उपयोग किया जाता है।
- **mysql2**: चुनौतियों और सत्यापन सत्रों को संग्रहीत करने के लिए
  [MySQL](https://www.corbado.com/blog/passkey-webauthn-database-guide) डेटाबेस कनेक्टिविटी प्रदान करता है।
- **uuid**: अद्वितीय चुनौती स्ट्रिंग्स (नॉनस) उत्पन्न करने के लिए एक लाइब्रेरी।
- **@types/uuid**: UUID पीढ़ी के लिए TypeScript प्रकार।

> **`openid-client` पर ध्यान दें:** अधिक उन्नत, उत्पादन-ग्रेड वेरिफ़ायर सीधे बैकएंड पर
> OpenID4VP प्रोटोकॉल को संभालने के लिए `openid-client` लाइब्रेरी का उपयोग कर सकते हैं,
> जिससे डायनामिक `redirect_uri` जैसी सुविधाएँ सक्षम होती हैं। एक `redirect_uri` के साथ
> सर्वर-चालित OpenID4VP प्रवाह में, `openid-client` का उपयोग सीधे `vp_token` प्रतिक्रियाओं
> को पार्स और मान्य करने के लिए किया जाएगा। इस ट्यूटोरियल के लिए, हम एक सरल,
> ब्राउज़र-मध्यस्थता प्रवाह का उपयोग कर रहे हैं जिसके लिए इसकी आवश्यकता नहीं है, जिससे
> प्रक्रिया को समझना आसान हो जाता है।

यह टेक स्टैक ब्राउज़र के डिजिटल क्रेडेंशियल API और ISO mDoc क्रेडेंशियल प्रारूप पर
केंद्रित एक मजबूत, टाइप-सुरक्षित और स्केलेबल वेरिफ़ायर कार्यान्वयन सुनिश्चित करता है।

### 2.3 एक टेस्ट वॉलेट और क्रेडेंशियल प्राप्त करें

अपने वेरिफ़ायर का परीक्षण करने के लिए, आपको एक मोबाइल वॉलेट की आवश्यकता है जो ब्राउज़र के
डिजिटल क्रेडेंशियल API के साथ इंटरैक्ट कर सके।

हम
**[CMWallet](https://github.com/digitalcredentialsdev/CMWallet/actions/runs/16407676816/artifacts/3574255220)**
का उपयोग करेंगे, जो [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) के लिए एक मजबूत
OpenID4VP-अनुपालन परीक्षण वॉलेट है।

**CMWallet कैसे स्थापित करें (Android):**

1. उपरोक्त लिंक का उपयोग करके सीधे अपने [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android)
   डिवाइस पर **APK फ़ाइल डाउनलोड करें**।
2. अपने डिवाइस की **सेटिंग्स > सुरक्षा** खोलें।
3. जिस ब्राउज़र का उपयोग आपने फ़ाइल डाउनलोड करने के लिए किया था, उसके लिए **"अज्ञात ऐप्स
   इंस्टॉल करें"** सक्षम करें।
4. अपने "डाउनलोड" फ़ोल्डर में डाउनलोड की गई APK का पता लगाएँ और स्थापना शुरू करने के लिए
   उस पर टैप करें।
5. स्थापना को पूरा करने के लिए ऑन-स्क्रीन संकेतों का पालन करें।
6. CMWallet खोलें, और आप पाएंगे कि यह परीक्षण क्रेडेंशियल के साथ पहले से लोड है, जो
   सत्यापन प्रवाह के लिए तैयार है।

> **ध्यान दें:** केवल उन स्रोतों से APK फ़ाइलें स्थापित करें जिन पर आप भरोसा करते हैं।
> प्रदान किया गया लिंक आधिकारिक परियोजना भंडार से है।

### 2.4 क्रिप्टोग्राफी ज्ञान

कार्यान्वयन में गोता लगाने से पहले, वेरिफ़ाएबल क्रेडेंशियल के आधारभूत क्रिप्टोग्राफिक
अवधारणाओं को समझना आवश्यक है। यही उन्हें "सत्यापन योग्य" और भरोसेमंद बनाता है।

#### 2.4.1 डिजिटल हस्ताक्षर: विश्वास की नींव

इसके मूल में, एक वेरिफ़ाएबल क्रेडेंशियल दावों का एक सेट है (जैसे नाम, जन्म तिथि, आदि) जिसे
एक जारीकर्ता द्वारा डिजिटल रूप से हस्ताक्षरित किया गया है। एक डिजिटल हस्ताक्षर दो
महत्वपूर्ण गारंटी प्रदान करता है:

- **प्रामाणिकता:** यह साबित करता है कि क्रेडेंशियल वास्तव में जारीकर्ता द्वारा बनाया गया
  था न कि किसी धोखेबाज द्वारा।
- **अखंडता:** यह साबित करता है कि हस्ताक्षर किए जाने के बाद से क्रेडेंशियल में कोई
  परिवर्तन या छेड़छाड़ नहीं की गई है।

#### 2.4.2 सार्वजनिक/निजी कुंजी क्रिप्टोग्राफी

डिजिटल हस्ताक्षर सार्वजनिक/निजी कुंजी क्रिप्टोग्राफी (जिसे असममित क्रिप्टोग्राफी भी कहा
जाता है) का उपयोग करके बनाए जाते हैं। यहाँ यह हमारे संदर्भ में कैसे काम करता है:

1. **जारीकर्ता के पास एक कुंजी जोड़ी होती है:** एक निजी कुंजी, जिसे गुप्त रखा जाता है, और
   एक सार्वजनिक कुंजी, जिसे सभी के लिए उपलब्ध कराया जाता है (आमतौर पर उनके DID दस्तावेज़
   के माध्यम से)।
2. **हस्ताक्षर करना:** जब कोई जारीकर्ता एक क्रेडेंशियल बनाता है, तो वे उस विशिष्ट
   क्रेडेंशियल डेटा के लिए एक अद्वितीय डिजिटल हस्ताक्षर उत्पन्न करने के लिए अपनी **निजी
   कुंजी** का उपयोग करते हैं।
3. **सत्यापन:** जब हमारा वेरिफ़ायर क्रेडेंशियल प्राप्त करता है, तो वह हस्ताक्षर की जाँच
   करने के लिए जारीकर्ता की **सार्वजनिक कुंजी** का उपयोग करता है। यदि जाँच पास हो जाती है,
   तो वेरिफ़ायर जानता है कि क्रेडेंशियल प्रामाणिक है और उसके साथ छेड़छाड़ नहीं की गई है।
   क्रेडेंशियल डेटा में कोई भी परिवर्तन हस्ताक्षर को अमान्य कर देगा।

> **DIDs पर ध्यान दें:** इस ट्यूटोरियल में, हम DIDs के माध्यम से जारीकर्ता कुंजियों को हल
> नहीं करते हैं। उत्पादन में, जारीकर्ता आमतौर पर DIDs या अन्य आधिकारिक एंडपॉइंट के माध्यम
> से सार्वजनिक कुंजियों को उजागर करेंगे, जिनका उपयोग वेरिफ़ायर क्रिप्टोग्राफ़िक सत्यापन के
> लिए करेगा।

#### 2.4.3 JWTs के रूप में वेरिफ़ाएबल क्रेडेंशियल

वेरिफ़ाएबल क्रेडेंशियल अक्सर **JSON वेब टोकन (JWTs)** के रूप में स्वरूपित होते हैं। एक JWT
दो पक्षों के बीच स्थानांतरित किए जाने वाले दावों का प्रतिनिधित्व करने का एक संक्षिप्त,
URL-सुरक्षित तरीका है। एक हस्ताक्षरित JWT (जिसे JWS भी कहा जाता है) के तीन भाग होते हैं जो
डॉट्स (`.`) से अलग होते हैं:

- **हेडर:** टोकन के बारे में मेटाडेटा होता है, जैसे उपयोग किया गया हस्ताक्षर एल्गोरिथ्म
  (`alg`)।
- **पेलोड:** वेरिफ़ाएबल क्रेडेंशियल (`vc` दावा) के वास्तविक दावे होते हैं, जिसमें
  `issuer`, `credentialSubject`, आदि शामिल हैं।
- **हस्ताक्षर:** जारीकर्ता द्वारा उत्पन्न डिजिटल हस्ताक्षर, जो हेडर और पेलोड को कवर करता
  है।

```
// एक JWT संरचना का उदाहरण
[हेडर].[पेलोड].[हस्ताक्षर]
```

> **ध्यान दें:** JWT-आधारित वेरिफ़ाएबल क्रेडेंशियल इस ब्लॉग पोस्ट के दायरे से बाहर हैं। यह
> कार्यान्वयन ISO mDoc क्रेडेंशियल और OpenID4VP पर केंद्रित है, न कि W3C वेरिफ़ाएबल
> क्रेडेंशियल या JWT-आधारित क्रेडेंशियल पर।

#### 2.4.4 वेरिफ़ाएबल प्रेजेंटेशन: कब्जे का प्रमाण

एक वेरिफ़ायर के लिए यह जानना पर्याप्त नहीं है कि एक क्रेडेंशियल मान्य है; उसे यह भी जानना
होगा कि क्रेडेंशियल प्रस्तुत करने वाला व्यक्ति वैध धारक है। यह किसी को चोरी किए गए
क्रेडेंशियल का उपयोग करने से रोकता है।

यह एक **वेरिफ़ाएबल प्रेजेंटेशन (VP)** का उपयोग करके हल किया जाता है। एक VP एक या एक से
अधिक VCs के चारों ओर एक रैपर है जिसे **धारक द्वारा स्वयं हस्ताक्षरित किया जाता है**।

प्रवाह इस प्रकार है:

1. वेरिफ़ायर उपयोगकर्ता से एक क्रेडेंशियल प्रस्तुत करने के लिए कहता है।
2. उपयोगकर्ता का वॉलेट एक वेरिफ़ाएबल प्रेजेंटेशन बनाता है, आवश्यक क्रेडेंशियल को उसके अंदर
   बंडल करता है, और **धारक की निजी कुंजी** का उपयोग करके पूरे प्रेजेंटेशन पर हस्ताक्षर
   करता है।
3. वॉलेट इस हस्ताक्षरित VP को वेरिफ़ायर को भेजता है।

हमारे वेरिफ़ायर को तब **दो** अलग-अलग हस्ताक्षर जाँच करनी चाहिए:

1. **क्रेडेंशियल को सत्यापित करें:** प्रेजेंटेशन के अंदर प्रत्येक VC पर **जारीकर्ता की
   सार्वजनिक कुंजी** का उपयोग करके हस्ताक्षर की जाँच करें। (साबित करता है कि क्रेडेंशियल
   वास्तविक है)।
2. **प्रेजेंटेशन को सत्यापित करें:** VP पर ही **धारक की सार्वजनिक कुंजी** का उपयोग करके
   हस्ताक्षर की जाँच करें। (साबित करता है कि इसे प्रस्तुत करने वाला व्यक्ति मालिक है)।

यह दो-स्तरीय जाँच क्रेडेंशियल की प्रामाणिकता और इसे प्रस्तुत करने वाले व्यक्ति की पहचान
दोनों सुनिश्चित करती है, जिससे एक मजबूत और सुरक्षित विश्वास मॉडल बनता है।

> **ध्यान दें:** W3C VC पारिस्थितिकी तंत्र में परिभाषित वेरिफ़ाएबल प्रेजेंटेशन की अवधारणा
> इस ब्लॉग पोस्ट के दायरे से बाहर है। यहाँ वेरिफ़ाएबल प्रेजेंटेशन शब्द OpenID4VP
> `vp_token` प्रतिक्रिया को संदर्भित करता है, जो W3C VP के समान व्यवहार करता है लेकिन W3C
> के [JSON-LD](https://www.corbado.com/glossary/json-ld) हस्ताक्षर मॉडल के बजाय ISO mDoc सिमेंटिक्स पर आधारित है।
> यह गाइड ISO mDoc क्रेडेंशियल और OpenID4VP पर केंद्रित है, न कि W3C वेरिफ़ाएबल
> प्रेजेंटेशन या उनके हस्ताक्षर सत्यापन पर।

## 3. वास्तुकला अवलोकन

हमारी वेरिफ़ायर वास्तुकला हमारे वेब एप्लिकेशन को उपयोगकर्ता के मोबाइल **CMWallet** से
जोड़ने के लिए एक सुरक्षित मध्यस्थ के रूप में ब्राउज़र के अंतर्निहित **डिजिटल क्रेडेंशियल
API** का उपयोग करती है। यह दृष्टिकोण ब्राउज़र को नेटिव QR कोड प्रदर्शन और वॉलेट संचार को
संभालने देकर प्रवाह को सरल बनाता है।

- **फ्रंटएंड (Next.js और React):** एक हल्का उपयोगकर्ता-सामना करने वाली वेबसाइट। इसका काम
  हमारे बैकएंड से एक अनुरोध ऑब्जेक्ट लाना है, इसे ब्राउज़र के
  `navigator.credentials.get()` API को पास करना है, परिणाम प्राप्त करना है, और इसे सत्यापन
  के लिए हमारे बैकएंड को अग्रेषित करना है।
- **बैकएंड (Next.js API रूट):** वेरिफ़ायर का पावरहाउस। यह ब्राउज़र API के लिए एक मान्य
  अनुरोध ऑब्जेक्ट उत्पन्न करता है और अंतिम सत्यापन के लिए फ्रंटएंड से क्रेडेंशियल
  प्रेजेंटेशन प्राप्त करने के लिए एक एंडपॉइंट को उजागर करता है।
- **ब्राउज़र (क्रेडेंशियल API):** सूत्रधार। यह हमारे फ्रंटएंड से अनुरोध ऑब्जेक्ट प्राप्त
  करता है, `openid4vp` प्रोटोकॉल को समझता है, और मूल रूप से एक QR कोड उत्पन्न करता है। यह
  तब वॉलेट से प्रतिक्रिया लौटने की प्रतीक्षा करता है।
- **CMWallet (मोबाइल ऐप):** उपयोगकर्ता का वॉलेट। यह QR कोड को स्कैन करता है, अनुरोध को
  संसाधित करता है, उपयोगकर्ता की सहमति प्राप्त करता है, और हस्ताक्षरित प्रतिक्रिया को वापस
  ब्राउज़र को भेजता है।

यहाँ एक अनुक्रम आरेख है जो पूर्ण और सटीक प्रवाह को दर्शाता है:

![ब्राउज़र के डिजिटल क्रेडेंशियल API का उपयोग करके सत्यापन प्रवाह](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/Mermaid_Chart_Create_complex_visual_diagrams_with_text_A_smarter_way_of_creating_diagrams_2025_07_24_233623_1b6ed9b957.svg)

**प्रवाह समझाया गया:**

1. **आरंभ:** उपयोगकर्ता हमारे **फ्रंटएंड** पर "सत्यापित करें" बटन पर क्लिक करता है।
2. **अनुरोध ऑब्जेक्ट:** फ्रंटएंड हमारे **बैकएंड** (`/api/verify/start`) को कॉल करता है, जो
   क्वेरी और एक नॉनस युक्त एक अनुरोध ऑब्जेक्ट उत्पन्न करता है, फिर उसे लौटाता है।
3. **ब्राउज़र API कॉल:** फ्रंटएंड अनुरोध ऑब्जेक्ट के साथ `navigator.credentials.get()` को
   कॉल करता है।
4. **नेटिव QR कोड:** **ब्राउज़र** `openid4vp` प्रोटोकॉल अनुरोध को देखता है और मूल रूप से
   एक QR कोड प्रदर्शित करता है। `.get()` वादा अब लंबित है।

> **ध्यान दें:** यह QR कोड प्रवाह डेस्कटॉप ब्राउज़र पर होता है। मोबाइल ब्राउज़र (प्रायोगिक
> ध्वज सक्षम के साथ Android Chrome) पर, ब्राउज़र सीधे उसी डिवाइस पर संगत वॉलेट के साथ
> संवाद कर सकता है, जिससे QR कोड स्कैनिंग की आवश्यकता समाप्त हो जाती है। Android Chrome पर
> इस सुविधा को सक्षम करने के लिए, `chrome://flags#web-identity-digital-credentials` पर
> जाएँ और ध्वज को "सक्षम" पर सेट करें।

5. **स्कैन और प्रस्तुत करें:** उपयोगकर्ता **CMWallet** के साथ QR कोड को स्कैन करता है।
   वॉलेट उपयोगकर्ता की स्वीकृति प्राप्त करता है और वेरिफ़ाएबल प्रेजेंटेशन को वापस ब्राउज़र
   को भेजता है।
6. **वादा समाधान:** ब्राउज़र प्रतिक्रिया प्राप्त करता है, और फ्रंटएंड पर मूल `.get()` वादा
   अंततः हल हो जाता है, प्रेजेंटेशन पेलोड वितरित करता है।
7. **बैकएंड सत्यापन:** फ्रंटएंड हमारे बैकएंड के `/api/verify/finish` एंडपॉइंट पर
   प्रेजेंटेशन पेलोड को **POST** करता है। बैकएंड नॉनस और क्रेडेंशियल को मान्य करता है।
8. **परिणाम:** बैकएंड फ्रंटएंड को एक अंतिम सफलता या विफलता संदेश लौटाता है, जो UI को अपडेट
   करता है।

## 4. वेरिफ़ायर का निर्माण

अब जब हमें मानकों, प्रोटोकॉल और वास्तुशिल्प प्रवाह की ठोस समझ है, तो हम अपना वेरिफ़ायर
बनाना शुरू कर सकते हैं।

> **साथ चलें या अंतिम कोड का उपयोग करें**
>
> अब हम सेटअप और कोड कार्यान्वयन के माध्यम से चरण-दर-चरण चलेंगे। यदि आप सीधे तैयार उत्पाद
> पर जाना पसंद करते हैं, तो आप हमारे GitHub रिपॉजिटरी से पूरी परियोजना को क्लोन कर सकते
> हैं और इसे स्थानीय रूप से चला सकते हैं।
>
> ```bash
> git clone https://github.com/corbado/digital-credentials-example.git
> ```

### 4.1 प्रोजेक्ट की स्थापना

सबसे पहले, हम एक नया Next.js प्रोजेक्ट शुरू करेंगे, आवश्यक निर्भरताएँ स्थापित करेंगे, और
अपना डेटाबेस शुरू करेंगे।

#### 4.1.1 Next.js ऐप को इनिशियलाइज़ करना

अपना टर्मिनल खोलें, उस डायरेक्टरी में जाएँ जहाँ आप अपना प्रोजेक्ट बनाना चाहते हैं, और
निम्न कमांड चलाएँ। हम इस प्रोजेक्ट के लिए ऐप राउटर, TypeScript और Tailwind CSS का उपयोग कर
रहे हैं।

```bash
npx create-next-app@latest . --ts --eslint --tailwind --app --src-dir --import-alias "@/*" --use-npm
```

यह कमांड आपकी वर्तमान डायरेक्टरी में एक नया Next.js एप्लिकेशन बनाता है।

#### 4.1.2 निर्भरताएँ स्थापित करना

अगला, हमें उन पुस्तकालयों को स्थापित करने की आवश्यकता है जो CBOR डीकोडिंग, डेटाबेस कनेक्शन
और UUID पीढ़ी को संभालेंगे।

```bash
npm install cbor-web mysql2 uuid @types/uuid
```

यह कमांड स्थापित करता है:

- `cbor-web`: mdoc क्रेडेंशियल पेलोड को डीकोड करने के लिए।
- `mysql2`: हमारे डेटाबेस के लिए MySQL क्लाइंट।
- `uuid`: अद्वितीय चुनौती स्ट्रिंग उत्पन्न करने के लिए।
- `@types/uuid`: `uuid` लाइब्रेरी के लिए TypeScript प्रकार।

#### 4.1.3 डेटाबेस शुरू करना

हमारे बैकएंड को OIDC सत्र डेटा संग्रहीत करने के लिए एक MySQL डेटाबेस की आवश्यकता होती है,
यह सुनिश्चित करते हुए कि प्रत्येक सत्यापन प्रवाह सुरक्षित और स्टेटफुल है। हमने इसे आसान
बनाने के लिए एक `docker-compose.yml` फ़ाइल शामिल की है।

यदि आपने रिपॉजिटरी को क्लोन किया है, तो आप बस `docker-compose up -d` चला सकते हैं। यदि आप
खरोंच से निर्माण कर रहे हैं, तो निम्न सामग्री के साथ `docker-compose.yml` नामक एक फ़ाइल
बनाएँ:

```yaml
services:
    mysql:
        image: mysql:8.0
        restart: always
        environment:
            MYSQL_ROOT_PASSWORD: rootpassword
            MYSQL_DATABASE: digital_credentials
            MYSQL_USER: app_user
            MYSQL_PASSWORD: app_password
        ports:
            - "3306:3306"
        volumes:
            - mysql_data:/var/lib/mysql
            - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql
        healthcheck:
            test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
            timeout: 20s
            retries: 10

volumes:
    mysql_data:
```

इस Docker Compose सेटअप के लिए एक SQL आरंभीकरण स्क्रिप्ट की भी आवश्यकता होती है। `sql`
नामक एक डायरेक्टरी बनाएँ और उसके अंदर, आवश्यक तालिकाओं को सेट करने के लिए निम्न सामग्री के
साथ `init.sql` नामक एक फ़ाइल बनाएँ:

```sql
-- Create database if not exists
CREATE DATABASE IF NOT EXISTS digital_credentials;
USE digital_credentials;

-- Table for storing challenges
CREATE TABLE IF NOT EXISTS challenges (
    id VARCHAR(36) PRIMARY KEY,
    challenge VARCHAR(255) NOT NULL UNIQUE,
    expires_at TIMESTAMP NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    used BOOLEAN DEFAULT FALSE,
    INDEX idx_challenge (challenge),
    INDEX idx_expires_at (expires_at)
);

-- Table for storing verification sessions
CREATE TABLE IF NOT EXISTS verification_sessions (
    id VARCHAR(36) PRIMARY KEY,
    challenge_id VARCHAR(36),
    status ENUM('pending', 'verified', 'failed', 'expired') DEFAULT 'pending',
    presentation_data JSON,
    verified_at TIMESTAMP NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (challenge_id) REFERENCES challenges(id) ON DELETE CASCADE,
    INDEX idx_challenge_id (challenge_id),
    INDEX idx_status (status)
);

-- Table for storing verified credentials data (optional)
CREATE TABLE IF NOT EXISTS verified_credentials (
    id VARCHAR(36) PRIMARY KEY,
    session_id VARCHAR(36),
    credential_type VARCHAR(255),
    issuer VARCHAR(255),
    subject VARCHAR(255),
    claims JSON,
    verified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (session_id) REFERENCES verification_sessions(id) ON DELETE CASCADE,
    INDEX idx_session_id (session_id),
    INDEX idx_credential_type (credential_type)
);
```

दोनों फाइलें बन जाने के बाद, अपने टर्मिनल को प्रोजेक्ट रूट में खोलें और चलाएँ:

```bash
docker-compose up -d
```

यह कमांड बैकग्राउंड में एक MySQL कंटेनर शुरू करेगा।

### 4.2 Next.js ऐप का वास्तुशिल्प अवलोकन

हमारा Next.js एप्लिकेशन फ्रंटएंड और बैकएंड के बीच चिंताओं को अलग करने के लिए संरचित है,
भले ही वे एक ही प्रोजेक्ट का हिस्सा हों।

- **फ्रंटएंड (`src/app/page.tsx`):** एक एकल [React](https://www.corbado.com/blog/react-passkeys) पृष्ठ जो सत्यापन
  प्रवाह शुरू करता है और परिणाम प्रदर्शित करता है। यह ब्राउज़र के डिजिटल क्रेडेंशियल API
  के साथ इंटरैक्ट करता है।
- **बैकएंड API रूट (`src/app/api/verify/...`):**
    - `start/route.ts`: OpenID4VP अनुरोध और एक सुरक्षा नॉनस उत्पन्न करता है।
    - `finish/route.ts`: वॉलेट से प्रस्तुति प्राप्त करता है (ब्राउज़र के माध्यम से), नॉनस
      को मान्य करता है, और क्रेडेंशियल को डीकोड करता है।
- **लाइब्रेरी (`src/lib/`):**
    - `database.ts`: सभी डेटाबेस इंटरैक्शन का प्रबंधन करता है (चुनौतियाँ बनाना, सत्रों का
      सत्यापन करना)।
    - `crypto.ts`: CBOR-आधारित mDoc क्रेडेंशियल की डीकोडिंग को संभालता है।

यहाँ आंतरिक वास्तुकला को दर्शाने वाला एक चित्र है:

![NextJS आंतरिक वास्तुकला](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/Mermaid_Chart_Create_complex_visual_diagrams_with_text_A_smarter_way_of_creating_diagrams_2025_07_25_091202_f96ccb049f.svg)

### 4.3 फ्रंटएंड का निर्माण

हमारा फ्रंटएंड जानबूझकर हल्का बनाया गया है। इसकी प्राथमिक जिम्मेदारी सत्यापन प्रवाह के लिए
उपयोगकर्ता-सामना करने वाले ट्रिगर के रूप में कार्य करना और हमारे बैकएंड और ब्राउज़र की
नेटिव क्रेडेंशियल हैंडलिंग क्षमताओं दोनों के साथ संवाद करना है। इसमें कोई जटिल प्रोटोकॉल
तर्क नहीं है; वह सब प्रत्यायोजित है।

विशेष रूप से, फ्रंटएंड निम्नलिखित को संभालेगा:

- **उपयोगकर्ता इंटरैक्शन:** उपयोगकर्ता को प्रक्रिया शुरू करने के लिए "सत्यापित करें" बटन
  जैसा एक सरल इंटरफ़ेस प्रदान करता है।
- **स्टेट मैनेजमेंट:** UI स्थिति का प्रबंधन करता है, सत्यापन के दौरान लोडिंग संकेतक दिखाता
  है और अंतिम सफलता या त्रुटि संदेश प्रदर्शित करता है।
- **बैकएंड कम्युनिकेशन (अनुरोध):** `/api/verify/start` को कॉल करता है और एक संरचित JSON
  पेलोड (`protocol`, `request`, `state`) प्राप्त करता है जो बताता है कि वॉलेट को वास्तव
  में क्या प्रस्तुत करना चाहिए।
- **ब्राउज़र API मंगलाचरण:** उस JSON ऑब्जेक्ट को `navigator.credentials.get()` को सौंपता
  है, जो एक नेटिव QR कोड प्रस्तुत करता है और वॉलेट प्रतिक्रिया की प्रतीक्षा करता है।
- **बैकएंड कम्युनिकेशन (प्रतिक्रिया):** एक बार जब ब्राउज़र API वेरिफ़ाएबल प्रेजेंटेशन
  लौटाता है, तो यह इस डेटा को अंतिम सर्वर-साइड सत्यापन के लिए हमारे `/api/verify/finish`
  एंडपॉइंट पर एक POST अनुरोध में भेजता है।
- **परिणाम प्रदर्शित करना:** बैकएंड से प्रतिक्रिया के आधार पर उपयोगकर्ता को यह सूचित करने
  के लिए UI को अपडेट करता है कि सत्यापन सफल रहा या विफल।

मुख्य तर्क `startVerification` फ़ंक्शन में है:

```typescript
// src/app/page.tsx

const startVerification = async () => {
    setLoading(true);
    setVerificationResult(null);

    try {
        // 1. जाँच करें कि क्या ब्राउज़र API का समर्थन करता है
        if (!navigator.credentials?.get) {
            throw new Error("ब्राउज़र क्रेडेंशियल API का समर्थन नहीं करता है।");
        }

        // 2. हमारे बैकएंड से एक अनुरोध ऑब्जेक्ट के लिए पूछें
        const res = await fetch("/api/verify/start");
        const { protocol, request } = await res.json();

        // 3. उस ऑब्जेक्ट को ब्राउज़र को सौंपें - यह नेटिव QR कोड को ट्रिगर करता है
        const credential = await (navigator.credentials as any).get({
            mediation: "required",
            digital: {
                requests: [
                    {
                        protocol, // "openid4vp"
                        data: request, // इसमें dcql_query, nonce, आदि शामिल हैं।
                    },
                ],
            },
        });

        // 4. सर्वर-साइड जाँच के लिए हमारे फिनिश एंडपॉइंट पर वॉलेट प्रतिक्रिया (ब्राउज़र से) अग्रेषित करें
        const verifyRes = await fetch("/api/verify/finish", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(credential),
        });

        const result = await verifyRes.json();

        if (verifyRes.ok && result.verified) {
            setVerificationResult(`सफलता: ${result.message}`);
        } else {
            throw new Error(result.message || "सत्यापन विफल।");
        }
    } catch (err) {
        setVerificationResult(`त्रुटि: ${(err as Error).message}`);
    } finally {
        setLoading(false);
    }
};
```

यह फ़ंक्शन फ्रंटएंड तर्क के चार प्रमुख चरणों को दिखाता है: API समर्थन की जाँच करना, बैकएंड
से अनुरोध प्राप्त करना, ब्राउज़र API को कॉल करना, और सत्यापन के लिए परिणाम वापस भेजना।
फ़ाइल का बाकी हिस्सा स्थिति और UI रेंडरिंग के लिए मानक [React](https://www.corbado.com/blog/react-passkeys)
बॉयलरप्लेट है, जिसे आप
[GitHub रिपॉजिटरी](https://github.com/corbado/digital-credentials-example) में देख सकते
हैं।

#### `digital` और `mediation: 'required'` क्यों?

आप देख सकते हैं कि `navigator.credentials.get()` पर हमारी कॉल सरल उदाहरणों से अलग दिखती
है। ऐसा इसलिए है क्योंकि हम आधिकारिक
[W3C डिजिटल क्रेडेंशियल API विनिर्देश](https://www.w3.org/TR/digital-credentials/#the-digital-credentials-api)
का सख्ती से पालन कर रहे हैं।

- **`digital` सदस्य:** विनिर्देश की आवश्यकता है कि सभी डिजिटल क्रेडेंशियल अनुरोध एक
  `digital` ऑब्जेक्ट के अंदर नेस्टेड हों। यह इस API के लिए एक स्पष्ट, मानकीकृत नेमस्पेस
  प्रदान करता है, इसे अन्य क्रेडेंशियल प्रकारों (जैसे `password` या `federated`) से अलग
  करता है और भविष्य में बिना किसी टकराव के विस्तार की अनुमति देता है।

- **`mediation: 'required'`:** यह विकल्प एक महत्वपूर्ण सुरक्षा और उपयोगकर्ता-अनुभव सुविधा
  है। यह लागू करता है कि उपयोगकर्ता को क्रेडेंशियल अनुरोध को स्वीकृत करने के लिए एक
  प्रॉम्प्ट (जैसे, एक बायोमेट्रिक स्कैन, पिन प्रविष्टि, या एक सहमति स्क्रीन) के साथ सक्रिय
  रूप से बातचीत करनी चाहिए। इसके बिना, एक वेबसाइट संभावित रूप से पृष्ठभूमि में चुपचाप
  क्रेडेंशियल तक पहुँचने का प्रयास कर सकती है, जो एक महत्वपूर्ण गोपनीयता जोखिम पैदा करता
  है। मध्यस्थता की आवश्यकता से, हम यह सुनिश्चित करते हैं कि उपयोगकर्ता हमेशा नियंत्रण में
  रहे और प्रत्येक लेनदेन के लिए स्पष्ट सहमति दे।

### 4.4 बैकएंड एंडपॉइंट्स का निर्माण

React UI के साथ अब हमें दो API रूटों की आवश्यकता है जो सर्वर पर भारी-भरकम काम करते हैं:

1. **`/api/verify/start`** – एक OpenID4VP अनुरोध बनाता है, MySQL में एक बार की चुनौती को
   बनाए रखता है और सब कुछ ब्राउज़र को वापस सौंपता है।
2. **`/api/verify/finish`** – वॉलेट प्रतिक्रिया प्राप्त करता है, चुनौती को मान्य करता है,
   क्रेडेंशियल को सत्यापित और डीकोड करता है, और अंत में UI को एक संक्षिप्त JSON परिणाम
   लौटाता है।

#### 4.4.1 `/api/verify/start`: OpenID4VP अनुरोध उत्पन्न करें

```typescript
// src/app/api/verify/start/route.ts
import { NextResponse } from "next/server";
import { v4 as uuidv4 } from "uuid";
import { createChallenge, cleanupExpiredChallenges } from "@/lib/database";

export async function GET() {
    // 1️⃣ एक अल्पकालिक, यादृच्छिक नॉनस (चुनौती) बनाएँ
    const challenge = uuidv4();
    const challengeId = uuidv4();
    const expiresAt = new Date(Date.now() + 5 * 60 * 1000);

    await createChallenge(challengeId, challenge, expiresAt);
    cleanupExpiredChallenges().catch(console.error);

    // 2️⃣ एक DCQL क्वेरी बनाएँ जो बताती है कि हमें *क्या* चाहिए
    const dcqlQuery = {
        credentials: [
            {
                id: "cred1",
                format: "mso_mdoc",
                meta: { doctype_value: "eu.europa.ec.eudi.pid.1" },
                claims: [
                    { path: ["eu.europa.ec.eudi.pid.1", "family_name"] },
                    { path: ["eu.europa.ec.eudi.pid.1", "given_name"] },
                    { path: ["eu.europa.ec.eudi.pid.1", "birth_date"] },
                ],
            },
        ],
    };

    // 3️⃣ एक ऑब्जेक्ट लौटाएँ जिसे ब्राउज़र navigator.credentials.get() को पास कर सकता है
    return NextResponse.json({
        protocol: "openid4vp", // ब्राउज़र को बताता है कि कौन सा वॉलेट प्रोटोकॉल उपयोग करना है
        request: {
            dcql_query: dcqlQuery, // क्या प्रस्तुत करना है
            nonce: challenge, // रीप्ले-विरोधी
            response_type: "vp_token",
            response_mode: "dc_api", // वॉलेट सीधे /finish पर पोस्ट करेगा
        },
        state: {
            credential_type: "mso_mdoc", // बाद की जाँच के लिए रखा गया
            nonce: challenge,
            challenge_id: challengeId,
        },
    });
}
```

> **मुख्य पैरामीटर**
>
> • **`nonce`** – क्रिप्टोग्राफ़िक चुनौती जो अनुरोध और प्रतिक्रिया को बांधती है (रीप्ले को
> रोकती है)। • **`dcql_query`** – एक ऑब्जेक्ट जो हमें आवश्यक सटीक दावों का वर्णन करता है।
> इस गाइड के लिए, हम डिजिटल क्रेडेंशियल क्वेरी भाषा के हालिया ड्राफ्ट से प्रेरित एक
> `dcql_query` संरचना का उपयोग करते हैं, भले ही यह अभी तक एक अंतिम मानक नहीं है। •
> **`state`** – वॉलेट द्वारा वापस प्रतिध्वनित मनमाना JSON ताकि हम DB रिकॉर्ड देख सकें।

#### 4.4.2 डेटाबेस हेल्पर्स

फ़ाइल `src/lib/database.ts` चुनौतियों और सत्यापन सत्रों (सम्मिलित करें, पढ़ें, उपयोग के
रूप में चिह्नित करें) के लिए बुनियादी MySQL संचालन को लपेटती है। इस तर्क को एक ही मॉड्यूल
में रखने से बाद में डेटास्टोर को बदलना आसान हो जाता है।

---

### 4.5 `/api/verify/finish`: प्रेजेंटेशन को मान्य और डीकोड करें

```typescript
// src/app/api/verify/finish/route.ts
import { NextResponse, NextRequest } from "next/server";
import { v4 as uuidv4 } from "uuid";
import {
    getChallenge,
    markChallengeAsUsed,
    createVerificationSession,
    updateVerificationSession,
} from "@/lib/database";
import { decodeDigitalCredential, decodeAllNamespaces } from "@/lib/crypto";

export async function POST(request: NextRequest) {
    const body = await request.json();

    // 1️⃣ वेरिफ़ाएबल प्रेजेंटेशन के टुकड़ों को निकालें
    const vpTokenMap = body.vp_token ?? body.data?.vp_token;
    const state = body.state;
    const mdocToken = vpTokenMap?.cred1; // हमने dcqlQuery में इस ID के लिए कहा था

    if (!vpTokenMap || !state || !mdocToken) {
        return NextResponse.json(
            { verified: false, message: "विकृत प्रतिक्रिया" },
            { status: 400 },
        );
    }

    // 2️⃣ एक-बार-उपयोग चुनौती सत्यापन
    const stored = await getChallenge(state.nonce);
    if (!stored) {
        return NextResponse.json(
            { verified: false, message: "अमान्य या समाप्त चुनौती" },
            { status: 400 },
        );
    }

    const sessionId = uuidv4();
    await createVerificationSession(sessionId, stored.id);

    // 3️⃣ (छद्म) क्रिप्टोग्राफ़िक जाँच - उत्पादन में वास्तविक mDL सत्यापन के साथ बदलें
    // एक वास्तविक एप्लिकेशन में, आप जारीकर्ता की सार्वजनिक कुंजी के विरुद्ध mdoc हस्ताक्षर का पूर्ण
    // क्रिप्टोग्राफ़िक सत्यापन करने के लिए एक समर्पित लाइब्रेरी का उपयोग करेंगे।
    const isValid = mdocToken.length > 0;
    if (!isValid) {
        await updateVerificationSession(sessionId, "failed", {
            reason: "mdoc सत्यापन विफल",
        });
        return NextResponse.json(
            { verified: false, message: "क्रेडेंशियल सत्यापन विफल" },
            { status: 400 },
        );
    }

    // 4️⃣ मोबाइल-डीएल (mdoc) पेलोड को मानव पठनीय JSON में डीकोड करें
    const decoded = await decodeDigitalCredential(mdocToken);
    const readable = decodeAllNamespaces(decoded)["eu.europa.ec.eudi.pid.1"];

    await markChallengeAsUsed(state.nonce);
    await updateVerificationSession(sessionId, "verified", { readable });

    return NextResponse.json({
        verified: true,
        message: "mdoc क्रेडेंशियल सफलतापूर्वक सत्यापित किया गया!",
        credentialData: readable,
        sessionId,
    });
}
```

> **वॉलेट प्रतिक्रिया में महत्वपूर्ण फ़ील्ड**
>
> • **`vp_token`** – मैप जो वॉलेट द्वारा लौटाए गए _प्रत्येक_ क्रेडेंशियल को रखता है। हमारे
> डेमो के लिए हम `vp_token.cred1` खींचते हैं। • **`state`** – `/start` में हमारे द्वारा
> प्रदान किए गए ब्लॉब की प्रतिध्वनि; इसमें `nonce` होता है ताकि हम DB रिकॉर्ड देख सकें। •
> **`mdocToken`** – एक Base64URL-एन्कोडेड CBOR संरचना जो ISO mDoc का प्रतिनिधित्व करती है।

### 4.6 mdoc क्रेडेंशियल को डीकोड करना

जब वेरिफ़ायर ब्राउज़र से एक mdoc क्रेडेंशियल प्राप्त करता है, तो यह एक Base64URL स्ट्रिंग
होती है जिसमें CBOR-एन्कोडेड बाइनरी डेटा होता है। वास्तविक दावों को निकालने के लिए,
`finish` एंडपॉइंट `src/lib/crypto.ts` से हेल्पर फ़ंक्शंस का उपयोग करके एक बहु-चरणीय
डीकोडिंग प्रक्रिया करता है।

#### 4.6.1 चरण 1: Base64URL और CBOR डीकोडिंग

`decodeDigitalCredential` फ़ंक्शन एन्कोडेड स्ट्रिंग से एक प्रयोग करने योग्य ऑब्जेक्ट में
रूपांतरण को संभालता है:

```typescript
// src/lib/crypto.ts
export async function decodeDigitalCredential(encodedCredential: string) {
    // 1. Base64URL को मानक Base64 में बदलें
    const base64UrlToBase64 = (input: string) => {
        let base64 = input.replace(/-/g, "+").replace(/_/g, "/");
        const pad = base64.length % 4;
        if (pad) base64 += "=".repeat(4 - pad);
        return base64;
    };

    const base64 = base64UrlToBase64(encodedCredential);

    // 2. Base64 को बाइनरी में डीकोड करें
    const binaryString = atob(base64);
    const byteArray = Uint8Array.from(binaryString, (char) => char.charCodeAt(0));

    // 3. CBOR को डीकोड करें
    const decoded = await cbor.decodeFirst(byteArray);
    return decoded;
}
```

- **Base64URL से Base64:** क्रेडेंशियल को Base64URL से मानक Base64 एन्कोडिंग में परिवर्तित
  करता है।
- **Base64 से बाइनरी:** Base64 स्ट्रिंग को बाइनरी बाइट ऐरे में डीकोड करता है।
- **CBOR डीकोडिंग:** बाइनरी डेटा को एक संरचित जावास्क्रिप्ट ऑब्जेक्ट में डीकोड करने के लिए
  `cbor-web` लाइब्रेरी का उपयोग करता है।

#### 4.6.2 चरण 2: नेमस्पेस वाले दावों को निकालना

`decodeAllNamespaces` फ़ंक्शन प्रासंगिक नेमस्पेस से वास्तविक दावों को निकालने के लिए डीकोड
किए गए CBOR ऑब्जेक्ट को और संसाधित करता है:

```typescript
// src/lib/crypto.ts
export function decodeAllNamespaces(jsonObj) {
    const decoded = {};

    try {
        jsonObj.documents.forEach((doc, idx) => {
            // 1) issuerSigned.nameSpaces:
            const issuerNS = doc.issuerSigned?.nameSpaces || {};
            Object.entries(issuerNS).forEach(([nsName, entries]) => {
                if (!decoded[nsName]) decoded[nsName] = {};
                (entries as any[]).forEach((entry) => {
                    const bytes = Uint8Array.from(entry.value);
                    const decodedEntry = cbor.decodeFirstSync(bytes);
                    Object.assign(decoded[nsName], decodedEntry);
                });
            });

            // 2) deviceSigned.nameSpaces (यदि मौजूद हो):
            const deviceNS = doc.deviceSigned?.nameSpaces;
            if (deviceNS?.value?.data) {
                const bytes = Uint8Array.from(deviceNS.value);
                decoded[`deviceSigned_ns_${idx}`] = cbor.decodeFirstSync(bytes);
            }
        });
    } catch (e) {
        console.error(e);
    }

    return decoded;
}
```

- डीकोड किए गए क्रेडेंशियल में **सभी दस्तावेज़ों पर पुनरावृति करता है**।
- **प्रत्येक नेमस्पेस को डीकोड करता है** (जैसे, `eu.europa.ec.eudi.pid.1`) वास्तविक दावा
  मानों (जैसे नाम, जन्म तिथि, आदि) को निकालने के लिए।
- यदि मौजूद हो तो **जारीकर्ता-हस्ताक्षरित और डिवाइस-हस्ताक्षरित दोनों नेमस्पेस को संभालता
  है**।

#### उदाहरण आउटपुट

इन चरणों से गुजरने के बाद, फिनिश एंडपॉइंट को mdoc से दावों वाला एक मानव-पठनीय ऑब्जेक्ट
प्राप्त होता है, उदाहरण के लिए:

```json
{
    "family_name": "Doe",
    "given_name": "John",
    "birth_date": "1990-01-01"
}
```

यह प्रक्रिया सुनिश्चित करती है कि वेरिफ़ायर प्रदर्शन और आगे की प्रक्रिया के लिए mdoc
क्रेडेंशियल से आवश्यक जानकारी को सुरक्षित और मज़बूती से निकाल सकता है।

### 4.7 UI में परिणाम को सतह पर लाना

फिनिश एंडपॉइंट फ्रंटएंड को एक न्यूनतम JSON ऑब्जेक्ट लौटाता है:

```json
{
    "verified": true,
    "message": "mdoc क्रेडेंशियल सफलतापूर्वक सत्यापित किया गया!",
    "credentialData": {
        "family_name": "Doe",
        "given_name": "John",
        "birth_date": "1990-01-01"
    }
}
```

फ्रंटएंड इस प्रतिक्रिया को `startVerification()` में प्राप्त करता है और बस इसे React
स्थिति में बनाए रखता है ताकि हम एक अच्छा पुष्टिकरण कार्ड प्रस्तुत कर सकें या व्यक्तिगत
दावों को प्रदर्शित कर सकें - जैसे _“आपका स्वागत है, जॉन डो (जन्म 1990-01-01)!”_।

## 5. वेरिफ़ायर चलाना और अगले चरण

अब आपके पास एक पूर्ण, काम करने वाला वेरिफ़ायर है जो ब्राउज़र की नेटिव क्रेडेंशियल हैंडलिंग
क्षमताओं का उपयोग करता है। यहाँ इसे स्थानीय रूप से कैसे चलाना है और इसे एक
प्रूफ-ऑफ-कॉन्सेप्ट से उत्पादन-तैयार एप्लिकेशन में ले जाने के लिए आप क्या कर सकते हैं।

### 5.1 उदाहरण कैसे चलाएँ

1. **रिपॉजिटरी को क्लोन करें:**

    ```bash
    git clone https://github.com/corbado/digital-credentials-example.git
    cd digital-credentials-example
    ```

2. **निर्भरताएँ स्थापित करें:**

    ```bash
    npm install
    ```

3. **डेटाबेस शुरू करें:** सुनिश्चित करें कि आपके मशीन पर Docker चल रहा है, फिर MySQL
   कंटेनर शुरू करें:

    ```bash
    docker-compose up -d
    ```

4. **एप्लिकेशन चलाएँ:**

    ```bash
    npm run dev
    ```

    अपने ब्राउज़र को `http://localhost:3000` पर खोलें, और आपको वेरिफ़ायर का UI देखना
    चाहिए। अब आप QR कोड को स्कैन करने और सत्यापन प्रवाह को पूरा करने के लिए अपने CMWallet
    का उपयोग कर सकते हैं।

### 5.2 अगले चरण: डेमो से उत्पादन तक

यह ट्यूटोरियल एक वेरिफ़ायर के लिए मूलभूत बिल्डिंग ब्लॉक प्रदान करता है। इसे उत्पादन-तैयार
बनाने के लिए, आपको कई अतिरिक्त सुविधाएँ लागू करने की आवश्यकता होगी:

- **पूर्ण क्रिप्टोग्राफ़िक सत्यापन:** वर्तमान कार्यान्वयन एक प्लेसहोल्डर जाँच
  (`mdocToken.length > 0`) का उपयोग करता है। एक वास्तविक दुनिया के परिदृश्य में, आपको
  जारीकर्ता की सार्वजनिक कुंजी के विरुद्ध mdoc हस्ताक्षर का पूर्ण क्रिप्टोग्राफ़िक सत्यापन
  करना होगा (जैसे, उनके DID को हल करके या उनके सार्वजनिक कुंजी प्रमाणपत्र को प्राप्त
  करके)। DID समाधान मानकों के लिए,
  [W3C DID समाधान विनिर्देश](https://www.w3.org/TR/did-resolution/) का संदर्भ लें।

- **जारीकर्ता निरस्तीकरण जाँच:** क्रेडेंशियल को उनकी समाप्ति तिथि से पहले जारीकर्ता द्वारा
  रद्द किया जा सकता है। एक उत्पादन वेरिफ़ायर को जारीकर्ता द्वारा प्रदान की गई एक
  निरस्तीकरण सूची या स्थिति एंडपॉइंट से पूछकर क्रेडेंशियल की स्थिति की जाँच करनी चाहिए।
  [W3C वेरिफ़ाएबल क्रेडेंशियल स्थिति सूची](https://www.w3.org/TR/vc-bitstring-status-list/)
  क्रेडेंशियल निरस्तीकरण सूचियों के लिए मानक प्रदान करती है।

- **मजबूत त्रुटि हैंडलिंग और सुरक्षा:** व्यापक त्रुटि हैंडलिंग, इनपुट सत्यापन, API
  एंडपॉइंट्स पर दर-सीमन जोड़ें, और सुनिश्चित करें कि सभी संचार HTTPS (TLS) पर हों ताकि
  पारगमन में डेटा की सुरक्षा हो सके।
  [OWASP API सुरक्षा दिशानिर्देश](https://owasp.org/www-project-api-security/) व्यापक API
  सुरक्षा सर्वोत्तम प्रथाओं को प्रदान करते हैं।

- **एकाधिक क्रेडेंशियल प्रकारों के लिए समर्थन:** यदि आप केवल यूरोपीय डिजिटल पहचान (EUDI)
  PID क्रेडेंशियल से अधिक प्राप्त करने की उम्मीद करते हैं, तो विभिन्न `doctype` मानों और
  क्रेडेंशियल प्रारूपों को संभालने के लिए तर्क का विस्तार करें।
  [W3C वेरिफ़ाएबल क्रेडेंशियल डेटा मॉडल](https://www.w3.org/TR/vc-data-model/) व्यापक VC
  प्रारूप विनिर्देश प्रदान करता है।

### 5.3 इस ट्यूटोरियल के दायरे से बाहर क्या है

यह उदाहरण जानबूझकर कोर ब्राउज़र-मध्यस्थता प्रवाह पर केंद्रित है ताकि इसे समझना आसान हो
सके। निम्नलिखित विषय दायरे से बाहर माने जाते हैं:

- **उत्पादन-तैयार सुरक्षा:** वेरिफ़ायर शैक्षिक उद्देश्यों के लिए है और इसमें एक लाइव
  वातावरण के लिए आवश्यक कठोरता का अभाव है।
- **W3C वेरिफ़ाएबल क्रेडेंशियल:** यह ट्यूटोरियल विशेष रूप से मोबाइल ड्राइविंग लाइसेंस के
  लिए ISO mDoc प्रारूप पर केंद्रित है। यह JWT-VCs या लिंक्ड डेटा प्रूफ (LD-प्रूफ) वाले VCs
  जैसे अन्य लोकप्रिय प्रारूपों को कवर नहीं करता है।
- **उन्नत OpenID4VP प्रवाह:** हम `redirect_uri` या डायनामिक क्लाइंट पंजीकरण का उपयोग करके
  सीधे वॉलेट-टू-बैकएंड संचार जैसी अधिक जटिल OpenID4VP सुविधाओं को लागू नहीं करते हैं।

इस नींव पर निर्माण करके और इन अगले चरणों को शामिल करके, आप एक मजबूत और सुरक्षित वेरिफ़ायर
विकसित कर सकते हैं जो आपके अपने अनुप्रयोगों में डिजिटल क्रेडेंशियल पर भरोसा करने और उन्हें
मान्य करने में सक्षम है।

## निष्कर्ष

बस इतना ही! 250 से कम TypeScript लाइनों के साथ, अब हमारे पास एक एंड-टू-एंड वेरिफ़ायर है
जो:

1. ब्राउज़र के क्रेडेंशियल API के लिए एक अनुरोध प्रकाशित करता है।
2. किसी भी अनुपालन वॉलेट को एक वेरिफ़ाएबल प्रेजेंटेशन की आपूर्ति करने देता है।
3. सर्वर पर प्रेजेंटेशन को मान्य करता है।
4. वास्तविक समय में UI को अपडेट करता है।

उत्पादन में, आप प्लेसहोल्डर सत्यापन को पूर्ण [ISO 18013-5](https://www.corbado.com/glossary/iso-18013-5) जाँचों
से बदल देंगे, जारीकर्ता निरस्तीकरण लुक-अप, दर-सीमन, ऑडिट लॉगिंग, और निश्चित रूप से,
एंड-टू-एंड TLS जोड़ेंगे—लेकिन कोर बिल्डिंग ब्लॉक बिल्कुल वही रहते हैं।

## संसाधन

यहाँ कुछ प्रमुख संसाधन, विनिर्देश और उपकरण हैं जिनका इस ट्यूटोरियल में उपयोग या संदर्भ
दिया गया है:

- **प्रोजेक्ट रिपॉजिटरी:**
    - [GitHub पर पूरा सोर्स कोड](https://github.com/corbado/digital-credentials-example)

- **प्रमुख विनिर्देश:**
    - [W3C वेरिफ़ाएबल क्रेडेंशियल डेटा मॉडल](https://www.w3.org/TR/vc-data-model/): VCs के
      लिए मूलभूत मानक।
    - [वेरिफ़ाएबल प्रेजेंटेशन के लिए OpenID (OpenID4VP)](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html):
      क्रेडेंशियल एक्सचेंज के लिए उपयोग किया जाने वाला प्रेजेंटेशन प्रोटोकॉल।
    - [ISO/IEC 18013-5 (mDoc)](https://www.iso.org/standard/69084.html): मोबाइल ड्राइविंग
      लाइसेंस (mDLs) के लिए अंतर्राष्ट्रीय मानक।
    - [W3C डिजिटल क्रेडेंशियल API](https://www.w3.org/TR/digital-credentials/#the-digital-credentials-api):
      वॉलेट से क्रेडेंशियल का अनुरोध करने के लिए उपयोग किया जाने वाला ब्राउज़र API।

- **उपकरण:**
    - [Android के लिए CMWallet](https://github.com/digitalcredentialsdev/CMWallet/actions/runs/16407676816/artifacts/3574255220):
      इस गाइड में उपयोग किया गया परीक्षण वॉलेट।

- **लाइब्रेरी:**
    - Next.js: फ्रंटएंड और बैकएंड बनाने के लिए React फ्रेमवर्क।
    - [cbor-web](https://github.com/hildjj/cbor-web): CBOR-एन्कोडेड mdoc क्रेडेंशियल को
      डीकोड करने के लिए।
    - [mysql2](https://github.com/sidorares/node-mysql2): [Node.js](https://www.corbado.com/blog/nodejs-passkeys)
      के लिए MySQL क्लाइंट।
