@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.cjs CHANGED
@@ -591,6 +591,28 @@ var ACTION_POLL_MAX_RETRIES = 20;
591
591
  var SIGN_PERMIT2_POLL_MS = 1e3;
592
592
  var SIGN_PERMIT2_MAX_POLLS = 15;
593
593
  var TRANSFER_SIGN_MAX_POLLS = 60;
594
+ function waitForDocumentFocus(timeoutMs = 5e3, intervalMs = 100) {
595
+ return new Promise((resolve, reject) => {
596
+ if (typeof document === "undefined") {
597
+ resolve();
598
+ return;
599
+ }
600
+ if (document.hasFocus()) {
601
+ resolve();
602
+ return;
603
+ }
604
+ const deadline = Date.now() + timeoutMs;
605
+ const timer = setInterval(() => {
606
+ if (document.hasFocus()) {
607
+ clearInterval(timer);
608
+ resolve();
609
+ } else if (Date.now() >= deadline) {
610
+ clearInterval(timer);
611
+ resolve();
612
+ }
613
+ }, intervalMs);
614
+ });
615
+ }
594
616
  function actionSuccess(action, message, data) {
595
617
  return { actionId: action.id, type: action.type, status: "success", message, data };
596
618
  }
@@ -682,6 +704,7 @@ async function createPasskeyCredential(userIdentifier) {
682
704
  const challenge = new Uint8Array(32);
683
705
  crypto.getRandomValues(challenge);
684
706
  const rpId = resolvePasskeyRpId();
707
+ await waitForDocumentFocus();
685
708
  const credential = await navigator.credentials.create({
686
709
  publicKey: {
687
710
  challenge,
@@ -1187,6 +1210,7 @@ function useTransferSigning(pollIntervalMs = 2e3, options) {
1187
1210
  type: "public-key",
1188
1211
  id: base64ToBytes(payload.passkeyCredentialId)
1189
1212
  }] : void 0;
1213
+ await waitForDocumentFocus();
1190
1214
  const assertion = await navigator.credentials.get({
1191
1215
  publicKey: {
1192
1216
  challenge: hashBytes,
@@ -1983,6 +2007,7 @@ function buildProcessingTimeoutMessage(status) {
1983
2007
  return `Payment is taking longer than expected (status: ${status}). Please try again.`;
1984
2008
  }
1985
2009
  var ACTIVE_CREDENTIAL_STORAGE_KEY = "swype_active_credential_id";
2010
+ var MIN_SEND_AMOUNT_USD = 0.25;
1986
2011
  function isMobile() {
1987
2012
  if (typeof navigator === "undefined") return false;
1988
2013
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
@@ -2065,7 +2090,7 @@ function SwypePayment({
2065
2090
  useWalletConnector
2066
2091
  }) {
2067
2092
  const { apiBaseUrl, tokens, depositAmount } = useSwypeConfig();
2068
- const { ready, authenticated, login, getAccessToken } = reactAuth.usePrivy();
2093
+ const { ready, authenticated, login, logout, getAccessToken } = reactAuth.usePrivy();
2069
2094
  const [step, setStep] = react.useState("login");
2070
2095
  const [error, setError] = react.useState(null);
2071
2096
  const [providers, setProviders] = react.useState([]);
@@ -2308,8 +2333,8 @@ function SwypePayment({
2308
2333
  }, [pendingSelectSourceAction, selectSourceChoices, selectSourceRecommended]);
2309
2334
  const handlePay = react.useCallback(async () => {
2310
2335
  const parsedAmount = parseFloat(amount);
2311
- if (isNaN(parsedAmount) || parsedAmount <= 0) {
2312
- setError("Enter a valid amount.");
2336
+ if (isNaN(parsedAmount) || parsedAmount < MIN_SEND_AMOUNT_USD) {
2337
+ setError(`Minimum amount is $${MIN_SEND_AMOUNT_USD.toFixed(2)}.`);
2313
2338
  return;
2314
2339
  }
2315
2340
  if (!sourceId) {
@@ -2416,6 +2441,38 @@ function SwypePayment({
2416
2441
  setAdvancedSettings({ asset: null, chain: null });
2417
2442
  if (accounts.length > 0) setSelectedAccountId(accounts[0].id);
2418
2443
  };
2444
+ const handleLogout = react.useCallback(async () => {
2445
+ try {
2446
+ await logout();
2447
+ } catch {
2448
+ }
2449
+ if (typeof window !== "undefined") {
2450
+ window.localStorage.removeItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
2451
+ }
2452
+ polling.stopPolling();
2453
+ setActiveCredentialId(null);
2454
+ setStep("login");
2455
+ setError(null);
2456
+ setTransfer(null);
2457
+ setCreatingTransfer(false);
2458
+ setRegisteringPasskey(false);
2459
+ setProviders([]);
2460
+ setAccounts([]);
2461
+ setChains([]);
2462
+ setSelectedAccountId(null);
2463
+ setSelectedWalletId(null);
2464
+ setSelectedProviderId(null);
2465
+ setConnectingNewAccount(false);
2466
+ setAmount(depositAmount != null ? depositAmount.toString() : "");
2467
+ setAdvancedSettings({ asset: null, chain: null });
2468
+ setMobileFlow(false);
2469
+ setSelectSourceChainName("");
2470
+ setSelectSourceTokenSymbol("");
2471
+ initializedSelectSourceActionRef.current = null;
2472
+ processingStartedAtRef.current = null;
2473
+ pollingTransferIdRef.current = null;
2474
+ mobileSigningTransferIdRef.current = null;
2475
+ }, [logout, polling, depositAmount]);
2419
2476
  const handleConnectNewAccount = (providerId) => {
2420
2477
  setSelectedProviderId(providerId);
2421
2478
  setSelectedAccountId(null);
@@ -2653,7 +2710,7 @@ function SwypePayment({
2653
2710
  }
2654
2711
  if (step === "enter-amount") {
2655
2712
  const parsedAmount = parseFloat(amount);
2656
- const canContinue = !isNaN(parsedAmount) && parsedAmount > 0;
2713
+ const canContinue = !isNaN(parsedAmount) && parsedAmount >= MIN_SEND_AMOUNT_USD;
2657
2714
  let maxSourceBalance = null;
2658
2715
  for (const acct of accounts) {
2659
2716
  for (const wallet of acct.wallets) {
@@ -2700,7 +2757,7 @@ function SwypePayment({
2700
2757
  "input",
2701
2758
  {
2702
2759
  type: "number",
2703
- min: "0.01",
2760
+ min: MIN_SEND_AMOUNT_USD.toFixed(2),
2704
2761
  step: "0.01",
2705
2762
  value: amount,
2706
2763
  onChange: (e) => setAmount(e.target.value),
@@ -2770,10 +2827,35 @@ function SwypePayment({
2770
2827
  }
2771
2828
  if (step === "ready") {
2772
2829
  const parsedAmount = parseFloat(amount);
2773
- const canPay = !isNaN(parsedAmount) && parsedAmount > 0 && !!sourceId && !loadingData;
2830
+ const canPay = !isNaN(parsedAmount) && parsedAmount >= MIN_SEND_AMOUNT_USD && !!sourceId && !loadingData;
2774
2831
  const noAccounts = !loadingData && accounts.length === 0;
2775
2832
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: cardStyle, children: [
2776
- stepBadge("Review & pay"),
2833
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
2834
+ stepBadge("Review & pay"),
2835
+ /* @__PURE__ */ jsxRuntime.jsx(
2836
+ "button",
2837
+ {
2838
+ type: "button",
2839
+ onClick: handleLogout,
2840
+ style: {
2841
+ position: "absolute",
2842
+ top: 0,
2843
+ right: 0,
2844
+ background: "transparent",
2845
+ border: "none",
2846
+ color: tokens.textMuted,
2847
+ cursor: "pointer",
2848
+ fontSize: "0.75rem",
2849
+ fontWeight: 600,
2850
+ letterSpacing: "0.04em",
2851
+ textTransform: "uppercase",
2852
+ fontFamily: "inherit",
2853
+ padding: 0
2854
+ },
2855
+ children: "Logout"
2856
+ }
2857
+ )
2858
+ ] }),
2777
2859
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorStyle, children: error }),
2778
2860
  loadingData ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "24px 0", textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { label: "Loading..." }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2779
2861
  /* @__PURE__ */ jsxRuntime.jsxs(