@reclaimprotocol/js-sdk 5.0.0-dev.0 → 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.0",
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
  },
@@ -177,13 +193,33 @@ var require_package = __commonJS({
177
193
  var index_exports = {};
178
194
  __export(index_exports, {
179
195
  ReclaimProofRequest: () => ReclaimProofRequest,
196
+ assertValidProofsByHash: () => assertValidProofsByHash,
197
+ assertValidateProof: () => assertValidateProof,
198
+ assertVerifiedProof: () => assertVerifiedProof,
180
199
  clearDeviceCache: () => clearDeviceCache,
200
+ createLinkWithTemplateData: () => createLinkWithTemplateData,
201
+ fetchProviderConfigs: () => fetchProviderConfigs,
202
+ fetchProviderHashRequirementsBy: () => fetchProviderHashRequirementsBy,
203
+ fetchStatusUrl: () => fetchStatusUrl,
204
+ generateSpecsFromRequestSpecTemplate: () => generateSpecsFromRequestSpecTemplate,
205
+ getAttestors: () => getAttestors,
181
206
  getDeviceType: () => getDeviceType,
207
+ getHttpProviderClaimParamsFromProof: () => getHttpProviderClaimParamsFromProof,
182
208
  getMobileDeviceType: () => getMobileDeviceType,
209
+ getProviderHashRequirementsFromSpec: () => getProviderHashRequirementsFromSpec,
210
+ getShortenedUrl: () => getShortenedUrl,
211
+ hashRequestSpec: () => hashRequestSpec,
212
+ initSession: () => initSession,
183
213
  isDesktopDevice: () => isDesktopDevice,
214
+ isHttpProviderClaimParams: () => isHttpProviderClaimParams,
184
215
  isMobileDevice: () => isMobileDevice,
216
+ recoverSignersOfSignedClaim: () => recoverSignersOfSignedClaim,
217
+ takePairsWhereValueIsArray: () => takePairsWhereValueIsArray,
218
+ takeTemplateParametersFromProofs: () => takeTemplateParametersFromProofs,
185
219
  transformForOnchain: () => transformForOnchain,
186
- verifyProof: () => verifyProof
220
+ updateSession: () => updateSession,
221
+ verifyProof: () => verifyProof,
222
+ verifyTeeAttestation: () => verifyTeeAttestation
187
223
  });
188
224
  module.exports = __toCommonJS(index_exports);
189
225
 
@@ -196,20 +232,20 @@ var RECLAIM_EXTENSION_ACTIONS = {
196
232
  };
197
233
 
198
234
  // src/Reclaim.ts
199
- var import_ethers4 = require("ethers");
235
+ var import_ethers5 = require("ethers");
200
236
  var import_canonicalize3 = __toESM(require("canonicalize"));
201
237
 
202
238
  // src/utils/errors.ts
203
239
  function createErrorClass(name) {
204
240
  return class extends Error {
205
241
  constructor(message, innerError) {
206
- 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;
207
243
  super(fullMessage);
208
244
  this.innerError = innerError;
209
245
  this.name = name;
210
246
  if (innerError) {
211
247
  this.stack += `
212
- Caused by: ${innerError.stack}`;
248
+ Caused by: ${innerError && typeof innerError === "object" && "stack" in innerError ? innerError.stack : String(innerError)}`;
213
249
  }
214
250
  }
215
251
  };
@@ -217,6 +253,7 @@ Caused by: ${innerError.stack}`;
217
253
  var TimeoutError = createErrorClass("TimeoutError");
218
254
  var ProofNotVerifiedError = createErrorClass("ProofNotVerifiedError");
219
255
  var ProofNotValidatedError = createErrorClass("ProofNotValidatedError");
256
+ var InvalidRequestSpecError = createErrorClass("InvalidRequestSpecError");
220
257
  var UnknownProofsNotValidatedError = createErrorClass("UnknownProofsNotValidatedError");
221
258
  var SessionNotStartedError = createErrorClass("SessionNotStartedError");
222
259
  var ProviderNotFoundError = createErrorClass("ProviderNotFoundError");
@@ -337,15 +374,13 @@ var constants = {
337
374
  get DEFAULT_ATTESTORS_URL() {
338
375
  return `${BACKEND_BASE_URL}/api/attestors`;
339
376
  },
340
- DEFAULT_PROVIDER_URL(providerId, exactProviderVersionString) {
341
- 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(",")) || ""}`;
342
379
  },
343
380
  // URL for sharing Reclaim templates
344
381
  RECLAIM_SHARE_URL: "https://share.reclaimprotocol.org/verifier/?template=",
345
382
  // Chrome extension URL for Reclaim Protocol
346
- CHROME_EXTENSION_URL: "https://chromewebstore.google.com/detail/reclaim-extension/oafieibbbcepkmenknelhmgaoahamdeh",
347
- // QR Code API base URL
348
- QR_CODE_API_URL: "https://api.qrserver.com/v1/create-qr-code/"
383
+ CHROME_EXTENSION_URL: "https://chromewebstore.google.com/detail/reclaim-extension/oafieibbbcepkmenknelhmgaoahamdeh"
349
384
  };
350
385
 
351
386
  // src/utils/validationUtils.ts
@@ -586,92 +621,6 @@ var http = {
586
621
  }
587
622
  };
588
623
 
589
- // src/witness.ts
590
- var import_ethers2 = require("ethers");
591
- function createSignDataForClaim(data) {
592
- const identifier = getIdentifierFromClaimInfo(data);
593
- const lines = [
594
- identifier,
595
- data.owner.toLowerCase(),
596
- data.timestampS.toString(),
597
- data.epoch.toString()
598
- ];
599
- return lines.join("\n");
600
- }
601
- function getIdentifierFromClaimInfo(info) {
602
- let canonicalContext = info.context || "";
603
- if (canonicalContext.length > 0) {
604
- try {
605
- const ctx = JSON.parse(canonicalContext);
606
- canonicalContext = canonicalStringify(ctx);
607
- } catch (e) {
608
- throw new Error("unable to parse non-empty context. Must be JSON");
609
- }
610
- }
611
- const str = `${info.provider}
612
- ${info.parameters}
613
- ${canonicalContext}`;
614
- return import_ethers2.ethers.keccak256(strToUint8Array(str)).toLowerCase();
615
- }
616
- function hashProofClaimParams(params) {
617
- const serializedParams = getProviderParamsAsCanonicalizedString(params);
618
- return import_ethers2.ethers.keccak256(
619
- strToUint8Array(serializedParams)
620
- ).toLowerCase();
621
- }
622
- function strToUint8Array(str) {
623
- return new TextEncoder().encode(str);
624
- }
625
- function getProviderParamsAsCanonicalizedString(params) {
626
- var _a, _b, _c, _d, _e, _f, _g;
627
- const filteredParams = {
628
- url: (_a = params == null ? void 0 : params.url) != null ? _a : "",
629
- // METHOD needs to be explicitly specified and absence or unknown method should cause error, but we're choosing to ignore it in this case
630
- method: (_b = params == null ? void 0 : params.method) != null ? _b : "GET",
631
- body: (_c = params == null ? void 0 : params.body) != null ? _c : "",
632
- responseMatches: (_e = (_d = params == null ? void 0 : params.responseMatches) == null ? void 0 : _d.map((it) => {
633
- var _a2, _b2;
634
- return {
635
- value: (_a2 = it.value) != null ? _a2 : "",
636
- // This needs to be explicitly specified and absence should cause error, but we're choosing to ignore it in this case
637
- type: (_b2 = it.type) != null ? _b2 : "contains",
638
- invert: it.invert || void 0,
639
- isOptional: it.isOptional || void 0
640
- };
641
- })) != null ? _e : [],
642
- responseRedactions: (_g = (_f = params == null ? void 0 : params.responseRedactions) == null ? void 0 : _f.map((it) => {
643
- var _a2, _b2, _c2;
644
- return {
645
- xPath: (_a2 = it.xPath) != null ? _a2 : "",
646
- jsonPath: (_b2 = it.jsonPath) != null ? _b2 : "",
647
- regex: (_c2 = it.regex) != null ? _c2 : "",
648
- hash: it.hash || void 0
649
- };
650
- })) != null ? _g : []
651
- };
652
- const serializedParams = canonicalStringify(filteredParams);
653
- return serializedParams;
654
- }
655
-
656
- // src/utils/providerUtils.ts
657
- function getProviderHashRequirementsFromSpec(spec) {
658
- var _a;
659
- return {
660
- hashes: ((_a = spec == null ? void 0 : spec.requests) == null ? void 0 : _a.map(hashRequestSpec)) || []
661
- };
662
- }
663
- function hashRequestSpec(request) {
664
- const hash = hashProofClaimParams(__spreadProps(__spreadValues({}, request), {
665
- // Body is strictly empty unless body sniff is explicitly enabled
666
- body: request.bodySniff.enabled ? request.bodySniff.template : ""
667
- }));
668
- return {
669
- value: hash,
670
- required: request.required,
671
- multiple: request.multiple
672
- };
673
- }
674
-
675
624
  // src/utils/sessionUtils.ts
676
625
  var logger4 = logger_default.logger;
677
626
  function initSession(providerId, appId, timestamp, signature, versionNumber) {
@@ -748,17 +697,24 @@ function fetchStatusUrl(sessionId) {
748
697
  }
749
698
  });
750
699
  }
751
- function fetchProviderConfig(providerId, exactProviderVersionString) {
700
+ function fetchProviderConfigs(providerId, exactProviderVersionString, allowedTags) {
752
701
  return __async(this, null, function* () {
753
702
  validateFunctionParams(
754
703
  [
755
- { input: providerId, paramName: "providerId", isString: true },
756
- { input: exactProviderVersionString, paramName: "exactProviderVersionString", isString: true }
704
+ { input: providerId, paramName: "providerId", isString: true }
757
705
  ],
758
- "fetchProviderConfig"
706
+ "fetchProviderConfigs"
759
707
  );
708
+ if (exactProviderVersionString != null && exactProviderVersionString != void 0) {
709
+ validateFunctionParams(
710
+ [
711
+ { input: exactProviderVersionString, paramName: "exactProviderVersionString", isString: true }
712
+ ],
713
+ "fetchProviderConfigs"
714
+ );
715
+ }
760
716
  try {
761
- 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), {
762
718
  method: "GET",
763
719
  headers: { "Content-Type": "application/json" }
764
720
  });
@@ -776,19 +732,116 @@ function fetchProviderConfig(providerId, exactProviderVersionString) {
776
732
  }
777
733
  });
778
734
  }
779
- function fetchProviderHashRequirementsBy(providerId, exactProviderVersion) {
780
- return __async(this, null, function* () {
781
- var _a, _b;
782
- const providerResponse = yield fetchProviderConfig(providerId, exactProviderVersion);
783
- const providerConfig = providerResponse.providers;
784
- return getProviderHashRequirementsFromSpec({
785
- requests: [...(_a = providerConfig == null ? void 0 : providerConfig.requestData) != null ? _a : [], ...(_b = providerConfig == null ? void 0 : providerConfig.allowedInjectedRequestData) != null ? _b : []]
786
- });
787
- });
788
- }
789
735
 
790
736
  // src/utils/proofUtils.ts
791
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
792
845
  var logger5 = logger_default.logger;
793
846
  function getShortenedUrl(url) {
794
847
  return __async(this, null, function* () {
@@ -865,6 +918,7 @@ function assertVerifiedProof(proof, attestors) {
865
918
  }
866
919
 
867
920
  // src/utils/modalUtils.ts
921
+ var import_qrcode = __toESM(require("qrcode"));
868
922
  var logger6 = logger_default.logger;
869
923
  var QRCodeModal = class {
870
924
  constructor(options = {}) {
@@ -1075,17 +1129,22 @@ var QRCodeModal = class {
1075
1129
  generateQRCode(text, containerId) {
1076
1130
  return __async(this, null, function* () {
1077
1131
  try {
1078
- 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
+ });
1079
1140
  const container = document.getElementById(containerId);
1080
1141
  const styles = this.getThemeStyles();
1081
1142
  if (container) {
1082
1143
  container.innerHTML = `
1083
- <img src="${qrCodeUrl}"
1084
- alt="QR Code for Reclaim verification"
1085
- style="width: 200px; height: 200px; border-radius: 4px;"
1086
- 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;">
1087
1147
  <div style="display: none; padding: 20px; color: ${styles.textColor}; font-size: 14px;">
1088
- QR code could not be loaded.<br>
1089
1148
  <a href="${text}" target="_blank" style="color: ${styles.linkColor}; text-decoration: underline;">
1090
1149
  Click here to open verification link
1091
1150
  </a>
@@ -1313,10 +1372,123 @@ function clearDeviceCache() {
1313
1372
  cachedMobileType = null;
1314
1373
  }
1315
1374
 
1316
- // src/utils/proofValidationUtils.ts
1375
+ // src/utils/providerUtils.ts
1317
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;
1318
1490
  var HASH_REQUIRED_DEFAULT = true;
1319
- var HASH_MATCH_MULTIPLE_DEFAULT = false;
1491
+ var HASH_MATCH_MULTIPLE_DEFAULT = true;
1320
1492
  function assertValidProofsByHash(proofs, config) {
1321
1493
  var _a, _b;
1322
1494
  if (!config.hashes) {
@@ -1326,31 +1498,36 @@ function assertValidProofsByHash(proofs, config) {
1326
1498
  for (let i = 0; i < proofs.length; i++) {
1327
1499
  const proof = proofs[i];
1328
1500
  const claimParams = getHttpProviderClaimParamsFromProof(proof);
1329
- const computedHashOfProof = hashProofClaimParams(claimParams).toLowerCase().trim();
1330
- 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);
1331
1504
  }
1332
1505
  for (const hashRequirement of config.hashes) {
1333
1506
  let found = false;
1334
- const expectedHash = hashRequirement.value.toLowerCase().trim();
1507
+ const expectedHashes = Array.isArray(hashRequirement.value) ? hashRequirement.value.map((h) => h.toLowerCase().trim()) : [hashRequirement.value.toLowerCase().trim()];
1335
1508
  const isRequired = (_a = hashRequirement.required) != null ? _a : HASH_REQUIRED_DEFAULT;
1336
1509
  const canMatchMultiple = (_b = hashRequirement.multiple) != null ? _b : HASH_MATCH_MULTIPLE_DEFAULT;
1337
- for (const [i, proofHash] of unvalidatedProofHashByIndex.entries()) {
1338
- 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) {
1339
1513
  unvalidatedProofHashByIndex.delete(i);
1340
1514
  if (!found) {
1341
1515
  found = true;
1342
1516
  } else if (!canMatchMultiple) {
1343
- 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`);
1344
1519
  }
1345
1520
  }
1346
1521
  }
1347
1522
  if (!found && isRequired) {
1348
- 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`);
1349
1525
  }
1350
1526
  }
1351
1527
  if (unvalidatedProofHashByIndex.size > 0) {
1352
1528
  const contactSupport = "Please contact Reclaim Protocol Support team or mail us at support@reclaimprotocol.org.";
1353
- 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}`);
1354
1531
  }
1355
1532
  }
1356
1533
  var allowedHttpMethods = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
@@ -1359,7 +1536,7 @@ function isHttpProviderClaimParams(claimParams) {
1359
1536
  return false;
1360
1537
  }
1361
1538
  const params = claimParams;
1362
- 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);
1363
1540
  }
1364
1541
  function getHttpProviderClaimParamsFromProof(proof) {
1365
1542
  try {
@@ -1372,31 +1549,781 @@ function getHttpProviderClaimParamsFromProof(proof) {
1372
1549
  throw new ProofNotValidatedError("Proof has no HTTP provider params to hash");
1373
1550
  }
1374
1551
  function assertValidateProof(proofs, config) {
1375
- if ("dangerouslyDisableContentValidation" in config && config.dangerouslyDisableContentValidation) {
1376
- logger7.warn("Validation skipped because it was disabled during proof verification");
1377
- 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);
1378
1761
  }
1379
- const effectiveHashRequirement = ("hashes" in config && Array.isArray(config == null ? void 0 : config.hashes) ? config.hashes : []).map((it) => {
1380
- if (typeof it == "string") {
1381
- return {
1382
- value: it
1383
- };
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" };
1384
1884
  } else {
1385
- 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!");
1386
2262
  }
1387
2263
  });
1388
- return assertValidProofsByHash(proofs, {
1389
- 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
+ }
1390
2317
  });
1391
2318
  }
1392
2319
 
1393
2320
  // src/Reclaim.ts
1394
- var logger8 = logger_default.logger;
2321
+ var logger10 = logger_default.logger;
1395
2322
  var sdkVersion = require_package().version;
1396
- function verifyProof(proofOrProofs, config) {
2323
+ function verifyProof(proofOrProofs, config, verifyTEE) {
1397
2324
  return __async(this, null, function* () {
2325
+ const proofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];
1398
2326
  try {
1399
- const proofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];
1400
2327
  if (proofs.length === 0) {
1401
2328
  throw new ProofNotValidatedError("No proofs provided");
1402
2329
  }
@@ -1407,14 +2334,57 @@ function verifyProof(proofOrProofs, config) {
1407
2334
  for (const proof of proofs) {
1408
2335
  yield assertVerifiedProof(proof, attestors);
1409
2336
  }
1410
- assertValidateProof(proofs, config);
1411
- 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;
1412
2364
  } catch (error) {
1413
- logger8.error("Error in validating proof:", error);
1414
- return false;
2365
+ logger10.error("Error in validating proof:", error);
2366
+ return {
2367
+ isVerified: false,
2368
+ data: []
2369
+ };
1415
2370
  }
1416
2371
  });
1417
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
+ }
1418
2388
  function transformForOnchain(proof) {
1419
2389
  const claimInfoBuilder = /* @__PURE__ */ new Map([
1420
2390
  ["context", proof.claimData.context],
@@ -1513,7 +2483,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1513
2483
  };
1514
2484
  return templateData;
1515
2485
  };
1516
- var _a, _b;
2486
+ var _a, _b, _c;
1517
2487
  this.providerId = providerId;
1518
2488
  this.timeStamp = Date.now().toString();
1519
2489
  this.applicationId = applicationId;
@@ -1530,34 +2500,38 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1530
2500
  logger_default.setLogLevel("silent");
1531
2501
  }
1532
2502
  if (options.useAppClip === void 0) {
1533
- options.useAppClip = true;
2503
+ options.useAppClip = false;
1534
2504
  }
2505
+ this.customSharePageUrl = (_c = (_b = options.portalUrl) != null ? _b : options.customSharePageUrl) != null ? _c : "https://portal.reclaimprotocol.org";
2506
+ options.customSharePageUrl = this.customSharePageUrl;
1535
2507
  if (options == null ? void 0 : options.envUrl) {
1536
2508
  setBackendBaseUrl(options.envUrl);
1537
- } else if ((_b = options == null ? void 0 : options.customSharePageUrl) == null ? void 0 : _b.includes("eu.portal.reclaimprotocol.org")) {
1538
- 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
+ }
1539
2516
  }
1540
2517
  if (options.extensionID) {
1541
2518
  this.extensionID = options.extensionID;
1542
2519
  }
1543
- if (options == null ? void 0 : options.customSharePageUrl) {
1544
- this.customSharePageUrl = options.customSharePageUrl;
1545
- }
1546
2520
  if (options == null ? void 0 : options.customAppClipUrl) {
1547
2521
  this.customAppClipUrl = options.customAppClipUrl;
1548
2522
  }
1549
2523
  this.options = options;
1550
2524
  this.sdkVersion = "js-" + sdkVersion;
1551
- logger8.info(`Initializing client with applicationId: ${this.applicationId}`);
2525
+ logger10.info(`Initializing client with applicationId: ${this.applicationId}`);
1552
2526
  }
1553
2527
  /**
1554
- * 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.
1555
2529
  *
1556
2530
  * @param applicationId - Your Reclaim application ID
1557
2531
  * @param appSecret - Your application secret key for signing requests
1558
2532
  * @param providerId - The ID of the provider to use for proof generation
1559
2533
  * @param options - Optional configuration options for the proof request
1560
- * @returns Promise<ReclaimProofRequest> - A fully initialized proof request instance
2534
+ * @returns A fully initialized proof request instance
1561
2535
  * @throws {InitError} When initialization fails due to invalid parameters or session creation errors
1562
2536
  *
1563
2537
  * @example
@@ -1566,7 +2540,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1566
2540
  * 'your-app-id',
1567
2541
  * 'your-app-secret',
1568
2542
  * 'provider-id',
1569
- * { log: true, acceptAiProviders: true }
2543
+ * { portalUrl: 'https://portal.reclaimprotocol.org', log: true }
1570
2544
  * );
1571
2545
  * ```
1572
2546
  */
@@ -1619,6 +2593,11 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1619
2593
  { paramName: "envUrl", input: options.envUrl, isString: true }
1620
2594
  ], "the constructor");
1621
2595
  }
2596
+ if (options.portalUrl) {
2597
+ validateFunctionParams([
2598
+ { paramName: "portalUrl", input: options.portalUrl, isString: true }
2599
+ ], "the constructor");
2600
+ }
1622
2601
  if (options.customSharePageUrl) {
1623
2602
  validateFunctionParams([
1624
2603
  { paramName: "customSharePageUrl", input: options.customSharePageUrl, isString: true }
@@ -1641,7 +2620,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1641
2620
  Intl.getCanonicalLocales(options.preferredLocale);
1642
2621
  return true;
1643
2622
  } catch (error) {
1644
- logger8.info("Failed to canonicalize locale", error);
2623
+ logger10.info("Failed to canonicalize locale", error);
1645
2624
  return false;
1646
2625
  }
1647
2626
  }
@@ -1655,10 +2634,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1655
2634
  proofRequestInstance.sessionId = data.sessionId;
1656
2635
  proofRequestInstance.resolvedProviderVersion = data.resolvedProviderVersion;
1657
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
+ }
1658
2648
  return proofRequestInstance;
1659
2649
  } catch (error) {
1660
2650
  console.error(error);
1661
- logger8.info("Failed to initialize ReclaimProofRequest", error);
2651
+ logger10.info("Failed to initialize ReclaimProofRequest", error);
1662
2652
  throw new InitError("Failed to initialize ReclaimProofRequest", error);
1663
2653
  }
1664
2654
  });
@@ -1775,7 +2765,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1775
2765
  Intl.getCanonicalLocales(options.preferredLocale);
1776
2766
  return true;
1777
2767
  } catch (error) {
1778
- logger8.info("Failed to canonicalize locale", error);
2768
+ logger10.info("Failed to canonicalize locale", error);
1779
2769
  return false;
1780
2770
  }
1781
2771
  }
