@reclaimprotocol/js-sdk 5.0.0-dev.1 → 5.0.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/dist/index.js CHANGED
@@ -22,6 +22,18 @@ var __spreadValues = (a, b) => {
22
22
  return a;
23
23
  };
24
24
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __objRest = (source, exclude) => {
26
+ var target = {};
27
+ for (var prop in source)
28
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
29
+ target[prop] = source[prop];
30
+ if (source != null && __getOwnPropSymbols)
31
+ for (var prop of __getOwnPropSymbols(source)) {
32
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
33
+ target[prop] = source[prop];
34
+ }
35
+ return target;
36
+ };
25
37
  var __commonJS = (cb, mod) => function __require() {
26
38
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
27
39
  };
@@ -72,7 +84,7 @@ var require_package = __commonJS({
72
84
  "package.json"(exports2, module2) {
73
85
  module2.exports = {
74
86
  name: "@reclaimprotocol/js-sdk",
75
- version: "5.0.0-dev.1",
87
+ version: "5.0.0-dev.2",
76
88
  description: "Designed to request proofs from the Reclaim protocol and manage the flow of claims and witness interactions.",
77
89
  main: "dist/index.js",
78
90
  types: "dist/index.d.ts",
@@ -148,6 +160,8 @@ var require_package = __commonJS({
148
160
  "@commitlint/config-conventional": "^17.7.0",
149
161
  "@release-it/conventional-changelog": "10.0.6",
150
162
  "@types/jest": "^30.0.0",
163
+ "@types/node-forge": "^1.3.14",
164
+ "@types/qrcode": "^1.5.5",
151
165
  "@types/qs": "^6.9.11",
152
166
  "@types/url-parse": "^1.4.11",
153
167
  "@types/uuid": "^9.0.7",
@@ -163,6 +177,8 @@ var require_package = __commonJS({
163
177
  canonicalize: "^2.0.0",
164
178
  ethers: "^6.9.1",
165
179
  "fetch-retry": "^6.0.0",
180
+ "node-forge": "^1.3.3",
181
+ qrcode: "^1.5.4",
166
182
  "url-parse": "^1.5.10",
167
183
  uuid: "^9.0.1"
168
184
  },
@@ -182,9 +198,10 @@ __export(index_exports, {
182
198
  assertVerifiedProof: () => assertVerifiedProof,
183
199
  clearDeviceCache: () => clearDeviceCache,
184
200
  createLinkWithTemplateData: () => createLinkWithTemplateData,
185
- fetchProviderConfig: () => fetchProviderConfig,
201
+ fetchProviderConfigs: () => fetchProviderConfigs,
186
202
  fetchProviderHashRequirementsBy: () => fetchProviderHashRequirementsBy,
187
203
  fetchStatusUrl: () => fetchStatusUrl,
204
+ generateSpecsFromRequestSpecTemplate: () => generateSpecsFromRequestSpecTemplate,
188
205
  getAttestors: () => getAttestors,
189
206
  getDeviceType: () => getDeviceType,
190
207
  getHttpProviderClaimParamsFromProof: () => getHttpProviderClaimParamsFromProof,
@@ -197,9 +214,12 @@ __export(index_exports, {
197
214
  isHttpProviderClaimParams: () => isHttpProviderClaimParams,
198
215
  isMobileDevice: () => isMobileDevice,
199
216
  recoverSignersOfSignedClaim: () => recoverSignersOfSignedClaim,
217
+ takePairsWhereValueIsArray: () => takePairsWhereValueIsArray,
218
+ takeTemplateParametersFromProofs: () => takeTemplateParametersFromProofs,
200
219
  transformForOnchain: () => transformForOnchain,
201
220
  updateSession: () => updateSession,
202
- verifyProof: () => verifyProof
221
+ verifyProof: () => verifyProof,
222
+ verifyTeeAttestation: () => verifyTeeAttestation
203
223
  });
204
224
  module.exports = __toCommonJS(index_exports);
205
225
 
@@ -212,20 +232,20 @@ var RECLAIM_EXTENSION_ACTIONS = {
212
232
  };
213
233
 
214
234
  // src/Reclaim.ts
215
- var import_ethers4 = require("ethers");
235
+ var import_ethers5 = require("ethers");
216
236
  var import_canonicalize3 = __toESM(require("canonicalize"));
217
237
 
218
238
  // src/utils/errors.ts
219
239
  function createErrorClass(name) {
220
240
  return class extends Error {
221
241
  constructor(message, innerError) {
222
- const fullMessage = innerError ? `${message || ""} caused by ${innerError.name}: ${innerError.message}` : message;
242
+ const fullMessage = innerError ? `${message || ""} caused by ${innerError && typeof innerError === "object" && "name" in innerError ? innerError.name : "Error"}: ${innerError && typeof innerError === "object" && "message" in innerError ? innerError.message : String(innerError)}` : message;
223
243
  super(fullMessage);
224
244
  this.innerError = innerError;
225
245
  this.name = name;
226
246
  if (innerError) {
227
247
  this.stack += `
228
- Caused by: ${innerError.stack}`;
248
+ Caused by: ${innerError && typeof innerError === "object" && "stack" in innerError ? innerError.stack : String(innerError)}`;
229
249
  }
230
250
  }
231
251
  };
@@ -233,6 +253,7 @@ Caused by: ${innerError.stack}`;
233
253
  var TimeoutError = createErrorClass("TimeoutError");
234
254
  var ProofNotVerifiedError = createErrorClass("ProofNotVerifiedError");
235
255
  var ProofNotValidatedError = createErrorClass("ProofNotValidatedError");
256
+ var InvalidRequestSpecError = createErrorClass("InvalidRequestSpecError");
236
257
  var UnknownProofsNotValidatedError = createErrorClass("UnknownProofsNotValidatedError");
237
258
  var SessionNotStartedError = createErrorClass("SessionNotStartedError");
238
259
  var ProviderNotFoundError = createErrorClass("ProviderNotFoundError");
@@ -353,15 +374,13 @@ var constants = {
353
374
  get DEFAULT_ATTESTORS_URL() {
354
375
  return `${BACKEND_BASE_URL}/api/attestors`;
355
376
  },
356
- DEFAULT_PROVIDER_URL(providerId, exactProviderVersionString) {
357
- return `${BACKEND_BASE_URL}/api/providers/${providerId}?versionNumber=${exactProviderVersionString}`;
377
+ DEFAULT_PROVIDER_CONFIGS_URL(providerId, exactProviderVersionString, allowedTags) {
378
+ return `${BACKEND_BASE_URL}/api/providers/${providerId}/configs?versionNumber=${exactProviderVersionString || ""}&allowedTags=${(allowedTags == null ? void 0 : allowedTags.join(",")) || ""}`;
358
379
  },
359
380
  // URL for sharing Reclaim templates
360
381
  RECLAIM_SHARE_URL: "https://share.reclaimprotocol.org/verifier/?template=",
361
382
  // Chrome extension URL for Reclaim Protocol
362
- CHROME_EXTENSION_URL: "https://chromewebstore.google.com/detail/reclaim-extension/oafieibbbcepkmenknelhmgaoahamdeh",
363
- // QR Code API base URL
364
- QR_CODE_API_URL: "https://api.qrserver.com/v1/create-qr-code/"
383
+ CHROME_EXTENSION_URL: "https://chromewebstore.google.com/detail/reclaim-extension/oafieibbbcepkmenknelhmgaoahamdeh"
365
384
  };
366
385
 
367
386
  // src/utils/validationUtils.ts
@@ -602,92 +621,6 @@ var http = {
602
621
  }
603
622
  };
604
623
 
605
- // src/witness.ts
606
- var import_ethers2 = require("ethers");
607
- function createSignDataForClaim(data) {
608
- const identifier = getIdentifierFromClaimInfo(data);
609
- const lines = [
610
- identifier,
611
- data.owner.toLowerCase(),
612
- data.timestampS.toString(),
613
- data.epoch.toString()
614
- ];
615
- return lines.join("\n");
616
- }
617
- function getIdentifierFromClaimInfo(info) {
618
- let canonicalContext = info.context || "";
619
- if (canonicalContext.length > 0) {
620
- try {
621
- const ctx = JSON.parse(canonicalContext);
622
- canonicalContext = canonicalStringify(ctx);
623
- } catch (e) {
624
- throw new Error("unable to parse non-empty context. Must be JSON");
625
- }
626
- }
627
- const str = `${info.provider}
628
- ${info.parameters}
629
- ${canonicalContext}`;
630
- return import_ethers2.ethers.keccak256(strToUint8Array(str)).toLowerCase();
631
- }
632
- function hashProofClaimParams(params) {
633
- const serializedParams = getProviderParamsAsCanonicalizedString(params);
634
- return import_ethers2.ethers.keccak256(
635
- strToUint8Array(serializedParams)
636
- ).toLowerCase();
637
- }
638
- function strToUint8Array(str) {
639
- return new TextEncoder().encode(str);
640
- }
641
- function getProviderParamsAsCanonicalizedString(params) {
642
- var _a, _b, _c, _d, _e, _f, _g;
643
- const filteredParams = {
644
- url: (_a = params == null ? void 0 : params.url) != null ? _a : "",
645
- // METHOD needs to be explicitly specified and absence or unknown method should cause error, but we're choosing to ignore it in this case
646
- method: (_b = params == null ? void 0 : params.method) != null ? _b : "GET",
647
- body: (_c = params == null ? void 0 : params.body) != null ? _c : "",
648
- responseMatches: (_e = (_d = params == null ? void 0 : params.responseMatches) == null ? void 0 : _d.map((it) => {
649
- var _a2, _b2;
650
- return {
651
- value: (_a2 = it.value) != null ? _a2 : "",
652
- // This needs to be explicitly specified and absence should cause error, but we're choosing to ignore it in this case
653
- type: (_b2 = it.type) != null ? _b2 : "contains",
654
- invert: it.invert || void 0,
655
- isOptional: it.isOptional || void 0
656
- };
657
- })) != null ? _e : [],
658
- responseRedactions: (_g = (_f = params == null ? void 0 : params.responseRedactions) == null ? void 0 : _f.map((it) => {
659
- var _a2, _b2, _c2;
660
- return {
661
- xPath: (_a2 = it.xPath) != null ? _a2 : "",
662
- jsonPath: (_b2 = it.jsonPath) != null ? _b2 : "",
663
- regex: (_c2 = it.regex) != null ? _c2 : "",
664
- hash: it.hash || void 0
665
- };
666
- })) != null ? _g : []
667
- };
668
- const serializedParams = canonicalStringify(filteredParams);
669
- return serializedParams;
670
- }
671
-
672
- // src/utils/providerUtils.ts
673
- function getProviderHashRequirementsFromSpec(spec) {
674
- var _a;
675
- return {
676
- hashes: ((_a = spec == null ? void 0 : spec.requests) == null ? void 0 : _a.map(hashRequestSpec)) || []
677
- };
678
- }
679
- function hashRequestSpec(request) {
680
- const hash = hashProofClaimParams(__spreadProps(__spreadValues({}, request), {
681
- // Body is strictly empty unless body sniff is explicitly enabled
682
- body: request.bodySniff.enabled ? request.bodySniff.template : ""
683
- }));
684
- return {
685
- value: hash,
686
- required: request.required,
687
- multiple: request.multiple
688
- };
689
- }
690
-
691
624
  // src/utils/sessionUtils.ts
692
625
  var logger4 = logger_default.logger;
693
626
  function initSession(providerId, appId, timestamp, signature, versionNumber) {
@@ -764,17 +697,24 @@ function fetchStatusUrl(sessionId) {
764
697
  }
765
698
  });
766
699
  }
767
- function fetchProviderConfig(providerId, exactProviderVersionString) {
700
+ function fetchProviderConfigs(providerId, exactProviderVersionString, allowedTags) {
768
701
  return __async(this, null, function* () {
769
702
  validateFunctionParams(
770
703
  [
771
- { input: providerId, paramName: "providerId", isString: true },
772
- { input: exactProviderVersionString, paramName: "exactProviderVersionString", isString: true }
704
+ { input: providerId, paramName: "providerId", isString: true }
773
705
  ],
774
- "fetchProviderConfig"
706
+ "fetchProviderConfigs"
775
707
  );
708
+ if (exactProviderVersionString != null && exactProviderVersionString != void 0) {
709
+ validateFunctionParams(
710
+ [
711
+ { input: exactProviderVersionString, paramName: "exactProviderVersionString", isString: true }
712
+ ],
713
+ "fetchProviderConfigs"
714
+ );
715
+ }
776
716
  try {
777
- const response = yield http.client(constants.DEFAULT_PROVIDER_URL(providerId, exactProviderVersionString), {
717
+ const response = yield http.client(constants.DEFAULT_PROVIDER_CONFIGS_URL(providerId, exactProviderVersionString, allowedTags), {
778
718
  method: "GET",
779
719
  headers: { "Content-Type": "application/json" }
780
720
  });
@@ -792,19 +732,116 @@ function fetchProviderConfig(providerId, exactProviderVersionString) {
792
732
  }
793
733
  });
794
734
  }
795
- function fetchProviderHashRequirementsBy(providerId, exactProviderVersion) {
796
- return __async(this, null, function* () {
797
- var _a, _b;
798
- const providerResponse = yield fetchProviderConfig(providerId, exactProviderVersion);
799
- const providerConfig = providerResponse.providers;
800
- return getProviderHashRequirementsFromSpec({
801
- requests: [...(_a = providerConfig == null ? void 0 : providerConfig.requestData) != null ? _a : [], ...(_b = providerConfig == null ? void 0 : providerConfig.allowedInjectedRequestData) != null ? _b : []]
802
- });
803
- });
804
- }
805
735
 
806
736
  // src/utils/proofUtils.ts
807
737
  var import_ethers3 = require("ethers");
738
+
739
+ // src/witness.ts
740
+ var import_ethers2 = require("ethers");
741
+ function createSignDataForClaim(data) {
742
+ const identifier = getIdentifierFromClaimInfo(data);
743
+ const lines = [
744
+ identifier,
745
+ data.owner.toLowerCase(),
746
+ data.timestampS.toString(),
747
+ data.epoch.toString()
748
+ ];
749
+ return lines.join("\n");
750
+ }
751
+ function getIdentifierFromClaimInfo(info) {
752
+ let canonicalContext = info.context || "";
753
+ if (canonicalContext.length > 0) {
754
+ try {
755
+ const ctx = JSON.parse(canonicalContext);
756
+ canonicalContext = canonicalStringify(ctx);
757
+ } catch (e) {
758
+ throw new Error("unable to parse non-empty context. Must be JSON");
759
+ }
760
+ }
761
+ const str = `${info.provider}
762
+ ${info.parameters}
763
+ ${canonicalContext}`;
764
+ return import_ethers2.ethers.keccak256(strToUint8Array(str)).toLowerCase();
765
+ }
766
+ function hashProofClaimParams(params) {
767
+ const serializedParams = getProviderParamsAsCanonicalizedString(params);
768
+ if (Array.isArray(serializedParams)) {
769
+ return serializedParams.map(
770
+ (serialized) => import_ethers2.ethers.keccak256(strToUint8Array(serialized)).toLowerCase()
771
+ );
772
+ }
773
+ return import_ethers2.ethers.keccak256(
774
+ strToUint8Array(serializedParams)
775
+ ).toLowerCase();
776
+ }
777
+ function strToUint8Array(str) {
778
+ return new TextEncoder().encode(str);
779
+ }
780
+ function getProviderParamsAsCanonicalizedString(params) {
781
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
782
+ const pairsCount = (_b = (_a = params == null ? void 0 : params.responseMatches) == null ? void 0 : _a.length) != null ? _b : 0;
783
+ const validCanonicalizedStrings = [];
784
+ const totalCombinations = 1 << pairsCount;
785
+ for (let i = 0; i < totalCombinations; i++) {
786
+ let isValidCombination = true;
787
+ let includedCount = 0;
788
+ const currentMatches = [];
789
+ const currentRedactions = [];
790
+ for (let j = 0; j < pairsCount; j++) {
791
+ const isIncluded = (i & 1 << j) !== 0;
792
+ const match = (_c = params == null ? void 0 : params.responseMatches) == null ? void 0 : _c[j];
793
+ const redaction = (_d = params == null ? void 0 : params.responseRedactions) == null ? void 0 : _d[j];
794
+ if (isIncluded) {
795
+ if (match) {
796
+ currentMatches.push({
797
+ value: (_e = match.value) != null ? _e : "",
798
+ // This needs to be explicitly specified and absence should cause error, but we're choosing to ignore it in this case
799
+ type: (_f = match.type) != null ? _f : "contains",
800
+ invert: match.invert || void 0
801
+ });
802
+ }
803
+ if (redaction) {
804
+ currentRedactions.push({
805
+ xPath: (_g = redaction.xPath) != null ? _g : "",
806
+ jsonPath: (_h = redaction.jsonPath) != null ? _h : "",
807
+ regex: (_i = redaction.regex) != null ? _i : "",
808
+ hash: redaction.hash || void 0
809
+ });
810
+ }
811
+ includedCount++;
812
+ } else {
813
+ if (match && !match.isOptional) {
814
+ isValidCombination = false;
815
+ break;
816
+ }
817
+ }
818
+ }
819
+ if (isValidCombination && includedCount > 0) {
820
+ const filteredParams = {
821
+ url: (_j = params == null ? void 0 : params.url) != null ? _j : "",
822
+ // METHOD needs to be explicitly specified and absence or unknown method should cause error, but we're choosing to ignore it in this case
823
+ method: (_k = params == null ? void 0 : params.method) != null ? _k : "GET",
824
+ body: (_l = params == null ? void 0 : params.body) != null ? _l : "",
825
+ responseMatches: currentMatches,
826
+ responseRedactions: currentRedactions
827
+ };
828
+ validCanonicalizedStrings.push(canonicalStringify(filteredParams));
829
+ }
830
+ }
831
+ if (validCanonicalizedStrings.length === 0) {
832
+ const filteredParams = {
833
+ url: (_m = params == null ? void 0 : params.url) != null ? _m : "",
834
+ method: (_n = params == null ? void 0 : params.method) != null ? _n : "GET",
835
+ body: (_o = params == null ? void 0 : params.body) != null ? _o : "",
836
+ responseMatches: [],
837
+ responseRedactions: []
838
+ };
839
+ return canonicalStringify(filteredParams);
840
+ }
841
+ return validCanonicalizedStrings.length === 1 ? validCanonicalizedStrings[0] : validCanonicalizedStrings;
842
+ }
843
+
844
+ // src/utils/proofUtils.ts
808
845
  var logger5 = logger_default.logger;
809
846
  function getShortenedUrl(url) {
810
847
  return __async(this, null, function* () {
@@ -881,6 +918,7 @@ function assertVerifiedProof(proof, attestors) {
881
918
  }
882
919
 
883
920
  // src/utils/modalUtils.ts
921
+ var import_qrcode = __toESM(require("qrcode"));
884
922
  var logger6 = logger_default.logger;
885
923
  var QRCodeModal = class {
886
924
  constructor(options = {}) {
@@ -1091,17 +1129,22 @@ var QRCodeModal = class {
1091
1129
  generateQRCode(text, containerId) {
1092
1130
  return __async(this, null, function* () {
1093
1131
  try {
1094
- const qrCodeUrl = `${constants.QR_CODE_API_URL}?size=200x200&data=${encodeURIComponent(text)}`;
1132
+ const dataUrl = yield import_qrcode.default.toDataURL(text, {
1133
+ width: 200,
1134
+ margin: 1,
1135
+ color: {
1136
+ dark: "#000000",
1137
+ light: "#ffffff"
1138
+ }
1139
+ });
1095
1140
  const container = document.getElementById(containerId);
1096
1141
  const styles = this.getThemeStyles();
1097
1142
  if (container) {
1098
1143
  container.innerHTML = `
1099
- <img src="${qrCodeUrl}"
1100
- alt="QR Code for Reclaim verification"
1101
- style="width: 200px; height: 200px; border-radius: 4px;"
1102
- onerror="this.style.display='none'; this.nextElementSibling.style.display='block';">
1144
+ <img src="${dataUrl}"
1145
+ alt="QR Code for Reclaim verification"
1146
+ style="width: 200px; height: 200px; border-radius: 4px;">
1103
1147
  <div style="display: none; padding: 20px; color: ${styles.textColor}; font-size: 14px;">
1104
- QR code could not be loaded.<br>
1105
1148
  <a href="${text}" target="_blank" style="color: ${styles.linkColor}; text-decoration: underline;">
1106
1149
  Click here to open verification link
1107
1150
  </a>
@@ -1329,10 +1372,123 @@ function clearDeviceCache() {
1329
1372
  cachedMobileType = null;
1330
1373
  }
1331
1374
 
1332
- // src/utils/proofValidationUtils.ts
1375
+ // src/utils/providerUtils.ts
1333
1376
  var logger7 = logger_default.logger;
1377
+ function fetchProviderHashRequirementsBy(providerId, exactProviderVersionString, allowedTags, proofs) {
1378
+ return __async(this, null, function* () {
1379
+ var _a, _b;
1380
+ const providerResponse = yield fetchProviderConfigs(providerId, exactProviderVersionString, allowedTags);
1381
+ try {
1382
+ const providerConfigs = providerResponse.providers;
1383
+ if (!providerConfigs || !providerConfigs.length) {
1384
+ throw new ProviderConfigFetchError(`No provider configs found for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);
1385
+ }
1386
+ const hashRequirements = [];
1387
+ for (const providerConfig of providerConfigs) {
1388
+ hashRequirements.push(getProviderHashRequirementsFromSpec({
1389
+ requests: [...(_a = providerConfig == null ? void 0 : providerConfig.requestData) != null ? _a : [], ...generateSpecsFromRequestSpecTemplate((_b = providerConfig == null ? void 0 : providerConfig.allowedInjectedRequestData) != null ? _b : [], takeTemplateParametersFromProofs(proofs))]
1390
+ }));
1391
+ }
1392
+ return hashRequirements;
1393
+ } catch (e) {
1394
+ const errorMessage = `Failed to fetch provider hash requirements for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`;
1395
+ logger7.info(errorMessage, e);
1396
+ throw new ProviderConfigFetchError(`Error fetching provider hash requirements for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);
1397
+ }
1398
+ });
1399
+ }
1400
+ function generateSpecsFromRequestSpecTemplate(requestSpecTemplates, templateParameters) {
1401
+ var _a;
1402
+ if (!requestSpecTemplates) return [];
1403
+ const generatedRequestTemplate = [];
1404
+ for (const template of requestSpecTemplates) {
1405
+ const templateVariables = (_a = template.templateParams) != null ? _a : [];
1406
+ if (!templateVariables.length) {
1407
+ generatedRequestTemplate.push(template);
1408
+ continue;
1409
+ }
1410
+ const templateParamsPairMatch = Object.entries(templateParameters).filter(([key, value]) => templateVariables.includes(key) && value.length);
1411
+ const hasAllTemplateVariableMatch = templateParamsPairMatch.length === templateVariables.length;
1412
+ if (!hasAllTemplateVariableMatch) {
1413
+ throw new InvalidRequestSpecError(`Not all template variables are present for template`);
1414
+ }
1415
+ const templateParamsPairMatchLength = templateParamsPairMatch[0][1].length;
1416
+ const allTemplateVariablesHaveSameLength = templateParamsPairMatch.every(([key, value]) => value.length === templateParamsPairMatchLength);
1417
+ if (!allTemplateVariablesHaveSameLength) {
1418
+ throw new InvalidRequestSpecError(`Not all template variables have same length for template`);
1419
+ }
1420
+ const getRequestSpecVariableTemplate = (key) => {
1421
+ return `\${${key}}`;
1422
+ };
1423
+ for (let i = 0; i < templateParamsPairMatchLength; i++) {
1424
+ const currentTemplateParams = {};
1425
+ for (const [key, values] of templateParamsPairMatch) {
1426
+ currentTemplateParams[key] = values[i];
1427
+ }
1428
+ const spec = __spreadProps(__spreadValues({}, template), {
1429
+ responseMatches: template.responseMatches ? template.responseMatches.map((m) => __spreadValues({}, m)) : [],
1430
+ responseRedactions: template.responseRedactions ? template.responseRedactions.map((r) => __spreadValues({}, r)) : []
1431
+ });
1432
+ for (const match of spec.responseMatches) {
1433
+ for (const [key, value] of Object.entries(currentTemplateParams)) {
1434
+ match.value = match.value.split(getRequestSpecVariableTemplate(key)).join(value);
1435
+ }
1436
+ }
1437
+ for (const redaction of spec.responseRedactions) {
1438
+ for (const [key, value] of Object.entries(currentTemplateParams)) {
1439
+ redaction.jsonPath = redaction.jsonPath.split(getRequestSpecVariableTemplate(key)).join(value);
1440
+ redaction.xPath = redaction.xPath.split(getRequestSpecVariableTemplate(key)).join(value);
1441
+ redaction.regex = redaction.regex.split(getRequestSpecVariableTemplate(key)).join(value);
1442
+ }
1443
+ }
1444
+ generatedRequestTemplate.push(spec);
1445
+ }
1446
+ }
1447
+ return generatedRequestTemplate;
1448
+ }
1449
+ function takeTemplateParametersFromProofs(proofs) {
1450
+ return takePairsWhereValueIsArray(proofs == null ? void 0 : proofs.map((it) => JSON.parse(it.claimData.context).extractedParameters).reduce((acc, it) => __spreadValues(__spreadValues({}, acc), it), {}));
1451
+ }
1452
+ function takePairsWhereValueIsArray(o) {
1453
+ if (!o) return {};
1454
+ const pairs = {};
1455
+ for (const [key, value] of Object.entries(o)) {
1456
+ if (Array.isArray(value) && value.length) {
1457
+ pairs[key] = value;
1458
+ } else {
1459
+ try {
1460
+ const parsedValue = JSON.parse(value);
1461
+ if (Array.isArray(parsedValue) && parsedValue.length) {
1462
+ pairs[key] = parsedValue;
1463
+ }
1464
+ } catch (_) {
1465
+ }
1466
+ }
1467
+ }
1468
+ return pairs;
1469
+ }
1470
+ function getProviderHashRequirementsFromSpec(spec) {
1471
+ var _a;
1472
+ return {
1473
+ hashes: ((_a = spec == null ? void 0 : spec.requests) == null ? void 0 : _a.map(hashRequestSpec)) || []
1474
+ };
1475
+ }
1476
+ function hashRequestSpec(request) {
1477
+ const hash = hashProofClaimParams(__spreadProps(__spreadValues({}, request), {
1478
+ // Body is strictly empty unless body sniff is explicitly enabled
1479
+ body: request.bodySniff.enabled ? request.bodySniff.template : ""
1480
+ }));
1481
+ return {
1482
+ value: hash,
1483
+ required: request.required,
1484
+ multiple: request.multiple
1485
+ };
1486
+ }
1487
+
1488
+ // src/utils/proofValidationUtils.ts
1489
+ var logger8 = logger_default.logger;
1334
1490
  var HASH_REQUIRED_DEFAULT = true;
1335
- var HASH_MATCH_MULTIPLE_DEFAULT = false;
1491
+ var HASH_MATCH_MULTIPLE_DEFAULT = true;
1336
1492
  function assertValidProofsByHash(proofs, config) {
1337
1493
  var _a, _b;
1338
1494
  if (!config.hashes) {
@@ -1342,31 +1498,36 @@ function assertValidProofsByHash(proofs, config) {
1342
1498
  for (let i = 0; i < proofs.length; i++) {
1343
1499
  const proof = proofs[i];
1344
1500
  const claimParams = getHttpProviderClaimParamsFromProof(proof);
1345
- const computedHashOfProof = hashProofClaimParams(claimParams).toLowerCase().trim();
1346
- unvalidatedProofHashByIndex.set(i, computedHashOfProof);
1501
+ const computedHashesOfProof = hashProofClaimParams(claimParams);
1502
+ const proofHashes = Array.isArray(computedHashesOfProof) ? computedHashesOfProof.map((h) => h.toLowerCase().trim()) : [computedHashesOfProof.toLowerCase().trim()];
1503
+ unvalidatedProofHashByIndex.set(i, proofHashes);
1347
1504
  }
1348
1505
  for (const hashRequirement of config.hashes) {
1349
1506
  let found = false;
1350
- const expectedHash = hashRequirement.value.toLowerCase().trim();
1507
+ const expectedHashes = Array.isArray(hashRequirement.value) ? hashRequirement.value.map((h) => h.toLowerCase().trim()) : [hashRequirement.value.toLowerCase().trim()];
1351
1508
  const isRequired = (_a = hashRequirement.required) != null ? _a : HASH_REQUIRED_DEFAULT;
1352
1509
  const canMatchMultiple = (_b = hashRequirement.multiple) != null ? _b : HASH_MATCH_MULTIPLE_DEFAULT;
1353
- for (const [i, proofHash] of unvalidatedProofHashByIndex.entries()) {
1354
- if (proofHash === expectedHash) {
1510
+ for (const [i, proofHashes] of unvalidatedProofHashByIndex.entries()) {
1511
+ const intersection = expectedHashes.filter((eh) => proofHashes.includes(eh));
1512
+ if (intersection.length > 0) {
1355
1513
  unvalidatedProofHashByIndex.delete(i);
1356
1514
  if (!found) {
1357
1515
  found = true;
1358
1516
  } else if (!canMatchMultiple) {
1359
- throw new ProofNotValidatedError(`Proof by hash '${expectedHash}' is not allowed to appear more than once`);
1517
+ const expectedHashStr = expectedHashes.length === 1 ? expectedHashes[0] : `[${expectedHashes.join(", ")}]`;
1518
+ throw new ProofNotValidatedError(`Proof by hash '${expectedHashStr}' is not allowed to appear more than once`);
1360
1519
  }
1361
1520
  }
1362
1521
  }
1363
1522
  if (!found && isRequired) {
1364
- throw new ProofNotValidatedError(`Proof by required hash '${expectedHash}' was not found`);
1523
+ const expectedHashStr = expectedHashes.length === 1 ? expectedHashes[0] : `[${expectedHashes.join(", ")}]`;
1524
+ throw new ProofNotValidatedError(`Proof by required hash '${expectedHashStr}' was not found`);
1365
1525
  }
1366
1526
  }
1367
1527
  if (unvalidatedProofHashByIndex.size > 0) {
1368
1528
  const contactSupport = "Please contact Reclaim Protocol Support team or mail us at support@reclaimprotocol.org.";
1369
- throw new UnknownProofsNotValidatedError(`Extra ${unvalidatedProofHashByIndex.size} proof(s) by hashes ${[...unvalidatedProofHashByIndex.values()].join(", ")} was found but could not be validated and indicates a security risk. ${contactSupport}`);
1529
+ const unvalidatedHashesStrArr = [...unvalidatedProofHashByIndex.values()].map((h) => h.length === 1 ? h[0] : `[${h.join(", ")}]`);
1530
+ throw new UnknownProofsNotValidatedError(`Extra ${unvalidatedProofHashByIndex.size} proof(s) by hashes ${unvalidatedHashesStrArr.join(", ")} was found but could not be validated and indicates a security risk. ${contactSupport}`);
1370
1531
  }
1371
1532
  }
1372
1533
  var allowedHttpMethods = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
@@ -1375,7 +1536,7 @@ function isHttpProviderClaimParams(claimParams) {
1375
1536
  return false;
1376
1537
  }
1377
1538
  const params = claimParams;
1378
- return typeof params.url === "string" && typeof params.method === "string" && allowedHttpMethods.has(params.method) && typeof params.body === "string" && Array.isArray(params.responseMatches) && params.responseMatches.length > 0 && Array.isArray(params.responseRedactions);
1539
+ return typeof params.url === "string" && typeof params.method === "string" && allowedHttpMethods.has(params.method) && (params.body == null || typeof params.body === "string") && Array.isArray(params.responseMatches) && params.responseMatches.length > 0 && Array.isArray(params.responseRedactions);
1379
1540
  }
1380
1541
  function getHttpProviderClaimParamsFromProof(proof) {
1381
1542
  try {
@@ -1388,31 +1549,781 @@ function getHttpProviderClaimParamsFromProof(proof) {
1388
1549
  throw new ProofNotValidatedError("Proof has no HTTP provider params to hash");
1389
1550
  }
1390
1551
  function assertValidateProof(proofs, config) {
1391
- if ("dangerouslyDisableContentValidation" in config && config.dangerouslyDisableContentValidation) {
1392
- logger7.warn("Validation skipped because it was disabled during proof verification");
1393
- return;
1552
+ return __async(this, null, function* () {
1553
+ if ("dangerouslyDisableContentValidation" in config && config.dangerouslyDisableContentValidation) {
1554
+ logger8.warn("Validation skipped because it was disabled during proof verification");
1555
+ return;
1556
+ }
1557
+ if ("providerId" in config) {
1558
+ if (!config.providerId || typeof config.providerId !== "string") {
1559
+ throw new ProofNotValidatedError("Provider id is required for proof validation");
1560
+ }
1561
+ if (config.providerVersion && typeof config.providerVersion !== "string") {
1562
+ throw new ProofNotValidatedError("Provider version must be a string");
1563
+ }
1564
+ const hashRequirementsFromProvider = yield fetchProviderHashRequirementsBy(config.providerId, config.providerVersion, config.allowedTags, proofs);
1565
+ if (!hashRequirementsFromProvider.length) {
1566
+ throw new ProofNotValidatedError("Could not find any provider information for the given provider id and version");
1567
+ }
1568
+ if (hashRequirementsFromProvider.length != 1) {
1569
+ let lastError = null;
1570
+ for (const hashRequirement of hashRequirementsFromProvider) {
1571
+ try {
1572
+ return yield assertValidateProof(proofs, hashRequirement);
1573
+ } catch (e) {
1574
+ lastError = e;
1575
+ }
1576
+ }
1577
+ throw new ProofNotValidatedError("Could not validate proof", lastError);
1578
+ } else {
1579
+ return assertValidateProof(proofs, hashRequirementsFromProvider[0]);
1580
+ }
1581
+ }
1582
+ const effectiveHashRequirement = ("hashes" in config && Array.isArray(config == null ? void 0 : config.hashes) ? config.hashes : []).map((it) => {
1583
+ if (typeof it == "string") {
1584
+ return {
1585
+ value: it
1586
+ };
1587
+ } else {
1588
+ return it;
1589
+ }
1590
+ });
1591
+ return assertValidProofsByHash(proofs, {
1592
+ hashes: effectiveHashRequirement
1593
+ });
1594
+ });
1595
+ }
1596
+
1597
+ // src/utils/verifyTee.ts
1598
+ var import_node_forge = __toESM(require("node-forge"));
1599
+ var import_ethers4 = require("ethers");
1600
+
1601
+ // src/utils/amdCerts.ts
1602
+ var AMD_CERTS = {
1603
+ "Milan": `-----BEGIN CERTIFICATE-----
1604
+ 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
1639
+ 0YPk
1640
+ -----END CERTIFICATE-----
1641
+ -----BEGIN CERTIFICATE-----
1642
+ MIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC
1643
+ BQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS
1644
+ BgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg
1645
+ Q2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp
1646
+ Y2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy
1647
+ MTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS
1648
+ BgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j
1649
+ ZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG
1650
+ 9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg
1651
+ W41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta
1652
+ 1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2
1653
+ SzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0
1654
+ 60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05
1655
+ gmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg
1656
+ bKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs
1657
+ +gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi
1658
+ Qi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ
1659
+ eTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18
1660
+ fHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j
1661
+ WhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI
1662
+ rFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG
1663
+ KWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG
1664
+ SIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI
1665
+ AWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel
1666
+ ETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw
1667
+ STjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK
1668
+ dHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq
1669
+ zT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp
1670
+ KGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e
1671
+ pmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq
1672
+ HnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh
1673
+ 3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn
1674
+ JZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH
1675
+ CViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4
1676
+ AFZEAwoKCQ==
1677
+ -----END CERTIFICATE-----`,
1678
+ "Genoa": `-----BEGIN CERTIFICATE-----
1679
+ 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
1714
+ 2cko
1715
+ -----END CERTIFICATE-----
1716
+ -----BEGIN CERTIFICATE-----
1717
+ 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
1751
+ /wMz1R1BHg==
1752
+ -----END CERTIFICATE-----`
1753
+ };
1754
+
1755
+ // src/utils/verifyTee.ts
1756
+ var crlCache = {};
1757
+ var logger9 = logger_default.logger;
1758
+ function toUint8Array(input) {
1759
+ if (typeof Buffer !== "undefined" && typeof Buffer.isBuffer === "function" && Buffer.isBuffer(input)) {
1760
+ return new Uint8Array(input);
1394
1761
  }
1395
- const effectiveHashRequirement = ("hashes" in config && Array.isArray(config == null ? void 0 : config.hashes) ? config.hashes : []).map((it) => {
1396
- if (typeof it == "string") {
1397
- return {
1398
- value: it
1399
- };
1762
+ if (input instanceof Uint8Array) {
1763
+ return new Uint8Array(input);
1764
+ }
1765
+ if (typeof ArrayBuffer !== "undefined" && input instanceof ArrayBuffer) {
1766
+ return new Uint8Array(input);
1767
+ }
1768
+ throw new Error("Unsupported binary data type");
1769
+ }
1770
+ function uint8ArrayToBinaryString(bytes) {
1771
+ let result = "";
1772
+ const chunkSize = 32768;
1773
+ for (let i = 0; i < bytes.length; i += chunkSize) {
1774
+ const chunk = bytes.subarray(i, i + chunkSize);
1775
+ result += String.fromCharCode(...chunk);
1776
+ }
1777
+ return result;
1778
+ }
1779
+ function binaryStringToUint8Array(binary) {
1780
+ const result = new Uint8Array(binary.length);
1781
+ for (let i = 0; i < binary.length; i++) {
1782
+ result[i] = binary.charCodeAt(i);
1783
+ }
1784
+ return result;
1785
+ }
1786
+ function base64ToUint8Array(base64) {
1787
+ if (typeof atob === "function") {
1788
+ const binary = atob(base64);
1789
+ return binaryStringToUint8Array(binary);
1790
+ }
1791
+ if (typeof Buffer !== "undefined") {
1792
+ return new Uint8Array(Buffer.from(base64, "base64"));
1793
+ }
1794
+ throw new Error("Base64 decoding is not supported in this environment");
1795
+ }
1796
+ function arrayBufferToHex(buffer) {
1797
+ const view = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
1798
+ let hex = "";
1799
+ for (let i = 0; i < view.length; i++) {
1800
+ hex += view[i].toString(16).padStart(2, "0");
1801
+ }
1802
+ return hex;
1803
+ }
1804
+ function concatUint8Arrays(parts) {
1805
+ const totalLength = parts.reduce((sum, arr) => sum + arr.length, 0);
1806
+ const result = new Uint8Array(totalLength);
1807
+ let offset = 0;
1808
+ for (const arr of parts) {
1809
+ result.set(arr, offset);
1810
+ offset += arr.length;
1811
+ }
1812
+ return result;
1813
+ }
1814
+ function reverseBytes(bytes) {
1815
+ const copy = Uint8Array.from(bytes);
1816
+ copy.reverse();
1817
+ return copy;
1818
+ }
1819
+ function normalizeSerial(s) {
1820
+ let cleaned = s.toLowerCase().replace(/[^a-f0-9]/g, "");
1821
+ while (cleaned.startsWith("0") && cleaned.length > 1) cleaned = cleaned.substring(1);
1822
+ return cleaned;
1823
+ }
1824
+ var isNode = typeof process !== "undefined" && process.versions && process.versions.node;
1825
+ var getSubtleCrypto = () => {
1826
+ var _a;
1827
+ if (typeof window !== "undefined" && ((_a = window.crypto) == null ? void 0 : _a.subtle)) return window.crypto.subtle;
1828
+ if (isNode) return require("crypto").webcrypto.subtle;
1829
+ throw new Error("No WebCrypto subtle implementation found in this environment");
1830
+ };
1831
+ function parseCert(buffer) {
1832
+ const bytes = toUint8Array(buffer);
1833
+ const asn1 = import_node_forge.default.asn1.fromDer(uint8ArrayToBinaryString(bytes));
1834
+ const certSeq = asn1.value;
1835
+ const tbsAsn1 = certSeq[0];
1836
+ const sigAlgAsn1 = certSeq[1];
1837
+ const sigValueAsn1 = certSeq[2];
1838
+ const tbsFields = tbsAsn1.value;
1839
+ let idx = 0;
1840
+ if (tbsFields[idx].tagClass === 128) idx++;
1841
+ const serialAsn1 = tbsFields[idx++];
1842
+ const serialNumber = import_node_forge.default.util.bytesToHex(serialAsn1.value);
1843
+ idx++;
1844
+ idx++;
1845
+ const validityAsn1 = tbsFields[idx++];
1846
+ idx++;
1847
+ const spkiAsn1 = tbsFields[idx];
1848
+ if (!validityAsn1 || !Array.isArray(validityAsn1.value) || validityAsn1.value.length < 2) {
1849
+ throw new Error("Certificate validity window is malformed");
1850
+ }
1851
+ const notBeforeNode = validityAsn1.value[0];
1852
+ const notAfterNode = validityAsn1.value[1];
1853
+ const notBefore = notBeforeNode ? parseAsn1Time(notBeforeNode) : void 0;
1854
+ const notAfter = notAfterNode ? parseAsn1Time(notAfterNode) : void 0;
1855
+ const sigRaw = typeof sigValueAsn1.value === "string" ? sigValueAsn1.value : "";
1856
+ const signature = binaryStringToUint8Array(sigRaw.substring(1));
1857
+ const sigAlgOid = import_node_forge.default.asn1.derToOid(sigAlgAsn1.value[0].value);
1858
+ return {
1859
+ serialNumber: normalizeSerial(serialNumber),
1860
+ tbsDer: binaryStringToUint8Array(import_node_forge.default.asn1.toDer(tbsAsn1).getBytes()),
1861
+ signature,
1862
+ sigAlgOid,
1863
+ spkiDer: binaryStringToUint8Array(import_node_forge.default.asn1.toDer(spkiAsn1).getBytes()),
1864
+ notBefore,
1865
+ notAfter
1866
+ };
1867
+ }
1868
+ function verifySignature(publicKeyPem, data, signature, sigAlgOid) {
1869
+ return __async(this, null, function* () {
1870
+ const cryptoSubtle = getSubtleCrypto();
1871
+ const forgeCert = import_node_forge.default.pki.certificateFromPem(publicKeyPem);
1872
+ const spkiBuf = binaryStringToUint8Array(import_node_forge.default.asn1.toDer(import_node_forge.default.pki.publicKeyToAsn1(forgeCert.publicKey)).getBytes());
1873
+ let importParams;
1874
+ let verifyParams;
1875
+ if (sigAlgOid === "1.2.840.113549.1.1.10") {
1876
+ importParams = { name: "RSA-PSS", hash: "SHA-384" };
1877
+ verifyParams = { name: "RSA-PSS", saltLength: 48 };
1878
+ } else if (sigAlgOid === "1.2.840.113549.1.1.11" || sigAlgOid === "1.2.840.113549.1.1.12" || sigAlgOid === "1.2.840.113549.1.1.5") {
1879
+ importParams = { name: "RSASSA-PKCS1-v1_5", hash: sigAlgOid === "1.2.840.113549.1.1.12" ? "SHA-384" : "SHA-256" };
1880
+ verifyParams = { name: "RSASSA-PKCS1-v1_5" };
1881
+ } else if (sigAlgOid === "1.2.840.10045.4.3.3") {
1882
+ importParams = { name: "ECDSA", namedCurve: "P-384" };
1883
+ verifyParams = { name: "ECDSA", hash: "SHA-384" };
1400
1884
  } else {
1401
- return it;
1885
+ importParams = { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" };
1886
+ verifyParams = { name: "RSASSA-PKCS1-v1_5" };
1887
+ }
1888
+ const key = yield cryptoSubtle.importKey("spki", spkiBuf, importParams, false, ["verify"]);
1889
+ const isValid = yield cryptoSubtle.verify(verifyParams, key, signature, data);
1890
+ if (!isValid) throw new Error(`Signature verification failed (OID: ${sigAlgOid}, ImportParams: ${JSON.stringify(importParams)})`);
1891
+ });
1892
+ }
1893
+ var COSIGN_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
1894
+ MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjiL30OjPuxa+GC1I7SAcBv2u2pMt
1895
+ h9WbP33IvB3eFww+C1hoW0fwdZPiq4FxBtKNiZuFpmYuFngW/nJteBu9kQ==
1896
+ -----END PUBLIC KEY-----
1897
+ `;
1898
+ function verifyTeeAttestation(proof, expectedApplicationId) {
1899
+ return __async(this, null, function* () {
1900
+ try {
1901
+ let teeAttestation = proof.teeAttestation;
1902
+ if (!teeAttestation) {
1903
+ throw new Error("Missing teeAttestation in proof");
1904
+ }
1905
+ if (typeof teeAttestation === "string") {
1906
+ teeAttestation = JSON.parse(teeAttestation);
1907
+ }
1908
+ let expectedNonceSignature;
1909
+ let nonceDataObj;
1910
+ try {
1911
+ const context = JSON.parse(proof.claimData.context);
1912
+ expectedNonceSignature = context.attestationNonce;
1913
+ nonceDataObj = context.attestationNonceData;
1914
+ } catch (e) {
1915
+ throw new Error("Failed to parse proof context to extract attestationNonce");
1916
+ }
1917
+ if (!expectedNonceSignature || !nonceDataObj) {
1918
+ throw new Error("Proof context is missing attestationNonce or attestationNonceData");
1919
+ }
1920
+ if (teeAttestation.nonce !== expectedNonceSignature) {
1921
+ throw new Error(`Nonce Mismatch! Expected signature ${expectedNonceSignature}, got ${teeAttestation.nonce}`);
1922
+ }
1923
+ const { applicationId, sessionId, timestamp } = nonceDataObj;
1924
+ if (expectedApplicationId && applicationId.toLowerCase() !== expectedApplicationId.toLowerCase()) {
1925
+ throw new Error(`Application ID Mismatch! Expected ${expectedApplicationId}, but proof context contains ${applicationId}`);
1926
+ }
1927
+ const expectedNonceData = `${applicationId}:${sessionId}:${timestamp}`;
1928
+ const nonceMsg = import_ethers4.ethers.getBytes(import_ethers4.ethers.keccak256(new TextEncoder().encode(expectedNonceData)));
1929
+ const recoveredAddress = import_ethers4.ethers.verifyMessage(nonceMsg, expectedNonceSignature);
1930
+ if (recoveredAddress.toLowerCase() !== applicationId.toLowerCase()) {
1931
+ throw new Error(`Nonce signature verification failed: recovered ${recoveredAddress}, expected ${applicationId}`);
1932
+ }
1933
+ try {
1934
+ const context = JSON.parse(proof.claimData.context);
1935
+ const paramSessionId = context.attestationNonceData.sessionId;
1936
+ if (!paramSessionId) {
1937
+ throw new Error(`Proof parameters are missing proxySessionId or sessionId`);
1938
+ }
1939
+ if (paramSessionId.toString() !== sessionId.toString()) {
1940
+ throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof parameters contain ${paramSessionId}`);
1941
+ }
1942
+ const claimTimestampMs = proof.claimData.timestampS * 1e3;
1943
+ const nonceTimestampMs = parseInt(timestamp, 10);
1944
+ const diffMs = Math.abs(claimTimestampMs - nonceTimestampMs);
1945
+ const TEN_MINUTES_MS = 10 * 60 * 1e3;
1946
+ if (diffMs > TEN_MINUTES_MS) {
1947
+ throw new Error(`Timestamp Skew Too Large! claimData.timestampS and attestationNonce timestamp differ by ${Math.round(diffMs / 1e3)}s (limit: 600s)`);
1948
+ }
1949
+ } catch (e) {
1950
+ if (e instanceof Error && (e.message.includes("Session ID Mismatch!") || e.message.includes("Timestamp Skew"))) {
1951
+ throw e;
1952
+ }
1953
+ throw new Error(`Failed to cross-verify session ID: ${e.message}`);
1954
+ }
1955
+ const reportBuffer = base64ToUint8Array(teeAttestation.snp_report);
1956
+ const report = parseAttestationReport(reportBuffer);
1957
+ if (report.isDebugEnabled) {
1958
+ throw new Error("POLICY CHECK FAILED: Debug mode is ALLOWED. Environment is compromised.");
1959
+ }
1960
+ const certBuffer = base64ToUint8Array(teeAttestation.vlek_cert);
1961
+ yield verifyAMDChain(certBuffer);
1962
+ verifyTCB(certBuffer, report);
1963
+ yield verifyHardwareSignature(reportBuffer, certBuffer);
1964
+ yield verifyReportData(teeAttestation, proof.claimData.context, report);
1965
+ return true;
1966
+ } catch (error) {
1967
+ logger9.error("TEE attestation verification failed:", error);
1968
+ return false;
1969
+ }
1970
+ });
1971
+ }
1972
+ function parseAttestationReport(buffer) {
1973
+ if (buffer.length < 1e3) {
1974
+ throw new Error(`Report buffer is too small: ${buffer.length} bytes`);
1975
+ }
1976
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
1977
+ const policy = view.getBigUint64(8, true);
1978
+ const isDebugEnabled = (policy & BigInt(1) << BigInt(19)) !== BigInt(0);
1979
+ const reported_tcb = {
1980
+ bootloader: buffer[56],
1981
+ tee: buffer[57],
1982
+ snp: buffer[62],
1983
+ microcode: buffer[63]
1984
+ };
1985
+ const reportData = arrayBufferToHex(buffer.subarray(80, 144));
1986
+ return { policy, isDebugEnabled, reported_tcb, reportData };
1987
+ }
1988
+ function getExtValue(certAsn1, oidString) {
1989
+ const tbsCert = certAsn1.value[0];
1990
+ if (!tbsCert || !tbsCert.value) return null;
1991
+ const extBlockWrapper = tbsCert.value.find((node) => node.tagClass === import_node_forge.default.asn1.Class.CONTEXT_SPECIFIC && node.type === 3);
1992
+ if (!extBlockWrapper || !extBlockWrapper.value || !extBlockWrapper.value.length) return null;
1993
+ const extSequence = extBlockWrapper.value[0];
1994
+ for (const ext of extSequence.value) {
1995
+ const extIdAsn1 = ext.value[0];
1996
+ const extIdStr = import_node_forge.default.asn1.derToOid(extIdAsn1.value);
1997
+ if (extIdStr === oidString) {
1998
+ const extValueAsn1 = ext.value[ext.value.length - 1];
1999
+ const rawOctetStringBytes = extValueAsn1.value;
2000
+ try {
2001
+ const innerAsn1 = import_node_forge.default.asn1.fromDer(import_node_forge.default.util.createBuffer(rawOctetStringBytes));
2002
+ if (innerAsn1.type === 2) {
2003
+ const bytes = innerAsn1.value;
2004
+ if (typeof bytes === "string" && bytes.length > 0) {
2005
+ return bytes.charCodeAt(bytes.length - 1);
2006
+ } else {
2007
+ throw new Error(`Extension ${oidString} INTEGER value is empty or invalid`);
2008
+ }
2009
+ } else {
2010
+ throw new Error(`Extension ${oidString} does not contain an INTEGER, found type ${innerAsn1.type}`);
2011
+ }
2012
+ } catch (e) {
2013
+ throw new Error(`Failed to strictly parse AMD TCB extension ${oidString}: ${e.message}`);
2014
+ }
2015
+ }
2016
+ }
2017
+ return null;
2018
+ }
2019
+ function verifyTCB(vlekCertBuffer, report) {
2020
+ const certAsn1 = import_node_forge.default.asn1.fromDer(import_node_forge.default.util.createBuffer(uint8ArrayToBinaryString(vlekCertBuffer)));
2021
+ const OID_BOOTLOADER = "1.3.6.1.4.1.3704.1.3.1";
2022
+ const OID_TEE = "1.3.6.1.4.1.3704.1.3.2";
2023
+ const OID_SNP = "1.3.6.1.4.1.3704.1.3.3";
2024
+ const OID_MICROCODE = "1.3.6.1.4.1.3704.1.3.8";
2025
+ const certTcb = {
2026
+ bootloader: getExtValue(certAsn1, OID_BOOTLOADER),
2027
+ tee: getExtValue(certAsn1, OID_TEE),
2028
+ snp: getExtValue(certAsn1, OID_SNP),
2029
+ microcode: getExtValue(certAsn1, OID_MICROCODE)
2030
+ };
2031
+ if (certTcb.bootloader !== null && report.reported_tcb.bootloader < certTcb.bootloader) {
2032
+ throw new Error(`TCB Downgrade! Bootloader reported ${report.reported_tcb.bootloader}, but certificate requires ${certTcb.bootloader}`);
2033
+ }
2034
+ if (certTcb.tee !== null && report.reported_tcb.tee < certTcb.tee) {
2035
+ throw new Error(`TCB Downgrade! TEE reported ${report.reported_tcb.tee}, but certificate requires ${certTcb.tee}`);
2036
+ }
2037
+ if (certTcb.snp !== null && report.reported_tcb.snp < certTcb.snp) {
2038
+ throw new Error(`TCB Downgrade! SNP reported ${report.reported_tcb.snp}, but certificate requires ${certTcb.snp}`);
2039
+ }
2040
+ if (certTcb.microcode !== null && report.reported_tcb.microcode < certTcb.microcode) {
2041
+ throw new Error(`TCB Downgrade! Microcode reported ${report.reported_tcb.microcode}, but certificate requires ${certTcb.microcode}`);
2042
+ }
2043
+ }
2044
+ function parseAsn1Time(node) {
2045
+ const s = node.value;
2046
+ if (node.type === import_node_forge.default.asn1.Type.UTCTIME) {
2047
+ const yr = parseInt(s.substring(0, 2), 10);
2048
+ return new Date(Date.UTC(
2049
+ yr >= 50 ? 1900 + yr : 2e3 + yr,
2050
+ parseInt(s.substring(2, 4), 10) - 1,
2051
+ parseInt(s.substring(4, 6), 10),
2052
+ parseInt(s.substring(6, 8), 10),
2053
+ parseInt(s.substring(8, 10), 10),
2054
+ parseInt(s.substring(10, 12), 10)
2055
+ ));
2056
+ } else {
2057
+ return new Date(Date.UTC(
2058
+ parseInt(s.substring(0, 4), 10),
2059
+ parseInt(s.substring(4, 6), 10) - 1,
2060
+ parseInt(s.substring(6, 8), 10),
2061
+ parseInt(s.substring(8, 10), 10),
2062
+ parseInt(s.substring(10, 12), 10),
2063
+ parseInt(s.substring(12, 14), 10)
2064
+ ));
2065
+ }
2066
+ }
2067
+ function verifyCRL(crlBuf, arkPem, vlekSerial) {
2068
+ return __async(this, null, function* () {
2069
+ const crlAsn1 = import_node_forge.default.asn1.fromDer(import_node_forge.default.util.createBuffer(uint8ArrayToBinaryString(crlBuf)));
2070
+ if (!Array.isArray(crlAsn1.value) || crlAsn1.value.length < 3) {
2071
+ throw new Error("CRL ASN.1 structure is invalid: expected SEQUENCE with TBSCertList, AlgorithmIdentifier, BIT STRING");
2072
+ }
2073
+ const tbsAsn1 = crlAsn1.value[0];
2074
+ const sigBitsAsn1 = crlAsn1.value[2];
2075
+ if (!Array.isArray(tbsAsn1.value)) {
2076
+ throw new Error("CRL TBSCertList is not a valid SEQUENCE");
2077
+ }
2078
+ const tbsFields = tbsAsn1.value;
2079
+ let fi = 0;
2080
+ if (fi < tbsFields.length && tbsFields[fi].tagClass === import_node_forge.default.asn1.Class.UNIVERSAL && tbsFields[fi].type === import_node_forge.default.asn1.Type.INTEGER) {
2081
+ fi++;
2082
+ }
2083
+ if (fi < tbsFields.length) fi++;
2084
+ if (fi >= tbsFields.length) throw new Error("CRL TBSCertList missing issuer");
2085
+ const issuerAsn1 = tbsFields[fi++];
2086
+ if (fi >= tbsFields.length) throw new Error("CRL TBSCertList missing thisUpdate");
2087
+ const thisUpdateAsn1 = tbsFields[fi++];
2088
+ let nextUpdateAsn1 = null;
2089
+ if (fi < tbsFields.length && tbsFields[fi].tagClass === import_node_forge.default.asn1.Class.UNIVERSAL && (tbsFields[fi].type === import_node_forge.default.asn1.Type.UTCTIME || tbsFields[fi].type === import_node_forge.default.asn1.Type.GENERALIZEDTIME)) {
2090
+ nextUpdateAsn1 = tbsFields[fi++];
2091
+ }
2092
+ let revokedSeq = null;
2093
+ if (fi < tbsFields.length && tbsFields[fi].tagClass === import_node_forge.default.asn1.Class.UNIVERSAL && tbsFields[fi].type === import_node_forge.default.asn1.Type.SEQUENCE) {
2094
+ revokedSeq = tbsFields[fi];
2095
+ }
2096
+ const now = /* @__PURE__ */ new Date();
2097
+ const thisUpdate = parseAsn1Time(thisUpdateAsn1);
2098
+ if (thisUpdate > now) {
2099
+ throw new Error(`CRL is not yet valid: thisUpdate is ${thisUpdate.toISOString()}`);
2100
+ }
2101
+ if (nextUpdateAsn1) {
2102
+ const nextUpdate = parseAsn1Time(nextUpdateAsn1);
2103
+ if (nextUpdate < now) {
2104
+ throw new Error(`CRL has expired: nextUpdate was ${nextUpdate.toISOString()}`);
2105
+ }
2106
+ }
2107
+ const crlIssuerDer = import_node_forge.default.asn1.toDer(issuerAsn1).getBytes();
2108
+ const arkForgeCert = import_node_forge.default.pki.certificateFromPem(arkPem);
2109
+ const arkCertAsn1 = import_node_forge.default.pki.certificateToAsn1(arkForgeCert);
2110
+ const arkSubjectAsn1 = arkCertAsn1.value[0].value[5];
2111
+ const arkSubjectDer = import_node_forge.default.asn1.toDer(arkSubjectAsn1).getBytes();
2112
+ if (crlIssuerDer !== arkSubjectDer) {
2113
+ throw new Error("CRL issuer does not match AMD ARK certificate subject \u2014 chain mismatch");
2114
+ }
2115
+ const tbsDerBuf = binaryStringToUint8Array(import_node_forge.default.asn1.toDer(tbsAsn1).getBytes());
2116
+ const sigRaw = typeof sigBitsAsn1.value === "string" ? sigBitsAsn1.value : "";
2117
+ const sigBuf = binaryStringToUint8Array(sigRaw.substring(1));
2118
+ const cryptoSubtle = getSubtleCrypto();
2119
+ const spkiBuf = binaryStringToUint8Array(
2120
+ import_node_forge.default.asn1.toDer(import_node_forge.default.pki.publicKeyToAsn1(arkForgeCert.publicKey)).getBytes()
2121
+ );
2122
+ const arkCryptoKey = yield cryptoSubtle.importKey(
2123
+ "spki",
2124
+ spkiBuf,
2125
+ { name: "RSA-PSS", hash: "SHA-384" },
2126
+ false,
2127
+ ["verify"]
2128
+ );
2129
+ const isValid = yield cryptoSubtle.verify(
2130
+ { name: "RSA-PSS", saltLength: 48 },
2131
+ // SHA-384 salt length is 48
2132
+ arkCryptoKey,
2133
+ sigBuf,
2134
+ tbsDerBuf
2135
+ );
2136
+ if (!isValid) {
2137
+ throw new Error("CRL signature is INVALID \u2014 the CRL may be tampered or forged");
2138
+ }
2139
+ const targetSerial = normalizeSerial(vlekSerial);
2140
+ if (revokedSeq && Array.isArray(revokedSeq.value)) {
2141
+ for (const entry of revokedSeq.value) {
2142
+ if (!Array.isArray(entry.value) || entry.value.length < 2) continue;
2143
+ const serialAsn1 = entry.value[0];
2144
+ if (serialAsn1.type !== import_node_forge.default.asn1.Type.INTEGER || typeof serialAsn1.value !== "string") continue;
2145
+ const serialHex = import_node_forge.default.util.bytesToHex(serialAsn1.value);
2146
+ if (normalizeSerial(serialHex) === targetSerial) {
2147
+ throw new Error("\u{1F6A8} VLEK Certificate is REVOKED per AMD CRL! This hardware may be compromised.");
2148
+ }
2149
+ }
2150
+ }
2151
+ });
2152
+ }
2153
+ function assertCertValidity(label, cert) {
2154
+ const now = Date.now();
2155
+ if (cert.notBefore && now < cert.notBefore.getTime()) {
2156
+ throw new Error(`${label} certificate is not yet valid (notBefore: ${cert.notBefore.toISOString()})`);
2157
+ }
2158
+ if (cert.notAfter && now > cert.notAfter.getTime()) {
2159
+ throw new Error(`${label} certificate expired on ${cert.notAfter.toISOString()}`);
2160
+ }
2161
+ }
2162
+ function verifyAMDChain(vlekCertBuffer) {
2163
+ return __async(this, null, function* () {
2164
+ const processors = ["Milan", "Genoa"];
2165
+ let chainVerified = false;
2166
+ const vlek = parseCert(vlekCertBuffer);
2167
+ assertCertValidity("VLEK", vlek);
2168
+ for (const processor of processors) {
2169
+ let matchedChain = false;
2170
+ try {
2171
+ const chainPem = AMD_CERTS[processor];
2172
+ if (!chainPem) continue;
2173
+ const certs = chainPem.split("-----END CERTIFICATE-----").map((c) => c.trim()).filter((c) => c.length > 0).map((c) => c + "\n-----END CERTIFICATE-----\n");
2174
+ const askCert = import_node_forge.default.pki.certificateFromPem(certs[0]);
2175
+ const arkCert = import_node_forge.default.pki.certificateFromPem(certs[1]);
2176
+ const askDer = import_node_forge.default.asn1.toDer(import_node_forge.default.pki.certificateToAsn1(askCert)).getBytes();
2177
+ const arkDer = import_node_forge.default.asn1.toDer(import_node_forge.default.pki.certificateToAsn1(arkCert)).getBytes();
2178
+ const ask = parseCert(binaryStringToUint8Array(askDer));
2179
+ const ark = parseCert(binaryStringToUint8Array(arkDer));
2180
+ assertCertValidity("ASK", ask);
2181
+ assertCertValidity("ARK", ark);
2182
+ try {
2183
+ yield verifySignature(certs[1], ark.tbsDer, ark.signature, ark.sigAlgOid);
2184
+ } catch (e) {
2185
+ throw new Error(`AMD ARK self-signature verification failed: ${e.message}`);
2186
+ }
2187
+ try {
2188
+ yield verifySignature(certs[1], ask.tbsDer, ask.signature, ask.sigAlgOid);
2189
+ } catch (e) {
2190
+ throw new Error(`AMD ASK-by-ARK signature verification failed: ${e.message}`);
2191
+ }
2192
+ try {
2193
+ yield verifySignature(certs[0], vlek.tbsDer, vlek.signature, vlek.sigAlgOid);
2194
+ } catch (e) {
2195
+ throw new Error(`VLEK-by-ASK signature verification failed: ${e.message}`);
2196
+ }
2197
+ matchedChain = true;
2198
+ let crlBuf;
2199
+ const now = Date.now();
2200
+ if (crlCache[processor] && now - crlCache[processor].fetchedAt < 36e5) {
2201
+ crlBuf = crlCache[processor].buffer;
2202
+ } else {
2203
+ const crlUrl = `https://kdsintf.amd.com/vlek/v1/${processor}/crl`;
2204
+ const controller = new AbortController();
2205
+ const timeoutId = setTimeout(() => controller.abort(), 5e3);
2206
+ const crlResp = yield fetch(crlUrl, { signal: controller.signal });
2207
+ clearTimeout(timeoutId);
2208
+ if (!crlResp.ok) continue;
2209
+ crlBuf = new Uint8Array(yield crlResp.arrayBuffer());
2210
+ crlCache[processor] = { buffer: crlBuf, fetchedAt: now };
2211
+ }
2212
+ if (vlek.serialNumber && crlBuf) {
2213
+ yield verifyCRL(crlBuf, certs[1], vlek.serialNumber);
2214
+ }
2215
+ chainVerified = true;
2216
+ break;
2217
+ } catch (e) {
2218
+ if (matchedChain) {
2219
+ throw e;
2220
+ }
2221
+ continue;
2222
+ }
2223
+ }
2224
+ if (!chainVerified) {
2225
+ throw new Error("VLEK Certificate failed verification against all known AMD Root of Trust chains!");
2226
+ }
2227
+ });
2228
+ }
2229
+ function verifyHardwareSignature(reportBytes, certBytes) {
2230
+ return __async(this, null, function* () {
2231
+ const vlek = parseCert(certBytes);
2232
+ const sigOffset = 672;
2233
+ const rLE = reportBytes.subarray(sigOffset, sigOffset + 72);
2234
+ const sLE = reportBytes.subarray(sigOffset + 72, sigOffset + 144);
2235
+ const rBE = reverseBytes(rLE);
2236
+ const sBE = reverseBytes(sLE);
2237
+ const signedData = reportBytes.subarray(0, 672);
2238
+ const cryptoSubtle = getSubtleCrypto();
2239
+ const importedKey = yield cryptoSubtle.importKey(
2240
+ "spki",
2241
+ vlek.spkiDer,
2242
+ { name: "ECDSA", namedCurve: "P-384" },
2243
+ false,
2244
+ ["verify"]
2245
+ );
2246
+ const rPadding = rBE.subarray(0, rBE.length - 48);
2247
+ const sPadding = sBE.subarray(0, sBE.length - 48);
2248
+ if (!rPadding.every((b) => b === 0) || !sPadding.every((b) => b === 0)) {
2249
+ throw new Error("Hardware ECDSA signature is malformed: non-zero padding bytes detected in the structural signature coordinates.");
2250
+ }
2251
+ const r48 = rBE.subarray(rBE.length - 48);
2252
+ const s48 = sBE.subarray(sBE.length - 48);
2253
+ const rawSignature = concatUint8Arrays([r48, s48]);
2254
+ const isValid = yield cryptoSubtle.verify(
2255
+ { name: "ECDSA", hash: { name: "SHA-384" } },
2256
+ importedKey,
2257
+ rawSignature,
2258
+ signedData
2259
+ );
2260
+ if (!isValid) {
2261
+ throw new Error("Hardware ECDSA signature is completely invalid!");
1402
2262
  }
1403
2263
  });
1404
- return assertValidProofsByHash(proofs, {
1405
- hashes: effectiveHashRequirement
2264
+ }
2265
+ function verifyReportData(teeAttestation, proofContext, report) {
2266
+ return __async(this, null, function* () {
2267
+ if (!teeAttestation.workload_digest || !teeAttestation.verifier_digest) {
2268
+ throw new Error("POLICY CHECK FAILED: Missing workload_digest or verifier_digest in TEE attestation.");
2269
+ }
2270
+ const { attestationNonce: nonce } = JSON.parse(proofContext);
2271
+ const cryptoSubtle = getSubtleCrypto();
2272
+ const extractDigestBytes = (imageRef) => {
2273
+ const marker = "@sha256:";
2274
+ const idx = imageRef.lastIndexOf(marker);
2275
+ if (idx < 0) throw new Error(`Image ref missing @sha256: digest: ${imageRef}`);
2276
+ const hexDigest = imageRef.substring(idx + marker.length);
2277
+ if (hexDigest.length !== 64) throw new Error(`SHA256 digest must be 64 hex chars, got ${hexDigest.length} in: ${imageRef}`);
2278
+ const bytes = new Uint8Array(32);
2279
+ for (let i = 0; i < 32; i++) bytes[i] = parseInt(hexDigest.substring(i * 2, i * 2 + 2), 16);
2280
+ return bytes;
2281
+ };
2282
+ const importedCosignKey = yield cryptoSubtle.importKey(
2283
+ "spki",
2284
+ base64ToUint8Array(
2285
+ COSIGN_PUBLIC_KEY.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").replace(/\s+/g, "")
2286
+ ),
2287
+ { name: "ECDSA", namedCurve: "P-256" },
2288
+ true,
2289
+ ["verify"]
2290
+ );
2291
+ const pubKeySpkiDer = yield cryptoSubtle.exportKey("spki", importedCosignKey);
2292
+ const pubKeyHashBuffer = yield cryptoSubtle.digest("SHA-256", pubKeySpkiDer);
2293
+ const pubKeyHashBytes = new Uint8Array(pubKeyHashBuffer);
2294
+ const nonceHex = (teeAttestation.nonce || nonce).replace(/^0x/i, "");
2295
+ const nonceBytes = new Uint8Array(nonceHex.length / 2);
2296
+ for (let i = 0; i < nonceBytes.length; i++) nonceBytes[i] = parseInt(nonceHex.substring(i * 2, i * 2 + 2), 16);
2297
+ const workloadBytes = extractDigestBytes(teeAttestation.workload_digest);
2298
+ const verifierBytes = extractDigestBytes(teeAttestation.verifier_digest);
2299
+ const domainSep = new TextEncoder().encode("POPCORN_TEE_REPORT_DATA_V1");
2300
+ const version = new Uint8Array([1]);
2301
+ const payload = new Uint8Array(
2302
+ domainSep.length + version.length + workloadBytes.length + verifierBytes.length + pubKeyHashBytes.length + nonceBytes.length
2303
+ );
2304
+ let offset = 0;
2305
+ for (const chunk of [domainSep, version, workloadBytes, verifierBytes, pubKeyHashBytes, nonceBytes]) {
2306
+ payload.set(chunk, offset);
2307
+ offset += chunk.length;
2308
+ }
2309
+ const hashBuffer = yield cryptoSubtle.digest("SHA-256", payload);
2310
+ const hashHex = arrayBufferToHex(hashBuffer);
2311
+ const expected64ByteHex = hashHex + hashHex;
2312
+ if (report.reportData !== expected64ByteHex) {
2313
+ throw new Error(`REPORT_DATA Mismatch! Hardware report is not bound to these image digests or nonce.
2314
+ Expected: ${expected64ByteHex}
2315
+ Got: ${report.reportData}`);
2316
+ }
1406
2317
  });
1407
2318
  }
1408
2319
 
1409
2320
  // src/Reclaim.ts
1410
- var logger8 = logger_default.logger;
2321
+ var logger10 = logger_default.logger;
1411
2322
  var sdkVersion = require_package().version;
1412
- function verifyProof(proofOrProofs, config) {
2323
+ function verifyProof(proofOrProofs, config, verifyTEE) {
1413
2324
  return __async(this, null, function* () {
2325
+ const proofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];
1414
2326
  try {
1415
- const proofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];
1416
2327
  if (proofs.length === 0) {
1417
2328
  throw new ProofNotValidatedError("No proofs provided");
1418
2329
  }
@@ -1423,14 +2334,57 @@ function verifyProof(proofOrProofs, config) {
1423
2334
  for (const proof of proofs) {
1424
2335
  yield assertVerifiedProof(proof, attestors);
1425
2336
  }
1426
- assertValidateProof(proofs, config);
1427
- return true;
2337
+ yield assertValidateProof(proofs, config);
2338
+ const result = {
2339
+ isVerified: true,
2340
+ data: proofs.map(extractProofData)
2341
+ };
2342
+ if (verifyTEE) {
2343
+ const hasTeeData = proofs.every((proof) => proof.teeAttestation || JSON.parse(proof.claimData.context).attestationNonce);
2344
+ if (!hasTeeData) {
2345
+ logger10.error("TEE verification requested but one or more proofs are missing TEE attestation data");
2346
+ result.isTeeVerified = false;
2347
+ result.isVerified = false;
2348
+ return result;
2349
+ }
2350
+ try {
2351
+ const teeResults = yield Promise.all(proofs.map((proof) => verifyTeeAttestation(proof)));
2352
+ result.isTeeVerified = teeResults.every((r) => r === true);
2353
+ if (!result.isTeeVerified) {
2354
+ logger10.error("TEE attestation verification failed for one or more proofs");
2355
+ }
2356
+ result.isVerified = result.isVerified && result.isTeeVerified;
2357
+ } catch (error) {
2358
+ logger10.error("Error verifying TEE attestation:", error);
2359
+ result.isTeeVerified = false;
2360
+ result.isVerified = false;
2361
+ }
2362
+ }
2363
+ return result;
1428
2364
  } catch (error) {
1429
- logger8.error("Error in validating proof:", error);
1430
- return false;
2365
+ logger10.error("Error in validating proof:", error);
2366
+ return {
2367
+ isVerified: false,
2368
+ data: []
2369
+ };
1431
2370
  }
1432
2371
  });
1433
2372
  }
2373
+ function extractProofData(proof) {
2374
+ try {
2375
+ const context = JSON.parse(proof.claimData.context);
2376
+ const _a = context, { extractedParameters } = _a, rest = __objRest(_a, ["extractedParameters"]);
2377
+ return {
2378
+ context: rest,
2379
+ extractedParameters: extractedParameters != null ? extractedParameters : {}
2380
+ };
2381
+ } catch (e) {
2382
+ return {
2383
+ context: {},
2384
+ extractedParameters: {}
2385
+ };
2386
+ }
2387
+ }
1434
2388
  function transformForOnchain(proof) {
1435
2389
  const claimInfoBuilder = /* @__PURE__ */ new Map([
1436
2390
  ["context", proof.claimData.context],
@@ -1529,7 +2483,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1529
2483
  };
1530
2484
  return templateData;
1531
2485
  };
1532
- var _a, _b;
2486
+ var _a, _b, _c;
1533
2487
  this.providerId = providerId;
1534
2488
  this.timeStamp = Date.now().toString();
1535
2489
  this.applicationId = applicationId;
@@ -1546,34 +2500,38 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1546
2500
  logger_default.setLogLevel("silent");
1547
2501
  }
1548
2502
  if (options.useAppClip === void 0) {
1549
- options.useAppClip = true;
2503
+ options.useAppClip = false;
1550
2504
  }
2505
+ this.customSharePageUrl = (_c = (_b = options.portalUrl) != null ? _b : options.customSharePageUrl) != null ? _c : "https://portal.reclaimprotocol.org";
2506
+ options.customSharePageUrl = this.customSharePageUrl;
1551
2507
  if (options == null ? void 0 : options.envUrl) {
1552
2508
  setBackendBaseUrl(options.envUrl);
1553
- } else if ((_b = options == null ? void 0 : options.customSharePageUrl) == null ? void 0 : _b.includes("eu.portal.reclaimprotocol.org")) {
1554
- setBackendBaseUrl("https://eu.api.reclaimprotocol.org");
2509
+ } else if (this.customSharePageUrl) {
2510
+ try {
2511
+ if (new URL(this.customSharePageUrl).hostname === "eu.portal.reclaimprotocol.org") {
2512
+ setBackendBaseUrl("https://eu.api.reclaimprotocol.org");
2513
+ }
2514
+ } catch (e) {
2515
+ }
1555
2516
  }
1556
2517
  if (options.extensionID) {
1557
2518
  this.extensionID = options.extensionID;
1558
2519
  }
1559
- if (options == null ? void 0 : options.customSharePageUrl) {
1560
- this.customSharePageUrl = options.customSharePageUrl;
1561
- }
1562
2520
  if (options == null ? void 0 : options.customAppClipUrl) {
1563
2521
  this.customAppClipUrl = options.customAppClipUrl;
1564
2522
  }
1565
2523
  this.options = options;
1566
2524
  this.sdkVersion = "js-" + sdkVersion;
1567
- logger8.info(`Initializing client with applicationId: ${this.applicationId}`);
2525
+ logger10.info(`Initializing client with applicationId: ${this.applicationId}`);
1568
2526
  }
1569
2527
  /**
1570
- * Initializes a new Reclaim proof request instance with automatic signature generation and session creation
2528
+ * Initializes a new Reclaim proof request instance with automatic signature generation and session creation.
1571
2529
  *
1572
2530
  * @param applicationId - Your Reclaim application ID
1573
2531
  * @param appSecret - Your application secret key for signing requests
1574
2532
  * @param providerId - The ID of the provider to use for proof generation
1575
2533
  * @param options - Optional configuration options for the proof request
1576
- * @returns Promise<ReclaimProofRequest> - A fully initialized proof request instance
2534
+ * @returns A fully initialized proof request instance
1577
2535
  * @throws {InitError} When initialization fails due to invalid parameters or session creation errors
1578
2536
  *
1579
2537
  * @example
@@ -1582,7 +2540,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1582
2540
  * 'your-app-id',
1583
2541
  * 'your-app-secret',
1584
2542
  * 'provider-id',
1585
- * { log: true, acceptAiProviders: true }
2543
+ * { portalUrl: 'https://portal.reclaimprotocol.org', log: true }
1586
2544
  * );
1587
2545
  * ```
1588
2546
  */
@@ -1635,6 +2593,11 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1635
2593
  { paramName: "envUrl", input: options.envUrl, isString: true }
1636
2594
  ], "the constructor");
1637
2595
  }
2596
+ if (options.portalUrl) {
2597
+ validateFunctionParams([
2598
+ { paramName: "portalUrl", input: options.portalUrl, isString: true }
2599
+ ], "the constructor");
2600
+ }
1638
2601
  if (options.customSharePageUrl) {
1639
2602
  validateFunctionParams([
1640
2603
  { paramName: "customSharePageUrl", input: options.customSharePageUrl, isString: true }
@@ -1657,7 +2620,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1657
2620
  Intl.getCanonicalLocales(options.preferredLocale);
1658
2621
  return true;
1659
2622
  } catch (error) {
1660
- logger8.info("Failed to canonicalize locale", error);
2623
+ logger10.info("Failed to canonicalize locale", error);
1661
2624
  return false;
1662
2625
  }
1663
2626
  }
@@ -1671,10 +2634,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1671
2634
  proofRequestInstance.sessionId = data.sessionId;
1672
2635
  proofRequestInstance.resolvedProviderVersion = data.resolvedProviderVersion;
1673
2636
  proofRequestInstance.context.reclaimSessionId = data.sessionId;
2637
+ if (options == null ? void 0 : options.acceptTeeAttestation) {
2638
+ const wallet = new import_ethers5.ethers.Wallet(appSecret);
2639
+ const nonceData = `${applicationId}:${data.sessionId}:${proofRequestInstance.timeStamp}`;
2640
+ const nonceMsg = import_ethers5.ethers.getBytes(import_ethers5.ethers.keccak256(new TextEncoder().encode(nonceData)));
2641
+ const nonceSignature = yield wallet.signMessage(nonceMsg);
2642
+ proofRequestInstance.setAttestationContext(nonceSignature, {
2643
+ applicationId,
2644
+ sessionId: data.sessionId,
2645
+ timestamp: proofRequestInstance.timeStamp
2646
+ });
2647
+ }
1674
2648
  return proofRequestInstance;
1675
2649
  } catch (error) {
1676
2650
  console.error(error);
1677
- logger8.info("Failed to initialize ReclaimProofRequest", error);
2651
+ logger10.info("Failed to initialize ReclaimProofRequest", error);
1678
2652
  throw new InitError("Failed to initialize ReclaimProofRequest", error);
1679
2653
  }
1680
2654
  });
@@ -1791,7 +2765,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1791
2765
  Intl.getCanonicalLocales(options.preferredLocale);
1792
2766
  return true;
1793
2767
  } catch (error) {
1794
- logger8.info("Failed to canonicalize locale", error);
2768
+ logger10.info("Failed to canonicalize locale", error);
1795
2769
  return false;
1796
2770
  }
1797
2771
  }
@@ -1800,6 +2774,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1800
2774
  const proofRequestInstance = new _ReclaimProofRequest(applicationId, providerId, options);
1801
2775
  proofRequestInstance.sessionId = sessionId;
1802
2776
  proofRequestInstance.context = context;
2777
+ proofRequestInstance.setAttestationContext(context == null ? void 0 : context.attestationNonce, context == null ? void 0 : context.attestationNonceData);
1803
2778
  proofRequestInstance.parameters = parameters;
1804
2779
  proofRequestInstance.appCallbackUrl = appCallbackUrl;
1805
2780
  proofRequestInstance.redirectUrl = redirectUrl;
@@ -1815,7 +2790,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1815
2790
  proofRequestInstance.cancelRedirectUrlOptions = cancelRedirectUrlOptions;
1816
2791
  return proofRequestInstance;
1817
2792
  } catch (error) {
1818
- logger8.info("Failed to parse JSON string in fromJsonString:", error);
2793
+ logger10.info("Failed to parse JSON string in fromJsonString:", error);
1819
2794
  throw new InvalidParamError("Invalid JSON string provided to fromJsonString");
1820
2795
  }
1821
2796
  });
@@ -1976,9 +2951,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1976
2951
  try {
1977
2952
  validateModalOptions(options, "setModalOptions");
1978
2953
  this.modalOptions = __spreadValues(__spreadValues({}, this.modalOptions), options);
1979
- logger8.info("Modal options set successfully");
2954
+ logger10.info("Modal options set successfully");
1980
2955
  } catch (error) {
1981
- logger8.info("Error setting modal options:", error);
2956
+ logger10.info("Error setting modal options:", error);
1982
2957
  throw new SetParamsError("Error setting modal options", error);
1983
2958
  }
1984
2959
  }
@@ -2006,8 +2981,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2006
2981
  { input: context, paramName: "context", isString: false }
2007
2982
  ], "setJsonContext");
2008
2983
  this.context = JSON.parse(canonicalStringify(__spreadProps(__spreadValues({}, context), { reclaimSessionId: this.sessionId })));
2984
+ this.applyAttestationContext();
2009
2985
  } catch (error) {
2010
- logger8.info("Error setting context", error);
2986
+ logger10.info("Error setting context", error);
2011
2987
  throw new SetContextError("Error setting context", error);
2012
2988
  }
2013
2989
  }
@@ -2037,8 +3013,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2037
3013
  { input: message, paramName: "message", isString: true }
2038
3014
  ], "setContext");
2039
3015
  this.context = { contextAddress: address, contextMessage: message, reclaimSessionId: this.sessionId };
3016
+ this.applyAttestationContext();
2040
3017
  } catch (error) {
2041
- logger8.info("Error setting context", error);
3018
+ logger10.info("Error setting context", error);
2042
3019
  throw new SetContextError("Error setting context", error);
2043
3020
  }
2044
3021
  }
@@ -2073,7 +3050,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2073
3050
  validateParameters(params);
2074
3051
  this.parameters = __spreadValues(__spreadValues({}, this.parameters), params);
2075
3052
  } catch (error) {
2076
- logger8.info("Error Setting Params:", error);
3053
+ logger10.info("Error Setting Params:", error);
2077
3054
  throw new SetParamsError("Error setting params", error);
2078
3055
  }
2079
3056
  }
@@ -2097,7 +3074,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2097
3074
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getAppCallbackUrl");
2098
3075
  return this.appCallbackUrl || `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`;
2099
3076
  } catch (error) {
2100
- logger8.info("Error getting app callback url", error);
3077
+ logger10.info("Error getting app callback url", error);
2101
3078
  throw new GetAppCallbackUrlError("Error getting app callback url", error);
2102
3079
  }
2103
3080
  }
@@ -2121,7 +3098,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2121
3098
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getCancelCallbackUrl");
2122
3099
  return this.cancelCallbackUrl || `${constants.DEFAULT_RECLAIM_CANCEL_CALLBACK_URL}${this.sessionId}`;
2123
3100
  } catch (error) {
2124
- logger8.info("Error getting cancel callback url", error);
3101
+ logger10.info("Error getting cancel callback url", error);
2125
3102
  throw new GetAppCallbackUrlError("Error getting cancel callback url", error);
2126
3103
  }
2127
3104
  }
@@ -2144,7 +3121,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2144
3121
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getStatusUrl");
2145
3122
  return `${constants.DEFAULT_RECLAIM_STATUS_URL}${this.sessionId}`;
2146
3123
  } catch (error) {
2147
- logger8.info("Error fetching Status Url", error);
3124
+ logger10.info("Error fetching Status Url", error);
2148
3125
  throw new GetStatusUrlError("Error fetching status url", error);
2149
3126
  }
