@reclaimprotocol/js-sdk 4.5.1 → 4.6.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
@@ -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.5.1",
75
+ version: "4.6.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",
@@ -163,6 +163,9 @@ var require_package = __commonJS({
163
163
  "release-it": "^19.0.4",
164
164
  "url-parse": "^1.5.10",
165
165
  uuid: "^9.0.1"
166
+ },
167
+ overrides: {
168
+ "@conventional-changelog/git-client": "^2.0.0"
166
169
  }
167
170
  };
168
171
  }
@@ -259,7 +262,7 @@ var DeviceType = /* @__PURE__ */ ((DeviceType2) => {
259
262
 
260
263
  // src/Reclaim.ts
261
264
  var import_ethers6 = require("ethers");
262
- var import_canonicalize2 = __toESM(require("canonicalize"));
265
+ var import_canonicalize3 = __toESM(require("canonicalize"));
263
266
 
264
267
  // src/utils/errors.ts
265
268
  function createErrorClass(name) {
@@ -293,7 +296,7 @@ var BackendServerError = createErrorClass("BackendServerError");
293
296
  var GetStatusUrlError = createErrorClass("GetStatusUrlError");
294
297
  var NoProviderParamsError = createErrorClass("NoProviderParamsError");
295
298
  var SetParamsError = createErrorClass("SetParamsError");
296
- var AddContextError = createErrorClass("AddContextError");
299
+ var SetContextError = createErrorClass("SetContextError");
297
300
  var SetSignatureError = createErrorClass("SetSignatureError");
298
301
  var GetAppCallbackUrlError = createErrorClass("GetAppCallbackUrlError");
299
302
  var StatusUrlError = createErrorClass("StatusUrlError");
@@ -1754,6 +1757,114 @@ function clearDeviceCache() {
1754
1757
  cachedMobileType = null;
1755
1758
  }
1756
1759
 
1760
+ // src/utils/apis/feature.ts
1761
+ var fetchFeatureFlagsFromServer = (_0) => __async(null, [_0], function* ({
1762
+ featureFlagNames,
1763
+ publicKey,
1764
+ appId,
1765
+ providerId,
1766
+ sessionId
1767
+ }) {
1768
+ const queryParams = new URLSearchParams();
1769
+ if (publicKey) queryParams.append("publicKey", publicKey);
1770
+ featureFlagNames.forEach((name) => queryParams.append("featureFlagNames", name));
1771
+ if (appId) queryParams.append("appId", appId);
1772
+ if (providerId) queryParams.append("providerId", providerId);
1773
+ if (sessionId) queryParams.append("sessionId", sessionId);
1774
+ try {
1775
+ const response = yield fetch(
1776
+ `https://api.reclaimprotocol.org/api/feature-flags/get?${queryParams.toString()}`,
1777
+ {
1778
+ method: "GET",
1779
+ headers: {
1780
+ "Content-Type": "application/json"
1781
+ }
1782
+ }
1783
+ );
1784
+ if (response.ok) {
1785
+ const responseData = yield response.json();
1786
+ const featureFlags = {};
1787
+ for (const flag of responseData) {
1788
+ const flagName = flag.name;
1789
+ const flagValue = flag.value;
1790
+ if (flag.type === "boolean") {
1791
+ featureFlags[flagName] = typeof flagValue === "boolean" ? flagValue : false;
1792
+ } else if (flag.type === "string") {
1793
+ featureFlags[flagName] = typeof flagValue === "string" ? flagValue : "";
1794
+ } else if (flag.type === "number") {
1795
+ featureFlags[flagName] = typeof flagValue === "number" ? flagValue : 0;
1796
+ }
1797
+ }
1798
+ return featureFlags;
1799
+ } else {
1800
+ throw new Error(`Failed to load feature flags: ${response.status}`);
1801
+ }
1802
+ } catch (e) {
1803
+ console.error("Error fetching feature flags:", e);
1804
+ return {};
1805
+ }
1806
+ });
1807
+ var CACHE_DURATION = 60 * 60 * 1e3;
1808
+ var InMemoryCache = class {
1809
+ constructor() {
1810
+ this.storage = {};
1811
+ }
1812
+ getItem(key) {
1813
+ return this.storage[key];
1814
+ }
1815
+ setItem(key, value) {
1816
+ this.storage[key] = value.toString();
1817
+ }
1818
+ removeItem(key) {
1819
+ delete this.storage[key];
1820
+ }
1821
+ };
1822
+ var InternalCacheProvider = class {
1823
+ static provide() {
1824
+ if ("localStorage" in globalThis) {
1825
+ return globalThis.localStorage;
1826
+ }
1827
+ return this.inMemory;
1828
+ }
1829
+ };
1830
+ InternalCacheProvider.inMemory = new InMemoryCache();
1831
+ var _Features = class _Features {
1832
+ constructor() {
1833
+ }
1834
+ };
1835
+ _Features.isNewLinkingEnabled = (config) => __async(null, null, function* () {
1836
+ try {
1837
+ const featureFlags = yield fetchFeatureFlagsFromServer({
1838
+ featureFlagNames: ["newLinkingAndroid"],
1839
+ appId: config == null ? void 0 : config.applicationId,
1840
+ providerId: config == null ? void 0 : config.providerId,
1841
+ sessionId: config == null ? void 0 : config.sessionId
1842
+ });
1843
+ return featureFlags.newLinkingAndroid === true;
1844
+ } catch (error) {
1845
+ console.error("Error checking feature flag:", error);
1846
+ return false;
1847
+ }
1848
+ });
1849
+ _Features.isFirstAttemptToLaunchAppClip = () => {
1850
+ const storage = InternalCacheProvider.provide();
1851
+ const d = /* @__PURE__ */ new Date();
1852
+ const key = `isFirstAttemptToLaunchAppClip:${d.toDateString()}`;
1853
+ const value = storage.getItem(key);
1854
+ storage.setItem(key, "true");
1855
+ return value == "true";
1856
+ };
1857
+ var Features = _Features;
1858
+
1859
+ // src/utils/strings.ts
1860
+ var import_canonicalize2 = __toESM(require("canonicalize"));
1861
+ function canonicalStringify(params) {
1862
+ if (!params) {
1863
+ return "";
1864
+ }
1865
+ return (0, import_canonicalize2.default)(params) || "";
1866
+ }
1867
+
1757
1868
  // src/Reclaim.ts
1758
1869
  var logger7 = logger_default.logger;
1759
1870
  var sdkVersion = require_package().version;
@@ -1786,7 +1897,7 @@ function verifyProof(proofOrProofs, allowAiWitness) {
1786
1897
  }
1787
1898
  const calculatedIdentifier = getIdentifierFromClaimInfo({
1788
1899
  parameters: JSON.parse(
1789
- (0, import_canonicalize2.default)(proof.claimData.parameters)
1900
+ (0, import_canonicalize3.default)(proof.claimData.parameters)
1790
1901
  ),
1791
1902
  provider: proof.claimData.provider,
1792
1903
  context: proof.claimData.context
@@ -1845,15 +1956,41 @@ var emptyTemplateData = {
1845
1956
  jsonProofResponse: false
1846
1957
  };
1847
1958
  var ReclaimProofRequest = class _ReclaimProofRequest {
1848
- // 30 seconds timeout, can be adjusted
1849
- // Private constructor
1850
1959
  constructor(applicationId, providerId, options) {
1851
1960
  this.context = { contextAddress: "0x0", contextMessage: "sample context" };
1852
1961
  this.claimCreationType = "createClaim" /* STANDALONE */;
1853
1962
  this.intervals = /* @__PURE__ */ new Map();
1854
1963
  this.jsonProofResponse = false;
1855
1964
  this.extensionID = "reclaim-extension";
1856
- this.FAILURE_TIMEOUT = 3e4;
1965
+ this.FAILURE_TIMEOUT = 30 * 1e3;
1966
+ /**
1967
+ * Validates signature and returns template data
1968
+ * @returns
1969
+ */
1970
+ this.getTemplateData = () => {
1971
+ var _a, _b, _c, _d, _e, _f;
1972
+ if (!this.signature) {
1973
+ throw new SignatureNotFoundError("Signature is not set.");
1974
+ }
1975
+ validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp);
1976
+ const templateData = {
1977
+ sessionId: this.sessionId,
1978
+ providerId: this.providerId,
1979
+ applicationId: this.applicationId,
1980
+ signature: this.signature,
1981
+ timestamp: this.timeStamp,
1982
+ callbackUrl: this.getAppCallbackUrl(),
1983
+ context: canonicalStringify(this.context),
1984
+ providerVersion: (_b = (_a = this.options) == null ? void 0 : _a.providerVersion) != null ? _b : "",
1985
+ resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
1986
+ parameters: this.parameters,
1987
+ redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
1988
+ acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
1989
+ sdkVersion: this.sdkVersion,
1990
+ jsonProofResponse: this.jsonProofResponse
1991
+ };
1992
+ return templateData;
1993
+ };
1857
1994
  var _a;
1858
1995
  this.providerId = providerId;
1859
1996
  this.timeStamp = Date.now().toString();
@@ -1888,8 +2025,32 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1888
2025
  this.options = options;
1889
2026
  this.sdkVersion = "js-" + sdkVersion;
1890
2027
  logger7.info(`Initializing client with applicationId: ${this.applicationId}`);
2028
+ this.isNewLinkingEnabledAsync = Features.isNewLinkingEnabled({
2029
+ applicationId,
2030
+ providerId,
2031
+ sessionId: this.sessionId
2032
+ });
1891
2033
  }
1892
- // Static initialization methods
2034
+ /**
2035
+ * Initializes a new Reclaim proof request instance with automatic signature generation and session creation
2036
+ *
2037
+ * @param applicationId - Your Reclaim application ID
2038
+ * @param appSecret - Your application secret key for signing requests
2039
+ * @param providerId - The ID of the provider to use for proof generation
2040
+ * @param options - Optional configuration options for the proof request
2041
+ * @returns Promise<ReclaimProofRequest> - A fully initialized proof request instance
2042
+ * @throws {InitError} When initialization fails due to invalid parameters or session creation errors
2043
+ *
2044
+ * @example
2045
+ * ```typescript
2046
+ * const proofRequest = await ReclaimProofRequest.init(
2047
+ * 'your-app-id',
2048
+ * 'your-app-secret',
2049
+ * 'provider-id',
2050
+ * { log: true, acceptAiProviders: true }
2051
+ * );
2052
+ * ```
2053
+ */
1893
2054
  static init(applicationId, appSecret, providerId, options) {
1894
2055
  return __async(this, null, function* () {
1895
2056
  try {
@@ -1963,6 +2124,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1963
2124
  }
1964
2125
  });
1965
2126
  }
2127
+ /**
2128
+ * Creates a ReclaimProofRequest instance from a JSON string representation
2129
+ *
2130
+ * This method deserializes a previously exported proof request (via toJsonString) and reconstructs
2131
+ * the instance with all its properties. Useful for recreating requests on the frontend or across different contexts.
2132
+ *
2133
+ * @param jsonString - JSON string containing the serialized proof request data
2134
+ * @returns {Promise<ReclaimProofRequest>} - Reconstructed proof request instance
2135
+ * @throws {InvalidParamError} When JSON string is invalid or contains invalid parameters
2136
+ *
2137
+ * @example
2138
+ * ```typescript
2139
+ * const jsonString = proofRequest.toJsonString();
2140
+ * const reconstructed = await ReclaimProofRequest.fromJsonString(jsonString);
2141
+ * // Can also be used with InApp SDK's startVerificationFromJson method
2142
+ * ```
2143
+ */
1966
2144
  static fromJsonString(jsonString) {
1967
2145
  return __async(this, null, function* () {
1968
2146
  try {
@@ -2044,19 +2222,75 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2044
2222
  }
2045
2223
  });
2046
2224
  }
2047
- // Setter methods
2225
+ /**
2226
+ * Sets a custom callback URL where proofs will be submitted via HTTP POST
2227
+ *
2228
+ * By default, proofs are posted as `application/x-www-form-urlencoded`.
2229
+ * When a custom callback URL is set, Reclaim will no longer receive proofs upon submission,
2230
+ * and listeners on the startSession method will not be triggered. Your application must
2231
+ * coordinate with your backend to receive and verify proofs using verifyProof().
2232
+ *
2233
+ * Note: InApp SDKs are unaffected by this property as they do not handle proof submission.
2234
+ *
2235
+ * @param url - The URL where proofs should be submitted via HTTP POST
2236
+ * @param jsonProofResponse - Optional. Set to true to submit proofs as `application/json`. Defaults to false
2237
+ * @throws {InvalidParamError} When URL is invalid
2238
+ *
2239
+ * @example
2240
+ * ```typescript
2241
+ * proofRequest.setAppCallbackUrl('https://your-backend.com/callback');
2242
+ * // Or with JSON format
2243
+ * proofRequest.setAppCallbackUrl('https://your-backend.com/callback', true);
2244
+ * ```
2245
+ */
2048
2246
  setAppCallbackUrl(url, jsonProofResponse) {
2049
2247
  validateURL(url, "setAppCallbackUrl");
2050
2248
  this.appCallbackUrl = url;
2051
2249
  this.jsonProofResponse = jsonProofResponse != null ? jsonProofResponse : false;
2052
2250
  }
2251
+ /**
2252
+ * Sets a redirect URL where users will be redirected after successfully acquiring and submitting proof
2253
+ *
2254
+ * @param url - The URL where users should be redirected after successful proof generation
2255
+ * @throws {InvalidParamError} When URL is invalid
2256
+ *
2257
+ * @example
2258
+ * ```typescript
2259
+ * proofRequest.setRedirectUrl('https://your-app.com/success');
2260
+ * ```
2261
+ */
2053
2262
  setRedirectUrl(url) {
2054
2263
  validateURL(url, "setRedirectUrl");
2055
2264
  this.redirectUrl = url;
2056
2265
  }
2266
+ /**
2267
+ * Sets the claim creation type for the proof request
2268
+ *
2269
+ * @param claimCreationType - The type of claim creation (e.g., STANDALONE)
2270
+ *
2271
+ * @example
2272
+ * ```typescript
2273
+ * proofRequest.setClaimCreationType(ClaimCreationType.STANDALONE);
2274
+ * ```
2275
+ */
2057
2276
  setClaimCreationType(claimCreationType) {
2058
2277
  this.claimCreationType = claimCreationType;
2059
2278
  }
2279
+ /**
2280
+ * Sets custom options for the QR code modal display
2281
+ *
2282
+ * @param options - Modal configuration options including title, description, theme, etc.
2283
+ * @throws {SetParamsError} When modal options are invalid
2284
+ *
2285
+ * @example
2286
+ * ```typescript
2287
+ * proofRequest.setModalOptions({
2288
+ * title: 'Scan QR Code',
2289
+ * description: 'Scan with your mobile device',
2290
+ * darkTheme: true
2291
+ * });
2292
+ * ```
2293
+ */
2060
2294
  setModalOptions(options) {
2061
2295
  try {
2062
2296
  validateModalOptions(options, "setModalOptions");
@@ -2067,18 +2301,86 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2067
2301
  throw new SetParamsError("Error setting modal options", error);
2068
2302
  }
2069
2303
  }
2070
- addContext(address, message) {
2304
+ /**
2305
+ * Sets additional context data to be stored with the claim
2306
+ *
2307
+ * This allows you to associate custom data (address and message) with the proof claim.
2308
+ * The context can be retrieved and validated when verifying the proof.
2309
+ *
2310
+ * Also see [setContext] which is an alternate way to set context that has an address & message.
2311
+ *
2312
+ * @param context - Any additional data you want to store with the claim. Should be serializable to a JSON string.
2313
+ * @throws {SetContextError} When context parameters are invalid
2314
+ *
2315
+ * @example
2316
+ * ```typescript
2317
+ * proofRequest.setJsonContext({foo: 'bar'});
2318
+ * ```
2319
+ */
2320
+ setJsonContext(context) {
2321
+ try {
2322
+ validateFunctionParams([
2323
+ { input: context, paramName: "context", isString: false }
2324
+ ], "setJsonContext");
2325
+ this.context = JSON.parse(canonicalStringify(context));
2326
+ } catch (error) {
2327
+ logger7.info("Error setting context", error);
2328
+ throw new SetContextError("Error setting context", error);
2329
+ }
2330
+ }
2331
+ /**
2332
+ * Sets additional context data to be stored with the claim
2333
+ *
2334
+ * This allows you to associate custom data (address and message) with the proof claim.
2335
+ * The context can be retrieved and validated when verifying the proof.
2336
+ *
2337
+ * @param address - Context address identifier
2338
+ * @param message - Additional data to associate with the address
2339
+ * @throws {SetContextError} When context parameters are invalid
2340
+ *
2341
+ * @example
2342
+ * ```typescript
2343
+ * proofRequest.setContext('0x1234...', 'User verification for premium access');
2344
+ * ```
2345
+ */
2346
+ setContext(address, message) {
2071
2347
  try {
2072
2348
  validateFunctionParams([
2073
2349
  { input: address, paramName: "address", isString: true },
2074
2350
  { input: message, paramName: "message", isString: true }
2075
- ], "addContext");
2351
+ ], "setContext");
2076
2352
  this.context = { contextAddress: address, contextMessage: message };
2077
2353
  } catch (error) {
2078
- logger7.info("Error adding context", error);
2079
- throw new AddContextError("Error adding context", error);
2354
+ logger7.info("Error setting context", error);
2355
+ throw new SetContextError("Error setting context", error);
2080
2356
  }
2081
2357
  }
2358
+ /**
2359
+ * @deprecated use setContext instead
2360
+ *
2361
+ * @param address
2362
+ * @param message additional data you want associated with the [address]
2363
+ */
2364
+ addContext(address, message) {
2365
+ this.setContext(address, message);
2366
+ }
2367
+ /**
2368
+ * Sets provider-specific parameters for the proof request
2369
+ *
2370
+ * These parameters are passed to the provider and may include configuration options,
2371
+ * filters, or other provider-specific settings required for proof generation.
2372
+ *
2373
+ * @param params - Key-value pairs of parameters to set
2374
+ * @throws {SetParamsError} When parameters are invalid
2375
+ *
2376
+ * @example
2377
+ * ```typescript
2378
+ * proofRequest.setParams({
2379
+ * minFollowers: '1000',
2380
+ * platform: 'twitter'
2381
+ * });
2382
+ * ```
2383
+ */
2082
2384
  setParams(params) {
2083
2385
  try {
2084
2386
  validateParameters(params);
@@ -2088,7 +2390,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2088
2390
  throw new SetParamsError("Error setting params", error);
2089
2391
  }
2090
2392
  }
2091
- // Getter methods
2393
+ /**
2394
+ * Returns the currently configured app callback URL
2395
+ *
2396
+ * If no custom callback URL was set via setAppCallbackUrl(), this returns the default
2397
+ * Reclaim service callback URL with the current session ID.
2398
+ *
2399
+ * @returns The callback URL where proofs will be submitted
2400
+ * @throws {GetAppCallbackUrlError} When unable to retrieve the callback URL
2401
+ *
2402
+ * @example
2403
+ * ```typescript
2404
+ * const callbackUrl = proofRequest.getAppCallbackUrl();
2405
+ * console.log('Proofs will be sent to:', callbackUrl);
2406
+ * ```
2407
+ */
2092
2408
  getAppCallbackUrl() {
2093
2409
  try {
2094
2410
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getAppCallbackUrl");
@@ -2098,6 +2414,20 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2098
2414
  throw new GetAppCallbackUrlError("Error getting app callback url", error);
2099
2415
  }
2100
2416
  }
2417
+ /**
2418
+ * Returns the status URL for monitoring the current session
2419
+ *
2420
+ * This URL can be used to check the status of the proof request session.
2421
+ *
2422
+ * @returns The status monitoring URL for the current session
2423
+ * @throws {GetStatusUrlError} When unable to retrieve the status URL
2424
+ *
2425
+ * @example
2426
+ * ```typescript
2427
+ * const statusUrl = proofRequest.getStatusUrl();
2428
+ * // Use this URL to poll for session status updates
2429
+ * ```
2430
+ */
2101
2431
  getStatusUrl() {
2102
2432
  try {
2103
2433
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getStatusUrl");
@@ -2107,7 +2437,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2107
2437
  throw new GetStatusUrlError("Error fetching status url", error);
2108
2438
  }
2109
2439
  }
2110
- // getter for SessionId
2440
+ /**
2441
+ * Returns the session ID associated with this proof request
2442
+ *
2443
+ * The session ID is automatically generated during initialization and uniquely
2444
+ * identifies this proof request session.
2445
+ *
2446
+ * @returns The session ID string
2447
+ * @throws {SessionNotStartedError} When session ID is not set
2448
+ *
2449
+ * @example
2450
+ * ```typescript
2451
+ * const sessionId = proofRequest.getSessionId();
2452
+ * console.log('Session ID:', sessionId);
2453
+ * ```
2454
+ */
2111
2455
  getSessionId() {
2112
2456
  if (!this.sessionId) {
2113
2457
  throw new SessionNotStartedError("SessionId is not set");
@@ -2129,7 +2473,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2129
2473
  return __async(this, null, function* () {
2130
2474
  try {
2131
2475
  const wallet = new import_ethers6.ethers.Wallet(applicationSecret);
2132
- const canonicalData = (0, import_canonicalize2.default)({ providerId: this.providerId, timestamp: this.timeStamp });
2476
+ const canonicalData = (0, import_canonicalize3.default)({ providerId: this.providerId, timestamp: this.timeStamp });
2133
2477
  if (!canonicalData) {
2134
2478
  throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
2135
2479
  }
@@ -2154,7 +2498,22 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2154
2498
  }
2155
2499
  return `${baseUrl}/?template=${template}`;
2156
2500
  }
2157
- // Public methods
2501
+ /**
2502
+ * Exports the Reclaim proof verification request as a JSON string
2503
+ *
2504
+ * This serialized format can be sent to the frontend to recreate this request using
2505
+ * ReclaimProofRequest.fromJsonString() or any InApp SDK's startVerificationFromJson()
2506
+ * method to initiate the verification journey.
2507
+ *
2508
+ * @returns JSON string representation of the proof request
2509
+ *
2510
+ * @example
2511
+ * ```typescript
2512
+ * const jsonString = proofRequest.toJsonString();
2513
+ * // Send to frontend or store for later use
2514
+ * // Can be reconstructed with: ReclaimProofRequest.fromJsonString(jsonString)
2515
+ * ```
2516
+ */
2158
2517
  toJsonString() {
2159
2518
  var _a;
2160
2519
  return JSON.stringify({
@@ -2183,40 +2542,45 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2183
2542
  } : void 0
2184
2543
  });
2185
2544
  }
2545
+ /**
2546
+ * Generates and returns the request URL for proof verification
2547
+ *
2548
+ * This URL can be shared with users to initiate the proof generation process.
2549
+ * The URL format varies based on device type:
2550
+ * - Mobile iOS: Returns App Clip URL (if useAppClip is enabled)
2551
+ * - Mobile Android: Returns Instant App URL (if useAppClip is enabled)
2552
+ * - Desktop/Other: Returns standard verification URL
2553
+ *
2554
+ * @returns Promise<string> - The generated request URL
2555
+ * @throws {SignatureNotFoundError} When signature is not set
2556
+ *
2557
+ * @example
2558
+ * ```typescript
2559
+ * const requestUrl = await proofRequest.getRequestUrl();
2560
+ * // Share this URL with users or display as QR code
2561
+ * ```
2562
+ */
2186
2563
  getRequestUrl() {
2187
2564
  return __async(this, null, function* () {
2188
- var _a, _b, _c, _d, _e, _f, _g;
2565
+ var _a;
2189
2566
  logger7.info("Creating Request Url");
2190
2567
  if (!this.signature) {
2191
2568
  throw new SignatureNotFoundError("Signature is not set.");
2192
2569
  }
2193
2570
  try {
2194
- validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp);
2195
- const templateData = {
2196
- sessionId: this.sessionId,
2197
- providerId: this.providerId,
2198
- providerVersion: (_b = (_a = this.options) == null ? void 0 : _a.providerVersion) != null ? _b : "",
2199
- resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
2200
- applicationId: this.applicationId,
2201
- signature: this.signature,
2202
- timestamp: this.timeStamp,
2203
- callbackUrl: this.getAppCallbackUrl(),
2204
- context: JSON.stringify(this.context),
2205
- parameters: this.parameters,
2206
- redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
2207
- acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
2208
- sdkVersion: this.sdkVersion,
2209
- jsonProofResponse: this.jsonProofResponse
2210
- };
2571
+ const templateData = this.getTemplateData();
2211
2572
  yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2212
2573
  const deviceType = getDeviceType();
2213
- if (((_g = this.options) == null ? void 0 : _g.useAppClip) && deviceType === "mobile" /* MOBILE */) {
2574
+ if (((_a = this.options) == null ? void 0 : _a.useAppClip) && deviceType === "mobile" /* MOBILE */) {
2214
2575
  let template = encodeURIComponent(JSON.stringify(templateData));
2215
2576
  template = replaceAll(template, "(", "%28");
2216
2577
  template = replaceAll(template, ")", "%29");
2217
2578
  const isIos = getMobileDeviceType() === "ios" /* IOS */;
2218
2579
  if (!isIos) {
2219
- const instantAppUrl = this.buildSharePageUrl(template);
2580
+ let instantAppUrl = this.buildSharePageUrl(template);
2581
+ if (yield this.isNewLinkingEnabledAsync) {
2582
+ instantAppUrl = instantAppUrl.replace("/verifier", "/link");
2583
+ }
2220
2584
  logger7.info("Instant App Url created successfully: " + instantAppUrl);
2221
2585
  return instantAppUrl;
2222
2586
  } else {
@@ -2235,37 +2599,39 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2235
2599
  }
2236
2600
  });
2237
2601
  }
2602
+ /**
2603
+ * Triggers the appropriate Reclaim verification flow based on device type and configuration
2604
+ *
2605
+ * This method automatically detects the device type and initiates the optimal verification flow:
2606
+ * - Desktop with browser extension: Triggers extension flow
2607
+ * - Desktop without extension: Shows QR code modal
2608
+ * - Mobile Android: Redirects to Instant App
2609
+ * - Mobile iOS: Redirects to App Clip
2610
+ *
2611
+ * @returns Promise<void>
2612
+ * @throws {SignatureNotFoundError} When signature is not set
2613
+ *
2614
+ * @example
2615
+ * ```typescript
2616
+ * await proofRequest.triggerReclaimFlow();
2617
+ * // The appropriate verification method will be triggered automatically
2618
+ * ```
2619
+ */
2238
2620
  triggerReclaimFlow() {
2239
2621
  return __async(this, null, function* () {
2240
- var _a, _b, _c, _d, _e, _f, _g;
2622
+ var _a;
2241
2623
  if (!this.signature) {
2242
2624
  throw new SignatureNotFoundError("Signature is not set.");
2243
2625
  }
2244
2626
  try {
2245
- validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp);
2246
- const templateData = {
2247
- sessionId: this.sessionId,
2248
- providerId: this.providerId,
2249
- applicationId: this.applicationId,
2250
- signature: this.signature,
2251
- timestamp: this.timeStamp,
2252
- callbackUrl: this.getAppCallbackUrl(),
2253
- context: JSON.stringify(this.context),
2254
- providerVersion: (_b = (_a = this.options) == null ? void 0 : _a.providerVersion) != null ? _b : "",
2255
- resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
2256
- parameters: this.parameters,
2257
- redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
2258
- acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
2259
- sdkVersion: this.sdkVersion,
2260
- jsonProofResponse: this.jsonProofResponse
2261
- };
2627
+ const templateData = this.getTemplateData();
2262
2628
  this.templateData = templateData;
2263
2629
  logger7.info("Triggering Reclaim flow");
2264
2630
  const deviceType = getDeviceType();
2265
- yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2631
+ updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2266
2632
  if (deviceType === "desktop" /* DESKTOP */) {
2267
2633
  const extensionAvailable = yield this.isBrowserExtensionAvailable();
2268
- if (((_g = this.options) == null ? void 0 : _g.useBrowserExtension) && extensionAvailable) {
2634
+ if (((_a = this.options) == null ? void 0 : _a.useBrowserExtension) && extensionAvailable) {
2269
2635
  logger7.info("Triggering browser extension flow");
2270
2636
  this.triggerBrowserExtensionFlow();
2271
2637
  return;
@@ -2280,7 +2646,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2280
2646
  yield this.redirectToInstantApp();
2281
2647
  } else if (mobileDeviceType === "ios" /* IOS */) {
2282
2648
  logger7.info("Redirecting to iOS app clip");
2283
- yield this.redirectToAppClip();
2649
+ this.redirectToAppClip();
2284
2650
  }
2285
2651
  }
2286
2652
  } catch (error) {
@@ -2289,6 +2655,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2289
2655
  }
2290
2656
  });
2291
2657
  }
2658
+ /**
2659
+ * Checks if the Reclaim browser extension is installed and available
2660
+ *
2661
+ * This method attempts to communicate with the browser extension to verify its availability.
2662
+ * It uses a timeout mechanism to quickly determine if the extension responds.
2663
+ *
2664
+ * @param timeout - Timeout in milliseconds to wait for extension response. Defaults to 200ms
2665
+ * @returns Promise<boolean> - True if extension is available, false otherwise
2666
+ *
2667
+ * @example
2668
+ * ```typescript
2669
+ * const hasExtension = await proofRequest.isBrowserExtensionAvailable();
2670
+ * if (hasExtension) {
2671
+ * console.log('Browser extension is installed');
2672
+ * }
2673
+ * ```
2674
+ */
2292
2675
  isBrowserExtensionAvailable(timeout = 200) {
2293
2676
  return __async(this, null, function* () {
2294
2677
  try {
@@ -2348,8 +2731,54 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2348
2731
  let template = encodeURIComponent(JSON.stringify(this.templateData));
2349
2732
  template = replaceAll(template, "(", "%28");
2350
2733
  template = replaceAll(template, ")", "%29");
2351
- const instantAppUrl = this.buildSharePageUrl(template);
2734
+ let instantAppUrl = this.buildSharePageUrl(template);
2352
2735
  logger7.info("Redirecting to Android instant app: " + instantAppUrl);
2736
+ if (yield this.isNewLinkingEnabledAsync) {
2737
+ instantAppUrl = instantAppUrl.replace("/verifier", "/link");
2738
+ const deepLink = `intent://details?id=org.reclaimprotocol.app&url=${encodeURIComponent(
2739
+ instantAppUrl
2740
+ )}&template=${template}#Intent;scheme=market;action=android.intent.action.VIEW;package=com.android.vending;end;`;
2741
+ try {
2742
+ const requestUrl = instantAppUrl;
2743
+ let appInstalled = false;
2744
+ let timeoutId;
2745
+ const iframe = document.createElement("iframe");
2746
+ iframe.style.display = "none";
2747
+ iframe.style.width = "1px";
2748
+ iframe.style.height = "1px";
2749
+ document.body.appendChild(iframe);
2750
+ const cleanup = () => {
2751
+ if (iframe.parentNode) {
2752
+ document.body.removeChild(iframe);
2753
+ }
2754
+ if (timeoutId) {
2755
+ clearTimeout(timeoutId);
2756
+ }
2757
+ };
2758
+ const onVisibilityChange = () => {
2759
+ if (document.hidden) {
2760
+ appInstalled = true;
2761
+ cleanup();
2762
+ window.location.href = deepLink;
2763
+ }
2764
+ };
2765
+ document.addEventListener("visibilitychange", onVisibilityChange, { once: true });
2766
+ iframe.src = deepLink.replace("intent:", "reclaimverifier:");
2767
+ timeoutId = setTimeout(() => {
2768
+ document.removeEventListener("visibilitychange", onVisibilityChange);
2769
+ cleanup();
2770
+ if (!appInstalled) {
2771
+ window.navigator.clipboard.writeText(requestUrl).catch(() => {
2772
+ console.error("We can't access the clipboard. Please copy this link and open Reclaim Verifier app.");
2773
+ });
2774
+ window.location.href = deepLink;
2775
+ }
2776
+ }, 1500);
2777
+ } catch (e) {
2778
+ window.location.href = instantAppUrl;
2779
+ }
2780
+ return;
2781
+ }
2353
2782
  window.location.href = instantAppUrl;
2354
2783
  } catch (error) {
2355
2784
  logger7.info("Error redirecting to instant app:", error);
@@ -2358,20 +2787,53 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2358
2787
  });
2359
2788
  }
2360
2789
  redirectToAppClip() {
2361
- return __async(this, null, function* () {
2362
- try {
2363
- let template = encodeURIComponent(JSON.stringify(this.templateData));
2364
- template = replaceAll(template, "(", "%28");
2365
- template = replaceAll(template, ")", "%29");
2366
- const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2367
- logger7.info("Redirecting to iOS app clip: " + appClipUrl);
2368
- window.location.href = appClipUrl;
2369
- } catch (error) {
2370
- logger7.info("Error redirecting to app clip:", error);
2371
- throw error;
2790
+ try {
2791
+ let template = encodeURIComponent(JSON.stringify(this.templateData));
2792
+ template = replaceAll(template, "(", "%28");
2793
+ template = replaceAll(template, ")", "%29");
2794
+ const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2795
+ logger7.info("Redirecting to iOS app clip: " + appClipUrl);
2796
+ window.location.href = appClipUrl;
2797
+ if (Features.isFirstAttemptToLaunchAppClip()) {
2798
+ setTimeout(() => {
2799
+ window.location.href = appClipUrl;
2800
+ }, 2e3);
2372
2801
  }
2373
- });
2802
+ } catch (error) {
2803
+ logger7.info("Error redirecting to app clip:", error);
2804
+ throw error;
2805
+ }
2374
2806
  }
2807
+ /**
2808
+ * Starts the proof request session and monitors for proof submission
2809
+ *
2810
+ * This method begins polling the session status to detect when
2811
+ * a proof has been generated and submitted. It handles both default Reclaim callbacks
2812
+ * and custom callback URLs.
2813
+ *
2814
+ * For default callbacks: Verifies proofs automatically and passes them to onSuccess
2815
+ * For custom callbacks: Monitors submission status and notifies via onSuccess when complete
2816
+ *
2817
+ * @param onSuccess - Callback function invoked when proof is successfully submitted
2818
+ * @param onError - Callback function invoked when an error occurs during the session
2819
+ * @returns Promise<void>
2820
+ * @throws {SessionNotStartedError} When session ID is not defined
2821
+ * @throws {ProofNotVerifiedError} When proof verification fails (default callback only)
2822
+ * @throws {ProofSubmissionFailedError} When proof submission fails (custom callback only)
2823
+ * @throws {ProviderFailedError} When proof generation fails with timeout
2824
+ *
2825
+ * @example
2826
+ * ```typescript
2827
+ * await proofRequest.startSession({
2828
+ * onSuccess: (proof) => {
2829
+ * console.log('Proof received:', proof);
2830
+ * },
2831
+ * onError: (error) => {
2832
+ * console.error('Error:', error);
2833
+ * }
2834
+ * });
2835
+ * ```
2836
+ */
2375
2837
  startSession(_0) {
2376
2838
  return __async(this, arguments, function* ({ onSuccess, onError }) {
2377
2839
  if (!this.sessionId) {
@@ -2380,6 +2842,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2380
2842
  throw new SessionNotStartedError(message);
2381
2843
  }
2382
2844
  logger7.info("Starting session");
2845
+ const sessionUpdatePollingInterval = 3 * 1e3;
2383
2846
  const interval = setInterval(() => __async(this, null, function* () {
2384
2847
  var _a, _b, _c;
2385
2848
  try {
@@ -2435,11 +2898,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2435
2898
  this.clearInterval();
2436
2899
  (_c = this.modal) == null ? void 0 : _c.close();
2437
2900
  }
2438
- }), 3e3);
2901
+ }), sessionUpdatePollingInterval);
2439
2902
  this.intervals.set(this.sessionId, interval);
2440
2903
  scheduleIntervalEndingTask(this.sessionId, this.intervals, onError);
2441
2904
  });
2442
2905
  }
2906
+ /**
2907
+ * Closes the QR code modal if it is currently open
2908
+ *
2909
+ * This method can be called to programmatically close the modal, for example,
2910
+ * when implementing custom UI behavior or cleanup logic.
2911
+ *
2912
+ * @example
2913
+ * ```typescript
2914
+ * // Close modal after some condition
2915
+ * proofRequest.closeModal();
2916
+ * ```
2917
+ */
2443
2918
  closeModal() {
2444
2919
  if (this.modal) {
2445
2920
  this.modal.close();