@reclaimprotocol/js-sdk 3.0.4 → 4.0.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: "3.0.3",
75
+ version: "4.0.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",
@@ -167,12 +167,21 @@ var require_package = __commonJS({
167
167
  var index_exports = {};
168
168
  __export(index_exports, {
169
169
  ClaimCreationType: () => ClaimCreationType,
170
+ RECLAIM_EXTENSION_ACTIONS: () => RECLAIM_EXTENSION_ACTIONS,
170
171
  ReclaimProofRequest: () => ReclaimProofRequest,
171
172
  transformForOnchain: () => transformForOnchain,
172
173
  verifyProof: () => verifyProof
173
174
  });
174
175
  module.exports = __toCommonJS(index_exports);
175
176
 
177
+ // src/utils/interfaces.ts
178
+ var RECLAIM_EXTENSION_ACTIONS = {
179
+ CHECK_EXTENSION: "RECLAIM_EXTENSION_CHECK",
180
+ EXTENSION_RESPONSE: "RECLAIM_EXTENSION_RESPONSE",
181
+ START_VERIFICATION: "RECLAIM_START_VERIFICATION",
182
+ STATUS_UPDATE: "RECLAIM_STATUS_UPDATE"
183
+ };
184
+
176
185
  // src/witness.ts
177
186
  var import_ethers = require("ethers");
178
187
  function fetchWitnessListForClaim({ witnesses, witnessesRequiredForClaim, epoch }, params, timestampS) {
@@ -360,7 +369,11 @@ var constants = {
360
369
  return `${BACKEND_BASE_URL}/api/sdk/session/`;
361
370
  },
362
371
  // URL for sharing Reclaim templates
363
- RECLAIM_SHARE_URL: "https://share.reclaimprotocol.org/verifier/?template="
372
+ RECLAIM_SHARE_URL: "https://share.reclaimprotocol.org/verifier/?template=",
373
+ // Chrome extension URL for Reclaim Protocol
374
+ CHROME_EXTENSION_URL: "https://chromewebstore.google.com/",
375
+ // QR Code API base URL
376
+ QR_CODE_API_URL: "https://api.qrserver.com/v1/create-qr-code/"
364
377
  };
365
378
 
366
379
  // src/utils/validationUtils.ts
@@ -1232,18 +1245,401 @@ function assertValidSignedClaim(claim, expectedWitnessAddresses) {
1232
1245
  }
1233
1246
  }
1234
1247
 
1248
+ // src/utils/modalUtils.ts
1249
+ var logger6 = logger_default.logger;
1250
+ var QRCodeModal = class {
1251
+ constructor(options = {}) {
1252
+ this.countdownSeconds = 60;
1253
+ this.modalId = "reclaim-qr-modal";
1254
+ this.options = __spreadValues({
1255
+ title: "Verify with Reclaim",
1256
+ description: "Scan the QR code with your mobile device to complete verification",
1257
+ extensionUrl: constants.CHROME_EXTENSION_URL,
1258
+ darkTheme: false
1259
+ }, options);
1260
+ }
1261
+ show(requestUrl) {
1262
+ return __async(this, null, function* () {
1263
+ try {
1264
+ this.close();
1265
+ const modalHTML = this.createModalHTML();
1266
+ document.body.insertAdjacentHTML("beforeend", modalHTML);
1267
+ yield this.generateQRCode(requestUrl, "reclaim-qr-code");
1268
+ this.addEventListeners();
1269
+ this.startAutoCloseTimer();
1270
+ } catch (error) {
1271
+ logger6.info("Error showing QR code modal:", error);
1272
+ throw error;
1273
+ }
1274
+ });
1275
+ }
1276
+ close() {
1277
+ if (this.autoCloseTimer) {
1278
+ clearTimeout(this.autoCloseTimer);
1279
+ this.autoCloseTimer = void 0;
1280
+ }
1281
+ if (this.countdownTimer) {
1282
+ clearInterval(this.countdownTimer);
1283
+ this.countdownTimer = void 0;
1284
+ }
1285
+ const modal = document.getElementById(this.modalId);
1286
+ if (modal) {
1287
+ modal.remove();
1288
+ }
1289
+ if (this.options.onClose) {
1290
+ this.options.onClose();
1291
+ }
1292
+ }
1293
+ getThemeStyles() {
1294
+ const isDark = this.options.darkTheme;
1295
+ return {
1296
+ modalBackground: isDark ? "rgba(0, 0, 0, 0.8)" : "rgba(0, 0, 0, 0.5)",
1297
+ cardBackground: isDark ? "#1f2937" : "white",
1298
+ titleColor: isDark ? "#f9fafb" : "#1f2937",
1299
+ textColor: isDark ? "#d1d5db" : "#6b7280",
1300
+ qrBackground: isDark ? "#374151" : "#f9fafb",
1301
+ tipBackground: isDark ? "#1e40af" : "#f0f9ff",
1302
+ tipBorder: isDark ? "#1e40af" : "#e0f2fe",
1303
+ tipTextColor: isDark ? "#dbeafe" : "#0369a1",
1304
+ buttonBackground: isDark ? "#374151" : "#f3f4f6",
1305
+ buttonColor: isDark ? "#f9fafb" : "#374151",
1306
+ buttonHoverBackground: isDark ? "#4b5563" : "#e5e7eb",
1307
+ countdownColor: isDark ? "#6b7280" : "#9ca3af",
1308
+ progressBackground: isDark ? "#4b5563" : "#e5e7eb",
1309
+ progressGradient: isDark ? "linear-gradient(90deg, #3b82f6 0%, #2563eb 50%, #1d4ed8 100%)" : "linear-gradient(90deg, #2563eb 0%, #1d4ed8 50%, #1e40af 100%)",
1310
+ linkColor: isDark ? "#60a5fa" : "#2563eb",
1311
+ extensionButtonBackground: isDark ? "#1e40af" : "#2563eb",
1312
+ extensionButtonHover: isDark ? "#1d4ed8" : "#1d4ed8"
1313
+ };
1314
+ }
1315
+ createModalHTML() {
1316
+ const styles = this.getThemeStyles();
1317
+ return `
1318
+ <div id="${this.modalId}" style="
1319
+ position: fixed;
1320
+ top: 0;
1321
+ left: 0;
1322
+ width: 100%;
1323
+ height: 100%;
1324
+ background-color: ${styles.modalBackground};
1325
+ display: flex;
1326
+ justify-content: center;
1327
+ align-items: center;
1328
+ z-index: 10000;
1329
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1330
+ ">
1331
+ <div style="
1332
+ background: ${styles.cardBackground};
1333
+ border-radius: 12px;
1334
+ padding: 32px;
1335
+ max-width: 400px;
1336
+ width: 90%;
1337
+ text-align: center;
1338
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
1339
+ position: relative;
1340
+ ">
1341
+ <button id="reclaim-close-modal" style="
1342
+ position: absolute;
1343
+ top: 16px;
1344
+ right: 16px;
1345
+ background: none;
1346
+ border: none;
1347
+ cursor: pointer;
1348
+ padding: 4px;
1349
+ border-radius: 6px;
1350
+ display: flex;
1351
+ align-items: center;
1352
+ justify-content: center;
1353
+ transition: background-color 0.2s;
1354
+ width: 32px;
1355
+ height: 32px;
1356
+ "
1357
+ onmouseover="this.style.backgroundColor='${styles.buttonHoverBackground}'"
1358
+ onmouseout="this.style.backgroundColor='transparent'"
1359
+ title="Close modal">
1360
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
1361
+ <path d="M12 4L4 12M4 4L12 12" stroke="${styles.buttonColor}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
1362
+ </svg>
1363
+ </button>
1364
+
1365
+ <h2 style="
1366
+ margin: 0 0 16px 0;
1367
+ font-size: 24px;
1368
+ font-weight: 600;
1369
+ color: ${styles.titleColor};
1370
+ ">${this.options.title}</h2>
1371
+
1372
+ <p style="
1373
+ margin: 0 0 24px 0;
1374
+ color: ${styles.textColor};
1375
+ font-size: 14px;
1376
+ line-height: 1.5;
1377
+ ">${this.options.description}</p>
1378
+
1379
+ <div id="reclaim-qr-code" style="
1380
+ margin: 0 auto 24px auto;
1381
+ background: ${styles.qrBackground};
1382
+ border-radius: 8px;
1383
+ display: inline-block;
1384
+ "></div>
1385
+
1386
+ <div style="
1387
+ margin-bottom: 24px;
1388
+ padding: 16px;
1389
+ background: ${styles.tipBackground};
1390
+ border: 1px solid ${styles.tipBorder};
1391
+ border-radius: 8px;
1392
+ ">
1393
+ <p style="
1394
+ margin: 0 0 12px 0;
1395
+ font-size: 14px;
1396
+ color: ${styles.tipTextColor};
1397
+ font-weight: 500;
1398
+ ">\u{1F4A1} For a better experience</p>
1399
+ <p style="
1400
+ margin: 0 0 12px 0;
1401
+ font-size: 13px;
1402
+ color: ${styles.tipTextColor};
1403
+ line-height: 1.4;
1404
+ ">Install our browser extension for seamless verification without QR codes</p>
1405
+ <a href="${this.options.extensionUrl}"
1406
+ target="_blank"
1407
+ style="
1408
+ display: inline-block;
1409
+ background: ${styles.extensionButtonBackground};
1410
+ color: white;
1411
+ text-decoration: none;
1412
+ padding: 8px 16px;
1413
+ border-radius: 6px;
1414
+ font-size: 12px;
1415
+ font-weight: 500;
1416
+ transition: background-color 0.2s;
1417
+ "
1418
+ onmouseover="this.style.backgroundColor='${styles.extensionButtonHover}'"
1419
+ onmouseout="this.style.backgroundColor='${styles.extensionButtonBackground}'">
1420
+ Install Extension
1421
+ </a>
1422
+ </div>
1423
+
1424
+ <div style="margin-top: 16px;">
1425
+ <div id="reclaim-countdown" style="
1426
+ font-size: 12px;
1427
+ color: ${styles.countdownColor};
1428
+ font-weight: 400;
1429
+ margin-bottom: 8px;
1430
+ ">Auto-close in 1:00</div>
1431
+
1432
+ <div style="
1433
+ width: 100%;
1434
+ height: 4px;
1435
+ background-color: ${styles.progressBackground};
1436
+ border-radius: 2px;
1437
+ overflow: hidden;
1438
+ ">
1439
+ <div id="reclaim-progress-bar" style="
1440
+ width: 100%;
1441
+ height: 100%;
1442
+ background: ${styles.progressGradient};
1443
+ border-radius: 2px;
1444
+ transition: width 1s linear;
1445
+ "></div>
1446
+ </div>
1447
+ </div>
1448
+ </div>
1449
+ </div>
1450
+ `;
1451
+ }
1452
+ generateQRCode(text, containerId) {
1453
+ return __async(this, null, function* () {
1454
+ try {
1455
+ const qrCodeUrl = `${constants.QR_CODE_API_URL}?size=200x200&data=${encodeURIComponent(text)}`;
1456
+ const container = document.getElementById(containerId);
1457
+ const styles = this.getThemeStyles();
1458
+ if (container) {
1459
+ container.innerHTML = `
1460
+ <img src="${qrCodeUrl}"
1461
+ alt="QR Code for Reclaim verification"
1462
+ style="width: 200px; height: 200px; border-radius: 4px;"
1463
+ onerror="this.style.display='none'; this.nextElementSibling.style.display='block';">
1464
+ <div style="display: none; padding: 20px; color: ${styles.textColor}; font-size: 14px;">
1465
+ QR code could not be loaded.<br>
1466
+ <a href="${text}" target="_blank" style="color: ${styles.linkColor}; text-decoration: underline;">
1467
+ Click here to open verification link
1468
+ </a>
1469
+ </div>
1470
+ `;
1471
+ }
1472
+ } catch (error) {
1473
+ logger6.info("Error generating QR code:", error);
1474
+ const container = document.getElementById(containerId);
1475
+ const styles = this.getThemeStyles();
1476
+ if (container) {
1477
+ container.innerHTML = `
1478
+ <div style="padding: 20px; color: ${styles.textColor}; font-size: 14px;">
1479
+ <a href="${text}" target="_blank" style="color: ${styles.linkColor}; text-decoration: underline;">
1480
+ Click here to open verification link
1481
+ </a>
1482
+ </div>
1483
+ `;
1484
+ }
1485
+ }
1486
+ });
1487
+ }
1488
+ addEventListeners() {
1489
+ const closeButton = document.getElementById("reclaim-close-modal");
1490
+ const modal = document.getElementById(this.modalId);
1491
+ const closeModal = () => {
1492
+ this.close();
1493
+ };
1494
+ if (closeButton) {
1495
+ closeButton.addEventListener("click", closeModal);
1496
+ }
1497
+ if (modal) {
1498
+ modal.addEventListener("click", (e) => {
1499
+ if (e.target === modal) {
1500
+ closeModal();
1501
+ }
1502
+ });
1503
+ }
1504
+ const handleEscape = (e) => {
1505
+ if (e.key === "Escape") {
1506
+ closeModal();
1507
+ document.removeEventListener("keydown", handleEscape);
1508
+ }
1509
+ };
1510
+ document.addEventListener("keydown", handleEscape);
1511
+ }
1512
+ startAutoCloseTimer() {
1513
+ this.countdownSeconds = 60;
1514
+ this.updateCountdownDisplay();
1515
+ this.countdownTimer = setInterval(() => {
1516
+ this.countdownSeconds--;
1517
+ this.updateCountdownDisplay();
1518
+ if (this.countdownSeconds <= 0) {
1519
+ this.close();
1520
+ }
1521
+ }, 1e3);
1522
+ this.autoCloseTimer = setTimeout(() => {
1523
+ this.close();
1524
+ }, 6e4);
1525
+ }
1526
+ updateCountdownDisplay() {
1527
+ const countdownElement = document.getElementById("reclaim-countdown");
1528
+ const progressBar = document.getElementById("reclaim-progress-bar");
1529
+ if (countdownElement) {
1530
+ const minutes = Math.floor(this.countdownSeconds / 60);
1531
+ const seconds = this.countdownSeconds % 60;
1532
+ const timeString = `${minutes}:${seconds.toString().padStart(2, "0")}`;
1533
+ countdownElement.textContent = `Auto-close in ${timeString}`;
1534
+ }
1535
+ if (progressBar) {
1536
+ const progressPercentage = this.countdownSeconds / 60 * 100;
1537
+ progressBar.style.width = `${progressPercentage}%`;
1538
+ }
1539
+ }
1540
+ };
1541
+
1235
1542
  // src/utils/device.ts
1236
1543
  var navigatorDefined = typeof navigator !== "undefined";
1237
1544
  var windowDefined = typeof window !== "undefined";
1238
1545
  var userAgent = navigatorDefined ? navigator.userAgent.toLowerCase() : "";
1239
1546
  var userAgentData = navigatorDefined ? navigator.userAgentData : void 0;
1240
- var userAgentIsAndroid = userAgent.includes("android" /* ANDROID */);
1241
- var isIpad = windowDefined && navigatorDefined && ((userAgentData == null ? void 0 : userAgentData.platform) === "ipad" /* IPAD */ || userAgent.includes("ipad" /* IPAD */));
1242
- var userAgentIsIOS = new RegExp(`${"ios" /* IOS */}|ipod`, "i").test(userAgent) || isIpad;
1243
- var userAgentIsMobile = new RegExp(`${"android" /* ANDROID */}|webos|${"ios" /* IOS */}|${"ipad" /* IPAD */}|ipod|blackberry|iemobile|opera mini`, "i").test(userAgent) || windowDefined && "orientation" in window;
1547
+ function getDeviceType() {
1548
+ var _a, _b;
1549
+ if (!navigatorDefined || !windowDefined) {
1550
+ return "desktop" /* DESKTOP */;
1551
+ }
1552
+ let mobileScore = 0;
1553
+ const CONFIDENCE_THRESHOLD = 3;
1554
+ const isTouchDevice = "ontouchstart" in window || navigatorDefined && navigator.maxTouchPoints > 0;
1555
+ if (isTouchDevice) {
1556
+ mobileScore += 2;
1557
+ }
1558
+ const screenWidth = window.innerWidth || ((_a = window.screen) == null ? void 0 : _a.width) || 0;
1559
+ const screenHeight = window.innerHeight || ((_b = window.screen) == null ? void 0 : _b.height) || 0;
1560
+ const hasSmallScreen = screenWidth <= 768 || screenHeight <= 768;
1561
+ if (hasSmallScreen) {
1562
+ mobileScore += 2;
1563
+ }
1564
+ const mobileUserAgentPattern = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i;
1565
+ if (mobileUserAgentPattern.test(userAgent)) {
1566
+ mobileScore += 3;
1567
+ }
1568
+ const hasMobileAPIs = "orientation" in window || "DeviceMotionEvent" in window || "DeviceOrientationEvent" in window;
1569
+ if (hasMobileAPIs) {
1570
+ mobileScore += 2;
1571
+ }
1572
+ const hasHighDPI = windowDefined && window.devicePixelRatio > 1.5;
1573
+ if (hasHighDPI && hasSmallScreen) {
1574
+ mobileScore += 1;
1575
+ }
1576
+ const hasViewportMeta = document.querySelector('meta[name="viewport"]') !== null;
1577
+ if (hasViewportMeta && hasSmallScreen) {
1578
+ mobileScore += 1;
1579
+ }
1580
+ const hasLargeScreen = screenWidth > 1024 && screenHeight > 768;
1581
+ const hasKeyboard = "keyboard" in navigator;
1582
+ const hasPointer = window.matchMedia && window.matchMedia("(pointer: fine)").matches;
1583
+ if (hasLargeScreen && !isTouchDevice) {
1584
+ mobileScore -= 2;
1585
+ }
1586
+ if (hasPointer && !isTouchDevice) {
1587
+ mobileScore -= 1;
1588
+ }
1589
+ const isPadWithKeyboard = userAgent.includes("macintosh") && isTouchDevice;
1590
+ if (isPadWithKeyboard) {
1591
+ mobileScore += 2;
1592
+ }
1593
+ return mobileScore >= CONFIDENCE_THRESHOLD ? "mobile" /* MOBILE */ : "desktop" /* DESKTOP */;
1594
+ }
1595
+ function getMobileDeviceType() {
1596
+ var _a, _b;
1597
+ if (!navigatorDefined || !windowDefined) {
1598
+ return "android" /* ANDROID */;
1599
+ }
1600
+ const ua = navigator.userAgent;
1601
+ const iosPattern = /iPad|iPhone|iPod/i;
1602
+ if (iosPattern.test(ua)) {
1603
+ return "ios" /* IOS */;
1604
+ }
1605
+ const androidPattern = /Android/i;
1606
+ if (androidPattern.test(ua)) {
1607
+ return "android" /* ANDROID */;
1608
+ }
1609
+ const isMacWithTouch = /Macintosh|MacIntel/i.test(ua) && "ontouchstart" in window;
1610
+ if (isMacWithTouch) {
1611
+ return "ios" /* IOS */;
1612
+ }
1613
+ if ((userAgentData == null ? void 0 : userAgentData.platform) === "macOS" && "ontouchstart" in window) {
1614
+ return "ios" /* IOS */;
1615
+ }
1616
+ if (typeof ((_a = window.DeviceMotionEvent) == null ? void 0 : _a.requestPermission) === "function") {
1617
+ return "ios" /* IOS */;
1618
+ }
1619
+ if (typeof CSS !== "undefined" && ((_b = CSS.supports) == null ? void 0 : _b.call(CSS, "-webkit-touch-callout", "none"))) {
1620
+ return "ios" /* IOS */;
1621
+ }
1622
+ const isIOSWebKit = /WebKit/i.test(ua) && !/Chrome|CriOS|Android/i.test(ua);
1623
+ if (isIOSWebKit) {
1624
+ return "ios" /* IOS */;
1625
+ }
1626
+ const isChromeOnMobile = window.chrome && /Mobile/i.test(ua);
1627
+ if (isChromeOnMobile && !iosPattern.test(ua)) {
1628
+ return "android" /* ANDROID */;
1629
+ }
1630
+ const androidMobilePattern = /Mobile.*Android|Android.*Mobile/i;
1631
+ if (androidMobilePattern.test(ua)) {
1632
+ return "android" /* ANDROID */;
1633
+ }
1634
+ const mobilePattern = /webos|blackberry|iemobile|opera mini/i;
1635
+ if (mobilePattern.test(ua)) {
1636
+ return "android" /* ANDROID */;
1637
+ }
1638
+ return "android" /* ANDROID */;
1639
+ }
1244
1640
 
1245
1641
  // src/Reclaim.ts
1246
- var logger6 = logger_default.logger;
1642
+ var logger7 = logger_default.logger;
1247
1643
  var sdkVersion = require_package().version;
1248
1644
  function verifyProof(proofOrProofs) {
1249
1645
  return __async(this, null, function* () {
@@ -1291,7 +1687,7 @@ function verifyProof(proofOrProofs) {
1291
1687
  };
1292
1688
  assertValidSignedClaim(signedClaim, witnesses);
1293
1689
  } catch (e) {
1294
- logger6.info(`Error verifying proof: ${e instanceof Error ? e.message : String(e)}`);
1690
+ logger7.info(`Error verifying proof: ${e instanceof Error ? e.message : String(e)}`);
1295
1691
  return false;
1296
1692
  }
1297
1693
  return true;
@@ -1316,6 +1712,20 @@ function transformForOnchain(proof) {
1316
1712
  };
1317
1713
  return { claimInfo, signedClaim };
1318
1714
  }
1715
+ var emptyTemplateData = {
1716
+ sessionId: "",
1717
+ providerId: "",
1718
+ applicationId: "",
1719
+ signature: "",
1720
+ timestamp: "",
1721
+ callbackUrl: "",
1722
+ context: "",
1723
+ parameters: {},
1724
+ redirectUrl: "",
1725
+ acceptAiProviders: false,
1726
+ sdkVersion: "",
1727
+ jsonProofResponse: false
1728
+ };
1319
1729
  var ReclaimProofRequest = class _ReclaimProofRequest {
1320
1730
  // 30 seconds timeout, can be adjusted
1321
1731
  // Private constructor
@@ -1324,36 +1734,36 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1324
1734
  this.claimCreationType = "createClaim" /* STANDALONE */;
1325
1735
  this.intervals = /* @__PURE__ */ new Map();
1326
1736
  this.jsonProofResponse = false;
1737
+ this.extensionID = "reclaim-extension";
1327
1738
  this.FAILURE_TIMEOUT = 3e4;
1739
+ var _a;
1328
1740
  this.providerId = providerId;
1329
1741
  this.timeStamp = Date.now().toString();
1330
1742
  this.applicationId = applicationId;
1331
1743
  this.sessionId = "";
1744
+ this.templateData = emptyTemplateData;
1332
1745
  this.parameters = {};
1333
1746
  if (!options) {
1334
1747
  options = {};
1335
1748
  }
1336
- if (!options.device) {
1337
- if (userAgentIsIOS) {
1338
- options.device = "ios" /* IOS */;
1339
- } else if (userAgentIsAndroid) {
1340
- options.device = "android" /* ANDROID */;
1341
- }
1342
- }
1343
- if (options.useAppClip === void 0) {
1344
- options.useAppClip = true;
1345
- }
1749
+ options.useBrowserExtension = (_a = options.useBrowserExtension) != null ? _a : true;
1346
1750
  if (options == null ? void 0 : options.log) {
1347
1751
  logger_default.setLogLevel("info");
1348
1752
  } else {
1349
1753
  logger_default.setLogLevel("silent");
1350
1754
  }
1755
+ if (options.useAppClip === void 0) {
1756
+ options.useAppClip = true;
1757
+ }
1351
1758
  if (options == null ? void 0 : options.envUrl) {
1352
1759
  setBackendBaseUrl(options.envUrl);
1353
1760
  }
1761
+ if (options.extensionID) {
1762
+ this.extensionID = options.extensionID;
1763
+ }
1354
1764
  this.options = options;
1355
1765
  this.sdkVersion = "js-" + sdkVersion;
1356
- logger6.info(`Initializing client with applicationId: ${this.applicationId}`);
1766
+ logger7.info(`Initializing client with applicationId: ${this.applicationId}`);
1357
1767
  }
1358
1768
  // Static initialization methods
1359
1769
  static init(applicationId, appSecret, providerId, options) {
@@ -1375,9 +1785,6 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1375
1785
  { paramName: "log", input: options.log }
1376
1786
  ], "the constructor");
1377
1787
  }
