@reclaimprotocol/js-sdk 3.0.4 → 4.1.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.1.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,18 +1963,25 @@ 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
  }
1970
+ // getter for SessionId
1971
+ getSessionId() {
1972
+ if (!this.sessionId) {
1973
+ throw new SessionNotStartedError("SessionId is not set");
1974
+ }
1975
+ return this.sessionId;
1976
+ }
1526
1977
  // Private helper methods
1527
1978
  setSignature(signature) {
1528
1979
  try {
1529
1980
  validateFunctionParams([{ input: signature, paramName: "signature", isString: true }], "setSignature");
1530
1981
  this.signature = signature;
1531
- logger6.info(`Signature set successfully for applicationId: ${this.applicationId}`);
1982
+ logger7.info(`Signature set successfully for applicationId: ${this.applicationId}`);
1532
1983
  } catch (error) {
1533
- logger6.info("Error setting signature", error);
1984
+ logger7.info("Error setting signature", error);
1534
1985
  throw new SetSignatureError("Error setting signature", error);
1535
1986
  }
1536
1987
  }
@@ -1545,7 +1996,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1545
1996
  const messageHash = import_ethers6.ethers.keccak256(new TextEncoder().encode(canonicalData));
1546
1997
  return yield wallet.signMessage(import_ethers6.ethers.getBytes(messageHash));
1547
1998
  } catch (err) {
1548
- logger6.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, signature: ${this.signature}, timeStamp: ${this.timeStamp}`, err);
1999
+ logger7.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, signature: ${this.signature}, timeStamp: ${this.timeStamp}`, err);
1549
2000
  throw new SignatureGeneratingError(`Error generating signature for applicationSecret: ${applicationSecret}`);
1550
2001
  }
1551
2002
  });
@@ -1576,8 +2027,8 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1576
2027
  }
