@reclaimprotocol/js-sdk 4.11.0 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
- var __defProps = Object.defineProperties;
5
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
8
6
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
7
  var __getProtoOf = Object.getPrototypeOf;
@@ -21,7 +19,6 @@ var __spreadValues = (a, b) => {
21
19
  }
22
20
  return a;
23
21
  };
24
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
22
  var __commonJS = (cb, mod) => function __require() {
26
23
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
27
24
  };
@@ -72,7 +69,7 @@ var require_package = __commonJS({
72
69
  "package.json"(exports2, module2) {
73
70
  module2.exports = {
74
71
  name: "@reclaimprotocol/js-sdk",
75
- version: "4.11.0",
72
+ version: "4.12.0",
76
73
  description: "Designed to request proofs from the Reclaim protocol and manage the flow of claims and witness interactions.",
77
74
  main: "dist/index.js",
78
75
  types: "dist/index.d.ts",
@@ -146,22 +143,23 @@ var require_package = __commonJS({
146
143
  devDependencies: {
147
144
  "@commitlint/cli": "^17.7.1",
148
145
  "@commitlint/config-conventional": "^17.7.0",
146
+ "@release-it/conventional-changelog": "^10.0.1",
149
147
  "@types/jest": "^30.0.0",
150
148
  "@types/qs": "^6.9.11",
151
149
  "@types/url-parse": "^1.4.11",
152
150
  "@types/uuid": "^9.0.7",
153
151
  jest: "^30.1.3",
154
152
  "jest-environment-jsdom": "^30.1.2",
153
+ qs: "^6.11.2",
154
+ "release-it": "^19.0.4",
155
155
  "ts-jest": "^29.4.1",
156
156
  tsup: "^8.0.1",
157
157
  typescript: "^5.3.3"
158
158
  },
159
159
  dependencies: {
160
- "@release-it/conventional-changelog": "^10.0.1",
161
160
  canonicalize: "^2.0.0",
162
161
  ethers: "^6.9.1",
163
- qs: "^6.11.2",
164
- "release-it": "^19.0.4",
162
+ "fetch-retry": "^6.0.0",
165
163
  "url-parse": "^1.5.10",
166
164
  uuid: "^9.0.1"
167
165
  },
@@ -175,11 +173,8 @@ var require_package = __commonJS({
175
173
  // src/index.ts
176
174
  var index_exports = {};
177
175
  __export(index_exports, {
178
- ClaimCreationType: () => ClaimCreationType,
179
- DeviceType: () => DeviceType,
180
- RECLAIM_EXTENSION_ACTIONS: () => RECLAIM_EXTENSION_ACTIONS,
181
176
  ReclaimProofRequest: () => ReclaimProofRequest,
182
- SessionStatus: () => SessionStatus,
177
+ assertValidProof: () => assertValidProof,
183
178
  clearDeviceCache: () => clearDeviceCache,
184
179
  getDeviceType: () => getDeviceType,
185
180
  getMobileDeviceType: () => getMobileDeviceType,
@@ -198,108 +193,8 @@ var RECLAIM_EXTENSION_ACTIONS = {
198
193
  STATUS_UPDATE: "RECLAIM_STATUS_UPDATE"
199
194
  };
200
195
 
201
- // src/witness.ts
202
- var import_ethers = require("ethers");
203
-
204
- // src/utils/strings.ts
205
- var import_canonicalize = __toESM(require("canonicalize"));
206
- function canonicalStringify(params) {
207
- if (!params) {
208
- return "";
209
- }
210
- return (0, import_canonicalize.default)(params) || "";
211
- }
212
-
213
- // src/witness.ts
214
- function fetchWitnessListForClaim({ witnesses, witnessesRequiredForClaim, epoch }, params, timestampS) {
215
- const identifier = typeof params === "string" ? params : getIdentifierFromClaimInfo(params);
216
- const completeInput = [
217
- identifier,
218
- epoch.toString(),
219
- witnessesRequiredForClaim.toString(),
220
- timestampS.toString()
221
- ].join("\n");
222
- const completeHashStr = import_ethers.ethers.keccak256(strToUint8Array(completeInput));
223
- const completeHash = import_ethers.ethers.getBytes(completeHashStr);
224
- const completeHashView = uint8ArrayToDataView(completeHash);
225
- const witnessesLeft = [...witnesses];
226
- const selectedWitnesses = [];
227
- let byteOffset = 0;
228
- for (let i = 0; i < witnessesRequiredForClaim; i++) {
229
- const randomSeed = completeHashView.getUint32(byteOffset);
230
- const witnessIndex = randomSeed % witnessesLeft.length;
231
- const witness = witnessesLeft[witnessIndex];
232
- selectedWitnesses.push(witness);
233
- witnessesLeft[witnessIndex] = witnessesLeft[witnessesLeft.length - 1];
234
- witnessesLeft.pop();
235
- byteOffset = (byteOffset + 4) % completeHash.length;
236
- }
237
- return selectedWitnesses;
238
- }
239
- function getIdentifierFromClaimInfo(info) {
240
- let canonicalContext = info.context || "";
241
- if (canonicalContext.length > 0) {
242
- try {
243
- const ctx = JSON.parse(canonicalContext);
244
- canonicalContext = canonicalStringify(ctx);
245
- } catch (e) {
246
- throw new Error("unable to parse non-empty context. Must be JSON");
247
- }
248
- }
249
- const str = `${info.provider}
250
- ${info.parameters}
251
- ${canonicalContext}`;
252
- return import_ethers.ethers.keccak256(strToUint8Array(str)).toLowerCase();
253
- }
254
- function strToUint8Array(str) {
255
- return new TextEncoder().encode(str);
256
- }
257
- function uint8ArrayToDataView(arr) {
258
- return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
259
- }
260
- function createSignDataForClaim(data) {
261
- const identifier = "identifier" in data ? data.identifier : getIdentifierFromClaimInfo(data);
262
- const lines = [
263
- identifier,
264
- data.owner.toLowerCase(),
265
- data.timestampS.toString(),
266
- data.epoch.toString()
267
- ];
268
- return lines.join("\n");
269
- }
270
-
271
- // src/utils/types.ts
272
- var ClaimCreationType = /* @__PURE__ */ ((ClaimCreationType2) => {
273
- ClaimCreationType2["STANDALONE"] = "createClaim";
274
- ClaimCreationType2["ON_ME_CHAIN"] = "createClaimOnMechain";
275
- return ClaimCreationType2;
276
- })(ClaimCreationType || {});
277
- var DeviceType = /* @__PURE__ */ ((DeviceType2) => {
278
- DeviceType2["ANDROID"] = "android";
279
- DeviceType2["IOS"] = "ios";
280
- DeviceType2["DESKTOP"] = "desktop";
281
- DeviceType2["MOBILE"] = "mobile";
282
- return DeviceType2;
283
- })(DeviceType || {});
284
- var SessionStatus = /* @__PURE__ */ ((SessionStatus2) => {
285
- SessionStatus2["SESSION_INIT"] = "SESSION_INIT";
286
- SessionStatus2["SESSION_STARTED"] = "SESSION_STARTED";
287
- SessionStatus2["USER_INIT_VERIFICATION"] = "USER_INIT_VERIFICATION";
288
- SessionStatus2["USER_STARTED_VERIFICATION"] = "USER_STARTED_VERIFICATION";
289
- SessionStatus2["PROOF_GENERATION_STARTED"] = "PROOF_GENERATION_STARTED";
290
- SessionStatus2["PROOF_GENERATION_SUCCESS"] = "PROOF_GENERATION_SUCCESS";
291
- SessionStatus2["PROOF_GENERATION_FAILED"] = "PROOF_GENERATION_FAILED";
292
- SessionStatus2["PROOF_SUBMITTED"] = "PROOF_SUBMITTED";
293
- SessionStatus2["AI_PROOF_SUBMITTED"] = "AI_PROOF_SUBMITTED";
294
- SessionStatus2["PROOF_SUBMISSION_FAILED"] = "PROOF_SUBMISSION_FAILED";
295
- SessionStatus2["ERROR_SUBMITTED"] = "ERROR_SUBMITTED";
296
- SessionStatus2["ERROR_SUBMISSION_FAILED"] = "ERROR_SUBMISSION_FAILED";
297
- SessionStatus2["PROOF_MANUAL_VERIFICATION_SUBMITED"] = "PROOF_MANUAL_VERIFICATION_SUBMITED";
298
- return SessionStatus2;
299
- })(SessionStatus || {});
300
-
301
196
  // src/Reclaim.ts
302
- var import_ethers6 = require("ethers");
197
+ var import_ethers4 = require("ethers");
303
198
  var import_canonicalize3 = __toESM(require("canonicalize"));
304
199
 
305
200
  // src/utils/errors.ts
@@ -432,6 +327,9 @@ var constants = {
432
327
  get DEFAULT_RECLAIM_STATUS_URL() {
433
328
  return `${BACKEND_BASE_URL}/api/sdk/session/`;
434
329
  },
330
+ get DEFAULT_ATTESTORS_URL() {
331
+ return `${BACKEND_BASE_URL}/api/attestors`;
332
+ },
435
333
  // URL for sharing Reclaim templates
436
334
  RECLAIM_SHARE_URL: "https://share.reclaimprotocol.org/verifier/?template=",
437
335
  // Chrome extension URL for Reclaim Protocol
@@ -441,8 +339,19 @@ var constants = {
441
339
  };
442
340
 
443
341
  // src/utils/validationUtils.ts
444
- var import_ethers2 = require("ethers");
342
+ var import_ethers = require("ethers");
445
343
  var import_canonicalize2 = __toESM(require("canonicalize"));
344
+
345
+ // src/utils/strings.ts
346
+ var import_canonicalize = __toESM(require("canonicalize"));
347
+ function canonicalStringify(params) {
348
+ if (!params) {
349
+ return "";
350
+ }
351
+ return (0, import_canonicalize.default)(params) || "";
352
+ }
353
+
354
+ // src/utils/validationUtils.ts
446
355
  var logger3 = logger_default.logger;
447
356
  function validateFunctionParams(params, functionName) {
448
357
  params.forEach(({ input, paramName, isString }) => {
@@ -534,12 +443,12 @@ function validateSignature(providerId, signature, applicationId, timestamp) {
534
443
  logger3.info("Failed to canonicalize message for signature validation");
535
444
  throw new Error("Failed to canonicalize message");
536
445
  }
537
- const messageHash = import_ethers2.ethers.keccak256(new TextEncoder().encode(message));
538
- let appId = import_ethers2.ethers.verifyMessage(
539
- import_ethers2.ethers.getBytes(messageHash),
540
- import_ethers2.ethers.hexlify(signature)
446
+ const messageHash = import_ethers.ethers.keccak256(new TextEncoder().encode(message));
447
+ let appId = import_ethers.ethers.verifyMessage(
448
+ import_ethers.ethers.getBytes(messageHash),
449
+ import_ethers.ethers.hexlify(signature)
541
450
  ).toLowerCase();
542
- if (import_ethers2.ethers.getAddress(appId) !== import_ethers2.ethers.getAddress(applicationId)) {
451
+ if (import_ethers.ethers.getAddress(appId) !== import_ethers.ethers.getAddress(applicationId)) {
543
452
  logger3.info(`Signature validation failed: Mismatch between derived appId (${appId}) and provided applicationId (${applicationId})`);
544
453
  throw new InvalidSignatureError(`Signature does not match the application id: ${appId}`);
545
454
  }
@@ -621,13 +530,59 @@ function validateModalOptions(modalOptions, functionName, paramPrefix = "") {
621
530
  }
622
531
  }
623
532
 
533
+ // src/utils/fetch.ts
534
+ var import_fetch_retry = __toESM(require("fetch-retry"));
535
+ var MAX_RETRIES = 3;
536
+ var MAX_RETRY_DELAY_MS = 60 * 1e3;
537
+ var isHttpResponseStatusRetryable = (statusCode) => {
538
+ return statusCode === 408 || statusCode === 429 || statusCode >= 500;
539
+ };
540
+ var getRetryDelay = (response) => {
541
+ const retryAfter = response == null ? void 0 : response.headers.get("Retry-After");
542
+ if (!retryAfter) {
543
+ return void 0;
544
+ }
545
+ const trimmed = retryAfter.trim();
546
+ if (/^\d+$/.test(trimmed)) {
547
+ return Math.min(parseInt(trimmed, 10) * 1e3, MAX_RETRY_DELAY_MS);
548
+ }
549
+ const date = new Date(trimmed);
550
+ if (!isNaN(date.getTime())) {
551
+ return Math.min(Math.max(0, date.getTime() - Date.now()), MAX_RETRY_DELAY_MS);
552
+ }
553
+ return void 0;
554
+ };
555
+ var http = {
556
+ get client() {
557
+ return (0, import_fetch_retry.default)(globalThis.fetch, {
558
+ retries: MAX_RETRIES,
559
+ retryDelay: function(attempt, _, response) {
560
+ const delay = getRetryDelay(response);
561
+ if (delay !== void 0) {
562
+ return delay;
563
+ }
564
+ return Math.pow(2, attempt) * 1e3;
565
+ },
566
+ retryOn: (attempt, error, response) => {
567
+ if (attempt >= MAX_RETRIES) {
568
+ return false;
569
+ }
570
+ if (response && Number.isInteger(response.status)) {
571
+ return isHttpResponseStatusRetryable(response.status);
572
+ }
573
+ return !!error && error.name !== "AbortError";
574
+ }
575
+ });
576
+ }
577
+ };
578
+
624
579
  // src/utils/sessionUtils.ts
625
580
  var logger4 = logger_default.logger;
626
581
  function initSession(providerId, appId, timestamp, signature, versionNumber) {
627
582
  return __async(this, null, function* () {
628
583
  logger4.info(`Initializing session for providerId: ${providerId}, appId: ${appId}`);
629
584
  try {
630
- const response = yield fetch(`${BACKEND_BASE_URL}/api/sdk/init/session/`, {
585
+ const response = yield http.client(`${BACKEND_BASE_URL}/api/sdk/init/session/`, {
631
586
  method: "POST",
632
587
  headers: { "Content-Type": "application/json" },
633
588
  body: JSON.stringify({ providerId, appId, timestamp, signature, versionNumber })
@@ -652,7 +607,7 @@ function updateSession(sessionId, status) {
652
607
  "updateSession"
653
608
  );
654
609
  try {
655
- const response = yield fetch(`${BACKEND_BASE_URL}/api/sdk/update/session/`, {
610
+ const response = yield http.client(`${BACKEND_BASE_URL}/api/sdk/update/session/`, {
656
611
  method: "POST",
657
612
  headers: { "Content-Type": "application/json" },
658
613
  body: JSON.stringify({ sessionId, status })
@@ -679,7 +634,7 @@ function fetchStatusUrl(sessionId) {
679
634
  "fetchStatusUrl"
680
635
  );
681
636
  try {
682
- const response = yield fetch(`${constants.DEFAULT_RECLAIM_STATUS_URL}${sessionId}`, {
637
+ const response = yield http.client(`${constants.DEFAULT_RECLAIM_STATUS_URL}${sessionId}`, {
683
638
  method: "GET",
684
639
  headers: { "Content-Type": "application/json" }
685
640
  });
@@ -699,629 +654,37 @@ function fetchStatusUrl(sessionId) {
699
654
  }
700
655
 
701
656
  // src/utils/proofUtils.ts
702
- var import_ethers5 = require("ethers");
703
-
704
- // src/contract-types/contracts/factories/Reclaim__factory.ts
705
657
  var import_ethers3 = require("ethers");
706
- var _abi = [
707
- {
708
- anonymous: false,
709
- inputs: [
710
- {
711
- indexed: false,
712
- internalType: "address",
713
- name: "previousAdmin",
714
- type: "address"
715
- },
716
- {
717
- indexed: false,
718
- internalType: "address",
719
- name: "newAdmin",
720
- type: "address"
721
- }
722
- ],
723
- name: "AdminChanged",
724
- type: "event"
725
- },
726
- {
727
- anonymous: false,
728
- inputs: [
729
- {
730
- indexed: true,
731
- internalType: "address",
732
- name: "beacon",
733
- type: "address"
734
- }
735
- ],
736
- name: "BeaconUpgraded",
737
- type: "event"
738
- },
739
- {
740
- anonymous: false,
741
- inputs: [
742
- {
743
- components: [
744
- {
745
- internalType: "uint32",
746
- name: "id",
747
- type: "uint32"
748
- },
749
- {
750
- internalType: "uint32",
751
- name: "timestampStart",
752
- type: "uint32"
753
- },
754
- {
755
- internalType: "uint32",
756
- name: "timestampEnd",
757
- type: "uint32"
758
- },
759
- {
760
- components: [
761
- {
762
- internalType: "address",
763
- name: "addr",
764
- type: "address"
765
- },
766
- {
767
- internalType: "string",
768
- name: "host",
769
- type: "string"
770
- }
771
- ],
772
- internalType: "struct Reclaim.Witness[]",
773
- name: "witnesses",
774
- type: "tuple[]"
775
- },
776
- {
777
- internalType: "uint8",
778
- name: "minimumWitnessesForClaimCreation",
779
- type: "uint8"
780
- }
781
- ],
782
- indexed: false,
783
- internalType: "struct Reclaim.Epoch",
784
- name: "epoch",
785
- type: "tuple"
786
- }
787
- ],
788
- name: "EpochAdded",
789
- type: "event"
790
- },
791
- {
792
- anonymous: false,
793
- inputs: [
794
- {
795
- indexed: false,
796
- internalType: "uint8",
797
- name: "version",
798
- type: "uint8"
799
- }
800
- ],
801
- name: "Initialized",
802
- type: "event"
803
- },
804
- {
805
- anonymous: false,
806
- inputs: [
807
- {
808
- indexed: true,
809
- internalType: "address",
810
- name: "previousOwner",
811
- type: "address"
812
- },
813
- {
814
- indexed: true,
815
- internalType: "address",
816
- name: "newOwner",
817
- type: "address"
818
- }
819
- ],
820
- name: "OwnershipTransferred",
821
- type: "event"
822
- },
823
- {
824
- anonymous: false,
825
- inputs: [
826
- {
827
- indexed: true,
828
- internalType: "address",
829
- name: "implementation",
830
- type: "address"
831
- }
832
- ],
833
- name: "Upgraded",
834
- type: "event"
835
- },
836
- {
837
- inputs: [
838
- {
839
- internalType: "address",
840
- name: "witnessAddress",
841
- type: "address"
842
- },
843
- {
844
- internalType: "string",
845
- name: "host",
846
- type: "string"
847
- }
848
- ],
849
- name: "addAsWitness",
850
- outputs: [],
851
- stateMutability: "nonpayable",
852
- type: "function"
853
- },
854
- {
855
- inputs: [],
856
- name: "addNewEpoch",
857
- outputs: [],
858
- stateMutability: "nonpayable",
859
- type: "function"
860
- },
861
- {
862
- inputs: [
863
- {
864
- internalType: "uint32",
865
- name: "epochNum",
866
- type: "uint32"
867
- },
868
- {
869
- components: [
870
- {
871
- internalType: "string",
872
- name: "provider",
873
- type: "string"
874
- },
875
- {
876
- internalType: "string",
877
- name: "parameters",
878
- type: "string"
879
- },
880
- {
881
- internalType: "string",
882
- name: "context",
883
- type: "string"
884
- }
885
- ],
886
- internalType: "struct Claims.ClaimInfo",
887
- name: "claimInfo",
888
- type: "tuple"
889
- },
890
- {
891
- components: [
892
- {
893
- internalType: "bytes32",
894
- name: "identifier",
895
- type: "bytes32"
896
- },
897
- {
898
- internalType: "address",
899
- name: "owner",
900
- type: "address"
901
- },
902
- {
903
- internalType: "uint32",
904
- name: "timestampS",
905
- type: "uint32"
906
- },
907
- {
908
- internalType: "uint256",
909
- name: "epoch",
910
- type: "uint256"
911
- }
912
- ],
913
- internalType: "struct Claims.CompleteClaimData",
914
- name: "claimData",
915
- type: "tuple"
916
- },
917
- {
918
- internalType: "bytes[]",
919
- name: "signatures",
920
- type: "bytes[]"
921
- }
922
- ],
923
- name: "assertValidEpochAndSignedClaim",
924
- outputs: [],
925
- stateMutability: "view",
926
- type: "function"
927
- },
928
- {
929
- inputs: [],
930
- name: "currentEpoch",
931
- outputs: [
932
- {
933
- internalType: "uint32",
934
- name: "",
935
- type: "uint32"
936
- }
937
- ],
938
- stateMutability: "view",
939
- type: "function"
940
- },
941
- {
942
- inputs: [],
943
- name: "epochDurationS",
944
- outputs: [
945
- {
946
- internalType: "uint32",
947
- name: "",
948
- type: "uint32"
949
- }
950
- ],
951
- stateMutability: "view",
952
- type: "function"
953
- },
954
- {
955
- inputs: [
956
- {
957
- internalType: "uint256",
958
- name: "",
959
- type: "uint256"
960
- }
961
- ],
962
- name: "epochs",
963
- outputs: [
964
- {
965
- internalType: "uint32",
966
- name: "id",
967
- type: "uint32"
968
- },
969
- {
970
- internalType: "uint32",
971
- name: "timestampStart",
972
- type: "uint32"
973
- },
974
- {
975
- internalType: "uint32",
976
- name: "timestampEnd",
977
- type: "uint32"
978
- },
979
- {
980
- internalType: "uint8",
981
- name: "minimumWitnessesForClaimCreation",
982
- type: "uint8"
983
- }
984
- ],
985
- stateMutability: "view",
986
- type: "function"
987
- },
988
- {
989
- inputs: [
990
- {
991
- internalType: "uint32",
992
- name: "epoch",
993
- type: "uint32"
994
- }
995
- ],
996
- name: "fetchEpoch",
997
- outputs: [
998
- {
999
- components: [
1000
- {
1001
- internalType: "uint32",
1002
- name: "id",
1003
- type: "uint32"
1004
- },
1005
- {
1006
- internalType: "uint32",
1007
- name: "timestampStart",
1008
- type: "uint32"
1009
- },
1010
- {
1011
- internalType: "uint32",
1012
- name: "timestampEnd",
1013
- type: "uint32"
1014
- },
1015
- {
1016
- components: [
1017
- {
1018
- internalType: "address",
1019
- name: "addr",
1020
- type: "address"
1021
- },
1022
- {
1023
- internalType: "string",
1024
- name: "host",
1025
- type: "string"
1026
- }
1027
- ],
1028
- internalType: "struct Reclaim.Witness[]",
1029
- name: "witnesses",
1030
- type: "tuple[]"
1031
- },
1032
- {
1033
- internalType: "uint8",
1034
- name: "minimumWitnessesForClaimCreation",
1035
- type: "uint8"
1036
- }
1037
- ],
1038
- internalType: "struct Reclaim.Epoch",
1039
- name: "",
1040
- type: "tuple"
1041
- }
1042
- ],
1043
- stateMutability: "view",
1044
- type: "function"
1045
- },
1046
- {
1047
- inputs: [
1048
- {
1049
- internalType: "uint32",
1050
- name: "epoch",
1051
- type: "uint32"
1052
- },
1053
- {
1054
- internalType: "bytes32",
1055
- name: "identifier",
1056
- type: "bytes32"
1057
- },
1058
- {
1059
- internalType: "uint32",
1060
- name: "timestampS",
1061
- type: "uint32"
1062
- }
1063
- ],
1064
- name: "fetchWitnessesForClaim",
1065
- outputs: [
1066
- {
1067
- components: [
1068
- {
1069
- internalType: "address",
1070
- name: "addr",
1071
- type: "address"
1072
- },
1073
- {
1074
- internalType: "string",
1075
- name: "host",
1076
- type: "string"
1077
- }
1078
- ],
1079
- internalType: "struct Reclaim.Witness[]",
1080
- name: "",
1081
- type: "tuple[]"
1082
- }
1083
- ],
1084
- stateMutability: "view",
1085
- type: "function"
1086
- },
1087
- {
1088
- inputs: [],
1089
- name: "initialize",
1090
- outputs: [],
1091
- stateMutability: "nonpayable",
1092
- type: "function"
1093
- },
1094
- {
1095
- inputs: [],
1096
- name: "minimumWitnessesForClaimCreation",
1097
- outputs: [
1098
- {
1099
- internalType: "uint8",
1100
- name: "",
1101
- type: "uint8"
1102
- }
1103
- ],
1104
- stateMutability: "view",
1105
- type: "function"
1106
- },
1107
- {
1108
- inputs: [],
1109
- name: "owner",
1110
- outputs: [
1111
- {
1112
- internalType: "address",
1113
- name: "",
1114
- type: "address"
1115
- }
1116
- ],
1117
- stateMutability: "view",
1118
- type: "function"
1119
- },
1120
- {
1121
- inputs: [],
1122
- name: "proxiableUUID",
1123
- outputs: [
1124
- {
1125
- internalType: "bytes32",
1126
- name: "",
1127
- type: "bytes32"
1128
- }
1129
- ],
1130
- stateMutability: "view",
1131
- type: "function"
1132
- },
1133
- {
1134
- inputs: [
1135
- {
1136
- internalType: "address",
1137
- name: "witnessAddress",
1138
- type: "address"
1139
- }
1140
- ],
1141
- name: "removeAsWitness",
1142
- outputs: [],
1143
- stateMutability: "nonpayable",
1144
- type: "function"
1145
- },
1146
- {
1147
- inputs: [],
1148
- name: "renounceOwnership",
1149
- outputs: [],
1150
- stateMutability: "nonpayable",
1151
- type: "function"
1152
- },
1153
- {
1154
- inputs: [
1155
- {
1156
- internalType: "address",
1157
- name: "newOwner",
1158
- type: "address"
1159
- }
1160
- ],
1161
- name: "transferOwnership",
1162
- outputs: [],
1163
- stateMutability: "nonpayable",
1164
- type: "function"
1165
- },
1166
- {
1167
- inputs: [
1168
- {
1169
- internalType: "address",
1170
- name: "addr",
1171
- type: "address"
1172
- },
1173
- {
1174
- internalType: "bool",
1175
- name: "isWhitelisted",
1176
- type: "bool"
1177
- }
1178
- ],
1179
- name: "updateWitnessWhitelist",
1180
- outputs: [],
1181
- stateMutability: "nonpayable",
1182
- type: "function"
1183
- },
1184
- {
1185
- inputs: [
1186
- {
1187
- internalType: "address",
1188
- name: "newImplementation",
1189
- type: "address"
1190
- }
1191
- ],
1192
- name: "upgradeTo",
1193
- outputs: [],
1194
- stateMutability: "nonpayable",
1195
- type: "function"
1196
- },
1197
- {
1198
- inputs: [
1199
- {
1200
- internalType: "address",
1201
- name: "newImplementation",
1202
- type: "address"
1203
- },
1204
- {
1205
- internalType: "bytes",
1206
- name: "data",
1207
- type: "bytes"
1208
- }
1209
- ],
1210
- name: "upgradeToAndCall",
1211
- outputs: [],
1212
- stateMutability: "payable",
1213
- type: "function"
1214
- },
1215
- {
1216
- inputs: [
1217
- {
1218
- internalType: "uint256",
1219
- name: "",
1220
- type: "uint256"
1221
- }
1222
- ],
1223
- name: "witnesses",
1224
- outputs: [
1225
- {
1226
- internalType: "address",
1227
- name: "addr",
1228
- type: "address"
1229
- },
1230
- {
1231
- internalType: "string",
1232
- name: "host",
1233
- type: "string"
1234
- }
1235
- ],
1236
- stateMutability: "view",
1237
- type: "function"
1238
- }
1239
- ];
1240
- var Reclaim__factory = class {
1241
- static connect(address, signerOrProvider) {
1242
- return new import_ethers3.Contract(address, _abi, signerOrProvider);
1243
- }
1244
- };
1245
- Reclaim__factory.abi = _abi;
1246
658
 
1247
- // src/contract-types/config.json
1248
- var config_default = {
1249
- "0x1a4": {
1250
- chainName: "opt-goerli",
1251
- address: "0xF93F605142Fb1Efad7Aa58253dDffF67775b4520",
1252
- rpcUrl: "https://opt-goerli.g.alchemy.com/v2/rksDkSUXd2dyk2ANy_zzODknx_AAokui"
1253
- },
1254
- "0xaa37dc": {
1255
- chainName: "opt-sepolia",
1256
- address: "0x6D0f81BDA11995f25921aAd5B43359630E65Ca96",
1257
- rpcUrl: "https://opt-sepolia.g.alchemy.com/v2/aO1-SfG4oFRLyAiLREqzyAUu0HTCwHgs"
1258
- }
1259
- };
1260
-
1261
- // src/smart-contract.ts
1262
- var import_ethers4 = require("ethers");
1263
- var DEFAULT_CHAIN_ID = 11155420;
1264
- function makeBeacon(chainId) {
1265
- chainId = chainId || DEFAULT_CHAIN_ID;
1266
- const contract = getContract(chainId);
1267
- if (contract) {
1268
- let _a;
1269
- return makeBeaconCacheable({
1270
- getState(epochId) {
1271
- return __async(this, null, function* () {
1272
- const epoch = yield contract.fetchEpoch(epochId || 0);
1273
- if (!epoch.id) {
1274
- throw new Error(`Invalid epoch ID: ${epochId}`);
1275
- }
1276
- return {
1277
- epoch: epoch.id,
1278
- witnesses: epoch.witnesses.map((w) => ({
1279
- id: w.addr.toLowerCase(),
1280
- url: w.host
1281
- })),
1282
- witnessesRequiredForClaim: epoch.minimumWitnessesForClaimCreation,
1283
- nextEpochTimestampS: epoch.timestampEnd
1284
- };
1285
- });
1286
- }
1287
- });
1288
- } else {
1289
- return void 0;
1290
- }
1291
- }
1292
- function makeBeaconCacheable(beacon) {
1293
- const cache = {};
1294
- return __spreadProps(__spreadValues({}, beacon), {
1295
- getState(epochId) {
1296
- return __async(this, null, function* () {
1297
- if (!epochId) {
1298
- const state = yield beacon.getState();
1299
- return state;
1300
- }
1301
- const key = epochId;
1302
- if (!cache[key]) {
1303
- cache[key] = beacon.getState(epochId);
1304
- }
1305
- return cache[key];
1306
- });
1307
- }
1308
- });
659
+ // src/witness.ts
660
+ var import_ethers2 = require("ethers");
661
+ function createSignDataForClaim(data) {
662
+ const identifier = "identifier" in data ? data.identifier : getIdentifierFromClaimInfo(data);
663
+ const lines = [
664
+ identifier,
665
+ data.owner.toLowerCase(),
666
+ data.timestampS.toString(),
667
+ data.epoch.toString()
668
+ ];
669
+ return lines.join("\n");
1309
670
  }
1310
- var existingContractsMap = {};
1311
- function getContract(chainId) {
1312
- const chainKey = `0x${chainId.toString(16)}`;
1313
- if (!existingContractsMap[chainKey]) {
1314
- const contractData = config_default[chainKey];
1315
- if (!contractData) {
1316
- throw new Error(`Unsupported chain: "${chainKey}"`);
671
+ function getIdentifierFromClaimInfo(info) {
672
+ let canonicalContext = info.context || "";
673
+ if (canonicalContext.length > 0) {
674
+ try {
675
+ const ctx = JSON.parse(canonicalContext);
676
+ canonicalContext = canonicalStringify(ctx);
677
+ } catch (e) {
678
+ throw new Error("unable to parse non-empty context. Must be JSON");
1317
679
  }
1318
- const rpcProvider = new import_ethers4.ethers.JsonRpcProvider(contractData.rpcUrl);
1319
- existingContractsMap[chainKey] = Reclaim__factory.connect(
1320
- contractData.address,
1321
- rpcProvider
1322
- );
1323
680
  }
1324
- return existingContractsMap[chainKey];
681
+ const str = `${info.provider}
682
+ ${info.parameters}
683
+ ${canonicalContext}`;
684
+ return import_ethers2.ethers.keccak256(strToUint8Array(str)).toLowerCase();
685
+ }
686
+ function strToUint8Array(str) {
687
+ return new TextEncoder().encode(str);
1325
688
  }
1326
689
 
1327
690
  // src/utils/proofUtils.ts
@@ -1331,7 +694,7 @@ function getShortenedUrl(url) {
1331
694
  logger5.info(`Attempting to shorten URL: ${url}`);
1332
695
  try {
1333
696
  validateURL(url, "getShortenedUrl");
1334
- const response = yield fetch(`${BACKEND_BASE_URL}/api/sdk/shortener`, {
697
+ const response = yield http.client(`${BACKEND_BASE_URL}/api/sdk/shortener`, {
1335
698
  method: "POST",
1336
699
  headers: { "Content-Type": "application/json" },
1337
700
  body: JSON.stringify({ fullUrl: url })
@@ -1364,17 +727,18 @@ function createLinkWithTemplateData(templateData, sharePagePath) {
1364
727
  }
1365
728
  });
1366
729
  }
1367
- function getWitnessesForClaim(epoch, identifier, timestampS) {
730
+ function getAttestors() {
1368
731
  return __async(this, null, function* () {
1369
- const beacon = makeBeacon();
1370
- if (!beacon) {
1371
- logger5.info("No beacon available for getting witnesses");
1372
- throw new Error("No beacon available");
732
+ var _a;
733
+ const response = yield http.client(constants.DEFAULT_ATTESTORS_URL);
734
+ if (!response.ok) {
735
+ (_a = response.body) == null ? void 0 : _a.cancel();
736
+ throw new BackendServerError(
737
+ `Failed to fetch witness addresses: ${response.status}`
738
+ );
1373
739
  }
1374
- const state = yield beacon.getState(epoch);
1375
- const witnessList = fetchWitnessListForClaim(state, identifier, timestampS);
1376
- const witnesses = witnessList.map((w) => w.id.toLowerCase());
1377
- return witnesses;
740
+ const { data } = yield response.json();
741
+ return data.map((wt) => ({ id: wt.address, url: "" }));
1378
742
  });
1379
743
  }
1380
744
  function recoverSignersOfSignedClaim({
@@ -1383,26 +747,10 @@ function recoverSignersOfSignedClaim({
1383
747
  }) {
1384
748
  const dataStr = createSignDataForClaim(__spreadValues({}, claim));
1385
749
  const signers = signatures.map(
1386
- (signature) => import_ethers5.ethers.verifyMessage(dataStr, import_ethers5.ethers.hexlify(signature)).toLowerCase()
750
+ (signature) => import_ethers3.ethers.verifyMessage(dataStr, import_ethers3.ethers.hexlify(signature)).toLowerCase()
1387
751
  );
1388
752
  return signers;
1389
753
  }
1390
- function assertValidSignedClaim(claim, expectedWitnessAddresses) {
1391
- const witnessAddresses = recoverSignersOfSignedClaim(claim);
1392
- const witnessesNotSeen = new Set(expectedWitnessAddresses);
1393
- for (const witness of witnessAddresses) {
1394
- if (witnessesNotSeen.has(witness)) {
1395
- witnessesNotSeen.delete(witness);
1396
- }
1397
- }
1398
- if (witnessesNotSeen.size > 0) {
1399
- const missingWitnesses = Array.from(witnessesNotSeen).join(", ");
1400
- logger5.info(`Claim validation failed. Missing signatures from: ${missingWitnesses}`);
1401
- throw new ProofNotVerifiedError(
1402
- `Missing signatures from ${missingWitnesses}`
1403
- );
1404
- }
1405
- }
1406
754
 
1407
755
  // src/utils/modalUtils.ts
1408
756
  var logger6 = logger_default.logger;
@@ -1856,56 +1204,30 @@ function clearDeviceCache() {
1856
1204
  // src/Reclaim.ts
1857
1205
  var logger7 = logger_default.logger;
1858
1206
  var sdkVersion = require_package().version;
1859
- function verifyProof(proofOrProofs, allowAiWitness) {
1207
+ function verifyProof(proofOrProofs, allowAiWitness = false) {
1860
1208
  return __async(this, null, function* () {
1861
- var _a;
1862
- if (Array.isArray(proofOrProofs)) {
1863
- for (const proof2 of proofOrProofs) {
1864
- const isVerified = yield verifyProof(proof2, allowAiWitness);
1865
- if (!isVerified) {
1866
- return false;
1867
- }
1868
- }
1209
+ try {
1210
+ yield assertValidProof(proofOrProofs, allowAiWitness);
1869
1211
  return true;
1212
+ } catch (error) {
1213
+ logger7.error("error in validating proof", error);
1214
+ return false;
1870
1215
  }
1871
- const proof = proofOrProofs;
1872
- if (!proof.signatures.length) {
1873
- throw new SignatureNotFoundError("No signatures");
1874
- }
1875
- try {
1876
- let witnesses = [];
1877
- if (proof.witnesses.length && ((_a = proof.witnesses[0]) == null ? void 0 : _a.url) === "ai-witness" && allowAiWitness === true) {
1878
- witnesses.push(proof.witnesses[0].id);
1879
- } else {
1880
- witnesses = yield getWitnessesForClaim(
1881
- proof.claimData.epoch,
1882
- proof.identifier,
1883
- proof.claimData.timestampS
1884
- );
1885
- }
1886
- const calculatedIdentifier = getIdentifierFromClaimInfo({
1887
- parameters: JSON.parse(
1888
- (0, import_canonicalize3.default)(proof.claimData.parameters)
1889
- ),
1890
- provider: proof.claimData.provider,
1891
- context: proof.claimData.context
1216
+ });
1217
+ }
1218
+ function assertValidProof(proofOrProofs, allowAiWitness = false) {
1219
+ return __async(this, null, function* () {
1220
+ const attestors = yield getAttestors();
1221
+ proofOrProofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];
1222
+ for (const proof of proofOrProofs) {
1223
+ const signers = recoverSignersOfSignedClaim({
1224
+ claim: proof.claimData,
1225
+ signatures: proof.signatures.map((signature) => import_ethers4.ethers.getBytes(signature))
1892
1226
  });
1893
- proof.identifier = replaceAll(proof.identifier, '"', "");
1894
- if (calculatedIdentifier !== proof.identifier) {
1895
- throw new ProofNotVerifiedError("Identifier Mismatch");
1227
+ if (!attestors.some((attestor) => signers.includes(attestor.id.toLowerCase()))) {
1228
+ throw new ProofNotVerifiedError("Identifier mismatch");
1896
1229
  }
1897
- const signedClaim = {
1898
- claim: __spreadValues({}, proof.claimData),
1899
- signatures: proof.signatures.map((signature) => {
1900
- return import_ethers6.ethers.getBytes(signature);
1901
- })
1902
- };
1903
- assertValidSignedClaim(signedClaim, witnesses);
1904
- } catch (e) {
1905
- logger7.info(`Error verifying proof: ${e instanceof Error ? e.message : String(e)}`);
1906
- return false;
1907
1230
  }
1908
- return true;
1909
1231
  });
1910
1232
  }
1911
1233
  function transformForOnchain(proof) {
@@ -1959,7 +1281,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1959
1281
  this.FAILURE_TIMEOUT = 30 * 1e3;
1960
1282
  /**
1961
1283
  * Validates signature and returns template data
1962
- * @returns
1284
+ * @returns
1963
1285
  */
1964
1286
  this.getTemplateData = () => {
1965
1287
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
@@ -2284,11 +1606,11 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2284
1606
  /**
2285
1607
  * Sets a custom callback URL where proofs will be submitted via HTTP `POST`
2286
1608
  *
2287
- * By default, proofs are sent as HTTP POST with `Content-Type` as `application/x-www-form-urlencoded`.
1609
+ * By default, proofs are sent as HTTP POST with `Content-Type` as `application/x-www-form-urlencoded`.
2288
1610
  * Pass function argument `jsonProofResponse` as `true` to send proofs with `Content-Type` as `application/json`.
2289
- *
1611
+ *
2290
1612
  * When a custom callback URL is set, proofs are sent to the custom URL *instead* of the Reclaim backend.
2291
- * Consequently, the startSession `onSuccess` callback will be invoked with an empty array (`[]`)
1613
+ * Consequently, the startSession `onSuccess` callback will be invoked with an empty array (`[]`)
2292
1614
  * instead of the proof data, as the proof is not available to the SDK in this flow.
2293
1615
  *
2294
1616
  * This verification session's id will be present in `X-Reclaim-Session-Id` header of the request.
@@ -2322,7 +1644,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2322
1644
  * `When `method` is set to `POST`, `body` will be sent with 'application/x-www-form-urlencoded' content type.
2323
1645
  * When `method` is set to `GET`, if `body` is set then `body` will be sent as query parameters.
2324
1646
  * Sending `body` on redirection is only supported in In-Browser SDK.
2325
- *
1647
+ *
2326
1648
  * @throws {InvalidParamError} When URL is invalid
2327
1649
  *
2328
1650
  * @example
@@ -2346,7 +1668,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2346
1668
  * coordinate with your backend to receive errors.
2347
1669
  *
2348
1670
  * This verification session's id will be present in `X-Reclaim-Session-Id` header of the request.
2349
- *
1671
+ *
2350
1672
  * Following is the data format which is sent as an HTTP POST request to the url with `Content-Type: application/json`:
2351
1673
 
2352
1674
  * ```json
@@ -2360,7 +1682,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2360
1682
  * // [key: any]: any
2361
1683
  * }
2362
1684
  * ```
2363
- *
1685
+ *
2364
1686
  * For more details about response format, check out [official documentation of Error Callback URL](https://docs.reclaimprotocol.org/js-sdk/preparing-request#cancel-callback).
2365
1687
  *
2366
1688
  * @param url - The URL where errors should be submitted via HTTP POST
@@ -2370,9 +1692,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2370
1692
  * ```typescript
2371
1693
  * proofRequest.setCancelCallbackUrl('https://your-backend.com/error-callback');
2372
1694
  * ```
2373
- *
1695
+ *
2374
1696
  * @since 4.8.1
2375
- *
1697
+ *
2376
1698
  */
2377
1699
  setCancelCallbackUrl(url) {
2378
1700
  validateURL(url, "setCancelCallbackUrl");
@@ -2394,9 +1716,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2394
1716
  * ```typescript
2395
1717
  * proofRequest.setCancelRedirectUrl('https://your-app.com/error');
2396
1718
  * ```
2397
- *
1719
+ *
2398
1720
  * @since 4.10.0
2399
- *
1721
+ *
2400
1722
  */
2401
1723
  setCancelRedirectUrl(url, method = "GET", body) {
2402
1724
  validateURL(url, "setCancelRedirectUrl");
@@ -2447,12 +1769,12 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2447
1769
  * Sets additional context data to be stored with the claim
2448
1770
  *
2449
1771
  * This allows you to associate custom JSON serializable data with the proof claim.
2450
- * The context can be retrieved and validated when verifying the proof.
2451
- *
1772
+ * The context can be retrieved and validated when verifying the proof.
1773
+ *
2452
1774
  * Also see [setContext] which is an alternate way to set context that has an address & message.
2453
1775
  *
2454
1776
  * [setContext] and [setJsonContext] overwrite each other. Each call replaces the existing context.
2455
- *
1777
+ *
2456
1778
  * @param context - Any additional data you want to store with the claim. Should be serializable to a JSON string.
2457
1779
  * @throws {SetContextError} When context parameters are invalid
2458
1780
  *
@@ -2479,9 +1801,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2479
1801
  * The context can be retrieved and validated when verifying the proof.
2480
1802
  *
2481
1803
  * Also see [setJsonContext] which is an alternate way to set context that allows for custom JSON serializable data.
2482
- *
1804
+ *
2483
1805
  * [setContext] and [setJsonContext] overwrite each other. Each call replaces the existing context.
2484
- *
1806
+ *
2485
1807
  * @param address - Context address identifier
2486
1808
  * @param message - Additional data to associate with the address
2487
1809
  * @throws {SetContextError} When context parameters are invalid
@@ -2506,8 +1828,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2506
1828
  /**
2507
1829
  * @deprecated use setContext instead
2508
1830
  *
2509
- * @param address
2510
- * @param message additional data you want associated with the [address]
1831
+ * @param address
1832
+ * @param message additional data you want associated with the [address]
2511
1833
  */
2512
1834
  addContext(address, message) {
2513
1835
  this.setContext(address, message);
@@ -2644,13 +1966,13 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2644
1966
  generateSignature(applicationSecret) {
2645
1967
  return __async(this, null, function* () {
2646
1968
  try {
2647
- const wallet = new import_ethers6.ethers.Wallet(applicationSecret);
1969
+ const wallet = new import_ethers4.ethers.Wallet(applicationSecret);
2648
1970
  const canonicalData = (0, import_canonicalize3.default)({ providerId: this.providerId, timestamp: this.timeStamp });
2649
1971
  if (!canonicalData) {
2650
1972
  throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
2651
1973
  }
2652
- const messageHash = import_ethers6.ethers.keccak256(new TextEncoder().encode(canonicalData));
2653
- return yield wallet.signMessage(import_ethers6.ethers.getBytes(messageHash));
1974
+ const messageHash = import_ethers4.ethers.keccak256(new TextEncoder().encode(canonicalData));
1975
+ return yield wallet.signMessage(import_ethers4.ethers.getBytes(messageHash));
2654
1976
  } catch (err) {
2655
1977
  logger7.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, signature: ${this.signature}, timeStamp: ${this.timeStamp}`, err);
2656
1978
  throw new SignatureGeneratingError(`Error generating signature for applicationSecret: ${applicationSecret}`);
@@ -2705,7 +2027,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2705
2027
  timestamp: this.timeStamp,
2706
2028
  // New field with correct spelling
2707
2029
  timeStamp: this.timeStamp,
2708
- // @deprecated: Remove in future versions
2030
+ // @deprecated: Remove in future versions
2709
2031
  options: this.options,
2710
2032
  sdkVersion: this.sdkVersion,
2711
2033
  jsonProofResponse: this.jsonProofResponse,
@@ -3001,10 +2323,10 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
3001
2323
  * In the custom-callback flow (where the SDK submits a proof to a provided callback URL),
3002
2324
  * onSuccess may be invoked with an empty array (onSuccess([])) when no proof is available
3003
2325
  * (this happens when a callback is set using setAppCallbackUrl where proof is sent to callback instead of reclaim backend).
3004
- *
2326
+ *
3005
2327
  * Please refer to the OnSuccess type signature ((proof?: Proof | Proof[]) => void)
3006
2328
  * and the startSession function source for more details.
3007
- *
2329
+ *
3008
2330
  * > [!TIP]
3009
2331
  * > **Best Practice:** When using `setAppCallbackUrl` and/or `setCancelCallbackUrl`, your backend receives the proof or cancellation details directly. We recommend your backend notifies the frontend (e.g. via WebSockets, SSE, or polling) to stop the verification process and handle the appropriate success/failure action. Do not rely completely on `startSession` callbacks on the frontend when using these backend callbacks.
3010
2332
  *
@@ -3135,11 +2457,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
3135
2457
  };
3136
2458
  // Annotate the CommonJS export names for ESM import in node:
3137
2459
  0 && (module.exports = {
3138
- ClaimCreationType,
3139
- DeviceType,
3140
- RECLAIM_EXTENSION_ACTIONS,
3141
2460
  ReclaimProofRequest,
3142
- SessionStatus,
2461
+ assertValidProof,
3143
2462
  clearDeviceCache,
3144
2463
  getDeviceType,
3145
2464
  getMobileDeviceType,