@@ -1784,6 +2774,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1784
2774
  const proofRequestInstance = new _ReclaimProofRequest(applicationId, providerId, options);
1785
2775
  proofRequestInstance.sessionId = sessionId;
1786
2776
  proofRequestInstance.context = context;
2777
+ proofRequestInstance.setAttestationContext(context == null ? void 0 : context.attestationNonce, context == null ? void 0 : context.attestationNonceData);
1787
2778
  proofRequestInstance.parameters = parameters;
1788
2779
  proofRequestInstance.appCallbackUrl = appCallbackUrl;
1789
2780
  proofRequestInstance.redirectUrl = redirectUrl;
@@ -1799,7 +2790,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1799
2790
  proofRequestInstance.cancelRedirectUrlOptions = cancelRedirectUrlOptions;
1800
2791
  return proofRequestInstance;
1801
2792
  } catch (error) {
1802
- logger8.info("Failed to parse JSON string in fromJsonString:", error);
2793
+ logger10.info("Failed to parse JSON string in fromJsonString:", error);
1803
2794
  throw new InvalidParamError("Invalid JSON string provided to fromJsonString");
1804
2795
  }
1805
2796
  });
@@ -1960,9 +2951,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1960
2951
  try {
1961
2952
  validateModalOptions(options, "setModalOptions");
1962
2953
  this.modalOptions = __spreadValues(__spreadValues({}, this.modalOptions), options);
1963
- logger8.info("Modal options set successfully");
2954
+ logger10.info("Modal options set successfully");
1964
2955
  } catch (error) {
1965
- logger8.info("Error setting modal options:", error);
2956
+ logger10.info("Error setting modal options:", error);
1966
2957
  throw new SetParamsError("Error setting modal options", error);
1967
2958
  }