1378
- if (options.useAppClip === void 0) {
1379
- options.useAppClip = true;
1380
- }
1381
1788
  if (options.useAppClip) {
1382
1789
  validateFunctionParams([
1383
1790
  { paramName: "useAppClip", input: options.useAppClip }
@@ -1388,6 +1795,16 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1388
1795
  { paramName: "device", input: options.device, isString: true }
1389
1796
  ], "the constructor");
1390
1797
  }
1798
+ if (options.useBrowserExtension) {
1799
+ validateFunctionParams([
1800
+ { paramName: "useBrowserExtension", input: options.useBrowserExtension }
1801
+ ], "the constructor");
1802
+ }
1803
+ if (options.extensionID) {
1804
+ validateFunctionParams([
1805
+ { paramName: "extensionID", input: options.extensionID, isString: true }
1806
+ ], "the constructor");
1807
+ }
1391
1808
  if (options.envUrl) {
1392
1809
  validateFunctionParams([
1393
1810
  { paramName: "envUrl", input: options.envUrl, isString: true }
@@ -1401,7 +1818,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1401
1818
  proofRequestInstance.sessionId = data.sessionId;
1402
1819
  return proofRequestInstance;
1403
1820
  } catch (error) {
1404
- logger6.info("Failed to initialize ReclaimProofRequest", error);
1821
+ logger7.info("Failed to initialize ReclaimProofRequest", error);
1405
1822
  throw new InitError("Failed to initialize ReclaimProofRequest", error);
1406
1823
  }
1407
1824
  });