2150
3127
  }
@@ -2174,25 +3151,25 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2174
3151
  try {
2175
3152
  validateFunctionParams([{ input: signature, paramName: "signature", isString: true }], "setSignature");
2176
3153
  this.signature = signature;
2177
- logger8.info(`Signature set successfully for applicationId: ${this.applicationId}`);
3154
+ logger10.info(`Signature set successfully for applicationId: ${this.applicationId}`);
2178
3155
  } catch (error) {
2179
- logger8.info("Error setting signature", error);
3156
+ logger10.info("Error setting signature", error);
2180
3157
  throw new SetSignatureError("Error setting signature", error);
2181
3158
  }
2182
3159
  }
2183
3160
  generateSignature(applicationSecret) {
2184
3161
  return __async(this, null, function* () {
2185
3162
  try {
2186
- const wallet = new import_ethers4.ethers.Wallet(applicationSecret);
3163
+ const wallet = new import_ethers5.ethers.Wallet(applicationSecret);
2187
3164
  const canonicalData = (0, import_canonicalize3.default)({ providerId: this.providerId, timestamp: this.timeStamp });
2188
3165
  if (!canonicalData) {
2189
3166
  throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
2190
3167
  }
2191
- const messageHash = import_ethers4.ethers.keccak256(new TextEncoder().encode(canonicalData));
2192
- return yield wallet.signMessage(import_ethers4.ethers.getBytes(messageHash));
3168
+ const messageHash = import_ethers5.ethers.keccak256(new TextEncoder().encode(canonicalData));
3169
+ return yield wallet.signMessage(import_ethers5.ethers.getBytes(messageHash));
2193
3170
  } catch (err) {
2194
- logger8.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, signature: ${this.signature}, timeStamp: ${this.timeStamp}`, err);
2195
- throw new SignatureGeneratingError(`Error generating signature for applicationSecret: ${applicationSecret}`);
3171
+ logger10.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, timeStamp: ${this.timeStamp}`);
3172
+ throw new SignatureGeneratingError(`Error generating signature for applicationId: ${this.applicationId}`);
2196
3173
  }
2197
3174
  });
