@reclaimprotocol/js-sdk 4.8.0 → 4.9.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/README.md CHANGED
@@ -442,6 +442,23 @@ const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER
442
442
  });
443
443
  ```
444
444
 
445
+ 15. Set preferred locale for verification client:
446
+
447
+ An identifier used to select a user's language and formatting preferences.
448
+
449
+ This represents a Unicode Language Identifier (i.e. without Locale extensions), except variants are not supported.
450
+ Locales are expected to be canonicalized according to the "preferred value" entries in the [IANA Language Subtag Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry).
451
+ For example, `he`, and `iw` are equal and both have the languageCode `he`, because `iw` is a deprecated language subtag that was replaced by the subtag `he`.
452
+
453
+ Defaults to the browser's locale if available, otherwise English (en).
454
+
455
+ ```js
456
+ // Initialize with options
457
+ const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, {
458
+ preferredLocale: 'en-US',
459
+ });
460
+ ```
461
+
445
462
  ## Handling Proofs on Your Backend
446
463
 
447
464
  For production applications, it's recommended to handle proofs, and errors on your backend:
package/dist/index.d.ts CHANGED
@@ -81,6 +81,19 @@ type ProofRequestOptions = {
81
81
  * @default true
82
82
  */
83
83
  canAutoSubmit?: boolean;
84
+ /**
85
+ * An identifier used to select a user's language and formatting preferences.
86
+ *
87
+ * Locales are expected to be canonicalized according to the "preferred value" entries in the [IANA Language Subtag Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry).
88
+ * For example, `he`, and `iw` are equal and both have the languageCode `he`, because `iw` is a deprecated language subtag that was replaced by the subtag `he`.
89
+ *
90
+ * Defaults to the browser's locale if available, otherwise English (en).
91
+ *
92
+ * For more info, refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#description
93
+ *
94
+ * @since 4.9.0
95
+ */
96
+ preferredLocale?: string;
84
97
  /**
85
98
  * Additional metadata to pass to the verification client.
86
99
  * This can be used to customize the client experience, such as customizing themes or UI by passing context-specific information.
@@ -145,6 +158,8 @@ type ProofPropertiesJSON = {
145
158
  timeStamp?: string;
146
159
  timestamp?: string;
147
160
  appCallbackUrl?: string;
161
+ errorCallbackUrl?: TemplateData['errorCallbackUrl'];
162
+ errorRedirectUrl?: TemplateData['errorRedirectUrl'];
148
163
  claimCreationType?: ClaimCreationType;
149
164
  options?: ProofRequestOptions;
150
165
  sdkVersion: string;
@@ -152,6 +167,30 @@ type ProofPropertiesJSON = {
152
167
  resolvedProviderVersion: string;
153
168
  modalOptions?: SerializableModalOptions;
154
169
  };
170
+ type TemplateData = {
171
+ sessionId: string;
172
+ providerId: string;
173
+ applicationId: string;
174
+ signature: string;
175
+ timestamp: string;
176
+ callbackUrl: string;
177
+ context: string;
178
+ parameters: {
179
+ [key: string]: string;
180
+ };
181
+ redirectUrl: string;
182
+ errorCallbackUrl?: string | null;
183
+ errorRedirectUrl?: string | null;
184
+ acceptAiProviders: boolean;
185
+ sdkVersion: string;
186
+ jsonProofResponse?: boolean;
187
+ providerVersion?: string;
188
+ resolvedProviderVersion: string;
189
+ log?: boolean;
190
+ canAutoSubmit?: boolean;
191
+ metadata?: Record<string, string>;
192
+ preferredLocale?: ProofRequestOptions['preferredLocale'];
193
+ };
155
194
 
156
195
  /**
157
196
  * Verifies one or more Reclaim proofs by validating signatures and witness information
@@ -198,6 +237,8 @@ declare class ReclaimProofRequest {
198
237
  private resolvedProviderVersion?;
199
238
  private parameters;
200
239
  private redirectUrl?;
240
+ private errorCallbackUrl?;
241
+ private errorRedirectUrl?;
201
242
  private intervals;
202
243
  private timeStamp;
203
244
  private sdkVersion;
@@ -284,6 +325,41 @@ declare class ReclaimProofRequest {
284
325
  * ```
285
326
  */
286
327
  setRedirectUrl(url: string): void;
