@paymanai/payman-ask-sdk 2.0.0 → 2.0.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.d.mts CHANGED
@@ -168,6 +168,7 @@ type MessageListV2Props = {
168
168
  payeeName?: string;
169
169
  };
170
170
  status: "pending" | "verifying" | "approved" | "rejected" | "error";
171
+ clearOtpTrigger?: number;
171
172
  } | null;
172
173
  onApproveAction?: (messageId: string, otp: string) => Promise<void>;
173
174
  onRejectAction?: (messageId: string) => Promise<void>;
package/dist/index.d.ts CHANGED
@@ -168,6 +168,7 @@ type MessageListV2Props = {
168
168
  payeeName?: string;
169
169
  };
170
170
  status: "pending" | "verifying" | "approved" | "rejected" | "error";
171
+ clearOtpTrigger?: number;
171
172
  } | null;
172
173
  onApproveAction?: (messageId: string, otp: string) => Promise<void>;
173
174
  onRejectAction?: (messageId: string) => Promise<void>;
package/dist/index.js CHANGED
@@ -1563,6 +1563,7 @@ function VerificationCardV2({
1563
1563
  messageId,
1564
1564
  action,
1565
1565
  status,
1566
+ clearOtpTrigger = 0,
1566
1567
  onApprove,
1567
1568
  onReject,
1568
1569
  onResend
@@ -1570,33 +1571,41 @@ function VerificationCardV2({
1570
1571
  const [otp, setOtp] = react.useState("");
1571
1572
  const [otpErrored, setOtpErrored] = react.useState(false);
1572
1573
  const [resendSec, setResendSec] = react.useState(0);
1574
+ const [localPending, setLocalPending] = react.useState(false);
1573
1575
  const lastSubmittedRef = react.useRef(null);
1574
1576
  const resendTimerRef = react.useRef(void 0);
1575
1577
  react.useEffect(() => {
1576
- if (status !== "error") {
1577
- setOtpErrored(false);
1578
- return;
1579
- }
1578
+ if (clearOtpTrigger <= 0) return;
1580
1579
  setOtpErrored(true);
1581
1580
  const t = window.setTimeout(() => {
1582
1581
  setOtp("");
1583
1582
  setOtpErrored(false);
1583
+ setLocalPending(false);
1584
1584
  lastSubmittedRef.current = null;
1585
1585
  }, 600);
1586
1586
  return () => window.clearTimeout(t);
1587
- }, [status]);
1587
+ }, [clearOtpTrigger]);
1588
1588
  react.useEffect(() => {
1589
1589
  if (otp.length < OTP_LEN) {
1590
1590
  lastSubmittedRef.current = null;
1591
1591
  }
1592
1592
  }, [otp]);
1593
+ react.useEffect(() => {
1594
+ if (status !== "pending") {
1595
+ setLocalPending(false);
1596
+ }
1597
+ }, [status]);
1593
1598
  react.useEffect(() => {
1594
1599
  if (otp.length !== OTP_LEN || !/^\d+$/.test(otp) || status !== "pending") {
1595
1600
  return;
1596
1601
  }
1597
1602
  if (lastSubmittedRef.current === otp) return;
1598
1603
  lastSubmittedRef.current = otp;
1599
- void onApprove(messageId, otp);
1604
+ setLocalPending(true);
1605
+ void onApprove(messageId, otp).catch(() => {
1606
+ lastSubmittedRef.current = null;
1607
+ setLocalPending(false);
1608
+ });
1600
1609
  }, [messageId, onApprove, otp, status]);
1601
1610
  react.useEffect(() => {
1602
1611
  return () => {
@@ -1624,23 +1633,25 @@ function VerificationCardV2({
1624
1633
  }, 1e3);
1625
1634
  }, []);
1626
1635
  const handleResend = react.useCallback(async () => {
1627
- if (resendSec > 0 || status === "verifying") return;
1628
- await onResend(messageId);
1629
- startResendCooldown();
1630
- }, [messageId, onResend, resendSec, startResendCooldown, status]);
1636
+ if (resendSec > 0 || status === "verifying" || localPending) return;
1637
+ setLocalPending(true);
1638
+ try {
1639
+ await onResend(messageId);
1640
+ startResendCooldown();
1641
+ } finally {
1642
+ setLocalPending(false);
1643
+ }
1644
+ }, [localPending, messageId, onResend, resendSec, startResendCooldown, status]);
1631
1645
  const handleCancel = react.useCallback(async () => {
1632
- await onReject(messageId);
1633
- }, [messageId, onReject]);
1634
- react.useCallback(async () => {
1635
- if (otp.length !== OTP_LEN || !/^\d+$/.test(otp) || status !== "pending") {
1636
- return;
1646
+ if (status === "verifying" || localPending) return;
1647
+ setLocalPending(true);
1648
+ try {
1649
+ await onReject(messageId);
1650
+ } finally {
1651
+ setLocalPending(false);
1637
1652
  }
1638
- if (lastSubmittedRef.current === otp) return;
1639
- lastSubmittedRef.current = otp;
1640
- await onApprove(messageId, otp);
1641
- }, [messageId, onApprove, otp, status]);
1642
- const busy = status === "verifying";
1643
- status === "pending" && otp.length === OTP_LEN && /^\d+$/.test(otp);
1653
+ }, [localPending, messageId, onReject, status]);
1654
+ const busy = status === "verifying" || localPending;
1644
1655
  if (status === "approved" || status === "rejected") {
1645
1656
  return null;
1646
1657
  }