2198
3175
  }
@@ -2202,12 +3179,25 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2202
3179
  this.intervals.delete(this.sessionId);
2203
3180
  }
2204
3181
  }
2205
- buildSharePageUrl(template) {
2206
- const baseUrl = "https://share.reclaimprotocol.org/verify";
2207
- if (this.customSharePageUrl) {
2208
- return `${this.customSharePageUrl}/?template=${template}`;
3182
+ setAttestationContext(nonce, data) {
3183
+ if (!nonce || !data) {
3184
+ return;
2209
3185
  }
2210
- return `${baseUrl}/?template=${template}`;
3186
+ this.attestationNonce = nonce;
3187
+ this.attestationNonceData = data;
3188
+ this.applyAttestationContext();
3189
+ }
3190
+ applyAttestationContext() {
3191
+ if (!this.attestationNonce || !this.attestationNonceData) {
3192
+ return;
3193
+ }
3194
+ this.context = __spreadProps(__spreadValues({}, this.context), {
3195
+ attestationNonce: this.attestationNonce,
3196
+ attestationNonceData: this.attestationNonceData
3197
+ });
3198
+ }
3199
+ buildSharePageUrl(template) {
3200
+ return `https://share.reclaimprotocol.org/verify/?template=${template}`;
2211
3201
  }
2212
3202
  /**
2213
3203
  * Exports the Reclaim proof verification request as a JSON string
@@ -2261,13 +3251,15 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2261
3251
  });
2262
3252
  }
2263
3253
  /**
2264
- * Generates and returns the request URL for proof verification
3254
+ * Generates and returns the request URL for proof verification.
2265
3255
  *
2266
- * This URL can be shared with users to initiate the proof generation process.
2267
- * The URL format varies based on device type:
2268
- * - Mobile iOS: Returns App Clip URL (if useAppClip is enabled)
2269
- * - Mobile Android: Returns Instant App URL (if useAppClip is enabled)
2270
- * - Desktop/Other: Returns standard verification URL
3256
+ * Defaults to portal mode. Pass `{ verificationMode: 'app' }` for native app flow URLs.
3257
+ *
3258
+ * - Portal mode (default): returns portal URL on all platforms
3259
+ * - App mode: returns share page URL on all platforms
3260
+ * - App mode + `useAppClip: true` on iOS: returns App Clip URL instead
3261
+ *
3262
+ * Falls back to `launchOptions` set at init time if not passed at call time.
2271
3263
  *
2272
3264
  * @param launchOptions - Optional launch configuration to override default behavior
2273
3265
  * @returns Promise<string> - The generated request URL
@@ -2275,59 +3267,58 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2275
3267
  *
2276
3268
  * @example
2277
3269
  * ```typescript
2278
- * const requestUrl = await proofRequest.getRequestUrl();
2279
- * // Share this URL with users or display as QR code
3270
+ * // Portal URL (default)
3271
+ * const url = await proofRequest.getRequestUrl();
3272
+ *
3273
+ * // Native app flow URL
3274
+ * const url = await proofRequest.getRequestUrl({ verificationMode: 'app' });
2280
3275
  * ```
2281
3276
  */
2282
3277
  getRequestUrl(launchOptions) {
2283
3278
  return __async(this, null, function* () {
2284
3279
  var _a, _b, _c;
2285
3280
  const options = launchOptions || ((_a = this.options) == null ? void 0 : _a.launchOptions) || {};
2286
- logger8.info("Creating Request Url");
3281
+ const mode = (_b = options.verificationMode) != null ? _b : "portal";
3282
+ logger10.info("Creating Request Url");
2287
3283
  if (!this.signature) {
2288
3284
  throw new SignatureNotFoundError("Signature is not set.");
2289
3285
  }
2290
3286
  try {
2291
3287
  const templateData = this.getTemplateData();
2292
3288
  yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2293
- const deviceType = getDeviceType();
2294
- if (((_b = this.options) == null ? void 0 : _b.useAppClip) && deviceType === "mobile" /* MOBILE */) {
3289
+ if (mode === "app") {
2295
3290
  let template = encodeURIComponent(JSON.stringify(templateData));
2296
3291
  template = replaceAll(template, "(", "%28");
2297
3292
  template = replaceAll(template, ")", "%29");
2298
- const isIos = getMobileDeviceType() === "ios" /* IOS */;
2299
- if (!isIos) {
2300
- let instantAppUrl = this.buildSharePageUrl(template);
2301
- const isDeferredDeeplinksFlowEnabled = (_c = options.canUseDeferredDeepLinksFlow) != null ? _c : false;
2302
- if (isDeferredDeeplinksFlowEnabled) {
2303
- instantAppUrl = instantAppUrl.replace("/verifier", "/link");
2304
- }
2305
- logger8.info("Instant App Url created successfully: " + instantAppUrl);
2306
- return instantAppUrl;
2307
- } else {
3293
+ if (((_c = this.options) == null ? void 0 : _c.useAppClip) && getDeviceType() === "mobile" /* MOBILE */ && getMobileDeviceType() === "ios" /* IOS */) {
2308
3294
  const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2309
- logger8.info("App Clip Url created successfully: " + appClipUrl);
3295
+ logger10.info("App Clip Url created successfully: " + appClipUrl);
2310
3296
  return appClipUrl;
2311
3297
  }
2312
- } else {
2313
- const link = yield createLinkWithTemplateData(templateData, this.customSharePageUrl);
2314
- logger8.info("Request Url created successfully: " + link);
2315
- return link;
3298
+ const sharePageUrl = yield createLinkWithTemplateData(templateData, "https://share.reclaimprotocol.org/verify");
3299
+ logger10.info("Share page Url created successfully: " + sharePageUrl);
3300
+ return sharePageUrl;
2316
3301
  }
3302
+ const link = yield createLinkWithTemplateData(templateData, this.customSharePageUrl);
3303
+ logger10.info("Request Url created successfully: " + link);
3304
+ return link;
2317
3305
  } catch (error) {
2318
- logger8.info("Error creating Request Url:", error);
3306
+ logger10.info("Error creating Request Url:", error);
2319
3307
  throw error;
2320
3308
  }
2321
3309
  });
2322
3310
  }
2323
3311
  /**
2324
- * Triggers the appropriate Reclaim verification flow based on device type and configuration
3312
+ * Triggers the appropriate Reclaim verification flow based on device type and configuration.
3313
+ *
3314
+ * Defaults to portal mode (remote browser verification). Pass `{ verificationMode: 'app' }`
3315
+ * for native app flow via the share page.
2325
3316
  *
2326
- * This method automatically detects the device type and initiates the optimal verification flow:
2327
- * - Desktop with browser extension: Triggers extension flow
2328
- * - Desktop without extension: Shows QR code modal
2329
- * - Mobile Android: Redirects to Instant App
2330
- * - Mobile iOS: Redirects to App Clip
3317
+ * - Desktop: browser extension takes priority in both modes
3318
+ * - Desktop portal mode (no extension): opens portal in new tab
3319
+ * - Desktop app mode (no extension): shows QR code modal with share page URL
3320
+ * - Mobile portal mode: opens portal in new tab
3321
+ * - Mobile app mode: opens share page (or App Clip on iOS if `useAppClip` is `true`)
2331
3322
  *
2332
3323
  * @param launchOptions - Optional launch configuration to override default behavior
2333
3324
  * @returns Promise<void>
@@ -2335,45 +3326,95 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2335
3326
  *
2336
3327
  * @example
2337
3328
  * ```typescript
3329
+ * // Portal flow (default)
2338
3330
  * await proofRequest.triggerReclaimFlow();
2339
- * // The appropriate verification method will be triggered automatically
3331
+ *
3332
+ * // Native app flow
3333
+ * await proofRequest.triggerReclaimFlow({ verificationMode: 'app' });
3334
+ *
3335
+ * // App Clip on iOS (requires useAppClip: true at init)
3336
+ * const request = await ReclaimProofRequest.init(APP_ID, SECRET, PROVIDER, { useAppClip: true });
3337
+ * await request.triggerReclaimFlow({ verificationMode: 'app' });
3338
+ *
3339
+ * // Can also set verificationMode at init time via launchOptions
3340
+ * const request = await ReclaimProofRequest.init(APP_ID, SECRET, PROVIDER, {
3341
+ * launchOptions: { verificationMode: 'app' }
3342
+ * });
3343
+ * await request.triggerReclaimFlow(); // uses 'app' mode from init
2340
3344
  * ```
2341
3345
  */
2342
3346
  triggerReclaimFlow(launchOptions) {
2343
3347
  return __async(this, null, function* () {
2344
- var _a, _b;
3348
+ var _a, _b, _c, _d, _e, _f;
2345
3349
  const options = launchOptions || ((_a = this.options) == null ? void 0 : _a.launchOptions) || {};
3350
+ const mode = (_b = options.verificationMode) != null ? _b : "portal";
2346
3351
  if (!this.signature) {
2347
3352
  throw new SignatureNotFoundError("Signature is not set.");
2348
3353
  }
2349
3354
  try {
2350
3355
  const templateData = this.getTemplateData();
2351
3356
  this.templateData = templateData;
2352
- logger8.info("Triggering Reclaim flow");
3357
+ logger10.info(`Triggering Reclaim flow (mode: ${mode})`);
2353
3358
  const deviceType = getDeviceType();
2354
3359
  updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2355
3360
  if (deviceType === "desktop" /* DESKTOP */) {
2356
3361
  const extensionAvailable = yield this.isBrowserExtensionAvailable();
2357
- if (((_b = this.options) == null ? void 0 : _b.useBrowserExtension) && extensionAvailable) {
2358
- logger8.info("Triggering browser extension flow");
3362
+ if (((_c = this.options) == null ? void 0 : _c.useBrowserExtension) && extensionAvailable) {
3363
+ logger10.info("Triggering browser extension flow");
2359
3364
  this.triggerBrowserExtensionFlow();
2360
3365
  return;
3366
+ }
3367
+ if (mode === "portal") {
3368
+ const portalUrl = (_d = this.customSharePageUrl) != null ? _d : "https://portal.reclaimprotocol.org";
3369
+ const newTab = window.open("about:blank", "_blank");
3370
+ const link = yield createLinkWithTemplateData(templateData, portalUrl);
3371
+ logger10.info("Opening portal in new tab: " + link);
3372
+ if (newTab) {
3373
+ newTab.location = link;
3374
+ setTimeout(() => {
3375
+ try {
3376
+ if (newTab.location.href === "about:blank") {
3377
+ newTab.close();
3378
+ window.open(link, "_blank");
3379
+ }
3380
+ } catch (_) {
3381
+ }
3382
+ }, 500);
3383
+ }
2361
3384
  } else {
2362
- logger8.info("Browser extension not available, showing QR code modal");
2363
- yield this.showQRCodeModal();
3385
+ logger10.info("Showing QR code modal with share page URL");
3386
+ yield this.showQRCodeModal("app");
2364
3387
  }
2365
3388
  } else if (deviceType === "mobile" /* MOBILE */) {
2366
- const mobileDeviceType = getMobileDeviceType();
2367
- if (mobileDeviceType === "android" /* ANDROID */) {
2368
- logger8.info("Redirecting to Android instant app");
2369
- yield this.redirectToInstantApp(options);
2370
- } else if (mobileDeviceType === "ios" /* IOS */) {
2371
- logger8.info("Redirecting to iOS app clip");
2372
- this.redirectToAppClip();
3389
+ if (mode === "app") {
3390
+ if (((_e = this.options) == null ? void 0 : _e.useAppClip) && getMobileDeviceType() === "ios" /* IOS */) {
3391
+ logger10.info("Redirecting to iOS app clip");
3392
+ this.redirectToAppClip();
3393
+ } else {
3394
+ logger10.info("Redirecting to share page");
3395
+ yield this.redirectToInstantApp(options);
3396
+ }
3397
+ } else {
3398
+ const portalUrl = (_f = this.customSharePageUrl) != null ? _f : "https://portal.reclaimprotocol.org";
3399
+ const newTab = window.open("about:blank", "_blank");
3400
+ const link = yield createLinkWithTemplateData(templateData, portalUrl);
3401
+ logger10.info("Opening portal on mobile: " + link);
3402
+ if (newTab) {
3403
+ newTab.location = link;
3404
+ setTimeout(() => {
3405
+ try {
3406
+ if (newTab.location.href === "about:blank") {
3407
+ newTab.close();
3408
+ window.open(link, "_blank");
3409
+ }
3410
+ } catch (_) {
3411
+ }
3412
+ }, 500);
3413
+ }
2373
3414
  }
2374
3415
  }
2375
3416
  } catch (error) {
2376
- logger8.info("Error triggering Reclaim flow:", error);
3417
+ logger10.info("Error triggering Reclaim flow:", error);
2377
3418
  throw error;
2378
3419
  }
2379
3420
  });
@@ -2421,7 +3462,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2421
3462
  window.postMessage(message, "*");
2422
3463
  });
2423
3464
  } catch (error) {
2424
- logger8.info("Error checking Reclaim extension installed:", error);
3465
+ logger10.info("Error checking Reclaim extension installed:", error);
2425
3466
  return false;
2426
3467
  }
2427
3468
  });
@@ -2434,16 +3475,17 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2434
3475
  extensionID: this.extensionID
2435
3476
  };
2436
3477
  window.postMessage(message, "*");
2437
- logger8.info("Browser extension flow triggered");
3478
+ logger10.info("Browser extension flow triggered");
2438
3479
  }
