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