@@ -1465,7 +1882,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1465
1882
  proofRequestInstance.sdkVersion = sdkVersion2;
1466
1883
  return proofRequestInstance;
1467
1884
  } catch (error) {
1468
- logger6.info("Failed to parse JSON string in fromJsonString:", error);
1885
+ logger7.info("Failed to parse JSON string in fromJsonString:", error);
1469
1886
  throw new InvalidParamError("Invalid JSON string provided to fromJsonString");
1470
1887
  }
1471
1888
  });
@@ -1483,6 +1900,33 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1483
1900
  setClaimCreationType(claimCreationType) {
1484
1901
  this.claimCreationType = claimCreationType;
1485
1902
  }
1903
+ setModalOptions(options) {
1904
+ try {
1905
+ if (options.title !== void 0) {
1906
+ validateFunctionParams([
1907
+ { input: options.title, paramName: "title", isString: true }
1908
+ ], "setModalOptions");
1909
+ }
1910
+ if (options.description !== void 0) {
1911
+ validateFunctionParams([
1912
+ { input: options.description, paramName: "description", isString: true }
1913
+ ], "setModalOptions");
1914
+ }
1915
+ if (options.extensionUrl !== void 0) {
1916
+ validateURL(options.extensionUrl, "setModalOptions");
1917
+ }
1918
+ if (options.darkTheme !== void 0) {
1919
+ validateFunctionParams([
1920
+ { input: options.darkTheme, paramName: "darkTheme" }
1921
+ ], "setModalOptions");
1922
+ }
1923
+ this.modalOptions = __spreadValues(__spreadValues({}, this.modalOptions), options);
1924
+ logger7.info("Modal options set successfully");
1925
+ } catch (error) {
1926
+ logger7.info("Error setting modal options:", error);
1927
+ throw new SetParamsError("Error setting modal options", error);
1928
+ }
1929
+ }
1486
1930
  addContext(address, message) {
1487
1931
  try {
1488
1932
  validateFunctionParams([
@@ -1491,7 +1935,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1491
1935
  ], "addContext");
1492
1936
  this.context = { contextAddress: address, contextMessage: message };
1493
1937
  } catch (error) {
1494
- logger6.info("Error adding context", error);
1938
+ logger7.info("Error adding context", error);
1495
1939
  throw new AddContextError("Error adding context", error);
1496
1940
  }
1497
1941
  }
