Build for the European Digital Identity Wallet with CodeB.
EU ID Wallet software, built in Malta by Aloaha Limited. Whether you are a Relying Party asking for a presentation, a public authority issuing credentials, a wallet vendor publishing your Wallet Attestation trust anchors, or an operator running a national trust list — the endpoints, snippets, and drop-in scripts below hook straight into the European Digital Identity Wallet ecosystem. Self-hostable, sovereign, Malta-registered. The upstream reference is docs.eudi.dev; nothing on this page is endorsed by the European Commission.
Honest scope. CodeB ships OID4VP FINAL, OID4VCI 1.0 Final, SD-JWT VC, mso_mdoc, and HAIP section 5.11 Wallet Attestation today.
Pick your role
Verifier / Relying Party
Ask for a presentation from a holder's wallet. Poll for completion, read claims.
Issuer
Mint SD-JWT VC or mso_mdoc credentials for holders via OID4VCI credential offers.
Wallet provider
Publish Wallet Attestation JWKS / PEM so verifiers can enforce HAIP §5.11.
Trust-anchor operator
Supply LOTL, SD-JWT-VC issuer, or mDoc issuer certificates to the verifier trust store.
Verifier setup
Every verifier flow uses the same three moves against the CodeB tenant: vp-start to open a presentation session, render the returned deep link (QR or native invocation), then poll vp-status until the wallet completes it.
1. Open a session
2. Render the deep link
Convert deep_link to a QR code for desktop flows, or invoke it directly on mobile. The deep link uses the openid4vp:// scheme (or haip:// when the tenant is configured for HAIP).
3. Poll for completion
4. Copy-paste JS
The vanilla-JS snippet handles the render + poll cycle. It exports one function:
A React hook variant lives at verifier-react-hook.jsx. Framework-scoped wrappers for Vue and Angular ship on the verifier integration cookbook.
Issuer setup
The issuer flow follows OID4VCI 1.0 Final (dedicated Nonce Endpoint, Notification Endpoint, credentials[] response shape; the Draft-15 scalar credential field is preserved as a backward-compat fallback). You declare which credential types your tenant supports, mint a credential offer per holder, and hand the wallet a openid-credential-offer:// deep link.
1. Declare supported VCTs
Drop VCT metadata JSON files under App_Data/<tenant>/vci/, or use the vci-admin UI. Each VCT declares its credential format (vc+sd-jwt or mso_mdoc), claims, and cryptographic constraints.
2. Mint a credential offer
3. Ready-to-copy credential offer JSON
Two sample offers ship in /downloads/eu-wallet/:
- issuer-credential-offer-sample.json - SD-JWT VC with pre-authorized-code grant (single-use bearer, no PIN).
- issuer-credential-offer-mdoc-sample.json - mso_mdoc PID with authorization_code flow.
Wallet-provider setup
Wallet providers publish the public keys that sign HAIP section 5.11 Wallet Attestation JWTs, so RPs can enforce that a presentation actually came from a specific wallet product.
1. Publish your JWKS
Static file at https://<YOUR_WALLET_DOMAIN>/.well-known/wallet-provider.jwks.json. A shape sample lives at wallet-provider-jwks.json.
2. Deposit at the tenant
The tenant operator drops the JWKS (or the equivalent X.509 PEM) under:
3. Enforce Wallet Attestation
Set Oidc:WalletAttestationRequired=true on the tenant to reject presentations that lack a valid HAIP §5.11 attestation JWT. The testscripts/wallet-attestation-smoke.py probe exercises the full path.
Trust-anchor setup
Verifier tenants need three distinct trust stores: the EU List of Trusted Lists (LOTL) for eIDAS certificate chains, an SD-JWT VC issuer set, and an mDoc issuer set. Each stores its inputs under App_Data/<tenant>/trust/ as PEM / JSON / DER.
The end-to-end operator walk-through, including nightly reconciler + wacs cert refresh, lives on the dedicated HAIP operator setup page. This section is intentionally short: the operator page is the source of truth.
Integrate in minutes
Copy-paste against your own tenant — replace your-tenant.example with your CodeB host. These call the same public endpoints documented in the EU Wallet verifier API and the OIDC provider. No SDK required.
Verify an EU Wallet presentation — OID4VP 1.0
# 1) Start a presentation request and keep its session cookie (OID4VP 1.0 / HAIP)
curl -s -c cj 'https://your-tenant.example/oidc.ashx?action=vp-start&client_id_prefix=x509_hash'
# -> { "id": "...", "deep_link": "openid4vp://...", "expires_in": 300, "status": "pending" }
# 2) Render deep_link as a QR (desktop) or open it on the phone.
# The EUDI wallet fetches the signed request and posts an encrypted SD-JWT VC.
# 3) Poll with the same cookie until the user finishes (about every 2 s)
curl -s -b cj 'https://your-tenant.example/oidc.ashx?action=vp-response&id=<id>'
# waiting -> HTTP 202 { "ok": false, "status": "pending" }
# verified -> HTTP 200 { "ok": true, "status": "completed", "user": "...",
# "claims": { ... }, "sso_assertion": "<RS256 JWT>" }
Sign in with OpenID Connect — Authorization Code + PKCE
# 1) Discover endpoints
curl -s https://your-tenant.example/.well-known/openid-configuration
# 2) Send the user to sign in (PKCE)
# https://your-tenant.example/oauth2/v1/authorize?response_type=code
# &client_id=<id>&redirect_uri=<cb>&scope=openid%20profile%20email
# &code_challenge=<S256>&code_challenge_method=S256&state=<s>&nonce=<n>
# 3) Exchange the code for tokens
curl -s -X POST https://your-tenant.example/oauth2/v1/token \
-d grant_type=authorization_code -d code=<code> -d redirect_uri=<cb> \
-d client_id=<id> -d code_verifier=<verifier>
# -> { "access_token": "...", "id_token": "...", "expires_in": 3600 }
# 4) Read claims
curl -s https://your-tenant.example/oauth2/v1/userinfo -H 'Authorization: Bearer <token>'
Register your client first in the tenant admin (OIDC clients). Full walkthrough: OIDC sign-up how-to.
Issue a credential to a wallet — OID4VCI
# Mint a credential offer in the issuer admin (see Issuer setup above), # then share the offer URI as a QR for the wallet to scan: curl -s 'https://your-tenant.example/vci.ashx?action=offer&id=<offer_id>' # -> openid-credential-offer://?credential_offer_uri=...
Formats: SD-JWT VC (dc+sd-jwt) and ISO 18013-5 mdoc. See Issuer setup.
Hand it to your coding assistant
No SDK to learn — paste this prompt into your coding assistant and let it scaffold the integration against your stack:
Integrate my app with a CodeB / EUDI identity tenant at https://your-tenant.example. - Sign-in: OpenID Connect, Authorization Code + PKCE. Read endpoints from /.well-known/openid-configuration (authorize/token/userinfo under /oauth2/v1/). - Verify an EU Digital Identity Wallet presentation: GET oidc.ashx?action=vp-start, render the returned deep_link as a QR, then poll oidc.ashx?action=vp-response&id=<id> until it returns HTTP 200 with ok:true and the verified claims (HTTP 202 while pending). Keep the session cookie set by vp-start and send it on every poll. - Credentials are SD-JWT VC (dc+sd-jwt) and ISO 18013-5 mdoc, OID4VP 1.0 / HAIP. - Handle the pending, expired and invalid_vp_token states. Generate the server and client code in <my stack>. Spec reference: docs.eudi.dev.
Deep-link builder (test harness)
Build a quick openid4vp:// or openid-credential-offer:// URL for wallet interop testing. Nothing here is sent to a server — this is a pure client-side helper. The same logic lives in openid4vp-deep-link-builder.js.
Reference: docs.eudi.dev for upstream EU Digital Identity Wallet reference implementations and protocol profiles.
Developer cookbooks: OIDC sign-in - JWT validation - M2M API keys - Webhooks
See also: wallet interoperability matrix · glossary.
Frequently asked questions
Which specs does CodeB implement for European Digital Identity Wallet integration?
OpenID for Verifiable Presentations (OID4VP) FINAL, OpenID for Verifiable Credential Issuance (OID4VCI) Draft 15, SD-JWT VC (draft-ietf-oauth-sd-jwt-vc), ISO/IEC 18013-5 mso_mdoc, and the High Assurance Interoperability Profile (HAIP). Upstream reference: docs.eudi.dev.
Do you ship official EU Commission endorsement?
No. CodeB is not endorsed by the European Commission. These integration guides implement public EUDI-ecosystem specifications and reference the upstream docs at docs.eudi.dev.
Does the verifier flow enforce Wallet Attestation?
Optional per tenant. Set Oidc:WalletAttestationRequired=true on the tenant to require HAIP section 5.11 wallet attestation on every presentation.