1968
2959
  }
@@ -1990,8 +2981,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1990
2981
  { input: context, paramName: "context", isString: false }
1991
2982
  ], "setJsonContext");
1992
2983
  this.context = JSON.parse(canonicalStringify(__spreadProps(__spreadValues({}, context), { reclaimSessionId: this.sessionId })));
2984
+ this.applyAttestationContext();
1993
2985
  } catch (error) {
1994
- logger8.info("Error setting context", error);
2986
+ logger10.info("Error setting context", error);
1995
2987
  throw new SetContextError("Error setting context", error);
1996
2988
  }
1997
2989
  }
@@ -2021,8 +3013,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2021
3013
  { input: message, paramName: "message", isString: true }
2022
3014
  ], "setContext");
2023
3015
  this.context = { contextAddress: address, contextMessage: message, reclaimSessionId: this.sessionId };
3016
+ this.applyAttestationContext();
2024
3017
  } catch (error) {
2025
- logger8.info("Error setting context", error);
3018
+ logger10.info("Error setting context", error);
2026
3019
  throw new SetContextError("Error setting context", error);
2027
3020
  }
2028
3021
  }
@@ -2057,7 +3050,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2057
3050
  validateParameters(params);
2058
3051
  this.parameters = __spreadValues(__spreadValues({}, this.parameters), params);
