@volr/react-ui 0.1.133 → 0.1.135

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.cjs CHANGED
@@ -552,12 +552,12 @@ var en = {
552
552
  alreadyExists: "Biometric login is already set up.",
553
553
  notSupported: "Your device doesn't support biometric login.",
554
554
  prfNotSupported: "Setup failed. Please use your device's biometric (Touch ID, Face ID) directly. Using other devices or apps may not work.",
555
- prfNotSupportedWindows: `Setup failed. Windows Hello doesn't support PRF. In the passkey picker, choose "Use a phone or tablet".`,
555
+ prfNotSupportedWindows: `Setup failed. The selected passkey provider doesn't support PRF. In the passkey picker, choose "Use a phone or tablet" and complete with Google Password Manager on the device.`,
556
556
  generic: "Setup failed. Please try again."
557
557
  },
558
558
  compatibility: {
559
559
  title: "Browser Update Required",
560
- inAppBrowser: "Secure login is not available in this app browser. Please open in Safari or Chrome.",
560
+ inAppBrowser: "Passkeys are not supported in in-app browsers. Please open in your device browser (Chrome/Edge on Android, Safari on iOS).",
561
561
  outdatedChrome: "Chrome 109 or later is required. Please update your browser.",
562
562
  outdatedEdge: "Edge 109 or later is required. Please update your browser.",
563
563
  outdatedSafari: "Safari 17.4 or later is required. Please update macOS/iOS.",
@@ -579,7 +579,7 @@ var en = {
579
579
  linux: "Scan the QR code on screen with your phone camera.",
580
580
  default: "Please use this device's biometric.",
581
581
  note: "Using other devices or apps may not work.",
582
- windowsNote: "This PC will use Face ID or fingerprint from your phone."
582
+ windowsNote: "Complete on your phone or tablet with Google Password Manager for best compatibility."
583
583
  },
584
584
  migration: {
585
585
  title: "Set up passkey for this site",
@@ -703,6 +703,16 @@ var en = {
703
703
  confirming: "Almost done...",
704
704
  default: "Processing...",
705
705
  doNotClose: "Please don't close this window"
706
+ },
707
+ result: {
708
+ successTitle: "Payment Complete",
709
+ failureTitle: "Payment Failed",
710
+ successMessage: "Your payment has been processed successfully",
711
+ failureMessage: "Something went wrong. Please try again.",
712
+ amountLabel: "Amount",
713
+ usdValueLabel: "USD Value",
714
+ transactionLabel: "Transaction",
715
+ reportIssue: "Report an issue"
706
716
  }
707
717
  },
708
718
  errors: {
@@ -799,12 +809,12 @@ var ko = {
799
809
  alreadyExists: "\uC774\uBBF8 \uC0DD\uCCB4 \uB85C\uADF8\uC778\uC774 \uC124\uC815\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.",
800
810
  notSupported: "\uC774 \uAE30\uAE30\uB294 \uC0DD\uCCB4 \uB85C\uADF8\uC778\uC744 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
801
811
  prfNotSupported: "\uC124\uC815\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uC774 \uAE30\uAE30\uC758 \uC0DD\uCCB4 \uC778\uC99D(Touch ID, Face ID)\uC744 \uC9C1\uC811 \uC120\uD0DD\uD574\uC8FC\uC138\uC694. \uB2E4\uB978 \uAE30\uAE30\uB098 \uC571 \uC0AC\uC6A9 \uC2DC \uB3D9\uC791\uD558\uC9C0 \uC54A\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
802
- prfNotSupportedWindows: '\uC124\uC815\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. Windows Hello\uB294 PRF\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uD328\uC2A4\uD0A4 \uC120\uD0DD \uD654\uBA74\uC5D0\uC11C "\uD734\uB300\uD3F0/\uD0DC\uBE14\uB9BF \uC0AC\uC6A9"\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694.',
812
+ prfNotSupportedWindows: '\uC124\uC815\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uC120\uD0DD\uD55C \uD328\uC2A4\uD0A4 \uC81C\uACF5\uC790\uAC00 PRF\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uD328\uC2A4\uD0A4 \uC120\uD0DD \uD654\uBA74\uC5D0\uC11C "\uD734\uB300\uD3F0/\uD0DC\uBE14\uB9BF \uC0AC\uC6A9"\uC744 \uC120\uD0DD\uD558\uACE0, \uD734\uB300\uD3F0/\uD0DC\uBE14\uB9BF\uC5D0\uC11C\uB294 Google Password Manager\uB85C \uC9C4\uD589\uD574\uC8FC\uC138\uC694.',
803
813
  generic: "\uC124\uC815\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."
804
814
  },
805
815
  compatibility: {
806
816
  title: "\uBE0C\uB77C\uC6B0\uC800 \uC5C5\uB370\uC774\uD2B8 \uD544\uC694",
807
- inAppBrowser: "\uD604\uC7AC \uC571 \uB0B4 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C\uB294 \uBCF4\uC548 \uB85C\uADF8\uC778\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. Safari \uB610\uB294 Chrome\uC5D0\uC11C \uC5F4\uC5B4\uC8FC\uC138\uC694.",
817
+ inAppBrowser: "\uC571 \uB0B4 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C\uB294 \uD328\uC2A4\uD0A4 \uB85C\uADF8\uC778\uC744 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uAE30\uBCF8 \uBE0C\uB77C\uC6B0\uC800(\uC548\uB4DC\uB85C\uC774\uB4DC: Chrome/Edge, iOS: Safari)\uC5D0\uC11C \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.",
808
818
  outdatedChrome: "Chrome 109 \uC774\uC0C1 \uBC84\uC804\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uBE0C\uB77C\uC6B0\uC800\uB97C \uC5C5\uB370\uC774\uD2B8\uD574\uC8FC\uC138\uC694.",
809
819
  outdatedEdge: "Edge 109 \uC774\uC0C1 \uBC84\uC804\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uBE0C\uB77C\uC6B0\uC800\uB97C \uC5C5\uB370\uC774\uD2B8\uD574\uC8FC\uC138\uC694.",
810
820
  outdatedSafari: "Safari 17.4 \uC774\uC0C1 \uBC84\uC804\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. macOS/iOS\uB97C \uC5C5\uB370\uC774\uD2B8\uD574\uC8FC\uC138\uC694.",
@@ -826,7 +836,7 @@ var ko = {
826
836
  linux: "\uD734\uB300\uD3F0 \uCE74\uBA54\uB77C\uB85C \uD654\uBA74\uC758 QR \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD574\uC8FC\uC138\uC694.",
827
837
  default: "\uC774 \uAE30\uAE30\uC758 \uC0DD\uCCB4 \uC778\uC99D\uC744 \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694.",
828
838
  note: "\uB2E4\uB978 \uAE30\uAE30\uB098 \uC571 \uC0AC\uC6A9 \uC2DC \uB3D9\uC791\uD558\uC9C0 \uC54A\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
829
- windowsNote: "\uC774 PC\uC5D0\uC11C\uB294 \uD734\uB300\uD3F0\uC758 Face ID \uB610\uB294 \uC9C0\uBB38 \uC778\uC2DD\uC744 \uC0AC\uC6A9\uD569\uB2C8\uB2E4."
839
+ windowsNote: "\uD734\uB300\uD3F0/\uD0DC\uBE14\uB9BF\uC5D0\uC11C\uB294 Google Password Manager\uB85C \uC9C4\uD589\uD558\uBA74 \uC548\uC815\uC801\uC785\uB2C8\uB2E4."
830
840
  },
831
841
  migration: {
832
842
  title: "\uC774 \uC0AC\uC774\uD2B8\uC6A9 \uD328\uC2A4\uD0A4 \uC124\uC815",
@@ -975,6 +985,16 @@ var ko = {
975
985
  confirming: "\uAC70\uC758 \uC644\uB8CC...",
976
986
  default: "\uCC98\uB9AC \uC911...",
977
987
  doNotClose: "\uCC3D\uC744 \uB2EB\uC9C0 \uB9C8\uC138\uC694"
988
+ },
989
+ result: {
990
+ successTitle: "\uACB0\uC81C \uC644\uB8CC",
991
+ failureTitle: "\uACB0\uC81C \uC2E4\uD328",
992
+ successMessage: "\uACB0\uC81C\uAC00 \uC815\uC0C1\uC801\uC73C\uB85C \uCC98\uB9AC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",
993
+ failureMessage: "\uBB38\uC81C\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.",
994
+ amountLabel: "\uAE08\uC561",
995
+ usdValueLabel: "USD \uAC00\uCE58",
996
+ transactionLabel: "\uD2B8\uB79C\uC7AD\uC158",
997
+ reportIssue: "\uBB38\uC81C \uC2E0\uACE0\uD558\uAE30"
978
998
  }
979
999
  },
980
1000
  errors: {
@@ -6006,6 +6026,15 @@ function usePaymentModalState(open, onOpenChange) {
6006
6026
  });
6007
6027
  createdPaymentId = payment.id;
6008
6028
  dispatch({ type: "SET_CREATED_PAYMENT", payment });
6029
+ if (payment.status !== "PENDING") {
6030
+ const alreadyProcessedError = new Error(
6031
+ payment.status === "CONFIRMED" ? "This payment has already been completed. If you used an idempotencyKey, the original payment was already processed." : `Payment already processed with status: ${payment.status}. If you used an idempotencyKey, the original payment was already processed.`
6032
+ );
6033
+ alreadyProcessedError.code = "PAYMENT_ALREADY_PROCESSED";
6034
+ alreadyProcessedError.paymentStatus = payment.status;
6035
+ alreadyProcessedError.payment = payment;
6036
+ throw alreadyProcessedError;
6037
+ }
6009
6038
  paymentOptions.options.handlers?.onCreated?.({ id: payment.id });
6010
6039
  const evmClient = evm.client(tokenInfo.chainId);
6011
6040
  dispatch({ type: "SET_PROCESSING_STEP", step: "broadcasting" });
@@ -6051,13 +6080,28 @@ function usePaymentModalState(open, onOpenChange) {
6051
6080
  }
6052
6081
  } catch (err) {
6053
6082
  console.error("Payment failed:", err);
6054
- if (createdPaymentId) {
6083
+ const isAlreadyProcessed = err.code === "PAYMENT_ALREADY_PROCESSED";
6084
+ if (createdPaymentId && !isAlreadyProcessed) {
6055
6085
  try {
6056
6086
  await failPendingPayment(createdPaymentId);
6057
6087
  } catch (failErr) {
6058
6088
  console.error("Failed to mark payment as failed:", failErr);
6059
6089
  }
6060
6090
  }
6091
+ if (isAlreadyProcessed && err.payment) {
6092
+ dispatch({ type: "PAYMENT_SUCCESS", payment: err.payment });
6093
+ if (err.payment.status === "CONFIRMED") {
6094
+ paymentOptions?.onComplete?.(err.payment);
6095
+ } else {
6096
+ const paymentError2 = {
6097
+ code: err.code || "PAYMENT_ALREADY_PROCESSED",
6098
+ message: err.message || "Payment already processed."
6099
+ };
6100
+ dispatch({ type: "PAYMENT_ERROR", error: paymentError2 });
6101
+ paymentOptions?.onError?.(paymentError2);
6102
+ }
6103
+ return;
6104
+ }
6061
6105
  const paymentError = {
6062
6106
  code: err.code || "PAYMENT_FAILED",
6063
6107
  message: err.message || "Payment failed. Please try again."
@@ -6617,8 +6661,14 @@ var PaymentResultView = ({
6617
6661
  onRetry,
6618
6662
  onReport
6619
6663
  }) => {
6664
+ const { t } = useI18n();
6620
6665
  const isSuccess = payment.status === "CONFIRMED";
6621
6666
  payment.status === "FAILED" || !!error;
6667
+ const isInAppBrowserError = error?.code === "INAPP_BROWSER_NOT_SUPPORTED";
6668
+ const handleOpenExternalBrowser = () => {
6669
+ if (typeof window === "undefined") return;
6670
+ window.open(window.location.href, "_system");
6671
+ };
6622
6672
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "volr:space-y-6", children: [
6623
6673
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "volr:flex volr:justify-center volr:pt-2", children: isSuccess ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "volr:w-14 volr:h-14 volr:rounded-full volr:bg-green-50 volr:flex volr:items-center volr:justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
6624
6674
  "svg",
@@ -6656,12 +6706,12 @@ var PaymentResultView = ({
6656
6706
  }
6657
6707
  ) }) }),
6658
6708
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "volr:text-center volr:space-y-1", children: [
6659
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "volr:text-lg volr:font-semibold volr:text-slate-900", children: isSuccess ? "Payment Complete" : "Payment Failed" }),
6660
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "volr:text-sm volr:text-slate-500", children: isSuccess ? "Your payment has been processed successfully" : error?.message || "Something went wrong. Please try again." })
6709
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "volr:text-lg volr:font-semibold volr:text-slate-900", children: isSuccess ? t("payment.result.successTitle") : t("payment.result.failureTitle") }),
6710
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "volr:text-sm volr:text-slate-500", children: isSuccess ? t("payment.result.successMessage") : isInAppBrowserError ? t("passkey.compatibility.inAppBrowser") : error?.message || t("payment.result.failureMessage") })
6661
6711
  ] }),
