For the complete documentation index, see llms.txt. This page is also available as Markdown.

Project Setup

What We Are Doing:

  • Initializing a Node.js/Express project.

  • Installing a minimal set of dependencies.

  • Preparing the base structure for talking to the Issuer and Verifier HTTP API.

Why: We need a backend server that:

  • Calls the Issuer API to create credential offers.

  • Calls the Verifier API to create authorization (presentation) requests and check results.

  • Serves a small frontend for user input and QR code display.

The Issuer and Verifier are exposed as a plain HTTP API (issuance follows OpenID4VCI, verification follows OpenID4VP). Our app speaks to the API directly with the built-in fetch, sending a standard OIDC Bearer token on every request — no client library is needed. That keeps the dependency list small: an HTTP server, an env loader, and a JWT helper.

Steps:

  1. Create a new directory and initialize a Node.js project:

    mkdir -p evdi-tutorial/{src,public} && \
    touch evdi-tutorial/src/{index.js,issuer-routes.js,verifier-routes.js,verification-flows.js,authorization-routes.js} \
      evdi-tutorial/public/{index.html,dashboard.html} \
      evdi-tutorial/.env
    cd evdi-tutorial
    npm init -y
    npm pkg set type=module

The npm pkg set type=module step marks the package as an ES module — all the code in this tutorial uses import/export syntax, which Node.js only accepts in .js files when package.json contains "type": "module".

Project structure:

  1. Install dependencies:

  • express — runs our backend and serves the frontend pages.

  • dotenv — loads the Issuer/Verifier URLs and token from .env.

  • jsonwebtoken — signs and verifies our own short-lived app session token (used later to gate the protected dashboard).

We use the built-in fetch for HTTP calls (available in Node.js 18+), so no extra HTTP client is needed.

  1. Add the API configuration to your .env file. The app authenticates to the Issuer and Verifier with an OIDC access token (an admin Bearer token from the deployment's Keycloak) sent as Authorization: Bearer <token>, so we store the base URLs and the per-service tokens here:

These values are accessible in your code as process.env.ISSUER_BASE_URL, process.env.VERIFIER_BASE_URL, process.env.ISSUER_ACCESS_TOKEN, and process.env.VERIFIER_ACCESS_TOKEN. We will obtain the access tokens and fill in the base URLs in the next steps, when we create the Issuer and Verifier. Next, we will look at how authentication works — the OIDC Bearer token that every request in this tutorial carries.

Last updated