@eudiplo/sdk-core 1.14.0-main.e94b102 → 1.14.0-main.eaeec84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -168
- package/dist/api/client/client.gen.d.mts +1 -1
- package/dist/api/client/client.gen.d.ts +1 -1
- package/dist/api/client/client.gen.js +106 -148
- package/dist/api/client/client.gen.mjs +106 -148
- package/dist/api/client/index.d.mts +4 -4
- package/dist/api/client/index.d.ts +4 -4
- package/dist/api/client/index.js +113 -159
- package/dist/api/client/index.mjs +113 -159
- package/dist/api/client/types.gen.d.mts +1 -1
- package/dist/api/client/types.gen.d.ts +1 -1
- package/dist/api/client.gen.d.mts +2 -2
- package/dist/api/client.gen.d.ts +2 -2
- package/dist/api/client.gen.js +107 -151
- package/dist/api/client.gen.mjs +107 -151
- package/dist/api/index.d.mts +210 -206
- package/dist/api/index.d.ts +210 -206
- package/dist/api/index.js +478 -374
- package/dist/api/index.mjs +432 -334
- package/dist/index.d.mts +133 -295
- package/dist/index.d.ts +133 -295
- package/dist/index.js +875 -553
- package/dist/index.mjs +823 -504
- package/dist/{types.gen-DDunhhsd.d.mts → types.gen-Cc6DtXw9.d.mts} +38 -31
- package/dist/{types.gen-DDunhhsd.d.ts → types.gen-Cc6DtXw9.d.ts} +38 -31
- package/dist/types.gen-z3We9JHj.d.mts +4555 -0
- package/dist/types.gen-z3We9JHj.d.ts +4555 -0
- package/package.json +10 -8
- package/dist/types.gen-D7mQfhiG.d.mts +0 -3051
- package/dist/types.gen-D7mQfhiG.d.ts +0 -3051
package/README.md
CHANGED
|
@@ -12,225 +12,102 @@ pnpm add @eudiplo/sdk-core
|
|
|
12
12
|
yarn add @eudiplo/sdk-core
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
## Quick Start
|
|
16
|
-
|
|
17
|
-
### One-liner for Age Verification
|
|
15
|
+
## Quick Start
|
|
18
16
|
|
|
19
17
|
```typescript
|
|
20
|
-
import {
|
|
18
|
+
import { EudiploClient } from '@eudiplo/sdk-core';
|
|
21
19
|
|
|
22
|
-
const
|
|
20
|
+
const client = new EudiploClient({
|
|
23
21
|
baseUrl: 'https://eudiplo.example.com',
|
|
24
22
|
clientId: 'my-demo',
|
|
25
23
|
clientSecret: 'secret',
|
|
26
|
-
configId: 'age-over-18',
|
|
27
|
-
onUri: (uri) => showQRCode(uri), // Your QR code display function
|
|
28
|
-
onUpdate: (s) => console.log('Status:', s.status),
|
|
29
24
|
});
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
### Two-step Flow (More Control)
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
import { verify } from '@eudiplo/sdk-core';
|
|
38
|
-
|
|
39
|
-
// Step 1: Create the request
|
|
40
|
-
const { uri, sessionId, waitForCompletion } = await verify({
|
|
41
|
-
baseUrl: 'https://eudiplo.example.com',
|
|
42
|
-
clientId: 'my-demo',
|
|
43
|
-
clientSecret: 'secret',
|
|
26
|
+
// Verification (QR flow)
|
|
27
|
+
const verifyOffer = await client.createPresentationRequest({
|
|
44
28
|
configId: 'age-over-18',
|
|
45
29
|
});
|
|
30
|
+
showQRCode(verifyOffer.uri);
|
|
31
|
+
const verifiedSession = await client.waitForSession(verifyOffer.sessionId);
|
|
46
32
|
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// Step 3: Wait for user to scan and respond
|
|
51
|
-
const session = await waitForCompletion();
|
|
52
|
-
console.log('Verified credentials:', session.credentials);
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Credential Issuance
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
import { issue } from '@eudiplo/sdk-core';
|
|
59
|
-
|
|
60
|
-
const { uri, waitForCompletion } = await issue({
|
|
61
|
-
baseUrl: 'https://eudiplo.example.com',
|
|
62
|
-
clientId: 'my-demo',
|
|
63
|
-
clientSecret: 'secret',
|
|
33
|
+
// Issuance (QR flow)
|
|
34
|
+
const issuanceOffer = await client.createIssuanceOffer({
|
|
64
35
|
credentialConfigurationIds: ['PID'],
|
|
65
36
|
claims: {
|
|
66
37
|
PID: { given_name: 'John', family_name: 'Doe', birthdate: '1990-01-15' },
|
|
67
38
|
},
|
|
68
39
|
});
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
await waitForCompletion();
|
|
40
|
+
showQRCode(issuanceOffer.uri);
|
|
41
|
+
await client.waitForSession(issuanceOffer.sessionId);
|
|
72
42
|
```
|
|
73
43
|
|
|
74
44
|
## Full API
|
|
75
45
|
|
|
76
|
-
###
|
|
46
|
+
### Class API
|
|
47
|
+
|
|
48
|
+
Use `EudiploClient` methods directly:
|
|
77
49
|
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
50
|
+
| Method | Description |
|
|
51
|
+
| ----------------------------- | ---------------------------------------------- |
|
|
52
|
+
| `createPresentationRequest()` | Create verification request URI and session ID |
|
|
53
|
+
| `createIssuanceOffer()` | Create issuance offer URI and session ID |
|
|
54
|
+
| `waitForSession()` | Poll session until terminal state |
|
|
55
|
+
| `subscribeToSession()` | Subscribe via SSE |
|
|
56
|
+
| `verifyWithDcApi()` | Browser-native DC API end-to-end flow |
|
|
84
57
|
|
|
85
58
|
### Digital Credentials API (Browser Native)
|
|
86
59
|
|
|
87
60
|
The SDK includes utilities for the [Digital Credentials API](https://wicg.github.io/digital-credentials/), enabling browser-native credential presentation without QR codes.
|
|
88
61
|
|
|
89
62
|
```typescript
|
|
90
|
-
import { isDcApiAvailable,
|
|
63
|
+
import { isDcApiAvailable, EudiploClient } from '@eudiplo/sdk-core';
|
|
64
|
+
|
|
65
|
+
const client = new EudiploClient({
|
|
66
|
+
baseUrl: 'https://eudiplo.example.com',
|
|
67
|
+
clientId: 'my-demo',
|
|
68
|
+
clientSecret: 'secret',
|
|
69
|
+
});
|
|
91
70
|
|
|
92
71
|
// Check if browser supports DC API
|
|
93
72
|
if (isDcApiAvailable()) {
|
|
94
|
-
const result = await verifyWithDcApi({
|
|
95
|
-
baseUrl: 'https://eudiplo.example.com',
|
|
96
|
-
clientId: 'my-demo',
|
|
97
|
-
clientSecret: 'secret',
|
|
73
|
+
const result = await client.verifyWithDcApi({
|
|
98
74
|
configId: 'age-over-18',
|
|
99
75
|
});
|
|
100
76
|
|
|
101
|
-
console.log('Verified!', result.
|
|
77
|
+
console.log('Verified!', result.credentials);
|
|
102
78
|
} else {
|
|
103
|
-
// Fall back to QR code flow
|
|
104
|
-
const session = await verifyAndWait({...});
|
|
79
|
+
// Fall back to QR code flow using EudiploClient methods
|
|
105
80
|
}
|
|
106
81
|
```
|
|
107
82
|
|
|
108
|
-
#### DC API
|
|
83
|
+
#### DC API Methods
|
|
109
84
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
| `isDcApiAvailable()`
|
|
113
|
-
| `verifyWithDcApi()`
|
|
114
|
-
| `
|
|
85
|
+
| Method | Description |
|
|
86
|
+
| -------------------------------------------- | --------------------------------------------------- |
|
|
87
|
+
| `isDcApiAvailable()` | Check if browser supports Digital Credentials API |
|
|
88
|
+
| `client.verifyWithDcApi()` | Complete verification flow using browser-native API |
|
|
89
|
+
| `client.createDcApiPresentationRequest(...)` | Create DC API session with request object |
|
|
115
90
|
|
|
116
91
|
#### Lower-level DC API Usage
|
|
117
92
|
|
|
118
93
|
```typescript
|
|
119
|
-
import {
|
|
94
|
+
import { EudiploClient } from '@eudiplo/sdk-core';
|
|
120
95
|
|
|
121
96
|
const client = new EudiploClient({...});
|
|
122
97
|
|
|
123
|
-
// Create
|
|
124
|
-
const
|
|
98
|
+
// Create DC API session with request object
|
|
99
|
+
const session = await client.createDcApiPresentationRequest({
|
|
125
100
|
configId: 'age-over-18',
|
|
126
|
-
responseType: 'dc-api',
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// Create the browser request object
|
|
130
|
-
const request = createDcApiRequest(uri);
|
|
131
|
-
|
|
132
|
-
// Call the browser API directly
|
|
133
|
-
const credential = await navigator.credentials.get(request);
|
|
134
|
-
|
|
135
|
-
// Submit the response and get verified session
|
|
136
|
-
const session = await client.submitDcApiResponse(sessionId, credential);
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
#### Secure Server/Client Deployment (Recommended for Production)
|
|
140
|
-
|
|
141
|
-
When deploying to production, you should **never expose your client credentials to the browser**. The SDK provides helper functions to split the DC API flow between your server (where credentials are safe) and the browser (where the DC API runs).
|
|
142
|
-
|
|
143
|
-
**Server-side Functions:**
|
|
144
|
-
| Function | Description |
|
|
145
|
-
| ---------------------- | --------------------------------------------------- |
|
|
146
|
-
| `createDcApiRequestForBrowser()` | Create request on server, return safe data for browser |
|
|
147
|
-
| `submitDcApiWalletResponse()` | Submit wallet response to EUDIPLO from server |
|
|
148
|
-
|
|
149
|
-
**Browser-side Functions:**
|
|
150
|
-
| Function | Description |
|
|
151
|
-
| ---------------------- | --------------------------------------------------- |
|
|
152
|
-
| `callDcApi()` | Call the native DC API with a request from your server |
|
|
153
|
-
|
|
154
|
-
##### Example: Express.js Backend + Browser Frontend
|
|
155
|
-
|
|
156
|
-
**Server (Express.js / Next.js API route):**
|
|
157
|
-
|
|
158
|
-
```typescript
|
|
159
|
-
import {
|
|
160
|
-
createDcApiRequestForBrowser,
|
|
161
|
-
submitDcApiWalletResponse,
|
|
162
|
-
} from '@eudiplo/sdk-core';
|
|
163
|
-
|
|
164
|
-
// POST /api/start-verification
|
|
165
|
-
app.post('/api/start-verification', async (req, res) => {
|
|
166
|
-
const requestData = await createDcApiRequestForBrowser({
|
|
167
|
-
baseUrl: process.env.EUDIPLO_URL,
|
|
168
|
-
clientId: process.env.EUDIPLO_CLIENT_ID, // ✅ Safe on server
|
|
169
|
-
clientSecret: process.env.EUDIPLO_SECRET, // ✅ Safe on server
|
|
170
|
-
configId: 'age-over-18',
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
// Only safe data is sent to browser (no secrets)
|
|
174
|
-
res.json(requestData);
|
|
175
101
|
});
|
|
176
102
|
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
const { responseUri, walletResponse } = req.body;
|
|
180
|
-
|
|
181
|
-
const result = await submitDcApiWalletResponse({
|
|
182
|
-
responseUri,
|
|
183
|
-
walletResponse,
|
|
184
|
-
sendResponse: true, // Get verified claims back
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
// result.credentials contains the verified data
|
|
188
|
-
res.json(result);
|
|
189
|
-
});
|
|
103
|
+
// Submit using the browser-native DC API end-to-end
|
|
104
|
+
const result = await client.submitDcApiPresentation(session);
|
|
190
105
|
```
|
|
191
106
|
|
|
192
|
-
|
|
107
|
+
#### Secure Deployment Note
|
|
193
108
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
async function verifyAge() {
|
|
198
|
-
// 1. Get the request from your server (credentials stay on server)
|
|
199
|
-
const requestData = await fetch('/api/start-verification', {
|
|
200
|
-
method: 'POST',
|
|
201
|
-
}).then((r) => r.json());
|
|
202
|
-
|
|
203
|
-
// 2. Check DC API support and call it locally
|
|
204
|
-
if (!isDcApiAvailable()) {
|
|
205
|
-
throw new Error('Digital Credentials API not supported');
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const walletResponse = await callDcApi(requestData.requestObject);
|
|
209
|
-
|
|
210
|
-
// 3. Send the wallet response back to your server for verification
|
|
211
|
-
const result = await fetch('/api/complete-verification', {
|
|
212
|
-
method: 'POST',
|
|
213
|
-
headers: { 'Content-Type': 'application/json' },
|
|
214
|
-
body: JSON.stringify({
|
|
215
|
-
responseUri: requestData.responseUri,
|
|
216
|
-
walletResponse,
|
|
217
|
-
}),
|
|
218
|
-
}).then((r) => r.json());
|
|
219
|
-
|
|
220
|
-
console.log('Verified!', result.credentials);
|
|
221
|
-
return result;
|
|
222
|
-
}
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
**What stays where:**
|
|
226
|
-
|
|
227
|
-
| Data | Location | Safe to expose? |
|
|
228
|
-
|------|----------|-----------------|
|
|
229
|
-
| `clientId` / `clientSecret` | Server only | ❌ Never expose |
|
|
230
|
-
| `requestObject` (signed JWT) | Server → Browser | ✅ Yes |
|
|
231
|
-
| `responseUri` | Server → Browser | ✅ Yes |
|
|
232
|
-
| Wallet response (encrypted VP) | Browser → Server | ✅ Yes |
|
|
233
|
-
| Verified credentials | Server only | Depends on use case |
|
|
109
|
+
For production deployments, keep `clientId` and `clientSecret` on the server.
|
|
110
|
+
Use `EudiploClient` methods to run the full flow (`createDcApiPresentationRequest` + `submitDcApiPresentation`) from trusted backend/application code.
|
|
234
111
|
|
|
235
112
|
### Class-based API (More Control)
|
|
236
113
|
|
|
@@ -325,6 +202,43 @@ const session = await client.waitForSession(sessionId, {
|
|
|
325
202
|
});
|
|
326
203
|
```
|
|
327
204
|
|
|
205
|
+
### `subscribeToSession(sessionId, options)`
|
|
206
|
+
|
|
207
|
+
Subscribe to real-time session status updates via Server-Sent Events (SSE).
|
|
208
|
+
This is more efficient than polling and provides instant updates.
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const subscription = await client.subscribeToSession(sessionId, {
|
|
212
|
+
onStatusChange: (event) => {
|
|
213
|
+
console.log(`Status: ${event.status}`);
|
|
214
|
+
if (['completed', 'expired', 'failed'].includes(event.status)) {
|
|
215
|
+
subscription.close();
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
onError: (error) => console.error('SSE error:', error),
|
|
219
|
+
onOpen: () => console.log('Connected'),
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Later, to close the connection:
|
|
223
|
+
subscription.close();
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### `waitForSessionWithSse(sessionId, options)`
|
|
227
|
+
|
|
228
|
+
Wait for session completion using SSE instead of polling. Returns a Promise
|
|
229
|
+
that resolves when the session completes.
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
try {
|
|
233
|
+
const finalStatus = await client.waitForSessionWithSse(sessionId, {
|
|
234
|
+
onStatusChange: (event) => console.log('Status:', event.status),
|
|
235
|
+
});
|
|
236
|
+
console.log('Session completed:', finalStatus);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.error('Session failed:', error);
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
328
242
|
## Examples
|
|
329
243
|
|
|
330
244
|
### Age Verification in a Web Shop
|