# Web5 in 5️⃣ minutes Let's build a decentralized application on the Web5 platform - in under 5 minutes. You will learn how to: ✅ Create unique digital IDs for users known as Decentralized Identifiers (DIDs) ✅ Issue and manage digital proofs using Verifiable Credentials(VCs) ✅ Store and read data from your personal data store called a Decentralized Web Node (DWN) Let’s go! 🚀 ## Installation ``` INFO Prerequisites Node Package Manager, npm, installed and on your system's $PATH. Node version 18 and above ``` ### 1. Create a directory This will be the home of your new Web5 app. Run the following commands in your CLI: ```bash mkdir web5-app cd web5-app ``` ### 2. Initialize Your Node Project: ```bash npm init -y ``` **Use NPM to install the necessary Web5 SDKs:** ```bash npm install @web5/api @web5/credentials ``` **These steps will create a package.json in the root of your project. Open the newly created`package.json` and add `module` as a type:** ```json { "dependencies": { "@web5/api": "0.9.3" "@web5/credentials": "1.0.1", }, "type": "module" } ``` ### 3. Import Web5 **Create an `index.js` file where you will write all of your application logic:** ```bash touch index.js ``` **For Windows using PowerShell:** ```bash New-Item index.js -ItemType File ``` ``` NOTE After npm resolves the dependency, you may see a few warnings. You can ignore these for now. ``` **At the top of your `index.js` file, add these lines to import the Web5 package dependencies that you will use to build your application:** ```js import { Web5 } from '@web5/api'; import { VerifiableCredential } from '@web5/credentials'; ``` <details> <summary>Additional import for Node 18</summary> ```javascript /* Needs globalThis.crypto polyfill. This is *not* the crypto you're thinking of. It's the original crypto...CRYPTOGRAPHY. */ import { webcrypto } from 'node:crypto'; // @ts-ignore if (!globalThis.crypto) globalThis.crypto = webcrypto; ``` </details> <details> <summary>Additional imports for React Native</summary> ```js /* React Native needs crypto.getRandomValues polyfill and sha512. This is *not* the crypto you're thinking of. It's the original crypto...CRYPTOGRAPHY. */ import 'react-native-get-random-values'; import { hmac } from '@noble/hashes/hmac'; import { sha256 } from '@noble/hashes/sha256'; import { sha512 } from '@noble/hashes/sha512'; ed.etc.sha512Sync = (...m) => sha512(ed.etc.concatBytes(...m)); ed.etc.sha512Async = (...m) => Promise.resolve(ed.etc.sha512Sync(...m)); secp.etc.hmacSha256Sync = (k, ...m) => hmac(sha256, k, secp.etc.concatBytes(...m)); secp.etc.hmacSha256Async = (k, ...m) => Promise.resolve(secp.etc.hmacSha256Sync(k, ...m)); ``` </details> **Now we have the Web5 SDKs installed and are ready to start building!** ## 1. Instantiate Web5 and Create DID In Web5 apps, a user’s unique identifier - like an email address - is called a [Decentralized Identifier (DID)](https://developer.tbd.website/docs/web5/learn/decentralized-identifiers). We are building a decentralized app, so your users are using identifiers that aren't tied to a centralized authority. The Web5 class is an isolated API object for doing all things Web5. The connect() function creates an instance of Web5 and also creates a decentralized identifier or obtains connection to an existing one. In index.js below the import statement, create a new instance of Web5: ```js const { web5, did: aliceDid } = await Web5.connect({password: 'my-secure-password'}); ``` This Web5 instance is what you'll use to access the other objects of Web5 such as did and dwn. Within the connect function we’re using `dht` as the DID method. Learn more [DID methods](https://developer.tbd.website/docs/web5/learn/decentralized-identifiers#methods). ``` INFO Web5 is split into three main top-level objects: web5.did web5.dwn web5.vc ``` <details> <summary>Password Option</summary> While not required, it's strongly recommended to use a strong, secure password when connecting to Web5. This helps prevent unauthorized access to your private data, including your identity and cryptographic keys. </details> <details> <summary>Test your code</summary> Wanna see the DID you just created? In index.js, add the following line and save your file: ```js console.log(aliceDid); ``` Then from the terminal, run: ```bash node index.js ``` You'll see the newly created DID. </details> ## 2. Access your Bearer Identity In the previous step, you generated what is known as a (DID), which appears as an alphanumeric string, referred to as a DID URI. This DID URI is part of a broader JSON object containing metadata such as cryptographic keys that prove ownership of the DID and rules governing its usage, management, or modification. This object is known as your BearerIdentity. It enables you to securely sign and verify data, ensuring authenticity and integrity. To access your Bearer Identity, add the following lines of code to your `index.js`: ```js const alice = await web5.agent.identity.get({ didUri: aliceDid }); ``` <details> <summary>Test your code</summary> Wanna see the identity you just created? In index.js, add the following line and save your file: ```js console.log(alice); ``` Then from the terminal, run: ```bash node index.js ``` You'll see the full identity. It should resemble the output below: ```bash BearerIdentity { // nested objects and properties here } ``` </details> ## 3. Create a VC [Verifiable Credentials (VCs)](https://developer.tbd.website/docs/web5/learn/verifiable-credentials) are digital badges of proof used to confirm specific facts or achievements about individuals, organizations, or entities. Typically, a trusted authority would issue a Verifiable Credential. For example, a university might issue a VC to prove that you have completed a degree program. In this step, you'll create a self-signed VC -- meaning you'll issue a Verifiable Credential that states claims about yourself. In your `index.js`, create your Verifiable Credential: ```js class UserDetailsCredential { constructor(name, dob, address, phoneNumber) { this.name = name; this.dob = dob; this.address = address; this.phoneNumber = phoneNumber; } } const vc = await VerifiableCredential.create({ type: 'UserDetailsCredential', issuer: aliceDid.uri, subject: aliceDid.uri, expirationDate: '2026-09-30T12:34:56Z', data: new UserDetailsCredential( 'Alice Smith', '1995-07-04T12:34:56Z', '106th and Park NY, USA 02110', '678-999-8212') }); ``` <details> <summary>Test your code</summary> Wanna see the VC you just created? In index.js, add the following line and save your file: ```js console.log(vc); ``` Then from the terminal, run: ```bash node index.js ``` You'll see the newly created VC. It should resemble the output below: ```bash VerifiableCredential { vcDataModel: { '@context': [ 'https://www.w3.org/2018/credentials/v1' ], type: [ 'VerifiableCredential', 'MyVerifiableCredential' ], id: 'urn:uuid:f4d872e9-0a74-4b96-a449-9dcb8fe9edca', issuer: 'did:dht:n3nzsqjqzyuwit1qh16gwimq7d3nih6gufpi4n3dwkd9fq3xyh3o', issuanceDate: '2024-05-06T00:17:48Z', credentialSubject: { id: 'did:dht:n3nzsqjqzyuwit1qh16gwimq7d3nih6gufpi4n3dwkd9fq3xyh3o', name: 'Alice Smith', dob: '1995-07-04T12:34:56Z', address: '106th and Park NY, USA 02110', phoneNumber: '678-999-8212' }, expirationDate: '2026-09-30T12:34:56Z' } } ``` </details> ## 4. Sign the VC Now, you will sign the VC to ensure its authenticity and integrity. To sign your VC, add this line to your `index.js`: ```js const signedVc = await vc.sign({ did: aliceDid }); ``` When an issuer signs a VC, it attests that they are truly the one who issued it. This cryptographic process also converts the VC into a JSON Web Token (JWT), making the credential tamper-evident and verifiable by others. <details> <summary>Test your code</summary> Wanna see the JWT version of your signed VC? In index.js, add the following line and save your file: ```js console.log(signedVc); ``` Then from the terminal, run: ```bash node index.js ``` You'll see the JWT-encoded version of your Verifiable Credential similar to the alphanumeric string below: ```bash eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6bWMxcWl6cnVhOG9pZWZ5cWhyNm9teTZjYzQzNnByY20xc3U1cjNwNzVxazkxdGY2eHcxbyMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTXlWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpZCI6InVybjp1dWlkOmI2NmE5ZDk3LWNjMzktNDQyYy1iNjFhLTE2YzhkOTJhOGM2NCIsImlzc3VlciI6ImRpZDpkaHQ6bWMxcWl6cnVhOG9pZWZ5cWhyNm9teTZjYzQzNnByY20xc3U1cjNwNzVxazkxdGY2eHcxbyIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDUtMDZUMDA6MDk6MTVaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0Om1jMXFpenJ1YThvaWVmeXFocjZvbXk2Y2M0MzZwcmNtMXN1NXIzcDc1cWs5MXRmNnh3MW8iLCJuYW1lIjoiQWxpY2UgU21pdGgiLCJkb2IiOiIxOTk1LTA3LTA0VDEyOjM0OjU2WiIsImFkZHJlc3MiOiIxMDZ0aCBhbmQgUGFyayBOWSwgVVNBIDAyMTEwIiwicGhvbmVOdW1iZXIiOiI2NzgtOTk5LTgyMTIifSwiZXhwaXJhdGlvbkRhdGUiOiIyMDI2LTA5LTMwVDEyOjM0OjU2WiJ9LCJuYmYiOjE3MTQ5NTQxNTUsImp0aSI6InVybjp1dWlkOmI2NmE5ZDk3LWNjMzktNDQyYy1iNjFhLTE2YzhkOTJhOGM2NCIsImlzcyI6ImRpZDpkaHQ6bWMxcWl6cnVhOG9pZWZ5cWhyNm9teTZjYzQzNnByY20xc3U1cjNwNzVxazkxdGY2eHcxbyIsInN1YiI6ImRpZDpkaHQ6bWMxcWl6cnVhOG9pZWZ5cWhyNm9teTZjYzQzNnByY20xc3U1cjNwNzVxazkxdGY2eHcxbyIsImlhdCI6MTcxNDk1NDE1NSwiZXhwIjoxNzkwNzcxNjk2fQ.pSv5Yp9_Doeotoqf1RPhM6Q_QnoHtPhUzZQr5i1H7ENfXUhdSNTDmsH8FA910jR2yLioPQQZ5cbTlw-PJqJCCw ``` </details> ## 5. Store your VC in your DWN Let's store your VC in your Decentralized Web Node(DWN). A DWN is a personal data store - a platform for messages, pictures, videos, medical records, and just about any content a user may want to store. <details> <summary>Read more about DWNs</summary> Your app should not store users' data in your centralized database. Instead, their data should be stored in their DWN. This is how the user retains ownership over their content. Through permissions, users can decide which apps can read, write, and delete content from their DWN. The DWN exists in local storage under the name dwn-info. The DWN persists across browser sessions and can be synched across a user's devices. A user can host their DWN in mulitple locations. The Web5 SDK is both browser and Node.js compliant, meaning you can use the same APIs on both client side and serverside. </details> To store your VC in your DWN, add the following lines of code to your `index.js`: ```js const { record } = await web5.dwn.records.create({ data: signedVc, message: { schema: 'UserDetailsCredential', dataFormat: 'application/vc+jwt', } }); ``` <details> <summary>Test your code</summary> Wanna see the identity you just imported? In index.js, add the following line and save your file: ```js console.log('writeResult', record); ``` Then from the terminal, run: ```bash node index.js ``` You'll see the record that was written to the user's DWN. It will resemble: ```bash writeResult _Record {} ``` </details> ## 6. Read your VC from your DWN To read the JWT-encoded VC stored in your DWN, add the following to index.js: ```js const readSignedVc = await record.data.text(); ``` ``` Note: This is your DWN, so you have permission to read this record. If you need to access record from a DWN that doesn't belong to you, you would need permissions from the DWN's owner and to use the [query](https://developer.tbd.website/docs/web5/build/decentralized-web-nodes/query-from-dwn) method. ``` <details> <summary>Test your code</summary> To see the record that was read from the DWN, add the following to index.js: In index.js, add the following line and save your file: ```js console.log('readResult', readSignedVc); ``` Then from the terminal, run: ```bash node index.js ``` You'll see the JWT-encoded version of your Verifiable Credential similar to the alphanumeric string below: ```bash eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6bWMxcWl6cnVhOG9pZWZ5cWhyNm9teTZjYzQzNnByY20xc3U1cjNwNzVxazkxdGY2eHcxbyMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTXlWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpZCI6InVybjp1dWlkOmI2NmE5ZDk3LWNjMzktNDQyYy1iNjFhLTE2YzhkOTJhOGM2NCIsImlzc3VlciI6ImRpZDpkaHQ6bWMxcWl6cnVhOG9pZWZ5cWhyNm9teTZjYzQzNnByY20xc3U1cjNwNzVxazkxdGY2eHcxbyIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDUtMDZUMDA6MDk6MTVaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0Om1jMXFpenJ1YThvaWVmeXFocjZvbXk2Y2M0MzZwcmNtMXN1NXIzcDc1cWs5MXRmNnh3MW8iLCJuYW1lIjoiQWxpY2UgU21pdGgiLCJkb2IiOiIxOTk1LTA3LTA0VDEyOjM0OjU2WiIsImFkZHJlc3MiOiIxMDZ0aCBhbmQgUGFyayBOWSwgVVNBIDAyMTEwIiwicGhvbmVOdW1iZXIiOiI2NzgtOTk5LTgyMTIifSwiZXhwaXJhdGlvbkRhdGUiOiIyMDI2LTA5LTMwVDEyOjM0OjU2WiJ9LCJuYmYiOjE3MTQ5NTQxNTUsImp0aSI6InVybjp1dWlkOmI2NmE5ZDk3LWNjMzktNDQyYy1iNjFhLTE2YzhkOTJhOGM2NCIsImlzcyI6ImRpZDpkaHQ6bWMxcWl6cnVhOG9pZWZ5cWhyNm9teTZjYzQzNnByY20xc3U1cjNwNzVxazkxdGY2eHcxbyIsInN1YiI6ImRpZDpkaHQ6bWMxcWl6cnVhOG9pZWZ5cWhyNm9teTZjYzQzNnByY20xc3U1cjNwNzVxazkxdGY2eHcxbyIsImlhdCI6MTcxNDk1NDE1NSwiZXhwIjoxNzkwNzcxNjk2fQ.pSv5Yp9_Doeotoqf1RPhM6Q_QnoHtPhUzZ ``` </details> ## 7. Parse your stored VC After storing your Verifiable Credential (VC) as a JSON Web Token (JWT), you can convert it back to JSON format using the `parseJwt()` method. This allows you to inspect the contents of the VC in a readable format. Add the following lines to your index.js to parse and inspect your JWT-encoded VC: ```js const parsedVc = VerifiableCredential.parseJwt({ vcJwt: readSignedVc }); ``` <details> <summary>Test your code</summary> Wanna see your parsed JWT? In index.js, add the following line and save your file: ```js console.log(parsedVc); ``` Then from the terminal, run: ```bash node index.js ``` Your VC may resemble the output below: ```bash VerifiableCredential { vcDataModel: { '@context': [ 'https://www.w3.org/2018/credentials/v1' ], type: [ 'VerifiableCredential', 'MyVerifiableCredential' ], id: 'urn:uuid:f4d872e9-0a74-4b96-a449-9dcb8fe9edca', issuer: 'did:dht:n3nzsqjqzyuwit1qh16gwimq7d3nih6gufpi4n3dwkd9fq3xyh3o', issuanceDate: '2024-05-06T00:17:48Z', credentialSubject: { id: 'did:dht:n3nzsqjqzyuwit1qh16gwimq7d3nih6gufpi4n3dwkd9fq3xyh3o', name: 'Alice Smith', dob: '1995-07-04T12:34:56Z', address: '106th and Park NY, USA 02110', phoneNumber: '678-999-8212' }, expirationDate: '2026-09-30T12:34:56Z' } } ``` </details> ## Summary Congrats! You've successfully created a VC and stored it in your local DWN. Your application can now issue Verifiable Credentials, empowering users to manage their personal data securely. ``` INFO Download the completed index.js file View source code for the interactive sandbox of this Quickstart Run interactive sandbox directly in your browser ``` ``` Next Steps Learn more about DIDs Learn more about VCs Learn more about DWNs Build a shared ToDo app ```