6662
6712
  isSuccess && payment.txHash && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "volr:bg-slate-50 volr:rounded-lg volr:p-4 volr:space-y-2", children: [
6663
6713
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "volr:flex volr:justify-between volr:text-sm", children: [
6664
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "volr:text-slate-500", children: "Amount" }),
6714
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "volr:text-slate-500", children: t("payment.result.amountLabel") }),
6665
6715
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "volr:font-medium volr:text-slate-900", children: [
6666
6716
  (Number(payment.amount) / Math.pow(10, payment.token.decimals)).toLocaleString(),
6667
6717
  " ",
@@ -6669,14 +6719,14 @@ var PaymentResultView = ({
6669
6719
  ] })
6670
6720
  ] }),
6671
6721
  payment.totalUsd && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "volr:flex volr:justify-between volr:text-sm", children: [
6672
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "volr:text-slate-500", children: "USD Value" }),
6722
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "volr:text-slate-500", children: t("payment.result.usdValueLabel") }),
6673
6723
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "volr:text-slate-600", children: [
6674
6724
  "$",
6675
6725
  parseFloat(payment.totalUsd).toFixed(2)
6676
6726
  ] })
6677
6727
  ] }),
6678
6728
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "volr:flex volr:justify-between volr:text-sm", children: [
6679
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "volr:text-slate-500", children: "Transaction" }),
6729
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "volr:text-slate-500", children: t("payment.result.transactionLabel") }),
6680
6730
  /* @__PURE__ */ jsxRuntime.jsxs("code", { className: "volr:text-xs volr:text-slate-600 volr:font-mono", children: [
6681
6731
  payment.txHash.slice(0, 8),
6682
6732
  "...",
@@ -6684,14 +6734,23 @@ var PaymentResultView = ({
6684
6734
  ] })
6685
6735
  ] })
