@swype-org/react-sdk 0.1.80 → 0.1.82

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.cts CHANGED
@@ -389,7 +389,8 @@ declare function SwypePayment(props: SwypePaymentProps): react_jsx_runtime.JSX.E
389
389
  * call (works in Chrome/Firefox with the iframe permissions policy). If
390
390
  * that fails (Safari), we open a same-origin pop-up window on the Swype
391
391
  * domain to perform the ceremony, then relay the result back via
392
- * `postMessage`.
392
+ * `BroadcastChannel` (Safari strips `window.opener` from popups opened
393
+ * by cross-origin iframes, so `postMessage` via opener doesn't work).
393
394
  *
394
395
  * Passkey *assertion* (`navigator.credentials.get`) still delegates to
395
396
  * the parent page via postMessage as before.
@@ -419,12 +420,19 @@ interface PasskeyPopupOptions {
419
420
  userVerification?: string;
420
421
  };
421
422
  timeout?: number;
423
+ /** Populated by `createPasskeyViaPopup`; not set by callers. */
424
+ channelId?: string;
422
425
  }
423
426
  /**
424
427
  * Opens a same-origin pop-up window on the Swype domain to perform
425
428
  * passkey creation. Used as a fallback when Safari blocks
426
429
  * `navigator.credentials.create()` inside a cross-origin iframe.
427
430
  *
431
+ * Communication uses `BroadcastChannel` because Safari strips
432
+ * `window.opener` from popups opened by cross-origin iframes.
433
+ * Falls back to `window.postMessage` for browsers that preserve the
434
+ * opener reference.
435
+ *
428
436
  * Must be called from a user-gesture handler (e.g. button click) to
429
437
  * avoid the browser's pop-up blocker.
430
438
  */
package/dist/index.d.ts CHANGED
@@ -389,7 +389,8 @@ declare function SwypePayment(props: SwypePaymentProps): react_jsx_runtime.JSX.E
389
389
  * call (works in Chrome/Firefox with the iframe permissions policy). If
390
390
  * that fails (Safari), we open a same-origin pop-up window on the Swype
391
391
  * domain to perform the ceremony, then relay the result back via
392
- * `postMessage`.
392
+ * `BroadcastChannel` (Safari strips `window.opener` from popups opened
393
+ * by cross-origin iframes, so `postMessage` via opener doesn't work).
393
394
  *
394
395
  * Passkey *assertion* (`navigator.credentials.get`) still delegates to
395
396
  * the parent page via postMessage as before.
@@ -419,12 +420,19 @@ interface PasskeyPopupOptions {
419
420
  userVerification?: string;
420
421
  };
421
422
  timeout?: number;
423
+ /** Populated by `createPasskeyViaPopup`; not set by callers. */
424
+ channelId?: string;
422
425
  }
423
426
  /**
424
427
  * Opens a same-origin pop-up window on the Swype domain to perform
425
428
  * passkey creation. Used as a fallback when Safari blocks
426
429
  * `navigator.credentials.create()` inside a cross-origin iframe.
427
430
  *
431
+ * Communication uses `BroadcastChannel` because Safari strips
432
+ * `window.opener` from popups opened by cross-origin iframes.
433
+ * Falls back to `window.postMessage` for browsers that preserve the
434
+ * opener reference.
435
+ *
428
436
  * Must be called from a user-gesture handler (e.g. button click) to
429
437
  * avoid the browser's pop-up blocker.
430
438
  */
package/dist/index.js CHANGED
@@ -328,6 +328,22 @@ async function reportActionCompletion(apiBaseUrl, actionId, result) {
328
328
  return await res.json();
329
329
  }
330
330
 
331
+ // src/sentry.ts
332
+ var _mod;
333
+ function captureException(error) {
334
+ if (_mod === null) return;
335
+ if (_mod) {
336
+ _mod.captureException(error);
337
+ return;
338
+ }
339
+ import('@sentry/react').then((m) => {
340
+ _mod = m;
341
+ m.captureException(error);
342
+ }).catch(() => {
343
+ _mod = null;
344
+ });
345
+ }
346
+
331
347
  // node_modules/@wagmi/core/dist/esm/version.js