328
+ /**
329
+ * Sets a custom callback URL where errors that abort the verification process will be submitted via HTTP POST
330
+ *
331
+ * Errors will be HTTP POSTed with `header 'Content-Type': 'application/json'`.
332
+ * When a custom error callback URL is set, Reclaim will no longer receive errors upon submission,
333
+ * and listeners on the startSession method will not be triggered. Your application must
334
+ * coordinate with your backend to receive errors.
335
+ *
336
+ * @param url - The URL where errors should be submitted via HTTP POST
337
+ * @throws {InvalidParamError} When URL is invalid
338
+ *
339
+ * @example
340
+ * ```typescript
341
+ * proofRequest.setErrorCallbackUrl('https://your-backend.com/error-callback');
342
+ * ```
343
+ *
344
+ * @since 4.8.1
345
+ *
346
+ */
347
+ setErrorCallbackUrl(url: string): void;
348
+ /**
349
+ * Sets an error redirect URL where users will be redirected after an error which aborts the verification process
350
+ *
351
+ * @param url - The URL where users should be redirected after an error which aborts the verification process
352
+ * @throws {InvalidParamError} When URL is invalid
353
+ *
354
+ * @example
355
+ * ```typescript
356
+ * proofRequest.setErrorRedirectUrl('https://your-app.com/error');
357
+ * ```
358
+ *
359
+ * @since 4.8.1
360
+ *
361
+ */
362
+ setErrorRedirectUrl(url: string): void;
287
363
  /**
288
364
  * Sets the claim creation type for the proof request
289
365
  *
@@ -387,6 +463,22 @@ declare class ReclaimProofRequest {
387
463
  * ```
388
464
  */
389
465
  getAppCallbackUrl(): string;
466
+ /**
467
+ * Returns the currently configured error callback URL
468
+ *
469
+ * If no custom error callback URL was set via setErrorCallbackUrl(), this returns the default
470
+ * Reclaim service error callback URL with the current session ID.
471
+ *
472
+ * @returns The error callback URL where proofs will be submitted
473
+ * @throws {GetAppCallbackUrlError} When unable to retrieve the error callback URL
474
+ *
475
+ * @example
476
+ * ```typescript
477
+ * const callbackUrl = proofRequest.getErrorCallbackUrl();
478
+ * console.log('Errors will be sent to:', callbackUrl);
479
+ * ```
480
+ */
481
+ getErrorCallbackUrl(): string;
390
482
  /**
391
483
  * Returns the status URL for monitoring the current session
392
484
  *
package/dist/index.js CHANGED
@@ -72,7 +72,7 @@ var require_package = __commonJS({
72
72
  "package.json"(exports2, module2) {
73
73
  module2.exports = {
74
74
  name: "@reclaimprotocol/js-sdk",
75
- version: "4.7.0",
75
+ version: "4.9.0",
76
76
  description: "Designed to request proofs from the Reclaim protocol and manage the flow of claims and witness interactions.",
77
77
  main: "dist/index.js",
78
78
  types: "dist/index.d.ts",
@@ -104,6 +104,7 @@ var require_package = __commonJS({
104
104
  },
105
105
  scripts: {
106
106
  build: "sh scripts/build.sh",
107
+ prepare: "npm run build",
107
108
  release: "release-it",
108
109
  test: "jest",
109
110
  "test:watch": "jest --watch",
@@ -322,6 +323,7 @@ var GetAppCallbackUrlError = createErrorClass("GetAppCallbackUrlError");
322
323
  var StatusUrlError = createErrorClass("StatusUrlError");
323
324
  var InavlidParametersError = createErrorClass("InavlidParametersError");
324
325
  var ProofSubmissionFailedError = createErrorClass("ProofSubmissionFailedError");
326
+ var ErrorDuringVerificationError = createErrorClass("ErrorDuringVerificationError");
325
327
 
326
328
  // src/utils/logger.ts
327
329
  var SimpleLogger = class {
@@ -405,6 +407,10 @@ var constants = {
405
407
  get DEFAULT_RECLAIM_CALLBACK_URL() {
406
408
  return `${BACKEND_BASE_URL}/api/sdk/callback?callbackId=`;
407
409
  },
410
+ // Default error callback URL for Reclaim protocol
411
+ get DEFAULT_RECLAIM_ERROR_CALLBACK_URL() {
412
+ return `${BACKEND_BASE_URL}/api/sdk/error-callback?callbackId=`;
413
+ },
408
414
  // Default status URL for Reclaim sessions
409
415
  get DEFAULT_RECLAIM_STATUS_URL() {
410
416
  return `${BACKEND_BASE_URL}/api/sdk/session/`;
@@ -437,6 +443,12 @@ function validateFunctionParams(params, functionName) {
437
443
  }
438
444
  });
439
445
  }
446
+ function validateFunctionParamsWithFn(param, functionName) {
447
+ if (!param.isValid()) {
448
+ logger3.info(`Validation failed: ${param.paramName} in ${functionName} is not valid`);
449
+ throw new InvalidParamError(`${param.paramName} passed to ${functionName} must be valid.`);
450
+ }
451
+ }
440
452
  function validateParameters(parameters) {
441
453
  try {
442
454
  if (typeof parameters !== "object" || parameters === null) {
@@ -1861,6 +1873,8 @@ var emptyTemplateData = {
1861
1873
  context: "",
1862
1874
  parameters: {},
1863
1875
  redirectUrl: "",
1876
+ errorCallbackUrl: "",
1877
+ errorRedirectUrl: "",
1864
1878
  acceptAiProviders: false,
1865
1879
  sdkVersion: "",
1866
1880
  providerVersion: "",
@@ -1882,7 +1896,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1882
1896
  * @returns
1883
1897
  */
