@reclaimprotocol/client 0.1.0-dev.1 → 0.1.0-dev.2

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/lib/result.js ADDED
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Consumer-side handling of a delivered callback. Two entry points:
3
+ * - {@link verifyResult}: the offline primitive — decrypt + decode + optional
4
+ * ES256K signature check (caller-supplied key) + `reclaimSessionId` nonce.
5
+ * - {@link verifyResultFull}: the full async verification — discovers the
6
+ * Verification Client's key via JWKS, verifies the top-level JWS, checks
7
+ * `reclaimSessionId`/`aud`/`exp`, and verifies each result's nested attestor
8
+ * proof + `content_hash` (see ./attestor-proof.ts and ./jwks.ts).
9
+ *
10
+ * See docs/verification-session.md → "Verification by Consumer".
11
+ */
12
+ import { sha256 } from '@noble/hashes/sha2.js';
13
+ import { keccak_256 } from '@noble/hashes/sha3.js';
14
+ import { compactDecrypt, CompactEncrypt, importJWK } from 'jose';
15
+ import { verifyNestedProof } from "./attestor-proof.js";
16
+ import { canonicalJson } from "./canonical.js";
17
+ import { b64url, base64urlToBytes, bytesToHex, hexToBytes } from "./encoding.js";
18
+ import { fetchJwks, jwkToUncompressedPublicKey, selectKey } from "./jwks.js";
19
+ import { addressFromUncompressedPubkey, secp } from "./secp.js";
20
+ /**
21
+ * JWE-encrypt `plaintext` for the holder of `publicJwk` (an X25519 public JWK,
22
+ * `{kty:'OKP', crv:'X25519', x}`) as a compact JWE (`ECDH-ES + A256GCM`). Used
23
+ * by the first-party Verification Client to encrypt the signed JWS for each
24
+ * Consumer before submitting it to the Builder (which only relays the
25
+ * ciphertext). Consumers never call this — they only {@link decryptCallback}.
26
+ *
27
+ * `plaintext` is bytes (e.g. `new TextEncoder().encode(JSON.stringify(jws))`);
28
+ * returns the compact JWE string.
29
+ */
30
+ export async function encryptForPublicJwk(publicJwk, plaintext) {
31
+ const key = await importJWK(publicJwk, 'ECDH-ES');
32
+ return new CompactEncrypt(plaintext)
33
+ .setProtectedHeader({ alg: 'ECDH-ES', enc: 'A256GCM' })
34
+ .encrypt(key);
35
+ }
36
+ /** Normalize any {@link CallbackBody} to the terminal-result `data` string —
37
+ * either a compact JWE (`xxxx.yyyy.zzzz.aaaa.bbbb`) or the plaintext JWS JSON
38
+ * (`{…}`). The envelope object/text wraps it in `.data`; raw bytes are decoded
39
+ * to text first. */
40
+ function payloadFrom(body) {
41
+ if (typeof body === 'string') {
42
+ const s = body.trim();
43
+ // A JSON envelope/JWS starts with '{'; anything else is the bare `data`
44
+ // (compact JWE). An envelope's `data` is extracted; a bare JWS is returned.
45
+ if (s.startsWith('{')) {
46
+ const parsed = JSON.parse(s);
47
+ if (typeof parsed.data === 'string') {
48
+ return parsed.data;
49
+ }
50
+ return s;
51
+ }
52
+ return s;
53
+ }
54
+ if (body instanceof ArrayBuffer) {
55
+ return payloadFrom(new TextDecoder().decode(new Uint8Array(body)));
56
+ }
57
+ if (body instanceof Uint8Array) {
58
+ return payloadFrom(new TextDecoder().decode(body));
59
+ }
60
+ return body.data;
61
+ }
62
+ /**
63
+ * Decrypt a delivered terminal callback to the signed JWS. `data` is either a
64
+ * compact JWE (decrypted with the X25519 `privateKey`) or — when the org has no
65
+ * encryption credential — the plaintext JWS JSON. A compact JWE has exactly
66
+ * five dot-separated base64url segments; a JSON JWS starts with `{`.
67
+ *
68
+ * `privateKey` may be absent (plaintext delivery); an encrypted delivery with
69
+ * no key throws a clear error.
70
+ */
71
+ export async function decryptCallback(privateKey, body) {
72
+ const data = payloadFrom(body);
73
+ const trimmed = data.trim();
74
+ // Plaintext delivery: `data` is the JWS JSON directly.
75
+ if (trimmed.startsWith('{')) {
76
+ return JSON.parse(trimmed);
77
+ }
78
+ // Otherwise it's a compact JWE — five base64url segments.
79
+ if (!privateKey) {
80
+ throw new Error('received an encrypted (JWE) delivery but no decryption credential was '
81
+ + 'configured — pass the X25519 private key (JWK/PEM): '
82
+ + 'results.receive(body, { credential }) or decrypt(body, credential)');
83
+ }
84
+ const { plaintext } = await compactDecrypt(trimmed, privateKey);
85
+ return JSON.parse(new TextDecoder().decode(plaintext));
86
+ }
87
+ /**
88
+ * Sign a verification result as a flattened JWS (JOSE ES256K = ECDSA/secp256k1
89
+ * over SHA-256 of the `<protected>.<payload>` signing input — a single hash).
90
+ * `kid` is the signer's ETH address (published via JWKS); `iss` is the issuer
91
+ * URL. Used by the Verification Client to sign results before encrypting them.
92
+ */
93
+ export function signResultJws(privateKeyHex, payload, iss) {
94
+ const priv = hexToBytes(privateKeyHex);
95
+ const protectedHeader = b64url(JSON.stringify({
96
+ alg: 'ES256K',
97
+ kid: addressFromUncompressedPubkey(secp.getPublicKey(priv, false)),
98
+ typ: 'JWS',
99
+ iss,
100
+ }));
101
+ const payloadB64 = b64url(JSON.stringify(payload));
102
+ const signingInput = new TextEncoder().encode(`${protectedHeader}.${payloadB64}`);
103
+ // Standard ES256K: a single SHA-256 of the signing input. `prehash:false`
104
+ // stops @noble hashing the digest again, so any JOSE tool can verify it.
105
+ const sig = secp.sign(sha256(signingInput), priv, { prehash: false });
106
+ return {
107
+ payload: payloadB64,
108
+ signatures: [{ protected: protectedHeader, signature: b64url(sig) }],
109
+ };
110
+ }
111
+ /** Decode the JWS payload (base64url JSON). */
112
+ export function decodeJwsPayload(jws) {
113
+ return JSON.parse(new TextDecoder().decode(base64urlToBytes(jws.payload)));
114
+ }
115
+ /**
116
+ * Verify a JWS signature (JOSE ES256K = ECDSA/secp256k1 over SHA-256 of the
117
+ * `<protected>.<payload>` signing input) with an uncompressed public key.
118
+ */
119
+ export function verifyJwsSignature(jws, signerPublicKey) {
120
+ const pub = hexToBytes(signerPublicKey);
121
+ return jws.signatures.some((s) => {
122
+ try {
123
+ const signingInput = new TextEncoder().encode(`${s.protected}.${jws.payload}`);
124
+ const digest = sha256(signingInput);
125
+ const sig = base64urlToBytes(s.signature);
126
+ // digest is the single SHA-256 of the signing input — don't let
127
+ // @noble hash it again (standard ES256K).
128
+ return secp.verify(sig, digest, pub, { prehash: false });
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ });
134
+ }
135
+ /** Content hash binding extracted parameters — MUST mirror the Verification
136
+ * Client's `contentHash` exactly (keccak256 of the RFC 8785 canonical JSON,
137
+ * via the shared `canonicalJson`). */
138
+ function contentHash(params) {
139
+ const canonical = canonicalJson(params);
140
+ return '0x' + bytesToHex(keccak_256(new TextEncoder().encode(canonical)));
141
+ }
142
+ /**
143
+ * Thrown by {@link verifyResult} / {@link verifyResultFull} (and therefore
144
+ * `reclaim.results.verify`/`receive`) when a result fails verification. Carries
145
+ * the full invalid outcome so callers can inspect it in a `catch`:
146
+ *
147
+ * try {
148
+ * const { result } = await reclaim.results.receive(body, { credential })
149
+ * // result is verified — use result.payload
150
+ * } catch (err) {
151
+ * if (err instanceof ResultVerificationError) {
152
+ * // e.g. 'expired', { payload, … }
153
+ * console.error(err.reason, err.outcome)
154
+ * }
155
+ * }
156
+ */
157
+ export class ResultVerificationError extends Error {
158
+ /** Machine-readable failure reason — `'bad-signature'`, `'expired'`,
159
+ * `'reclaimSessionId-mismatch'`, `'aud-mismatch'`, `'invalid-proof'`, … */
160
+ reason;
161
+ /** The full (invalid) outcome: `payload`, `reclaimSessionId`, and per-proof
162
+ * detail (`proofs`) when verification got that far. */
163
+ outcome;
164
+ constructor(outcome) {
165
+ super(`result verification failed: ${outcome.reason ?? 'invalid'}`);
166
+ this.name = 'ResultVerificationError';
167
+ this.reason = outcome.reason ?? 'invalid';
168
+ this.outcome = outcome;
169
+ }
170
+ }
171
+ /**
172
+ * Full consumer verification: discovers the Verification Client's signing key
173
+ * via JWKS (header `iss`/`kid`), verifies the top-level JWS, checks
174
+ * `reclaimSessionId`/`aud`/`exp`, then verifies each result's nested attestor
175
+ * proof and its `content_hash`. Network access (JWKS) makes this async; use
176
+ * {@link verifyResult} for the offline primitive.
177
+ */
178
+ export async function verifyResultFull(jws, opts = {}) {
179
+ const payload = decodeJwsPayload(jws);
180
+ const reclaimSessionId = payload.reclaimSessionId;
181
+ /** Throw with the full invalid outcome — verification never *returns* an
182
+ * invalid result. */
183
+ const fail = (reason, extra = {}) => {
184
+ throw new ResultVerificationError({
185
+ valid: false,
186
+ reason,
187
+ payload,
188
+ reclaimSessionId,
189
+ ...extra,
190
+ });
191
+ };
192
+ // 1. Resolve the VC signer key: explicit override, else JWKS via header iss.
193
+ let signerPublicKey = opts.signerPublicKey;
194
+ let header = {};
195
+ const sig0 = jws.signatures[0];
196
+ if (sig0) {
197
+ try {
198
+ header = JSON.parse(new TextDecoder().decode(base64urlToBytes(sig0.protected)));
199
+ }
200
+ catch {
201
+ return fail('bad-header');
202
+ }
203
+ }
204
+ if (!signerPublicKey) {
205
+ const iss = String(header.iss ?? '');
206
+ if (!iss) {
207
+ return fail('no-issuer');
208
+ }
209
+ const keys = await fetchJwks(iss, opts.fetchImpl);
210
+ const jwk = selectKey(keys, String(header.kid ?? ''));
211
+ if (!jwk) {
212
+ return fail('signer-key-not-found');
213
+ }
214
+ signerPublicKey = jwkToUncompressedPublicKey(jwk);
215
+ }
216
+ if (!verifyJwsSignature(jws, signerPublicKey)) {
217
+ return fail('bad-signature');
218
+ }
219
+ // 2. Freshness / audience / expiry.
220
+ if (opts.expectedReclaimSessionId &&
221
+ reclaimSessionId !== opts.expectedReclaimSessionId) {
222
+ return fail('reclaimSessionId-mismatch');
223
+ }
224
+ if (opts.expectedAud && payload.aud !== opts.expectedAud) {
225
+ return fail('aud-mismatch');
226
+ }
227
+ const now = opts.now ?? Math.floor(Date.now() / 1000);
228
+ if (typeof payload.exp === 'number' && payload.exp < now) {
229
+ return fail('expired');
230
+ }
231
+ // 3. Per-result nested attestor proof + content_hash binding.
232
+ const results = Array.isArray(payload.results)
233
+ ? payload.results
234
+ : [];
235
+ const proofs = [];
236
+ for (const r of results) {
237
+ const requestId = typeof r.request_id === 'string' ? r.request_id : undefined;
238
+ if (typeof r.proof !== 'string') {
239
+ proofs.push({ requestId, proofValid: false, reason: 'proof-missing' });
240
+ continue;
241
+ }
242
+ const np = verifyNestedProof(r.proof, {
243
+ attestorAddresses: opts.attestorAddresses,
244
+ });
245
+ if (!np.valid) {
246
+ proofs.push({
247
+ requestId,
248
+ proofValid: false,
249
+ reason: np.reason,
250
+ attestorAddress: np.attestorAddress,
251
+ });
252
+ continue;
253
+ }
254
+ if (typeof r.content_hash === 'string' &&
255
+ r.extracted_parameters &&
256
+ typeof r.extracted_parameters === 'object') {
257
+ const params = r.extracted_parameters;
258
+ if (contentHash(params).toLowerCase() !== r.content_hash.toLowerCase()) {
259
+ proofs.push({
260
+ requestId,
261
+ proofValid: false,
262
+ reason: 'content-hash-mismatch',
263
+ attestorAddress: np.attestorAddress,
264
+ });
265
+ continue;
266
+ }
267
+ }
268
+ proofs.push({
269
+ requestId,
270
+ proofValid: true,
271
+ attestorAddress: np.attestorAddress,
272
+ });
273
+ }
274
+ if (!proofs.every((p) => p.proofValid)) {
275
+ return fail('invalid-proof', { proofs });
276
+ }
277
+ return { valid: true, payload, reclaimSessionId, proofs };
278
+ }
279
+ /** Decrypt-and-verify in one step. */
280
+ export function verifyResult(jws, opts = {}) {
281
+ const payload = decodeJwsPayload(jws);
282
+ const reclaimSessionId = payload.reclaimSessionId;
283
+ if (opts.signerPublicKey && !verifyJwsSignature(jws, opts.signerPublicKey)) {
284
+ throw new ResultVerificationError({
285
+ valid: false, reason: 'bad-signature', payload, reclaimSessionId,
286
+ });
287
+ }
288
+ if (opts.expectedReclaimSessionId &&
289
+ reclaimSessionId !== opts.expectedReclaimSessionId) {
290
+ throw new ResultVerificationError({
291
+ valid: false,
292
+ reason: 'reclaimSessionId-mismatch',
293
+ payload,
294
+ reclaimSessionId,
295
+ });
296
+ }
297
+ return { valid: true, payload, reclaimSessionId };
298
+ }
@@ -3,6 +3,10 @@ export declare const ROUTES: {
3
3
  readonly method: "post";
4
4
  readonly path: "/orgs/{orgId}/members";
5
5
  };
6
+ readonly AdminCallbackDlq: {
7
+ readonly method: "get";
8
+ readonly path: "/admin/callback-dlq";
9
+ };
6
10
  readonly AdminHome: {
7
11
  readonly method: "get";
8
12
  readonly path: "/admin";
@@ -19,6 +23,10 @@ export declare const ROUTES: {
19
23
  readonly method: "get";
20
24
  readonly path: "/admin/reviews";
21
25
  };
26
+ readonly AdminSessions: {
27
+ readonly method: "get";
28
+ readonly path: "/admin/sessions";
29
+ };
22
30
  readonly AdminThemes: {
23
31
  readonly method: "get";
24
32
  readonly path: "/admin/themes";
@@ -47,10 +55,18 @@ export declare const ROUTES: {
47
55
  readonly method: "post";
48
56
  readonly path: "/credentials/attach/sessions";
49
57
  };
58
+ readonly CreateCallbackSubscription: {
59
+ readonly method: "post";
60
+ readonly path: "/verifications/callback-subscriptions";
61
+ };
50
62
  readonly CreateOrg: {
51
63
  readonly method: "post";
52
64
  readonly path: "/orgs";
53
65
  };
66
+ readonly CreateOrgCallbackSubscription: {
67
+ readonly method: "post";
68
+ readonly path: "/orgs/{orgId}/callback-subscriptions";
69
+ };
54
70
  readonly CreateProvider: {
55
71
  readonly method: "post";
56
72
  readonly path: "/providers";
@@ -63,18 +79,18 @@ export declare const ROUTES: {
63
79
  readonly method: "post";
64
80
  readonly path: "/orgs/{orgId}/themes";
65
81
  };
66
- readonly CredentialAuthChallenge: {
82
+ readonly CreateVerificationSession: {
67
83
  readonly method: "post";
68
- readonly path: "/credentials/auth/challenge";
69
- };
70
- readonly CredentialAuthVerify: {
71
- readonly method: "post";
72
- readonly path: "/credentials/auth/verify";
84
+ readonly path: "/verifications/sessions";
73
85
  };
74
86
  readonly DecideProviderVersionReview: {
75
87
  readonly method: "post";
76
88
  readonly path: "/providers/{providerId}/versions/{version}/review-decision";
77
89
  };
90
+ readonly DeleteCallbackSubscription: {
91
+ readonly method: "delete";
92
+ readonly path: "/verifications/callback-subscriptions/{subscriptionId}";
93
+ };
78
94
  readonly DeleteOrg: {
79
95
  readonly method: "delete";
80
96
  readonly path: "/orgs/{orgId}";
@@ -83,6 +99,14 @@ export declare const ROUTES: {
83
99
  readonly method: "delete";
84
100
  readonly path: "/orgs/{orgId}/billing";
85
101
  };
102
+ readonly DeleteOrgCallbackSubscription: {
103
+ readonly method: "delete";
104
+ readonly path: "/orgs/{orgId}/callback-subscriptions/{subscriptionId}";
105
+ };
106
+ readonly DeleteOrgCredential: {
107
+ readonly method: "delete";
108
+ readonly path: "/orgs/{orgId}/credential";
109
+ };
86
110
  readonly DeleteOrgIcon: {
87
111
  readonly method: "delete";
88
112
  readonly path: "/orgs/{orgId}/icon";
@@ -111,14 +135,6 @@ export declare const ROUTES: {
111
135
  readonly method: "get";
112
136
  readonly path: "/credentials/attach/sessions/{code}";
113
137
  };
114
- readonly GetCredential: {
115
- readonly method: "get";
116
- readonly path: "/credentials/{credentialId}";
117
- };
118
- readonly GetCredentialByAddress: {
119
- readonly method: "get";
120
- readonly path: "/credentials/by-address/{address}";
121
- };
122
138
  readonly GetImage: {
123
139
  readonly method: "get";
124
140
  readonly path: "/images/{imageId}";
@@ -135,6 +151,18 @@ export declare const ROUTES: {
135
151
  readonly method: "get";
136
152
  readonly path: "/orgs/{orgId}/billing";
137
153
  };
154
+ readonly GetOrgCredential: {
155
+ readonly method: "get";
156
+ readonly path: "/orgs/{orgId}/credential";
157
+ };
158
+ readonly GetOrgSession: {
159
+ readonly method: "get";
160
+ readonly path: "/orgs/{orgId}/sessions/{sessionId}";
161
+ };
162
+ readonly GetOrgToken: {
163
+ readonly method: "get";
164
+ readonly path: "/orgs/{orgId}/token";
165
+ };
138
166
  readonly GetProvider: {
139
167
  readonly method: "get";
140
168
  readonly path: "/providers/{providerId}";
@@ -155,30 +183,70 @@ export declare const ROUTES: {
155
183
  readonly method: "get";
156
184
  readonly path: "/users/{userId}";
157
185
  };
186
+ readonly GetVerificationRecipe: {
187
+ readonly method: "get";
188
+ readonly path: "/verifications/sessions/{sessionId}/recipe";
189
+ };
190
+ readonly GetVerificationResult: {
191
+ readonly method: "get";
192
+ readonly path: "/verifications/sessions/{sessionId}/result";
193
+ };
194
+ readonly GetVerificationSession: {
195
+ readonly method: "get";
196
+ readonly path: "/verifications/sessions/{sessionId}";
197
+ };
158
198
  readonly Index: {
159
199
  readonly method: "get";
160
200
  readonly path: "/";
161
201
  };
162
- readonly LinkCredential: {
202
+ readonly IssueOrgToken: {
163
203
  readonly method: "post";
164
- readonly path: "/credentials";
204
+ readonly path: "/orgs/{orgId}/token";
165
205
  };
166
- readonly ListOrgCredentials: {
206
+ readonly JwksJson: {
167
207
  readonly method: "get";
168
- readonly path: "/orgs/{orgId}/credentials";
208
+ readonly path: "/.well-known/jwks.json";
209
+ };
210
+ readonly ListCallbackDlq: {
211
+ readonly method: "get";
212
+ readonly path: "/verifications/callback-dlq";
213
+ };
214
+ readonly ListCallbackSubscriptions: {
215
+ readonly method: "get";
216
+ readonly path: "/verifications/callback-subscriptions";
217
+ };
218
+ readonly ListOrgCallbackSubscriptions: {
219
+ readonly method: "get";
220
+ readonly path: "/orgs/{orgId}/callback-subscriptions";
169
221
  };
170
222
  readonly ListOrgs: {
171
223
  readonly method: "get";
172
224
  readonly path: "/orgs";
173
225
  };
226
+ readonly ListOrgVerificationSessions: {
227
+ readonly method: "get";
228
+ readonly path: "/orgs/{orgId}/sessions";
229
+ };
174
230
  readonly ListProviderVersions: {
175
231
  readonly method: "get";
176
232
  readonly path: "/providers/{providerId}/versions";
177
233
  };
234
+ readonly ListSessionCallbackKeys: {
235
+ readonly method: "get";
236
+ readonly path: "/verifications/sessions/{sessionId}/callback-keys";
237
+ };
178
238
  readonly ListThemes: {
179
239
  readonly method: "get";
180
240
  readonly path: "/orgs/{orgId}/themes";
181
241
  };
242
+ readonly ListVerificationDeliveries: {
243
+ readonly method: "get";
244
+ readonly path: "/verifications/sessions/{sessionId}/deliveries";
245
+ };
246
+ readonly ListVerificationEvents: {
247
+ readonly method: "get";
248
+ readonly path: "/verifications/sessions/{sessionId}/events";
249
+ };
182
250
  readonly Login: {
183
251
  readonly method: "post";
184
252
  readonly path: "/auth/login";
@@ -215,18 +283,34 @@ export declare const ROUTES: {
215
283
  readonly method: "delete";
216
284
  readonly path: "/orgs/{orgId}/members/{memberId}";
217
285
  };
286
+ readonly ReportClaimant: {
287
+ readonly method: "post";
288
+ readonly path: "/v/{sessionId}/claimant";
289
+ };
290
+ readonly ReportVerificationEvent: {
291
+ readonly method: "post";
292
+ readonly path: "/verifications/sessions/{sessionId}/events";
293
+ };
218
294
  readonly RequestPublicListing: {
219
295
  readonly method: "post";
220
296
  readonly path: "/providers/{providerId}/request-public";
221
297
  };
222
- readonly RevokeCredential: {
223
- readonly method: "delete";
224
- readonly path: "/credentials/{credentialId}";
298
+ readonly RetryCallbackDlq: {
299
+ readonly method: "post";
300
+ readonly path: "/verifications/callback-dlq/{dlqId}/retry";
301
+ };
302
+ readonly RetryVerificationCallback: {
303
+ readonly method: "post";
304
+ readonly path: "/verifications/sessions/{sessionId}/retry-callback";
225
305
  };
226
306
  readonly Robots: {
227
307
  readonly method: "get";
228
308
  readonly path: "/robots.txt";
229
309
  };
310
+ readonly SetOrgCredential: {
311
+ readonly method: "put";
312
+ readonly path: "/orgs/{orgId}/credential";
313
+ };
230
314
  readonly SetupProviderCreate: {
231
315
  readonly method: "post";
232
316
  readonly path: "/providers/setup";
@@ -239,6 +323,10 @@ export declare const ROUTES: {
239
323
  readonly method: "post";
240
324
  readonly path: "/providers/{providerId}/versions/{version}/review";
241
325
  };
326
+ readonly SubmitVerificationResult: {
327
+ readonly method: "post";
328
+ readonly path: "/verifications/sessions/{sessionId}/result";
329
+ };
242
330
  readonly TransferProvider: {
243
331
  readonly method: "post";
244
332
  readonly path: "/providers/{providerId}/transfer";
@@ -275,5 +363,17 @@ export declare const ROUTES: {
275
363
  readonly method: "patch";
276
364
  readonly path: "/orgs/{orgId}/themes/{themeId}";
277
365
  };
366
+ readonly VerificationPage: {
367
+ readonly method: "get";
368
+ readonly path: "/v/{sessionId}";
369
+ };
370
+ readonly VerificationSessionSse: {
371
+ readonly method: "get";
372
+ readonly path: "/v/{sessionId}/sse";
373
+ };
374
+ readonly VerificationStatus: {
375
+ readonly method: "get";
376
+ readonly path: "/v/{sessionId}/status";
377
+ };
278
378
  };
279
379
  export type RouteId = keyof typeof ROUTES;
package/lib/routes.gen.js CHANGED
@@ -4,10 +4,12 @@
4
4
  // to regenerate. Do not edit by hand.
5
5
  export const ROUTES = {
6
6
  "AddOrgMember": { "method": "post", "path": "/orgs/{orgId}/members" },
7
+ "AdminCallbackDlq": { "method": "get", "path": "/admin/callback-dlq" },
7
8
  "AdminHome": { "method": "get", "path": "/admin" },
8
9
  "AdminOrgs": { "method": "get", "path": "/admin/orgs" },
9
10
  "AdminProviders": { "method": "get", "path": "/admin/providers" },
10
11
  "AdminReviews": { "method": "get", "path": "/admin/reviews" },
12
+ "AdminSessions": { "method": "get", "path": "/admin/sessions" },
11
13
  "AdminThemes": { "method": "get", "path": "/admin/themes" },
12
14
  "AdminUsers": { "method": "get", "path": "/admin/users" },
13
15
  "AttachPage": { "method": "get", "path": "/attach/{code}" },
@@ -15,15 +17,19 @@ export const ROUTES = {
15
17
  "ComponentsDemo": { "method": "get", "path": "/components_demo" },
16
18
  "ConfirmAttachSession": { "method": "post", "path": "/credentials/attach/sessions/{code}/confirm" },
17
19
  "CreateAttachSession": { "method": "post", "path": "/credentials/attach/sessions" },
20
+ "CreateCallbackSubscription": { "method": "post", "path": "/verifications/callback-subscriptions" },
18
21
  "CreateOrg": { "method": "post", "path": "/orgs" },
22
+ "CreateOrgCallbackSubscription": { "method": "post", "path": "/orgs/{orgId}/callback-subscriptions" },
19
23
  "CreateProvider": { "method": "post", "path": "/providers" },
20
24
  "CreateProviderVersion": { "method": "post", "path": "/providers/{providerId}/versions" },
21
25
  "CreateTheme": { "method": "post", "path": "/orgs/{orgId}/themes" },
22
- "CredentialAuthChallenge": { "method": "post", "path": "/credentials/auth/challenge" },
23
- "CredentialAuthVerify": { "method": "post", "path": "/credentials/auth/verify" },
26
+ "CreateVerificationSession": { "method": "post", "path": "/verifications/sessions" },
24
27
  "DecideProviderVersionReview": { "method": "post", "path": "/providers/{providerId}/versions/{version}/review-decision" },
28
+ "DeleteCallbackSubscription": { "method": "delete", "path": "/verifications/callback-subscriptions/{subscriptionId}" },
25
29
  "DeleteOrg": { "method": "delete", "path": "/orgs/{orgId}" },
26
30
  "DeleteOrgBilling": { "method": "delete", "path": "/orgs/{orgId}/billing" },
31
+ "DeleteOrgCallbackSubscription": { "method": "delete", "path": "/orgs/{orgId}/callback-subscriptions/{subscriptionId}" },
32
+ "DeleteOrgCredential": { "method": "delete", "path": "/orgs/{orgId}/credential" },
27
33
  "DeleteOrgIcon": { "method": "delete", "path": "/orgs/{orgId}/icon" },
28
34
  "DeleteProvider": { "method": "delete", "path": "/providers/{providerId}" },
29
35
  "DeleteProviderVersion": { "method": "delete", "path": "/providers/{providerId}/versions/{version}" },
@@ -31,23 +37,34 @@ export const ROUTES = {
31
37
  "Docs": { "method": "get", "path": "/docs" },
32
38
  "ExplorePreviewImage": { "method": "get", "path": "/og/explore.png" },
33
39
  "GetAttachSession": { "method": "get", "path": "/credentials/attach/sessions/{code}" },
34
- "GetCredential": { "method": "get", "path": "/credentials/{credentialId}" },
35
- "GetCredentialByAddress": { "method": "get", "path": "/credentials/by-address/{address}" },
36
40
  "GetImage": { "method": "get", "path": "/images/{imageId}" },
37
41
  "GetMe": { "method": "get", "path": "/me" },
38
42
  "GetOrg": { "method": "get", "path": "/orgs/{orgId}" },
39
43
  "GetOrgBilling": { "method": "get", "path": "/orgs/{orgId}/billing" },
44
+ "GetOrgCredential": { "method": "get", "path": "/orgs/{orgId}/credential" },
45
+ "GetOrgSession": { "method": "get", "path": "/orgs/{orgId}/sessions/{sessionId}" },
46
+ "GetOrgToken": { "method": "get", "path": "/orgs/{orgId}/token" },
40
47
  "GetProvider": { "method": "get", "path": "/providers/{providerId}" },
41
48
  "GetProviderBySlug": { "method": "get", "path": "/providers/{providerId}/{slug}" },
42
49
  "GetProviderVersion": { "method": "get", "path": "/providers/{providerId}/versions/{version}" },
43
50
  "GetTheme": { "method": "get", "path": "/orgs/{orgId}/themes/{themeId}" },
44
51
  "GetUser": { "method": "get", "path": "/users/{userId}" },
52
+ "GetVerificationRecipe": { "method": "get", "path": "/verifications/sessions/{sessionId}/recipe" },
53
+ "GetVerificationResult": { "method": "get", "path": "/verifications/sessions/{sessionId}/result" },
54
+ "GetVerificationSession": { "method": "get", "path": "/verifications/sessions/{sessionId}" },
45
55
  "Index": { "method": "get", "path": "/" },
46
- "LinkCredential": { "method": "post", "path": "/credentials" },
47
- "ListOrgCredentials": { "method": "get", "path": "/orgs/{orgId}/credentials" },
56
+ "IssueOrgToken": { "method": "post", "path": "/orgs/{orgId}/token" },
57
+ "JwksJson": { "method": "get", "path": "/.well-known/jwks.json" },
58
+ "ListCallbackDlq": { "method": "get", "path": "/verifications/callback-dlq" },
59
+ "ListCallbackSubscriptions": { "method": "get", "path": "/verifications/callback-subscriptions" },
60
+ "ListOrgCallbackSubscriptions": { "method": "get", "path": "/orgs/{orgId}/callback-subscriptions" },
48
61
  "ListOrgs": { "method": "get", "path": "/orgs" },
62
+ "ListOrgVerificationSessions": { "method": "get", "path": "/orgs/{orgId}/sessions" },
49
63
  "ListProviderVersions": { "method": "get", "path": "/providers/{providerId}/versions" },
64
+ "ListSessionCallbackKeys": { "method": "get", "path": "/verifications/sessions/{sessionId}/callback-keys" },
50
65
  "ListThemes": { "method": "get", "path": "/orgs/{orgId}/themes" },
66
+ "ListVerificationDeliveries": { "method": "get", "path": "/verifications/sessions/{sessionId}/deliveries" },
67
+ "ListVerificationEvents": { "method": "get", "path": "/verifications/sessions/{sessionId}/events" },
51
68
  "Login": { "method": "post", "path": "/auth/login" },
52
69
  "LoginPage": { "method": "get", "path": "/login" },
53
70
  "Logout": { "method": "post", "path": "/logout" },
@@ -57,12 +74,17 @@ export const ROUTES = {
57
74
  "Providers": { "method": "get", "path": "/providers" },
58
75
  "PublishProviderVersion": { "method": "post", "path": "/providers/{providerId}/versions/{version}/publish" },
59
76
  "RemoveOrgMember": { "method": "delete", "path": "/orgs/{orgId}/members/{memberId}" },
77
+ "ReportClaimant": { "method": "post", "path": "/v/{sessionId}/claimant" },
78
+ "ReportVerificationEvent": { "method": "post", "path": "/verifications/sessions/{sessionId}/events" },
60
79
  "RequestPublicListing": { "method": "post", "path": "/providers/{providerId}/request-public" },
61
- "RevokeCredential": { "method": "delete", "path": "/credentials/{credentialId}" },
80
+ "RetryCallbackDlq": { "method": "post", "path": "/verifications/callback-dlq/{dlqId}/retry" },
81
+ "RetryVerificationCallback": { "method": "post", "path": "/verifications/sessions/{sessionId}/retry-callback" },
62
82
  "Robots": { "method": "get", "path": "/robots.txt" },
83
+ "SetOrgCredential": { "method": "put", "path": "/orgs/{orgId}/credential" },
63
84
  "SetupProviderCreate": { "method": "post", "path": "/providers/setup" },
64
85
  "Sitemap": { "method": "get", "path": "/sitemap.xml" },
65
86
  "SubmitProviderVersionForReview": { "method": "post", "path": "/providers/{providerId}/versions/{version}/review" },
87
+ "SubmitVerificationResult": { "method": "post", "path": "/verifications/sessions/{sessionId}/result" },
66
88
  "TransferProvider": { "method": "post", "path": "/providers/{providerId}/transfer" },
67
89
  "UpdateMe": { "method": "patch", "path": "/me" },
68
90
  "UpdateOrg": { "method": "patch", "path": "/orgs/{orgId}" },
@@ -72,4 +94,7 @@ export const ROUTES = {
72
94
  "UpdateProvider": { "method": "patch", "path": "/providers/{providerId}" },
73
95
  "UpdateProviderVersion": { "method": "patch", "path": "/providers/{providerId}/versions/{version}" },
74
96
  "UpdateTheme": { "method": "patch", "path": "/orgs/{orgId}/themes/{themeId}" },
97
+ "VerificationPage": { "method": "get", "path": "/v/{sessionId}" },
98
+ "VerificationSessionSse": { "method": "get", "path": "/v/{sessionId}/sse" },
99
+ "VerificationStatus": { "method": "get", "path": "/v/{sessionId}/status" },
75
100
  };
package/lib/secp.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { keccak_256 } from '@noble/hashes/sha3.js';
2
+ import * as secp from '@noble/secp256k1';
3
+ export { keccak_256, secp };
4
+ /** Lowercase 0x ETH address from an uncompressed (65-byte) public key:
5
+ * keccak256 of the 64-byte X‖Y (drop the 0x04 prefix), last 20 bytes. */
6
+ export declare function addressFromUncompressedPubkey(pub: Uint8Array): string;