EUDI Wallet (eIDAS 2.0)
Beta disclaimer: Mandaitor is currently exploring and implementing EUDI Wallet support, but the required registration and ecosystem onboarding steps are still outstanding. Mandaitor should therefore not yet be described as an official EUDI Wallet party, production Relying Party, or formally recognized participant in the EUDI ecosystem.
The EU Digital Identity Wallet (EUDI Wallet) is the centrepiece of eIDAS 2.0 (Regulation EU 2024/1183). Mandaitor is preparing an integration path to consume verified Person Identification Data (PID) from EUDI Wallets and bind it to mandates once the required registration and operational prerequisites are complete.
Why EUDI Wallet?
eIDAS 2.0 answers "who is this person?" through government-issued PID. Mandaitor answers "may this person act on behalf of another?" through its mandate registry. Together, they provide a complete delegation infrastructure with legally-backed identity verification.
| Aspect | Details |
|---|---|
| Protocol | OpenID for Verifiable Presentations (OpenID4VP) |
| Credential Format | SD-JWT VC (online) + mdoc/ISO 18013-5 (proximity) |
| Assurance Level | Target state: HIGH once ecosystem onboarding is complete |
| Privacy | Selective disclosure — only requested attributes shared |
| Deadline | All EU Member States must issue wallets by December 2026 |
Integration Flow
Cross-Device Flow (QR Code)
┌──────────┐ ┌──────────────┐ ┌─────────────┐
│ Dashboard │ │ Mandaitor │ │ EUDI Wallet │
│ (Browser) │ │ API │ │ (Phone) │
└────┬─────┘ └──────┬───────┘ └──────┬──────┘
│ POST /eudi/sessions│ │
│────────────────────>│ │
│ {session_id, qr} │ │
│<────────────────────│ │
│ │ │
│ Render QR Code │ │
│ ┌──────────┐ │ │
│ │ ██ QR ██ │ │ Scan QR │
│ └──────────┘ │<──────────────────────│
│ │ │
│ │ GET /eudi/request/{id} │
│ │<──────────────────────│
│ │ (signed request JWT) │
│ │──────────────────────>│
│ │ │
│ │ User consents │
│ │ │
│ │ POST /eudi/sessions/ │
│ │ {id}/response │
│ │<──────────────────────│
│ │ (VP Token: SD-JWT VC) │
│ │ │
│ Poll GET /eudi/ │ Verify VP Token │
│ sessions/{id} │ ✓ Signature │
│────────────────────>│ ✓ Trusted List │
│ {status: COMPLETED, │ ✓ Revocation │
│ resolved_identity} │ ✓ Nonce │
│<────────────────────│ │
Same-Device Flow (Deep Link)
For mobile-first scenarios, Mandaitor returns a deep link (openid4vp://authorize?...) that opens the wallet app directly on the same device.
PID Attributes
The wallet presents Person Identification Data with selective disclosure:
| Attribute | Required | Description |
|---|---|---|
unique_id | Yes | Persistent identifier from the Member State |
family_name | Yes | Current surname(s) |
given_name | Yes | Current first name(s) |
birth_date | Optional | Date of birth (ISO 8601) |
nationality | Optional | ISO 3166-1 alpha-2 country code |
For beta planning and prototype evaluation, Mandaitor currently models three presentation definitions with different data requirements:
mandaitor-pid-minimal— Onlyunique_id(most privacy-preserving)mandaitor-pid-standard— Name + unique ID (default for mandate creation)mandaitor-pid-delegation— PID + delegation EAA attestation
SDK Usage
import { MandaitorClient } from "@mandaitor/sdk";
const client = new MandaitorClient({
apiKey: "mk_live_...",
tenantId: "tnt_your_tenant",
});
// 1. Initiate EUDI session
const session = await client.initiateEudiSession("mandaitor-pid-standard");
console.log(session.qr_code_uri); // Render as QR code
console.log(session.deep_link_uri); // Or open directly on mobile
// 2. Poll for completion (wallet responds asynchronously)
const status = await client.getEudiSessionStatus(session.session_id);
if (status.status === "COMPLETED") {
console.log(status.resolved_identity.subject_id); // "eudi:DE/123..."
console.log(status.resolved_identity.eidas_attributes.family_name);
}
// 3. Create mandate bound to EUDI identity
const mandate = await client.createMandate({
principal: {
type: "NATURAL_PERSON",
subject_id: status.resolved_identity.subject_id,
eidas_attributes: status.resolved_identity.eidas_attributes,
},
delegate: {
type: "AGENT",
subject_id: "agent:my-ai-agent",
},
scope: {
actions: ["construction.validation.approve"],
resources: ["monco:project:*"],
effect: "ALLOW",
},
constraints: {},
eudi_session_id: session.session_id, // Binds the verified identity
});
React Widget
import WalletVerification from "@/components/eudi/WalletVerification";
function MyComponent() {
return (
<WalletVerification
presentationDefinitionId="mandaitor-pid-standard"
onVerified={(session) => {
console.log("Verified:", session.resolved_identity.subject_id);
}}
onError={(error) => console.error(error)}
onCancel={() => console.log("Cancelled")}
/>
);
}
Credential Verification
Once the EUDI integration path is fully enabled, Mandaitor is designed to verify VP Tokens through a multi-step process:
- SD-JWT parsing — Decode the compact serialization and extract disclosures
- Disclosure hash verification — Verify each disclosure hash matches the
_sdarray - Cryptographic signature — Verify the JWT signature against the issuer's JWKS
- Issuer trust — Check the issuer against the EU Trusted Lists (LOTL)
- Credential revocation — Check StatusList2021 / BitstringStatusListEntry status
- Nonce validation — Prevent replay attacks with session-bound nonces
- Expiration check — Reject expired credentials
mdoc Support
For proximity presentations (BLE/NFC), Mandaitor also supports the mdoc format (ISO 18013-5). mdoc credentials use CBOR encoding and the eu.europa.ec.eudi.pid.1 namespace for PID claims.
Trusted Lists
The intended production integration maintains a cached copy of the EU List of Trusted Lists (LOTL) to verify that PID issuers are legitimate. During beta preparation, this should be understood as target architecture rather than a statement that Mandaitor has already completed every formal onboarding, registration, or recognition requirement of the EUDI ecosystem.