1577
2028
  getRequestUrl() {
1578
2029
  return __async(this, null, function* () {
1579
- var _a, _b, _c, _d, _e;
1580
- logger6.info("Creating Request Url");
2030
+ var _a, _b, _c, _d;
2031
+ logger7.info("Creating Request Url");
1581
2032
  if (!this.signature) {
1582
2033
  throw new SignatureNotFoundError("Signature is not set.");
1583
2034
  }
@@ -1602,23 +2053,158 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1602
2053
  let template = encodeURIComponent(JSON.stringify(templateData));
1603
2054
  template = replaceAll(template, "(", "%28");
1604
2055
  template = replaceAll(template, ")", "%29");
1605
- const isIos = ((_e = this.options) == null ? void 0 : _e.device) === "ios";
2056
+ const isIos = getMobileDeviceType() === "ios" /* IOS */;
1606
2057
  if (!isIos) {
1607
2058
  const instantAppUrl = `https://share.reclaimprotocol.org/verify/?template=${template}`;
1608
- logger6.info("Instant App Url created successfully: " + instantAppUrl);
2059
+ logger7.info("Instant App Url created successfully: " + instantAppUrl);
1609
2060
  return instantAppUrl;
1610
2061
  } else {
1611
2062
  const appClipUrl = `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
1612
- logger6.info("App Clip Url created successfully: " + appClipUrl);
2063
+ logger7.info("App Clip Url created successfully: " + appClipUrl);
1613
2064
  return appClipUrl;
1614
2065
  }
1615
2066
  } else {
1616
2067
  const link = yield createLinkWithTemplateData(templateData);
1617
- logger6.info("Request Url created successfully: " + link);
2068
+ logger7.info("Request Url created successfully: " + link);
1618
2069
  return link;
1619
2070
  }
1620
2071
  } catch (error) {
1621
- logger6.info("Error creating Request Url:", error);
2072
+ logger7.info("Error creating Request Url:", error);
2073
+ throw error;
2074
+ }
2075
+ });
2076
+ }
2077
+ triggerReclaimFlow() {
2078
+ return __async(this, null, function* () {
2079
+ var _a, _b, _c, _d;
2080
+ if (!this.signature) {
2081
+ throw new SignatureNotFoundError("Signature is not set.");
2082
+ }
2083
+ try {
2084
+ validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp);
2085
+ const templateData = {
2086
+ sessionId: this.sessionId,
2087
+ providerId: this.providerId,
2088
+ applicationId: this.applicationId,
2089
+ signature: this.signature,
2090
+ timestamp: this.timeStamp,
2091
+ callbackUrl: this.getAppCallbackUrl(),
2092
+ context: JSON.stringify(this.context),
2093
+ parameters: this.parameters,
2094
+ redirectUrl: (_a = this.redirectUrl) != null ? _a : "",
2095
+ acceptAiProviders: (_c = (_b = this.options) == null ? void 0 : _b.acceptAiProviders) != null ? _c : false,
2096
+ sdkVersion: this.sdkVersion,
2097
+ jsonProofResponse: this.jsonProofResponse
2098
+ };
2099
+ this.templateData = templateData;
2100
+ logger7.info("Triggering Reclaim flow");
2101
+ const deviceType = getDeviceType();
2102
+ yield updateSession(this.sessionId, "SESSION_STARTED" /* SESSION_STARTED */);
2103
+ if (deviceType === "desktop" /* DESKTOP */) {
2104
+ const extensionAvailable = yield this.isBrowserExtensionAvailable();
2105
+ if (((_d = this.options) == null ? void 0 : _d.useBrowserExtension) && extensionAvailable) {
2106
+ logger7.info("Triggering browser extension flow");
2107
+ this.triggerBrowserExtensionFlow();
2108
+ return;
2109
+ } else {
2110
+ logger7.info("Browser extension not available, showing QR code modal");
2111
+ yield this.showQRCodeModal();
2112
+ }
2113
+ } else if (deviceType === "mobile" /* MOBILE */) {
2114
+ const mobileDeviceType = getMobileDeviceType();
2115
+ if (mobileDeviceType === "android" /* ANDROID */) {
2116
+ logger7.info("Redirecting to Android instant app");
2117
+ yield this.redirectToInstantApp();
2118
+ } else if (mobileDeviceType === "ios" /* IOS */) {
2119
+ logger7.info("Redirecting to iOS app clip");
2120
+ yield this.redirectToAppClip();
2121
+ }
2122
+ }
2123
+ } catch (error) {
2124
+ logger7.info("Error triggering Reclaim flow:", error);
2125
+ throw error;
2126
+ }
2127
+ });
2128
+ }
2129
+ isBrowserExtensionAvailable(timeout = 200) {
2130
+ return __async(this, null, function* () {
2131
+ try {
2132
+ return new Promise((resolve) => {
2133
+ const messageId = `reclaim-check-${Date.now()}`;
2134
+ const timeoutId = setTimeout(() => {
2135
+ window.removeEventListener("message", messageListener);
2136
+ resolve(false);
2137
+ }, timeout);
2138
+ const messageListener = (event) => {
2139
+ var _a, _b;
2140
+ if (((_a = event.data) == null ? void 0 : _a.action) === RECLAIM_EXTENSION_ACTIONS.EXTENSION_RESPONSE && ((_b = event.data) == null ? void 0 : _b.messageId) === messageId) {
2141
+ clearTimeout(timeoutId);
2142
+ window.removeEventListener("message", messageListener);
2143
+ resolve(!!event.data.installed);
2144
+ }
2145
+ };
2146
+ window.addEventListener("message", messageListener);
2147
+ const message = {
2148
+ action: RECLAIM_EXTENSION_ACTIONS.CHECK_EXTENSION,
2149
+ extensionID: this.extensionID,
2150
+ messageId
2151
+ };
2152
+ window.postMessage(message, "*");
2153
+ });
2154
+ } catch (error) {
2155
+ logger7.info("Error checking Reclaim extension installed:", error);
2156
+ return false;
2157
+ }
2158
+ });
2159
+ }
2160
+ triggerBrowserExtensionFlow() {
2161
+ const message = {
2162
+ action: RECLAIM_EXTENSION_ACTIONS.START_VERIFICATION,
2163
+ messageId: this.sessionId,
2164
+ data: this.templateData,
2165
+ extensionID: this.extensionID
2166
+ };
2167
+ window.postMessage(message, "*");
2168
+ logger7.info("Browser extension flow triggered");
2169
+ }
2170
+ showQRCodeModal() {
2171
+ return __async(this, null, function* () {
2172
+ try {
2173
+ const requestUrl = yield createLinkWithTemplateData(this.templateData);
2174
+ const modal = new QRCodeModal(this.modalOptions);
2175
+ yield modal.show(requestUrl);
2176
+ } catch (error) {
2177
+ logger7.info("Error showing QR code modal:", error);
2178
+ throw error;
2179
+ }
2180
+ });
2181
+ }
2182
+ redirectToInstantApp() {
2183
+ return __async(this, null, function* () {
2184
+ try {
2185
+ let template = encodeURIComponent(JSON.stringify(this.templateData));
2186
+ template = replaceAll(template, "(", "%28");
2187
+ template = replaceAll(template, ")", "%29");
2188
+ const instantAppUrl = `https://share.reclaimprotocol.org/verify/?template=${template}`;
2189
+ logger7.info("Redirecting to Android instant app: " + instantAppUrl);
2190
+ window.location.href = instantAppUrl;
2191
+ } catch (error) {
2192
+ logger7.info("Error redirecting to instant app:", error);
2193
+ throw error;
2194
+ }
2195
+ });
2196
+ }
2197
+ redirectToAppClip() {
2198
+ return __async(this, null, function* () {
2199
+ try {
2200
+ let template = encodeURIComponent(JSON.stringify(this.templateData));
2201
+ template = replaceAll(template, "(", "%28");
2202
+ template = replaceAll(template, ")", "%29");
2203
+ const appClipUrl = `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;
2204
+ logger7.info("Redirecting to iOS app clip: " + appClipUrl);
2205
+ window.location.href = appClipUrl;
2206
+ } catch (error) {
2207
+ logger7.info("Error redirecting to app clip:", error);
1622
2208
  throw error;
1623
2209
  }
1624
2210
  });
@@ -1627,10 +2213,10 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1627
2213
  return __async(this, arguments, function* ({ onSuccess, onError }) {
1628
2214
  if (!this.sessionId) {
1629
2215
  const message = "Session can't be started due to undefined value of sessionId";
1630
- logger6.info(message);
2216
+ logger7.info(message);
1631
2217
  throw new SessionNotStartedError(message);
1632
2218
  }
1633
- logger6.info("Starting session");
2219
+ logger7.info("Starting session");
1634
2220
  const interval = setInterval(() => __async(this, null, function* () {
1635
2221
  try {
1636
2222
  const statusUrlResponse = yield fetchStatusUrl(this.sessionId);
@@ -1654,7 +2240,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1654
2240
  if (this.claimCreationType === "createClaim" /* STANDALONE */) {
1655
2241
  const verified = yield verifyProof(proofs);
1656
2242
  if (!verified) {
1657
- logger6.info(`Proofs not verified: ${JSON.stringify(proofs)}`);
2243
+ logger7.info(`Proofs not verified: ${JSON.stringify(proofs)}`);
1658
2244
  throw new ProofNotVerifiedError();
1659
2245
  }
1660
2246
  }
@@ -1691,6 +2277,7 @@ var ReclaimProofRequest = class _ReclaimProofRequest {
1691
2277
  // Annotate the CommonJS export names for ESM import in node:
1692
2278
  0 && (module.exports = {
1693
2279
  ClaimCreationType,
2280
+ RECLAIM_EXTENSION_ACTIONS,
1694
2281
  ReclaimProofRequest,
1695
2282
  transformForOnchain,
1696
2283
  verifyProof