2439
- showQRCodeModal() {
3480
+ showQRCodeModal(mode = "portal") {
2440
3481
  return __async(this, null, function* () {
2441
3482
  try {
2442
- const requestUrl = yield createLinkWithTemplateData(this.templateData, this.customSharePageUrl);
3483
+ const url = mode === "app" ? "https://share.reclaimprotocol.org/verify" : this.customSharePageUrl;
3484
+ const requestUrl = yield createLinkWithTemplateData(this.templateData, url);
2443
3485
  this.modal = new QRCodeModal(this.modalOptions);
2444
3486
  yield this.modal.show(requestUrl);
2445
3487
  } catch (error) {
2446
- logger8.info("Error showing QR code modal:", error);
3488
+ logger10.info("Error showing QR code modal:", error);
2447
3489
  throw error;
2448
3490
  }
2449
3491
  });
@@ -2456,7 +3498,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2456
3498
  template = replaceAll(template, "(", "%28");
2457
3499
  template = replaceAll(template, ")", "%29");
2458
3500
  let instantAppUrl = this.buildSharePageUrl(template);
2459
- logger8.info("Redirecting to Android instant app: " + instantAppUrl);
3501
+ logger10.info("Redirecting to Android instant app: " + instantAppUrl);
2460
3502
  const isDeferredDeeplinksFlowEnabled = (_a = options.canUseDeferredDeepLinksFlow) != null ? _a : false;
2461
3503
  if (isDeferredDeeplinksFlowEnabled) {
2462
3504
  instantAppUrl = instantAppUrl.replace("/verifier", "/link");
@@ -2506,7 +3548,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2506
3548
  }
2507
3549
  window.location.href = instantAppUrl;
2508
3550
  } catch (error) {
2509
- logger8.info("Error redirecting to instant app:", error);
3551
+ logger10.info("Error redirecting to instant app:", error);
2510
3552
  throw error;
2511
3553
  }
2512
3554
  });
