@swype-org/react-sdk 0.1.34 → 0.1.36

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
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
2
3
 
3
4
  /** Wallet provider (e.g. MetaMask) */
4
5
  interface Provider {
@@ -490,4 +491,95 @@ interface UseTransferSigningOptions {
490
491
  */
491
492
  declare function useTransferSigning(pollIntervalMs?: number, options?: UseTransferSigningOptions): UseTransferSigningResult;
492
493
 
493
- export { type Account, type ActionExecutionResult, type AdvancedSettings, type Amount, type AuthorizationAction, type AuthorizationSession, type AuthorizationSessionDetail, type Chain, type Destination, type ErrorResponse, type ListResponse, type MerchantAuthorization, type MerchantPublicKey, type PaymentStep, type Provider, type SourceOption, type SourceSelection, type SourceType, SwypePayment, type SwypePaymentProps, SwypeProvider, type SwypeProviderProps, type ThemeMode, type ThemeTokens, type TokenBalance, type Transfer, type TransferDestination, type UserConfig, type Wallet, type WalletSource, type WalletToken, createPasskeyCredential, darkTheme, deviceHasPasskey, findDevicePasskey, getTheme, lightTheme, api as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
494
+ interface ScreenLayoutProps {
495
+ children: ReactNode;
496
+ /** Content pinned to the bottom of the screen (buttons, footer) */
497
+ footer?: ReactNode;
498
+ }
499
+ declare function ScreenLayout({ children, footer }: ScreenLayoutProps): react_jsx_runtime.JSX.Element;
500
+
501
+ interface ScreenHeaderProps {
502
+ /** Center title text */
503
+ title?: string;
504
+ /** Right-aligned element (avatar, close button, etc.) */
505
+ right?: ReactNode;
506
+ /** Called when back arrow is pressed. Omit to hide the back arrow. */
507
+ onBack?: () => void;
508
+ /** Optional secondary label next to the title (e.g. "Simple") */
509
+ badge?: string;
510
+ }
511
+ declare function ScreenHeader({ title, right, onBack, badge }: ScreenHeaderProps): react_jsx_runtime.JSX.Element;
512
+
513
+ declare function PoweredByFooter(): react_jsx_runtime.JSX.Element;
514
+
515
+ interface PrimaryButtonProps {
516
+ children: ReactNode;
517
+ onClick?: () => void;
518
+ disabled?: boolean;
519
+ loading?: boolean;
520
+ /** Optional icon element rendered left of the label */
521
+ icon?: ReactNode;
522
+ }
523
+ declare function PrimaryButton({ children, onClick, disabled, loading, icon }: PrimaryButtonProps): react_jsx_runtime.JSX.Element;
524
+
525
+ interface OutlineButtonProps {
526
+ children: ReactNode;
527
+ onClick?: () => void;
528
+ disabled?: boolean;
529
+ }
530
+ declare function OutlineButton({ children, onClick, disabled }: OutlineButtonProps): react_jsx_runtime.JSX.Element;
531
+
532
+ type IconCircleVariant = 'accent' | 'success' | 'error';
533
+ interface IconCircleProps {
534
+ children: ReactNode;
535
+ variant?: IconCircleVariant;
536
+ size?: number;
537
+ }
538
+ declare function IconCircle({ children, variant, size }: IconCircleProps): react_jsx_runtime.JSX.Element;
539
+
540
+ interface StepItem {
541
+ label: string;
542
+ /** Optional sublabel (e.g. "$100 limit · 2 tokens approved") */
543
+ detail?: string;
544
+ status: 'pending' | 'active' | 'complete';
545
+ }
546
+ interface StepListProps {
547
+ steps: StepItem[];
548
+ }
549
+ declare function StepList({ steps }: StepListProps): react_jsx_runtime.JSX.Element;
550
+
551
+ interface SettingsMenuProps {
552
+ onLogout: () => void;
553
+ }
554
+ declare function SettingsMenu({ onLogout }: SettingsMenuProps): react_jsx_runtime.JSX.Element;
555
+
556
+ interface SpinnerProps {
557
+ size?: number;
558
+ label?: string;
559
+ }
560
+ declare function Spinner({ size, label }: SpinnerProps): react_jsx_runtime.JSX.Element;
561
+
562
+ interface ChainChoice {
563
+ chainName: string;
564
+ balance: number;
565
+ tokens: {
566
+ tokenSymbol: string;
567
+ balance: number;
568
+ }[];
569
+ }
570
+ interface SelectSourceScreenProps {
571
+ choices: ChainChoice[];
572
+ selectedChainName: string;
573
+ selectedTokenSymbol: string;
574
+ recommended: {
575
+ chainName: string;
576
+ tokenSymbol: string;
577
+ } | null;
578
+ onChainChange: (chainName: string) => void;
579
+ onTokenChange: (tokenSymbol: string) => void;
580
+ onConfirm: () => void;
581
+ onLogout: () => void;
582
+ }
583
+ declare function SelectSourceScreen({ choices, selectedChainName, selectedTokenSymbol, recommended, onChainChange, onTokenChange, onConfirm, onLogout, }: SelectSourceScreenProps): react_jsx_runtime.JSX.Element;
584
+
585
+ export { type Account, type ActionExecutionResult, type AdvancedSettings, type Amount, type AuthorizationAction, type AuthorizationSession, type AuthorizationSessionDetail, type Chain, type Destination, type ErrorResponse, IconCircle, type ListResponse, type MerchantAuthorization, type MerchantPublicKey, OutlineButton, type PaymentStep, PoweredByFooter, PrimaryButton, type Provider, ScreenHeader, ScreenLayout, SelectSourceScreen, SettingsMenu, type SourceOption, type SourceSelection, type SourceType, Spinner, type StepItem, StepList, SwypePayment, type SwypePaymentProps, SwypeProvider, type SwypeProviderProps, type ThemeMode, type ThemeTokens, type TokenBalance, type Transfer, type TransferDestination, type UserConfig, type Wallet, type WalletSource, type WalletToken, createPasskeyCredential, darkTheme, deviceHasPasskey, findDevicePasskey, getTheme, lightTheme, api as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
2
3
 
3
4
  /** Wallet provider (e.g. MetaMask) */
4
5
  interface Provider {
@@ -490,4 +491,95 @@ interface UseTransferSigningOptions {
490
491
  */
491
492
  declare function useTransferSigning(pollIntervalMs?: number, options?: UseTransferSigningOptions): UseTransferSigningResult;
492
493
 
493
- export { type Account, type ActionExecutionResult, type AdvancedSettings, type Amount, type AuthorizationAction, type AuthorizationSession, type AuthorizationSessionDetail, type Chain, type Destination, type ErrorResponse, type ListResponse, type MerchantAuthorization, type MerchantPublicKey, type PaymentStep, type Provider, type SourceOption, type SourceSelection, type SourceType, SwypePayment, type SwypePaymentProps, SwypeProvider, type SwypeProviderProps, type ThemeMode, type ThemeTokens, type TokenBalance, type Transfer, type TransferDestination, type UserConfig, type Wallet, type WalletSource, type WalletToken, createPasskeyCredential, darkTheme, deviceHasPasskey, findDevicePasskey, getTheme, lightTheme, api as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
494
+ interface ScreenLayoutProps {
495
+ children: ReactNode;
496
+ /** Content pinned to the bottom of the screen (buttons, footer) */
497
+ footer?: ReactNode;
498
+ }
499
+ declare function ScreenLayout({ children, footer }: ScreenLayoutProps): react_jsx_runtime.JSX.Element;
500
+
501
+ interface ScreenHeaderProps {
502
+ /** Center title text */
503
+ title?: string;
504
+ /** Right-aligned element (avatar, close button, etc.) */
505
+ right?: ReactNode;
506
+ /** Called when back arrow is pressed. Omit to hide the back arrow. */
507
+ onBack?: () => void;
508
+ /** Optional secondary label next to the title (e.g. "Simple") */
509
+ badge?: string;
510
+ }
511
+ declare function ScreenHeader({ title, right, onBack, badge }: ScreenHeaderProps): react_jsx_runtime.JSX.Element;
512
+
513
+ declare function PoweredByFooter(): react_jsx_runtime.JSX.Element;
514
+
515
+ interface PrimaryButtonProps {
516
+ children: ReactNode;
517
+ onClick?: () => void;
518
+ disabled?: boolean;
519
+ loading?: boolean;
520
+ /** Optional icon element rendered left of the label */
521
+ icon?: ReactNode;
522
+ }
523
+ declare function PrimaryButton({ children, onClick, disabled, loading, icon }: PrimaryButtonProps): react_jsx_runtime.JSX.Element;
524
+
525
+ interface OutlineButtonProps {
526
+ children: ReactNode;
527
+ onClick?: () => void;
528
+ disabled?: boolean;
529
+ }
530
+ declare function OutlineButton({ children, onClick, disabled }: OutlineButtonProps): react_jsx_runtime.JSX.Element;
531
+
532
+ type IconCircleVariant = 'accent' | 'success' | 'error';
533
+ interface IconCircleProps {
534
+ children: ReactNode;
535
+ variant?: IconCircleVariant;
536
+ size?: number;
537
+ }
538
+ declare function IconCircle({ children, variant, size }: IconCircleProps): react_jsx_runtime.JSX.Element;
539
+
540
+ interface StepItem {
541
+ label: string;
542
+ /** Optional sublabel (e.g. "$100 limit · 2 tokens approved") */
543
+ detail?: string;
544
+ status: 'pending' | 'active' | 'complete';
545
+ }
546
+ interface StepListProps {
547
+ steps: StepItem[];
548
+ }
549
+ declare function StepList({ steps }: StepListProps): react_jsx_runtime.JSX.Element;
550
+
551
+ interface SettingsMenuProps {
552
+ onLogout: () => void;
553
+ }
554
+ declare function SettingsMenu({ onLogout }: SettingsMenuProps): react_jsx_runtime.JSX.Element;
555
+
556
+ interface SpinnerProps {
557
+ size?: number;
558
+ label?: string;
559
+ }
560
+ declare function Spinner({ size, label }: SpinnerProps): react_jsx_runtime.JSX.Element;
561
+
562
+ interface ChainChoice {
563
+ chainName: string;
564
+ balance: number;
565
+ tokens: {
566
+ tokenSymbol: string;
567
+ balance: number;
568
+ }[];
569
+ }
570
+ interface SelectSourceScreenProps {
571
+ choices: ChainChoice[];
572
+ selectedChainName: string;
573
+ selectedTokenSymbol: string;
574
+ recommended: {
575
+ chainName: string;
576
+ tokenSymbol: string;
577
+ } | null;
578
+ onChainChange: (chainName: string) => void;
579
+ onTokenChange: (tokenSymbol: string) => void;
580
+ onConfirm: () => void;
581
+ onLogout: () => void;
582
+ }
583
+ declare function SelectSourceScreen({ choices, selectedChainName, selectedTokenSymbol, recommended, onChainChange, onTokenChange, onConfirm, onLogout, }: SelectSourceScreenProps): react_jsx_runtime.JSX.Element;
584
+
585
+ export { type Account, type ActionExecutionResult, type AdvancedSettings, type Amount, type AuthorizationAction, type AuthorizationSession, type AuthorizationSessionDetail, type Chain, type Destination, type ErrorResponse, IconCircle, type ListResponse, type MerchantAuthorization, type MerchantPublicKey, OutlineButton, type PaymentStep, PoweredByFooter, PrimaryButton, type Provider, ScreenHeader, ScreenLayout, SelectSourceScreen, SettingsMenu, type SourceOption, type SourceSelection, type SourceType, Spinner, type StepItem, StepList, SwypePayment, type SwypePaymentProps, SwypeProvider, type SwypeProviderProps, type ThemeMode, type ThemeTokens, type TokenBalance, type Transfer, type TransferDestination, type UserConfig, type Wallet, type WalletSource, type WalletToken, createPasskeyCredential, darkTheme, deviceHasPasskey, findDevicePasskey, getTheme, lightTheme, api as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { createContext, useRef, useState, useCallback, useMemo, useContext, useE
2
2
  import { PrivyProvider, usePrivy, useLoginWithEmail, useLoginWithSms, useLoginWithOAuth } from '@privy-io/react-auth';
3
3
  import { createConfig, http, WagmiProvider, useConfig, useConnect, useSwitchChain } from 'wagmi';
4
4
  import { mainnet, arbitrum, base } from 'wagmi/chains';
5
+ import { injected } from 'wagmi/connectors';
5
6
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
6
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
8
  import { recoverTypedDataAddress, decodeAbiParameters, walletActions, createClient, custom } from 'viem';
@@ -74,6 +75,7 @@ function getTheme(mode) {
74
75
  var SWYPE_PRIVY_APP_ID = "cmlil87uv004n0ck0blwumwek";
75
76
  var wagmiConfig = createConfig({
76
77
  chains: [mainnet, arbitrum, base],
78
+ connectors: [injected()],
77
79
  transports: {
78
80
  [mainnet.id]: http(),
79
81
  [arbitrum.id]: http(),
@@ -2560,13 +2562,20 @@ var WALLET_EMOJIS = {
2560
2562
  ora: "\u2666\uFE0F",
2561
2563
  phantom: "\u{1F47B}"
2562
2564
  };
2565
+ function truncateAddress(address) {
2566
+ if (address.length <= 10) return address;
2567
+ return `${address.slice(0, 6)}...${address.slice(-4)}`;
2568
+ }
2563
2569
  function WalletPickerScreen({
2564
2570
  providers,
2571
+ pendingConnections,
2565
2572
  onSelectProvider,
2573
+ onContinueConnection,
2566
2574
  onBack
2567
2575
  }) {
2568
2576
  const { tokens } = useSwypeConfig();
2569
2577
  const [hoveredId, setHoveredId] = useState(null);
2578
+ const hasPending = pendingConnections != null && pendingConnections.length > 0;
2570
2579
  const displayProviders = providers.length > 0 ? providers : [
2571
2580
  { id: "metamask", name: "MetaMask" },
2572
2581
  { id: "rabby", name: "Rabby" },
@@ -2582,8 +2591,44 @@ function WalletPickerScreen({
2582
2591
  ] }),
2583
2592
  children: [
2584
2593
  /* @__PURE__ */ jsx(ScreenHeader, { title: "Set up Swype", onBack }),
2585
- /* @__PURE__ */ jsx("h2", { style: headingStyle4(tokens.text), children: "Where are your stablecoins?" }),
2586
- /* @__PURE__ */ jsx("p", { style: subtitleStyle4(tokens.textSecondary), children: "Select the wallet you want to deposit from" }),
2594
+ hasPending && /* @__PURE__ */ jsxs(Fragment, { children: [
2595
+ /* @__PURE__ */ jsx("h2", { style: headingStyle4(tokens.text), children: "Continue where you left off" }),
2596
+ /* @__PURE__ */ jsx("p", { style: subtitleStyle4(tokens.textSecondary), children: "You have a wallet that still needs setup" }),
2597
+ /* @__PURE__ */ jsx("div", { style: pendingListStyle, children: pendingConnections.map((acct) => {
2598
+ const wallet = acct.wallets[0];
2599
+ const address = wallet ? truncateAddress(wallet.name) : void 0;
2600
+ const isHovered = hoveredId === `pending-${acct.id}`;
2601
+ return /* @__PURE__ */ jsxs(
2602
+ "button",
2603
+ {
2604
+ onClick: () => onContinueConnection?.(acct.id),
2605
+ onMouseEnter: () => setHoveredId(`pending-${acct.id}`),
2606
+ onMouseLeave: () => setHoveredId(null),
2607
+ style: pendingCardStyle(tokens, isHovered),
2608
+ children: [
2609
+ /* @__PURE__ */ jsxs("div", { style: pendingCardContentStyle, children: [
2610
+ /* @__PURE__ */ jsx("div", { style: pendingIconStyle, children: /* @__PURE__ */ jsx("span", { style: emojiStyle, children: WALLET_EMOJIS[acct.name.toLowerCase()] ?? acct.name.charAt(0) }) }),
2611
+ /* @__PURE__ */ jsxs("div", { style: pendingInfoStyle, children: [
2612
+ /* @__PURE__ */ jsx("span", { style: pendingNameStyle(tokens.text), children: acct.name }),
2613
+ address && /* @__PURE__ */ jsx("span", { style: pendingAddressStyle(tokens.textMuted), children: address })
2614
+ ] }),
2615
+ /* @__PURE__ */ jsx("span", { style: pendingBadgeStyle(tokens), children: "Setup incomplete" })
2616
+ ] }),
2617
+ /* @__PURE__ */ jsxs("div", { style: continueRowStyle(tokens), children: [
2618
+ "Continue setup",
2619
+ /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z", fill: "currentColor" }) })
2620
+ ] })
2621
+ ]
2622
+ },
2623
+ acct.id
2624
+ );
2625
+ }) }),
2626
+ /* @__PURE__ */ jsx("div", { style: dividerStyle2(tokens.border), children: /* @__PURE__ */ jsx("span", { style: dividerTextStyle(tokens.textMuted), children: "Or connect a new wallet" }) })
2627
+ ] }),
2628
+ !hasPending && /* @__PURE__ */ jsxs(Fragment, { children: [
2629
+ /* @__PURE__ */ jsx("h2", { style: headingStyle4(tokens.text), children: "Where are your stablecoins?" }),
2630
+ /* @__PURE__ */ jsx("p", { style: subtitleStyle4(tokens.textSecondary), children: "Select the wallet you want to deposit from" })
2631
+ ] }),
2587
2632
  /* @__PURE__ */ jsxs("div", { style: gridStyle, children: [
2588
2633
  displayProviders.map((p) => {
2589
2634
  const emoji = WALLET_EMOJIS[p.name.toLowerCase()] ?? p.name.charAt(0);
@@ -2687,6 +2732,86 @@ var hintStyle2 = (color) => ({
2687
2732
  color,
2688
2733
  margin: "0 0 4px"
2689
2734
  });
2735
+ var pendingListStyle = {
2736
+ display: "flex",
2737
+ flexDirection: "column",
2738
+ gap: 10,
2739
+ marginBottom: 20
2740
+ };
2741
+ var pendingCardStyle = (tokens, hovered) => ({
2742
+ display: "flex",
2743
+ flexDirection: "column",
2744
+ gap: 0,
2745
+ padding: 0,
2746
+ background: hovered ? tokens.bgHover : tokens.bgInput,
2747
+ border: `1.5px solid ${tokens.warning}44`,
2748
+ borderRadius: 16,
2749
+ cursor: "pointer",
2750
+ fontFamily: "inherit",
2751
+ transition: "background 0.15s ease",
2752
+ outline: "none",
2753
+ overflow: "hidden",
2754
+ textAlign: "left"
2755
+ });
2756
+ var pendingCardContentStyle = {
2757
+ display: "flex",
2758
+ alignItems: "center",
2759
+ gap: 12,
2760
+ padding: "14px 16px"
2761
+ };
2762
+ var pendingIconStyle = {
2763
+ flexShrink: 0
2764
+ };
2765
+ var pendingInfoStyle = {
2766
+ display: "flex",
2767
+ flexDirection: "column",
2768
+ gap: 2,
2769
+ flex: 1,
2770
+ minWidth: 0
2771
+ };
2772
+ var pendingNameStyle = (color) => ({
2773
+ fontSize: "0.92rem",
2774
+ fontWeight: 600,
2775
+ color
2776
+ });
2777
+ var pendingAddressStyle = (color) => ({
2778
+ fontSize: "0.78rem",
2779
+ color,
2780
+ fontFamily: "monospace"
2781
+ });
2782
+ var pendingBadgeStyle = (tokens) => ({
2783
+ fontSize: "0.72rem",
2784
+ fontWeight: 600,
2785
+ color: tokens.warningText ?? tokens.warning,
2786
+ background: tokens.warningBg ?? `${tokens.warning}1a`,
2787
+ padding: "3px 8px",
2788
+ borderRadius: 6,
2789
+ whiteSpace: "nowrap",
2790
+ flexShrink: 0
2791
+ });
2792
+ var continueRowStyle = (tokens) => ({
2793
+ display: "flex",
2794
+ alignItems: "center",
2795
+ justifyContent: "center",
2796
+ gap: 4,
2797
+ padding: "10px 16px",
2798
+ fontSize: "0.84rem",
2799
+ fontWeight: 600,
2800
+ color: tokens.accent,
2801
+ background: `${tokens.accent}0d`,
2802
+ borderTop: `1px solid ${tokens.accent}22`
2803
+ });
2804
+ var dividerStyle2 = (borderColor) => ({
2805
+ display: "flex",
2806
+ alignItems: "center",
2807
+ gap: 12,
2808
+ margin: "4px 0 16px"
2809
+ });
2810
+ var dividerTextStyle = (color) => ({
2811
+ fontSize: "0.82rem",
2812
+ color,
2813
+ whiteSpace: "nowrap"
2814
+ });
2690
2815
  var DEFAULT_MAX = 500;
2691
2816
  var ABSOLUTE_MIN = 1;
2692
2817
  function buildTicks(min, max) {
@@ -3774,17 +3899,36 @@ function SwypePayment({
3774
3899
  const [setupComplete, setSetupComplete] = useState(false);
3775
3900
  const [setupStepLabel, setSetupStepLabel] = useState(void 0);
3776
3901
  const [mobileFlow, setMobileFlow] = useState(false);
3902
+ const [mobileSetupFlow, setMobileSetupFlow] = useState(false);
3777
3903
  const pollingTransferIdRef = useRef(null);
3778
3904
  const mobileSigningTransferIdRef = useRef(null);
3779
3905
  const processingStartedAtRef = useRef(null);
3780
3906
  const [selectSourceChainName, setSelectSourceChainName] = useState("");
3781
3907
  const [selectSourceTokenSymbol, setSelectSourceTokenSymbol] = useState("");
3782
3908
  const initializedSelectSourceActionRef = useRef(null);
3909
+ const preSelectSourceStepRef = useRef(null);
3783
3910
  const authExecutor = useAuthorizationExecutor();
3784
3911
  const polling = useTransferPolling();
3785
3912
  const transferSigning = useTransferSigning();
3786
3913
  const sourceType = connectingNewAccount ? "providerId" : selectedWalletId ? "walletId" : selectedAccountId ? "accountId" : "providerId";
3787
3914
  const sourceId = connectingNewAccount ? selectedProviderId ?? "" : selectedWalletId ? selectedWalletId : selectedAccountId ? selectedAccountId : selectedProviderId ?? "";
3915
+ const reloadAccounts = useCallback(async () => {
3916
+ const token = await getAccessToken();
3917
+ if (!token || !activeCredentialId) return;
3918
+ const [accts, prov] = await Promise.all([
3919
+ fetchAccounts(apiBaseUrl, token, activeCredentialId),
3920
+ fetchProviders(apiBaseUrl, token)
3921
+ ]);
3922
+ setAccounts(accts);
3923
+ setProviders(prov);
3924
+ const parsedAmt = depositAmount != null ? depositAmount : 0;
3925
+ const defaults = computeSmartDefaults(accts, parsedAmt);
3926
+ if (defaults) {
3927
+ setSelectedAccountId(defaults.accountId);
3928
+ setSelectedWalletId(defaults.walletId);
3929
+ setConnectingNewAccount(false);
3930
+ }
3931
+ }, [getAccessToken, activeCredentialId, apiBaseUrl, depositAmount]);
3788
3932
  useEffect(() => {
3789
3933
  if (depositAmount != null) {
3790
3934
  setAmount(depositAmount.toString());
@@ -3795,7 +3939,7 @@ function SwypePayment({
3795
3939
  setVerificationTarget(null);
3796
3940
  setOtpCode("");
3797
3941
  }, []);
3798
- const handleSocialLogin = useCallback(async (provider) => {
3942
+ useCallback(async (provider) => {
3799
3943
  setError(null);
3800
3944
  try {
3801
3945
  await initOAuth({ provider });
@@ -3934,7 +4078,10 @@ function SwypePayment({
3934
4078
  } else if (prov.length > 0) {
3935
4079
  setSelectedProviderId(prov[0].id);
3936
4080
  }
3937
- if (accts.length === 0 && step === "deposit") {
4081
+ const hasActiveWallet = accts.some(
4082
+ (a) => a.wallets.some((w) => w.status === "ACTIVE")
4083
+ );
4084
+ if ((accts.length === 0 || !hasActiveWallet) && step === "deposit") {
3938
4085
  setStep("wallet-picker");
3939
4086
  }
3940
4087
  } catch (err) {
@@ -3993,7 +4140,24 @@ function SwypePayment({
3993
4140
  return () => window.clearTimeout(timeoutId);
3994
4141
  }, [step, polling.transfer, transfer, polling.stopPolling, onError]);
3995
4142
  useEffect(() => {
3996
- if (!mobileFlow) return;
4143
+ if (!mobileSetupFlow) return;
4144
+ const polledTransfer = polling.transfer;
4145
+ if (!polledTransfer) return;
4146
+ if (polledTransfer.status !== "AUTHORIZED" && polledTransfer.status !== "COMPLETED") return;
4147
+ polling.stopPolling();
4148
+ setMobileFlow(false);
4149
+ setMobileSetupFlow(false);
4150
+ const finishSetup = async () => {
4151
+ try {
4152
+ await reloadAccounts();
4153
+ } catch {
4154
+ }
4155
+ setStep("deposit");
4156
+ };
4157
+ void finishSetup();
4158
+ }, [mobileSetupFlow, polling, reloadAccounts]);
4159
+ useEffect(() => {
4160
+ if (!mobileFlow || mobileSetupFlow) return;
3997
4161
  const polledTransfer = polling.transfer;
3998
4162
  if (!polledTransfer || polledTransfer.status !== "AUTHORIZED") return;
3999
4163
  if (transferSigning.signing) return;
@@ -4011,7 +4175,7 @@ function SwypePayment({
4011
4175
  }
4012
4176
  };
4013
4177
  void sign();
4014
- }, [mobileFlow, polling.transfer, transferSigning, onError]);
4178
+ }, [mobileFlow, mobileSetupFlow, polling.transfer, transferSigning, onError]);
4015
4179
  useEffect(() => {
4016
4180
  if (!mobileFlow) return;
4017
4181
  const transferIdToResume = pollingTransferIdRef.current ?? transfer?.id;
@@ -4059,12 +4223,30 @@ function SwypePayment({
4059
4223
  initializedSelectSourceActionRef.current = pendingSelectSourceAction.id;
4060
4224
  }, [pendingSelectSourceAction, selectSourceChoices, selectSourceRecommended]);
4061
4225
  useEffect(() => {
4062
- if (pendingSelectSourceAction && step === "processing") {
4226
+ if (pendingSelectSourceAction && (step === "processing" || step === "setup-status")) {
4227
+ preSelectSourceStepRef.current = step;
4063
4228
  setStep("select-source");
4064
4229
  } else if (!pendingSelectSourceAction && step === "select-source") {
4065
- setStep("processing");
4230
+ setStep(preSelectSourceStepRef.current ?? "processing");
4231
+ preSelectSourceStepRef.current = null;
4066
4232
  }
4067
4233
  }, [pendingSelectSourceAction, step]);
4234
+ const SETUP_ACTION_LABELS = useMemo(() => ({
4235
+ OPEN_PROVIDER: "Connecting wallet",
4236
+ SELECT_SOURCE: "Selecting source",
4237
+ SWITCH_CHAIN: "Switching network",
4238
+ APPROVE_PERMIT2: "Approving tokens",
4239
+ SIGN_PERMIT2: "Signing permit",
4240
+ DEPLOY_SMART_ACCOUNT: "Setting up account",
4241
+ CREATE_SMART_ACCOUNT: "Creating account"
4242
+ }), []);
4243
+ useEffect(() => {
4244
+ if (step !== "setup-status") return;
4245
+ const actionType = authExecutor.currentAction?.type;
4246
+ if (!actionType) return;
4247
+ const label = SETUP_ACTION_LABELS[actionType];
4248
+ if (label) setSetupStepLabel(label);
4249
+ }, [step, authExecutor.currentAction, SETUP_ACTION_LABELS]);
4068
4250
  const handleSelectSourceChainChange = useCallback(
4069
4251
  (chainName) => {
4070
4252
  setSelectSourceChainName(chainName);
@@ -4078,6 +4260,12 @@ function SwypePayment({
4078
4260
  },
4079
4261
  [selectSourceChoices, selectSourceRecommended]
4080
4262
  );
4263
+ const pendingConnections = useMemo(
4264
+ () => accounts.filter(
4265
+ (a) => a.wallets.length > 0 && !a.wallets.some((w) => w.status === "ACTIVE")
4266
+ ),
4267
+ [accounts]
4268
+ );
4081
4269
  const selectedAccount = accounts.find((a) => a.id === selectedAccountId);
4082
4270
  const selectedWallet = selectedAccount?.wallets.find((w) => w.id === selectedWalletId);
4083
4271
  const sourceName = selectedAccount?.name ?? selectedWallet?.chain.name ?? "Wallet";
@@ -4221,7 +4409,10 @@ function SwypePayment({
4221
4409
  await registerPasskey(apiBaseUrl, token, credentialId, publicKey);
4222
4410
  setActiveCredentialId(credentialId);
4223
4411
  window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
4224
- if (accounts.length === 0) {
4412
+ const hasActiveWallet = accounts.some(
4413
+ (a) => a.wallets.some((w) => w.status === "ACTIVE")
4414
+ );
4415
+ if (accounts.length === 0 || !hasActiveWallet) {
4225
4416
  setStep("wallet-picker");
4226
4417
  } else {
4227
4418
  setStep("deposit");
@@ -4231,19 +4422,22 @@ function SwypePayment({
4231
4422
  } finally {
4232
4423
  setRegisteringPasskey(false);
4233
4424
  }
4234
- }, [getAccessToken, user, apiBaseUrl, accounts.length]);
4425
+ }, [getAccessToken, user, apiBaseUrl, accounts]);
4235
4426
  const handleSkipPasskey = useCallback(() => {
4236
- if (accounts.length === 0) {
4427
+ const hasActiveWallet = accounts.some(
4428
+ (a) => a.wallets.some((w) => w.status === "ACTIVE")
4429
+ );
4430
+ if (accounts.length === 0 || !hasActiveWallet) {
4237
4431
  setStep("wallet-picker");
4238
4432
  } else {
4239
4433
  setStep("deposit");
4240
4434
  }
4241
- }, [accounts.length]);
4435
+ }, [accounts]);
4242
4436
  const handleSetupOneTap = useCallback(async (limit) => {
4243
4437
  setOneTapLimit(limit);
4244
4438
  setStep("setup-status");
4245
4439
  setSetupComplete(false);
4246
- setSetupStepLabel("Approving tokens");
4440
+ setSetupStepLabel("Preparing");
4247
4441
  setError(null);
4248
4442
  try {
4249
4443
  const token = await getAccessToken();
@@ -4251,6 +4445,7 @@ function SwypePayment({
4251
4445
  if (!sourceId) {
4252
4446
  throw new Error("No wallet selected for setup.");
4253
4447
  }
4448
+ await updateUserConfig(apiBaseUrl, token, { defaultAllowance: limit });
4254
4449
  const setupAmount = depositAmount ?? MIN_SEND_AMOUNT_USD;
4255
4450
  const t = await createTransfer(apiBaseUrl, token, {
4256
4451
  id: idempotencyKey,
@@ -4268,11 +4463,16 @@ function SwypePayment({
4268
4463
  });
4269
4464
  if (!shouldUseConnector) {
4270
4465
  setMobileFlow(true);
4466
+ setMobileSetupFlow(true);
4467
+ pollingTransferIdRef.current = t.id;
4468
+ polling.startPolling(t.id);
4271
4469
  window.location.href = t.authorizationSessions[0].uri;
4470
+ return;
4272
4471
  } else {
4273
4472
  await authExecutor.executeSession(t);
4274
4473
  }
4275
4474
  }
4475
+ await reloadAccounts();
4276
4476
  setSetupStepLabel(void 0);
4277
4477
  setSetupComplete(true);
4278
4478
  } catch (err) {
@@ -4291,8 +4491,10 @@ function SwypePayment({
4291
4491
  merchantAuthorization,
4292
4492
  useWalletConnector,
4293
4493
  authExecutor,
4494
+ polling,
4294
4495
  onError,
4295
- depositAmount
4496
+ depositAmount,
4497
+ reloadAccounts
4296
4498
  ]);
4297
4499
  const handleSelectProvider = useCallback((providerId) => {
4298
4500
  setSelectedProviderId(providerId);
@@ -4300,12 +4502,23 @@ function SwypePayment({
4300
4502
  setConnectingNewAccount(true);
4301
4503
  setStep("setup");
4302
4504
  }, []);
4505
+ const handleContinueConnection = useCallback(
4506
+ (accountId) => {
4507
+ const acct = accounts.find((a) => a.id === accountId);
4508
+ setSelectedAccountId(accountId);
4509
+ setSelectedWalletId(acct?.wallets[0]?.id ?? null);
4510
+ setConnectingNewAccount(false);
4511
+ setStep("setup");
4512
+ },
4513
+ [accounts]
4514
+ );
4303
4515
  const handleNewPayment = useCallback(() => {
4304
4516
  setStep("deposit");
4305
4517
  setTransfer(null);
4306
4518
  setError(null);
4307
4519
  setAmount(depositAmount != null ? depositAmount.toString() : "");
4308
4520
  setMobileFlow(false);
4521
+ setMobileSetupFlow(false);
4309
4522
  processingStartedAtRef.current = null;
4310
4523
  pollingTransferIdRef.current = null;
4311
4524
  mobileSigningTransferIdRef.current = null;
@@ -4338,6 +4551,7 @@ function SwypePayment({
4338
4551
  setConnectingNewAccount(false);
4339
4552
  setAmount(depositAmount != null ? depositAmount.toString() : "");
4340
4553
  setMobileFlow(false);
4554
+ setMobileSetupFlow(false);
4341
4555
  setSetupComplete(false);
4342
4556
  resetHeadlessLogin();
4343
4557
  }, [logout, polling, depositAmount, resetHeadlessLogin]);
@@ -4354,8 +4568,7 @@ function SwypePayment({
4354
4568
  sending: activeOtpStatus === "sending-code",
4355
4569
  error,
4356
4570
  onBack,
4357
- merchantInitials: merchantName ? merchantName.slice(0, 2).toUpperCase() : void 0,
4358
- onSocialLogin: handleSocialLogin
4571
+ merchantInitials: merchantName ? merchantName.slice(0, 2).toUpperCase() : void 0
4359
4572
  }
4360
4573
  );
4361
4574
  }
@@ -4402,7 +4615,9 @@ function SwypePayment({
4402
4615
  WalletPickerScreen,
4403
4616
  {
4404
4617
  providers,
4618
+ pendingConnections,
4405
4619
  onSelectProvider: handleSelectProvider,
4620
+ onContinueConnection: handleContinueConnection,
4406
4621
  onBack: () => setStep("create-passkey")
4407
4622
  }
4408
4623
  );
@@ -4541,6 +4756,6 @@ function SwypePayment({
4541
4756
  return null;
4542
4757
  }
4543
4758
 
4544
- export { SwypePayment, SwypeProvider, createPasskeyCredential, darkTheme, deviceHasPasskey, findDevicePasskey, getTheme, lightTheme, api_exports as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
4759
+ export { IconCircle, OutlineButton, PoweredByFooter, PrimaryButton, ScreenHeader, ScreenLayout, SelectSourceScreen, SettingsMenu, Spinner, StepList, SwypePayment, SwypeProvider, createPasskeyCredential, darkTheme, deviceHasPasskey, findDevicePasskey, getTheme, lightTheme, api_exports as swypeApi, useAuthorizationExecutor, useSwypeConfig, useSwypeDepositAmount, useTransferPolling, useTransferSigning };
4545
4760
  //# sourceMappingURL=index.js.map
4546
4761
  //# sourceMappingURL=index.js.map