@@ -1652,61 +1663,53 @@ function VerificationCardV2({
1652
1663
  animate: { opacity: 1, y: 0 },
1653
1664
  transition: { type: "spring", stiffness: 320, damping: 28 },
1654
1665
  children: [
1655
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-verification-card", children: [
1656
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-verification-header", children: [
1657
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-verification-header-row", children: [
1658
- /* @__PURE__ */ jsxRuntime.jsx(
1659
- lucideReact.ShieldCheck,
1660
- {
1661
- className: "payman-v2-verification-icon",
1662
- size: 18,
1663
- strokeWidth: 1.75,
1664
- "aria-hidden": true
1665
- }
1666
- ),
1667
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-verification-title", children: "Verify" }),
1668
- action.amount != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-verification-amount", children: action.amount }) : action.payeeName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-verification-payee", children: action.payeeName }) : null
1669
- ] }),
1670
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-verification-description", children: "Enter the 6-digit code sent to your phone" }),
1671
- /* @__PURE__ */ jsxRuntime.jsx(
1672
- OtpInputV2,
1673
- {
1674
- value: otp,
1675
- onChange: setOtp,
1676
- maxLength: OTP_LEN,
1677
- disabled: busy,
1678
- error: otpErrored
1679
- }
1666
+ /* @__PURE__ */ jsxRuntime.jsxs(
1667
+ "div",
1668
+ {
1669
+ className: cn(
1670
+ "payman-v2-verification-card",
1671
+ busy && "payman-v2-verification-card-busy"
1680
1672
  ),
1681
- busy ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-verification-submitting", children: [
1682
- /* @__PURE__ */ jsxRuntime.jsx(
1683
- framerMotion.motion.span,
1673
+ children: [
1674
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-verification-header", children: [
1675
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-verification-header-row", children: [
1676
+ /* @__PURE__ */ jsxRuntime.jsx(
1677
+ lucideReact.ShieldCheck,
1678
+ {
1679
+ className: "payman-v2-verification-icon",
1680
+ size: 18,
1681
+ strokeWidth: 1.75,
1682
+ "aria-hidden": true
1683
+ }
1684
+ ),
1685
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-verification-title", children: "Verify" }),
1686
+ action.amount != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-verification-amount", children: action.amount }) : action.payeeName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-verification-payee", children: action.payeeName }) : null
1687
+ ] }),
1688
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-verification-description", children: "Enter the 6-digit code sent to your phone" }),
1689
+ /* @__PURE__ */ jsxRuntime.jsx(
1690
+ OtpInputV2,
1691
+ {
1692
+ value: otp,
1693
+ onChange: setOtp,
1694
+ maxLength: OTP_LEN,
1695
+ disabled: busy,
1696
+ error: otpErrored
1697
+ }
1698
+ )
1699
+ ] }),
1700
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-verification-actions", children: /* @__PURE__ */ jsxRuntime.jsx(
1701
+ "button",
1684
1702
  {
1685
- "aria-hidden": true,
1686
- style: { display: "inline-flex" },
1687
- animate: { rotate: 360 },
1688
- transition: {
1689
- repeat: Infinity,
1690
- duration: 0.7,
1691
- ease: "linear"
1692
- },
1693
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 14, strokeWidth: 2 })
1703
+ type: "button",
1704
+ className: "payman-v2-verification-cancel-btn",
1705
+ disabled: busy,
1706
+ onClick: () => void handleCancel(),
1707
+ children: "Cancel"
1694
1708
  }