@@ -1500,7 +1944,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1500
1944
  validateParameters(params);
1501
1945
  this.parameters = __spreadValues(__spreadValues({}, this.parameters), params);
1502
1946
  } catch (error) {
1503
- logger6.info("Error Setting Params:", error);
1947
+ logger7.info("Error Setting Params:", error);
1504
1948
  throw new SetParamsError("Error setting params", error);
1505
1949
  }
1506
1950
  }
@@ -1510,7 +1954,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1510
1954
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getAppCallbackUrl");
1511
1955
  return this.appCallbackUrl || `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`;
1512
1956
  } catch (error) {
1513
- logger6.info("Error getting app callback url", error);
1957
+ logger7.info("Error getting app callback url", error);
1514
1958
  throw new GetAppCallbackUrlError("Error getting app callback url", error);
1515
1959
  }
1516
1960
  }
@@ -1519,7 +1963,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1519
1963
  validateFunctionParams([{ input: this.sessionId, paramName: "sessionId", isString: true }], "getStatusUrl");
1520
1964
  return `${constants.DEFAULT_RECLAIM_STATUS_URL}${this.sessionId}`;
1521
1965
  } catch (error) {
1522
- logger6.info("Error fetching Status Url", error);
1966
+ logger7.info("Error fetching Status Url", error);
1523
1967
  throw new GetStatusUrlError("Error fetching status url", error);
1524
1968
  }
