@swype-org/react-sdk 0.1.13 → 0.1.15

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
@@ -588,6 +588,28 @@ var ACTION_POLL_MAX_RETRIES = 20;
588
588
  var SIGN_PERMIT2_POLL_MS = 1e3;
589
589
  var SIGN_PERMIT2_MAX_POLLS = 15;
590
590
  var TRANSFER_SIGN_MAX_POLLS = 60;
591
+ function waitForDocumentFocus(timeoutMs = 5e3, intervalMs = 100) {
592
+ return new Promise((resolve, reject) => {
593
+ if (typeof document === "undefined") {
594
+ resolve();
595
+ return;
596
+ }
597
+ if (document.hasFocus()) {
598
+ resolve();
599
+ return;
600
+ }
601
+ const deadline = Date.now() + timeoutMs;
602
+ const timer = setInterval(() => {
603
+ if (document.hasFocus()) {
604
+ clearInterval(timer);
605
+ resolve();
606
+ } else if (Date.now() >= deadline) {
607
+ clearInterval(timer);
608
+ resolve();
609
+ }
610
+ }, intervalMs);
611
+ });
612
+ }
591
613
  function actionSuccess(action, message, data) {
592
614
  return { actionId: action.id, type: action.type, status: "success", message, data };
593
615
  }