1884
1898
  this.getTemplateData = () => {
1885
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1899
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1886
1900
  if (!this.signature) {
1887
1901
  throw new SignatureNotFoundError("Signature is not set.");
1888
1902
  }
@@ -1899,12 +1913,15 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1899
1913
  resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
1900
1914
  parameters: this.parameters,
1901
1915
  redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
1916
+ errorCallbackUrl: this.getErrorCallbackUrl(),
1917
+ errorRedirectUrl: this.errorRedirectUrl,
1902
1918
  acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
1903
1919
  sdkVersion: this.sdkVersion,
1904
1920
  jsonProofResponse: this.jsonProofResponse,
1905
1921
  log: (_h = (_g = this.options) == null ? void 0 : _g.log) != null ? _h : false,
1906
1922
  canAutoSubmit: (_j = (_i = this.options) == null ? void 0 : _i.canAutoSubmit) != null ? _j : true,
1907
- metadata: (_k = this.options) == null ? void 0 : _k.metadata
1923
+ metadata: (_k = this.options) == null ? void 0 : _k.metadata,
1924
+ preferredLocale: (_l = this.options) == null ? void 0 : _l.preferredLocale
1908
1925
  };
1909
1926
  return templateData;
1910
1927
  };
@@ -2022,6 +2039,24 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2022
2039
  { paramName: "customAppClipUrl", input: options.customAppClipUrl, isString: true }
2023
2040
  ], "the constructor");
2024
2041
  }
2042
+ if (options.preferredLocale) {
2043
+ validateFunctionParams([
2044
+ { paramName: "preferredLocale", input: options.preferredLocale, isString: true }
2045
+ ], "the constructor");
2046
+ validateFunctionParamsWithFn({
2047
+ paramName: "preferredLocale",
2048
+ input: options.preferredLocale,
2049
+ isValid: () => {
2050
+ try {
2051
+ Intl.getCanonicalLocales(options.preferredLocale);
2052
+ return true;
2053
+ } catch (error) {
2054
+ logger7.info("Failed to canonicalize locale", error);
2055
+ return false;
2056
+ }
2057
+ }
2058
+ }, "the constructor");
2059
+ }
2025
2060
  }
2026
2061
  const proofRequestInstance = new _ReclaimProofRequest(applicationId, providerId, options);
2027
2062
  const signature = yield proofRequestInstance.generateSignature(appSecret);
@@ -2064,6 +2099,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2064
2099
  parameters,
2065
2100
  signature,
2066
2101
  redirectUrl,
2102
+ errorCallbackUrl,
2103
+ errorRedirectUrl,
2067
2104
  timeStamp,
2068
2105
  timestamp,
2069
2106
  appCallbackUrl,
@@ -2092,6 +2129,12 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2092
2129
  if (appCallbackUrl) {
2093
2130
  validateURL(appCallbackUrl, "fromJsonString");
2094
2131
  }
2132
+ if (errorRedirectUrl) {
2133
+ validateURL(errorRedirectUrl, "fromJsonString");
2134
+ }
2135
+ if (errorCallbackUrl) {
2136
+ validateURL(errorCallbackUrl, "fromJsonString");
2137
+ }
2095
2138
  if (context) {
2096
2139
  validateContext(context);
2097
2140
  }
@@ -2110,7 +2153,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2110
2153
  }
2111
2154
  if (options == null ? void 0 : options.providerVersion) {
2112
2155
  validateFunctionParams([
2113
- { input: options.providerVersion, paramName: "providerVersion", isString: true }
2156
+ { input: options.providerVersion, paramName: "options.providerVersion", isString: true }
2114
2157
  ], "fromJsonString");
2115
2158
  }
