@reclaimprotocol/client 0.1.27 → 0.1.28

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.
Files changed (73) hide show
  1. package/README.md +634 -42
  2. package/lib/api-client.d.ts +31 -0
  3. package/lib/api-client.js +112 -0
  4. package/lib/api-consts.d.ts +4 -0
  5. package/lib/api-consts.js +4 -0
  6. package/lib/api-errors.d.ts +13 -0
  7. package/lib/api-errors.js +30 -0
  8. package/lib/api.d.ts +7 -0
  9. package/lib/api.js +3 -0
  10. package/lib/attestor-proof.d.ts +6 -0
  11. package/lib/attestor-proof.js +45 -18
  12. package/lib/client.d.ts +1 -6
  13. package/lib/client.js +12 -33
  14. package/lib/consts.d.ts +1 -1
  15. package/lib/consts.js +1 -1
  16. package/lib/eip191.d.ts +4 -2
  17. package/lib/eip191.js +17 -1
  18. package/lib/errors.d.ts +38 -4
  19. package/lib/errors.js +99 -16
  20. package/lib/index.d.ts +9 -7
  21. package/lib/index.js +8 -4
  22. package/lib/jwks.d.ts +25 -1
  23. package/lib/jwks.js +69 -4
  24. package/lib/legacy-proof.d.ts +57 -0
  25. package/lib/legacy-proof.js +211 -0
  26. package/lib/proof-hash.d.ts +35 -0
  27. package/lib/proof-hash.js +216 -0
  28. package/lib/proof-recipe.d.ts +18 -0
  29. package/lib/proof-recipe.js +37 -0
  30. package/lib/proof-trust-constants.d.ts +3 -0
  31. package/lib/proof-trust-constants.js +43 -0
  32. package/lib/proof-types.d.ts +62 -0
  33. package/lib/proof-types.js +1 -0
  34. package/lib/proof-verification-error.d.ts +13 -0
  35. package/lib/proof-verification-error.js +11 -0
  36. package/lib/reclaim.d.ts +27 -5
  37. package/lib/reclaim.js +140 -14
  38. package/lib/result.d.ts +58 -6
  39. package/lib/result.js +252 -61
  40. package/lib/routes.gen.d.ts +54 -6
  41. package/lib/routes.gen.js +15 -3
  42. package/lib/tee-binding.d.ts +82 -0
  43. package/lib/tee-binding.js +112 -0
  44. package/lib/types/openapi.gen.d.ts +1343 -206
  45. package/lib/verification-clients.d.ts +17 -0
  46. package/lib/verification-clients.js +14 -0
  47. package/lib/verify-attestor-tee.d.ts +76 -0
  48. package/lib/verify-attestor-tee.js +243 -0
  49. package/lib/verify-tee.d.ts +32 -0
  50. package/lib/verify-tee.js +347 -0
  51. package/package.json +5 -1
  52. package/src/api.ts +15 -0
  53. package/src/attestor-proof.ts +57 -20
  54. package/src/client.ts +15 -38
  55. package/src/consts.ts +1 -2
  56. package/src/eip191.ts +31 -3
  57. package/src/errors.ts +132 -18
  58. package/src/index.ts +50 -5
  59. package/src/jwks.ts +128 -5
  60. package/src/legacy-proof.ts +367 -0
  61. package/src/proof-hash.ts +316 -0
  62. package/src/proof-recipe.ts +75 -0
  63. package/src/proof-trust-constants.ts +45 -0
  64. package/src/proof-types.ts +57 -0
  65. package/src/proof-verification-error.ts +13 -0
  66. package/src/reclaim.ts +206 -19
  67. package/src/result.ts +403 -68
  68. package/src/routes.gen.ts +15 -3
  69. package/src/tee-binding.ts +192 -0
  70. package/src/types/openapi.gen.ts +1343 -206
  71. package/src/verification-clients.ts +22 -0
  72. package/src/verify-attestor-tee.ts +365 -0
  73. package/src/verify-tee.ts +507 -0
package/lib/result.js CHANGED
@@ -2,20 +2,20 @@
2
2
  * Consumer-side handling of a delivered callback. Two entry points:
3
3
  * - {@link verifyResult}: the offline primitive — decrypt + decode + optional
4
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).
5
+ * - {@link verifyResultFull}: the recommended server-side verification —
6
+ * resolves a registered issuer, discovers the Verification Client's key
7
+ * via JWKS, checks
8
+ * `reclaimSessionId`/`aud` and any legacy `exp`, and passes every exact
9
+ * legacy proof to the in-package, legacy-compatible `verifyProof` verifier.
9
10
  *
10
11
  * See docs/verification-session.md → "Verification by Consumer".
11
12
  */
12
13
  import { sha256 } from '@noble/hashes/sha2.js';