1525
1969
  }
@@ -1528,9 +1972,9 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1528
1972
  try {
1529
1973
  validateFunctionParams([{ input: signature, paramName: "signature", isString: true }], "setSignature");
1530
1974
  this.signature = signature;
1531
- logger6.info(`Signature set successfully for applicationId: ${this.applicationId}`);
1975
+ logger7.info(`Signature set successfully for applicationId: ${this.applicationId}`);
1532
1976
  } catch (error) {
1533
- logger6.info("Error setting signature", error);
1977
+ logger7.info("Error setting signature", error);
1534
1978
  throw new SetSignatureError("Error setting signature", error);
1535
1979
  }
1536
1980
  }
@@ -1545,7 +1989,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1545
1989
  const messageHash = import_ethers6.ethers.keccak256(new TextEncoder().encode(canonicalData));
1546
1990
  return yield wallet.signMessage(import_ethers6.ethers.getBytes(messageHash));
1547
1991
  } catch (err) {
1548
- logger6.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, signature: ${this.signature}, timeStamp: ${this.timeStamp}`, err);
1992
+ logger7.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, signature: ${this.signature}, timeStamp: ${this.timeStamp}`, err);
1549
1993
  throw new SignatureGeneratingError(`Error generating signature for applicationSecret: ${applicationSecret}`);
