@reclaimprotocol/js-sdk 4.5.2 → 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.2",
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",
@@ -262,7 +262,7 @@ var DeviceType = /* @__PURE__ */ ((DeviceType2) => {
262
262
 
263
263
  // src/Reclaim.ts
264
264
  var import_ethers6 = require("ethers");
265
- var import_canonicalize2 = __toESM(require("canonicalize"));
265
+ var import_canonicalize3 = __toESM(require("canonicalize"));
266
266
 
267
267
  // src/utils/errors.ts
268
268
  function createErrorClass(name) {
@@ -1757,6 +1757,114 @@ function clearDeviceCache() {
1757
1757
  cachedMobileType = null;
1758
1758
  }
1759
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
+
1760
1868
  // src/Reclaim.ts
1761
1869
  var logger7 = logger_default.logger;
1762
1870
  var sdkVersion = require_package().version;
@@ -1789,7 +1897,7 @@ function verifyProof(proofOrProofs, allowAiWitness) {
1789
1897
  }
1790
1898
  const calculatedIdentifier = getIdentifierFromClaimInfo({
1791
1899
  parameters: JSON.parse(
1792
- (0, import_canonicalize2.default)(proof.claimData.parameters)
1900
+ (0, import_canonicalize3.default)(proof.claimData.parameters)
1793
1901
  ),
1794
1902
  provider: proof.claimData.provider,
1795
1903
  context: proof.claimData.context
@@ -1848,15 +1956,41 @@ var emptyTemplateData = {
1848
1956
  jsonProofResponse: false
1849
1957
  };
1850
1958
  var ReclaimProofRequest = class _ReclaimProofRequest {
1851
- // 30 seconds timeout, can be adjusted
1852
- // Private constructor
1853
1959
  constructor(applicationId, providerId, options) {
1854
1960
  this.context = { contextAddress: "0x0", contextMessage: "sample context" };
1855
1961
  this.claimCreationType = "createClaim" /* STANDALONE */;
1856
1962
  this.intervals = /* @__PURE__ */ new Map();
1857
1963
  this.jsonProofResponse = false;
1858
1964
  this.extensionID = "reclaim-extension";
1859
- 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
+ };
1860
1994
  var _a;
1861
1995
  this.providerId = providerId;
1862
1996
  this.timeStamp = Date.now().toString();
@@ -1891,8 +2025,32 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1891
2025
  this.options = options;
1892
2026
  this.sdkVersion = "js-" + sdkVersion;
1893
2027
  logger7.info(`Initializing client with applicationId: ${this.applicationId}`);
2028
+ this.isNewLinkingEnabledAsync = Features.isNewLinkingEnabled({
2029
+ applicationId,
2030
+ providerId,
2031
+ sessionId: this.sessionId
2032
+ });
1894
2033
  }
1895
- // 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
+ */
1896
2054
  static init(applicationId, appSecret, providerId, options) {
1897
2055
  return __async(this, null, function* () {
1898
2056
  try {
@@ -1966,6 +2124,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1966
2124
  }
1967
2125
  });
1968
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
+ */
1969
2144
  static fromJsonString(jsonString) {
1970
2145
  return __async(this, null, function* () {
1971
2146
  try {
@@ -2047,19 +2222,75 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2047
2222
  }
2048
2223
  });
2049
2224
  }
2050
- // 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
+ */
2051
2246
  setAppCallbackUrl(url, jsonProofResponse) {
2052
2247
  validateURL(url, "setAppCallbackUrl");
2053
2248
  this.appCallbackUrl = url;
2054
2249
  this.jsonProofResponse = jsonProofResponse != null ? jsonProofResponse : false;
2055
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
+ */
2056
2262
  setRedirectUrl(url) {
2057
2263
  validateURL(url, "setRedirectUrl");
2058
2264
  this.redirectUrl = url;
2059
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
+ */
2060
2276
  setClaimCreationType(claimCreationType) {
2061
2277
  this.claimCreationType = claimCreationType;
2062
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
+ */
2063
2294
  setModalOptions(options) {
2064
2295
  try {
2065
2296
  validateModalOptions(options, "setModalOptions");
@@ -2070,6 +2301,48 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2070
2301
  throw new SetParamsError("Error setting modal options", error);
2071
2302
  }
2072
2303
  }
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
+ */
2073
2346
  setContext(address, message) {
2074
2347
  try {
2075
2348
  validateFunctionParams([
@@ -2082,10 +2355,32 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2082
2355
  throw new SetContextError("Error setting context", error);
2083
2356
  }
2084
2357
  }
2085
- // deprecated method: use setContext instead
2358
+ /**
2359
+ * @deprecated use setContext instead
2360
+ *
2361
+ * @param address
2362
+ * @param message additional data you want associated with the [address]
2363
+ */
2086
2364
  addContext(address, message) {
2087
2365
  this.setContext(address, message);
2088
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
+ */
2089
2384
  setParams(params) {
2090
2385
  try {
2091
2386
  validateParameters(params);
@@ -2095,7 +2390,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2095
2390
  throw new SetParamsError("Error setting params", error);
2096
2391
  }
2097
2392
  }
2098
- // 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
+ */
2099
2408
  getAppCallbackUrl() {
2100
2409
  try {
2101
2410
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getAppCallbackUrl");
@@ -2105,6 +2414,20 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2105
2414
  throw new GetAppCallbackUrlError("Error getting app callback url", error);
2106
2415
  }
2107
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
+ */
2108
2431
  getStatusUrl() {
2109
2432
  try {
2110
2433
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getStatusUrl");
@@ -2114,7 +2437,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2114
2437
  throw new GetStatusUrlError("Error fetching status url", error);
2115
2438
  }
2116
2439
  }
2117
- // 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
+ */
2118
2455
  getSessionId() {
2119
2456
  if (!this.sessionId) {
2120
2457
  throw new SessionNotStartedError("SessionId is not set");
@@ -2136,7 +2473,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2136
2473
  return __async(this, null, function* () {
2137
2474
  try {
2138
2475
  const wallet = new import_ethers6.ethers.Wallet(applicationSecret);
2139
- 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 });
2140
2477
  if (!canonicalData) {
2141
2478
  throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
2142
2479
  }
@@ -2161,7 +2498,22 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2161
2498
  }
2162
2499
  return `${baseUrl}/?template=${template}`;
2163
2500
  }
2164
- // 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
+ */
2165
2517
  toJsonString() {
2166
2518
  var _a;
2167
2519
  return JSON.stringify({
@@ -2190,40 +2542,45 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2190
2542
  } : void 0
2191
2543
  });
2192
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
+ */
2193
2563
  getRequestUrl() {
2194
2564
  return __async(this, null, function* () {
2195
- var _a, _b, _c, _d, _e, _f, _g;
2565
+ var _a;
2196
2566
  logger7.info("Creating Request Url");
2197
2567
  if (!this.signature) {
2198
2568
  throw new SignatureNotFoundError("Signature is not set.");
2199
2569
  }
2200
2570
  try {
2201
- validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp);
2202
- const templateData = {
2203
- sessionId: this.sessionId,
2204
- providerId: this.providerId,
2205
- providerVersion: (_b = (_a = this.options) == null ? void 0 : _a.providerVersion) != null ? _b : "",
2206
- resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
2207
- applicationId: this.applicationId,
2208
- signature: this.signature,
2209
- timestamp: this.timeStamp,
2210
- callbackUrl: this.getAppCallbackUrl(),
2211
- context: JSON.stringify(this.context),
2212
- parameters: this.parameters,
2213
- redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
2214
- acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
2215
- sdkVersion: this.sdkVersion,
2216
- jsonProofResponse: this.jsonProofResponse
2217
- };
2571
+ const templateData = this.getTemplateData();
2218
2572
  yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2219
2573
  const deviceType = getDeviceType();
2220
- 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 */) {
2221
2575
  let template = encodeURIComponent(JSON.stringify(templateData));
2222
2576
  template = replaceAll(template, "(", "%28");
2223
2577
  template = replaceAll(template, ")", "%29");
2224
2578
  const isIos = getMobileDeviceType() === "ios" /* IOS */;
2225
2579
  if (!isIos) {
2226
- const instantAppUrl = this.buildSharePageUrl(template);
2580
+ let instantAppUrl = this.buildSharePageUrl(template);
2581
+ if (yield this.isNewLinkingEnabledAsync) {
2582
+ instantAppUrl = instantAppUrl.replace("/verifier", "/link");
2583
+ }
2227
2584
  logger7.info("Instant App Url created successfully: " + instantAppUrl);
2228
2585
  return instantAppUrl;
2229
2586
  } else {
@@ -2242,37 +2599,39 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2242
2599
  }
2243
2600
  });
2244
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
+ */
2245
2620
  triggerReclaimFlow() {
2246
2621
  return __async(this, null, function* () {
2247
- var _a, _b, _c, _d, _e, _f, _g;
2622
+ var _a;
2248
2623
  if (!this.signature) {
2249
2624
  throw new SignatureNotFoundError("Signature is not set.");
2250
2625
  }
2251
2626
  try {
2252
- validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp);
2253
- const templateData = {
2254
- sessionId: this.sessionId,
2255
- providerId: this.providerId,
2256
- applicationId: this.applicationId,
2257
- signature: this.signature,
2258
- timestamp: this.timeStamp,
2259
- callbackUrl: this.getAppCallbackUrl(),
2260
- context: JSON.stringify(this.context),
2261
- providerVersion: (_b = (_a = this.options) == null ? void 0 : _a.providerVersion) != null ? _b : "",
2262
- resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
2263
- parameters: this.parameters,
2264
- redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
2265
- acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
2266
- sdkVersion: this.sdkVersion,
2267
- jsonProofResponse: this.jsonProofResponse
2268
- };
2627
+ const templateData = this.getTemplateData();
2269
2628
  this.templateData = templateData;
2270
2629
  logger7.info("Triggering Reclaim flow");
2271
2630
  const deviceType = getDeviceType();
2272
- yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2631
+ updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2273
2632
  if (deviceType === "desktop" /* DESKTOP */) {
2274
2633
  const extensionAvailable = yield this.isBrowserExtensionAvailable();
2275
- if (((_g = this.options) == null ? void 0 : _g.useBrowserExtension) && extensionAvailable) {
2634
+ if (((_a = this.options) == null ? void 0 : _a.useBrowserExtension) && extensionAvailable) {
2276
2635
  logger7.info("Triggering browser extension flow");
2277
2636
  this.triggerBrowserExtensionFlow();
2278
2637
  return;
@@ -2287,7 +2646,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2287
2646
  yield this.redirectToInstantApp();
2288
2647
  } else if (mobileDeviceType === "ios" /* IOS */) {
2289
2648
  logger7.info("Redirecting to iOS app clip");
2290
- yield this.redirectToAppClip();
2649
+ this.redirectToAppClip();
2291
2650
  }
2292
2651
  }
2293
2652
  } catch (error) {
@@ -2296,6 +2655,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2296
2655
  }
2297
2656
  });
2298
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
+ */
2299
2675
  isBrowserExtensionAvailable(timeout = 200) {
2300
2676
  return __async(this, null, function* () {
2301
2677
  try {
@@ -2355,8 +2731,54 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2355
2731
  let template = encodeURIComponent(JSON.stringify(this.templateData));
2356
2732
  template = replaceAll(template, "(", "%28");
2357
2733
  template = replaceAll(template, ")", "%29");
2358
- const instantAppUrl = this.buildSharePageUrl(template);
2734
+ let instantAppUrl = this.buildSharePageUrl(template);
2359
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
+ }
2360
2782
  window.location.href = instantAppUrl;
2361
2783
  } catch (error) {
2362
2784
  logger7.info("Error redirecting to instant app:", error);
@@ -2365,20 +2787,53 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2365
2787
  });
2366
2788
  }
2367
2789
  redirectToAppClip() {
2368
- return __async(this, null, function* () {
2369
- try {
2370
- let template = encodeURIComponent(JSON.stringify(this.templateData));
2371
- template = replaceAll(template, "(", "%28");
2372
- template = replaceAll(template, ")", "%29");
2373
- const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2374
- logger7.info("Redirecting to iOS app clip: " + appClipUrl);
2375
- window.location.href = appClipUrl;
2376
- } catch (error) {
2377
- logger7.info("Error redirecting to app clip:", error);
2378
- 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);
2379
2801
  }
2380
- });
2802
+ } catch (error) {
2803
+ logger7.info("Error redirecting to app clip:", error);
2804
+ throw error;
2805
+ }
2381
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
+ */
2382
2837
  startSession(_0) {
2383
2838
  return __async(this, arguments, function* ({ onSuccess, onError }) {
2384
2839
  if (!this.sessionId) {
@@ -2387,6 +2842,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2387
2842
  throw new SessionNotStartedError(message);
2388
2843
  }
2389
2844
  logger7.info("Starting session");
2845
+ const sessionUpdatePollingInterval = 3 * 1e3;
2390
2846
  const interval = setInterval(() => __async(this, null, function* () {
2391
2847
  var _a, _b, _c;
2392
2848
  try {
@@ -2442,11 +2898,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2442
2898
  this.clearInterval();
2443
2899
  (_c = this.modal) == null ? void 0 : _c.close();
2444
2900
  }
2445
- }), 3e3);
2901
+ }), sessionUpdatePollingInterval);
2446
2902
  this.intervals.set(this.sessionId, interval);
2447
2903
  scheduleIntervalEndingTask(this.sessionId, this.intervals, onError);
2448
2904
  });
2449
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
+ */
2450
2918
  closeModal() {
2451
2919
  if (this.modal) {
2452
2920
  this.modal.close();