@swype-org/react-sdk 0.1.12 → 0.1.14

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
@@ -1957,6 +1957,31 @@ function AdvancedSettings({
1957
1957
  )
1958
1958
  ] });
1959
1959
  }
1960
+
1961
+ // src/processingStatus.ts
1962
+ var PROCESSING_TIMEOUT_MS = 18e4;
1963
+ function resolvePreferredTransfer(polledTransfer, localTransfer) {
1964
+ return polledTransfer ?? localTransfer;
1965
+ }
1966
+ function getTransferStatus(polledTransfer, localTransfer) {
1967
+ const transfer = resolvePreferredTransfer(polledTransfer, localTransfer);
1968
+ return transfer?.status ?? "UNKNOWN";
1969
+ }
1970
+ function getDisplayTransferStatus(polledTransfer, localTransfer) {
1971
+ return getTransferStatus(polledTransfer, localTransfer).toUpperCase();
1972
+ }
1973
+ function getTransferIdSuffix(polledTransfer, localTransfer) {
1974
+ const transfer = resolvePreferredTransfer(polledTransfer, localTransfer);
1975
+ if (!transfer?.id) return "n/a";
1976
+ return transfer.id.slice(-8);
1977
+ }
1978
+ function hasProcessingTimedOut(processingStartedAtMs, nowMs) {
1979
+ if (!processingStartedAtMs) return false;
1980
+ return nowMs - processingStartedAtMs >= PROCESSING_TIMEOUT_MS;
1981
+ }
1982
+ function buildProcessingTimeoutMessage(status) {
1983
+ return `Payment is taking longer than expected (status: ${status}). Please try again.`;
1984
+ }
1960
1985
  var ACTIVE_CREDENTIAL_STORAGE_KEY = "swype_active_credential_id";