6686
6736
  ] }),
6687
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "volr:space-y-4", children: isSuccess ? /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onDone, className: "volr:w-full", children: "Done" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6688
- /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onRetry, className: "volr:w-full", children: "Try Again" }),
6737
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "volr:space-y-4", children: isSuccess ? /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onDone, className: "volr:w-full", children: t("common.done") }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6738
+ isInAppBrowserError && /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleOpenExternalBrowser, className: "volr:w-full", children: t("passkey.compatibility.openInExternalBrowser") }),
6739
+ /* @__PURE__ */ jsxRuntime.jsx(
6740
+ Button,
6741
+ {
6742
+ onClick: onRetry,
6743
+ className: "volr:w-full",
6744
+ variant: isInAppBrowserError ? "secondary" : void 0,
6745
+ children: t("common.tryAgain")
6746
+ }
6747
+ ),
6689
6748
  /* @__PURE__ */ jsxRuntime.jsx(
6690
6749
  "button",
6691
6750
  {
6692
6751
  onClick: onReport,
6693
6752
  className: "volr:w-full volr:text-sm volr:text-slate-400 hover:volr:text-slate-600 volr:transition-colors volr:py-2",
6694
- children: "Report an issue"
6753
+ children: t("payment.result.reportIssue")
6695
6754
  }
6696
6755
  )
6697
6756
  ] }) }),