@reclaimprotocol/js-sdk 4.10.1 → 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.10.1",
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,10 +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,
177
+ assertValidProof: () => assertValidProof,
182
178
  clearDeviceCache: () => clearDeviceCache,
183
179
  getDeviceType: () => getDeviceType,
184
180
  getMobileDeviceType: () => getMobileDeviceType,
@@ -197,92 +193,8 @@ var RECLAIM_EXTENSION_ACTIONS = {
197
193
  STATUS_UPDATE: "RECLAIM_STATUS_UPDATE"
198
194
  };
199
195
 
200
- // src/witness.ts
201
- var import_ethers = require("ethers");
202
-
203
- // src/utils/strings.ts
204
- var import_canonicalize = __toESM(require("canonicalize"));
205
- function canonicalStringify(params) {
206
- if (!params) {
207
- return "";
208
- }
209
- return (0, import_canonicalize.default)(params) || "";
210
- }
211
-
212
- // src/witness.ts
213
- function fetchWitnessListForClaim({ witnesses, witnessesRequiredForClaim, epoch }, params, timestampS) {
214
- const identifier = typeof params === "string" ? params : getIdentifierFromClaimInfo(params);
215
- const completeInput = [
216
- identifier,
217
- epoch.toString(),
218
- witnessesRequiredForClaim.toString(),
219
- timestampS.toString()
220
- ].join("\n");
221
- const completeHashStr = import_ethers.ethers.keccak256(strToUint8Array(completeInput));
222
- const completeHash = import_ethers.ethers.getBytes(completeHashStr);
223
- const completeHashView = uint8ArrayToDataView(completeHash);
224
- const witnessesLeft = [...witnesses];
225
- const selectedWitnesses = [];
226
- let byteOffset = 0;
227
- for (let i = 0; i < witnessesRequiredForClaim; i++) {
228
- const randomSeed = completeHashView.getUint32(byteOffset);
229
- const witnessIndex = randomSeed % witnessesLeft.length;
230
- const witness = witnessesLeft[witnessIndex];
231
- selectedWitnesses.push(witness);
232
- witnessesLeft[witnessIndex] = witnessesLeft[witnessesLeft.length - 1];
233
- witnessesLeft.pop();
234
- byteOffset = (byteOffset + 4) % completeHash.length;
235
- }
236
- return selectedWitnesses;
237
- }
238
- function getIdentifierFromClaimInfo(info) {
239
- let canonicalContext = info.context || "";
240
- if (canonicalContext.length > 0) {
241
- try {
242
- const ctx = JSON.parse(canonicalContext);
243
- canonicalContext = canonicalStringify(ctx);
244
- } catch (e) {
245
- throw new Error("unable to parse non-empty context. Must be JSON");
246
- }
247
- }
248
- const str = `${info.provider}
249
- ${info.parameters}
250
- ${canonicalContext}`;
251
- return import_ethers.ethers.keccak256(strToUint8Array(str)).toLowerCase();
252
- }
253
- function strToUint8Array(str) {
254
- return new TextEncoder().encode(str);
255
- }
256
- function uint8ArrayToDataView(arr) {
257
- return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
258
- }
259
- function createSignDataForClaim(data) {
260
- const identifier = "identifier" in data ? data.identifier : getIdentifierFromClaimInfo(data);
261
- const lines = [
262
- identifier,
263
- data.owner.toLowerCase(),
264
- data.timestampS.toString(),
265
- data.epoch.toString()
266
- ];
267
- return lines.join("\n");
268
- }
269
-
270
- // src/utils/types.ts
271
- var ClaimCreationType = /* @__PURE__ */ ((ClaimCreationType2) => {
272
- ClaimCreationType2["STANDALONE"] = "createClaim";
273
- ClaimCreationType2["ON_ME_CHAIN"] = "createClaimOnMechain";
274
- return ClaimCreationType2;
275
- })(ClaimCreationType || {});
276
- var DeviceType = /* @__PURE__ */ ((DeviceType2) => {
277
- DeviceType2["ANDROID"] = "android";
278
- DeviceType2["IOS"] = "ios";
279
- DeviceType2["DESKTOP"] = "desktop";
280
- DeviceType2["MOBILE"] = "mobile";
281
- return DeviceType2;
282
- })(DeviceType || {});
283
-
284
196
  // src/Reclaim.ts
285
- var import_ethers6 = require("ethers");
197
+ var import_ethers4 = require("ethers");
286
198
  var import_canonicalize3 = __toESM(require("canonicalize"));
287
199
 
288
200
  // src/utils/errors.ts