1550
1994
  }
1551
1995
  });
@@ -1576,8 +2020,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1576
2020
  }
1577
2021
  getRequestUrl() {
1578
2022
  return __async(this, null, function* () {
1579
- var _a, _b, _c, _d, _e;
1580
- logger6.info("Creating Request Url");
2023
+ var _a, _b, _c, _d;
2024
+ logger7.info("Creating Request Url");
1581
2025
  if (!this.signature) {
1582
2026
  throw new SignatureNotFoundError("Signature is not set.");
1583
2027
  }
@@ -1602,23 +2046,158 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1602
2046
  let template = encodeURIComponent(JSON.stringify(templateData));
1603
2047
  template = replaceAll(template, "(", "%28");
1604
2048
  template = replaceAll(template, ")", "%29");
1605
- const isIos = ((_e = this.options) == null ? void 0 : _e.device) === "ios";
2049
+ const isIos = getMobileDeviceType() === "ios" /* IOS */;
1606
2050
  if (!isIos) {
1607
2051
  const instantAppUrl = `https://share.reclaimprotocol.org/verify/?template=${template}`;
1608
- logger6.info("Instant App Url created successfully: " + instantAppUrl);
2052
+ logger7.info("Instant App Url created successfully: " + instantAppUrl);
1609
2053
  return instantAppUrl;
1610
2054
  } else {
1611
2055
  const appClipUrl = `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
1612
- logger6.info("App Clip Url created successfully: " + appClipUrl);
2056
+ logger7.info("App Clip Url created successfully: " + appClipUrl);
1613
2057
  return appClipUrl;
1614
2058
  }
1615
2059
  } else {
1616
2060
  const link = yield createLinkWithTemplateData(templateData);
1617
- logger6.info("Request Url created successfully: " + link);
2061
+ logger7.info("Request Url created successfully: " + link);
1618
2062
  return link;
1619
2063
  }
1620
2064
  } catch (error) {
1621
- logger6.info("Error creating Request Url:", error);
2065
+ logger7.info("Error creating Request Url:", error);
2066
+ throw error;
2067
+ }
2068
+ });
2069
+ }
2070
+ triggerReclaimFlow() {
2071
+ return __async(this, null, function* () {
2072
+ var _a, _b, _c, _d;
2073
+ if (!this.signature) {
2074
+ throw new SignatureNotFoundError("Signature is not set.");
2075
+ }
2076
+ try {
2077
+ validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp);
2078
+ const templateData = {
2079
+ sessionId: this.sessionId,
2080
+ providerId: this.providerId,
2081
+ applicationId: this.applicationId,
2082
+ signature: this.signature,
2083
+ timestamp: this.timeStamp,
2084
+ callbackUrl: this.getAppCallbackUrl(),
2085
+ context: JSON.stringify(this.context),
2086
+ parameters: this.parameters,
2087
+ redirectUrl: (_a = this.redirectUrl) != null ? _a : "",
2088
+ acceptAiProviders: (_c = (_b = this.options) == null ? void 0 : _b.acceptAiProviders) != null ? _c : false,
2089
+ sdkVersion: this.sdkVersion,
2090
+ jsonProofResponse: this.jsonProofResponse
2091
+ };
2092
+ this.templateData = templateData;
2093
+ logger7.info("Triggering Reclaim flow");
2094
+ const deviceType = getDeviceType();
2095
+ yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2096
+ if (deviceType === "desktop" /* DESKTOP */) {
2097
+ const extensionAvailable = yield this.isBrowserExtensionAvailable();
2098
+ if (((_d = this.options) == null ? void 0 : _d.useBrowserExtension) && extensionAvailable) {
2099
+ logger7.info("Triggering browser extension flow");
2100
+ this.triggerBrowserExtensionFlow();
2101
+ return;
2102
+ } else {
2103
+ logger7.info("Browser extension not available, showing QR code modal");
2104
+ yield this.showQRCodeModal();
2105
+ }
2106
+ } else if (deviceType === "mobile" /* MOBILE */) {
2107
+ const mobileDeviceType = getMobileDeviceType();
2108
+ if (mobileDeviceType === "android" /* ANDROID */) {
2109
+ logger7.info("Redirecting to Android instant app");
2110
+ yield this.redirectToInstantApp();
2111
+ } else if (mobileDeviceType === "ios" /* IOS */) {
2112
+ logger7.info("Redirecting to iOS app clip");
2113
+ yield this.redirectToAppClip();
2114
+ }
2115
+ }
2116
+ } catch (error) {
2117
+ logger7.info("Error triggering Reclaim flow:", error);
2118
+ throw error;
2119
+ }
2120
+ });
2121
+ }
2122
+ isBrowserExtensionAvailable(timeout = 200) {
2123
+ return __async(this, null, function* () {
2124
+ try {
2125
+ return new Promise((resolve) => {
2126
+ const messageId = `reclaim-check-${Date.now()}`;
2127
+ const timeoutId = setTimeout(() => {
2128
+ window.removeEventListener("message", messageListener);
2129
+ resolve(false);
2130
+ }, timeout);
2131
+ const messageListener = (event) => {
2132
+ var _a, _b;
2133
+ if (((_a = event.data) == null ? void 0 : _a.action) === RECLAIM_EXTENSION_ACTIONS.EXTENSION_RESPONSE && ((_b = event.data) == null ? void 0 : _b.messageId) === messageId) {
2134
+ clearTimeout(timeoutId);
2135
+ window.removeEventListener("message", messageListener);
2136
+ resolve(!!event.data.installed);
2137
+ }
2138
+ };
2139
+ window.addEventListener("message", messageListener);
2140
+ const message = {
2141
+ action: RECLAIM_EXTENSION_ACTIONS.CHECK_EXTENSION,
2142
+ extensionID: this.extensionID,
2143
+ messageId
2144
+ };
2145
+ window.postMessage(message, "*");
2146
+ });
2147
+ } catch (error) {
2148
+ logger7.info("Error checking Reclaim extension installed:", error);
2149
+ return false;
2150
+ }
2151
+ });
2152
+ }
2153
+ triggerBrowserExtensionFlow() {
2154
+ const message = {
2155
+ action: RECLAIM_EXTENSION_ACTIONS.START_VERIFICATION,
2156
+ messageId: this.sessionId,
2157
+ data: this.templateData,
2158
+ extensionID: this.extensionID
2159
+ };
2160
+ window.postMessage(message, "*");
2161
+ logger7.info("Browser extension flow triggered");
2162
+ }
2163
+ showQRCodeModal() {
2164
+ return __async(this, null, function* () {
2165
+ try {
2166
+ const requestUrl = yield createLinkWithTemplateData(this.templateData);
2167
+ const modal = new QRCodeModal(this.modalOptions);
2168
+ yield modal.show(requestUrl);
2169
+ } catch (error) {
2170
+ logger7.info("Error showing QR code modal:", error);
2171
+ throw error;
2172
+ }
2173
+ });
2174
+ }
2175
+ redirectToInstantApp() {
2176
+ return __async(this, null, function* () {
2177
+ try {
2178
+ let template = encodeURIComponent(JSON.stringify(this.templateData));
2179
+ template = replaceAll(template, "(", "%28");
2180
+ template = replaceAll(template, ")", "%29");
2181
+ const instantAppUrl = `https://share.reclaimprotocol.org/verify/?template=${template}`;
2182
+ logger7.info("Redirecting to Android instant app: " + instantAppUrl);
2183
+ window.location.href = instantAppUrl;
2184
+ } catch (error) {
2185
+ logger7.info("Error redirecting to instant app:", error);
2186
+ throw error;
2187
+ }
2188
+ });
2189
+ }
2190
+ redirectToAppClip() {
2191
+ return __async(this, null, function* () {
2192
+ try {
2193
+ let template = encodeURIComponent(JSON.stringify(this.templateData));
2194
+ template = replaceAll(template, "(", "%28");
2195
+ template = replaceAll(template, ")", "%29");
2196
+ const appClipUrl = `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2197
+ logger7.info("Redirecting to iOS app clip: " + appClipUrl);
2198
+ window.location.href = appClipUrl;
2199
+ } catch (error) {
2200
+ logger7.info("Error redirecting to app clip:", error);
1622
2201
  throw error;
1623
2202
  }
1624
2203
  });
@@ -1627,10 +2206,10 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1627
2206
  return __async(this, arguments, function* ({ onSuccess, onError }) {
1628
2207
  if (!this.sessionId) {
1629
2208
  const message = "Session can't be started due to undefined value of sessionId";
1630
- logger6.info(message);
2209
+ logger7.info(message);
1631
2210
  throw new SessionNotStartedError(message);
1632
2211
  }
1633
- logger6.info("Starting session");
2212
+ logger7.info("Starting session");
1634
2213
  const interval = setInterval(() => __async(this, null, function* () {
1635
2214
  try {
1636
2215
  const statusUrlResponse = yield fetchStatusUrl(this.sessionId);
@@ -1654,7 +2233,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1654
2233
  if (this.claimCreationType === "createClaim" /* STANDALONE */) {
1655
2234
  const verified = yield verifyProof(proofs);
1656
2235
  if (!verified) {
1657
- logger6.info(`Proofs not verified: ${JSON.stringify(proofs)}`);
2236
+ logger7.info(`Proofs not verified: ${JSON.stringify(proofs)}`);
1658
2237
  throw new ProofNotVerifiedError();
1659
2238
  }
1660
2239
  }
@@ -1691,6 +2270,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1691
2270
  // Annotate the CommonJS export names for ESM import in node:
1692
2271
  0 && (module.exports = {
1693
2272
  ClaimCreationType,
2273
+ RECLAIM_EXTENSION_ACTIONS,
1694
2274
  ReclaimProofRequest,
1695
2275
  transformForOnchain,
1696
2276
  verifyProof