@worldcoin/idkit 4.0.4 → 4.0.6

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
@@ -1,6 +1,6 @@
1
1
  import { IDKitErrorCodes, IDKit } from '@worldcoin/idkit-core';
2
- export { IDKit, IDKitErrorCodes, documentLegacy, orbLegacy, secureDocumentLegacy, selfieCheck, signRequest } from '@worldcoin/idkit-core';
3
- import { memo, useMemo, useRef, useEffect, useState, useCallback } from 'react';
2
+ export { IDKit, IDKitErrorCodes, documentLegacy, orbLegacy, secureDocumentLegacy, selfieCheckLegacy, signRequest } from '@worldcoin/idkit-core';
3
+ import { memo, useMemo, useState, useRef, useEffect, useCallback } from 'react';
4
4
  import { createPortal } from 'react-dom';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
  import QRCodeUtil from 'qrcode/lib/core/qrcode.js';
@@ -542,6 +542,7 @@ var WIDGET_STYLES = `
542
542
  animation: idkit-spin 1s linear infinite;
543
543
  }
544
544
  .idkit-spinner svg {
545
+ display: block;
545
546
  width: 24px;
546
547
  height: 24px;
547
548
  }
@@ -714,6 +715,8 @@ var en = {
714
715
  "You've cancelled the request in World App.": "You've cancelled the request in World App.",
715
716
  "Connection lost": "Connection lost",
716
717
  "Please check your connection and try again.": "Please check your connection and try again.",
718
+ "Verification declined": "Verification declined",
719
+ "Failed to verify your credential proof. Please contact the website owner.": "Failed to verify your credential proof. Please contact the website owner.",
717
720
  "We couldn't complete your request. Please try again.": "We couldn't complete your request. Please try again.",
718
721
  "Try Again": "Try Again",
719
722
  "Open World App": "Open World App",
@@ -722,6 +725,7 @@ var en = {
722
725
  "Use phone camera to scan the QR code": "Use phone camera to scan the QR code",
723
726
  "Connecting...": "Connecting...",
724
727
  "Please continue in app": "Please continue in app",
728
+ "Transmitting verification to host app. Please wait...": "Transmitting verification to host app. Please wait...",
725
729
  "You will be redirected to the app, please return to this page once you're done": "You will be redirected to the app, please return to this page once you're done",
726
730
  "Terms & Privacy": "Terms & Privacy"
727
731
  };
@@ -735,6 +739,8 @@ var es = {
735
739
  "You've cancelled the request in World App.": "Has cancelado la solicitud en World App.",
736
740
  "Connection lost": "Conexion perdida",
737
741
  "Please check your connection and try again.": "Por favor verifica tu conexion e intenta de nuevo.",
742
+ "Verification declined": "Verificaci\xF3n rechazada",
743
+ "Failed to verify your credential proof. Please contact the website owner.": "No se pudo verificar tu prueba de credencial. Por favor contacta al propietario del sitio web.",
738
744
  "We couldn't complete your request. Please try again.": "No pudimos completar tu solicitud. Por favor intenta de nuevo.",
739
745
  "Try Again": "Intentar de nuevo",
740
746
  "Open World App": "Abrir World App",
@@ -743,6 +749,7 @@ var es = {
743
749
  "Use phone camera to scan the QR code": "Usa la c\xE1mara del tel\xE9fono para escanear el c\xF3digo QR",
744
750
  "Connecting...": "Conectando...",
745
751
  "Please continue in app": "Por favor contin\xFAa en la aplicaci\xF3n",
752
+ "Transmitting verification to host app. Please wait...": "Enviando verificaci\xF3n a la aplicaci\xF3n anfitriona. Por favor espera...",
746
753
  "You will be redirected to the app, please return to this page once you're done": "Ser\xE1s redirigido a la aplicaci\xF3n, por favor regresa a esta p\xE1gina una vez que hayas terminado",
747
754
  "Terms & Privacy": "T\xE9rminos y privacidad"
748
755
  };
@@ -756,6 +763,8 @@ var th = {
756
763
  "You've cancelled the request in World App.": "\u0E04\u0E38\u0E13\u0E44\u0E14\u0E49\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01\u0E04\u0E33\u0E02\u0E2D\u0E43\u0E19 World App",
757
764
  "Connection lost": "\u0E01\u0E32\u0E23\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D\u0E02\u0E32\u0E14\u0E2B\u0E32\u0E22",
758
765
  "Please check your connection and try again.": "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E01\u0E32\u0E23\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D\u0E41\u0E25\u0E49\u0E27\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07",
766
+ "Verification declined": "\u0E01\u0E32\u0E23\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E16\u0E39\u0E01\u0E1B\u0E0F\u0E34\u0E40\u0E2A\u0E18",
767
+ "Failed to verify your credential proof. Please contact the website owner.": "\u0E44\u0E21\u0E48\u0E2A\u0E32\u0E21\u0E32\u0E23\u0E16\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E2B\u0E25\u0E31\u0E01\u0E10\u0E32\u0E19\u0E02\u0E2D\u0E07 Credential \u0E44\u0E14\u0E49 \u0E42\u0E1B\u0E23\u0E14\u0E15\u0E34\u0E14\u0E15\u0E48\u0E2D\u0E40\u0E08\u0E49\u0E32\u0E02\u0E2D\u0E07\u0E40\u0E27\u0E47\u0E1A\u0E44\u0E0B\u0E15\u0E4C",
759
768
  "We couldn't complete your request. Please try again.": "\u0E40\u0E23\u0E32\u0E44\u0E21\u0E48\u0E2A\u0E32\u0E21\u0E32\u0E23\u0E16\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23\u0E15\u0E32\u0E21\u0E04\u0E33\u0E02\u0E2D\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E44\u0E14\u0E49 \u0E01\u0E23\u0E38\u0E13\u0E32\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07",
760
769
  "Try Again": "\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07",
761
770
  "Open World App": "\u0E40\u0E1B\u0E34\u0E14 World App",
@@ -764,6 +773,7 @@ var th = {
764
773
  "Use phone camera to scan the QR code": "\u0E43\u0E0A\u0E49\u0E01\u0E25\u0E49\u0E2D\u0E07\u0E42\u0E17\u0E23\u0E28\u0E31\u0E1E\u0E17\u0E4C\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E2A\u0E41\u0E01\u0E19 QR code",
765
774
  "Connecting...": "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E40\u0E0A\u0E37\u0E48\u0E2D\u0E21\u0E15\u0E48\u0E2D...",
766
775
  "Please continue in app": "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23\u0E15\u0E48\u0E2D\u0E43\u0E19\u0E41\u0E2D\u0E1B",
776
+ "Transmitting verification to host app. Please wait...": "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2A\u0E48\u0E07\u0E01\u0E32\u0E23\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E44\u0E1B\u0E22\u0E31\u0E07\u0E41\u0E2D\u0E1B\u0E42\u0E2E\u0E2A\u0E15\u0E4C \u0E01\u0E23\u0E38\u0E13\u0E32\u0E23\u0E2D\u0E2A\u0E31\u0E01\u0E04\u0E23\u0E39\u0E48...",
767
777
  "You will be redirected to the app, please return to this page once you're done": "\u0E04\u0E38\u0E13\u0E08\u0E30\u0E16\u0E39\u0E01\u0E19\u0E33\u0E44\u0E1B\u0E22\u0E31\u0E07\u0E41\u0E2D\u0E1B \u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E25\u0E31\u0E1A\u0E21\u0E32\u0E17\u0E35\u0E48\u0E2B\u0E19\u0E49\u0E32\u0E19\u0E35\u0E49\u0E40\u0E21\u0E37\u0E48\u0E2D\u0E40\u0E2A\u0E23\u0E47\u0E08\u0E41\u0E25\u0E49\u0E27",
768
778
  "Terms & Privacy": "\u0E02\u0E49\u0E2D\u0E01\u0E33\u0E2B\u0E19\u0E14\u0E41\u0E25\u0E30\u0E04\u0E27\u0E32\u0E21\u0E40\u0E1B\u0E47\u0E19\u0E2A\u0E48\u0E27\u0E19\u0E15\u0E31\u0E27"
769
779
  };
@@ -1517,9 +1527,9 @@ function WarningIcon(props) {
1517
1527
  var errorCodeVariants = {
1518
1528
  [IDKitErrorCodes.UserRejected]: "cancelled",
1519
1529
  [IDKitErrorCodes.VerificationRejected]: "cancelled",
1520
- [IDKitErrorCodes.FailedByHostApp]: "cancelled",
1521
1530
  [IDKitErrorCodes.Cancelled]: "cancelled",
1522
- [IDKitErrorCodes.ConnectionFailed]: "connection"
1531
+ [IDKitErrorCodes.ConnectionFailed]: "connection",
1532
+ [IDKitErrorCodes.FailedByHostApp]: "host_verification"
1523
1533
  };
1524
1534
  var variantConfig = {
1525
1535
  cancelled: {
@@ -1533,6 +1543,11 @@ var variantConfig = {
1533
1543
  Icon: ErrorIcon
1534
1544
  // placeholder — swap for WifiOffIcon later
1535
1545
  },
1546
+ host_verification: {
1547
+ title: "Verification declined",
1548
+ message: "Failed to verify your credential proof. Please contact the website owner.",
1549
+ Icon: ErrorIcon
1550
+ },
1536
1551
  generic: {
1537
1552
  title: "Something went wrong",
1538
1553
  message: "We couldn't complete your request. Please try again.",
@@ -1569,26 +1584,60 @@ function ErrorState({
1569
1584
  }
1570
1585
  );
1571
1586
  }
1572
- function getVisualStage(isSuccess, isError) {
1573
- if (isSuccess) {
1574
- return "success";
1575
- }
1576
- if (isError) {
1577
- return "error";
1578
- }
1587
+ function HostAppVerificationState({
1588
+ onVerify,
1589
+ onPass,
1590
+ onFail
1591
+ }) {
1592
+ useEffect(() => {
1593
+ let cancelled = false;
1594
+ void Promise.resolve(onVerify()).then(() => {
1595
+ if (!cancelled) onPass();
1596
+ }).catch(() => {
1597
+ if (!cancelled) onFail();
1598
+ });
1599
+ return () => {
1600
+ cancelled = true;
1601
+ };
1602
+ }, []);
1603
+ return /* @__PURE__ */ jsxs(
1604
+ "div",
1605
+ {
1606
+ style: {
1607
+ display: "flex",
1608
+ flexDirection: "column",
1609
+ alignItems: "center",
1610
+ textAlign: "center"
1611
+ },
1612
+ children: [
1613
+ /* @__PURE__ */ jsx("div", { className: "idkit-spinner", children: /* @__PURE__ */ jsx(LoadingIcon, {}) }),
1614
+ /* @__PURE__ */ jsx("p", { className: "idkit-subtext", children: __("Transmitting verification to host app. Please wait...") })
1615
+ ]
1616
+ }
1617
+ );
1618
+ }
1619
+ function getVisualStage(isSuccess, isError, isHostVerifying) {
1620
+ if (isError) return "error";
1621
+ if (isHostVerifying) return "host_verification";
1622
+ if (isSuccess) return "success";
1579
1623
  return "worldid";
1580
1624
  }
1581
1625
  function IDKitRequestWidget({
1582
1626
  open,
1583
1627
  onOpenChange,
1628
+ handleVerify,
1584
1629
  onSuccess,
1585
1630
  onError,
1586
1631
  autoClose = true,
1587
1632
  language,
1588
1633
  ...config
1589
1634
  }) {
1635
+ if (typeof onSuccess !== "function") {
1636
+ throw new Error("IDKitRequestWidget requires an onSuccess callback.");
1637
+ }
1590
1638
  const flow = useIDKitRequest(config);
1591
1639
  const { open: openFlow, reset: resetFlow } = flow;
1640
+ const [hostVerifyResult, setHostVerifyResult] = useState(null);
1592
1641
  const lastResultRef = useRef(null);
1593
1642
  const lastErrorCodeRef = useRef(null);
1594
1643
  useEffect(() => {
@@ -1598,34 +1647,42 @@ function IDKitRequestWidget({
1598
1647
  }, [language]);
1599
1648
  useEffect(() => {
1600
1649
  if (open) {
1650
+ setHostVerifyResult(null);
1601
1651
  openFlow();
1602
1652
  return;
1603
1653
  }
1654
+ setHostVerifyResult(null);
1655
+ lastResultRef.current = null;
1656
+ lastErrorCodeRef.current = null;
1604
1657
  resetFlow();
1605
1658
  }, [open, openFlow, resetFlow]);
1659
+ const isSuccess = flow.isSuccess && (!handleVerify || hostVerifyResult === "passed");
1660
+ const isError = flow.isError || hostVerifyResult === "failed";
1661
+ const isHostVerifying = flow.isSuccess && Boolean(handleVerify) && hostVerifyResult === null;
1662
+ const effectiveErrorCode = flow.errorCode ?? (hostVerifyResult === "failed" ? IDKitErrorCodes.FailedByHostApp : null);
1606
1663
  useEffect(() => {
1607
- if (!flow.result || flow.result === lastResultRef.current) {
1664
+ if (!isSuccess || !flow.result || flow.result === lastResultRef.current) {
1608
1665
  return;
1609
1666
  }
1610
1667
  lastResultRef.current = flow.result;
1611
- void Promise.resolve(onSuccess?.(flow.result)).catch(() => {
1668
+ void Promise.resolve(onSuccess(flow.result)).catch(() => {
1612
1669
  });
1613
- }, [onSuccess, flow.result]);
1670
+ }, [flow.result, isSuccess, onSuccess]);
1614
1671
  useEffect(() => {
1615
- if (!flow.errorCode || flow.errorCode === lastErrorCodeRef.current) {
1672
+ if (!effectiveErrorCode || effectiveErrorCode === lastErrorCodeRef.current) {
1616
1673
  return;
1617
1674
  }
1618
- lastErrorCodeRef.current = flow.errorCode;
1619
- void Promise.resolve(onError?.(flow.errorCode)).catch(() => {
1675
+ lastErrorCodeRef.current = effectiveErrorCode;
1676
+ void Promise.resolve(onError?.(effectiveErrorCode)).catch(() => {
1620
1677
  });
1621
- }, [flow.errorCode, onError]);
1678
+ }, [effectiveErrorCode, onError]);
1622
1679
  useEffect(() => {
1623
- if (flow.isSuccess && autoClose) {
1680
+ if (isSuccess && autoClose) {
1624
1681
  const timer = setTimeout(() => onOpenChange(false), 2500);
1625
1682
  return () => clearTimeout(timer);
1626
1683
  }
1627
- }, [flow.isSuccess, autoClose, onOpenChange]);
1628
- const stage = getVisualStage(flow.isSuccess, flow.isError);
1684
+ }, [isSuccess, autoClose, onOpenChange]);
1685
+ const stage = getVisualStage(isSuccess, isError, isHostVerifying);
1629
1686
  const showSimulatorCallout = config.environment === "staging";
1630
1687
  return /* @__PURE__ */ jsxs(IDKitModal, { open, onOpenChange, children: [
1631
1688
  stage === "worldid" && /* @__PURE__ */ jsx(
@@ -1636,12 +1693,23 @@ function IDKitRequestWidget({
1636
1693
  showSimulatorCallout
1637
1694
  }
1638
1695
  ),
1696
+ stage === "host_verification" && /* @__PURE__ */ jsx(
1697
+ HostAppVerificationState,
1698
+ {
1699
+ onVerify: () => handleVerify(flow.result),
1700
+ onPass: () => setHostVerifyResult("passed"),
1701
+ onFail: () => setHostVerifyResult("failed")
1702
+ }
1703
+ ),
1639
1704
  stage === "success" && /* @__PURE__ */ jsx(SuccessState, {}),
1640
1705
  stage === "error" && /* @__PURE__ */ jsx(
1641
1706
  ErrorState,
1642
1707
  {
1643
- errorCode: flow.errorCode,
1708
+ errorCode: effectiveErrorCode,
1644
1709
  onRetry: () => {
1710
+ setHostVerifyResult(null);
1711
+ lastResultRef.current = null;
1712
+ lastErrorCodeRef.current = null;
1645
1713
  resetFlow();
1646
1714
  openFlow();
1647
1715
  }