332
348
  var version = "2.22.1";
333
349
 
@@ -698,13 +714,17 @@ var POPUP_RESULT_TIMEOUT_MS = 12e4;
698
714
  var POPUP_CLOSED_POLL_MS = 500;
699
715
  function createPasskeyViaPopup(options) {
700
716
  return new Promise((resolve, reject) => {
701
- const encoded = btoa(JSON.stringify(options));
717
+ const channelId = `swype-pk-${Date.now()}-${Math.random().toString(36).slice(2)}`;
718
+ const payload = { ...options, channelId };
719
+ const encoded = btoa(JSON.stringify(payload));
702
720
  const popupUrl = `${window.location.origin}/passkey-register#${encoded}`;
703
721
  const popup = window.open(popupUrl, "swype-passkey");
704
722
  if (!popup) {
705
723
  reject(new Error("Pop-up blocked. Please allow pop-ups for this site and try again."));
706
724
  return;
707
725
  }
726
+ let settled = false;
727
+ const channel = typeof BroadcastChannel !== "undefined" ? new BroadcastChannel(channelId) : null;
708
728
  const timer = setTimeout(() => {
709
729
  cleanup();
710
730
  reject(new Error("Passkey creation timed out. Please try again."));
@@ -715,11 +735,11 @@ function createPasskeyViaPopup(options) {
715
735
  reject(new Error("Passkey setup window was closed before completing."));
716
736
  }
717
737
  }, POPUP_CLOSED_POLL_MS);
718
- const handler = (event) => {
719
- if (event.source !== popup) return;
720
- const data = event.data;
738
+ function handleResult(data) {
739
+ if (settled) return;
721
740
  if (!data || typeof data !== "object") return;
722
741
  if (data.type !== "swype:passkey-popup-result") return;
742
+ settled = true;
723
743
  cleanup();
724
744
  if (data.error) {
725
745
  reject(new Error(data.error));
@@ -728,13 +748,21 @@ function createPasskeyViaPopup(options) {
728
748
  } else {
729
749
  reject(new Error("Invalid passkey popup response."));
730
750
  }
751
+ }
752
+ if (channel) {
753
+ channel.onmessage = (event) => handleResult(event.data);
754
+ }
755
+ const postMessageHandler = (event) => {
756
+ if (event.source !== popup) return;
757
+ handleResult(event.data);
731
758
  };
759
+ window.addEventListener("message", postMessageHandler);
732
760
  function cleanup() {
733
761
  clearTimeout(timer);
734
762
  clearInterval(closedPoll);
735
- window.removeEventListener("message", handler);
763
+ window.removeEventListener("message", postMessageHandler);
764
+ channel?.close();
736
765
  }
737
- window.addEventListener("message", handler);
738
766
  });
739
767
  }
740
768
 
@@ -4343,8 +4371,8 @@ var PaymentErrorBoundary = class extends Component {
4343
4371
  static getDerivedStateFromError() {
4344
4372
  return { hasError: true };
4345
4373
  }
4346
- componentDidCatch(error, info) {
4347
- console.error("[SwypePayment] Uncaught error:", error, info.componentStack);
4374
+ componentDidCatch(error, _info) {
4375
+ captureException(error);
4348
4376
  }
4349
4377
  handleReset = () => {
4350
4378
  this.setState({ hasError: false });
@@ -4662,6 +4690,7 @@ function SwypePaymentInner({
4662
4690
  try {
4663
4691
  await initOAuth({ provider });
4664
4692
  } catch (err) {
4693
+ captureException(err);
4665
4694
  setError(err instanceof Error ? err.message : "Social login failed");
4666
4695
  }
4667
4696
  }, [initOAuth]);
@@ -4688,6 +4717,7 @@ function SwypePaymentInner({
4688
4717
  setVerificationTarget(normalizedIdentifier);
4689
4718
  setStep("otp-verify");
4690
4719
  } catch (err) {
4720
+ captureException(err);
4691
4721
  setError(err instanceof Error ? err.message : "Failed to send verification code");
4692
4722
  }
4693
4723
  }, [authInput, sendEmailCode, sendSmsCode]);
@@ -4706,6 +4736,7 @@ function SwypePaymentInner({
4706
4736
  await loginWithSmsCode({ code: trimmedCode });
4707
4737
  }
4708
4738
  } catch (err) {
4739
+ captureException(err);
4709
4740
  setError(err instanceof Error ? err.message : "Failed to verify code");
4710
4741
  }
4711
4742
  }, [verificationTarget, otpCode, loginWithEmailCode, loginWithSmsCode]);
@@ -4724,6 +4755,7 @@ function SwypePaymentInner({
4724
4755
  await sendSmsCode({ phoneNumber: verificationTarget.value });
4725
4756
  }
4726
4757
  } catch (err) {
4758
+ captureException(err);
4727
4759
  setError(err instanceof Error ? err.message : "Failed to resend code");
4728
4760
  }
4729
4761
  }, [verificationTarget, sendEmailCode, sendSmsCode]);