2059
3052
  } catch (error) {
2060
- logger8.info("Error Setting Params:", error);
3053
+ logger10.info("Error Setting Params:", error);
2061
3054
  throw new SetParamsError("Error setting params", error);
2062
3055
  }
2063
3056
  }
@@ -2081,7 +3074,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2081
3074
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getAppCallbackUrl");
2082
3075
  return this.appCallbackUrl || `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`;
2083
3076
  } catch (error) {
2084
- logger8.info("Error getting app callback url", error);
3077
+ logger10.info("Error getting app callback url", error);
2085
3078
  throw new GetAppCallbackUrlError("Error getting app callback url", error);
2086
3079
  }
2087
3080
  }
@@ -2105,7 +3098,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2105
3098
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getCancelCallbackUrl");
2106
3099
  return this.cancelCallbackUrl || `${constants.DEFAULT_RECLAIM_CANCEL_CALLBACK_URL}${this.sessionId}`;
2107
3100
  } catch (error) {
2108
- logger8.info("Error getting cancel callback url", error);
3101
+ logger10.info("Error getting cancel callback url", error);
2109
3102
  throw new GetAppCallbackUrlError("Error getting cancel callback url", error);
2110
3103
  }
2111
3104
  }
@@ -2128,7 +3121,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2128
3121
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getStatusUrl");
2129
3122
  return `${constants.DEFAULT_RECLAIM_STATUS_URL}${this.sessionId}`;
