WalletGate EUDI SDK

EU Digital Identity Wallet verification made simple

WalletGate is a Verifier/Relying Party solution in the EU Digital Identity Wallet ecosystem. We enable businesses to accept and verify electronic attestations from EUDI Wallets using real EU government infrastructure.

🏛️

Real EU Infrastructure

Direct connection to EU LOTL

📋

Standards Compliant

OpenID4VP, ISO 18013-5, SD-JWT VC

🚀

Simple Integration

5 lines of code instead of 500+

Installation

Node.js / JavaScript / TypeScript

npm install @walletgate/eudi

💡 Other Languages

For Ruby, PHP, Java, Python, Go, and other languages, use our HTTP API directly. No SDK installation required - same functionality as JavaScript SDK.

Quick Start

Before you begin: Get a free test API key (wg_test_*) at walletgate.app

1. Initialize

import { WalletGate } from '@walletgate/eudi';

const eudi = new WalletGate({
  apiKey: process.env.WALLETGATE_API_KEY,
  baseUrl: 'https://api.walletgate.app'
});

2. Start Verification

const session = await eudi.startVerification({
  checks: [
    { type: 'age_over', value: 18 },
    { type: 'residency_in', value: ['EU'] }
  ],
  redirectUrl: 'https://yourapp.com/verify-complete'
});

// Redirect user to wallet
window.location.href = session.verificationUrl;

3. Get Results

const result = await eudi.getResult(sessionId);

if (result.status === 'verified') {
  console.log('Verification successful!');
}

Verification Types

TypeDescriptionExample
age_overVerify minimum age{ type: "age_over", value: 18 }
age_underVerify maximum age{ type: "age_under", value: 65 }
residency_inVerify residency{ type: "residency_in", value: ["DE", "FR"] }
name_matchKYC name matching{ type: "name_match", value: "John Doe" }

Webhooks

Receive real-time notifications when verification status changes.

app.post('/webhooks/walletgate', (req, res) => {
  const signature = req.headers['wg-signature'];
  const timestamp = req.headers['wg-timestamp'];

  // Verify webhook authenticity
  const isValid = eudi.verifyWebhook(
    req.rawBody,
    signature,
    process.env.WEBHOOK_SECRET,
    timestamp
  );

  if (!isValid) return res.status(400).send('Invalid signature');

  const event = JSON.parse(req.rawBody);

  switch(event.type) {
    case 'verification.completed':
      // Handle successful verification
      break;
    case 'verification.failed':
      // Handle failed verification
      break;
  }

  res.sendStatus(200);
});

API Reference

new WalletGate(config)

  • apiKey - Your WalletGate API key
  • baseUrl - API endpoint (optional)
  • timeout - Request timeout in ms (optional)
  • retries - Retry configuration object (optional)
  • onRateLimit - Callback for rate limit events (optional)

startVerification(input)

  • checks - Array of verification requirements
  • redirectUrl - Post-verification redirect (optional)
  • metadata - Custom metadata object (optional)
  • Returns: VerificationSession

getResult(sessionId)

  • sessionId - From startVerification
  • Returns: VerificationResult

verifyWebhook(rawBody, signature, secret, timestamp)

Verify webhook signatures (Node.js only)

  • Returns: boolean

makeQrDataUrl(url)

Generate QR code for cross-device flow

  • Returns: Promise<string> (data URL)

Framework Examples

Next.js

// pages/api/verify.ts
export default async function handler(req, res) {
  const eudi = new WalletGate({ apiKey: process.env.WALLETGATE_API_KEY });

  if (req.method === 'POST') {
    const session = await eudi.startVerification({
      checks: [{ type: 'age_over', value: 18 }]
    });
    res.json(session);
  }
}

// components/AgeGate.tsx
export function AgeGate() {
  const verifyAge = async () => {
    const res = await fetch('/api/verify', { method: 'POST' });
    const { verificationUrl } = await res.json();
    window.location.href = verificationUrl;
  };

  return <button onClick={verifyAge}>Verify Age with EUDI Wallet</button>;
}

Express.js

import express from 'express';
import { WalletGate } from '@walletgate/eudi';

const app = express();
const eudi = new WalletGate({ apiKey: process.env.WALLETGATE_API_KEY });

app.post('/verify/start', async (req, res) => {
  const session = await eudi.startVerification({
    checks: req.body.checks,
    redirectUrl: `${req.protocol}://${req.get('host')}/verify/complete`
  });

  res.json({
    sessionId: session.id,
    walletUrl: session.verificationUrl
  });
});

app.get('/verify/:sessionId', async (req, res) => {
  const result = await eudi.getResult(req.params.sessionId);
  res.json(result);
});

TypeScript Types

interface WalletGateConfig {
  apiKey: string;
  baseUrl?: string;
  timeout?: number;
  retries?: {
    maxRetries?: number;
    baseDelayMs?: number;
    factor?: number;
    jitter?: boolean;
  };
  onRateLimit?: (info: RateLimitInfo) => void;
}

interface VerificationSession {
  id: string;
  verificationUrl: string;
  status: 'pending';
  environment: 'test' | 'live';
  testMode?: boolean;
  warning?: string;
  createdAt: string;
}

interface VerificationResult {
  id: string;
  status: 'pending' | 'verified' | 'failed' | 'expired';
  environment: 'test' | 'live';
  testMode?: boolean;
  warning?: string;
  checks: Record<string, boolean>;
  reason?: string;
  completedAt?: string;
}

Links & Resources