@@ -2517,29 +3559,49 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2517
3559
  template = replaceAll(template, "(", "%28");
2518
3560
  template = replaceAll(template, ")", "%29");
2519
3561
  const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2520
- logger8.info("Redirecting to iOS app clip: " + appClipUrl);
3562
+ logger10.info("Redirecting to iOS app clip: " + appClipUrl);
2521
3563
  const verifierUrl = `https://share.reclaimprotocol.org/verifier/?template=${template}`;
2522
3564
  window.location.href = appClipUrl;
2523
3565
  setTimeout(() => {
2524
3566
  window.location.href = verifierUrl;
2525
3567
  }, 5 * 1e3);
2526
3568
  } catch (error) {
2527
- logger8.info("Error redirecting to app clip:", error);
3569
+ logger10.info("Error redirecting to app clip:", error);
2528
3570
  throw error;
2529
3571
  }
2530
3572
  }
3573
+ /**
3574
+ * Returns the provider id and exact version of the provider that was used in the verification session of this request.
3575
+ *
3576
+ * This can be provided as a config parameter to the `verifyProof` function to verify the proof.
3577
+ *
3578
+ * See also:
3579
+ * * `verifyProof()` - Verifies a proof against the expected provider configuration.
3580
+ * * `getProviderHashRequirements()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.
3581
+ * * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.
3582
+ */
3583
+ getProviderVersion() {
3584
+ var _a, _b;
3585
+ const exactProviderVersionString = (_a = this.resolvedProviderVersion) != null ? _a : "";
3586
+ return {
3587
+ providerId: this.providerId,
3588
+ providerVersion: exactProviderVersionString,
3589
+ allowedTags: ((_b = this.options) == null ? void 0 : _b.acceptAiProviders) ? ["ai"] : []
3590
+ };
3591
+ }
2531
3592
  /**
2532
3593
  * Fetches the provider config that was used for this session and returns the hash requirements
2533
3594
  *
2534
3595
  * See also:
3596
+ * * `verifyProof()` - Verifies a proof against the expected provider configuration.
2535
3597
  * * `fetchProviderHashRequirementsBy()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.
2536
3598
  * * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.
2537
3599
  *
2538
- * @returns A promise that resolves to a ProviderHashRequirementsConfig
3600
+ * @returns A promise that resolves to a `ProviderHashRequirementsConfig` or `ProviderHashRequirementsConfig[]`
2539
3601
  */