2130
3123
  } catch (error) {
2131
- logger8.info("Error fetching Status Url", error);
3124
+ logger10.info("Error fetching Status Url", error);
2132
3125
  throw new GetStatusUrlError("Error fetching status url", error);
2133
3126
  }
2134
3127
  }
@@ -2158,25 +3151,25 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2158
3151
  try {
2159
3152
  validateFunctionParams([{ input: signature, paramName: "signature", isString: true }], "setSignature");
2160
3153
  this.signature = signature;
2161
- logger8.info(`Signature set successfully for applicationId: ${this.applicationId}`);
3154
+ logger10.info(`Signature set successfully for applicationId: ${this.applicationId}`);
2162
3155
  } catch (error) {
2163
- logger8.info("Error setting signature", error);
3156
+ logger10.info("Error setting signature", error);
2164
3157
  throw new SetSignatureError("Error setting signature", error);
2165
3158
  }
2166
3159
  }
2167
3160
  generateSignature(applicationSecret) {
2168
3161
  return __async(this, null, function* () {
2169
3162
  try {
2170
- const wallet = new import_ethers4.ethers.Wallet(applicationSecret);
3163
+ const wallet = new import_ethers5.ethers.Wallet(applicationSecret);
2171
3164
  const canonicalData = (0, import_canonicalize3.default)({ providerId: this.providerId, timestamp: this.timeStamp });
2172
3165
  if (!canonicalData) {
2173
3166
  throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
2174
3167
  }
2175
- const messageHash = import_ethers4.ethers.keccak256(new TextEncoder().encode(canonicalData));
2176
- 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));
2177
3170
  } catch (err) {
2178
- logger8.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, signature: ${this.signature}, timeStamp: ${this.timeStamp}`, err);
2179
- 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}`);
2180
3173
  }
2181
3174
  });
2182
3175
  }
@@ -2186,12 +3179,25 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2186
3179
  this.intervals.delete(this.sessionId);
2187
3180
  }
2188
3181
  }