13
- import { keccak_256 } from '@noble/hashes/sha3.js';
14
14
  import { decrypt as eciesDecrypt, encrypt as eciesEncrypt } from 'eciesjs';
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";
15
+ import { b64url, base64urlToBytes, hexToBytes } from "./encoding.js";
16
+ import { fetchReclaimJwks, jwkToUncompressedPublicKey, selectVerificationResultKey, } from "./jwks.js";
17
+ import { verifyProof, } from "./legacy-proof.js";
18
+ import { proofHashesFromBuilderRecipe, } from "./proof-recipe.js";
19
19
  import { addressFromUncompressedPubkey, secp } from "./secp.js";
20
20
  /**
21
21
  * ECIES-encrypt `plaintext` for the holder of `publicJwk` (the org's secp256k1
@@ -134,13 +134,6 @@ export function verifyJwsSignature(jws, signerPublicKey) {
134
134
  }
135
135
  });
136
136
  }
137
- /** Content hash binding extracted parameters — MUST mirror the Verification
138
- * Client's `contentHash` exactly (keccak256 of the RFC 8785 canonical JSON,
139
- * via the shared `canonicalJson`). */
140
- function contentHash(params) {
141
- const canonical = canonicalJson(params);
142
- return '0x' + bytesToHex(keccak_256(new TextEncoder().encode(canonical)));
143
- }
144
137
  /**
145
138
  * Thrown by {@link verifyResult} / {@link verifyResultFull} (and therefore
146
139
  * `reclaim.results.verify`/`receive`) when a result fails verification. Carries
@@ -165,15 +158,17 @@ export class ResultVerificationError extends Error {
165
158
  }
166
159
  }
167
160
  /**
168
- * Full consumer verification: discovers the Verification Client's signing key
169
- * via JWKS (header `iss`/`kid`), verifies the top-level JWS, checks
170
- * `reclaimSessionId`/`aud`/`exp`, then verifies each result's nested attestor
171
- * proof and its `content_hash`. Network access (JWKS) makes this async; use
172
- * {@link verifyResult} for the offline primitive.
161
+ * Full consumer verification: resolves a trusted, registered issuer before
162
+ * using JWKS (header `iss`/`kid`), verifies the top-level JWS, checks
163
+ * `reclaimSessionId`/`aud` and any legacy `exp`, then verifies each exact
164
+ * legacy proof.
165
+ * Network access (JWKS and optional provider resolution) makes this async.
166
+ * Use {@link verifyResult} for the offline primitive.
173
167
  */
174
168
  export async function verifyResultFull(jws, opts = {}) {
175
169
  const payload = decodeJwsPayload(jws);
176
170
  const reclaimSessionId = payload.reclaimSessionId;
171
+ let jwksAttestorAddresses = [];
177
172
  /** Throw with the full invalid outcome — verification never *returns* an
178
173
  * invalid result. */
179
174
  const fail = (reason, extra = {}) => {
@@ -185,7 +180,8 @@ export async function verifyResultFull(jws, opts = {}) {
185
180
  ...extra,
186
181
  });
187
182
  };
188
- // 1. Resolve the VC signer key: explicit override, else JWKS via header iss.
183
+ // 1. Resolve the VC signer key. Never use the signed header's `iss` as a
184
+ // network destination until it has matched an explicit or registered issuer.
189
185
  let signerPublicKey = opts.signerPublicKey;
190
186
  let header = {};
191
187
  const sig0 = jws.signatures[0];
@@ -198,12 +194,37 @@ export async function verifyResultFull(jws, opts = {}) {
198
194
  }
199
195
  }