2540
- getProviderHashRequirements() {
3602
+ getProviderHashRequirements(proofs, allowedTags) {
2541
3603
  var _a;
2542
- return fetchProviderHashRequirementsBy(this.providerId, (_a = this.resolvedProviderVersion) != null ? _a : "");
3604
+ return fetchProviderHashRequirementsBy(this.providerId, (_a = this.resolvedProviderVersion) != null ? _a : "", allowedTags, proofs);
2543
3605
  }
2544
3606
  /**
2545
3607
  * Starts the proof request session and monitors for proof submission
@@ -2581,16 +3643,16 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2581
3643
  * ```
2582
3644
  */
2583
3645
  startSession(_0) {
2584
- return __async(this, arguments, function* ({ onSuccess, onError }) {
3646
+ return __async(this, arguments, function* ({ onSuccess, onError, verificationConfig }) {
2585
3647
  if (!this.sessionId) {
2586
3648
  const message = "Session can't be started due to undefined value of sessionId";
2587
- logger8.info(message);
3649
+ logger10.info(message);
2588
3650
  throw new SessionNotStartedError(message);
2589
3651
  }
2590
- logger8.info("Starting session");
3652
+ logger10.info("Starting session");
2591
3653
  const sessionUpdatePollingInterval = 3 * 1e3;
2592
3654
  const interval = setInterval(() => __async(this, null, function* () {
2593
- var _a, _b, _c;
3655
+ var _a, _b, _c, _d, _e;
2594
3656
  try {
2595
3657
  const statusUrlResponse = yield fetchStatusUrl(this.sessionId);
2596
3658
  if (!statusUrlResponse.session) return;
@@ -2602,7 +3664,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2602
3664
  if (!this.lastFailureTime) {
2603
3665
  this.lastFailureTime = currentTime;
2604
3666
  } else if (currentTime - this.lastFailureTime >= this.FAILURE_TIMEOUT) {
2605
- throw new ProviderFailedError("Proof generation failed - timeout reached");
3667
+ const errorMessage = ((_a = statusUrlResponse.session.error) == null ? void 0 : _a.message) || "Proof generation failed - timeout reached";
3668
+ throw new ProviderFailedError(errorMessage);
2606
3669
  }
2607
3670
  return;
2608
3671
  }
@@ -2614,9 +3677,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2614
3677
  if (statusUrlResponse.session.proofs && statusUrlResponse.session.proofs.length > 0) {
2615
3678
  const proofs = statusUrlResponse.session.proofs;
2616
3679
  if (this.claimCreationType === "createClaim" /* STANDALONE */) {
2617
- const verified = yield verifyProof(proofs, yield this.getProviderHashRequirements());
3680
+ const { isVerified: verified } = yield verifyProof(proofs, this.getProviderVersion());
2618
3681
  if (!verified) {
2619
- logger8.info(`Proofs not verified: ${JSON.stringify(proofs)}`);
3682
+ logger10.info(`Proofs not verified: count=${proofs == null ? void 0 : proofs.length}`);
2620
3683
  throw new ProofNotVerifiedError();
2621
3684
  }
2622
3685
  }
@@ -2626,18 +3689,19 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2626
3689
  onSuccess(proofs);
2627
3690
  }
2628
3691
  this.clearInterval();
2629
- (_a = this.modal) == null ? void 0 : _a.close();
3692
+ (_b = this.modal) == null ? void 0 : _b.close();
2630
3693
  }
2631
3694
  } else {
2632
3695
  if (statusUrlResponse.session.statusV2 === "PROOF_SUBMISSION_FAILED" /* PROOF_SUBMISSION_FAILED */) {
2633
- throw new ProofSubmissionFailedError();
3696
+ const errorMessage = ((_c = statusUrlResponse.session.error) == null ? void 0 : _c.message) || "Proof submission failed";
3697
+ throw new ProofSubmissionFailedError(errorMessage);
2634
3698
  }
2635
3699
  if (statusUrlResponse.session.statusV2 === "PROOF_SUBMITTED" /* PROOF_SUBMITTED */ || statusUrlResponse.session.statusV2 === "AI_PROOF_SUBMITTED" /* AI_PROOF_SUBMITTED */) {
2636
3700
  if (onSuccess) {
2637
3701
  onSuccess([]);
2638
3702
  }
2639
3703
  this.clearInterval();
2640
- (_b = this.modal) == null ? void 0 : _b.close();
3704
+ (_d = this.modal) == null ? void 0 : _d.close();
2641
3705
  }
2642
3706
  }
2643
3707
  } catch (e) {
@@ -2645,7 +3709,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2645
3709
  onError(e);
2646
3710
  }
2647
3711
  this.clearInterval();
2648
- (_c = this.modal) == null ? void 0 : _c.close();
3712
+ (_e = this.modal) == null ? void 0 : _e.close();
2649
3713
  }
2650
3714
  }), sessionUpdatePollingInterval);
2651
3715
  this.intervals.set(this.sessionId, interval);
@@ -2667,7 +3731,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2667
3731
  closeModal() {
2668
3732
  if (this.modal) {
2669
3733
  this.modal.close();
2670
- logger8.info("Modal closed by user");
3734
+ logger10.info("Modal closed by user");
2671
3735
  }
2672
3736
  }
2673
3737
  /**
@@ -2693,9 +3757,10 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2693
3757
  assertVerifiedProof,
2694
3758
  clearDeviceCache,
2695
3759
  createLinkWithTemplateData,
2696
- fetchProviderConfig,
3760
+ fetchProviderConfigs,
2697
3761
  fetchProviderHashRequirementsBy,
2698
3762
  fetchStatusUrl,
3763
+ generateSpecsFromRequestSpecTemplate,
2699
3764
  getAttestors,
2700
3765
  getDeviceType,
2701
3766
  getHttpProviderClaimParamsFromProof,
@@ -2708,8 +3773,11 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2708
3773
  isHttpProviderClaimParams,
2709
3774
  isMobileDevice,
2710
3775
  recoverSignersOfSignedClaim,
3776
+ takePairsWhereValueIsArray,
3777
+ takeTemplateParametersFromProofs,
2711
3778
  transformForOnchain,
2712
3779
  updateSession,
2713
- verifyProof
3780
+ verifyProof,
3781
+ verifyTeeAttestation
2714
3782
  });
2715
3783
  //# sourceMappingURL=index.js.map