2189
- buildSharePageUrl(template) {
2190
- const baseUrl = "https://share.reclaimprotocol.org/verify";
2191
- if (this.customSharePageUrl) {
2192
- return `${this.customSharePageUrl}/?template=${template}`;
3182
+ setAttestationContext(nonce, data) {
3183
+ if (!nonce || !data) {
3184
+ return;
2193
3185
  }
2194
- 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}`;
2195
3201
  }
2196
3202
  /**
2197
3203
  * Exports the Reclaim proof verification request as a JSON string
@@ -2245,13 +3251,15 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2245
3251
  });
2246
3252
  }
2247
3253
  /**
2248
- * Generates and returns the request URL for proof verification
3254
+ * Generates and returns the request URL for proof verification.
2249
3255
  *
2250
- * This URL can be shared with users to initiate the proof generation process.
2251
- * The URL format varies based on device type:
2252
- * - Mobile iOS: Returns App Clip URL (if useAppClip is enabled)
2253
- * - Mobile Android: Returns Instant App URL (if useAppClip is enabled)
2254
- * - 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.
2255
3263
  *
2256
3264
  * @param launchOptions - Optional launch configuration to override default behavior
2257
3265
  * @returns Promise<string> - The generated request URL
@@ -2259,59 +3267,58 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2259
3267
  *
2260
3268
  * @example
2261
3269
  * ```typescript
2262
- * const requestUrl = await proofRequest.getRequestUrl();
2263
- * // 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' });
2264
3275
  * ```
2265
3276
  */
2266
3277
  getRequestUrl(launchOptions) {
2267
3278
  return __async(this, null, function* () {
2268
3279
  var _a, _b, _c;
2269
3280
  const options = launchOptions || ((_a = this.options) == null ? void 0 : _a.launchOptions) || {};
2270
- logger8.info("Creating Request Url");
3281
+ const mode = (_b = options.verificationMode) != null ? _b : "portal";
3282
+ logger10.info("Creating Request Url");
2271
3283
  if (!this.signature) {
2272
3284
  throw new SignatureNotFoundError("Signature is not set.");
2273
3285
  }
2274
3286
  try {
2275
3287
  const templateData = this.getTemplateData();
2276
3288
  yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2277
- const deviceType = getDeviceType();
2278
- if (((_b = this.options) == null ? void 0 : _b.useAppClip) && deviceType === "mobile" /* MOBILE */) {
3289
+ if (mode === "app") {
2279
3290
  let template = encodeURIComponent(JSON.stringify(templateData));
2280
3291
  template = replaceAll(template, "(", "%28");
2281
3292
  template = replaceAll(template, ")", "%29");
2282
- const isIos = getMobileDeviceType() === "ios" /* IOS */;
2283
- if (!isIos) {
2284
- let instantAppUrl = this.buildSharePageUrl(template);
2285
- const isDeferredDeeplinksFlowEnabled = (_c = options.canUseDeferredDeepLinksFlow) != null ? _c : false;
2286
- if (isDeferredDeeplinksFlowEnabled) {
2287
- instantAppUrl = instantAppUrl.replace("/verifier", "/link");
2288
- }
2289
- logger8.info("Instant App Url created successfully: " + instantAppUrl);
2290
- return instantAppUrl;
2291
- } else {
3293
+ if (((_c = this.options) == null ? void 0 : _c.useAppClip) && getDeviceType() === "mobile" /* MOBILE */ && getMobileDeviceType() === "ios" /* IOS */) {
2292
3294
  const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2293
- logger8.info("App Clip Url created successfully: " + appClipUrl);
3295
+ logger10.info("App Clip Url created successfully: " + appClipUrl);
2294
3296
  return appClipUrl;
2295
3297
  }
2296
- } else {
2297
- const link = yield createLinkWithTemplateData(templateData, this.customSharePageUrl);
2298
- logger8.info("Request Url created successfully: " + link);
2299
- 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;
2300
3301
  }
3302
+ const link = yield createLinkWithTemplateData(templateData, this.customSharePageUrl);
3303
+ logger10.info("Request Url created successfully: " + link);
3304
+ return link;
2301
3305
  } catch (error) {
2302
- logger8.info("Error creating Request Url:", error);
3306
+ logger10.info("Error creating Request Url:", error);
2303
3307
  throw error;
2304
3308
  }
2305
3309
  });
2306
3310
  }
2307
3311
  /**
2308
- * 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.
2309
3316
  *
2310
- * This method automatically detects the device type and initiates the optimal verification flow:
2311
- * - Desktop with browser extension: Triggers extension flow
2312
- * - Desktop without extension: Shows QR code modal
2313
- * - Mobile Android: Redirects to Instant App
2314
- * - 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`)
2315
3322
  *
2316
3323
  * @param launchOptions - Optional launch configuration to override default behavior
2317
3324
  * @returns Promise<void>
@@ -2319,45 +3326,95 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2319
3326
  *
2320
3327
  * @example
2321
3328
  * ```typescript
3329
+ * // Portal flow (default)
2322
3330
  * await proofRequest.triggerReclaimFlow();
2323
- * // 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
2324
3344
  * ```
2325
3345
  */
2326
3346
  triggerReclaimFlow(launchOptions) {
2327
3347
  return __async(this, null, function* () {
2328
- var _a, _b;
3348
+ var _a, _b, _c, _d, _e, _f;
2329
3349
  const options = launchOptions || ((_a = this.options) == null ? void 0 : _a.launchOptions) || {};
3350
+ const mode = (_b = options.verificationMode) != null ? _b : "portal";
2330
3351
  if (!this.signature) {
2331
3352
  throw new SignatureNotFoundError("Signature is not set.");
2332
3353
  }
2333
3354
  try {
2334
3355
  const templateData = this.getTemplateData();
2335
3356
  this.templateData = templateData;
2336
- logger8.info("Triggering Reclaim flow");
3357
+ logger10.info(`Triggering Reclaim flow (mode: ${mode})`);
2337
3358
  const deviceType = getDeviceType();
2338
3359
  updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2339
3360
  if (deviceType === "desktop" /* DESKTOP */) {
2340
3361
  const extensionAvailable = yield this.isBrowserExtensionAvailable();
2341
- if (((_b = this.options) == null ? void 0 : _b.useBrowserExtension) && extensionAvailable) {
2342
- logger8.info("Triggering browser extension flow");
3362
+ if (((_c = this.options) == null ? void 0 : _c.useBrowserExtension) && extensionAvailable) {
3363
+ logger10.info("Triggering browser extension flow");
2343
3364
  this.triggerBrowserExtensionFlow();
2344
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
+ }
2345
3384
  } else {
2346
- logger8.info("Browser extension not available, showing QR code modal");
2347
- yield this.showQRCodeModal();
3385
+ logger10.info("Showing QR code modal with share page URL");
3386
+ yield this.showQRCodeModal("app");
2348
3387
  }
2349
3388
  } else if (deviceType === "mobile" /* MOBILE */) {
2350
- const mobileDeviceType = getMobileDeviceType();
2351
- if (mobileDeviceType === "android" /* ANDROID */) {
2352
- logger8.info("Redirecting to Android instant app");
2353
- yield this.redirectToInstantApp(options);
2354
- } else if (mobileDeviceType === "ios" /* IOS */) {
2355
- logger8.info("Redirecting to iOS app clip");
2356
- 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
+ }
2357
3414
  }
2358
3415
  }
2359
3416
  } catch (error) {
2360
- logger8.info("Error triggering Reclaim flow:", error);
3417
+ logger10.info("Error triggering Reclaim flow:", error);
2361
3418
  throw error;
2362
3419
  }
2363
3420
  });
@@ -2405,7 +3462,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2405
3462
  window.postMessage(message, "*");
2406
3463
  });