@@ -679,6 +701,7 @@ async function createPasskeyCredential(userIdentifier) {
679
701
  const challenge = new Uint8Array(32);
680
702
  crypto.getRandomValues(challenge);
681
703
  const rpId = resolvePasskeyRpId();
704
+ await waitForDocumentFocus();
682
705
  const credential = await navigator.credentials.create({
683
706
  publicKey: {
684
707
  challenge,
@@ -1184,6 +1207,7 @@ function useTransferSigning(pollIntervalMs = 2e3, options) {
1184
1207
  type: "public-key",
1185
1208
  id: base64ToBytes(payload.passkeyCredentialId)
1186
1209
  }] : void 0;
1210
+ await waitForDocumentFocus();
1187
1211
  const assertion = await navigator.credentials.get({
1188
1212
  publicKey: {
1189
1213
  challenge: hashBytes,
@@ -1980,6 +2004,7 @@ function buildProcessingTimeoutMessage(status) {
1980
2004
  return `Payment is taking longer than expected (status: ${status}). Please try again.`;
1981
2005
  }
1982
2006
  var ACTIVE_CREDENTIAL_STORAGE_KEY = "swype_active_credential_id";
2007
+ var MIN_SEND_AMOUNT_USD = 0.25;
1983
2008
  function isMobile() {
1984
2009
  if (typeof navigator === "undefined") return false;
1985
2010
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
@@ -2062,7 +2087,7 @@ function SwypePayment({
2062
2087
  useWalletConnector
2063
2088
  }) {
2064
2089
  const { apiBaseUrl, tokens, depositAmount } = useSwypeConfig();
2065
- const { ready, authenticated, login, getAccessToken } = usePrivy();
2090
+ const { ready, authenticated, login, logout, getAccessToken } = usePrivy();
2066
2091
  const [step, setStep] = useState("login");
2067
2092
  const [error, setError] = useState(null);
2068
2093
  const [providers, setProviders] = useState([]);
@@ -2305,8 +2330,8 @@ function SwypePayment({
2305
2330
  }, [pendingSelectSourceAction, selectSourceChoices, selectSourceRecommended]);
2306
2331
  const handlePay = useCallback(async () => {
2307
2332
  const parsedAmount = parseFloat(amount);
2308
- if (isNaN(parsedAmount) || parsedAmount <= 0) {
2309
- setError("Enter a valid amount.");
2333
+ if (isNaN(parsedAmount) || parsedAmount < MIN_SEND_AMOUNT_USD) {
2334
+ setError(`Minimum amount is $${MIN_SEND_AMOUNT_USD.toFixed(2)}.`);
2310
2335
  return;
2311
2336
  }
2312
2337
  if (!sourceId) {
@@ -2413,6 +2438,38 @@ function SwypePayment({
2413
2438
  setAdvancedSettings({ asset: null, chain: null });
2414
2439
  if (accounts.length > 0) setSelectedAccountId(accounts[0].id);
2415
2440
  };
2441
+ const handleLogout = useCallback(async () => {
2442
+ try {
2443
+ await logout();
2444
+ } catch {
2445
+ }
2446
+ if (typeof window !== "undefined") {
2447
+ window.localStorage.removeItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
2448
+ }
2449
+ polling.stopPolling();
2450
+ setActiveCredentialId(null);
2451
+ setStep("login");
2452
+ setError(null);
2453
+ setTransfer(null);
2454
+ setCreatingTransfer(false);
2455
+ setRegisteringPasskey(false);
2456
+ setProviders([]);
2457
+ setAccounts([]);
2458
+ setChains([]);
2459
+ setSelectedAccountId(null);
2460
+ setSelectedWalletId(null);
2461
+ setSelectedProviderId(null);
2462
+ setConnectingNewAccount(false);
2463
+ setAmount(depositAmount != null ? depositAmount.toString() : "");
2464
+ setAdvancedSettings({ asset: null, chain: null });
2465
+ setMobileFlow(false);
2466
+ setSelectSourceChainName("");
2467
+ setSelectSourceTokenSymbol("");
2468
+ initializedSelectSourceActionRef.current = null;
2469
+ processingStartedAtRef.current = null;
2470
+ pollingTransferIdRef.current = null;
2471
+ mobileSigningTransferIdRef.current = null;
2472
+ }, [logout, polling, depositAmount]);
2416
2473
  const handleConnectNewAccount = (providerId) => {
2417
2474
  setSelectedProviderId(providerId);
2418
2475
  setSelectedAccountId(null);
@@ -2650,7 +2707,7 @@ function SwypePayment({
2650
2707
  }
2651
2708
  if (step === "enter-amount") {
2652
2709
  const parsedAmount = parseFloat(amount);
2653
- const canContinue = !isNaN(parsedAmount) && parsedAmount > 0;
2710
+ const canContinue = !isNaN(parsedAmount) && parsedAmount >= MIN_SEND_AMOUNT_USD;
2654
2711
  let maxSourceBalance = null;
2655
2712
  for (const acct of accounts) {
2656
2713
  for (const wallet of acct.wallets) {
@@ -2697,7 +2754,7 @@ function SwypePayment({
2697
2754
  "input",
2698
2755
  {
2699
2756
  type: "number",
2700
- min: "0.01",
2757
+ min: MIN_SEND_AMOUNT_USD.toFixed(2),
2701
2758
  step: "0.01",
2702
2759
  value: amount,
2703
2760
  onChange: (e) => setAmount(e.target.value),
@@ -2767,10 +2824,35 @@ function SwypePayment({
2767
2824
  }
2768
2825
  if (step === "ready") {
2769
2826
  const parsedAmount = parseFloat(amount);
2770
- const canPay = !isNaN(parsedAmount) && parsedAmount > 0 && !!sourceId && !loadingData;
2827
+ const canPay = !isNaN(parsedAmount) && parsedAmount >= MIN_SEND_AMOUNT_USD && !!sourceId && !loadingData;
2771
2828
  const noAccounts = !loadingData && accounts.length === 0;
2772
2829
  return /* @__PURE__ */ jsxs("div", { style: cardStyle, children: [
2773
- stepBadge("Review & pay"),
2830
+ /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
2831
+ stepBadge("Review & pay"),
2832
+ /* @__PURE__ */ jsx(
2833
+ "button",
2834
+ {
2835
+ type: "button",
2836
+ onClick: handleLogout,
2837
+ style: {
2838
+ position: "absolute",
2839
+ top: 0,
2840
+ right: 0,
2841
+ background: "transparent",
2842
+ border: "none",
2843
+ color: tokens.textMuted,
2844
+ cursor: "pointer",
2845
+ fontSize: "0.75rem",
2846
+ fontWeight: 600,
2847
+ letterSpacing: "0.04em",
2848
+ textTransform: "uppercase",
2849
+ fontFamily: "inherit",
2850
+ padding: 0
2851
+ },
2852
+ children: "Logout"
2853
+ }
2854
+ )
2855
+ ] }),
2774
2856
  error && /* @__PURE__ */ jsx("div", { style: errorStyle, children: error }),
2775
2857
  loadingData ? /* @__PURE__ */ jsx("div", { style: { padding: "24px 0", textAlign: "center" }, children: /* @__PURE__ */ jsx(Spinner, { label: "Loading..." }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2776
2858
  /* @__PURE__ */ jsxs(