@@ -4938,6 +4970,7 @@ function SwypePaymentInner({
4938
4970
  }
4939
4971
  } catch (err) {
4940
4972
  if (!cancelled) {
4973
+ captureException(err);
4941
4974
  setError(err instanceof Error ? err.message : "Failed to load data");
4942
4975
  }
4943
4976
  } finally {
@@ -4980,6 +5013,7 @@ function SwypePaymentInner({
4980
5013
  if (!hasProcessingTimedOut(processingStartedAtRef.current, Date.now())) return;
4981
5014
  const status = getTransferStatus(polling.transfer, transfer);
4982
5015
  const msg = buildProcessingTimeoutMessage(status);
5016
+ captureException(new Error(msg));
4983
5017
  polling.stopPolling();
4984
5018
  setStep("deposit");
4985
5019
  setError(msg);
@@ -5204,6 +5238,7 @@ function SwypePaymentInner({
5204
5238
  setTransfer(signedTransfer);
5205
5239
  polling.startPolling(t.id);
5206
5240
  } catch (err) {
5241
+ captureException(err);
5207
5242
  const msg = err instanceof Error ? err.message : "Transfer failed";
5208
5243
  setError(msg);
5209
5244
  onError?.(msg);
@@ -5282,6 +5317,7 @@ function SwypePaymentInner({
5282
5317
  triggerDeeplink(uri);
5283
5318
  }
5284
5319
  } catch (err) {
5320
+ captureException(err);
5285
5321
  const msg = err instanceof Error ? err.message : "Failed to increase limit";
5286
5322
  setError(msg);
5287
5323
  onError?.(msg);
@@ -5336,6 +5372,7 @@ function SwypePaymentInner({
5336
5372
  if (err instanceof PasskeyIframeBlockedError) {
5337
5373
  setPasskeyPopupNeeded(true);
5338
5374
  } else {
5375
+ captureException(err);
5339
5376
  setError(err instanceof Error ? err.message : "Failed to register passkey");
5340
5377
  }
5341
5378
  } finally {
@@ -5354,6 +5391,7 @@ function SwypePaymentInner({
5354
5391
  const { credentialId, publicKey } = await createPasskeyViaPopup(popupOptions);
5355
5392
  await completePasskeyRegistration(credentialId, publicKey);
5356
5393
  } catch (err) {
5394
+ captureException(err);
5357
5395
  setError(err instanceof Error ? err.message : "Failed to register passkey");
5358
5396
  } finally {
5359
5397
  setRegisteringPasskey(false);
@@ -5441,6 +5479,7 @@ function SwypePaymentInner({
5441
5479
  setStep("processing");
5442
5480
  polling.startPolling(t.id);
5443
5481
  } catch (err) {
5482
+ captureException(err);
5444
5483
  const msg = err instanceof Error ? err.message : "Failed to sign transfer";
5445
5484
  setError(msg);
5446
5485
  onError?.(msg);