200
196
  if (!signerPublicKey) {
197
+ const verificationClientId = getVerificationClientId(payload) ?? '';
198
+ let configuredIssuers;
199
+ try {
200
+ configuredIssuers = await resolveTrustedIssuers(opts, verificationClientId);
201
+ }
202
+ catch {
203
+ return fail('issuer-resolution-failed');
204
+ }
205
+ if (!configuredIssuers.length) {
206
+ return fail('issuer-not-configured');
207
+ }
201
208
  const iss = String(header.iss ?? '');
202
209
  if (!iss) {
203
210
  return fail('no-issuer');
204
211
  }
205
- const keys = await fetchJwks(iss, opts.fetchImpl);
206
- const jwk = selectKey(keys, String(header.kid ?? ''));
212
+ const trustedIssuer = configuredIssuers.find((candidate) => (normalizeIssuer(candidate) === normalizeIssuer(iss)));
213
+ if (!trustedIssuer) {
214
+ return fail('issuer-not-trusted');
215
+ }
216
+ let keys;
217
+ try {
218
+ const jwksUrl = await resolveTrustedJwksUrl(opts, verificationClientId);
219
+ const registry = await fetchReclaimJwks(jwksUrl
220
+ ?? `${trustedIssuer.replace(/\/+$/, '')}/.well-known/jwks.json`, opts.fetchImpl);
221
+ keys = registry.keys;
222
+ jwksAttestorAddresses = registry['x-reclaim-attestors'] ?? [];
223
+ }
224
+ catch {
225
+ return fail('jwks-fetch-failed');
226
+ }
227
+ const jwk = selectVerificationResultKey(keys, String(header.kid ?? ''), verificationClientId);
207
228
  if (!jwk) {
208
229
  return fail('signer-key-not-found');
209
230
  }
@@ -212,78 +233,248 @@ export async function verifyResultFull(jws, opts = {}) {
212
233
  if (!verifyJwsSignature(jws, signerPublicKey)) {
213
234
  return fail('bad-signature');
214
235
  }
215
- // 2. Freshness / audience / expiry.
216
- if (opts.expectedReclaimSessionId &&
217
- reclaimSessionId !== opts.expectedReclaimSessionId) {
236
+ if (typeof payload.iss === 'string'
237
+ && typeof header.iss === 'string'
238
+ && normalizeIssuer(payload.iss) !== normalizeIssuer(header.iss)) {
239
+ return fail('issuer-mismatch');
240
+ }
241
+ // 2. Session binding, audience, and optional legacy result expiry.
242
+ const expectedResultSessionId = opts.sessionId
243
+ ?? opts.expectedReclaimSessionId;
244
+ if (expectedResultSessionId && reclaimSessionId !== expectedResultSessionId) {
218
245
  return fail('reclaimSessionId-mismatch');
219
246
  }
220
247
  if (opts.expectedAud && payload.aud !== opts.expectedAud) {
221
248
  return fail('aud-mismatch');
222
249
  }
223
250
  const now = opts.now ?? Math.floor(Date.now() / 1000);
224
- if (typeof payload.exp === 'number' && payload.exp < now) {
251
+ if (!opts.ignoreExpiration
252
+ && typeof payload.exp === 'number'
253
+ && payload.exp < now) {
225
254
  return fail('expired');
226
255
  }
227
- // 3. Per-provider, per-request nested attestor proof + content_hash binding.
228
- // `results` is grouped by provider: [{ provider_id, resolved_version,
229
- // requests: [...] }]. Every request across every provider must verify.
256
+ // 3. Verify every exact legacy proof carried by the signed result. The outer
257
+ // envelope groups proofs by provider, but it never changes the proof shape.
230
258
  const providerResults = Array.isArray(payload.results)
231
259
  ? payload.results
232
260
  : [];
233
261
  const proofs = [];
262
+ const proofGroups = [];
234
263
  for (const prov of providerResults) {
235
264
  const providerId = typeof prov.provider_id === 'string' ? prov.provider_id : undefined;
265
+ const providerVersion = typeof prov.resolved_version === 'string'
266
+ ? prov.resolved_version
267
+ : undefined;
236
268
  const requests = Array.isArray(prov.requests)
237
269
  ? prov.requests
238
270
  : [];
239
271
  for (const r of requests) {
240
272
  const requestId = typeof r.request_id === 'string' ? r.request_id : undefined;
241
- if (typeof r.proof !== 'string') {
273
+ if (!isLegacyProof(r.proof)) {
242
274
  proofs.push({
243
275
  providerId, requestId, proofValid: false, reason: 'proof-missing',
244
276
  });
245
277
  continue;
246
278
  }
247
- const np = verifyNestedProof(r.proof, {
248
- attestorAddresses: opts.attestorAddresses,
249
- });
250
- if (!np.valid) {
251
- proofs.push({
252
- providerId,
253
- requestId,
254
- proofValid: false,
255
- reason: np.reason,
256
- attestorAddress: np.attestorAddress,
257
- });
258
- continue;
259
- }
260
- if (typeof r.content_hash === 'string' &&
261
- r.extracted_parameters &&
262
- typeof r.extracted_parameters === 'object') {
263
- const params = r.extracted_parameters;
264
- if (contentHash(params).toLowerCase() !== r.content_hash.toLowerCase()) {
265
- proofs.push({
266
- providerId,
267
- requestId,
268
- proofValid: false,
269
- reason: 'content-hash-mismatch',
270
- attestorAddress: np.attestorAddress,
271
- });
272
- continue;
273
- }
274
- }
275
279
  proofs.push({
276
280
  providerId,
277
281
  requestId,
278
282
  proofValid: true,
279
- attestorAddress: np.attestorAddress,
283
+ attestorAddress: r.proof.witnesses[0]?.id,
284
+ });
285
+ proofGroups.push({
286
+ providerId,
287
+ providerVersion,
288
+ proof: r.proof,
289
+ outcomeIndex: proofs.length - 1,
280
290
  });
281
291
  }
282
292
  }
293
+ const verificationStatus = getVerificationStatus(payload);
294
+ if (verificationStatus === 'success' && !proofGroups.length) {
295
+ return fail('proof-missing', { proofs });
296
+ }
297
+ if (proofGroups.length) {
298
+ const expectedSessionId = expectedResultSessionId;
299
+ const configuredProofValidation = opts.proofValidation
300
+ ?? opts.proofVerification;
301
+ const attestorAddresses = [...new Set([
302
+ ...(configuredProofValidation?.attestorAddresses ?? []),
303
+ ...(opts.attestorAddresses ?? []),
304
+ ...jwksAttestorAddresses,
305
+ ])];
306
+ const commonValidation = {
307
+ ...configuredProofValidation,
308
+ ...(opts.hashes ? { hashes: opts.hashes } : {}),
309
+ ...(attestorAddresses.length
310
+ ? { attestorAddresses }
311
+ : {}),
312
+ ...(expectedSessionId
313
+ ? { expectedSessionId }
314
+ : {}),
315
+ };
316
+ if (hasContentValidation(commonValidation)) {
317
+ await verifyLegacyProofGroup(proofGroups, commonValidation);
318
+ }
319
+ else {
320
+ await verifyByResolvedRecipes(commonValidation, expectedSessionId);
321
+ }
322
+ }
283
323
  if (!proofs.every((p) => p.proofValid)) {
284
324
  return fail('invalid-proof', { proofs });
285
325
  }
286
326
  return { valid: true, payload, reclaimSessionId, proofs };
327
+ async function verifyLegacyProofGroup(group, validation) {
328
+ const legacyOutcome = await verifyProof(group.map(({ proof }) => proof), validation);
329
+ if (legacyOutcome.valid) {
330
+ for (const [index, item] of group.entries()) {
331
+ proofs[item.outcomeIndex].data = legacyOutcome.data?.[index];
332
+ proofs[item.outcomeIndex].publicData =
333
+ legacyOutcome.publicData?.[index];
334
+ }
335
+ return;
336
+ }
337
+ for (const { outcomeIndex } of group) {
338
+ proofs[outcomeIndex].proofValid = false;
339
+ proofs[outcomeIndex].reason = legacyOutcome.reason;
340
+ }
341
+ }
342
+ async function verifyByResolvedRecipes(common, expectedSessionId) {
343
+ let recipes = opts.proofRecipes;
344
+ if (!recipes && expectedSessionId && opts.resolveSession) {
345
+ try {
346
+ const resolved = await opts.resolveSession(expectedSessionId);
347
+ recipes = resolved.recipes;
348
+ }
349
+ catch {
350
+ return fail('session-resolution-failed', { proofs });
351
+ }
352
+ }
353
+ const groups = Map.groupBy(proofGroups, proofGroupKey);
354
+ if (recipes && !recipeGroupsMatch(recipes, groups)) {
355
+ markInvalid(proofGroups, 'recipe-mismatch');
356
+ return fail('invalid-proof', { proofs });
357
+ }
358
+ for (const group of groups.values()) {
359
+ await verifyResolvedGroup(group, recipes, common);
360
+ }
361
+ }
362
+ async function verifyResolvedGroup(group, recipes, common) {
363
+ const providerId = group[0]?.providerId;
364
+ const providerVersion = group[0]?.providerVersion;
365
+ const providerValidation = providerId
366
+ ? opts.proofValidationByProviderId?.[providerId]
367
+ : undefined;
368
+ const recipe = recipes?.find((candidate) => (candidate.providerId === providerId
369
+ && candidate.resolvedVersion === providerVersion));
370
+ let hashes;
371
+ if (recipe) {
372
+ try {
373
+ hashes = proofHashesFromBuilderRecipe(recipe, group.map(({ proof }) => proof));
374
+ }
375
+ catch {
376
+ markInvalid(group, 'recipe-hash-failed');
377
+ return;
378
+ }
379
+ }
380
+ await verifyLegacyProofGroup(group, {
381
+ ...common,
382
+ ...(recipe
383
+ ? { hashes }
384
+ : providerId
385
+ ? { providerId, providerVersion }
386
+ : {}),
387
+ ...providerValidation,
388
+ });
389
+ }
390
+ function markInvalid(group, reason) {
391
+ for (const { outcomeIndex } of group) {
392
+ proofs[outcomeIndex].proofValid = false;
393
+ proofs[outcomeIndex].reason = reason;
394
+ }
395
+ }
396
+ }
397
+ function hasContentValidation(config) {
398
+ return Boolean(config.hashes
399
+ || config.providerId
400
+ || config.dangerouslyDisableContentValidation);
401
+ }
402
+ function proofGroupKey(group) {
403
+ return `${group.providerId ?? ''}\u0000${group.providerVersion ?? ''}`;
404
+ }
405
+ function recipeGroupsMatch(recipes, groups) {
406
+ const expected = new Set(recipes.map((recipe) => (`${recipe.providerId}\u0000${recipe.resolvedVersion}`)));
407
+ return expected.size === groups.size
408
+ && [...groups.keys()].every((key) => expected.has(key));
409
+ }
410
+ function isLegacyProof(value) {
411
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
412
+ return false;
413
+ }
414
+ const proof = value;
415
+ return typeof proof.identifier === 'string'
416
+ && !!proof.claimData
417
+ && typeof proof.claimData === 'object'
418
+ && Array.isArray(proof.signatures)
419
+ && Array.isArray(proof.witnesses)
420
+ && 'extractedParameterValues' in proof;
421
+ }
422
+ function getVerificationStatus(payload) {
423
+ const session = payload.verification_session;
424
+ if (!session || typeof session !== 'object' || Array.isArray(session)) {
425
+ return undefined;
426
+ }
427
+ const status = session.status;
428
+ return typeof status === 'string' ? status : undefined;
429
+ }
430
+ function normalizeIssuer(issuer) {
431
+ return issuer.trim().replace(/\/+$/, '').toLowerCase();
432
+ }
433
+ function getVerificationClientId(payload) {
434
+ if (typeof payload.verificationClientId === 'string') {
435
+ return payload.verificationClientId;
436
+ }
437
+ if (typeof payload.verification_client_id === 'string') {
438
+ return payload.verification_client_id;
439
+ }
440
+ const session = payload.verification_session;
441
+ if (!session || typeof session !== 'object' || Array.isArray(session)) {
442
+ return undefined;
443
+ }
444
+ const sessionRecord = session;
445
+ const id = sessionRecord.verificationClientId
446
+ ?? sessionRecord.verification_client_id;
447
+ return typeof id === 'string' ? id : undefined;
448
+ }
449
+ async function resolveTrustedIssuers(opts, verificationClientId) {
450
+ const explicit = [
451
+ opts.issuer,
452
+ opts.trustedIssuer,
453
+ ...(opts.issuers ?? []),
454
+ ...(opts.trustedIssuers ?? []),
455
+ ].filter((issuer) => typeof issuer === 'string');
456
+ if (explicit.length) {
457
+ return [...new Set(explicit.map(normalizeIssuer))];
458
+ }
459
+ if (!verificationClientId) {
460
+ return [];
461
+ }
462
+ const registered = opts.issuersByVerificationClientId?.[verificationClientId] ?? [];
463
+ const resolve = opts.resolveIssuers ?? opts.issuerResolver;
464
+ const resolved = resolve
465
+ ? await resolve(verificationClientId)
466
+ : [];
467
+ return [...new Set([...registered, ...resolved].map(normalizeIssuer))];
468
+ }
469
+ async function resolveTrustedJwksUrl(opts, verificationClientId) {
470
+ if (opts.jwksUrl) {
471
+ return opts.jwksUrl;
472
+ }
473
+ if (!verificationClientId) {
474
+ return undefined;
475
+ }
476
+ const registered = opts.jwksUrlsByVerificationClientId?.[verificationClientId];
477
+ return registered ?? await opts.resolveJwksUrl?.(verificationClientId);
287
478
  }
288
479
  /** Decrypt-and-verify in one step. */
289
480
  export function verifyResult(jws, opts = {}) {
@@ -11,6 +11,10 @@ export declare const ROUTES: {
11
11
  readonly method: "post";
12
12
  readonly path: "/orgs/{orgId}/members";
13
13
  };
14
+ readonly AddProviderContributionComment: {
15
+ readonly method: "post";
16
+ readonly path: "/providers/{providerId}/contributions/{campaignId}/comments";
17
+ };
14
18
  readonly AddStaffMember: {
15
19
  readonly method: "post";
16
20
  readonly path: "/admin/staff";
@@ -83,6 +87,10 @@ export declare const ROUTES: {
83
87
  readonly method: "post";
84
88
  readonly path: "/admin/orgs/{orgId}/credits/{grantId}/void";
85
89
  };
90
+ readonly BindVerificationSessionTeeNonce: {
91
+ readonly method: "put";
92
+ readonly path: "/verifications/sessions/{sessionId}/tee-nonce";
93
+ };
86
94
  readonly CancelBillingSubscription: {
87
95
  readonly method: "delete";
88
96
  readonly path: "/orgs/{orgId}/billing/subscription";
@@ -143,10 +151,22 @@ export declare const ROUTES: {
143
151
  readonly method: "post";
144
152
  readonly path: "/providers";
145
153
  };
154
+ readonly CreateProviderContributionCampaign: {
155
+ readonly method: "post";
156
+ readonly path: "/providers/{providerId}/contributions";
157
+ };
158
+ readonly CreateProviderContributionRequirementRevision: {
159
+ readonly method: "post";
160
+ readonly path: "/providers/{providerId}/contributions/{campaignId}/requirements";
161
+ };
146
162
  readonly CreateProviderVersion: {
147
163
  readonly method: "post";
148
164
  readonly path: "/providers/{providerId}/versions";
149
165
  };
166
+ readonly CreatePublicContributionAttempt: {
167
+ readonly method: "post";
168
+ readonly path: "/contribute/{publicId}";
169
+ };
150
170
  readonly CreateTheme: {
151
171
  readonly method: "post";
152
172
  readonly path: "/orgs/{orgId}/themes";
@@ -279,6 +299,10 @@ export declare const ROUTES: {
279
299
  readonly method: "get";
280
300
  readonly path: "/providers/{providerId}/versions/{version}";
281
301
  };
302
+ readonly GetPublicContributionCampaign: {
303
+ readonly method: "get";
304
+ readonly path: "/contribute/{publicId}";
305
+ };
282
306
  readonly GetTheme: {
283
307
  readonly method: "get";
284
308
  readonly path: "/orgs/{orgId}/themes/{themeId}";
@@ -287,6 +311,10 @@ export declare const ROUTES: {
287
311
  readonly method: "get";
288
312
  readonly path: "/users/{userId}";
289
313
  };
314
+ readonly GetVerificationFunnel: {
315
+ readonly method: "get";
316
+ readonly path: "/orgs/{orgId}/verification-funnel";
317
+ };
290
318
  readonly GetVerificationRecipe: {
291
319
  readonly method: "get";
292
320
  readonly path: "/verifications/sessions/{sessionId}/recipe";
@@ -351,6 +379,10 @@ export declare const ROUTES: {
351
379
  readonly method: "get";
352
380
  readonly path: "/orgs/{orgId}/sessions";
353
381
  };
382
+ readonly ListProviderContributionCampaigns: {
383
+ readonly method: "get";
384
+ readonly path: "/providers/{providerId}/contributions";
385
+ };
354
386
  readonly ListProviderVersions: {
355
387
  readonly method: "get";
356
388
  readonly path: "/providers/{providerId}/versions";
@@ -395,6 +427,10 @@ export declare const ROUTES: {
395
427
  readonly method: "get";
396
428
  readonly path: "/orgs/{orgId}/invite";
397
429
  };
430
+ readonly PatchVerificationClaimant: {
431
+ readonly method: "patch";
432
+ readonly path: "/verifications/sessions/{sessionId}/claimant";
433
+ };
398
434
  readonly ProviderPreviewImage: {
399
435
  readonly method: "get";
400
436
  readonly path: "/providers/{providerId}/preview.png";
@@ -471,18 +507,22 @@ export declare const ROUTES: {
471
507
  readonly method: "post";
472
508
  readonly path: "/admin/billing/plans/{planId}/default";
473
509
  };
474
- readonly SetOrgCreditGrace: {
510
+ readonly SetOrgCreditAllowance: {
475
511
  readonly method: "post";
476
- readonly path: "/admin/orgs/{orgId}/credits/grace";
477
- };
478
- readonly SetOrgGrace: {
479
- readonly method: "post";
480
- readonly path: "/admin/orgs/{orgId}/billing/grace";
512
+ readonly path: "/admin/orgs/{orgId}/credits/allowance";
481
513
  };
482
514
  readonly SetOrgKeypair: {
483
515
  readonly method: "put";
484
516
  readonly path: "/orgs/{orgId}/keypair";
485
517
  };
518
+ readonly SetOrgPaymentAllowance: {
519
+ readonly method: "post";
520
+ readonly path: "/admin/orgs/{orgId}/billing/allowance";
521
+ };
522
+ readonly SetProviderContributionCampaignStatus: {
523
+ readonly method: "post";
524
+ readonly path: "/providers/{providerId}/contributions/{campaignId}";
525
+ };
486
526
  readonly SetupBillingPlan: {
487
527
  readonly method: "post";
488
528
  readonly path: "/admin/billing/plans/setup";
@@ -543,6 +583,10 @@ export declare const ROUTES: {
543
583
  readonly method: "post";
544
584
  readonly path: "/providers/{providerId}/versions/{version}/review";
545
585
  };
586
+ readonly SubmitPublicContributionFeedback: {
587
+ readonly method: "post";
588
+ readonly path: "/contribute/{publicId}/feedback";
589
+ };
546
590
  readonly SubmitVerificationResult: {
547
591
  readonly method: "post";
548
592
  readonly path: "/verifications/sessions/{sessionId}/result";
@@ -571,6 +615,10 @@ export declare const ROUTES: {
571
615
  readonly method: "patch";
572
616
  readonly path: "/providers/{providerId}";
573
617
  };
618
+ readonly UpdateProviderContributionCampaign: {
619
+ readonly method: "patch";
620
+ readonly path: "/providers/{providerId}/contributions/{campaignId}";
621
+ };
574
622
  readonly UpdateProviderVersion: {
575
623
  readonly method: "patch";
576
624
  readonly path: "/providers/{providerId}/versions/{version}";
package/lib/routes.gen.js CHANGED
@@ -1,11 +1,12 @@
1
1
  // AUTO-GENERATED by packages/app/scripts/mcp-tools-gen.ts
2
2
  // from packages/app/openapi.yaml.
3
- // Run `npm run openapi:typegen --workspace=packages/client`
3
+ // Run `npm run openapi:gen --workspace=packages/app`
4
4
  // to regenerate. Do not edit by hand.
5
5
  export const ROUTES = {
6
6
  "AcceptOrgInvite": { "method": "post", "path": "/orgs/{orgId}/invite" },
7
7
  "ActivateFixWithAiRepair": { "method": "post", "path": "/v/{sessionId}/fix-with-ai/activate" },
8
8
  "AddOrgMember": { "method": "post", "path": "/orgs/{orgId}/members" },
9
+ "AddProviderContributionComment": { "method": "post", "path": "/providers/{providerId}/contributions/{campaignId}/comments" },
9
10
  "AddStaffMember": { "method": "post", "path": "/admin/staff" },
10
11
  "AddVerificationClientKey": { "method": "post", "path": "/admin/verification-clients/{clientId}/keys" },
11
12
  "AdminBillingPlans": { "method": "get", "path": "/admin/billing/plans" },
@@ -24,6 +25,7 @@ export const ROUTES = {
24
25
  "AdminUsers": { "method": "get", "path": "/admin/users" },
25
26
  "AdminVerificationClients": { "method": "get", "path": "/admin/verification-clients" },
26
27
  "AdminVoidOrgCredit": { "method": "post", "path": "/admin/orgs/{orgId}/credits/{grantId}/void" },
28
+ "BindVerificationSessionTeeNonce": { "method": "put", "path": "/verifications/sessions/{sessionId}/tee-nonce" },
27
29
  "CancelBillingSubscription": { "method": "delete", "path": "/orgs/{orgId}/billing/subscription" },
28
30
  "CancelPublicListingRequest": { "method": "post", "path": "/providers/{providerId}/versions/{version}/cancel-review" },
29
31
  "ChangeOrgPlan": { "method": "post", "path": "/orgs/{orgId}/billing/change-plan" },
@@ -39,7 +41,10 @@ export const ROUTES = {
39
41
  "CreateOrg": { "method": "post", "path": "/orgs" },
40
42
  "CreateOrgCallbackSubscription": { "method": "post", "path": "/orgs/{orgId}/callback-subscriptions" },
41
43
  "CreateProvider": { "method": "post", "path": "/providers" },
44
+ "CreateProviderContributionCampaign": { "method": "post", "path": "/providers/{providerId}/contributions" },
45
+ "CreateProviderContributionRequirementRevision": { "method": "post", "path": "/providers/{providerId}/contributions/{campaignId}/requirements" },
42
46
  "CreateProviderVersion": { "method": "post", "path": "/providers/{providerId}/versions" },
47
+ "CreatePublicContributionAttempt": { "method": "post", "path": "/contribute/{publicId}" },
43
48
  "CreateTheme": { "method": "post", "path": "/orgs/{orgId}/themes" },
44
49
  "CreateVerificationClient": { "method": "post", "path": "/admin/verification-clients" },
45
50
  "CreateVerificationSession": { "method": "post", "path": "/verifications/sessions" },
@@ -73,8 +78,10 @@ export const ROUTES = {
73
78
  "GetProvider": { "method": "get", "path": "/providers/{providerId}" },
74
79
  "GetProviderBySlug": { "method": "get", "path": "/providers/{providerId}/{slug}" },
75
80
  "GetProviderVersion": { "method": "get", "path": "/providers/{providerId}/versions/{version}" },
81
+ "GetPublicContributionCampaign": { "method": "get", "path": "/contribute/{publicId}" },
76
82
  "GetTheme": { "method": "get", "path": "/orgs/{orgId}/themes/{themeId}" },
77
83
  "GetUser": { "method": "get", "path": "/users/{userId}" },
84
+ "GetVerificationFunnel": { "method": "get", "path": "/orgs/{orgId}/verification-funnel" },
78
85
  "GetVerificationRecipe": { "method": "get", "path": "/verifications/sessions/{sessionId}/recipe" },
79
86
  "GetVerificationResult": { "method": "get", "path": "/verifications/sessions/{sessionId}/result" },
80
87
  "GetVerificationSession": { "method": "get", "path": "/verifications/sessions/{sessionId}" },
@@ -91,6 +98,7 @@ export const ROUTES = {
91
98
  "ListOrgTokens": { "method": "get", "path": "/orgs/{orgId}/token" },
92
99
  "ListOrgTransactions": { "method": "get", "path": "/orgs/{orgId}/billing/transactions" },
93
100
  "ListOrgVerificationSessions": { "method": "get", "path": "/orgs/{orgId}/sessions" },
101
+ "ListProviderContributionCampaigns": { "method": "get", "path": "/providers/{providerId}/contributions" },
94
102
  "ListProviderVersions": { "method": "get", "path": "/providers/{providerId}/versions" },
95
103
  "ListSessionCallbackKeys": { "method": "get", "path": "/verifications/sessions/{sessionId}/callback-keys" },
96
104
  "ListStaffMembers": { "method": "get", "path": "/admin/staff" },
@@ -102,6 +110,7 @@ export const ROUTES = {
102
110
  "MakePrivate": { "method": "post", "path": "/providers/{providerId}/make-private" },
103
111
  "OpenApiSpec": { "method": "get", "path": "/openapi.yaml" },
104
112
  "OrgInvitePage": { "method": "get", "path": "/orgs/{orgId}/invite" },
113
+ "PatchVerificationClaimant": { "method": "patch", "path": "/verifications/sessions/{sessionId}/claimant" },
105
114
  "ProviderPreviewImage": { "method": "get", "path": "/providers/{providerId}/preview.png" },
106
115
  "Providers": { "method": "get", "path": "/providers" },
107
116
  "PublishProviderVersion": { "method": "post", "path": "/providers/{providerId}/versions/{version}/publish" },
@@ -121,9 +130,10 @@ export const ROUTES = {
121
130
  "Robots": { "method": "get", "path": "/robots.txt" },
122
131
  "SearchOrgMembers": { "method": "get", "path": "/orgs/{orgId}/members" },
123
132
  "SetDefaultBillingPlan": { "method": "post", "path": "/admin/billing/plans/{planId}/default" },
124
- "SetOrgCreditGrace": { "method": "post", "path": "/admin/orgs/{orgId}/credits/grace" },
125
- "SetOrgGrace": { "method": "post", "path": "/admin/orgs/{orgId}/billing/grace" },
133
+ "SetOrgCreditAllowance": { "method": "post", "path": "/admin/orgs/{orgId}/credits/allowance" },
126
134
  "SetOrgKeypair": { "method": "put", "path": "/orgs/{orgId}/keypair" },
135
+ "SetOrgPaymentAllowance": { "method": "post", "path": "/admin/orgs/{orgId}/billing/allowance" },
136
+ "SetProviderContributionCampaignStatus": { "method": "post", "path": "/providers/{providerId}/contributions/{campaignId}" },
127
137
  "SetupBillingPlan": { "method": "post", "path": "/admin/billing/plans/setup" },
128
138
  "SetupProviderCreate": { "method": "post", "path": "/providers/setup" },
129
139
  "SiteAiProvider": { "method": "post", "path": "/site/{domain}/ai-provider" },
@@ -139,6 +149,7 @@ export const ROUTES = {
139
149
  "StripeWebhook": { "method": "post", "path": "/billing/stripe/webhook" },
140
150
  "SubmitConsent": { "method": "post", "path": "/oauth/consent" },
141
151
  "SubmitProviderVersionForReview": { "method": "post", "path": "/providers/{providerId}/versions/{version}/review" },
152
+ "SubmitPublicContributionFeedback": { "method": "post", "path": "/contribute/{publicId}/feedback" },
142
153
  "SubmitVerificationResult": { "method": "post", "path": "/verifications/sessions/{sessionId}/result" },
143
154
  "TransferProvider": { "method": "post", "path": "/providers/{providerId}/transfer" },
144
155
  "UpdateBillingPlan": { "method": "put", "path": "/admin/billing/plans/{planId}" },
@@ -146,6 +157,7 @@ export const ROUTES = {
146
157
  "UpdateOrgIcon": { "method": "put", "path": "/orgs/{orgId}/icon" },
147
158
  "UpdateOrgMember": { "method": "patch", "path": "/orgs/{orgId}/members/{memberId}" },
148
159
  "UpdateProvider": { "method": "patch", "path": "/providers/{providerId}" },
160
+ "UpdateProviderContributionCampaign": { "method": "patch", "path": "/providers/{providerId}/contributions/{campaignId}" },
149
161
  "UpdateProviderVersion": { "method": "patch", "path": "/providers/{providerId}/versions/{version}" },
150
162
  "UpdateTheme": { "method": "patch", "path": "/orgs/{orgId}/themes/{themeId}" },
151
163
  "UpdateVerificationClient": { "method": "put", "path": "/admin/verification-clients/{clientId}" },