Cloud Wallet UI is the frontend application for the EUDI Cloud Wallet experience.
It allows users to register a wallet tenant, scan credential offers, complete issuance and presentation flows, and view stored credentials.
- Technology stack
- Getting started
- Available scripts
- Environment configuration
- Application routes
- Issuance flow
- Presentation flow
- Project structure
- React 19
- TypeScript
- Vite
- Tailwind CSS
- ESLint (flat config)
- Prettier
- Vitest
- Playwright (e2e testing)
- Node.js 20+ (recommended)
- npm 10+ (recommended)
npm install
npm run devThe app runs with Vite's default development server and hot module replacement.
npm run dev- Start the local development server.npm run build- Type-check and produce a production build.npm run lint- Run ESLint (warnings treated as errors).npm run lint:fix- Auto-fix lint issues where possible.npm run format- Check formatting with Prettier.npm run format:write- Write formatting updates.npm run test- Run unit tests with Vitest.npm run build:e2e- Type-check and build for end-to-end testing mode.npm run test:e2e- Run end-to-end tests with Playwright.npm run preview- Preview the production build locally.
The application uses Vite environment variables.
-
VITE_API_BASE_URL
Backend base URL. When/api/v1is missing, the app appends it automatically.
Example:http://localhost:3000becomeshttp://localhost:3000/api/v1. -
VITE_ALLOWED_CREDENTIAL_OFFER_HOSTS(optional)
Comma-separated allowlist ofhost[:port]values for plainhttpscredential-offer payloads.
If omitted, the app only accepts conservative plain-HTTPS offers (path must containcredential-offer).
openid-credential-offer://...links remain accepted regardless. -
VITE_DEBUG_API(optional)
Set totrueto enableconsole.debuglogging of all traffic fromapiGet/apiPostand the issuance SSE stream (useSseStream): request method and path, redacted headers (Authorizationis never logged in full), response status and JSON bodies, and parsed SSE events.
Do not enable in production builds. Leave unset (default) so no API traffic is logged. -
VITE_E2E(optional)
Set totruein e2e builds to enable test helpers (e.g., sample QR-code offers on the scan screen). Do not enable in production builds.
Create .env in the project root:
VITE_API_BASE_URL=http://localhost:3000
# Optional:
# VITE_ALLOWED_CREDENTIAL_OFFER_HOSTS=issuer.example.com,wallet.example.org
# VITE_DEBUG_API=true
# VITE_E2E=trueYou can also copy .env.example to .env (or .env.local) and adjust values.
| Route | Purpose |
|---|---|
/registration |
Initial tenant registration (first-time users). |
/ |
Home screen and entry point to scanning. |
/scan |
QR scanner and credential-offer / presentation intake. |
/present |
Presentation request review (verifier details). |
/present/details |
Proof details and consent screen (Share / Decline). |
/present/success |
Success state after presentation submission. |
/credential-types |
Credential types offered by issuer. |
/credential-types/:optionId |
Selected credential type details and issuance actions. |
/issuance/success/:credentialId? |
Success state after issuance. |
/credentials |
Wallet credential list or empty state. |
/credentials/:credentialId |
Credential details with reveal/hide controls. |
/credentials/:credentialId/remove |
Remove credential confirmation screen. |
All routes except /registration are protected and require a stored tenant ID.
- User scans a credential-offer QR code on
/scan. - Wallet validates and submits the offer to create an issuance session.
- User accepts the offer and selects a credential type.
- User starts issuance on the credential details screen.
- Flow continues through one of:
- redirect-based authorization,
- pre-authorized flow with transaction code, or
- direct issuance.
- SSE events update processing state until completion or failure.
- On success, user is redirected to
/issuance/successand can open credential details.
- User scans a verifier QR code or receives a deep link on
/scan. - Wallet validates and submits the request to start a presentation session via
POST /presentation/start. - Backend resolves the request, evaluates the DCQL query against stored credentials, and returns verifier metadata and credential matches.
- User reviews verifier details, requested claims, and matched credentials on
/present/details. - User consents (Share) or declines the presentation.
- Backend builds and submits the VP Token to the verifier synchronously.
- On success:
- Cross-device flow: user is shown
/present/successand the verifier has received the VP Token. - Same-device flow: the browser is redirected to the verifier's
redirect_uri.
- Cross-device flow: user is shown
src/
api/ # API clients and endpoint modules (grouped by feature)
auth/ # Tenant registration and auth initialization
components/ # Reusable UI components (grouped by feature)
constants/ # App constants (routes, keys)
e2e/ # End-to-end test helpers and sample data
hooks/ # Custom React hooks
pages/ # Page-level components (grouped by feature)
state/ # Issuance and presentation flow state stores/providers
types/ # Shared TypeScript types
utils/ # Utility helpers and parsers (grouped by feature)
*/tests/ # Unit tests grouped by feature