1961
1986
  function isMobile() {
1962
1987
  if (typeof navigator === "undefined") return false;
@@ -2040,7 +2065,7 @@ function SwypePayment({
2040
2065
  useWalletConnector
2041
2066
  }) {
2042
2067
  const { apiBaseUrl, tokens, depositAmount } = useSwypeConfig();
2043
- const { ready, authenticated, login, getAccessToken } = reactAuth.usePrivy();
2068
+ const { ready, authenticated, login, logout, getAccessToken } = reactAuth.usePrivy();
2044
2069
  const [step, setStep] = react.useState("login");
2045
2070
  const [error, setError] = react.useState(null);
2046
2071
  const [providers, setProviders] = react.useState([]);
@@ -2068,6 +2093,7 @@ function SwypePayment({
2068
2093
  const [mobileFlow, setMobileFlow] = react.useState(false);
2069
2094
  const pollingTransferIdRef = react.useRef(null);
2070
2095
  const mobileSigningTransferIdRef = react.useRef(null);
2096
+ const processingStartedAtRef = react.useRef(null);
2071
2097
  const [selectSourceChainName, setSelectSourceChainName] = react.useState("");
2072
2098
  const [selectSourceTokenSymbol, setSelectSourceTokenSymbol] = react.useState("");
2073
2099
  const initializedSelectSourceActionRef = react.useRef(null);
@@ -2175,6 +2201,36 @@ function SwypePayment({
2175
2201
  setError("Transfer failed.");
2176
2202
  }
2177
2203
  }, [polling.transfer, onComplete]);
2204
+ react.useEffect(() => {
2205
+ if (step !== "processing") {
2206
+ processingStartedAtRef.current = null;
2207
+ return;
2208
+ }
2209
+ if (!processingStartedAtRef.current) {
2210
+ processingStartedAtRef.current = Date.now();
2211
+ }
2212
+ const elapsedMs = Date.now() - processingStartedAtRef.current;
2213
+ const remainingMs = PROCESSING_TIMEOUT_MS - elapsedMs;
2214
+ const handleTimeout = () => {
2215
+ if (!hasProcessingTimedOut(processingStartedAtRef.current, Date.now())) {
2216
+ return;
2217
+ }
2218
+ const status = getTransferStatus(polling.transfer, transfer);
2219
+ const msg = buildProcessingTimeoutMessage(status);
2220
+ polling.stopPolling();
2221
+ setStep("ready");
2222
+ setError(msg);
2223
+ onError?.(msg);
2224
+ };
2225
+ if (remainingMs <= 0) {
2226
+ handleTimeout();
2227
+ return;
2228
+ }
2229
+ const timeoutId = window.setTimeout(handleTimeout, remainingMs);
2230
+ return () => {
2231
+ window.clearTimeout(timeoutId);
2232
+ };
2233
+ }, [step, polling.transfer, transfer, polling.stopPolling, onError]);
2178
2234
  react.useEffect(() => {
2179
2235
  if (!mobileFlow) return;
2180
2236
  const polledTransfer = polling.transfer;
@@ -2266,6 +2322,7 @@ function SwypePayment({
2266
2322
  return;
2267
2323
  }
2268
2324
  setStep("processing");
2325
+ processingStartedAtRef.current = Date.now();
2269
2326
  setError(null);
2270
2327
  setCreatingTransfer(true);
2271
2328
  setMobileFlow(false);
@@ -2351,6 +2408,7 @@ function SwypePayment({
2351
2408
  setError(null);
2352
2409
  setAmount(depositAmount != null ? depositAmount.toString() : "");
2353
2410
  setMobileFlow(false);
2411
+ processingStartedAtRef.current = null;
2354
2412
  pollingTransferIdRef.current = null;
2355
2413
  mobileSigningTransferIdRef.current = null;
2356
2414
  setConnectingNewAccount(false);
@@ -2358,6 +2416,38 @@ function SwypePayment({
2358
2416
  setAdvancedSettings({ asset: null, chain: null });
2359
2417
  if (accounts.length > 0) setSelectedAccountId(accounts[0].id);
2360
2418
  };
2419
+ const handleLogout = react.useCallback(async () => {
2420
+ try {
2421
+ await logout();
2422
+ } catch {
2423
+ }
2424
+ if (typeof window !== "undefined") {
2425
+ window.localStorage.removeItem(ACTIVE_CREDENTIAL_STORAGE_KEY);
2426
+ }
2427
+ polling.stopPolling();
2428
+ setActiveCredentialId(null);
2429
+ setStep("login");
2430
+ setError(null);
2431
+ setTransfer(null);
2432
+ setCreatingTransfer(false);
2433
+ setRegisteringPasskey(false);
2434
+ setProviders([]);
2435
+ setAccounts([]);
2436
+ setChains([]);
2437
+ setSelectedAccountId(null);
2438
+ setSelectedWalletId(null);
2439
+ setSelectedProviderId(null);
2440
+ setConnectingNewAccount(false);
2441
+ setAmount(depositAmount != null ? depositAmount.toString() : "");
2442
+ setAdvancedSettings({ asset: null, chain: null });
2443
+ setMobileFlow(false);
2444
+ setSelectSourceChainName("");
2445
+ setSelectSourceTokenSymbol("");
2446
+ initializedSelectSourceActionRef.current = null;
2447
+ processingStartedAtRef.current = null;
2448
+ pollingTransferIdRef.current = null;
2449
+ mobileSigningTransferIdRef.current = null;
2450
+ }, [logout, polling, depositAmount]);
2361
2451
  const handleConnectNewAccount = (providerId) => {
2362
2452
  setSelectedProviderId(providerId);
2363
2453
  setSelectedAccountId(null);
@@ -2715,7 +2805,32 @@ function SwypePayment({
2715
2805
  const canPay = !isNaN(parsedAmount) && parsedAmount > 0 && !!sourceId && !loadingData;
2716
2806
  const noAccounts = !loadingData && accounts.length === 0;
2717
2807
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: cardStyle, children: [
2718
- stepBadge("Review & pay"),
2808
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
2809
+ stepBadge("Review & pay"),
2810
+ /* @__PURE__ */ jsxRuntime.jsx(
2811
+ "button",
2812
+ {
2813
+ type: "button",
2814
+ onClick: handleLogout,
2815
+ style: {
2816
+ position: "absolute",
2817
+ top: 0,
2818
+ right: 0,
2819
+ background: "transparent",
2820
+ border: "none",
2821
+ color: tokens.textMuted,
2822
+ cursor: "pointer",
2823
+ fontSize: "0.75rem",
2824
+ fontWeight: 600,
2825
+ letterSpacing: "0.04em",
2826
+ textTransform: "uppercase",
2827
+ fontFamily: "inherit",
2828
+ padding: 0
2829
+ },
2830
+ children: "Logout"
2831
+ }
2832
+ )
2833
+ ] }),
2719
2834
  error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: errorStyle, children: error }),
2720
2835
  loadingData ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "24px 0", textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, { label: "Loading..." }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2721
2836
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3107,6 +3222,8 @@ function SwypePayment({
3107
3222
  }
3108
3223
  };
3109
3224
  const regMsg = getRegistrationMessage();
3225
+ const transferStatus = getDisplayTransferStatus(polling.transfer, transfer);
3226
+ const transferIdSuffix = getTransferIdSuffix(polling.transfer, transfer);
3110
3227
  const statusLabel = creatingTransfer ? "Creating transfer..." : mobileFlow ? "Waiting for authorization..." : authExecutor.executing && regMsg.label ? regMsg.label : authExecutor.executing ? "Authorizing..." : transferSigning.signing ? "Preparing transfer..." : polling.isPolling ? "Processing payment..." : "Please wait...";
3111
3228
  const statusDescription = creatingTransfer ? "Setting up your transfer..." : mobileFlow ? "Complete the authorization in your wallet app, then return here." : authExecutor.executing && regMsg.description ? regMsg.description : authExecutor.executing ? "Complete the wallet prompts to authorize this payment." : transferSigning.signing ? "Waiting for backend to prepare your transfer payload..." : polling.isPolling ? "Your payment is being processed. This usually takes a few moments." : "Hang tight...";
3112
3229
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", padding: "16px 0" }, children: [
@@ -3134,6 +3251,39 @@ function SwypePayment({
3134
3251
  children: statusDescription
3135
3252
  }
3136
3253
  ),
3254
+ /* @__PURE__ */ jsxRuntime.jsxs(
3255
+ "p",
3256
+ {
3257
+ style: {
3258
+ marginTop: "12px",
3259
+ marginBottom: 0,
3260
+ fontSize: "0.8rem",
3261
+ color: tokens.textSecondary
3262
+ },
3263
+ children: [
3264
+ "Current status: ",
3265
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: tokens.text }, children: transferStatus }),
3266
+ " \xB7 ",
3267
+ "Transfer: ",
3268
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: tokens.textMuted }, children: transferIdSuffix })
3269
+ ]
3270
+ }
3271
+ ),
3272
+ polling.error && /* @__PURE__ */ jsxRuntime.jsxs(
3273
+ "p",
3274
+ {
3275
+ style: {
3276
+ marginTop: "8px",
3277
+ marginBottom: 0,
3278
+ fontSize: "0.75rem",
3279
+ color: tokens.textMuted
3280
+ },
3281
+ children: [
3282
+ "Last polling error: ",
3283
+ polling.error
3284
+ ]
3285
+ }
3286
+ ),
3137
3287
  !mobileFlow && authExecutor.results.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: "20px", textAlign: "left" }, children: authExecutor.results.map((r) => /* @__PURE__ */ jsxRuntime.jsxs(
3138
3288
  "div",
3139
3289
  {