2407
3464
  } catch (error) {
2408
- logger8.info("Error checking Reclaim extension installed:", error);
3465
+ logger10.info("Error checking Reclaim extension installed:", error);
2409
3466
  return false;
2410
3467
  }
2411
3468
  });
@@ -2418,16 +3475,17 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2418
3475
  extensionID: this.extensionID
2419
3476
  };
2420
3477
  window.postMessage(message, "*");
2421
- logger8.info("Browser extension flow triggered");
3478
+ logger10.info("Browser extension flow triggered");
2422
3479
  }
2423
- showQRCodeModal() {
3480
+ showQRCodeModal(mode = "portal") {
2424
3481
  return __async(this, null, function* () {
2425
3482
  try {
2426
- 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);
2427
3485
  this.modal = new QRCodeModal(this.modalOptions);
2428
3486
  yield this.modal.show(requestUrl);
2429
3487
  } catch (error) {
2430
- logger8.info("Error showing QR code modal:", error);
3488
+ logger10.info("Error showing QR code modal:", error);
2431
3489
  throw error;
2432
3490
  }
2433
3491
  });
@@ -2440,7 +3498,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2440
3498
  template = replaceAll(template, "(", "%28");
2441
3499
  template = replaceAll(template, ")", "%29");
2442
3500
  let instantAppUrl = this.buildSharePageUrl(template);
2443
- logger8.info("Redirecting to Android instant app: " + instantAppUrl);
3501
+ logger10.info("Redirecting to Android instant app: " + instantAppUrl);
2444
3502
  const isDeferredDeeplinksFlowEnabled = (_a = options.canUseDeferredDeepLinksFlow) != null ? _a : false;
2445
3503
  if (isDeferredDeeplinksFlowEnabled) {
2446
3504
  instantAppUrl = instantAppUrl.replace("/verifier", "/link");
@@ -2490,7 +3548,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2490
3548
  }
2491
3549
  window.location.href = instantAppUrl;
2492
3550
  } catch (error) {
2493
- logger8.info("Error redirecting to instant app:", error);
3551
+ logger10.info("Error redirecting to instant app:", error);
2494
3552
  throw error;
2495
3553
  }
2496
3554
  });
@@ -2501,29 +3559,49 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2501
3559
  template = replaceAll(template, "(", "%28");
2502
3560
  template = replaceAll(template, ")", "%29");
2503
3561
  const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2504
- logger8.info("Redirecting to iOS app clip: " + appClipUrl);
3562
+ logger10.info("Redirecting to iOS app clip: " + appClipUrl);
2505
3563
  const verifierUrl = `https://share.reclaimprotocol.org/verifier/?template=${template}`;
2506
3564
  window.location.href = appClipUrl;
2507
3565
  setTimeout(() => {
2508
3566
  window.location.href = verifierUrl;
2509
3567
  }, 5 * 1e3);
2510
3568
  } catch (error) {
2511
- logger8.info("Error redirecting to app clip:", error);
3569
+ logger10.info("Error redirecting to app clip:", error);
2512
3570
  throw error;
2513
3571
  }
2514
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
+ }
2515
3592
  /**
2516
3593
  * Fetches the provider config that was used for this session and returns the hash requirements
2517
3594
  *
2518
3595
  * See also:
3596
+ * * `verifyProof()` - Verifies a proof against the expected provider configuration.
2519
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.
2520
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.
2521
3599
  *
2522
- * @returns A promise that resolves to a ProviderHashRequirementsConfig
3600
+ * @returns A promise that resolves to a `ProviderHashRequirementsConfig` or `ProviderHashRequirementsConfig[]`
2523
3601
  */