2116
2159
  if (resolvedProviderVersion) {
@@ -2118,6 +2161,24 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2118
2161
  { input: resolvedProviderVersion, paramName: "resolvedProviderVersion", isString: true }
2119
2162
  ], "fromJsonString");
2120
2163
  }
2164
+ if (options == null ? void 0 : options.preferredLocale) {
2165
+ validateFunctionParams([
2166
+ { paramName: "options.preferredLocale", input: options.preferredLocale, isString: true }
2167
+ ], "fromJsonString");
2168
+ validateFunctionParamsWithFn({
2169
+ paramName: "options.preferredLocale",
2170
+ input: options.preferredLocale,
2171
+ isValid: () => {
2172
+ try {
2173
+ Intl.getCanonicalLocales(options.preferredLocale);
2174
+ return true;
2175
+ } catch (error) {
2176
+ logger7.info("Failed to canonicalize locale", error);
2177
+ return false;
2178
+ }
2179
+ }
2180
+ }, "fromJsonString");
2181
+ }
2121
2182
  const proofRequestInstance = new _ReclaimProofRequest(applicationId, providerId, options);
2122
2183
  proofRequestInstance.sessionId = sessionId;
2123
2184
  proofRequestInstance.context = context;
@@ -2130,6 +2191,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2130
2191
  proofRequestInstance.resolvedProviderVersion = resolvedProviderVersion;
2131
2192
  proofRequestInstance.modalOptions = modalOptions;
2132
2193
  proofRequestInstance.jsonProofResponse = jsonProofResponse != null ? jsonProofResponse : false;
2194
+ proofRequestInstance.errorCallbackUrl = errorCallbackUrl;
2195
+ proofRequestInstance.errorRedirectUrl = errorRedirectUrl;
2133
2196
  return proofRequestInstance;
2134
2197
  } catch (error) {
2135
2198
  logger7.info("Failed to parse JSON string in fromJsonString:", error);
@@ -2178,6 +2241,47 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2178
2241
  validateURL(url, "setRedirectUrl");
2179
2242
  this.redirectUrl = url;
2180
2243
  }
