@reclaimprotocol/js-sdk 4.5.2 → 4.6.1

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.1",
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,15 @@ function clearDeviceCache() {
1757
1757
  cachedMobileType = null;
1758
1758
  }
1759
1759
 
1760
+ // src/utils/strings.ts
1761
+ var import_canonicalize2 = __toESM(require("canonicalize"));
1762
+ function canonicalStringify(params) {
1763
+ if (!params) {
1764
+ return "";
1765
+ }
1766
+ return (0, import_canonicalize2.default)(params) || "";
1767
+ }
1768
+
1760
1769
  // src/Reclaim.ts
1761
1770
  var logger7 = logger_default.logger;
1762
1771
  var sdkVersion = require_package().version;
@@ -1789,7 +1798,7 @@ function verifyProof(proofOrProofs, allowAiWitness) {
1789
1798
  }
1790
1799
  const calculatedIdentifier = getIdentifierFromClaimInfo({
1791
1800
  parameters: JSON.parse(
1792
- (0, import_canonicalize2.default)(proof.claimData.parameters)
1801
+ (0, import_canonicalize3.default)(proof.claimData.parameters)
1793
1802
  ),
1794
1803
  provider: proof.claimData.provider,
1795
1804
  context: proof.claimData.context
@@ -1849,14 +1858,41 @@ var emptyTemplateData = {
1849
1858
  };
1850
1859
  var ReclaimProofRequest = class _ReclaimProofRequest {
1851
1860
  // 30 seconds timeout, can be adjusted
1852
- // Private constructor
1853
1861
  constructor(applicationId, providerId, options) {
1854
1862
  this.context = { contextAddress: "0x0", contextMessage: "sample context" };
1855
1863
  this.claimCreationType = "createClaim" /* STANDALONE */;
1856
1864
  this.intervals = /* @__PURE__ */ new Map();
1857
1865
  this.jsonProofResponse = false;
1858
1866
  this.extensionID = "reclaim-extension";
1859
- this.FAILURE_TIMEOUT = 3e4;
1867
+ this.FAILURE_TIMEOUT = 30 * 1e3;
1868
+ /**
1869
+ * Validates signature and returns template data
1870
+ * @returns
1871
+ */
1872
+ this.getTemplateData = () => {
1873
+ var _a, _b, _c, _d, _e, _f;
1874
+ if (!this.signature) {
1875
+ throw new SignatureNotFoundError("Signature is not set.");
1876
+ }
1877
+ validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp);
1878
+ const templateData = {
1879
+ sessionId: this.sessionId,
1880
+ providerId: this.providerId,
1881
+ applicationId: this.applicationId,
1882
+ signature: this.signature,
1883
+ timestamp: this.timeStamp,
1884
+ callbackUrl: this.getAppCallbackUrl(),
1885
+ context: canonicalStringify(this.context),
1886
+ providerVersion: (_b = (_a = this.options) == null ? void 0 : _a.providerVersion) != null ? _b : "",
1887
+ resolvedProviderVersion: (_c = this.resolvedProviderVersion) != null ? _c : "",
1888
+ parameters: this.parameters,
1889
+ redirectUrl: (_d = this.redirectUrl) != null ? _d : "",
1890
+ acceptAiProviders: (_f = (_e = this.options) == null ? void 0 : _e.acceptAiProviders) != null ? _f : false,
1891
+ sdkVersion: this.sdkVersion,
1892
+ jsonProofResponse: this.jsonProofResponse
1893
+ };
1894
+ return templateData;
1895
+ };
1860
1896
  var _a;
1861
1897
  this.providerId = providerId;
1862
1898
  this.timeStamp = Date.now().toString();
@@ -1892,7 +1928,26 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1892
1928
  this.sdkVersion = "js-" + sdkVersion;
1893
1929
  logger7.info(`Initializing client with applicationId: ${this.applicationId}`);
1894
1930
  }
1895
- // Static initialization methods
1931
+ /**
1932
+ * Initializes a new Reclaim proof request instance with automatic signature generation and session creation
1933
+ *
1934
+ * @param applicationId - Your Reclaim application ID
1935
+ * @param appSecret - Your application secret key for signing requests
1936
+ * @param providerId - The ID of the provider to use for proof generation
1937
+ * @param options - Optional configuration options for the proof request
1938
+ * @returns Promise<ReclaimProofRequest> - A fully initialized proof request instance
1939
+ * @throws {InitError} When initialization fails due to invalid parameters or session creation errors
1940
+ *
1941
+ * @example
1942
+ * ```typescript
1943
+ * const proofRequest = await ReclaimProofRequest.init(
1944
+ * 'your-app-id',
1945
+ * 'your-app-secret',
1946
+ * 'provider-id',
1947
+ * { log: true, acceptAiProviders: true }
1948
+ * );
1949
+ * ```
1950
+ */
1896
1951
  static init(applicationId, appSecret, providerId, options) {
1897
1952
  return __async(this, null, function* () {
1898
1953
  try {
@@ -1966,6 +2021,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1966
2021
  }
1967
2022
  });
1968
2023
  }
2024
+ /**
2025
+ * Creates a ReclaimProofRequest instance from a JSON string representation
2026
+ *
2027
+ * This method deserializes a previously exported proof request (via toJsonString) and reconstructs
2028
+ * the instance with all its properties. Useful for recreating requests on the frontend or across different contexts.
2029
+ *
2030
+ * @param jsonString - JSON string containing the serialized proof request data
2031
+ * @returns {Promise<ReclaimProofRequest>} - Reconstructed proof request instance
2032
+ * @throws {InvalidParamError} When JSON string is invalid or contains invalid parameters
2033
+ *
2034
+ * @example
2035
+ * ```typescript
2036
+ * const jsonString = proofRequest.toJsonString();
2037
+ * const reconstructed = await ReclaimProofRequest.fromJsonString(jsonString);
2038
+ * // Can also be used with InApp SDK's startVerificationFromJson method
2039
+ * ```
2040
+ */
1969
2041
  static fromJsonString(jsonString) {
1970
2042
  return __async(this, null, function* () {
1971
2043
  try {
@@ -2047,19 +2119,75 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2047
2119
  }
2048
2120
  });
2049
2121
  }
2050
- // Setter methods
2122
+ /**
2123
+ * Sets a custom callback URL where proofs will be submitted via HTTP POST
2124
+ *
2125
+ * By default, proofs are posted as `application/x-www-form-urlencoded`.
2126
+ * When a custom callback URL is set, Reclaim will no longer receive proofs upon submission,
2127
+ * and listeners on the startSession method will not be triggered. Your application must
2128
+ * coordinate with your backend to receive and verify proofs using verifyProof().
2129
+ *
2130
+ * Note: InApp SDKs are unaffected by this property as they do not handle proof submission.
2131
+ *
2132
+ * @param url - The URL where proofs should be submitted via HTTP POST
2133
+ * @param jsonProofResponse - Optional. Set to true to submit proofs as `application/json`. Defaults to false
2134
+ * @throws {InvalidParamError} When URL is invalid
2135
+ *
2136
+ * @example
2137
+ * ```typescript
2138
+ * proofRequest.setAppCallbackUrl('https://your-backend.com/callback');
2139
+ * // Or with JSON format
2140
+ * proofRequest.setAppCallbackUrl('https://your-backend.com/callback', true);
2141
+ * ```
2142
+ */
2051
2143
  setAppCallbackUrl(url, jsonProofResponse) {
2052
2144
  validateURL(url, "setAppCallbackUrl");
2053
2145
  this.appCallbackUrl = url;
2054
2146
  this.jsonProofResponse = jsonProofResponse != null ? jsonProofResponse : false;
2055
2147
  }
2148
+ /**
2149
+ * Sets a redirect URL where users will be redirected after successfully acquiring and submitting proof
2150
+ *
2151
+ * @param url - The URL where users should be redirected after successful proof generation
2152
+ * @throws {InvalidParamError} When URL is invalid
2153
+ *
2154
+ * @example
2155
+ * ```typescript
2156
+ * proofRequest.setRedirectUrl('https://your-app.com/success');
2157
+ * ```
2158
+ */
2056
2159
  setRedirectUrl(url) {
2057
2160
  validateURL(url, "setRedirectUrl");
2058
2161
  this.redirectUrl = url;
2059
2162
  }
2163
+ /**
2164
+ * Sets the claim creation type for the proof request
2165
+ *
2166
+ * @param claimCreationType - The type of claim creation (e.g., STANDALONE)
2167
+ *
2168
+ * @example
2169
+ * ```typescript
2170
+ * proofRequest.setClaimCreationType(ClaimCreationType.STANDALONE);
2171
+ * ```
2172
+ */
2060
2173
  setClaimCreationType(claimCreationType) {
2061
2174
  this.claimCreationType = claimCreationType;
2062
2175
  }
2176
+ /**
2177
+ * Sets custom options for the QR code modal display
2178
+ *
2179
+ * @param options - Modal configuration options including title, description, theme, etc.
2180
+ * @throws {SetParamsError} When modal options are invalid
2181
+ *
2182
+ * @example
2183
+ * ```typescript
2184
+ * proofRequest.setModalOptions({
2185
+ * title: 'Scan QR Code',
2186
+ * description: 'Scan with your mobile device',
2187
+ * darkTheme: true
2188
+ * });
2189
+ * ```
2190
+ */
2063
2191
  setModalOptions(options) {
2064
2192
  try {
2065
2193
  validateModalOptions(options, "setModalOptions");
@@ -2070,6 +2198,48 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2070
2198
  throw new SetParamsError("Error setting modal options", error);
2071
2199
  }
2072
2200
  }
2201
+ /**
2202
+ * Sets additional context data to be stored with the claim
2203
+ *
2204
+ * This allows you to associate custom data (address and message) with the proof claim.
2205
+ * The context can be retrieved and validated when verifying the proof.
2206
+ *
2207
+ * Also see [setContext] which is an alternate way to set context that has an address & message.
2208
+ *
2209
+ * @param context - Any additional data you want to store with the claim. Should be serializable to a JSON string.
2210
+ * @throws {SetContextError} When context parameters are invalid
2211
+ *
2212
+ * @example
2213
+ * ```typescript
2214
+ * proofRequest.setJsonContext({foo: 'bar'});
2215
+ * ```
2216
+ */
2217
+ setJsonContext(context) {
2218
+ try {
2219
+ validateFunctionParams([
2220
+ { input: context, paramName: "context", isString: false }
2221
+ ], "setJsonContext");
2222
+ this.context = JSON.parse(canonicalStringify(context));
2223
+ } catch (error) {
2224
+ logger7.info("Error setting context", error);
2225
+ throw new SetContextError("Error setting context", error);
2226
+ }
2227
+ }
2228
+ /**
2229
+ * Sets additional context data to be stored with the claim
2230
+ *
2231
+ * This allows you to associate custom data (address and message) with the proof claim.
2232
+ * The context can be retrieved and validated when verifying the proof.
2233
+ *
2234
+ * @param address - Context address identifier
2235
+ * @param message - Additional data to associate with the address
2236
+ * @throws {SetContextError} When context parameters are invalid
2237
+ *
2238
+ * @example
2239
+ * ```typescript
2240
+ * proofRequest.setContext('0x1234...', 'User verification for premium access');
2241
+ * ```
2242
+ */
2073
2243
  setContext(address, message) {
2074
2244
  try {
2075
2245
  validateFunctionParams([
@@ -2082,10 +2252,32 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2082
2252
  throw new SetContextError("Error setting context", error);
2083
2253
  }
2084
2254
  }
2085
- // deprecated method: use setContext instead
2255
+ /**
2256
+ * @deprecated use setContext instead
2257
+ *
2258
+ * @param address
2259
+ * @param message additional data you want associated with the [address]
2260
+ */
2086
2261
  addContext(address, message) {
2087
2262
  this.setContext(address, message);
2088
2263
  }
2264
+ /**
2265
+ * Sets provider-specific parameters for the proof request
2266
+ *
2267
+ * These parameters are passed to the provider and may include configuration options,
2268
+ * filters, or other provider-specific settings required for proof generation.
2269
+ *
2270
+ * @param params - Key-value pairs of parameters to set
2271
+ * @throws {SetParamsError} When parameters are invalid
2272
+ *
2273
+ * @example
2274
+ * ```typescript
2275
+ * proofRequest.setParams({
2276
+ * minFollowers: '1000',
2277
+ * platform: 'twitter'
2278
+ * });
2279
+ * ```
2280
+ */
2089
2281
  setParams(params) {
2090
2282
  try {
2091
2283
  validateParameters(params);
@@ -2095,7 +2287,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2095
2287
  throw new SetParamsError("Error setting params", error);
2096
2288
  }
2097
2289
  }
2098
- // Getter methods
2290
+ /**
2291
+ * Returns the currently configured app callback URL
2292
+ *
2293
+ * If no custom callback URL was set via setAppCallbackUrl(), this returns the default
2294
+ * Reclaim service callback URL with the current session ID.
2295
+ *
2296
+ * @returns The callback URL where proofs will be submitted
2297
+ * @throws {GetAppCallbackUrlError} When unable to retrieve the callback URL
2298
+ *
2299
+ * @example
2300
+ * ```typescript
2301
+ * const callbackUrl = proofRequest.getAppCallbackUrl();
2302
+ * console.log('Proofs will be sent to:', callbackUrl);
2303
+ * ```
2304
+ */
2099
2305
  getAppCallbackUrl() {
2100
2306
  try {
2101
2307
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getAppCallbackUrl");
@@ -2105,6 +2311,20 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2105
2311
  throw new GetAppCallbackUrlError("Error getting app callback url", error);
2106
2312
  }
2107
2313
  }
2314
+ /**
2315
+ * Returns the status URL for monitoring the current session
2316
+ *
2317
+ * This URL can be used to check the status of the proof request session.
2318
+ *
2319
+ * @returns The status monitoring URL for the current session
2320
+ * @throws {GetStatusUrlError} When unable to retrieve the status URL
2321
+ *
2322
+ * @example
2323
+ * ```typescript
2324
+ * const statusUrl = proofRequest.getStatusUrl();
2325
+ * // Use this URL to poll for session status updates
2326
+ * ```
2327
+ */
2108
2328
  getStatusUrl() {
2109
2329
  try {
2110
2330
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getStatusUrl");
@@ -2114,7 +2334,21 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2114
2334
  throw new GetStatusUrlError("Error fetching status url", error);
2115
2335
  }
2116
2336
  }
2117
- // getter for SessionId
2337
+ /**
2338
+ * Returns the session ID associated with this proof request
2339
+ *
2340
+ * The session ID is automatically generated during initialization and uniquely
2341
+ * identifies this proof request session.
2342
+ *
2343
+ * @returns The session ID string
2344
+ * @throws {SessionNotStartedError} When session ID is not set
2345
+ *
2346
+ * @example
2347
+ * ```typescript
2348
+ * const sessionId = proofRequest.getSessionId();
2349
+ * console.log('Session ID:', sessionId);
2350
+ * ```
2351
+ */
2118
2352
  getSessionId() {
2119
2353
  if (!this.sessionId) {
2120
2354
  throw new SessionNotStartedError("SessionId is not set");
@@ -2136,7 +2370,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2136
2370
  return __async(this, null, function* () {
2137
2371
  try {
2138
2372
  const wallet = new import_ethers6.ethers.Wallet(applicationSecret);
2139
- const canonicalData = (0, import_canonicalize2.default)({ providerId: this.providerId, timestamp: this.timeStamp });
2373
+ const canonicalData = (0, import_canonicalize3.default)({ providerId: this.providerId, timestamp: this.timeStamp });
2140
2374
  if (!canonicalData) {
2141
2375
  throw new SignatureGeneratingError("Failed to canonicalize data for signing.");
2142
2376
  }
@@ -2161,7 +2395,22 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2161
2395
  }
2162
2396
  return `${baseUrl}/?template=${template}`;
2163
2397
  }
2164
- // Public methods
2398
+ /**
2399
+ * Exports the Reclaim proof verification request as a JSON string
2400
+ *
2401
+ * This serialized format can be sent to the frontend to recreate this request using
2402
+ * ReclaimProofRequest.fromJsonString() or any InApp SDK's startVerificationFromJson()
2403
+ * method to initiate the verification journey.
2404
+ *
2405
+ * @returns JSON string representation of the proof request
2406
+ *
2407
+ * @example
2408
+ * ```typescript
2409
+ * const jsonString = proofRequest.toJsonString();
2410
+ * // Send to frontend or store for later use
2411
+ * // Can be reconstructed with: ReclaimProofRequest.fromJsonString(jsonString)
2412
+ * ```
2413
+ */
2165
2414
  toJsonString() {
2166
2415
  var _a;
2167
2416
  return JSON.stringify({
@@ -2190,40 +2439,48 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2190
2439
  } : void 0
2191
2440
  });
2192
2441
  }
2193
- getRequestUrl() {
2442
+ /**
2443
+ * Generates and returns the request URL for proof verification
2444
+ *
2445
+ * This URL can be shared with users to initiate the proof generation process.
2446
+ * The URL format varies based on device type:
2447
+ * - Mobile iOS: Returns App Clip URL (if useAppClip is enabled)
2448
+ * - Mobile Android: Returns Instant App URL (if useAppClip is enabled)
2449
+ * - Desktop/Other: Returns standard verification URL
2450
+ *
2451
+ * @param launchOptions - Optional launch configuration to override default behavior
2452
+ * @returns Promise<string> - The generated request URL
2453
+ * @throws {SignatureNotFoundError} When signature is not set
2454
+ *
2455
+ * @example
2456
+ * ```typescript
2457
+ * const requestUrl = await proofRequest.getRequestUrl();
2458
+ * // Share this URL with users or display as QR code
2459
+ * ```
2460
+ */
2461
+ getRequestUrl(launchOptions) {
2194
2462
  return __async(this, null, function* () {
2195
- var _a, _b, _c, _d, _e, _f, _g;
2463
+ var _a, _b, _c;
2464
+ const options = launchOptions || ((_a = this.options) == null ? void 0 : _a.launchOptions) || {};
2196
2465
  logger7.info("Creating Request Url");
2197
2466
  if (!this.signature) {
2198
2467
  throw new SignatureNotFoundError("Signature is not set.");
2199
2468
  }
2200
2469
  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
- };
2470
+ const templateData = this.getTemplateData();
2218
2471
  yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2219
2472
  const deviceType = getDeviceType();
2220
- if (((_g = this.options) == null ? void 0 : _g.useAppClip) && deviceType === "mobile" /* MOBILE */) {
2473
+ if (((_b = this.options) == null ? void 0 : _b.useAppClip) && deviceType === "mobile" /* MOBILE */) {
2221
2474
  let template = encodeURIComponent(JSON.stringify(templateData));
2222
2475
  template = replaceAll(template, "(", "%28");
2223
2476
  template = replaceAll(template, ")", "%29");
2224
2477
  const isIos = getMobileDeviceType() === "ios" /* IOS */;
2225
2478
  if (!isIos) {
2226
- const instantAppUrl = this.buildSharePageUrl(template);
2479
+ let instantAppUrl = this.buildSharePageUrl(template);
2480
+ const isDeferredDeeplinksFlowEnabled = (_c = options.canUseDeferredDeepLinksFlow) != null ? _c : false;
2481
+ if (isDeferredDeeplinksFlowEnabled) {
2482
+ instantAppUrl = instantAppUrl.replace("/verifier", "/link");
2483
+ }
2227
2484
  logger7.info("Instant App Url created successfully: " + instantAppUrl);
2228
2485
  return instantAppUrl;
2229
2486
  } else {
@@ -2242,37 +2499,41 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2242
2499
  }
2243
2500
  });
2244
2501
  }
2245
- triggerReclaimFlow() {
2502
+ /**
2503
+ * Triggers the appropriate Reclaim verification flow based on device type and configuration
2504
+ *
2505
+ * This method automatically detects the device type and initiates the optimal verification flow:
2506
+ * - Desktop with browser extension: Triggers extension flow
2507
+ * - Desktop without extension: Shows QR code modal
2508
+ * - Mobile Android: Redirects to Instant App
2509
+ * - Mobile iOS: Redirects to App Clip
2510
+ *
2511
+ * @param launchOptions - Optional launch configuration to override default behavior
2512
+ * @returns Promise<void>
2513
+ * @throws {SignatureNotFoundError} When signature is not set
2514
+ *
2515
+ * @example
2516
+ * ```typescript
2517
+ * await proofRequest.triggerReclaimFlow();
2518
+ * // The appropriate verification method will be triggered automatically
2519
+ * ```
2520
+ */
2521
+ triggerReclaimFlow(launchOptions) {
2246
2522
  return __async(this, null, function* () {
2247
- var _a, _b, _c, _d, _e, _f, _g;
2523
+ var _a, _b;
2524
+ const options = launchOptions || ((_a = this.options) == null ? void 0 : _a.launchOptions) || {};
2248
2525
  if (!this.signature) {
2249
2526
  throw new SignatureNotFoundError("Signature is not set.");
2250
2527
  }
2251
2528
  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
- };
2529
+ const templateData = this.getTemplateData();
2269
2530
  this.templateData = templateData;
2270
2531
  logger7.info("Triggering Reclaim flow");
2271
2532
  const deviceType = getDeviceType();
2272
- yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2533
+ updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2273
2534
  if (deviceType === "desktop" /* DESKTOP */) {
2274
2535
  const extensionAvailable = yield this.isBrowserExtensionAvailable();
2275
- if (((_g = this.options) == null ? void 0 : _g.useBrowserExtension) && extensionAvailable) {
2536
+ if (((_b = this.options) == null ? void 0 : _b.useBrowserExtension) && extensionAvailable) {
2276
2537
  logger7.info("Triggering browser extension flow");
2277
2538
  this.triggerBrowserExtensionFlow();
2278
2539
  return;
@@ -2284,10 +2545,10 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2284
2545
  const mobileDeviceType = getMobileDeviceType();
2285
2546
  if (mobileDeviceType === "android" /* ANDROID */) {
2286
2547
  logger7.info("Redirecting to Android instant app");
2287
- yield this.redirectToInstantApp();
2548
+ yield this.redirectToInstantApp(options);
2288
2549
  } else if (mobileDeviceType === "ios" /* IOS */) {
2289
2550
  logger7.info("Redirecting to iOS app clip");
2290
- yield this.redirectToAppClip();
2551
+ this.redirectToAppClip();
2291
2552
  }
2292
2553
  }
2293
2554
  } catch (error) {
@@ -2296,6 +2557,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2296
2557
  }
2297
2558
  });
2298
2559
  }
2560
+ /**
2561
+ * Checks if the Reclaim browser extension is installed and available
2562
+ *
2563
+ * This method attempts to communicate with the browser extension to verify its availability.
2564
+ * It uses a timeout mechanism to quickly determine if the extension responds.
2565
+ *
2566
+ * @param timeout - Timeout in milliseconds to wait for extension response. Defaults to 200ms
2567
+ * @returns Promise<boolean> - True if extension is available, false otherwise
2568
+ *
2569
+ * @example
2570
+ * ```typescript
2571
+ * const hasExtension = await proofRequest.isBrowserExtensionAvailable();
2572
+ * if (hasExtension) {
2573
+ * console.log('Browser extension is installed');
2574
+ * }
2575
+ * ```
2576
+ */
2299
2577
  isBrowserExtensionAvailable(timeout = 200) {
2300
2578
  return __async(this, null, function* () {
2301
2579
  try {
@@ -2349,14 +2627,62 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2349
2627
  }
2350
2628
  });
2351
2629
  }
2352
- redirectToInstantApp() {
2630
+ redirectToInstantApp(options) {
2353
2631
  return __async(this, null, function* () {
2632
+ var _a;
2354
2633
  try {
2355
2634
  let template = encodeURIComponent(JSON.stringify(this.templateData));
2356
2635
  template = replaceAll(template, "(", "%28");
2357
2636
  template = replaceAll(template, ")", "%29");
2358
- const instantAppUrl = this.buildSharePageUrl(template);
2637
+ let instantAppUrl = this.buildSharePageUrl(template);
2359
2638
  logger7.info("Redirecting to Android instant app: " + instantAppUrl);
2639
+ const isDeferredDeeplinksFlowEnabled = (_a = options.canUseDeferredDeepLinksFlow) != null ? _a : false;
2640
+ if (isDeferredDeeplinksFlowEnabled) {
2641
+ instantAppUrl = instantAppUrl.replace("/verifier", "/link");
2642
+ const deepLink = `intent://details?id=org.reclaimprotocol.app&url=${encodeURIComponent(
2643
+ instantAppUrl
2644
+ )}&template=${template}#Intent;scheme=market;action=android.intent.action.VIEW;package=com.android.vending;end;`;
2645
+ try {
2646
+ const requestUrl = instantAppUrl;
2647
+ let appInstalled = false;
2648
+ let timeoutId;
2649
+ const iframe = document.createElement("iframe");
2650
+ iframe.style.display = "none";
2651
+ iframe.style.width = "1px";
2652
+ iframe.style.height = "1px";
2653
+ document.body.appendChild(iframe);
2654
+ const cleanup = () => {
2655
+ if (iframe.parentNode) {
2656
+ document.body.removeChild(iframe);
2657
+ }
2658
+ if (timeoutId) {
2659
+ clearTimeout(timeoutId);
2660
+ }
2661
+ };
2662
+ const onVisibilityChange = () => {
2663
+ if (document.hidden) {
2664
+ appInstalled = true;
2665
+ cleanup();
2666
+ window.location.href = deepLink;
2667
+ }
2668
+ };
2669
+ document.addEventListener("visibilitychange", onVisibilityChange, { once: true });
2670
+ iframe.src = deepLink.replace("intent:", "reclaimverifier:");
2671
+ timeoutId = setTimeout(() => {
2672
+ document.removeEventListener("visibilitychange", onVisibilityChange);
2673
+ cleanup();
2674
+ if (!appInstalled) {
2675
+ window.navigator.clipboard.writeText(requestUrl).catch(() => {
2676
+ console.error("We can't access the clipboard. Please copy this link and open Reclaim Verifier app.");
2677
+ });
2678
+ window.location.href = deepLink;
2679
+ }
2680
+ }, 1500);
2681
+ } catch (e) {
2682
+ window.location.href = instantAppUrl;
2683
+ }
2684
+ return;
2685
+ }
2360
2686
  window.location.href = instantAppUrl;
2361
2687
  } catch (error) {
2362
2688
  logger7.info("Error redirecting to instant app:", error);
@@ -2365,20 +2691,51 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2365
2691
  });
2366
2692
  }
2367
2693
  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);
2694
+ try {
2695
+ let template = encodeURIComponent(JSON.stringify(this.templateData));
2696
+ template = replaceAll(template, "(", "%28");
2697
+ template = replaceAll(template, ")", "%29");
2698
+ const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2699
+ logger7.info("Redirecting to iOS app clip: " + appClipUrl);
2700
+ window.location.href = appClipUrl;
2701
+ setTimeout(() => {
2375
2702
  window.location.href = appClipUrl;
2376
- } catch (error) {
2377
- logger7.info("Error redirecting to app clip:", error);
2378
- throw error;
2379
- }
2380
- });
2703
+ }, 5 * 1e3);
2704
+ } catch (error) {
2705
+ logger7.info("Error redirecting to app clip:", error);
2706
+ throw error;
2707
+ }
2381
2708
  }
2709
+ /**
2710
+ * Starts the proof request session and monitors for proof submission
2711
+ *
2712
+ * This method begins polling the session status to detect when
2713
+ * a proof has been generated and submitted. It handles both default Reclaim callbacks
2714
+ * and custom callback URLs.
2715
+ *
2716
+ * For default callbacks: Verifies proofs automatically and passes them to onSuccess
2717
+ * For custom callbacks: Monitors submission status and notifies via onSuccess when complete
2718
+ *
2719
+ * @param onSuccess - Callback function invoked when proof is successfully submitted
2720
+ * @param onError - Callback function invoked when an error occurs during the session
2721
+ * @returns Promise<void>
2722
+ * @throws {SessionNotStartedError} When session ID is not defined
2723
+ * @throws {ProofNotVerifiedError} When proof verification fails (default callback only)
2724
+ * @throws {ProofSubmissionFailedError} When proof submission fails (custom callback only)
2725
+ * @throws {ProviderFailedError} When proof generation fails with timeout
2726
+ *
2727
+ * @example
2728
+ * ```typescript
2729
+ * await proofRequest.startSession({
2730
+ * onSuccess: (proof) => {
2731
+ * console.log('Proof received:', proof);
2732
+ * },
2733
+ * onError: (error) => {
2734
+ * console.error('Error:', error);
2735
+ * }
2736
+ * });
2737
+ * ```
2738
+ */
2382
2739
  startSession(_0) {
2383
2740
  return __async(this, arguments, function* ({ onSuccess, onError }) {
2384
2741
  if (!this.sessionId) {
@@ -2387,6 +2744,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2387
2744
  throw new SessionNotStartedError(message);
2388
2745
  }
2389
2746
  logger7.info("Starting session");
2747
+ const sessionUpdatePollingInterval = 3 * 1e3;
2390
2748
  const interval = setInterval(() => __async(this, null, function* () {
2391
2749
  var _a, _b, _c;
2392
2750
  try {
@@ -2442,11 +2800,23 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
2442
2800
  this.clearInterval();
2443
2801
  (_c = this.modal) == null ? void 0 : _c.close();
2444
2802
  }
2445
- }), 3e3);
2803
+ }), sessionUpdatePollingInterval);
2446
2804
  this.intervals.set(this.sessionId, interval);
2447
2805
  scheduleIntervalEndingTask(this.sessionId, this.intervals, onError);
2448
2806
  });
2449
2807
  }
2808
+ /**
2809
+ * Closes the QR code modal if it is currently open
2810
+ *
2811
+ * This method can be called to programmatically close the modal, for example,
2812
+ * when implementing custom UI behavior or cleanup logic.
2813
+ *
2814
+ * @example
2815
+ * ```typescript
2816
+ * // Close modal after some condition
2817
+ * proofRequest.closeModal();
2818
+ * ```
2819
+ */
2450
2820
  closeModal() {
2451
2821
  if (this.modal) {
2452
2822
  this.modal.close();