2524
- getProviderHashRequirements() {
3602
+ getProviderHashRequirements(proofs, allowedTags) {
2525
3603
  var _a;
2526
- return fetchProviderHashRequirementsBy(this.providerId, (_a = this.resolvedProviderVersion) != null ? _a : "");
3604
+ return fetchProviderHashRequirementsBy(this.providerId, (_a = this.resolvedProviderVersion) != null ? _a : "", allowedTags, proofs);
2527
3605
  }
2528
3606
  /**
2529
3607
  * Starts the proof request session and monitors for proof submission
@@ -2565,16 +3643,16 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2565
3643
  * ```
2566
3644
  */
2567
3645
  startSession(_0) {
2568
- return __async(this, arguments, function* ({ onSuccess, onError }) {
3646
+ return __async(this, arguments, function* ({ onSuccess, onError, verificationConfig }) {
2569
3647
  if (!this.sessionId) {
2570
3648
  const message = "Session can't be started due to undefined value of sessionId";
2571
- logger8.info(message);
3649
+ logger10.info(message);
2572
3650
  throw new SessionNotStartedError(message);
2573
3651
  }
2574
- logger8.info("Starting session");
3652
+ logger10.info("Starting session");
2575
3653
  const sessionUpdatePollingInterval = 3 * 1e3;
2576
3654
  const interval = setInterval(() => __async(this, null, function* () {
2577
- var _a, _b, _c;
3655
+ var _a, _b, _c, _d, _e;
2578
3656
  try {
2579
3657
  const statusUrlResponse = yield fetchStatusUrl(this.sessionId);
2580
3658
  if (!statusUrlResponse.session) return;
@@ -2586,7 +3664,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2586
3664
  if (!this.lastFailureTime) {
2587
3665
  this.lastFailureTime = currentTime;
2588
3666
  } else if (currentTime - this.lastFailureTime >= this.FAILURE_TIMEOUT) {
2589
- 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);
2590
3669
  }
2591
3670
  return;
2592
3671
  }
@@ -2598,9 +3677,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2598
3677
  if (statusUrlResponse.session.proofs && statusUrlResponse.session.proofs.length > 0) {
2599
3678
  const proofs = statusUrlResponse.session.proofs;
2600
3679
  if (this.claimCreationType === "createClaim" /* STANDALONE */) {
2601
- const verified = yield verifyProof(proofs, yield this.getProviderHashRequirements());
3680
+ const { isVerified: verified } = yield verifyProof(proofs, this.getProviderVersion());
2602
3681
  if (!verified) {
2603
- logger8.info(`Proofs not verified: ${JSON.stringify(proofs)}`);
3682
+ logger10.info(`Proofs not verified: count=${proofs == null ? void 0 : proofs.length}`);
2604
3683
  throw new ProofNotVerifiedError();
2605
3684
  }
2606
3685
  }
@@ -2610,18 +3689,19 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2610
3689
  onSuccess(proofs);
2611
3690
  }
2612
3691
  this.clearInterval();
2613
- (_a = this.modal) == null ? void 0 : _a.close();
3692
+ (_b = this.modal) == null ? void 0 : _b.close();
2614
3693
  }
2615
3694
  } else {
2616
3695
  if (statusUrlResponse.session.statusV2 === "PROOF_SUBMISSION_FAILED" /* PROOF_SUBMISSION_FAILED */) {
2617
- throw new ProofSubmissionFailedError();
3696
+ const errorMessage = ((_c = statusUrlResponse.session.error) == null ? void 0 : _c.message) || "Proof submission failed";
3697
+ throw new ProofSubmissionFailedError(errorMessage);
2618
3698
  }
2619
3699
  if (statusUrlResponse.session.statusV2 === "PROOF_SUBMITTED" /* PROOF_SUBMITTED */ || statusUrlResponse.session.statusV2 === "AI_PROOF_SUBMITTED" /* AI_PROOF_SUBMITTED */) {
2620
3700
  if (onSuccess) {
2621
3701
  onSuccess([]);
2622
3702
  }
2623
3703
  this.clearInterval();
2624
- (_b = this.modal) == null ? void 0 : _b.close();
3704
+ (_d = this.modal) == null ? void 0 : _d.close();
2625
3705
  }
2626
3706
  }
2627
3707
  } catch (e) {
@@ -2629,7 +3709,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2629
3709
  onError(e);
2630
3710
  }
2631
3711
  this.clearInterval();
2632
- (_c = this.modal) == null ? void 0 : _c.close();
3712
+ (_e = this.modal) == null ? void 0 : _e.close();
2633
3713
  }
2634
3714
  }), sessionUpdatePollingInterval);
2635
3715
  this.intervals.set(this.sessionId, interval);
@@ -2651,7 +3731,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2651
3731
  closeModal() {
2652
3732
  if (this.modal) {
2653
3733
  this.modal.close();
2654
- logger8.info("Modal closed by user");
3734
+ logger10.info("Modal closed by user");
2655
3735
  }
2656
3736
  }
2657
3737
  /**
@@ -2672,12 +3752,32 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2672
3752
  // Annotate the CommonJS export names for ESM import in node:
2673
3753
  0 && (module.exports = {
2674
3754
  ReclaimProofRequest,
3755
+ assertValidProofsByHash,
3756
+ assertValidateProof,
3757
+ assertVerifiedProof,
2675
3758
  clearDeviceCache,
3759
+ createLinkWithTemplateData,
3760
+ fetchProviderConfigs,
3761
+ fetchProviderHashRequirementsBy,
3762
+ fetchStatusUrl,
3763
+ generateSpecsFromRequestSpecTemplate,
3764
+ getAttestors,
2676
3765
  getDeviceType,
3766
+ getHttpProviderClaimParamsFromProof,
2677
3767
  getMobileDeviceType,
3768
+ getProviderHashRequirementsFromSpec,
3769
+ getShortenedUrl,
3770
+ hashRequestSpec,
3771
+ initSession,
2678
3772
  isDesktopDevice,
3773
+ isHttpProviderClaimParams,
2679
3774
  isMobileDevice,
3775
+ recoverSignersOfSignedClaim,
3776
+ takePairsWhereValueIsArray,
3777
+ takeTemplateParametersFromProofs,
2680
3778
  transformForOnchain,
2681
- verifyProof
3779
+ updateSession,
3780
+ verifyProof,
3781
+ verifyTeeAttestation
2682
3782
  });
2683
3783
  //# sourceMappingURL=index.js.map