@@ -415,6 +327,9 @@ var constants = {
415
327
  get DEFAULT_RECLAIM_STATUS_URL() {
416
328
  return `${BACKEND_BASE_URL}/api/sdk/session/`;
417
329
  },
330
+ get DEFAULT_ATTESTORS_URL() {
331
+ return `${BACKEND_BASE_URL}/api/attestors`;
332
+ },
418
333
  // URL for sharing Reclaim templates
419
334
  RECLAIM_SHARE_URL: "https://share.reclaimprotocol.org/verifier/?template=",
420
335
  // Chrome extension URL for Reclaim Protocol
@@ -424,8 +339,19 @@ var constants = {
424
339
  };
425
340
 
426
341
  // src/utils/validationUtils.ts
427
- var import_ethers2 = require("ethers");
342
+ var import_ethers = require("ethers");
428
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
429
355
  var logger3 = logger_default.logger;
430
356
  function validateFunctionParams(params, functionName) {
431
357
  params.forEach(({ input, paramName, isString }) => {
@@ -474,6 +400,41 @@ function validateURL(url, functionName) {
474
400
  throw new InvalidParamError(`Invalid URL format ${url} passed to ${functionName}.`, e);
475
401
  }
476
402
  }
403
+ function validateRedirectionMethod(method, functionName) {
404
+ try {
405
+ if (method === null || method === void 0) {
406
+ return;
407
+ }
408
+ if (method !== "GET" && method !== "POST") {
409
+ throw new Error(`Invalid redirection method ${method} passed to ${functionName}.`);
410
+ }
411
+ } catch (e) {
412
+ logger3.info(`Redirection method validation failed for ${method} in ${functionName}: ${e.message}`);
413
+ throw new InvalidParamError(`Invalid redirection method ${method} passed to ${functionName}.`, e);
414
+ }
415
+ }
416
+ function validateRedirectionBody(records, functionName) {
417
+ try {
418
+ if (records === null || records === void 0) {
419
+ return;
420
+ }
421
+ if (Array.isArray(records)) {
422
+ for (const record of records) {
423
+ if ("name" in record && record.name && typeof record.name === "string") {
424
+ if ("value" in record && typeof record.value === "string") {
425
+ continue;
426
+ }
427
+ }
428
+ throw new Error("Record in form entries do not have a valid name and/or value");
429
+ }
430
+ } else {
431
+ throw new Error("Redirection body must be an array of objects with name, and value");
432
+ }
433
+ } catch (e) {
434
+ logger3.info(`Redirection body validation failed for ${records} in ${functionName}: ${e.message}`);
435
+ throw new InvalidParamError(`Invalid redirection body ${records} passed to ${functionName}.`, e);
436
+ }
437
+ }
477
438
  function validateSignature(providerId, signature, applicationId, timestamp) {
478
439
  try {
479
440
  logger3.info(`Starting signature validation for providerId: ${providerId}, applicationId: ${applicationId}, timestamp: ${timestamp}`);
@@ -482,12 +443,12 @@ function validateSignature(providerId, signature, applicationId, timestamp) {
482
443
  logger3.info("Failed to canonicalize message for signature validation");
483
444
  throw new Error("Failed to canonicalize message");
484
445
  }
485
- const messageHash = import_ethers2.ethers.keccak256(new TextEncoder().encode(message));
486
- let appId = import_ethers2.ethers.verifyMessage(
487
- import_ethers2.ethers.getBytes(messageHash),
488
- 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)
489
450
  ).toLowerCase();
490
- if (import_ethers2.ethers.getAddress(appId) !== import_ethers2.ethers.getAddress(applicationId)) {
451
+ if (import_ethers.ethers.getAddress(appId) !== import_ethers.ethers.getAddress(applicationId)) {
491
452
  logger3.info(`Signature validation failed: Mismatch between derived appId (${appId}) and provided applicationId (${applicationId})`);
492
453
  throw new InvalidSignatureError(`Signature does not match the application id: ${appId}`);
493
454
  }
@@ -569,13 +530,59 @@ function validateModalOptions(modalOptions, functionName, paramPrefix = "") {
569
530
  }
570
531
  }
571
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
+
572
579
  // src/utils/sessionUtils.ts
573
580
  var logger4 = logger_default.logger;
574
581
  function initSession(providerId, appId, timestamp, signature, versionNumber) {
575
582
  return __async(this, null, function* () {
576
583
  logger4.info(`Initializing session for providerId: ${providerId}, appId: ${appId}`);
577
584
  try {
578
- const response = yield fetch(`${BACKEND_BASE_URL}/api/sdk/init/session/`, {
585
+ const response = yield http.client(`${BACKEND_BASE_URL}/api/sdk/init/session/`, {
579
586
  method: "POST",
580
587
  headers: { "Content-Type": "application/json" },
581
588
  body: JSON.stringify({ providerId, appId, timestamp, signature, versionNumber })
@@ -600,7 +607,7 @@ function updateSession(sessionId, status) {
600
607
  "updateSession"
601
608
  );
602
609
  try {
603
- const response = yield fetch(`${BACKEND_BASE_URL}/api/sdk/update/session/`, {
610
+ const response = yield http.client(`${BACKEND_BASE_URL}/api/sdk/update/session/`, {
604
611
  method: "POST",
605
612
  headers: { "Content-Type": "application/json" },
606
613
  body: JSON.stringify({ sessionId, status })
@@ -627,7 +634,7 @@ function fetchStatusUrl(sessionId) {
627
634
  "fetchStatusUrl"
628
635
  );
629
636
  try {
630
- const response = yield fetch(`${constants.DEFAULT_RECLAIM_STATUS_URL}${sessionId}`, {
637
+ const response = yield http.client(`${constants.DEFAULT_RECLAIM_STATUS_URL}${sessionId}`, {
631
638
  method: "GET",
632
639
  headers: { "Content-Type": "application/json" }
633
640
  });
@@ -647,629 +654,37 @@ function fetchStatusUrl(sessionId) {
647
654
  }
648
655
 
649
656
  // src/utils/proofUtils.ts
650
- var import_ethers5 = require("ethers");
651
-
652
- // src/contract-types/contracts/factories/Reclaim__factory.ts
653
657
  var import_ethers3 = require("ethers");
654
- var _abi = [
655
- {
656
- anonymous: false,
657
- inputs: [
658
- {
659
- indexed: false,
660
- internalType: "address",
661
- name: "previousAdmin",
662
- type: "address"
663
- },
664
- {
665
- indexed: false,
666
- internalType: "address",
667
- name: "newAdmin",
668
- type: "address"
669
- }
670
- ],
671
- name: "AdminChanged",
672
- type: "event"
673
- },
674
- {
675
- anonymous: false,
676
- inputs: [
677
- {
678
- indexed: true,
679
- internalType: "address",
680
- name: "beacon",
681
- type: "address"
682
- }
683
- ],
684
- name: "BeaconUpgraded",
685
- type: "event"
686
- },
687
- {
688
- anonymous: false,
689
- inputs: [
690
- {
691
- components: [
692
- {
693
- internalType: "uint32",
694
- name: "id",
695
- type: "uint32"
696
- },
697
- {
698
- internalType: "uint32",
699
- name: "timestampStart",
700
- type: "uint32"
701
- },
702
- {
703
- internalType: "uint32",
704
- name: "timestampEnd",
705
- type: "uint32"
706
- },
707
- {
708
- components: [
709
- {
710
- internalType: "address",
711
- name: "addr",
712
- type: "address"
713
- },
714
- {
715
- internalType: "string",
716
- name: "host",
717
- type: "string"
718
- }
719
- ],
720
- internalType: "struct Reclaim.Witness[]",
721
- name: "witnesses",
722
- type: "tuple[]"
723
- },
724
- {
725
- internalType: "uint8",
726
- name: "minimumWitnessesForClaimCreation",
727
- type: "uint8"
728
- }
729
- ],
730
- indexed: false,
731
- internalType: "struct Reclaim.Epoch",
732
- name: "epoch",
733
- type: "tuple"
734
- }
735
- ],
736
- name: "EpochAdded",
737
- type: "event"
738
- },
739
- {
740
- anonymous: false,
741
- inputs: [
742
- {
743
- indexed: false,
744
- internalType: "uint8",
745
- name: "version",
746
- type: "uint8"
747
- }
748
- ],
749
- name: "Initialized",
750
- type: "event"
751
- },
752
- {
753
- anonymous: false,
754
- inputs: [
755
- {
756
- indexed: true,
757
- internalType: "address",
758
- name: "previousOwner",
759
- type: "address"
760
- },
761
- {
762
- indexed: true,
763
- internalType: "address",
764
- name: "newOwner",
765
- type: "address"
766
- }
767
- ],
768
- name: "OwnershipTransferred",
769
- type: "event"
770
- },
771
- {
772
- anonymous: false,
773
- inputs: [
774
- {
775
- indexed: true,
776
- internalType: "address",
777
- name: "implementation",
778
- type: "address"
779
- }
780
- ],
781
- name: "Upgraded",
782
- type: "event"
783
- },
784
- {
785
- inputs: [
786
- {
787
- internalType: "address",
788
- name: "witnessAddress",
789
- type: "address"
790
- },
791
- {
792
- internalType: "string",
793
- name: "host",
794
- type: "string"
795
- }
796
- ],
797
- name: "addAsWitness",
798
- outputs: [],
799
- stateMutability: "nonpayable",
800
- type: "function"
801
- },
802
- {
803
- inputs: [],
804
- name: "addNewEpoch",
805
- outputs: [],
806
- stateMutability: "nonpayable",
807
- type: "function"
808
- },
809
- {
810
- inputs: [
811
- {
812
- internalType: "uint32",
813
- name: "epochNum",
814
- type: "uint32"
815
- },
816
- {
817
- components: [
818
- {
819
- internalType: "string",
820
- name: "provider",
821
- type: "string"
822
- },
823
- {
824
- internalType: "string",
825
- name: "parameters",
826
- type: "string"
827
- },
828
- {
829
- internalType: "string",
830
- name: "context",
831
- type: "string"
832
- }
833
- ],
834
- internalType: "struct Claims.ClaimInfo",
835
- name: "claimInfo",
836
- type: "tuple"
837
- },
838
- {
839
- components: [
840
- {
841
- internalType: "bytes32",
842
- name: "identifier",
843
- type: "bytes32"
844
- },
845
- {
846
- internalType: "address",
847
- name: "owner",
848
- type: "address"
849
- },
850
- {
851
- internalType: "uint32",
852
- name: "timestampS",
853
- type: "uint32"
854
- },
855
- {
856
- internalType: "uint256",
857
- name: "epoch",
858
- type: "uint256"
859
- }
860
- ],
861
- internalType: "struct Claims.CompleteClaimData",
862
- name: "claimData",
863
- type: "tuple"
864
- },
865
- {
866
- internalType: "bytes[]",
867
- name: "signatures",
868
- type: "bytes[]"
869
- }
870
- ],
871
- name: "assertValidEpochAndSignedClaim",
872
- outputs: [],
873
- stateMutability: "view",
874
- type: "function"
875
- },
876
- {
877
- inputs: [],
878
- name: "currentEpoch",
879
- outputs: [
880
- {
881
- internalType: "uint32",
882
- name: "",
883
- type: "uint32"
884
- }
885
- ],
886
- stateMutability: "view",
887
- type: "function"
888
- },
889
- {
890
- inputs: [],
891
- name: "epochDurationS",
892
- outputs: [
893
- {
894
- internalType: "uint32",
895
- name: "",
896
- type: "uint32"
897
- }
898
- ],
899
- stateMutability: "view",
900
- type: "function"
901
- },
902
- {
903
- inputs: [
904
- {
905
- internalType: "uint256",
906
- name: "",
907
- type: "uint256"
908
- }
909
- ],
910
- name: "epochs",
911
- outputs: [
912
- {
913
- internalType: "uint32",
914
- name: "id",
915
- type: "uint32"
916
- },
917
- {
918
- internalType: "uint32",
919
- name: "timestampStart",
920
- type: "uint32"
921
- },
922
- {
923
- internalType: "uint32",
924
- name: "timestampEnd",
925
- type: "uint32"
926
- },
927
- {
928
- internalType: "uint8",
929
- name: "minimumWitnessesForClaimCreation",
930
- type: "uint8"
931
- }
932
- ],
933
- stateMutability: "view",
934
- type: "function"
935
- },
936
- {
937
- inputs: [
938
- {
939
- internalType: "uint32",
940
- name: "epoch",
941
- type: "uint32"
942
- }
943
- ],
944
- name: "fetchEpoch",
945
- outputs: [
946
- {
947
- components: [
948
- {
949
- internalType: "uint32",
950
- name: "id",
951
- type: "uint32"
952
- },
953
- {
954
- internalType: "uint32",
955
- name: "timestampStart",
956
- type: "uint32"
957
- },
958
- {
959
- internalType: "uint32",
960
- name: "timestampEnd",
961
- type: "uint32"
962
- },
963
- {
964
- components: [
965
- {
966
- internalType: "address",
967
- name: "addr",
968
- type: "address"
969
- },
970
- {
971
- internalType: "string",
972
- name: "host",
973
- type: "string"
974
- }
975
- ],
976
- internalType: "struct Reclaim.Witness[]",
977
- name: "witnesses",
978
- type: "tuple[]"
979
- },
980
- {
981
- internalType: "uint8",
982
- name: "minimumWitnessesForClaimCreation",
983
- type: "uint8"
984
- }
985
- ],
986
- internalType: "struct Reclaim.Epoch",
987
- name: "",
988
- type: "tuple"
989
- }
990
- ],
991
- stateMutability: "view",
992
- type: "function"
993
- },
994
- {
995
- inputs: [
996
- {
997
- internalType: "uint32",
998
- name: "epoch",
999
- type: "uint32"
1000
- },
1001
- {
1002
- internalType: "bytes32",
1003
- name: "identifier",
1004
- type: "bytes32"
1005
- },
1006
- {
1007
- internalType: "uint32",
1008
- name: "timestampS",
1009
- type: "uint32"
1010
- }
1011
- ],
1012
- name: "fetchWitnessesForClaim",
1013
- outputs: [
1014
- {
1015
- components: [
1016
- {
1017
- internalType: "address",
1018
- name: "addr",
1019
- type: "address"
1020
- },
1021
- {
1022
- internalType: "string",
1023
- name: "host",
1024
- type: "string"
1025
- }
1026
- ],
1027
- internalType: "struct Reclaim.Witness[]",
1028
- name: "",
1029
- type: "tuple[]"
1030
- }
1031
- ],
1032
- stateMutability: "view",
1033
- type: "function"
1034
- },
1035
- {
1036
- inputs: [],
1037
- name: "initialize",
1038
- outputs: [],
1039
- stateMutability: "nonpayable",
1040
- type: "function"
1041
- },
1042
- {
1043
- inputs: [],
1044
- name: "minimumWitnessesForClaimCreation",
1045
- outputs: [
1046
- {
1047
- internalType: "uint8",
1048
- name: "",
1049
- type: "uint8"
1050
- }
1051
- ],
1052
- stateMutability: "view",
1053
- type: "function"
1054
- },
1055
- {
1056
- inputs: [],
1057
- name: "owner",
1058
- outputs: [
1059
- {
1060
- internalType: "address",
1061
- name: "",
1062
- type: "address"
1063
- }
1064
- ],
1065
- stateMutability: "view",
1066
- type: "function"
1067
- },
1068
- {
1069
- inputs: [],
1070
- name: "proxiableUUID",
1071
- outputs: [
1072
- {
1073
- internalType: "bytes32",
1074
- name: "",
1075
- type: "bytes32"
1076
- }
1077
- ],
1078
- stateMutability: "view",
1079
- type: "function"
1080
- },
1081
- {
1082
- inputs: [
1083
- {
1084
- internalType: "address",
1085
- name: "witnessAddress",
1086
- type: "address"
1087
- }
1088
- ],
1089
- name: "removeAsWitness",
1090
- outputs: [],
1091
- stateMutability: "nonpayable",
1092
- type: "function"
1093
- },
1094
- {
1095
- inputs: [],
1096
- name: "renounceOwnership",
1097
- outputs: [],
1098
- stateMutability: "nonpayable",
1099
- type: "function"
1100
- },
1101
- {
1102
- inputs: [
1103
- {
1104
- internalType: "address",
1105
- name: "newOwner",
1106
- type: "address"
1107
- }
1108
- ],
1109
- name: "transferOwnership",
1110
- outputs: [],
1111
- stateMutability: "nonpayable",
1112
- type: "function"
1113
- },
1114
- {
1115
- inputs: [
1116
- {
1117
- internalType: "address",
1118
- name: "addr",
1119
- type: "address"
1120
- },
1121
- {
1122
- internalType: "bool",
1123
- name: "isWhitelisted",
1124
- type: "bool"
1125
- }
1126
- ],
1127
- name: "updateWitnessWhitelist",
1128
- outputs: [],
1129
- stateMutability: "nonpayable",
1130
- type: "function"
1131
- },
1132
- {
1133
- inputs: [
1134
- {
1135
- internalType: "address",
1136
- name: "newImplementation",
1137
- type: "address"
1138
- }
1139
- ],
1140
- name: "upgradeTo",
1141
- outputs: [],
1142
- stateMutability: "nonpayable",
1143
- type: "function"
1144
- },
1145
- {
1146
- inputs: [
1147
- {
1148
- internalType: "address",
1149
- name: "newImplementation",
1150
- type: "address"
1151
- },
1152
- {
1153
- internalType: "bytes",
1154
- name: "data",
1155
- type: "bytes"
1156
- }
1157
- ],
1158
- name: "upgradeToAndCall",
1159
- outputs: [],
1160
- stateMutability: "payable",
1161
- type: "function"
1162
- },
1163
- {
1164
- inputs: [
1165
- {
1166
- internalType: "uint256",
1167
- name: "",
1168
- type: "uint256"
1169
- }
1170
- ],
1171
- name: "witnesses",
1172
- outputs: [
1173
- {
1174
- internalType: "address",
1175
- name: "addr",
1176
- type: "address"
1177
- },
1178
- {
1179
- internalType: "string",
1180
- name: "host",
1181
- type: "string"
1182
- }
1183
- ],
1184
- stateMutability: "view",
1185
- type: "function"
1186
- }
1187
- ];
1188
- var Reclaim__factory = class {
1189
- static connect(address, signerOrProvider) {
1190
- return new import_ethers3.Contract(address, _abi, signerOrProvider);
1191
- }
1192
- };
1193
- Reclaim__factory.abi = _abi;
1194
-
1195
- // src/contract-types/config.json
1196
- var config_default = {
1197
- "0x1a4": {
1198
- chainName: "opt-goerli",
1199
- address: "0xF93F605142Fb1Efad7Aa58253dDffF67775b4520",
1200
- rpcUrl: "https://opt-goerli.g.alchemy.com/v2/rksDkSUXd2dyk2ANy_zzODknx_AAokui"
1201
- },
1202
- "0xaa37dc": {
1203
- chainName: "opt-sepolia",
1204
- address: "0x6D0f81BDA11995f25921aAd5B43359630E65Ca96",
1205
- rpcUrl: "https://opt-sepolia.g.alchemy.com/v2/aO1-SfG4oFRLyAiLREqzyAUu0HTCwHgs"
1206
- }
1207
- };
1208
658
 
1209
- // src/smart-contract.ts
1210
- var import_ethers4 = require("ethers");
1211
- var DEFAULT_CHAIN_ID = 11155420;
1212
- function makeBeacon(chainId) {
1213
- chainId = chainId || DEFAULT_CHAIN_ID;
1214
- const contract = getContract(chainId);
1215
- if (contract) {
1216
- let _a;
1217
- return makeBeaconCacheable({
1218
- getState(epochId) {
1219
- return __async(this, null, function* () {
1220
- const epoch = yield contract.fetchEpoch(epochId || 0);
1221
- if (!epoch.id) {
1222
- throw new Error(`Invalid epoch ID: ${epochId}`);
1223
- }
1224
- return {
1225
- epoch: epoch.id,
1226
- witnesses: epoch.witnesses.map((w) => ({
1227
- id: w.addr.toLowerCase(),
1228
- url: w.host
1229
- })),
1230
- witnessesRequiredForClaim: epoch.minimumWitnessesForClaimCreation,
1231
- nextEpochTimestampS: epoch.timestampEnd
1232
- };
1233
- });
1234
- }
1235
- });
1236
- } else {
1237
- return void 0;
1238
- }
1239
- }
1240
- function makeBeaconCacheable(beacon) {
1241
- const cache = {};
1242
- return __spreadProps(__spreadValues({}, beacon), {
1243
- getState(epochId) {
1244
- return __async(this, null, function* () {
1245
- if (!epochId) {
1246
- const state = yield beacon.getState();
1247
- return state;
1248
- }
1249
- const key = epochId;
1250
- if (!cache[key]) {
1251
- cache[key] = beacon.getState(epochId);
1252
- }
1253
- return cache[key];
1254
- });
1255
- }
1256
- });
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");
1257
670
  }
1258
- var existingContractsMap = {};
1259
- function getContract(chainId) {
1260
- const chainKey = `0x${chainId.toString(16)}`;
1261
- if (!existingContractsMap[chainKey]) {
1262
- const contractData = config_default[chainKey];
1263
- if (!contractData) {
1264
- 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");
1265
679
  }
1266
- const rpcProvider = new import_ethers4.ethers.JsonRpcProvider(contractData.rpcUrl);
1267
- existingContractsMap[chainKey] = Reclaim__factory.connect(
1268
- contractData.address,
1269
- rpcProvider
1270
- );
1271
680
  }
1272
- 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);
1273
688
  }
1274
689
 
1275
690
  // src/utils/proofUtils.ts
@@ -1279,7 +694,7 @@ function getShortenedUrl(url) {
1279
694
  logger5.info(`Attempting to shorten URL: ${url}`);
1280
695
  try {
1281
696
  validateURL(url, "getShortenedUrl");
1282
- const response = yield fetch(`${BACKEND_BASE_URL}/api/sdk/shortener`, {
697
+ const response = yield http.client(`${BACKEND_BASE_URL}/api/sdk/shortener`, {
1283
698
  method: "POST",
1284
699
  headers: { "Content-Type": "application/json" },
1285
700
  body: JSON.stringify({ fullUrl: url })
@@ -1312,17 +727,18 @@ function createLinkWithTemplateData(templateData, sharePagePath) {
1312
727
  }
1313
728
  });
1314
729
  }
1315
- function getWitnessesForClaim(epoch, identifier, timestampS) {
730
+ function getAttestors() {
1316
731
  return __async(this, null, function* () {
1317
- const beacon = makeBeacon();
1318
- if (!beacon) {
1319
- logger5.info("No beacon available for getting witnesses");
1320
- 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
+ );
1321
739
  }
1322
- const state = yield beacon.getState(epoch);
1323
- const witnessList = fetchWitnessListForClaim(state, identifier, timestampS);
1324
- const witnesses = witnessList.map((w) => w.id.toLowerCase());
1325
- return witnesses;
740
+ const { data } = yield response.json();
741
+ return data.map((wt) => ({ id: wt.address, url: "" }));
1326
742
  });
1327
743
  }
1328
744
  function recoverSignersOfSignedClaim({
@@ -1331,26 +747,10 @@ function recoverSignersOfSignedClaim({
1331
747
  }) {
1332
748
  const dataStr = createSignDataForClaim(__spreadValues({}, claim));
1333
749
  const signers = signatures.map(
1334
- (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()
1335
751
  );
1336
752
  return signers;
1337
753
  }
1338
- function assertValidSignedClaim(claim, expectedWitnessAddresses) {
1339
- const witnessAddresses = recoverSignersOfSignedClaim(claim);
1340
- const witnessesNotSeen = new Set(expectedWitnessAddresses);
1341
- for (const witness of witnessAddresses) {
1342
- if (witnessesNotSeen.has(witness)) {
1343
- witnessesNotSeen.delete(witness);
1344
- }
1345
- }
1346
- if (witnessesNotSeen.size > 0) {
1347
- const missingWitnesses = Array.from(witnessesNotSeen).join(", ");
1348
- logger5.info(`Claim validation failed. Missing signatures from: ${missingWitnesses}`);
1349
- throw new ProofNotVerifiedError(
1350
- `Missing signatures from ${missingWitnesses}`
1351
- );
1352
- }
1353
- }
1354
754
 
1355
755
  // src/utils/modalUtils.ts
1356
756
  var logger6 = logger_default.logger;
@@ -1804,56 +1204,30 @@ function clearDeviceCache() {
1804
1204
  // src/Reclaim.ts
1805
1205
  var logger7 = logger_default.logger;
1806
1206
  var sdkVersion = require_package().version;
1807
- function verifyProof(proofOrProofs, allowAiWitness) {
1207
+ function verifyProof(proofOrProofs, allowAiWitness = false) {
1808
1208
  return __async(this, null, function* () {
1809
- var _a;
1810
- if (Array.isArray(proofOrProofs)) {
1811
- for (const proof2 of proofOrProofs) {
1812
- const isVerified = yield verifyProof(proof2, allowAiWitness);
1813
- if (!isVerified) {
1814
- return false;
1815
- }
1816
- }
1209
+ try {
1210
+ yield assertValidProof(proofOrProofs, allowAiWitness);
1817
1211
  return true;
1212
+ } catch (error) {
1213
+ logger7.error("error in validating proof", error);
1214
+ return false;
1818
1215
  }
1819
- const proof = proofOrProofs;
1820
- if (!proof.signatures.length) {
1821
- throw new SignatureNotFoundError("No signatures");
1822
- }
1823
- try {
1824
- let witnesses = [];
1825
- if (proof.witnesses.length && ((_a = proof.witnesses[0]) == null ? void 0 : _a.url) === "ai-witness" && allowAiWitness === true) {
1826
- witnesses.push(proof.witnesses[0].id);
1827
- } else {
1828
- witnesses = yield getWitnessesForClaim(
1829
- proof.claimData.epoch,
1830
- proof.identifier,
1831
- proof.claimData.timestampS
1832
- );
1833
- }
1834
- const calculatedIdentifier = getIdentifierFromClaimInfo({
1835
- parameters: JSON.parse(
1836
- (0, import_canonicalize3.default)(proof.claimData.parameters)
1837
- ),
1838
- provider: proof.claimData.provider,
1839
- 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))
1840
1226
  });
1841
- proof.identifier = replaceAll(proof.identifier, '"', "");
1842
- if (calculatedIdentifier !== proof.identifier) {
1843
- throw new ProofNotVerifiedError("Identifier Mismatch");
1227
+ if (!attestors.some((attestor) => signers.includes(attestor.id.toLowerCase()))) {
1228
+ throw new ProofNotVerifiedError("Identifier mismatch");
1844
1229
  }
1845
- const signedClaim = {
1846
- claim: __spreadValues({}, proof.claimData),
1847
- signatures: proof.signatures.map((signature) => {
1848
- return import_ethers6.ethers.getBytes(signature);
1849
- })
1850
- };
1851
- assertValidSignedClaim(signedClaim, witnesses);
1852
- } catch (e) {
1853
- logger7.info(`Error verifying proof: ${e instanceof Error ? e.message : String(e)}`);
1854
- return false;
1855
1230
  }
1856
- return true;
1857
1231
  });
1858
1232
  }
1859
1233
  function transformForOnchain(proof) {
@@ -1885,8 +1259,10 @@ var emptyTemplateData = {
1885
1259
  context: "",
1886
1260
  parameters: {},
1887
1261
  redirectUrl: "",
1262
+ redirectUrlOptions: { method: "GET" },
1888
1263
  cancelCallbackUrl: "",
1889
1264
  cancelRedirectUrl: "",
1265
+ cancelRedirectUrlOptions: { method: "GET" },
1890
1266
  acceptAiProviders: false,
1891
1267
  sdkVersion: "",
1892
1268
  providerVersion: "",
@@ -1905,7 +1281,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1905
1281
  this.FAILURE_TIMEOUT = 30 * 1e3;
1906
1282
  /**
1907
1283
  * Validates signature and returns template data
1908
- * @returns
1284
+ * @returns
1909
1285
  */
1910
1286
  this.getTemplateData = () => {
1911
1287
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
@@ -1925,8 +1301,10 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1925
1301
  resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
1926
1302
  parameters: this.parameters,
1927
1303
  redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
1304
+ redirectUrlOptions: this.redirectUrlOptions,
1928
1305
  cancelCallbackUrl: this.getCancelCallbackUrl(),
1929
1306
  cancelRedirectUrl: this.cancelRedirectUrl,
1307
+ cancelRedirectUrlOptions: this.cancelRedirectUrlOptions,
1930
1308
  acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
1931
1309
  sdkVersion: this.sdkVersion,
1932
1310
  jsonProofResponse: this.jsonProofResponse,
@@ -2112,8 +1490,10 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2112
1490
  parameters,
2113
1491
  signature,
2114
1492
  redirectUrl,
1493
+ redirectUrlOptions,
2115
1494
  cancelCallbackUrl,
2116
1495
  cancelRedirectUrl,
1496
+ cancelRedirectUrlOptions,
2117
1497
  timeStamp,
2118
1498
  timestamp,
2119
1499
  appCallbackUrl,
@@ -2139,12 +1519,20 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2139
1519
  if (redirectUrl) {
2140
1520
  validateURL(redirectUrl, "fromJsonString");
2141
1521
  }
1522
+ if (redirectUrlOptions) {
1523
+ validateRedirectionMethod(redirectUrlOptions.method, "fromJsonString");
1524
+ validateRedirectionBody(redirectUrlOptions.body, "fromJsonString");
1525
+ }
2142
1526
  if (appCallbackUrl) {
2143
1527
  validateURL(appCallbackUrl, "fromJsonString");
2144
1528
  }
2145
1529
  if (cancelRedirectUrl) {
2146
1530
  validateURL(cancelRedirectUrl, "fromJsonString");
2147
1531
  }
1532
+ if (cancelRedirectUrlOptions) {
1533
+ validateRedirectionMethod(cancelRedirectUrlOptions.method, "fromJsonString");
1534
+ validateRedirectionBody(cancelRedirectUrlOptions.body, "fromJsonString");
1535
+ }
2148
1536
  if (cancelCallbackUrl) {
2149
1537
  validateURL(cancelCallbackUrl, "fromJsonString");
2150
1538
  }
@@ -2198,6 +1586,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2198
1586
  proofRequestInstance.parameters = parameters;
2199
1587
  proofRequestInstance.appCallbackUrl = appCallbackUrl;
2200
1588
  proofRequestInstance.redirectUrl = redirectUrl;
1589
+ proofRequestInstance.redirectUrlOptions = redirectUrlOptions;
2201
1590
  proofRequestInstance.timeStamp = resolvedTimestamp;
2202
1591
  proofRequestInstance.signature = signature;
2203
1592
  proofRequestInstance.sdkVersion = sdkVersion2;
@@ -2206,6 +1595,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2206
1595
  proofRequestInstance.jsonProofResponse = jsonProofResponse != null ? jsonProofResponse : false;
2207
1596
  proofRequestInstance.cancelCallbackUrl = cancelCallbackUrl;
2208
1597
  proofRequestInstance.cancelRedirectUrl = cancelRedirectUrl;
1598
+ proofRequestInstance.cancelRedirectUrlOptions = cancelRedirectUrlOptions;
2209
1599
  return proofRequestInstance;
2210
1600
  } catch (error) {
2211
1601
  logger7.info("Failed to parse JSON string in fromJsonString:", error);
@@ -2216,13 +1606,16 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2216
1606
  /**
2217
1607
  * Sets a custom callback URL where proofs will be submitted via HTTP `POST`
2218
1608
  *
2219
- * 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`.
2220
1610
  * Pass function argument `jsonProofResponse` as `true` to send proofs with `Content-Type` as `application/json`.
2221
- *
1611
+ *
2222
1612
  * When a custom callback URL is set, proofs are sent to the custom URL *instead* of the Reclaim backend.
2223
- * 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 (`[]`)
2224
1614
  * instead of the proof data, as the proof is not available to the SDK in this flow.
2225
- *
1615
+ *
1616
+ * This verification session's id will be present in `X-Reclaim-Session-Id` header of the request.
1617
+ * The request URL will contain query param `allowAiWitness` with value `true` when AI Witness should be allowed by handler of the request.
1618
+ *
2226
1619
  * Note: InApp SDKs are unaffected by this property as they do not handle proof submission.
2227
1620
  *
2228
1621
  * @param url - The URL where proofs should be submitted via HTTP `POST`
@@ -2245,6 +1638,13 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2245
1638
  * Sets a redirect URL where users will be redirected after successfully acquiring and submitting proof
2246
1639
  *
2247
1640
  * @param url - The URL where users should be redirected after successful proof generation
1641
+ * @param method - The redirection method that should be used for redirection. Allowed options: `GET`, and `POST`.
1642
+ * `POST` form redirection is only supported in In-Browser SDK.
1643
+ * @param body - List of name-value pairs to be sent as the body of the form request.
1644
+ * `When `method` is set to `POST`, `body` will be sent with 'application/x-www-form-urlencoded' content type.
1645
+ * When `method` is set to `GET`, if `body` is set then `body` will be sent as query parameters.
1646
+ * Sending `body` on redirection is only supported in In-Browser SDK.
1647
+ *
2248
1648
  * @throws {InvalidParamError} When URL is invalid
2249
1649
  *
2250
1650
  * @example
@@ -2252,29 +1652,50 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2252
1652
  * proofRequest.setRedirectUrl('https://your-app.com/success');
2253
1653
  * ```
2254
1654
  */
2255
- setRedirectUrl(url) {
1655
+ setRedirectUrl(url, method = "GET", body) {
2256
1656
  validateURL(url, "setRedirectUrl");
1657
+ validateRedirectionMethod(method, "setRedirectUrl");
1658
+ validateRedirectionBody(body, "setRedirectUrl");
2257
1659
  this.redirectUrl = url;
1660
+ this.redirectUrlOptions = { method: method || "GET", body };
2258
1661
  }
2259
1662
  /**
2260
- * Sets a custom callback URL where errors that abort the verification process will be submitted via HTTP POST
2261
- *
2262
- * Errors will be HTTP POSTed with `header 'Content-Type': 'application/json'`.
2263
- * When a custom error callback URL is set, Reclaim will no longer receive errors upon submission,
2264
- * and listeners on the startSession method will not be triggered. Your application must
2265
- * coordinate with your backend to receive errors.
2266
- *
2267
- * @param url - The URL where errors should be submitted via HTTP POST
2268
- * @throws {InvalidParamError} When URL is invalid
2269
- *
2270
- * @example
2271
- * ```typescript
2272
- * proofRequest.setCancelCallbackUrl('https://your-backend.com/error-callback');
2273
- * ```
2274
- *
2275
- * @since 4.8.1
2276
- *
2277
- */
1663
+ * Sets a custom callback URL where errors that abort the verification process will be submitted via HTTP POST
1664
+ *
1665
+ * Errors will be HTTP POSTed with `header 'Content-Type': 'application/json'`.
1666
+ * When a custom error callback URL is set, Reclaim will no longer receive errors upon submission,
1667
+ * and listeners on the startSession method will not be triggered. Your application must
1668
+ * coordinate with your backend to receive errors.
1669
+ *
1670
+ * This verification session's id will be present in `X-Reclaim-Session-Id` header of the request.
1671
+ *
1672
+ * Following is the data format which is sent as an HTTP POST request to the url with `Content-Type: application/json`:
1673
+
1674
+ * ```json
1675
+ * {
1676
+ * "type": "string", // Name of the exception
1677
+ * "message": "string",
1678
+ * "sessionId": "string",
1679
+ * // context as canonicalized json string
1680
+ * "context": "string",
1681
+ * // Other fields with more details about error may be present
1682
+ * // [key: any]: any
1683
+ * }
1684
+ * ```
1685
+ *
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).
1687
+ *
1688
+ * @param url - The URL where errors should be submitted via HTTP POST
1689
+ * @throws {InvalidParamError} When URL is invalid
1690
+ *
1691
+ * @example
1692
+ * ```typescript
1693
+ * proofRequest.setCancelCallbackUrl('https://your-backend.com/error-callback');
1694
+ * ```
1695
+ *
1696
+ * @since 4.8.1
1697
+ *
1698
+ */
2278
1699
  setCancelCallbackUrl(url) {
2279
1700
  validateURL(url, "setCancelCallbackUrl");
2280
1701
  this.cancelCallbackUrl = url;
@@ -2283,19 +1704,28 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2283
1704
  * Sets an error redirect URL where users will be redirected after an error which aborts the verification process
2284
1705
  *
2285
1706
  * @param url - The URL where users should be redirected after an error which aborts the verification process
1707
+ * @param method - The redirection method that should be used for redirection. Allowed options: `GET`, and `POST`.
1708
+ * `POST` form redirection is only supported in In-Browser SDK.
1709
+ * @param body - List of name-value pairs to be sent as the body of the form request.
1710
+ * When `method` is set to `POST`, `body` will be sent with 'application/x-www-form-urlencoded' content type.
1711
+ * When `method` is set to `GET`, if `body` is set then `body` will be sent as query parameters.
1712
+ * Sending `body` on redirection is only supported in In-Browser SDK.
2286
1713
  * @throws {InvalidParamError} When URL is invalid
2287
1714
  *
2288
1715
  * @example
2289
1716
  * ```typescript
2290
1717
  * proofRequest.setCancelRedirectUrl('https://your-app.com/error');
2291
1718
  * ```
2292
- *
1719
+ *
2293
1720
  * @since 4.10.0
2294
- *
1721
+ *
2295
1722
  */
2296
- setCancelRedirectUrl(url) {
1723
+ setCancelRedirectUrl(url, method = "GET", body) {
2297
1724
  validateURL(url, "setCancelRedirectUrl");
1725
+ validateRedirectionMethod(method, "setCancelRedirectUrl");
1726
+ validateRedirectionBody(body, "setCancelRedirectUrl");
2298
1727
  this.cancelRedirectUrl = url;
1728
+ this.cancelRedirectUrlOptions = { method: method || "GET", body };
2299
1729
  }
2300
1730
  /**
2301
1731
  * Sets the claim creation type for the proof request
@@ -2339,12 +1769,12 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2339
1769
  * Sets additional context data to be stored with the claim
2340
1770
  *
2341
1771
  * This allows you to associate custom JSON serializable data with the proof claim.
2342
- * The context can be retrieved and validated when verifying the proof.
2343
- *
1772
+ * The context can be retrieved and validated when verifying the proof.
1773
+ *
2344
1774
  * Also see [setContext] which is an alternate way to set context that has an address & message.
2345
1775
  *
2346
1776
  * [setContext] and [setJsonContext] overwrite each other. Each call replaces the existing context.
2347
- *
1777
+ *
2348
1778
  * @param context - Any additional data you want to store with the claim. Should be serializable to a JSON string.
2349
1779
  * @throws {SetContextError} When context parameters are invalid
2350
1780
  *
@@ -2371,9 +1801,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2371
1801
  * The context can be retrieved and validated when verifying the proof.
2372
1802
  *
2373
1803
  * Also see [setJsonContext] which is an alternate way to set context that allows for custom JSON serializable data.
2374
- *
1804
+ *
2375
1805
  * [setContext] and [setJsonContext] overwrite each other. Each call replaces the existing context.
2376
- *
1806
+ *
2377
1807
  * @param address - Context address identifier
2378
1808
  * @param message - Additional data to associate with the address
2379
1809
  * @throws {SetContextError} When context parameters are invalid
@@ -2398,8 +1828,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2398
1828
  /**
2399
1829
  * @deprecated use setContext instead
2400
1830
  *
2401
- * @param address
2402
- * @param message additional data you want associated with the [address]
1831
+ * @param address
1832
+ * @param message additional data you want associated with the [address]
2403
1833
  */
2404
1834
  addContext(address, message) {
2405
1835
  this.setContext(address, message);
@@ -2536,13 +1966,13 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2536
1966
  generateSignature(applicationSecret) {
2537
1967
  return __async(this, null, function* () {
2538
1968
  try {
2539
- const wallet = new import_ethers6.ethers.Wallet(applicationSecret);
1969
+ const wallet = new import_ethers4.ethers.Wallet(applicationSecret);
2540
1970
  const canonicalData = (0, import_canonicalize3.default)({ providerId: this.providerId, timestamp: this.timeStamp });
2541
1971
  if (!canonicalData) {
2542
1972
  throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
2543
1973
  }
2544
- const messageHash = import_ethers6.ethers.keccak256(new TextEncoder().encode(canonicalData));
2545
- 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));
2546
1976
  } catch (err) {
2547
1977
  logger7.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, signature: ${this.signature}, timeStamp: ${this.timeStamp}`, err);
2548
1978
  throw new SignatureGeneratingError(`Error generating signature for applicationSecret: ${applicationSecret}`);
@@ -2590,12 +2020,14 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2590
2020
  parameters: this.parameters,
2591
2021
  signature: this.signature,
2592
2022
  redirectUrl: this.redirectUrl,
2023
+ redirectUrlOptions: this.redirectUrlOptions,
2593
2024
  cancelCallbackUrl: this.cancelCallbackUrl,
2594
2025
  cancelRedirectUrl: this.cancelRedirectUrl,
2026
+ cancelRedirectUrlOptions: this.cancelRedirectUrlOptions,
2595
2027
  timestamp: this.timeStamp,
2596
2028
  // New field with correct spelling
2597
2029
  timeStamp: this.timeStamp,
2598
- // @deprecated: Remove in future versions
2030
+ // @deprecated: Remove in future versions
2599
2031
  options: this.options,
2600
2032
  sdkVersion: this.sdkVersion,
2601
2033
  jsonProofResponse: this.jsonProofResponse,
@@ -2891,10 +2323,10 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2891
2323
  * In the custom-callback flow (where the SDK submits a proof to a provided callback URL),
2892
2324
  * onSuccess may be invoked with an empty array (onSuccess([])) when no proof is available
2893
2325
  * (this happens when a callback is set using setAppCallbackUrl where proof is sent to callback instead of reclaim backend).
2894
- *
2326
+ *
2895
2327
  * Please refer to the OnSuccess type signature ((proof?: Proof | Proof[]) => void)
2896
2328
  * and the startSession function source for more details.
2897
- *
2329
+ *
2898
2330
  * > [!TIP]
2899
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.
2900
2332
  *
@@ -3025,10 +2457,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
3025
2457
  };
3026
2458
  // Annotate the CommonJS export names for ESM import in node:
3027
2459
  0 && (module.exports = {
3028
- ClaimCreationType,
3029
- DeviceType,
3030
- RECLAIM_EXTENSION_ACTIONS,
3031
2460
  ReclaimProofRequest,
2461
+ assertValidProof,
3032
2462
  clearDeviceCache,
3033
2463
  getDeviceType,
3034
2464
  getMobileDeviceType,