1695
- ),
1696
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-verification-submitting-text", children: "Verifying..." })
1697
- ] }) : null
1698
- ] }),
1699
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-verification-actions", children: /* @__PURE__ */ jsxRuntime.jsx(
1700
- "button",
1701
- {
1702
- type: "button",
1703
- className: "payman-v2-verification-cancel-btn",
1704
- disabled: busy,
1705
- onClick: () => void handleCancel(),
1706
- children: "Cancel"
1707
- }
1708
- ) })
1709
- ] }),
1709
+ ) })
1710
+ ]
1711
+ }
1712
+ ),
1710
1713
  /* @__PURE__ */ jsxRuntime.jsx(
1711
1714
  "button",
1712
1715
  {
@@ -1899,6 +1902,7 @@ var MessageListV2 = react.forwardRef(
1899
1902
  messageId: userAction.messageId,
1900
1903
  action: userAction.action,
1901
1904
  status: userAction.status,
1905
+ clearOtpTrigger: userAction.clearOtpTrigger,
1902
1906
  onApprove: onApproveAction ?? (async () => {
1903
1907
  }),
1904
1908
  onReject: onRejectAction ?? (async () => {
@@ -3707,6 +3711,14 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
3707
3711
  }),
3708
3712
  [performResetSession, clearMessages, cancelStream, getSessionId, getMessages, loadSession]
3709
3713
  );
3714
+ const [v2VerificationPending, setV2VerificationPending] = react.useState(false);
3715
+ react.useEffect(() => {
3716
+ setV2VerificationPending(false);
3717
+ }, [
3718
+ userActionState.request?.userActionId,
3719
+ userActionState.clearOtpTrigger,
3720
+ userActionState.result
3721
+ ]);
3710
3722
  if (availability.state === "disabled") {
3711
3723
  return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
3712
3724
  "div",
@@ -3729,7 +3741,8 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
3729
3741
  if (!userActionState.request) return null;
3730
3742
  const req = userActionState.request;
3731
3743
  let status = "pending";
3732
- if (userActionState.result === "approved") status = "approved";
3744
+ if (v2VerificationPending) status = "verifying";
3745
+ else if (userActionState.result === "approved") status = "approved";
3733
3746
  else if (userActionState.result === "rejected") status = "rejected";
3734
3747
  return {
3735
3748
  messageId: `ua-${req.userActionId || Date.now()}`,
@@ -3739,9 +3752,15 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
3739
3752
  amount: req.metadata?.amount,
3740
3753
  payeeName: req.metadata?.payeeName
3741
3754
  },
3742
- status
3755
+ status,
3756
+ clearOtpTrigger: userActionState.clearOtpTrigger
3743
3757
  };
3744
- }, [userActionState.request, userActionState.result]);
3758
+ }, [
3759
+ userActionState.request,
3760
+ userActionState.result,
3761
+ userActionState.clearOtpTrigger,
3762
+ v2VerificationPending
3763
+ ]);
3745
3764
  const hideV2SendDuringVerification = v2UserAction != null && v2UserAction.status !== "approved" && v2UserAction.status !== "rejected";
3746
3765
  const handleV2Send = (text) => {
3747
3766
  if (isRecording) stopRecording();
@@ -3903,10 +3922,22 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
3903
3922
  retryDisabled: isWaitingForResponse,
3904
3923
  userAction: v2UserAction,
3905
3924
  onApproveAction: async (_id, otp) => {
3906
- await approveUserAction(otp);
3925
+ setV2VerificationPending(true);
3926
+ try {
3927
+ await approveUserAction(otp);
3928
+ } catch (error) {
3929
+ setV2VerificationPending(false);
3930
+ throw error;
3931
+ }
3907
3932
  },
3908
3933
  onRejectAction: async () => {
3909
- await rejectUserAction();
3934
+ setV2VerificationPending(true);
3935
+ try {
3936
+ await rejectUserAction();
3937
+ } catch (error) {
3938
+ setV2VerificationPending(false);
3939
+ throw error;
3940
+ }
3910
3941
  },
3911
3942
  onResendAction: async () => {
3912
3943
  await resendOtp();