2244
+ /**
2245
+ * Sets a custom callback URL where errors that abort the verification process will be submitted via HTTP POST
2246
+ *
2247
+ * Errors will be HTTP POSTed with `header 'Content-Type': 'application/json'`.
2248
+ * When a custom error callback URL is set, Reclaim will no longer receive errors upon submission,
2249
+ * and listeners on the startSession method will not be triggered. Your application must
2250
+ * coordinate with your backend to receive errors.
2251
+ *
2252
+ * @param url - The URL where errors should be submitted via HTTP POST
2253
+ * @throws {InvalidParamError} When URL is invalid
2254
+ *
2255
+ * @example
2256
+ * ```typescript
2257
+ * proofRequest.setErrorCallbackUrl('https://your-backend.com/error-callback');
2258
+ * ```
2259
+ *
2260
+ * @since 4.8.1
2261
+ *
2262
+ */
2263
+ setErrorCallbackUrl(url) {
2264
+ validateURL(url, "setErrorCallbackUrl");
2265
+ this.errorCallbackUrl = url;
2266
+ }
2267
+ /**
2268
+ * Sets an error redirect URL where users will be redirected after an error which aborts the verification process
2269
+ *
2270
+ * @param url - The URL where users should be redirected after an error which aborts the verification process
2271
+ * @throws {InvalidParamError} When URL is invalid
2272
+ *
2273
+ * @example
2274
+ * ```typescript
2275
+ * proofRequest.setErrorRedirectUrl('https://your-app.com/error');
2276
+ * ```
2277
+ *
2278
+ * @since 4.8.1
2279
+ *
2280
+ */
2281
+ setErrorRedirectUrl(url) {
2282
+ validateURL(url, "setErrorRedirectUrl");
2283
+ this.errorRedirectUrl = url;
2284
+ }
2181
2285
  /**
2182
2286
  * Sets the claim creation type for the proof request
2183
2287
  *
@@ -2329,6 +2433,30 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2329
2433
  throw new GetAppCallbackUrlError("Error getting app callback url", error);
2330
2434
  }
2331
2435
  }
2436
+ /**
2437
+ * Returns the currently configured error callback URL
2438
+ *
2439
+ * If no custom error callback URL was set via setErrorCallbackUrl(), this returns the default
2440
+ * Reclaim service error callback URL with the current session ID.
2441
+ *
2442
+ * @returns The error callback URL where proofs will be submitted
2443
+ * @throws {GetAppCallbackUrlError} When unable to retrieve the error callback URL
2444
+ *
2445
+ * @example
2446
+ * ```typescript
2447
+ * const callbackUrl = proofRequest.getErrorCallbackUrl();
2448
+ * console.log('Errors will be sent to:', callbackUrl);
2449
+ * ```
2450
+ */
2451
+ getErrorCallbackUrl() {
2452
+ try {
2453
+ validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getErrorCallbackUrl");
2454
+ return this.errorCallbackUrl || `${constants.DEFAULT_RECLAIM_ERROR_CALLBACK_URL}${this.sessionId}`;
2455
+ } catch (error) {
2456
+ logger7.info("Error getting error callback url", error);
2457
+ throw new GetAppCallbackUrlError("Error getting error callback url", error);
2458
+ }
2459
+ }
2332
2460
  /**
2333
2461
  * Returns the status URL for monitoring the current session
2334
2462
  *
@@ -2441,6 +2569,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2441
2569
  parameters: this.parameters,
2442
2570
  signature: this.signature,
2443
2571
  redirectUrl: this.redirectUrl,
2572
+ errorCallbackUrl: this.errorCallbackUrl,
2573
+ errorRedirectUrl: this.errorRedirectUrl,
2444
2574
  timestamp: this.timeStamp,
2445
2575
  // New field with correct spelling
2446
2576
  timeStamp: this.timeStamp,
@@ -2768,7 +2898,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2768
2898
  logger7.info("Starting session");
2769
2899
  const sessionUpdatePollingInterval = 3 * 1e3;
2770
2900
  const interval = setInterval(() => __async(this, null, function* () {
2771
- var _a, _b, _c;
2901
+ var _a, _b, _c, _d;
2772
2902
  try {
2773
2903
  const statusUrlResponse = yield fetchStatusUrl(this.sessionId);
2774
2904
  if (!statusUrlResponse.session) return;
@@ -2784,12 +2914,15 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2784
2914
  }
2785
2915
  return;
2786
2916
  }
2917
+ if (statusUrlResponse.session.statusV2 === "ERROR_SUBMISSION_FAILED" /* ERROR_SUBMISSION_FAILED */ || statusUrlResponse.session.statusV2 === "ERROR_SUBMITTED" /* ERROR_SUBMITTED */) {
2918
+ throw new ErrorDuringVerificationError();
2919
+ }
2787
2920
  const isDefaultCallbackUrl = this.getAppCallbackUrl() === `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`;
2788
2921
  if (isDefaultCallbackUrl) {
2789
2922
  if (statusUrlResponse.session.proofs && statusUrlResponse.session.proofs.length > 0) {
2790
2923
  const proofs = statusUrlResponse.session.proofs;
2791
2924
  if (this.claimCreationType === "createClaim" /* STANDALONE */) {
2792
- const verified = yield verifyProof(proofs);
2925
+ const verified = yield verifyProof(proofs, (_a = this.options) == null ? void 0 : _a.acceptAiProviders);
2793
2926
  if (!verified) {
2794
2927
  logger7.info(`Proofs not verified: ${JSON.stringify(proofs)}`);
2795
2928
  throw new ProofNotVerifiedError();
@@ -2801,7 +2934,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2801
2934
  onSuccess(proofs);
2802
2935
  }
2803
2936
  this.clearInterval();
2804
- (_a = this.modal) == null ? void 0 : _a.close();
2937
+ (_b = this.modal) == null ? void 0 : _b.close();
2805
2938
  }
2806
2939
  } else {
2807
2940
  if (statusUrlResponse.session.statusV2 === "PROOF_SUBMISSION_FAILED" /* PROOF_SUBMISSION_FAILED */) {
@@ -2812,7 +2945,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2812
2945
  onSuccess("Proof submitted successfully to the custom callback url");
2813
2946
  }
2814
2947
  this.clearInterval();
2815
- (_b = this.modal) == null ? void 0 : _b.close();
2948
+ (_c = this.modal) == null ? void 0 : _c.close();
2816
2949
  }
2817
2950
  }
2818
2951
  } catch (e) {
@@ -2820,7 +2953,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2820
2953
  onError(e);
2821
2954
  }
2822
2955
  this.clearInterval();
2823
- (_c = this.modal) == null ? void 0 : _c.close();
2956
+ (_d = this.modal) == null ? void 0 : _d.close();
2824
2957
  }
2825
2958
  }), sessionUpdatePollingInterval);
2826
2959
  this.intervals.set(this.sessionId, interval);